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