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