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