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