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