Throttled DOMTimers can prevent their document from being garbage collected
[WebKit-https.git] / Source / WebCore / dom / Element.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2001 Peter Kelly (pmk@post.com)
5  *           (C) 2001 Dirk Mueller (mueller@kde.org)
6  *           (C) 2007 David Smith (catfish.man@gmail.com)
7  * Copyright (C) 2004-2014 Apple Inc. All rights reserved.
8  *           (C) 2007 Eric Seidel (eric@webkit.org)
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public License
21  * along with this library; see the file COPYING.LIB.  If not, write to
22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23  * Boston, MA 02110-1301, USA.
24  */
25
26 #include "config.h"
27 #include "Element.h"
28
29 #include "AXObjectCache.h"
30 #include "Attr.h"
31 #include "CSSParser.h"
32 #include "Chrome.h"
33 #include "ChromeClient.h"
34 #include "ClientRect.h"
35 #include "ClientRectList.h"
36 #include "ContainerNodeAlgorithms.h"
37 #include "DOMTokenList.h"
38 #include "DocumentSharedObjectPool.h"
39 #include "ElementIterator.h"
40 #include "ElementRareData.h"
41 #include "EventDispatcher.h"
42 #include "FlowThreadController.h"
43 #include "FocusController.h"
44 #include "FocusEvent.h"
45 #include "FrameSelection.h"
46 #include "FrameView.h"
47 #include "HTMLCanvasElement.h"
48 #include "HTMLCollection.h"
49 #include "HTMLDocument.h"
50 #include "HTMLFormControlsCollection.h"
51 #include "HTMLLabelElement.h"
52 #include "HTMLNameCollection.h"
53 #include "HTMLOptionsCollection.h"
54 #include "HTMLParserIdioms.h"
55 #include "HTMLSelectElement.h"
56 #include "HTMLTableRowsCollection.h"
57 #include "InsertionPoint.h"
58 #include "KeyboardEvent.h"
59 #include "MutationObserverInterestGroup.h"
60 #include "MutationRecord.h"
61 #include "NodeRenderStyle.h"
62 #include "PlatformWheelEvent.h"
63 #include "PointerLockController.h"
64 #include "RenderLayer.h"
65 #include "RenderNamedFlowFragment.h"
66 #include "RenderRegion.h"
67 #include "RenderTheme.h"
68 #include "RenderView.h"
69 #include "RenderWidget.h"
70 #include "SVGDocumentExtensions.h"
71 #include "SVGElement.h"
72 #include "SVGNames.h"
73 #include "SelectorQuery.h"
74 #include "Settings.h"
75 #include "StyleProperties.h"
76 #include "StyleResolver.h"
77 #include "TextIterator.h"
78 #include "VoidCallback.h"
79 #include "WheelEvent.h"
80 #include "XLinkNames.h"
81 #include "XMLNSNames.h"
82 #include "XMLNames.h"
83 #include "htmlediting.h"
84 #include <wtf/BitVector.h>
85 #include <wtf/CurrentTime.h>
86 #include <wtf/text/CString.h>
87
88 namespace WebCore {
89
90 using namespace HTMLNames;
91 using namespace XMLNames;
92
93 static inline bool shouldIgnoreAttributeCase(const Element& element)
94 {
95     return element.isHTMLElement() && element.document().isHTMLDocument();
96 }
97
98 static HashMap<Element*, Vector<RefPtr<Attr>>>& attrNodeListMap()
99 {
100     static NeverDestroyed<HashMap<Element*, Vector<RefPtr<Attr>>>> map;
101     return map;
102 }
103
104 static Vector<RefPtr<Attr>>* attrNodeListForElement(Element& element)
105 {
106     if (!element.hasSyntheticAttrChildNodes())
107         return nullptr;
108     ASSERT(attrNodeListMap().contains(&element));
109     return &attrNodeListMap().find(&element)->value;
110 }
111
112 static Vector<RefPtr<Attr>>& ensureAttrNodeListForElement(Element& element)
113 {
114     if (element.hasSyntheticAttrChildNodes()) {
115         ASSERT(attrNodeListMap().contains(&element));
116         return attrNodeListMap().find(&element)->value;
117     }
118     ASSERT(!attrNodeListMap().contains(&element));
119     element.setHasSyntheticAttrChildNodes(true);
120     return attrNodeListMap().add(&element, Vector<RefPtr<Attr>>()).iterator->value;
121 }
122
123 static void removeAttrNodeListForElement(Element& element)
124 {
125     ASSERT(element.hasSyntheticAttrChildNodes());
126     ASSERT(attrNodeListMap().contains(&element));
127     attrNodeListMap().remove(&element);
128     element.setHasSyntheticAttrChildNodes(false);
129 }
130
131 static Attr* findAttrNodeInList(Vector<RefPtr<Attr>>& attrNodeList, const QualifiedName& name)
132 {
133     for (auto& node : attrNodeList) {
134         if (node->qualifiedName() == name)
135             return node.get();
136     }
137     return nullptr;
138 }
139
140 PassRefPtr<Element> Element::create(const QualifiedName& tagName, Document& document)
141 {
142     return adoptRef(new Element(tagName, document, CreateElement));
143 }
144
145 Element::Element(const QualifiedName& tagName, Document& document, ConstructionType type)
146     : ContainerNode(document, type)
147     , m_tagName(tagName)
148 {
149 }
150
151 Element::~Element()
152 {
153 #ifndef NDEBUG
154     if (document().hasLivingRenderTree()) {
155         // When the document is not destroyed, an element that was part of a named flow
156         // content nodes should have been removed from the content nodes collection
157         // and the isNamedFlowContentNode flag reset.
158         ASSERT_WITH_SECURITY_IMPLICATION(!isNamedFlowContentNode());
159     }
160 #endif
161
162     ASSERT(!beforePseudoElement());
163     ASSERT(!afterPseudoElement());
164
165     removeShadowRoot();
166
167     if (hasSyntheticAttrChildNodes())
168         detachAllAttrNodesFromElement();
169
170     if (hasPendingResources()) {
171         document().accessSVGExtensions().removeElementFromPendingResources(this);
172         ASSERT(!hasPendingResources());
173     }
174 }
175
176 inline ElementRareData* Element::elementRareData() const
177 {
178     ASSERT_WITH_SECURITY_IMPLICATION(hasRareData());
179     return static_cast<ElementRareData*>(rareData());
180 }
181
182 inline ElementRareData& Element::ensureElementRareData()
183 {
184     return static_cast<ElementRareData&>(ensureRareData());
185 }
186
187 void Element::clearTabIndexExplicitlyIfNeeded()
188 {
189     if (hasRareData())
190         elementRareData()->clearTabIndexExplicitly();
191 }
192
193 void Element::setTabIndexExplicitly(short tabIndex)
194 {
195     ensureElementRareData().setTabIndexExplicitly(tabIndex);
196 }
197
198 bool Element::supportsFocus() const
199 {
200     return hasRareData() && elementRareData()->tabIndexSetExplicitly();
201 }
202
203 Element* Element::focusDelegate()
204 {
205     return this;
206 }
207
208 short Element::tabIndex() const
209 {
210     return hasRareData() ? elementRareData()->tabIndex() : 0;
211 }
212
213 void Element::setTabIndex(int value)
214 {
215     setIntegralAttribute(tabindexAttr, value);
216 }
217
218 bool Element::isKeyboardFocusable(KeyboardEvent*) const
219 {
220     return isFocusable() && tabIndex() >= 0;
221 }
222
223 bool Element::isMouseFocusable() const
224 {
225     return isFocusable();
226 }
227
228 bool Element::shouldUseInputMethod()
229 {
230     return isContentEditable(UserSelectAllIsAlwaysNonEditable);
231 }
232
233 bool Element::dispatchMouseEvent(const PlatformMouseEvent& platformEvent, const AtomicString& eventType, int detail, Element* relatedTarget)
234 {
235     if (isDisabledFormControl())
236         return false;
237
238     RefPtr<MouseEvent> mouseEvent = MouseEvent::create(eventType, document().defaultView(), platformEvent, detail, relatedTarget);
239
240     if (mouseEvent->type().isEmpty())
241         return true; // Shouldn't happen.
242
243     ASSERT(!mouseEvent->target() || mouseEvent->target() != relatedTarget);
244     bool didNotSwallowEvent = dispatchEvent(mouseEvent) && !mouseEvent->defaultHandled();
245
246     if (mouseEvent->type() == eventNames().clickEvent && mouseEvent->detail() == 2) {
247         // Special case: If it's a double click event, we also send the dblclick event. This is not part
248         // of the DOM specs, but is used for compatibility with the ondblclick="" attribute. This is treated
249         // as a separate event in other DOM-compliant browsers like Firefox, and so we do the same.
250         RefPtr<MouseEvent> doubleClickEvent = MouseEvent::create();
251         doubleClickEvent->initMouseEvent(eventNames().dblclickEvent,
252             mouseEvent->bubbles(), mouseEvent->cancelable(), mouseEvent->view(), mouseEvent->detail(),
253             mouseEvent->screenX(), mouseEvent->screenY(), mouseEvent->clientX(), mouseEvent->clientY(),
254             mouseEvent->ctrlKey(), mouseEvent->altKey(), mouseEvent->shiftKey(), mouseEvent->metaKey(),
255             mouseEvent->button(), relatedTarget);
256
257         if (mouseEvent->defaultHandled())
258             doubleClickEvent->setDefaultHandled();
259
260         dispatchEvent(doubleClickEvent);
261         if (doubleClickEvent->defaultHandled() || doubleClickEvent->defaultPrevented())
262             return false;
263     }
264     return didNotSwallowEvent;
265 }
266
267
268 bool Element::dispatchWheelEvent(const PlatformWheelEvent& event)
269 {
270     RefPtr<WheelEvent> wheelEvent = WheelEvent::create(event, document().defaultView());
271     return EventDispatcher::dispatchEvent(this, wheelEvent) && !wheelEvent->defaultHandled();
272 }
273
274 bool Element::dispatchKeyEvent(const PlatformKeyboardEvent& platformEvent)
275 {
276     RefPtr<KeyboardEvent> event = KeyboardEvent::create(platformEvent, document().defaultView());
277     return EventDispatcher::dispatchEvent(this, event) && !event->defaultHandled();
278 }
279
280 void Element::dispatchSimulatedClick(Event* underlyingEvent, SimulatedClickMouseEventOptions eventOptions, SimulatedClickVisualOptions visualOptions)
281 {
282     EventDispatcher::dispatchSimulatedClick(this, underlyingEvent, eventOptions, visualOptions);
283 }
284
285 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, blur);
286 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, error);
287 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, focus);
288 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, load);
289
290 PassRefPtr<Node> Element::cloneNode(bool deep)
291 {
292     return deep ? cloneElementWithChildren() : cloneElementWithoutChildren();
293 }
294
295 PassRefPtr<Element> Element::cloneElementWithChildren()
296 {
297     RefPtr<Element> clone = cloneElementWithoutChildren();
298     cloneChildNodes(clone.get());
299     return clone.release();
300 }
301
302 PassRefPtr<Element> Element::cloneElementWithoutChildren()
303 {
304     RefPtr<Element> clone = cloneElementWithoutAttributesAndChildren();
305     // This will catch HTML elements in the wrong namespace that are not correctly copied.
306     // This is a sanity check as HTML overloads some of the DOM methods.
307     ASSERT(isHTMLElement() == clone->isHTMLElement());
308
309     clone->cloneDataFromElement(*this);
310     return clone.release();
311 }
312
313 PassRefPtr<Element> Element::cloneElementWithoutAttributesAndChildren()
314 {
315     return document().createElement(tagQName(), false);
316 }
317
318 PassRefPtr<Attr> Element::detachAttribute(unsigned index)
319 {
320     ASSERT(elementData());
321
322     const Attribute& attribute = elementData()->attributeAt(index);
323
324     RefPtr<Attr> attrNode = attrIfExists(attribute.name());
325     if (attrNode)
326         detachAttrNodeFromElementWithValue(attrNode.get(), attribute.value());
327     else
328         attrNode = Attr::create(document(), attribute.name(), attribute.value());
329
330     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
331     return attrNode.release();
332 }
333
334 bool Element::removeAttribute(const QualifiedName& name)
335 {
336     if (!elementData())
337         return false;
338
339     unsigned index = elementData()->findAttributeIndexByName(name);
340     if (index == ElementData::attributeNotFound)
341         return false;
342
343     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
344     return true;
345 }
346
347 void Element::setBooleanAttribute(const QualifiedName& name, bool value)
348 {
349     if (value)
350         setAttribute(name, emptyAtom);
351     else
352         removeAttribute(name);
353 }
354
355 NamedNodeMap& Element::attributes() const
356 {
357     ElementRareData& rareData = const_cast<Element*>(this)->ensureElementRareData();
358     if (NamedNodeMap* attributeMap = rareData.attributeMap())
359         return *attributeMap;
360
361     rareData.setAttributeMap(NamedNodeMap::create(const_cast<Element&>(*this)));
362     return *rareData.attributeMap();
363 }
364
365 Node::NodeType Element::nodeType() const
366 {
367     return ELEMENT_NODE;
368 }
369
370 bool Element::hasAttribute(const QualifiedName& name) const
371 {
372     return hasAttributeNS(name.namespaceURI(), name.localName());
373 }
374
375 void Element::synchronizeAllAttributes() const
376 {
377     if (!elementData())
378         return;
379     if (elementData()->styleAttributeIsDirty()) {
380         ASSERT(isStyledElement());
381         static_cast<const StyledElement*>(this)->synchronizeStyleAttributeInternal();
382     }
383
384     if (elementData()->animatedSVGAttributesAreDirty()) {
385         ASSERT(isSVGElement());
386         downcast<SVGElement>(*this).synchronizeAnimatedSVGAttribute(anyQName());
387     }
388 }
389
390 ALWAYS_INLINE void Element::synchronizeAttribute(const QualifiedName& name) const
391 {
392     if (!elementData())
393         return;
394     if (UNLIKELY(name == styleAttr && elementData()->styleAttributeIsDirty())) {
395         ASSERT_WITH_SECURITY_IMPLICATION(isStyledElement());
396         static_cast<const StyledElement*>(this)->synchronizeStyleAttributeInternal();
397         return;
398     }
399
400     if (UNLIKELY(elementData()->animatedSVGAttributesAreDirty())) {
401         ASSERT(isSVGElement());
402         downcast<SVGElement>(*this).synchronizeAnimatedSVGAttribute(name);
403     }
404 }
405
406 ALWAYS_INLINE void Element::synchronizeAttribute(const AtomicString& localName) const
407 {
408     // This version of synchronizeAttribute() is streamlined for the case where you don't have a full QualifiedName,
409     // e.g when called from DOM API.
410     if (!elementData())
411         return;
412     if (elementData()->styleAttributeIsDirty() && equalPossiblyIgnoringCase(localName, styleAttr.localName(), shouldIgnoreAttributeCase(*this))) {
413         ASSERT_WITH_SECURITY_IMPLICATION(isStyledElement());
414         static_cast<const StyledElement*>(this)->synchronizeStyleAttributeInternal();
415         return;
416     }
417
418     if (elementData()->animatedSVGAttributesAreDirty()) {
419         // We're not passing a namespace argument on purpose. SVGNames::*Attr are defined w/o namespaces as well.
420         ASSERT_WITH_SECURITY_IMPLICATION(isSVGElement());
421         downcast<SVGElement>(*this).synchronizeAnimatedSVGAttribute(QualifiedName(nullAtom, localName, nullAtom));
422     }
423 }
424
425 const AtomicString& Element::getAttribute(const QualifiedName& name) const
426 {
427     if (!elementData())
428         return nullAtom;
429     synchronizeAttribute(name);
430     if (const Attribute* attribute = findAttributeByName(name))
431         return attribute->value();
432     return nullAtom;
433 }
434
435 bool Element::isFocusable() const
436 {
437     if (!inDocument() || !supportsFocus())
438         return false;
439
440     if (!renderer()) {
441         // If the node is in a display:none tree it might say it needs style recalc but
442         // the whole document is actually up to date.
443         ASSERT(!needsStyleRecalc() || !document().childNeedsStyleRecalc());
444
445         // Elements in canvas fallback content are not rendered, but they are allowed to be
446         // focusable as long as their canvas is displayed and visible.
447         if (auto* canvas = ancestorsOfType<HTMLCanvasElement>(*this).first())
448             return canvas->renderer() && canvas->renderer()->style().visibility() == VISIBLE;
449     }
450
451     // FIXME: Even if we are not visible, we might have a child that is visible.
452     // Hyatt wants to fix that some day with a "has visible content" flag or the like.
453     if (!renderer() || renderer()->style().visibility() != VISIBLE)
454         return false;
455
456     return true;
457 }
458
459 bool Element::isUserActionElementInActiveChain() const
460 {
461     ASSERT(isUserActionElement());
462     return document().userActionElements().isInActiveChain(this);
463 }
464
465 bool Element::isUserActionElementActive() const
466 {
467     ASSERT(isUserActionElement());
468     return document().userActionElements().isActive(this);
469 }
470
471 bool Element::isUserActionElementFocused() const
472 {
473     ASSERT(isUserActionElement());
474     return document().userActionElements().isFocused(this);
475 }
476
477 bool Element::isUserActionElementHovered() const
478 {
479     ASSERT(isUserActionElement());
480     return document().userActionElements().isHovered(this);
481 }
482
483 void Element::setActive(bool flag, bool pause)
484 {
485     if (flag == active())
486         return;
487
488     document().userActionElements().setActive(this, flag);
489
490     if (!renderer())
491         return;
492
493     bool reactsToPress = renderStyle()->affectedByActive() || childrenAffectedByActive();
494     if (reactsToPress)
495         setNeedsStyleRecalc();
496
497     if (renderer()->style().hasAppearance() && renderer()->theme().stateChanged(*renderer(), ControlStates::PressedState))
498         reactsToPress = true;
499
500     // The rest of this function implements a feature that only works if the
501     // platform supports immediate invalidations on the ChromeClient, so bail if
502     // that isn't supported.
503     if (!document().page()->chrome().client().supportsImmediateInvalidation())
504         return;
505
506     if (reactsToPress && pause) {
507         // The delay here is subtle. It relies on an assumption, namely that the amount of time it takes
508         // to repaint the "down" state of the control is about the same time as it would take to repaint the
509         // "up" state. Once you assume this, you can just delay for 100ms - that time (assuming that after you
510         // leave this method, it will be about that long before the flush of the up state happens again).
511 #ifdef HAVE_FUNC_USLEEP
512         double startTime = monotonicallyIncreasingTime();
513 #endif
514
515         document().updateStyleIfNeeded();
516
517         // Do an immediate repaint.
518         if (renderer())
519             renderer()->repaint();
520
521         // FIXME: Come up with a less ridiculous way of doing this.
522 #ifdef HAVE_FUNC_USLEEP
523         // Now pause for a small amount of time (1/10th of a second from before we repainted in the pressed state)
524         double remainingTime = 0.1 - (monotonicallyIncreasingTime() - startTime);
525         if (remainingTime > 0)
526             usleep(static_cast<useconds_t>(remainingTime * 1000000.0));
527 #endif
528     }
529 }
530
531 void Element::setFocus(bool flag)
532 {
533     if (flag == focused())
534         return;
535
536     document().userActionElements().setFocused(this, flag);
537     setNeedsStyleRecalc();
538 }
539
540 void Element::setHovered(bool flag)
541 {
542     if (flag == hovered())
543         return;
544
545     document().userActionElements().setHovered(this, flag);
546
547     if (!renderer()) {
548         // When setting hover to false, the style needs to be recalc'd even when
549         // there's no renderer (imagine setting display:none in the :hover class,
550         // if a nil renderer would prevent this element from recalculating its
551         // style, it would never go back to its normal style and remain
552         // stuck in its hovered style).
553         if (!flag)
554             setNeedsStyleRecalc();
555
556         return;
557     }
558
559     if (renderer()->style().affectedByHover() || childrenAffectedByHover())
560         setNeedsStyleRecalc();
561
562     if (renderer()->style().hasAppearance())
563         renderer()->theme().stateChanged(*renderer(), ControlStates::HoverState);
564 }
565
566 void Element::scrollIntoView(bool alignToTop) 
567 {
568     document().updateLayoutIgnorePendingStylesheets();
569
570     if (!renderer())
571         return;
572
573     LayoutRect bounds = boundingBox();
574     // Align to the top / bottom and to the closest edge.
575     if (alignToTop)
576         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
577     else
578         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignBottomAlways);
579 }
580
581 void Element::scrollIntoViewIfNeeded(bool centerIfNeeded)
582 {
583     document().updateLayoutIgnorePendingStylesheets();
584
585     if (!renderer())
586         return;
587
588     LayoutRect bounds = boundingBox();
589     if (centerIfNeeded)
590         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignCenterIfNeeded, ScrollAlignment::alignCenterIfNeeded);
591     else
592         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
593 }
594
595 void Element::scrollByUnits(int units, ScrollGranularity granularity)
596 {
597     document().updateLayoutIgnorePendingStylesheets();
598
599     if (!renderer())
600         return;
601
602     if (!renderer()->hasOverflowClip())
603         return;
604
605     ScrollDirection direction = ScrollDown;
606     if (units < 0) {
607         direction = ScrollUp;
608         units = -units;
609     }
610     Element* stopElement = this;
611     downcast<RenderBox>(*renderer()).scroll(direction, granularity, units, &stopElement);
612 }
613
614 void Element::scrollByLines(int lines)
615 {
616     scrollByUnits(lines, ScrollByLine);
617 }
618
619 void Element::scrollByPages(int pages)
620 {
621     scrollByUnits(pages, ScrollByPage);
622 }
623
624 static double localZoomForRenderer(const RenderElement& renderer)
625 {
626     // FIXME: This does the wrong thing if two opposing zooms are in effect and canceled each
627     // other out, but the alternative is that we'd have to crawl up the whole render tree every
628     // time (or store an additional bit in the RenderStyle to indicate that a zoom was specified).
629     double zoomFactor = 1;
630     if (renderer.style().effectiveZoom() != 1) {
631         // Need to find the nearest enclosing RenderElement that set up
632         // a differing zoom, and then we divide our result by it to eliminate the zoom.
633         const RenderElement* prev = &renderer;
634         for (RenderElement* curr = prev->parent(); curr; curr = curr->parent()) {
635             if (curr->style().effectiveZoom() != prev->style().effectiveZoom()) {
636                 zoomFactor = prev->style().zoom();
637                 break;
638             }
639             prev = curr;
640         }
641         if (prev->isRenderView())
642             zoomFactor = prev->style().zoom();
643     }
644     return zoomFactor;
645 }
646
647 static double adjustForLocalZoom(LayoutUnit value, const RenderElement& renderer, double& zoomFactor)
648 {
649     zoomFactor = localZoomForRenderer(renderer);
650     if (zoomFactor == 1)
651         return value.toDouble();
652     return value.toDouble() / zoomFactor;
653 }
654
655 enum LegacyCSSOMElementMetricsRoundingStrategy { Round, Floor };
656
657 static bool subpixelMetricsEnabled(const Document& document)
658 {
659     return document.settings() && document.settings()->subpixelCSSOMElementMetricsEnabled();
660 }
661
662 static double convertToNonSubpixelValueIfNeeded(double value, const Document& document, LegacyCSSOMElementMetricsRoundingStrategy roundStrategy = Round)
663 {
664     return subpixelMetricsEnabled(document) ? value : roundStrategy == Round ? round(value) : floor(value);
665 }
666
667 double Element::offsetLeft()
668 {
669     document().updateLayoutIgnorePendingStylesheets();
670     if (RenderBoxModelObject* renderer = renderBoxModelObject()) {
671         LayoutUnit offsetLeft = subpixelMetricsEnabled(renderer->document()) ? renderer->offsetLeft() : LayoutUnit(renderer->pixelSnappedOffsetLeft());
672         double zoomFactor = 1;
673         double offsetLeftAdjustedWithZoom = adjustForLocalZoom(offsetLeft, *renderer, zoomFactor);
674         return convertToNonSubpixelValueIfNeeded(offsetLeftAdjustedWithZoom, renderer->document(), zoomFactor == 1 ? Floor : Round);
675     }
676     return 0;
677 }
678
679 double Element::offsetTop()
680 {
681     document().updateLayoutIgnorePendingStylesheets();
682     if (RenderBoxModelObject* renderer = renderBoxModelObject()) {
683         LayoutUnit offsetTop = subpixelMetricsEnabled(renderer->document()) ? renderer->offsetTop() : LayoutUnit(renderer->pixelSnappedOffsetTop());
684         double zoomFactor = 1;
685         double offsetTopAdjustedWithZoom = adjustForLocalZoom(offsetTop, *renderer, zoomFactor);
686         return convertToNonSubpixelValueIfNeeded(offsetTopAdjustedWithZoom, renderer->document(), zoomFactor == 1 ? Floor : Round);
687     }
688     return 0;
689 }
690
691 double Element::offsetWidth()
692 {
693     document().updateLayoutIgnorePendingStylesheets();
694     if (RenderBoxModelObject* renderer = renderBoxModelObject()) {
695         LayoutUnit offsetWidth = subpixelMetricsEnabled(renderer->document()) ? renderer->offsetWidth() : LayoutUnit(renderer->pixelSnappedOffsetWidth());
696         return convertToNonSubpixelValueIfNeeded(adjustLayoutUnitForAbsoluteZoom(offsetWidth, *renderer).toDouble(), renderer->document());
697     }
698     return 0;
699 }
700
701 double Element::offsetHeight()
702 {
703     document().updateLayoutIgnorePendingStylesheets();
704     if (RenderBoxModelObject* renderer = renderBoxModelObject()) {
705         LayoutUnit offsetHeight = subpixelMetricsEnabled(renderer->document()) ? renderer->offsetHeight() : LayoutUnit(renderer->pixelSnappedOffsetHeight());
706         return convertToNonSubpixelValueIfNeeded(adjustLayoutUnitForAbsoluteZoom(offsetHeight, *renderer).toDouble(), renderer->document());
707     }
708     return 0;
709 }
710
711 Element* Element::bindingsOffsetParent()
712 {
713     Element* element = offsetParent();
714     if (!element || !element->isInShadowTree())
715         return element;
716     return element->containingShadowRoot()->type() == ShadowRoot::UserAgentShadowRoot ? 0 : element;
717 }
718
719 Element* Element::offsetParent()
720 {
721     document().updateLayoutIgnorePendingStylesheets();
722     auto renderer = this->renderer();
723     if (!renderer)
724         return nullptr;
725     auto offsetParent = renderer->offsetParent();
726     if (!offsetParent)
727         return nullptr;
728     return offsetParent->element();
729 }
730
731 double Element::clientLeft()
732 {
733     document().updateLayoutIgnorePendingStylesheets();
734
735     if (RenderBox* renderer = renderBox()) {
736         LayoutUnit clientLeft = subpixelMetricsEnabled(renderer->document()) ? renderer->clientLeft() : LayoutUnit(roundToInt(renderer->clientLeft()));
737         return convertToNonSubpixelValueIfNeeded(adjustLayoutUnitForAbsoluteZoom(clientLeft, *renderer).toDouble(), renderer->document());
738     }
739     return 0;
740 }
741
742 double Element::clientTop()
743 {
744     document().updateLayoutIgnorePendingStylesheets();
745
746     if (RenderBox* renderer = renderBox()) {
747         LayoutUnit clientTop = subpixelMetricsEnabled(renderer->document()) ? renderer->clientTop() : LayoutUnit(roundToInt(renderer->clientTop()));
748         return convertToNonSubpixelValueIfNeeded(adjustLayoutUnitForAbsoluteZoom(clientTop, *renderer).toDouble(), renderer->document());
749     }
750     return 0;
751 }
752
753 double Element::clientWidth()
754 {
755     document().updateLayoutIgnorePendingStylesheets();
756
757     if (!document().hasLivingRenderTree())
758         return 0;
759     RenderView& renderView = *document().renderView();
760
761     // When in strict mode, clientWidth for the document element should return the width of the containing frame.
762     // When in quirks mode, clientWidth for the body element should return the width of the containing frame.
763     bool inQuirksMode = document().inQuirksMode();
764     if ((!inQuirksMode && document().documentElement() == this) || (inQuirksMode && isHTMLElement() && document().body() == this))
765         return adjustForAbsoluteZoom(renderView.frameView().layoutWidth(), renderView);
766     
767     if (RenderBox* renderer = renderBox()) {
768         LayoutUnit clientWidth = subpixelMetricsEnabled(renderer->document()) ? renderer->clientWidth() : LayoutUnit(renderer->pixelSnappedClientWidth());
769         return convertToNonSubpixelValueIfNeeded(adjustLayoutUnitForAbsoluteZoom(clientWidth, *renderer).toDouble(), renderer->document());
770     }
771     return 0;
772 }
773
774 double Element::clientHeight()
775 {
776     document().updateLayoutIgnorePendingStylesheets();
777
778     if (!document().hasLivingRenderTree())
779         return 0;
780     RenderView& renderView = *document().renderView();
781
782     // When in strict mode, clientHeight for the document element should return the height of the containing frame.
783     // When in quirks mode, clientHeight for the body element should return the height of the containing frame.
784     bool inQuirksMode = document().inQuirksMode();
785     if ((!inQuirksMode && document().documentElement() == this) || (inQuirksMode && isHTMLElement() && document().body() == this))
786         return adjustForAbsoluteZoom(renderView.frameView().layoutHeight(), renderView);
787
788     if (RenderBox* renderer = renderBox()) {
789         LayoutUnit clientHeight = subpixelMetricsEnabled(renderer->document()) ? renderer->clientHeight() : LayoutUnit(renderer->pixelSnappedClientHeight());
790         return convertToNonSubpixelValueIfNeeded(adjustLayoutUnitForAbsoluteZoom(clientHeight, *renderer).toDouble(), renderer->document());
791     }
792     return 0;
793 }
794
795 int Element::scrollLeft()
796 {
797     document().updateLayoutIgnorePendingStylesheets();
798
799     if (RenderBox* rend = renderBox())
800         return adjustForAbsoluteZoom(rend->scrollLeft(), *rend);
801     return 0;
802 }
803
804 int Element::scrollTop()
805 {
806     document().updateLayoutIgnorePendingStylesheets();
807
808     if (RenderBox* rend = renderBox())
809         return adjustForAbsoluteZoom(rend->scrollTop(), *rend);
810     return 0;
811 }
812
813 void Element::setScrollLeft(int newLeft)
814 {
815     document().updateLayoutIgnorePendingStylesheets();
816
817     if (RenderBox* renderer = renderBox()) {
818         renderer->setScrollLeft(static_cast<int>(newLeft * renderer->style().effectiveZoom()));
819         if (auto* scrollableArea = renderer->layer())
820             scrollableArea->setScrolledProgrammatically(true);
821     }
822 }
823
824 void Element::setScrollTop(int newTop)
825 {
826     document().updateLayoutIgnorePendingStylesheets();
827
828     if (RenderBox* renderer = renderBox()) {
829         renderer->setScrollTop(static_cast<int>(newTop * renderer->style().effectiveZoom()));
830         if (auto* scrollableArea = renderer->layer())
831             scrollableArea->setScrolledProgrammatically(true);
832     }
833 }
834
835 int Element::scrollWidth()
836 {
837     document().updateLayoutIgnorePendingStylesheets();
838     if (RenderBox* rend = renderBox())
839         return adjustForAbsoluteZoom(rend->scrollWidth(), *rend);
840     return 0;
841 }
842
843 int Element::scrollHeight()
844 {
845     document().updateLayoutIgnorePendingStylesheets();
846     if (RenderBox* rend = renderBox())
847         return adjustForAbsoluteZoom(rend->scrollHeight(), *rend);
848     return 0;
849 }
850
851 IntRect Element::boundsInRootViewSpace()
852 {
853     document().updateLayoutIgnorePendingStylesheets();
854
855     FrameView* view = document().view();
856     if (!view)
857         return IntRect();
858
859     Vector<FloatQuad> quads;
860
861     if (isSVGElement() && renderer()) {
862         // Get the bounding rectangle from the SVG model.
863         SVGElement& svgElement = downcast<SVGElement>(*this);
864         FloatRect localRect;
865         if (svgElement.getBoundingBox(localRect))
866             quads.append(renderer()->localToAbsoluteQuad(localRect));
867     } else {
868         // Get the bounding rectangle from the box model.
869         if (renderBoxModelObject())
870             renderBoxModelObject()->absoluteQuads(quads);
871     }
872
873     if (quads.isEmpty())
874         return IntRect();
875
876     IntRect result = quads[0].enclosingBoundingBox();
877     for (size_t i = 1; i < quads.size(); ++i)
878         result.unite(quads[i].enclosingBoundingBox());
879
880     result = view->contentsToRootView(result);
881     return result;
882 }
883
884 PassRefPtr<ClientRectList> Element::getClientRects()
885 {
886     document().updateLayoutIgnorePendingStylesheets();
887
888     RenderBoxModelObject* renderBoxModelObject = this->renderBoxModelObject();
889     if (!renderBoxModelObject)
890         return ClientRectList::create();
891
892     // FIXME: Handle SVG elements.
893     // FIXME: Handle table/inline-table with a caption.
894
895     Vector<FloatQuad> quads;
896     renderBoxModelObject->absoluteQuads(quads);
897     document().adjustFloatQuadsForScrollAndAbsoluteZoomAndFrameScale(quads, renderBoxModelObject->style());
898     return ClientRectList::create(quads);
899 }
900
901 PassRefPtr<ClientRect> Element::getBoundingClientRect()
902 {
903     document().updateLayoutIgnorePendingStylesheets();
904
905     Vector<FloatQuad> quads;
906     if (isSVGElement() && renderer() && !renderer()->isSVGRoot()) {
907         // Get the bounding rectangle from the SVG model.
908         SVGElement& svgElement = downcast<SVGElement>(*this);
909         FloatRect localRect;
910         if (svgElement.getBoundingBox(localRect))
911             quads.append(renderer()->localToAbsoluteQuad(localRect));
912     } else {
913         // Get the bounding rectangle from the box model.
914         if (renderBoxModelObject())
915             renderBoxModelObject()->absoluteQuads(quads);
916     }
917
918     if (quads.isEmpty())
919         return ClientRect::create();
920
921     FloatRect result = quads[0].boundingBox();
922     for (size_t i = 1; i < quads.size(); ++i)
923         result.unite(quads[i].boundingBox());
924
925     document().adjustFloatRectForScrollAndAbsoluteZoomAndFrameScale(result, renderer()->style());
926     return ClientRect::create(result);
927 }
928
929 IntRect Element::clientRect() const
930 {
931     if (RenderObject* renderer = this->renderer())
932         return document().view()->contentsToRootView(renderer->absoluteBoundingBoxRect());
933     return IntRect();
934 }
935     
936 IntRect Element::screenRect() const
937 {
938     if (RenderObject* renderer = this->renderer())
939         return document().view()->contentsToScreen(renderer->absoluteBoundingBoxRect());
940     return IntRect();
941 }
942
943 const AtomicString& Element::getAttribute(const AtomicString& localName) const
944 {
945     if (!elementData())
946         return nullAtom;
947     synchronizeAttribute(localName);
948     if (const Attribute* attribute = elementData()->findAttributeByName(localName, shouldIgnoreAttributeCase(*this)))
949         return attribute->value();
950     return nullAtom;
951 }
952
953 const AtomicString& Element::getAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const
954 {
955     return getAttribute(QualifiedName(nullAtom, localName, namespaceURI));
956 }
957
958 void Element::setAttribute(const AtomicString& localName, const AtomicString& value, ExceptionCode& ec)
959 {
960     if (!Document::isValidName(localName)) {
961         ec = INVALID_CHARACTER_ERR;
962         return;
963     }
964
965     synchronizeAttribute(localName);
966     const AtomicString& caseAdjustedLocalName = shouldIgnoreAttributeCase(*this) ? localName.lower() : localName;
967
968     unsigned index = elementData() ? elementData()->findAttributeIndexByName(caseAdjustedLocalName, false) : ElementData::attributeNotFound;
969     const QualifiedName& qName = index != ElementData::attributeNotFound ? attributeAt(index).name() : QualifiedName(nullAtom, caseAdjustedLocalName, nullAtom);
970     setAttributeInternal(index, qName, value, NotInSynchronizationOfLazyAttribute);
971 }
972
973 void Element::setAttribute(const QualifiedName& name, const AtomicString& value)
974 {
975     synchronizeAttribute(name);
976     unsigned index = elementData() ? elementData()->findAttributeIndexByName(name) : ElementData::attributeNotFound;
977     setAttributeInternal(index, name, value, NotInSynchronizationOfLazyAttribute);
978 }
979
980 void Element::setAttributeWithoutSynchronization(const QualifiedName& name, const AtomicString& value)
981 {
982     unsigned index = elementData() ? elementData()->findAttributeIndexByName(name) : ElementData::attributeNotFound;
983     setAttributeInternal(index, name, value, NotInSynchronizationOfLazyAttribute);
984 }
985
986 void Element::setSynchronizedLazyAttribute(const QualifiedName& name, const AtomicString& value)
987 {
988     unsigned index = elementData() ? elementData()->findAttributeIndexByName(name) : ElementData::attributeNotFound;
989     setAttributeInternal(index, name, value, InSynchronizationOfLazyAttribute);
990 }
991
992 inline void Element::setAttributeInternal(unsigned index, const QualifiedName& name, const AtomicString& newValue, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
993 {
994     if (newValue.isNull()) {
995         if (index != ElementData::attributeNotFound)
996             removeAttributeInternal(index, inSynchronizationOfLazyAttribute);
997         return;
998     }
999
1000     if (index == ElementData::attributeNotFound) {
1001         addAttributeInternal(name, newValue, inSynchronizationOfLazyAttribute);
1002         return;
1003     }
1004
1005     const Attribute& attribute = attributeAt(index);
1006     AtomicString oldValue = attribute.value();
1007     bool valueChanged = newValue != oldValue;
1008     QualifiedName attributeName = (!inSynchronizationOfLazyAttribute || valueChanged) ? attribute.name() : name;
1009
1010     if (!inSynchronizationOfLazyAttribute)
1011         willModifyAttribute(attributeName, oldValue, newValue);
1012
1013     if (valueChanged) {
1014         // If there is an Attr node hooked to this attribute, the Attr::setValue() call below
1015         // will write into the ElementData.
1016         // FIXME: Refactor this so it makes some sense.
1017         if (RefPtr<Attr> attrNode = inSynchronizationOfLazyAttribute ? 0 : attrIfExists(attributeName))
1018             attrNode->setValue(newValue);
1019         else
1020             ensureUniqueElementData().attributeAt(index).setValue(newValue);
1021     }
1022
1023     if (!inSynchronizationOfLazyAttribute)
1024         didModifyAttribute(attributeName, oldValue, newValue);
1025 }
1026
1027 static inline AtomicString makeIdForStyleResolution(const AtomicString& value, bool inQuirksMode)
1028 {
1029     if (inQuirksMode)
1030         return value.lower();
1031     return value;
1032 }
1033
1034 static bool checkNeedsStyleInvalidationForIdChange(const AtomicString& oldId, const AtomicString& newId, StyleResolver* styleResolver)
1035 {
1036     ASSERT(newId != oldId);
1037     if (!oldId.isEmpty() && styleResolver->hasSelectorForId(oldId))
1038         return true;
1039     if (!newId.isEmpty() && styleResolver->hasSelectorForId(newId))
1040         return true;
1041     return false;
1042 }
1043
1044 void Element::attributeChanged(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason)
1045 {
1046     parseAttribute(name, newValue);
1047
1048     document().incDOMTreeVersion();
1049
1050     if (oldValue == newValue)
1051         return;
1052
1053     StyleResolver* styleResolver = document().styleResolverIfExists();
1054     bool testShouldInvalidateStyle = inRenderedDocument() && styleResolver && styleChangeType() < FullStyleChange;
1055     bool shouldInvalidateStyle = false;
1056
1057     if (name == HTMLNames::idAttr) {
1058         AtomicString oldId = elementData()->idForStyleResolution();
1059         AtomicString newId = makeIdForStyleResolution(newValue, document().inQuirksMode());
1060         if (newId != oldId) {
1061             elementData()->setIdForStyleResolution(newId);
1062             shouldInvalidateStyle = testShouldInvalidateStyle && checkNeedsStyleInvalidationForIdChange(oldId, newId, styleResolver);
1063         }
1064     } else if (name == classAttr)
1065         classAttributeChanged(newValue);
1066     else if (name == HTMLNames::nameAttr)
1067         elementData()->setHasNameAttribute(!newValue.isNull());
1068     else if (name == HTMLNames::pseudoAttr)
1069         shouldInvalidateStyle |= testShouldInvalidateStyle && isInShadowTree();
1070
1071
1072     invalidateNodeListAndCollectionCachesInAncestors(&name, this);
1073
1074     // If there is currently no StyleResolver, we can't be sure that this attribute change won't affect style.
1075     shouldInvalidateStyle |= !styleResolver;
1076
1077     if (shouldInvalidateStyle)
1078         setNeedsStyleRecalc();
1079
1080     if (AXObjectCache* cache = document().existingAXObjectCache())
1081         cache->handleAttributeChanged(name, this);
1082 }
1083
1084 template <typename CharacterType>
1085 static inline bool classStringHasClassName(const CharacterType* characters, unsigned length)
1086 {
1087     ASSERT(length > 0);
1088
1089     unsigned i = 0;
1090     do {
1091         if (isNotHTMLSpace(characters[i]))
1092             break;
1093         ++i;
1094     } while (i < length);
1095
1096     return i < length;
1097 }
1098
1099 static inline bool classStringHasClassName(const AtomicString& newClassString)
1100 {
1101     unsigned length = newClassString.length();
1102
1103     if (!length)
1104         return false;
1105
1106     if (newClassString.is8Bit())
1107         return classStringHasClassName(newClassString.characters8(), length);
1108     return classStringHasClassName(newClassString.characters16(), length);
1109 }
1110
1111 static bool checkSelectorForClassChange(const SpaceSplitString& changedClasses, const StyleResolver& styleResolver)
1112 {
1113     unsigned changedSize = changedClasses.size();
1114     for (unsigned i = 0; i < changedSize; ++i) {
1115         if (styleResolver.hasSelectorForClass(changedClasses[i]))
1116             return true;
1117     }
1118     return false;
1119 }
1120
1121 static bool checkSelectorForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, const StyleResolver& styleResolver)
1122 {
1123     unsigned oldSize = oldClasses.size();
1124     if (!oldSize)
1125         return checkSelectorForClassChange(newClasses, styleResolver);
1126     BitVector remainingClassBits;
1127     remainingClassBits.ensureSize(oldSize);
1128     // Class vectors tend to be very short. This is faster than using a hash table.
1129     unsigned newSize = newClasses.size();
1130     for (unsigned i = 0; i < newSize; ++i) {
1131         bool foundFromBoth = false;
1132         for (unsigned j = 0; j < oldSize; ++j) {
1133             if (newClasses[i] == oldClasses[j]) {
1134                 remainingClassBits.quickSet(j);
1135                 foundFromBoth = true;
1136             }
1137         }
1138         if (foundFromBoth)
1139             continue;
1140         if (styleResolver.hasSelectorForClass(newClasses[i]))
1141             return true;
1142     }
1143     for (unsigned i = 0; i < oldSize; ++i) {
1144         // If the bit is not set the the corresponding class has been removed.
1145         if (remainingClassBits.quickGet(i))
1146             continue;
1147         if (styleResolver.hasSelectorForClass(oldClasses[i]))
1148             return true;
1149     }
1150     return false;
1151 }
1152
1153 void Element::classAttributeChanged(const AtomicString& newClassString)
1154 {
1155     StyleResolver* styleResolver = document().styleResolverIfExists();
1156     bool testShouldInvalidateStyle = inRenderedDocument() && styleResolver && styleChangeType() < FullStyleChange;
1157     bool shouldInvalidateStyle = false;
1158
1159     if (classStringHasClassName(newClassString)) {
1160         const bool shouldFoldCase = document().inQuirksMode();
1161         // Note: We'll need ElementData, but it doesn't have to be UniqueElementData.
1162         if (!elementData())
1163             ensureUniqueElementData();
1164         const SpaceSplitString oldClasses = elementData()->classNames();
1165         elementData()->setClass(newClassString, shouldFoldCase);
1166         const SpaceSplitString& newClasses = elementData()->classNames();
1167         shouldInvalidateStyle = testShouldInvalidateStyle && checkSelectorForClassChange(oldClasses, newClasses, *styleResolver);
1168     } else if (elementData()) {
1169         const SpaceSplitString& oldClasses = elementData()->classNames();
1170         shouldInvalidateStyle = testShouldInvalidateStyle && checkSelectorForClassChange(oldClasses, *styleResolver);
1171         elementData()->clearClass();
1172     }
1173
1174     if (hasRareData())
1175         elementRareData()->clearClassListValueForQuirksMode();
1176
1177     if (shouldInvalidateStyle)
1178         setNeedsStyleRecalc();
1179 }
1180
1181 URL Element::absoluteLinkURL() const
1182 {
1183     if (!isLink())
1184         return URL();
1185
1186     AtomicString linkAttribute;
1187     if (hasTagName(SVGNames::aTag))
1188         linkAttribute = getAttribute(XLinkNames::hrefAttr);
1189     else
1190         linkAttribute = getAttribute(HTMLNames::hrefAttr);
1191
1192     if (linkAttribute.isEmpty())
1193         return URL();
1194
1195     return document().completeURL(stripLeadingAndTrailingHTMLSpaces(linkAttribute));
1196 }
1197
1198 WeakPtr<Element> Element::createWeakPtr()
1199 {
1200     return ensureElementRareData().weakPtrFactory().createWeakPtr();
1201 }
1202
1203 // Returns true is the given attribute is an event handler.
1204 // We consider an event handler any attribute that begins with "on".
1205 // It is a simple solution that has the advantage of not requiring any
1206 // code or configuration change if a new event handler is defined.
1207
1208 static inline bool isEventHandlerAttribute(const Attribute& attribute)
1209 {
1210     return attribute.name().namespaceURI().isNull() && attribute.name().localName().startsWith("on");
1211 }
1212
1213 bool Element::isJavaScriptURLAttribute(const Attribute& attribute) const
1214 {
1215     return isURLAttribute(attribute) && protocolIsJavaScript(stripLeadingAndTrailingHTMLSpaces(attribute.value()));
1216 }
1217
1218 void Element::stripScriptingAttributes(Vector<Attribute>& attributeVector) const
1219 {
1220     size_t destination = 0;
1221     for (size_t source = 0; source < attributeVector.size(); ++source) {
1222         if (isEventHandlerAttribute(attributeVector[source])
1223             || isJavaScriptURLAttribute(attributeVector[source])
1224             || isHTMLContentAttribute(attributeVector[source]))
1225             continue;
1226
1227         if (source != destination)
1228             attributeVector[destination] = attributeVector[source];
1229
1230         ++destination;
1231     }
1232     attributeVector.shrink(destination);
1233 }
1234
1235 void Element::parserSetAttributes(const Vector<Attribute>& attributeVector)
1236 {
1237     ASSERT(!inDocument());
1238     ASSERT(!parentNode());
1239     ASSERT(!m_elementData);
1240
1241     if (!attributeVector.isEmpty()) {
1242         if (document().sharedObjectPool())
1243             m_elementData = document().sharedObjectPool()->cachedShareableElementDataWithAttributes(attributeVector);
1244         else
1245             m_elementData = ShareableElementData::createWithAttributes(attributeVector);
1246
1247     }
1248
1249     parserDidSetAttributes();
1250
1251     // Use attributeVector instead of m_elementData because attributeChanged might modify m_elementData.
1252     for (const auto& attribute : attributeVector)
1253         attributeChanged(attribute.name(), nullAtom, attribute.value(), ModifiedDirectly);
1254 }
1255
1256 void Element::parserDidSetAttributes()
1257 {
1258 }
1259
1260 bool Element::hasAttributes() const
1261 {
1262     synchronizeAllAttributes();
1263     return elementData() && elementData()->length();
1264 }
1265
1266 bool Element::hasEquivalentAttributes(const Element* other) const
1267 {
1268     synchronizeAllAttributes();
1269     other->synchronizeAllAttributes();
1270     if (elementData() == other->elementData())
1271         return true;
1272     if (elementData())
1273         return elementData()->isEquivalent(other->elementData());
1274     if (other->elementData())
1275         return other->elementData()->isEquivalent(elementData());
1276     return true;
1277 }
1278
1279 String Element::nodeName() const
1280 {
1281     return m_tagName.toString();
1282 }
1283
1284 String Element::nodeNamePreservingCase() const
1285 {
1286     return m_tagName.toString();
1287 }
1288
1289 void Element::setPrefix(const AtomicString& prefix, ExceptionCode& ec)
1290 {
1291     ec = 0;
1292     checkSetPrefix(prefix, ec);
1293     if (ec)
1294         return;
1295
1296     m_tagName.setPrefix(prefix.isEmpty() ? AtomicString() : prefix);
1297 }
1298
1299 URL Element::baseURI() const
1300 {
1301     const AtomicString& baseAttribute = getAttribute(baseAttr);
1302     URL base(URL(), baseAttribute);
1303     if (!base.protocol().isEmpty())
1304         return base;
1305
1306     ContainerNode* parent = parentNode();
1307     if (!parent)
1308         return base;
1309
1310     const URL& parentBase = parent->baseURI();
1311     if (parentBase.isNull())
1312         return base;
1313
1314     return URL(parentBase, baseAttribute);
1315 }
1316
1317 const AtomicString& Element::imageSourceURL() const
1318 {
1319     return fastGetAttribute(srcAttr);
1320 }
1321
1322 bool Element::rendererIsNeeded(const RenderStyle& style)
1323 {
1324     return style.display() != NONE;
1325 }
1326
1327 RenderPtr<RenderElement> Element::createElementRenderer(PassRef<RenderStyle> style)
1328 {
1329     return RenderElement::createFor(*this, WTF::move(style));
1330 }
1331
1332 Node::InsertionNotificationRequest Element::insertedInto(ContainerNode& insertionPoint)
1333 {
1334     bool wasInDocument = inDocument();
1335     // need to do superclass processing first so inDocument() is true
1336     // by the time we reach updateId
1337     ContainerNode::insertedInto(insertionPoint);
1338     ASSERT(!wasInDocument || inDocument());
1339
1340 #if ENABLE(FULLSCREEN_API)
1341     if (containsFullScreenElement() && parentElement() && !parentElement()->containsFullScreenElement())
1342         setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(true);
1343 #endif
1344
1345     if (!insertionPoint.isInTreeScope())
1346         return InsertionDone;
1347
1348     if (hasRareData())
1349         elementRareData()->clearClassListValueForQuirksMode();
1350
1351     TreeScope* newScope = &insertionPoint.treeScope();
1352     HTMLDocument* newDocument = !wasInDocument && inDocument() && is<HTMLDocument>(newScope->documentScope()) ? &downcast<HTMLDocument>(newScope->documentScope()) : nullptr;
1353     if (newScope != &treeScope())
1354         newScope = nullptr;
1355
1356     const AtomicString& idValue = getIdAttribute();
1357     if (!idValue.isNull()) {
1358         if (newScope)
1359             updateIdForTreeScope(*newScope, nullAtom, idValue);
1360         if (newDocument)
1361             updateIdForDocument(*newDocument, nullAtom, idValue, AlwaysUpdateHTMLDocumentNamedItemMaps);
1362     }
1363
1364     const AtomicString& nameValue = getNameAttribute();
1365     if (!nameValue.isNull()) {
1366         if (newScope)
1367             updateNameForTreeScope(*newScope, nullAtom, nameValue);
1368         if (newDocument)
1369             updateNameForDocument(*newDocument, nullAtom, nameValue);
1370     }
1371
1372     if (newScope && hasTagName(labelTag)) {
1373         if (newScope->shouldCacheLabelsByForAttribute())
1374             updateLabel(*newScope, nullAtom, fastGetAttribute(forAttr));
1375     }
1376
1377     return InsertionDone;
1378 }
1379
1380 void Element::removedFrom(ContainerNode& insertionPoint)
1381 {
1382 #if ENABLE(FULLSCREEN_API)
1383     if (containsFullScreenElement())
1384         setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false);
1385 #endif
1386 #if ENABLE(POINTER_LOCK)
1387     if (document().page())
1388         document().page()->pointerLockController().elementRemoved(this);
1389 #endif
1390
1391     setSavedLayerScrollOffset(IntSize());
1392
1393     if (insertionPoint.isInTreeScope()) {
1394         TreeScope* oldScope = &insertionPoint.treeScope();
1395         HTMLDocument* oldDocument = inDocument() && is<HTMLDocument>(oldScope->documentScope()) ? &downcast<HTMLDocument>(oldScope->documentScope()) : nullptr;
1396         if (oldScope != &treeScope() || !isInTreeScope())
1397             oldScope = nullptr;
1398
1399         const AtomicString& idValue = getIdAttribute();
1400         if (!idValue.isNull()) {
1401             if (oldScope)
1402                 updateIdForTreeScope(*oldScope, idValue, nullAtom);
1403             if (oldDocument)
1404                 updateIdForDocument(*oldDocument, idValue, nullAtom, AlwaysUpdateHTMLDocumentNamedItemMaps);
1405         }
1406
1407         const AtomicString& nameValue = getNameAttribute();
1408         if (!nameValue.isNull()) {
1409             if (oldScope)
1410                 updateNameForTreeScope(*oldScope, nameValue, nullAtom);
1411             if (oldDocument)
1412                 updateNameForDocument(*oldDocument, nameValue, nullAtom);
1413         }
1414
1415         if (oldScope && hasTagName(labelTag)) {
1416             if (oldScope->shouldCacheLabelsByForAttribute())
1417                 updateLabel(*oldScope, fastGetAttribute(forAttr), nullAtom);
1418         }
1419     }
1420
1421     ContainerNode::removedFrom(insertionPoint);
1422
1423     if (hasPendingResources())
1424         document().accessSVGExtensions().removeElementFromPendingResources(this);
1425 }
1426
1427 void Element::unregisterNamedFlowContentElement()
1428 {
1429     if (document().cssRegionsEnabled() && isNamedFlowContentNode() && document().renderView())
1430         document().renderView()->flowThreadController().unregisterNamedFlowContentElement(*this);
1431 }
1432
1433 ShadowRoot* Element::shadowRoot() const
1434 {
1435     return hasRareData() ? elementRareData()->shadowRoot() : 0;
1436 }
1437
1438 static bool shouldUseNodeRenderingTraversalSlowPath(const Element& element)
1439 {
1440     if (element.isShadowRoot())
1441         return true;
1442     return element.isInsertionPoint() || element.shadowRoot();
1443 }
1444
1445 void Element::resetNeedsNodeRenderingTraversalSlowPath()
1446 {
1447     setNeedsNodeRenderingTraversalSlowPath(shouldUseNodeRenderingTraversalSlowPath(*this));
1448 }
1449
1450 void Element::addShadowRoot(PassRefPtr<ShadowRoot> newShadowRoot)
1451 {
1452     ASSERT(!shadowRoot());
1453
1454     ShadowRoot* shadowRoot = newShadowRoot.get();
1455     ensureElementRareData().setShadowRoot(newShadowRoot);
1456
1457     shadowRoot->setHostElement(this);
1458     shadowRoot->setParentTreeScope(&treeScope());
1459     shadowRoot->distributor().didShadowBoundaryChange(this);
1460
1461     ChildNodeInsertionNotifier(*this).notify(*shadowRoot);
1462
1463     resetNeedsNodeRenderingTraversalSlowPath();
1464
1465     setNeedsStyleRecalc(ReconstructRenderTree);
1466
1467     InspectorInstrumentation::didPushShadowRoot(this, shadowRoot);
1468 }
1469
1470 void Element::removeShadowRoot()
1471 {
1472     RefPtr<ShadowRoot> oldRoot = shadowRoot();
1473     if (!oldRoot)
1474         return;
1475     InspectorInstrumentation::willPopShadowRoot(this, oldRoot.get());
1476     document().removeFocusedNodeOfSubtree(oldRoot.get());
1477
1478     ASSERT(!oldRoot->renderer());
1479
1480     elementRareData()->clearShadowRoot();
1481
1482     oldRoot->setHostElement(0);
1483     oldRoot->setParentTreeScope(&document());
1484
1485     ChildNodeRemovalNotifier(*this).notify(*oldRoot);
1486
1487     oldRoot->distributor().invalidateDistribution(this);
1488 }
1489
1490 PassRefPtr<ShadowRoot> Element::createShadowRoot(ExceptionCode& ec)
1491 {
1492     if (alwaysCreateUserAgentShadowRoot())
1493         ensureUserAgentShadowRoot();
1494
1495     ec = HIERARCHY_REQUEST_ERR;
1496     return nullptr;
1497 }
1498
1499 ShadowRoot* Element::userAgentShadowRoot() const
1500 {
1501     if (ShadowRoot* shadowRoot = this->shadowRoot()) {
1502         ASSERT(shadowRoot->type() == ShadowRoot::UserAgentShadowRoot);
1503         return shadowRoot;
1504     }
1505     return nullptr;
1506 }
1507
1508 ShadowRoot& Element::ensureUserAgentShadowRoot()
1509 {
1510     ShadowRoot* shadowRoot = userAgentShadowRoot();
1511     if (!shadowRoot) {
1512         addShadowRoot(ShadowRoot::create(document(), ShadowRoot::UserAgentShadowRoot));
1513         shadowRoot = userAgentShadowRoot();
1514         didAddUserAgentShadowRoot(shadowRoot);
1515     }
1516     return *shadowRoot;
1517 }
1518
1519 const AtomicString& Element::shadowPseudoId() const
1520 {
1521     return pseudo();
1522 }
1523
1524 bool Element::childTypeAllowed(NodeType type) const
1525 {
1526     switch (type) {
1527     case ELEMENT_NODE:
1528     case TEXT_NODE:
1529     case COMMENT_NODE:
1530     case PROCESSING_INSTRUCTION_NODE:
1531     case CDATA_SECTION_NODE:
1532     case ENTITY_REFERENCE_NODE:
1533         return true;
1534     default:
1535         break;
1536     }
1537     return false;
1538 }
1539
1540 static void checkForEmptyStyleChange(Element& element)
1541 {
1542     if (element.styleAffectedByEmpty()) {
1543         RenderStyle* style = element.renderStyle();
1544         if (!style || (!style->emptyState() || element.hasChildNodes()))
1545             element.setNeedsStyleRecalc();
1546     }
1547 }
1548
1549 enum SiblingCheckType { FinishedParsingChildren, SiblingElementRemoved, Other };
1550
1551 static void checkForSiblingStyleChanges(Element* parent, SiblingCheckType checkType, Element* elementBeforeChange, Element* elementAfterChange)
1552 {
1553     // :empty selector.
1554     checkForEmptyStyleChange(*parent);
1555
1556     if (parent->styleChangeType() >= FullStyleChange)
1557         return;
1558
1559     // :first-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
1560     // In the DOM case, we only need to do something if |afterChange| is not 0.
1561     // |afterChange| is 0 in the parser case, so it works out that we'll skip this block.
1562     if (parent->childrenAffectedByFirstChildRules() && elementAfterChange) {
1563         // Find our new first child.
1564         Element* newFirstElement = ElementTraversal::firstChild(parent);
1565         // Find the first element node following |afterChange|
1566
1567         // This is the insert/append case.
1568         if (newFirstElement != elementAfterChange) {
1569             RenderStyle* style = elementAfterChange->renderStyle();
1570             if (!style || style->firstChildState())
1571                 elementAfterChange->setNeedsStyleRecalc();
1572         }
1573
1574         // We also have to handle node removal.
1575         if (checkType == SiblingElementRemoved && newFirstElement == elementAfterChange && newFirstElement) {
1576             RenderStyle* style = newFirstElement->renderStyle();
1577             if (!style || !style->firstChildState())
1578                 newFirstElement->setNeedsStyleRecalc();
1579         }
1580     }
1581
1582     // :last-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
1583     // In the DOM case, we only need to do something if |afterChange| is not 0.
1584     if (parent->childrenAffectedByLastChildRules() && elementBeforeChange) {
1585         // Find our new last child.
1586         Element* newLastElement = ElementTraversal::lastChild(parent);
1587
1588         if (newLastElement != elementBeforeChange) {
1589             RenderStyle* style = elementBeforeChange->renderStyle();
1590             if (!style || style->lastChildState())
1591                 elementBeforeChange->setNeedsStyleRecalc();
1592         }
1593
1594         // We also have to handle node removal.  The parser callback case is similar to node removal as well in that we need to change the last child
1595         // to match now.
1596         if ((checkType == SiblingElementRemoved || checkType == FinishedParsingChildren) && newLastElement == elementBeforeChange && newLastElement) {
1597             RenderStyle* style = newLastElement->renderStyle();
1598             if (!style || !style->lastChildState())
1599                 newLastElement->setNeedsStyleRecalc();
1600         }
1601     }
1602
1603     if (elementAfterChange) {
1604         if (elementAfterChange->styleIsAffectedByPreviousSibling())
1605             elementAfterChange->setNeedsStyleRecalc();
1606         else if (elementAfterChange->affectsNextSiblingElementStyle()) {
1607             Element* elementToInvalidate = elementAfterChange;
1608             do {
1609                 elementToInvalidate = elementToInvalidate->nextElementSibling();
1610             } while (elementToInvalidate && !elementToInvalidate->styleIsAffectedByPreviousSibling());
1611
1612             if (elementToInvalidate)
1613                 elementToInvalidate->setNeedsStyleRecalc();
1614         }
1615     }
1616
1617     // Backward positional selectors include nth-last-child, nth-last-of-type, last-of-type and only-of-type.
1618     // We have to invalidate everything following the insertion point in the forward case, and everything before the insertion point in the
1619     // backward case.
1620     // |afterChange| is 0 in the parser callback case, so we won't do any work for the forward case if we don't have to.
1621     // For performance reasons we just mark the parent node as changed, since we don't want to make childrenChanged O(n^2) by crawling all our kids
1622     // here.  recalcStyle will then force a walk of the children when it sees that this has happened.
1623     if (parent->childrenAffectedByBackwardPositionalRules() && elementBeforeChange)
1624         parent->setNeedsStyleRecalc();
1625 }
1626
1627 void Element::childrenChanged(const ChildChange& change)
1628 {
1629     ContainerNode::childrenChanged(change);
1630     if (change.source == ChildChangeSourceParser)
1631         checkForEmptyStyleChange(*this);
1632     else {
1633         SiblingCheckType checkType = change.type == ElementRemoved ? SiblingElementRemoved : Other;
1634         checkForSiblingStyleChanges(this, checkType, change.previousSiblingElement, change.nextSiblingElement);
1635     }
1636
1637     if (ShadowRoot* shadowRoot = this->shadowRoot())
1638         shadowRoot->invalidateDistribution();
1639 }
1640
1641 void Element::removeAllEventListeners()
1642 {
1643     ContainerNode::removeAllEventListeners();
1644     if (ShadowRoot* shadowRoot = this->shadowRoot())
1645         shadowRoot->removeAllEventListeners();
1646 }
1647
1648 void Element::beginParsingChildren()
1649 {
1650     clearIsParsingChildrenFinished();
1651     if (auto styleResolver = document().styleResolverIfExists())
1652         styleResolver->pushParentElement(this);
1653 }
1654
1655 void Element::finishParsingChildren()
1656 {
1657     ContainerNode::finishParsingChildren();
1658     setIsParsingChildrenFinished();
1659     checkForSiblingStyleChanges(this, FinishedParsingChildren, ElementTraversal::lastChild(this), nullptr);
1660     if (auto styleResolver = document().styleResolverIfExists())
1661         styleResolver->popParentElement(this);
1662 }
1663
1664 #ifndef NDEBUG
1665 void Element::formatForDebugger(char* buffer, unsigned length) const
1666 {
1667     StringBuilder result;
1668     String s;
1669
1670     result.append(nodeName());
1671
1672     s = getIdAttribute();
1673     if (s.length() > 0) {
1674         if (result.length() > 0)
1675             result.appendLiteral("; ");
1676         result.appendLiteral("id=");
1677         result.append(s);
1678     }
1679
1680     s = getAttribute(classAttr);
1681     if (s.length() > 0) {
1682         if (result.length() > 0)
1683             result.appendLiteral("; ");
1684         result.appendLiteral("class=");
1685         result.append(s);
1686     }
1687
1688     strncpy(buffer, result.toString().utf8().data(), length - 1);
1689 }
1690 #endif
1691
1692 const Vector<RefPtr<Attr>>& Element::attrNodeList()
1693 {
1694     ASSERT(hasSyntheticAttrChildNodes());
1695     return *attrNodeListForElement(*this);
1696 }
1697
1698 PassRefPtr<Attr> Element::setAttributeNode(Attr* attrNode, ExceptionCode& ec)
1699 {
1700     if (!attrNode) {
1701         ec = TYPE_MISMATCH_ERR;
1702         return 0;
1703     }
1704
1705     RefPtr<Attr> oldAttrNode = attrIfExists(attrNode->qualifiedName());
1706     if (oldAttrNode.get() == attrNode)
1707         return attrNode; // This Attr is already attached to the element.
1708
1709     // INUSE_ATTRIBUTE_ERR: Raised if node is an Attr that is already an attribute of another Element object.
1710     // The DOM user must explicitly clone Attr nodes to re-use them in other elements.
1711     if (attrNode->ownerElement()) {
1712         ec = INUSE_ATTRIBUTE_ERR;
1713         return 0;
1714     }
1715
1716     synchronizeAllAttributes();
1717     UniqueElementData& elementData = ensureUniqueElementData();
1718
1719     unsigned index = elementData.findAttributeIndexByNameForAttributeNode(attrNode, shouldIgnoreAttributeCase(*this));
1720     if (index != ElementData::attributeNotFound) {
1721         if (oldAttrNode)
1722             detachAttrNodeFromElementWithValue(oldAttrNode.get(), elementData.attributeAt(index).value());
1723         else
1724             oldAttrNode = Attr::create(document(), attrNode->qualifiedName(), elementData.attributeAt(index).value());
1725     }
1726
1727     setAttributeInternal(index, attrNode->qualifiedName(), attrNode->value(), NotInSynchronizationOfLazyAttribute);
1728
1729     attrNode->attachToElement(this);
1730     treeScope().adoptIfNeeded(attrNode);
1731     ensureAttrNodeListForElement(*this).append(attrNode);
1732
1733     return oldAttrNode.release();
1734 }
1735
1736 PassRefPtr<Attr> Element::setAttributeNodeNS(Attr* attr, ExceptionCode& ec)
1737 {
1738     return setAttributeNode(attr, ec);
1739 }
1740
1741 PassRefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionCode& ec)
1742 {
1743     if (!attr) {
1744         ec = TYPE_MISMATCH_ERR;
1745         return 0;
1746     }
1747     if (attr->ownerElement() != this) {
1748         ec = NOT_FOUND_ERR;
1749         return 0;
1750     }
1751
1752     ASSERT(&document() == &attr->document());
1753
1754     synchronizeAttribute(attr->qualifiedName());
1755
1756     unsigned index = elementData()->findAttributeIndexByNameForAttributeNode(attr);
1757     if (index == ElementData::attributeNotFound) {
1758         ec = NOT_FOUND_ERR;
1759         return 0;
1760     }
1761
1762     RefPtr<Attr> attrNode = attr;
1763     detachAttrNodeFromElementWithValue(attr, elementData()->attributeAt(index).value());
1764     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
1765     return attrNode.release();
1766 }
1767
1768 bool Element::parseAttributeName(QualifiedName& out, const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionCode& ec)
1769 {
1770     String prefix, localName;
1771     if (!Document::parseQualifiedName(qualifiedName, prefix, localName, ec))
1772         return false;
1773     ASSERT(!ec);
1774
1775     QualifiedName qName(prefix, localName, namespaceURI);
1776
1777     if (!Document::hasValidNamespaceForAttributes(qName)) {
1778         ec = NAMESPACE_ERR;
1779         return false;
1780     }
1781
1782     out = qName;
1783     return true;
1784 }
1785
1786 void Element::setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode& ec)
1787 {
1788     QualifiedName parsedName = anyName;
1789     if (!parseAttributeName(parsedName, namespaceURI, qualifiedName, ec))
1790         return;
1791     setAttribute(parsedName, value);
1792 }
1793
1794 void Element::removeAttributeInternal(unsigned index, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
1795 {
1796     ASSERT_WITH_SECURITY_IMPLICATION(index < attributeCount());
1797
1798     UniqueElementData& elementData = ensureUniqueElementData();
1799
1800     QualifiedName name = elementData.attributeAt(index).name();
1801     AtomicString valueBeingRemoved = elementData.attributeAt(index).value();
1802
1803     if (!inSynchronizationOfLazyAttribute) {
1804         if (!valueBeingRemoved.isNull())
1805             willModifyAttribute(name, valueBeingRemoved, nullAtom);
1806     }
1807
1808     if (RefPtr<Attr> attrNode = attrIfExists(name))
1809         detachAttrNodeFromElementWithValue(attrNode.get(), elementData.attributeAt(index).value());
1810
1811     elementData.removeAttribute(index);
1812
1813     if (!inSynchronizationOfLazyAttribute)
1814         didRemoveAttribute(name, valueBeingRemoved);
1815 }
1816
1817 void Element::addAttributeInternal(const QualifiedName& name, const AtomicString& value, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
1818 {
1819     if (!inSynchronizationOfLazyAttribute)
1820         willModifyAttribute(name, nullAtom, value);
1821     ensureUniqueElementData().addAttribute(name, value);
1822     if (!inSynchronizationOfLazyAttribute)
1823         didAddAttribute(name, value);
1824 }
1825
1826 bool Element::removeAttribute(const AtomicString& name)
1827 {
1828     if (!elementData())
1829         return false;
1830
1831     AtomicString localName = shouldIgnoreAttributeCase(*this) ? name.lower() : name;
1832     unsigned index = elementData()->findAttributeIndexByName(localName, false);
1833     if (index == ElementData::attributeNotFound) {
1834         if (UNLIKELY(localName == styleAttr) && elementData()->styleAttributeIsDirty() && is<StyledElement>(*this))
1835             downcast<StyledElement>(*this).removeAllInlineStyleProperties();
1836         return false;
1837     }
1838
1839     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
1840     return true;
1841 }
1842
1843 bool Element::removeAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName)
1844 {
1845     return removeAttribute(QualifiedName(nullAtom, localName, namespaceURI));
1846 }
1847
1848 PassRefPtr<Attr> Element::getAttributeNode(const AtomicString& localName)
1849 {
1850     if (!elementData())
1851         return 0;
1852     synchronizeAttribute(localName);
1853     const Attribute* attribute = elementData()->findAttributeByName(localName, shouldIgnoreAttributeCase(*this));
1854     if (!attribute)
1855         return 0;
1856     return ensureAttr(attribute->name());
1857 }
1858
1859 PassRefPtr<Attr> Element::getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName)
1860 {
1861     if (!elementData())
1862         return 0;
1863     QualifiedName qName(nullAtom, localName, namespaceURI);
1864     synchronizeAttribute(qName);
1865     const Attribute* attribute = elementData()->findAttributeByName(qName);
1866     if (!attribute)
1867         return 0;
1868     return ensureAttr(attribute->name());
1869 }
1870
1871 bool Element::hasAttribute(const AtomicString& localName) const
1872 {
1873     if (!elementData())
1874         return false;
1875     synchronizeAttribute(localName);
1876     return elementData()->findAttributeByName(shouldIgnoreAttributeCase(*this) ? localName.lower() : localName, false);
1877 }
1878
1879 bool Element::hasAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const
1880 {
1881     if (!elementData())
1882         return false;
1883     QualifiedName qName(nullAtom, localName, namespaceURI);
1884     synchronizeAttribute(qName);
1885     return elementData()->findAttributeByName(qName);
1886 }
1887
1888 CSSStyleDeclaration *Element::style()
1889 {
1890     return 0;
1891 }
1892
1893 void Element::focus(bool restorePreviousSelection, FocusDirection direction)
1894 {
1895     if (!inDocument())
1896         return;
1897
1898     if (document().focusedElement() == this)
1899         return;
1900
1901     // If the stylesheets have already been loaded we can reliably check isFocusable.
1902     // If not, we continue and set the focused node on the focus controller below so
1903     // that it can be updated soon after attach. 
1904     if (document().haveStylesheetsLoaded()) {
1905         document().updateLayoutIgnorePendingStylesheets();
1906         if (!isFocusable())
1907             return;
1908     }
1909
1910     if (!supportsFocus())
1911         return;
1912
1913     RefPtr<Node> protect;
1914     if (Page* page = document().page()) {
1915         // Focus and change event handlers can cause us to lose our last ref.
1916         // If a focus event handler changes the focus to a different node it
1917         // does not make sense to continue and update appearence.
1918         protect = this;
1919         if (!page->focusController().setFocusedElement(this, document().frame(), direction))
1920             return;
1921     }
1922
1923     // Setting the focused node above might have invalidated the layout due to scripts.
1924     document().updateLayoutIgnorePendingStylesheets();
1925
1926     if (!isFocusable()) {
1927         ensureElementRareData().setNeedsFocusAppearanceUpdateSoonAfterAttach(true);
1928         return;
1929     }
1930         
1931     cancelFocusAppearanceUpdate();
1932 #if PLATFORM(IOS)
1933     // Focusing a form element triggers animation in UIKit to scroll to the right position.
1934     // Calling updateFocusAppearance() would generate an unnecessary call to ScrollView::setScrollPosition(),
1935     // which would jump us around during this animation. See <rdar://problem/6699741>.
1936     FrameView* view = document().view();
1937     bool isFormControl = view && is<HTMLFormControlElement>(*this);
1938     if (isFormControl)
1939         view->setProhibitsScrolling(true);
1940 #endif
1941     updateFocusAppearance(restorePreviousSelection);
1942 #if PLATFORM(IOS)
1943     if (isFormControl)
1944         view->setProhibitsScrolling(false);
1945 #endif
1946 }
1947
1948 void Element::updateFocusAppearanceAfterAttachIfNeeded()
1949 {
1950     if (!hasRareData())
1951         return;
1952     ElementRareData* data = elementRareData();
1953     if (!data->needsFocusAppearanceUpdateSoonAfterAttach())
1954         return;
1955     if (isFocusable() && document().focusedElement() == this)
1956         document().updateFocusAppearanceSoon(false /* don't restore selection */);
1957     data->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
1958 }
1959
1960 void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
1961 {
1962     if (isRootEditableElement()) {
1963         Frame* frame = document().frame();
1964         if (!frame)
1965             return;
1966         
1967         // When focusing an editable element in an iframe, don't reset the selection if it already contains a selection.
1968         if (this == frame->selection().selection().rootEditableElement())
1969             return;
1970
1971         // FIXME: We should restore the previous selection if there is one.
1972         VisibleSelection newSelection = VisibleSelection(firstPositionInOrBeforeNode(this), DOWNSTREAM);
1973         
1974         if (frame->selection().shouldChangeSelection(newSelection)) {
1975             frame->selection().setSelection(newSelection);
1976             frame->selection().revealSelection();
1977         }
1978     } else if (renderer() && !renderer()->isWidget())
1979         renderer()->scrollRectToVisible(boundingBox());
1980 }
1981
1982 void Element::blur()
1983 {
1984     cancelFocusAppearanceUpdate();
1985     if (treeScope().focusedElement() == this) {
1986         if (Frame* frame = document().frame())
1987             frame->page()->focusController().setFocusedElement(0, frame);
1988         else
1989             document().setFocusedElement(0);
1990     }
1991 }
1992
1993 void Element::dispatchFocusInEvent(const AtomicString& eventType, PassRefPtr<Element> oldFocusedElement)
1994 {
1995     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
1996     ASSERT(eventType == eventNames().focusinEvent || eventType == eventNames().DOMFocusInEvent);
1997     dispatchScopedEvent(FocusEvent::create(eventType, true, false, document().defaultView(), 0, oldFocusedElement));
1998 }
1999
2000 void Element::dispatchFocusOutEvent(const AtomicString& eventType, PassRefPtr<Element> newFocusedElement)
2001 {
2002     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
2003     ASSERT(eventType == eventNames().focusoutEvent || eventType == eventNames().DOMFocusOutEvent);
2004     dispatchScopedEvent(FocusEvent::create(eventType, true, false, document().defaultView(), 0, newFocusedElement));
2005 }
2006
2007 void Element::dispatchFocusEvent(PassRefPtr<Element> oldFocusedElement, FocusDirection)
2008 {
2009     if (document().page())
2010         document().page()->chrome().client().elementDidFocus(this);
2011
2012     RefPtr<FocusEvent> event = FocusEvent::create(eventNames().focusEvent, false, false, document().defaultView(), 0, oldFocusedElement);
2013     EventDispatcher::dispatchEvent(this, event.release());
2014 }
2015
2016 void Element::dispatchBlurEvent(PassRefPtr<Element> newFocusedElement)
2017 {
2018     if (document().page())
2019         document().page()->chrome().client().elementDidBlur(this);
2020
2021     RefPtr<FocusEvent> event = FocusEvent::create(eventNames().blurEvent, false, false, document().defaultView(), 0, newFocusedElement);
2022     EventDispatcher::dispatchEvent(this, event.release());
2023 }
2024
2025
2026 String Element::innerText()
2027 {
2028     // We need to update layout, since plainText uses line boxes in the render tree.
2029     document().updateLayoutIgnorePendingStylesheets();
2030
2031     if (!renderer())
2032         return textContent(true);
2033
2034     return plainText(rangeOfContents(*this).get());
2035 }
2036
2037 String Element::outerText()
2038 {
2039     // Getting outerText is the same as getting innerText, only
2040     // setting is different. You would think this should get the plain
2041     // text for the outer range, but this is wrong, <br> for instance
2042     // would return different values for inner and outer text by such
2043     // a rule, but it doesn't in WinIE, and we want to match that.
2044     return innerText();
2045 }
2046
2047 String Element::title() const
2048 {
2049     return String();
2050 }
2051
2052 const AtomicString& Element::pseudo() const
2053 {
2054     return fastGetAttribute(pseudoAttr);
2055 }
2056
2057 void Element::setPseudo(const AtomicString& value)
2058 {
2059     setAttributeWithoutSynchronization(pseudoAttr, value);
2060 }
2061
2062 LayoutSize Element::minimumSizeForResizing() const
2063 {
2064     return hasRareData() ? elementRareData()->minimumSizeForResizing() : defaultMinimumSizeForResizing();
2065 }
2066
2067 void Element::setMinimumSizeForResizing(const LayoutSize& size)
2068 {
2069     if (!hasRareData() && size == defaultMinimumSizeForResizing())
2070         return;
2071     ensureElementRareData().setMinimumSizeForResizing(size);
2072 }
2073
2074 static PseudoElement* beforeOrAfterPseudoElement(Element* host, PseudoId pseudoElementSpecifier)
2075 {
2076     switch (pseudoElementSpecifier) {
2077     case BEFORE:
2078         return host->beforePseudoElement();
2079     case AFTER:
2080         return host->afterPseudoElement();
2081     default:
2082         return 0;
2083     }
2084 }
2085
2086 RenderStyle* Element::computedStyle(PseudoId pseudoElementSpecifier)
2087 {
2088     if (PseudoElement* pseudoElement = beforeOrAfterPseudoElement(this, pseudoElementSpecifier))
2089         return pseudoElement->computedStyle();
2090
2091     // FIXME: Find and use the renderer from the pseudo element instead of the actual element so that the 'length'
2092     // properties, which are only known by the renderer because it did the layout, will be correct and so that the
2093     // values returned for the ":selection" pseudo-element will be correct.
2094     if (RenderStyle* usedStyle = renderStyle()) {
2095         if (pseudoElementSpecifier) {
2096             RenderStyle* cachedPseudoStyle = usedStyle->getCachedPseudoStyle(pseudoElementSpecifier);
2097             return cachedPseudoStyle ? cachedPseudoStyle : usedStyle;
2098         }
2099         return usedStyle;
2100     }
2101
2102     if (!inDocument()) {
2103         // FIXME: Try to do better than this. Ensure that styleForElement() works for elements that are not in the
2104         // document tree and figure out when to destroy the computed style for such elements.
2105         return nullptr;
2106     }
2107
2108     ElementRareData& data = ensureElementRareData();
2109     if (!data.computedStyle())
2110         data.setComputedStyle(document().styleForElementIgnoringPendingStylesheets(this));
2111     return pseudoElementSpecifier ? data.computedStyle()->getCachedPseudoStyle(pseudoElementSpecifier) : data.computedStyle();
2112 }
2113
2114 void Element::setStyleAffectedByEmpty()
2115 {
2116     ensureElementRareData().setStyleAffectedByEmpty(true);
2117 }
2118
2119 void Element::setChildrenAffectedByActive()
2120 {
2121     ensureElementRareData().setChildrenAffectedByActive(true);
2122 }
2123
2124 void Element::setChildrenAffectedByDrag()
2125 {
2126     ensureElementRareData().setChildrenAffectedByDrag(true);
2127 }
2128
2129 void Element::setChildrenAffectedByBackwardPositionalRules()
2130 {
2131     ensureElementRareData().setChildrenAffectedByBackwardPositionalRules(true);
2132 }
2133
2134 void Element::setChildrenAffectedByPropertyBasedBackwardPositionalRules()
2135 {
2136     ensureElementRareData().setChildrenAffectedByPropertyBasedBackwardPositionalRules(true);
2137 }
2138
2139 void Element::setChildIndex(unsigned index)
2140 {
2141     ElementRareData& rareData = ensureElementRareData();
2142     if (RenderStyle* style = renderStyle())
2143         style->setUnique();
2144     rareData.setChildIndex(index);
2145 }
2146
2147 bool Element::hasFlagsSetDuringStylingOfChildren() const
2148 {
2149     if (childrenAffectedByHover() || childrenAffectedByFirstChildRules() || childrenAffectedByLastChildRules())
2150         return true;
2151
2152     if (!hasRareData())
2153         return false;
2154     return rareDataChildrenAffectedByActive()
2155         || rareDataChildrenAffectedByDrag()
2156         || rareDataChildrenAffectedByBackwardPositionalRules()
2157         || rareDataChildrenAffectedByPropertyBasedBackwardPositionalRules();
2158 }
2159
2160 bool Element::rareDataStyleAffectedByEmpty() const
2161 {
2162     ASSERT(hasRareData());
2163     return elementRareData()->styleAffectedByEmpty();
2164 }
2165
2166 bool Element::rareDataChildrenAffectedByActive() const
2167 {
2168     ASSERT(hasRareData());
2169     return elementRareData()->childrenAffectedByActive();
2170 }
2171
2172 bool Element::rareDataChildrenAffectedByDrag() const
2173 {
2174     ASSERT(hasRareData());
2175     return elementRareData()->childrenAffectedByDrag();
2176 }
2177
2178 bool Element::rareDataChildrenAffectedByBackwardPositionalRules() const
2179 {
2180     ASSERT(hasRareData());
2181     return elementRareData()->childrenAffectedByBackwardPositionalRules();
2182 }
2183
2184 bool Element::rareDataChildrenAffectedByPropertyBasedBackwardPositionalRules() const
2185 {
2186     ASSERT(hasRareData());
2187     return elementRareData()->childrenAffectedByPropertyBasedBackwardPositionalRules();
2188 }
2189
2190 unsigned Element::rareDataChildIndex() const
2191 {
2192     ASSERT(hasRareData());
2193     return elementRareData()->childIndex();
2194 }
2195
2196 void Element::setRegionOversetState(RegionOversetState state)
2197 {
2198     ensureElementRareData().setRegionOversetState(state);
2199 }
2200
2201 RegionOversetState Element::regionOversetState() const
2202 {
2203     return hasRareData() ? elementRareData()->regionOversetState() : RegionUndefined;
2204 }
2205
2206 AtomicString Element::computeInheritedLanguage() const
2207 {
2208     if (const ElementData* elementData = this->elementData()) {
2209         if (const Attribute* attribute = elementData->findLanguageAttribute())
2210             return attribute->value();
2211     }
2212
2213     // The language property is inherited, so we iterate over the parents to find the first language.
2214     const Node* currentNode = this;
2215     while ((currentNode = currentNode->parentNode())) {
2216         if (is<Element>(*currentNode)) {
2217             if (const ElementData* elementData = downcast<Element>(*currentNode).elementData()) {
2218                 if (const Attribute* attribute = elementData->findLanguageAttribute())
2219                     return attribute->value();
2220             }
2221         } else if (is<Document>(*currentNode)) {
2222             // checking the MIME content-language
2223             return downcast<Document>(*currentNode).contentLanguage();
2224         }
2225     }
2226
2227     return nullAtom;
2228 }
2229
2230 Locale& Element::locale() const
2231 {
2232     return document().getCachedLocale(computeInheritedLanguage());
2233 }
2234
2235 void Element::cancelFocusAppearanceUpdate()
2236 {
2237     if (hasRareData())
2238         elementRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
2239     if (document().focusedElement() == this)
2240         document().cancelFocusAppearanceUpdate();
2241 }
2242
2243 void Element::normalizeAttributes()
2244 {
2245     if (!hasAttributes())
2246         return;
2247     for (const Attribute& attribute : attributesIterator()) {
2248         if (RefPtr<Attr> attr = attrIfExists(attribute.name()))
2249             attr->normalize();
2250     }
2251 }
2252
2253 PseudoElement* Element::beforePseudoElement() const
2254 {
2255     return hasRareData() ? elementRareData()->beforePseudoElement() : 0;
2256 }
2257
2258 PseudoElement* Element::afterPseudoElement() const
2259 {
2260     return hasRareData() ? elementRareData()->afterPseudoElement() : 0;
2261 }
2262
2263 void Element::setBeforePseudoElement(PassRefPtr<PseudoElement> element)
2264 {
2265     ensureElementRareData().setBeforePseudoElement(element);
2266 }
2267
2268 void Element::setAfterPseudoElement(PassRefPtr<PseudoElement> element)
2269 {
2270     ensureElementRareData().setAfterPseudoElement(element);
2271 }
2272
2273 static void disconnectPseudoElement(PseudoElement* pseudoElement)
2274 {
2275     if (!pseudoElement)
2276         return;
2277     if (pseudoElement->renderer())
2278         Style::detachRenderTree(*pseudoElement);
2279     ASSERT(pseudoElement->hostElement());
2280     pseudoElement->clearHostElement();
2281 }
2282
2283 void Element::clearBeforePseudoElement()
2284 {
2285     if (!hasRareData())
2286         return;
2287     disconnectPseudoElement(elementRareData()->beforePseudoElement());
2288     elementRareData()->setBeforePseudoElement(nullptr);
2289 }
2290
2291 void Element::clearAfterPseudoElement()
2292 {
2293     if (!hasRareData())
2294         return;
2295     disconnectPseudoElement(elementRareData()->afterPseudoElement());
2296     elementRareData()->setAfterPseudoElement(nullptr);
2297 }
2298
2299 // ElementTraversal API
2300 Element* Element::firstElementChild() const
2301 {
2302     return ElementTraversal::firstChild(this);
2303 }
2304
2305 Element* Element::lastElementChild() const
2306 {
2307     return ElementTraversal::lastChild(this);
2308 }
2309
2310 Element* Element::previousElementSibling() const
2311 {
2312     return ElementTraversal::previousSibling(this);
2313 }
2314
2315 Element* Element::nextElementSibling() const
2316 {
2317     return ElementTraversal::nextSibling(this);
2318 }
2319
2320 unsigned Element::childElementCount() const
2321 {
2322     unsigned count = 0;
2323     Node* n = firstChild();
2324     while (n) {
2325         count += n->isElementNode();
2326         n = n->nextSibling();
2327     }
2328     return count;
2329 }
2330
2331 bool Element::matchesReadWritePseudoClass() const
2332 {
2333     return false;
2334 }
2335
2336 bool Element::matches(const String& selector, ExceptionCode& ec)
2337 {
2338     SelectorQuery* selectorQuery = document().selectorQueryForString(selector, ec);
2339     return selectorQuery && selectorQuery->matches(*this);
2340 }
2341
2342 Element* Element::closest(const String& selector, ExceptionCode& ec)
2343 {
2344     SelectorQuery* selectorQuery = document().selectorQueryForString(selector, ec);
2345     if (selectorQuery)
2346         return selectorQuery->closest(*this);
2347     return nullptr;
2348 }
2349
2350 bool Element::shouldAppearIndeterminate() const
2351 {
2352     return false;
2353 }
2354
2355 bool Element::isInsideViewport(const IntRect* visibleRect) const
2356 {
2357     return renderer() && renderer()->isInsideViewport(visibleRect);
2358 }
2359
2360 DOMTokenList& Element::classList()
2361 {
2362     ElementRareData& data = ensureElementRareData();
2363     if (!data.classList())
2364         data.setClassList(std::make_unique<ClassList>(*this));
2365     return *data.classList();
2366 }
2367
2368 DatasetDOMStringMap& Element::dataset()
2369 {
2370     ElementRareData& data = ensureElementRareData();
2371     if (!data.dataset())
2372         data.setDataset(std::make_unique<DatasetDOMStringMap>(*this));
2373     return *data.dataset();
2374 }
2375
2376 URL Element::getURLAttribute(const QualifiedName& name) const
2377 {
2378 #if !ASSERT_DISABLED
2379     if (elementData()) {
2380         if (const Attribute* attribute = findAttributeByName(name))
2381             ASSERT(isURLAttribute(*attribute));
2382     }
2383 #endif
2384     return document().completeURL(stripLeadingAndTrailingHTMLSpaces(getAttribute(name)));
2385 }
2386
2387 URL Element::getNonEmptyURLAttribute(const QualifiedName& name) const
2388 {
2389 #if !ASSERT_DISABLED
2390     if (elementData()) {
2391         if (const Attribute* attribute = findAttributeByName(name))
2392             ASSERT(isURLAttribute(*attribute));
2393     }
2394 #endif
2395     String value = stripLeadingAndTrailingHTMLSpaces(getAttribute(name));
2396     if (value.isEmpty())
2397         return URL();
2398     return document().completeURL(value);
2399 }
2400
2401 int Element::getIntegralAttribute(const QualifiedName& attributeName) const
2402 {
2403     return getAttribute(attributeName).string().toInt();
2404 }
2405
2406 void Element::setIntegralAttribute(const QualifiedName& attributeName, int value)
2407 {
2408     setAttribute(attributeName, AtomicString::number(value));
2409 }
2410
2411 unsigned Element::getUnsignedIntegralAttribute(const QualifiedName& attributeName) const
2412 {
2413     return getAttribute(attributeName).string().toUInt();
2414 }
2415
2416 void Element::setUnsignedIntegralAttribute(const QualifiedName& attributeName, unsigned value)
2417 {
2418     setAttribute(attributeName, AtomicString::number(value));
2419 }
2420
2421 #if ENABLE(INDIE_UI)
2422 void Element::setUIActions(const AtomicString& actions)
2423 {
2424     setAttribute(uiactionsAttr, actions);
2425 }
2426
2427 const AtomicString& Element::UIActions() const
2428 {
2429     return getAttribute(uiactionsAttr);
2430 }
2431 #endif
2432
2433 bool Element::childShouldCreateRenderer(const Node& child) const
2434 {
2435     // Only create renderers for SVG elements whose parents are SVG elements, or for proper <svg xmlns="svgNS"> subdocuments.
2436     if (child.isSVGElement()) {
2437         ASSERT(!isSVGElement());
2438         const SVGElement& childElement = downcast<SVGElement>(child);
2439         return is<SVGSVGElement>(childElement) && childElement.isValid();
2440     }
2441     return true;
2442 }
2443
2444 #if ENABLE(FULLSCREEN_API)
2445 void Element::webkitRequestFullscreen()
2446 {
2447     document().requestFullScreenForElement(this, ALLOW_KEYBOARD_INPUT, Document::EnforceIFrameAllowFullScreenRequirement);
2448 }
2449
2450 void Element::webkitRequestFullScreen(unsigned short flags)
2451 {
2452     document().requestFullScreenForElement(this, (flags | LEGACY_MOZILLA_REQUEST), Document::EnforceIFrameAllowFullScreenRequirement);
2453 }
2454
2455 bool Element::containsFullScreenElement() const
2456 {
2457     return hasRareData() && elementRareData()->containsFullScreenElement();
2458 }
2459
2460 void Element::setContainsFullScreenElement(bool flag)
2461 {
2462     ensureElementRareData().setContainsFullScreenElement(flag);
2463     setNeedsStyleRecalc(SyntheticStyleChange);
2464 }
2465
2466 static Element* parentCrossingFrameBoundaries(Element* element)
2467 {
2468     ASSERT(element);
2469     return element->parentElement() ? element->parentElement() : element->document().ownerElement();
2470 }
2471
2472 void Element::setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(bool flag)
2473 {
2474     Element* element = this;
2475     while ((element = parentCrossingFrameBoundaries(element)))
2476         element->setContainsFullScreenElement(flag);
2477 }
2478 #endif
2479
2480 #if ENABLE(POINTER_LOCK)
2481 void Element::requestPointerLock()
2482 {
2483     if (document().page())
2484         document().page()->pointerLockController().requestPointerLock(this);
2485 }
2486 #endif
2487
2488 SpellcheckAttributeState Element::spellcheckAttributeState() const
2489 {
2490     const AtomicString& value = fastGetAttribute(HTMLNames::spellcheckAttr);
2491     if (value == nullAtom)
2492         return SpellcheckAttributeDefault;
2493     if (equalIgnoringCase(value, "true") || equalIgnoringCase(value, ""))
2494         return SpellcheckAttributeTrue;
2495     if (equalIgnoringCase(value, "false"))
2496         return SpellcheckAttributeFalse;
2497
2498     return SpellcheckAttributeDefault;
2499 }
2500
2501 bool Element::isSpellCheckingEnabled() const
2502 {
2503     for (const Element* element = this; element; element = element->parentOrShadowHostElement()) {
2504         switch (element->spellcheckAttributeState()) {
2505         case SpellcheckAttributeTrue:
2506             return true;
2507         case SpellcheckAttributeFalse:
2508             return false;
2509         case SpellcheckAttributeDefault:
2510             break;
2511         }
2512     }
2513
2514     return true;
2515 }
2516
2517 RenderNamedFlowFragment* Element::renderNamedFlowFragment() const
2518 {
2519     if (renderer() && renderer()->isRenderNamedFlowFragmentContainer())
2520         return downcast<RenderBlockFlow>(*renderer()).renderNamedFlowFragment();
2521
2522     return nullptr;
2523 }
2524
2525 #if ENABLE(CSS_REGIONS)
2526
2527 bool Element::shouldMoveToFlowThread(const RenderStyle& styleToUse) const
2528 {
2529 #if ENABLE(FULLSCREEN_API)
2530     if (document().webkitIsFullScreen() && document().webkitCurrentFullScreenElement() == this)
2531         return false;
2532 #endif
2533
2534     if (isInShadowTree())
2535         return false;
2536
2537     if (!styleToUse.hasFlowInto())
2538         return false;
2539
2540     return true;
2541 }
2542
2543 const AtomicString& Element::webkitRegionOverset() const
2544 {
2545     document().updateLayoutIgnorePendingStylesheets();
2546
2547     DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, undefinedState, ("undefined", AtomicString::ConstructFromLiteral));
2548     if (!document().cssRegionsEnabled() || !renderNamedFlowFragment())
2549         return undefinedState;
2550
2551     switch (regionOversetState()) {
2552     case RegionFit: {
2553         DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, fitState, ("fit", AtomicString::ConstructFromLiteral));
2554         return fitState;
2555     }
2556     case RegionEmpty: {
2557         DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, emptyState, ("empty", AtomicString::ConstructFromLiteral));
2558         return emptyState;
2559     }
2560     case RegionOverset: {
2561         DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, overflowState, ("overset", AtomicString::ConstructFromLiteral));
2562         return overflowState;
2563     }
2564     case RegionUndefined:
2565         return undefinedState;
2566     }
2567
2568     ASSERT_NOT_REACHED();
2569     return undefinedState;
2570 }
2571
2572 Vector<RefPtr<Range>> Element::webkitGetRegionFlowRanges() const
2573 {
2574     Vector<RefPtr<Range>> rangeObjects;
2575     if (!document().cssRegionsEnabled())
2576         return rangeObjects;
2577
2578     document().updateLayoutIgnorePendingStylesheets();
2579     if (renderer() && renderer()->isRenderNamedFlowFragmentContainer()) {
2580         RenderNamedFlowFragment& namedFlowFragment = *downcast<RenderBlockFlow>(*renderer()).renderNamedFlowFragment();
2581         if (namedFlowFragment.isValid())
2582             namedFlowFragment.getRanges(rangeObjects);
2583     }
2584
2585     return rangeObjects;
2586 }
2587
2588 #endif
2589
2590 #ifndef NDEBUG
2591 bool Element::fastAttributeLookupAllowed(const QualifiedName& name) const
2592 {
2593     if (name == HTMLNames::styleAttr)
2594         return false;
2595
2596     if (isSVGElement())
2597         return !downcast<SVGElement>(*this).isAnimatableAttribute(name);
2598
2599     return true;
2600 }
2601 #endif
2602
2603 #ifdef DUMP_NODE_STATISTICS
2604 bool Element::hasNamedNodeMap() const
2605 {
2606     return hasRareData() && elementRareData()->attributeMap();
2607 }
2608 #endif
2609
2610 inline void Element::updateName(const AtomicString& oldName, const AtomicString& newName)
2611 {
2612     if (!isInTreeScope())
2613         return;
2614
2615     if (oldName == newName)
2616         return;
2617
2618     updateNameForTreeScope(treeScope(), oldName, newName);
2619
2620     if (!inDocument())
2621         return;
2622     if (!is<HTMLDocument>(document()))
2623         return;
2624     updateNameForDocument(downcast<HTMLDocument>(document()), oldName, newName);
2625 }
2626
2627 void Element::updateNameForTreeScope(TreeScope& scope, const AtomicString& oldName, const AtomicString& newName)
2628 {
2629     ASSERT(oldName != newName);
2630
2631     if (!oldName.isEmpty())
2632         scope.removeElementByName(*oldName.impl(), *this);
2633     if (!newName.isEmpty())
2634         scope.addElementByName(*newName.impl(), *this);
2635 }
2636
2637 void Element::updateNameForDocument(HTMLDocument& document, const AtomicString& oldName, const AtomicString& newName)
2638 {
2639     ASSERT(oldName != newName);
2640
2641     if (WindowNameCollection::elementMatchesIfNameAttributeMatch(*this)) {
2642         const AtomicString& id = WindowNameCollection::elementMatchesIfIdAttributeMatch(*this) ? getIdAttribute() : nullAtom;
2643         if (!oldName.isEmpty() && oldName != id)
2644             document.removeWindowNamedItem(*oldName.impl(), *this);
2645         if (!newName.isEmpty() && newName != id)
2646             document.addWindowNamedItem(*newName.impl(), *this);
2647     }
2648
2649     if (DocumentNameCollection::elementMatchesIfNameAttributeMatch(*this)) {
2650         const AtomicString& id = DocumentNameCollection::elementMatchesIfIdAttributeMatch(*this) ? getIdAttribute() : nullAtom;
2651         if (!oldName.isEmpty() && oldName != id)
2652             document.removeDocumentNamedItem(*oldName.impl(), *this);
2653         if (!newName.isEmpty() && newName != id)
2654             document.addDocumentNamedItem(*newName.impl(), *this);
2655     }
2656 }
2657
2658 inline void Element::updateId(const AtomicString& oldId, const AtomicString& newId)
2659 {
2660     if (!isInTreeScope())
2661         return;
2662
2663     if (oldId == newId)
2664         return;
2665
2666     updateIdForTreeScope(treeScope(), oldId, newId);
2667
2668     if (!inDocument())
2669         return;
2670     if (!is<HTMLDocument>(document()))
2671         return;
2672     updateIdForDocument(downcast<HTMLDocument>(document()), oldId, newId, UpdateHTMLDocumentNamedItemMapsOnlyIfDiffersFromNameAttribute);
2673 }
2674
2675 void Element::updateIdForTreeScope(TreeScope& scope, const AtomicString& oldId, const AtomicString& newId)
2676 {
2677     ASSERT(isInTreeScope());
2678     ASSERT(oldId != newId);
2679
2680     if (!oldId.isEmpty())
2681         scope.removeElementById(*oldId.impl(), *this);
2682     if (!newId.isEmpty())
2683         scope.addElementById(*newId.impl(), *this);
2684 }
2685
2686 void Element::updateIdForDocument(HTMLDocument& document, const AtomicString& oldId, const AtomicString& newId, HTMLDocumentNamedItemMapsUpdatingCondition condition)
2687 {
2688     ASSERT(inDocument());
2689     ASSERT(oldId != newId);
2690
2691     if (WindowNameCollection::elementMatchesIfIdAttributeMatch(*this)) {
2692         const AtomicString& name = condition == UpdateHTMLDocumentNamedItemMapsOnlyIfDiffersFromNameAttribute && WindowNameCollection::elementMatchesIfNameAttributeMatch(*this) ? getNameAttribute() : nullAtom;
2693         if (!oldId.isEmpty() && oldId != name)
2694             document.removeWindowNamedItem(*oldId.impl(), *this);
2695         if (!newId.isEmpty() && newId != name)
2696             document.addWindowNamedItem(*newId.impl(), *this);
2697     }
2698
2699     if (DocumentNameCollection::elementMatchesIfIdAttributeMatch(*this)) {
2700         const AtomicString& name = condition == UpdateHTMLDocumentNamedItemMapsOnlyIfDiffersFromNameAttribute && DocumentNameCollection::elementMatchesIfNameAttributeMatch(*this) ? getNameAttribute() : nullAtom;
2701         if (!oldId.isEmpty() && oldId != name)
2702             document.removeDocumentNamedItem(*oldId.impl(), *this);
2703         if (!newId.isEmpty() && newId != name)
2704             document.addDocumentNamedItem(*newId.impl(), *this);
2705     }
2706 }
2707
2708 void Element::updateLabel(TreeScope& scope, const AtomicString& oldForAttributeValue, const AtomicString& newForAttributeValue)
2709 {
2710     ASSERT(hasTagName(labelTag));
2711
2712     if (!inDocument())
2713         return;
2714
2715     if (oldForAttributeValue == newForAttributeValue)
2716         return;
2717
2718     if (!oldForAttributeValue.isEmpty())
2719         scope.removeLabel(*oldForAttributeValue.impl(), downcast<HTMLLabelElement>(*this));
2720     if (!newForAttributeValue.isEmpty())
2721         scope.addLabel(*newForAttributeValue.impl(), downcast<HTMLLabelElement>(*this));
2722 }
2723
2724 void Element::willModifyAttribute(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue)
2725 {
2726     if (name == HTMLNames::idAttr)
2727         updateId(oldValue, newValue);
2728     else if (name == HTMLNames::nameAttr)
2729         updateName(oldValue, newValue);
2730     else if (name == HTMLNames::forAttr && hasTagName(labelTag)) {
2731         if (treeScope().shouldCacheLabelsByForAttribute())
2732             updateLabel(treeScope(), oldValue, newValue);
2733     }
2734
2735     if (oldValue != newValue) {
2736         auto styleResolver = document().styleResolverIfExists();
2737         if (styleResolver && styleResolver->hasSelectorForAttribute(*this, name.localName()))
2738             setNeedsStyleRecalc();
2739     }
2740
2741     if (std::unique_ptr<MutationObserverInterestGroup> recipients = MutationObserverInterestGroup::createForAttributesMutation(*this, name))
2742         recipients->enqueueMutationRecord(MutationRecord::createAttributes(*this, name, oldValue));
2743
2744 #if ENABLE(INSPECTOR)
2745     InspectorInstrumentation::willModifyDOMAttr(&document(), this, oldValue, newValue);
2746 #endif
2747 }
2748
2749 void Element::didAddAttribute(const QualifiedName& name, const AtomicString& value)
2750 {
2751     attributeChanged(name, nullAtom, value);
2752     InspectorInstrumentation::didModifyDOMAttr(&document(), this, name.localName(), value);
2753     dispatchSubtreeModifiedEvent();
2754 }
2755
2756 void Element::didModifyAttribute(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue)
2757 {
2758     attributeChanged(name, oldValue, newValue);
2759     InspectorInstrumentation::didModifyDOMAttr(&document(), this, name.localName(), newValue);
2760     // Do not dispatch a DOMSubtreeModified event here; see bug 81141.
2761 }
2762
2763 void Element::didRemoveAttribute(const QualifiedName& name, const AtomicString& oldValue)
2764 {
2765     attributeChanged(name, oldValue, nullAtom);
2766     InspectorInstrumentation::didRemoveDOMAttr(&document(), this, name.localName());
2767     dispatchSubtreeModifiedEvent();
2768 }
2769
2770 PassRefPtr<HTMLCollection> Element::ensureCachedHTMLCollection(CollectionType type)
2771 {
2772     if (HTMLCollection* collection = cachedHTMLCollection(type))
2773         return collection;
2774
2775     if (type == TableRows) {
2776         return ensureRareData().ensureNodeLists().addCachedCollection<HTMLTableRowsCollection>(downcast<HTMLTableElement>(*this), type);
2777     } else if (type == SelectOptions) {
2778         return ensureRareData().ensureNodeLists().addCachedCollection<HTMLOptionsCollection>(downcast<HTMLSelectElement>(*this), type);
2779     } else if (type == FormControls) {
2780         ASSERT(hasTagName(formTag) || hasTagName(fieldsetTag));
2781         return ensureRareData().ensureNodeLists().addCachedCollection<HTMLFormControlsCollection>(*this, type);
2782     }
2783     return ensureRareData().ensureNodeLists().addCachedCollection<HTMLCollection>(*this, type);
2784 }
2785
2786 HTMLCollection* Element::cachedHTMLCollection(CollectionType type)
2787 {
2788     return hasRareData() && rareData()->nodeLists() ? rareData()->nodeLists()->cachedCollection<HTMLCollection>(type) : 0;
2789 }
2790
2791 IntSize Element::savedLayerScrollOffset() const
2792 {
2793     return hasRareData() ? elementRareData()->savedLayerScrollOffset() : IntSize();
2794 }
2795
2796 void Element::setSavedLayerScrollOffset(const IntSize& size)
2797 {
2798     if (size.isZero() && !hasRareData())
2799         return;
2800     ensureElementRareData().setSavedLayerScrollOffset(size);
2801 }
2802
2803 PassRefPtr<Attr> Element::attrIfExists(const QualifiedName& name)
2804 {
2805     if (auto* attrNodeList = attrNodeListForElement(*this))
2806         return findAttrNodeInList(*attrNodeList, name);
2807     return nullptr;
2808 }
2809
2810 PassRefPtr<Attr> Element::ensureAttr(const QualifiedName& name)
2811 {
2812     auto& attrNodeList = ensureAttrNodeListForElement(*this);
2813     RefPtr<Attr> attrNode = findAttrNodeInList(attrNodeList, name);
2814     if (!attrNode) {
2815         attrNode = Attr::create(this, name);
2816         treeScope().adoptIfNeeded(attrNode.get());
2817         attrNodeList.append(attrNode);
2818     }
2819     return attrNode.release();
2820 }
2821
2822 void Element::detachAttrNodeFromElementWithValue(Attr* attrNode, const AtomicString& value)
2823 {
2824     ASSERT(hasSyntheticAttrChildNodes());
2825     attrNode->detachFromElementWithValue(value);
2826
2827     auto* attrNodeList = attrNodeListForElement(*this);
2828     for (unsigned i = 0; i < attrNodeList->size(); ++i) {
2829         if (attrNodeList->at(i)->qualifiedName() == attrNode->qualifiedName()) {
2830             attrNodeList->remove(i);
2831             if (attrNodeList->isEmpty())
2832                 removeAttrNodeListForElement(*this);
2833             return;
2834         }
2835     }
2836     ASSERT_NOT_REACHED();
2837 }
2838
2839 void Element::detachAllAttrNodesFromElement()
2840 {
2841     auto* attrNodeList = attrNodeListForElement(*this);
2842     ASSERT(attrNodeList);
2843
2844     for (const Attribute& attribute : attributesIterator()) {
2845         if (RefPtr<Attr> attrNode = findAttrNodeInList(*attrNodeList, attribute.name()))
2846             attrNode->detachFromElementWithValue(attribute.value());
2847     }
2848
2849     removeAttrNodeListForElement(*this);
2850 }
2851
2852 void Element::resetComputedStyle()
2853 {
2854     if (!hasRareData() || !elementRareData()->computedStyle())
2855         return;
2856
2857     auto reset = [](Element& element) {
2858         if (!element.hasRareData() || !element.elementRareData()->computedStyle())
2859             return;
2860         if (element.hasCustomStyleResolveCallbacks())
2861             element.willResetComputedStyle();
2862         element.elementRareData()->resetComputedStyle();
2863     };
2864     reset(*this);
2865     for (auto& child : descendantsOfType<Element>(*this))
2866         reset(child);
2867 }
2868
2869 void Element::clearStyleDerivedDataBeforeDetachingRenderer()
2870 {
2871     unregisterNamedFlowContentElement();
2872     cancelFocusAppearanceUpdate();
2873     clearBeforePseudoElement();
2874     clearAfterPseudoElement();
2875     if (!hasRareData())
2876         return;
2877     ElementRareData* data = elementRareData();
2878     data->resetComputedStyle();
2879     data->resetDynamicRestyleObservations();
2880 }
2881
2882 void Element::clearHoverAndActiveStatusBeforeDetachingRenderer()
2883 {
2884     if (!isUserActionElement())
2885         return;
2886     if (hovered())
2887         document().hoveredElementDidDetach(this);
2888     if (inActiveChain())
2889         document().elementInActiveChainDidDetach(this);
2890     document().userActionElements().didDetach(this);
2891 }
2892
2893 bool Element::willRecalcStyle(Style::Change)
2894 {
2895     ASSERT(hasCustomStyleResolveCallbacks());
2896     return true;
2897 }
2898
2899 void Element::didRecalcStyle(Style::Change)
2900 {
2901     ASSERT(hasCustomStyleResolveCallbacks());
2902 }
2903
2904 void Element::willResetComputedStyle()
2905 {
2906     ASSERT(hasCustomStyleResolveCallbacks());
2907 }
2908
2909 void Element::willAttachRenderers()
2910 {
2911     ASSERT(hasCustomStyleResolveCallbacks());
2912 }
2913
2914 void Element::didAttachRenderers()
2915 {
2916     ASSERT(hasCustomStyleResolveCallbacks());
2917 }
2918
2919 void Element::willDetachRenderers()
2920 {
2921     ASSERT(hasCustomStyleResolveCallbacks());
2922 }
2923
2924 void Element::didDetachRenderers()
2925 {
2926     ASSERT(hasCustomStyleResolveCallbacks());
2927 }
2928
2929 PassRefPtr<RenderStyle> Element::customStyleForRenderer(RenderStyle&)
2930 {
2931     ASSERT(hasCustomStyleResolveCallbacks());
2932     return 0;
2933 }
2934
2935 void Element::cloneAttributesFromElement(const Element& other)
2936 {
2937     if (hasSyntheticAttrChildNodes())
2938         detachAllAttrNodesFromElement();
2939
2940     other.synchronizeAllAttributes();
2941     if (!other.m_elementData) {
2942         m_elementData.clear();
2943         return;
2944     }
2945
2946     // We can't update window and document's named item maps since the presence of image and object elements depend on other attributes and children.
2947     // Fortunately, those named item maps are only updated when this element is in the document, which should never be the case.
2948     ASSERT(!inDocument());
2949
2950     const AtomicString& oldID = getIdAttribute();
2951     const AtomicString& newID = other.getIdAttribute();
2952
2953     if (!oldID.isNull() || !newID.isNull())
2954         updateId(oldID, newID);
2955
2956     const AtomicString& oldName = getNameAttribute();
2957     const AtomicString& newName = other.getNameAttribute();
2958
2959     if (!oldName.isNull() || !newName.isNull())
2960         updateName(oldName, newName);
2961
2962     // If 'other' has a mutable ElementData, convert it to an immutable one so we can share it between both elements.
2963     // We can only do this if there is no CSSOM wrapper for other's inline style, and there are no presentation attributes.
2964     if (is<UniqueElementData>(*other.m_elementData)
2965         && !other.m_elementData->presentationAttributeStyle()
2966         && (!other.m_elementData->inlineStyle() || !other.m_elementData->inlineStyle()->hasCSSOMWrapper()))
2967         const_cast<Element&>(other).m_elementData = downcast<UniqueElementData>(*other.m_elementData).makeShareableCopy();
2968
2969     if (!other.m_elementData->isUnique())
2970         m_elementData = other.m_elementData;
2971     else
2972         m_elementData = other.m_elementData->makeUniqueCopy();
2973
2974     for (const Attribute& attribute : attributesIterator())
2975         attributeChanged(attribute.name(), nullAtom, attribute.value(), ModifiedByCloning);
2976 }
2977
2978 void Element::cloneDataFromElement(const Element& other)
2979 {
2980     cloneAttributesFromElement(other);
2981     copyNonAttributePropertiesFromElement(other);
2982 }
2983
2984 void Element::createUniqueElementData()
2985 {
2986     if (!m_elementData)
2987         m_elementData = UniqueElementData::create();
2988     else
2989         m_elementData = downcast<ShareableElementData>(*m_elementData).makeUniqueCopy();
2990 }
2991
2992 bool Element::hasPendingResources() const
2993 {
2994     return hasRareData() && elementRareData()->hasPendingResources();
2995 }
2996
2997 void Element::setHasPendingResources()
2998 {
2999     ensureElementRareData().setHasPendingResources(true);
3000 }
3001
3002 void Element::clearHasPendingResources()
3003 {
3004     ensureElementRareData().setHasPendingResources(false);
3005 }
3006
3007 bool Element::canContainRangeEndPoint() const
3008 {
3009     return !equalIgnoringCase(fastGetAttribute(roleAttr), "img");
3010 }
3011
3012 String Element::completeURLsInAttributeValue(const URL& base, const Attribute& attribute) const
3013 {
3014     return URL(base, attribute.value()).string();
3015 }
3016
3017 } // namespace WebCore