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