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