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