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