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