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