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