[CSS Shadow Parts] Parse 'part' attribute
[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::partAttr)
1723             partAttributeChanged(newValue);
1724         else if (name == HTMLNames::idAttr) {
1725             AtomString oldId = elementData()->idForStyleResolution();
1726             AtomString newId = makeIdForStyleResolution(newValue, document().inQuirksMode());
1727             if (newId != oldId) {
1728                 Style::IdChangeInvalidation styleInvalidation(*this, oldId, newId);
1729                 elementData()->setIdForStyleResolution(newId);
1730             }
1731
1732             if (!oldValue.isEmpty())
1733                 treeScope().idTargetObserverRegistry().notifyObservers(*oldValue.impl());
1734             if (!newValue.isEmpty())
1735                 treeScope().idTargetObserverRegistry().notifyObservers(*newValue.impl());
1736         } else if (name == HTMLNames::nameAttr)
1737             elementData()->setHasNameAttribute(!newValue.isNull());
1738         else if (name == HTMLNames::pseudoAttr) {
1739             if (needsStyleInvalidation() && isInShadowTree())
1740                 invalidateStyleForSubtree();
1741         } else if (name == HTMLNames::slotAttr) {
1742             if (auto* parent = parentElement()) {
1743                 if (auto* shadowRoot = parent->shadowRoot())
1744                     shadowRoot->hostChildElementDidChangeSlotAttribute(*this, oldValue, newValue);
1745             }
1746         }
1747     }
1748
1749     parseAttribute(name, newValue);
1750
1751     document().incDOMTreeVersion();
1752
1753     if (UNLIKELY(isDefinedCustomElement()))
1754         CustomElementReactionQueue::enqueueAttributeChangedCallbackIfNeeded(*this, name, oldValue, newValue);
1755
1756     if (valueIsSameAsBefore)
1757         return;
1758
1759     invalidateNodeListAndCollectionCachesInAncestorsForAttribute(name);
1760
1761     if (AXObjectCache* cache = document().existingAXObjectCache())
1762         cache->deferAttributeChangeIfNeeded(name, this);
1763 }
1764
1765 template <typename CharacterType>
1766 static inline bool isNonEmptyTokenList(const CharacterType* characters, unsigned length)
1767 {
1768     ASSERT(length > 0);
1769
1770     unsigned i = 0;
1771     do {
1772         if (isNotHTMLSpace(characters[i]))
1773             break;
1774         ++i;
1775     } while (i < length);
1776
1777     return i < length;
1778 }
1779
1780 static inline bool isNonEmptyTokenList(const AtomString& stringValue)
1781 {
1782     unsigned length = stringValue.length();
1783
1784     if (!length)
1785         return false;
1786
1787     if (stringValue.is8Bit())
1788         return isNonEmptyTokenList(stringValue.characters8(), length);
1789     return isNonEmptyTokenList(stringValue.characters16(), length);
1790 }
1791
1792 void Element::classAttributeChanged(const AtomString& newClassString)
1793 {
1794     // Note: We'll need ElementData, but it doesn't have to be UniqueElementData.
1795     if (!elementData())
1796         ensureUniqueElementData();
1797
1798     bool shouldFoldCase = document().inQuirksMode();
1799     bool newStringHasClasses = isNonEmptyTokenList(newClassString);
1800
1801     auto oldClassNames = elementData()->classNames();
1802     auto newClassNames = newStringHasClasses ? SpaceSplitString(newClassString, shouldFoldCase) : SpaceSplitString();
1803     {
1804         Style::ClassChangeInvalidation styleInvalidation(*this, oldClassNames, newClassNames);
1805         elementData()->setClassNames(newClassNames);
1806     }
1807
1808     if (hasRareData()) {
1809         if (auto* classList = elementRareData()->classList())
1810             classList->associatedAttributeValueChanged(newClassString);
1811     }
1812 }
1813
1814 void Element::partAttributeChanged(const AtomString& newValue)
1815 {
1816     if (!RuntimeEnabledFeatures::sharedFeatures().cssShadowPartsEnabled())
1817         return;
1818
1819     bool hasParts = isNonEmptyTokenList(newValue);
1820     if (hasParts || !partNames().isEmpty()) {
1821         auto newParts = hasParts ? SpaceSplitString(newValue, false) : SpaceSplitString();
1822         ensureElementRareData().setPartNames(WTFMove(newParts));
1823     }
1824
1825     if (hasRareData()) {
1826         if (auto* partList = elementRareData()->partList())
1827             partList->associatedAttributeValueChanged(newValue);
1828     }
1829 }
1830
1831 URL Element::absoluteLinkURL() const
1832 {
1833     if (!isLink())
1834         return URL();
1835
1836     AtomString linkAttribute;
1837     if (hasTagName(SVGNames::aTag))
1838         linkAttribute = getAttribute(SVGNames::hrefAttr, XLinkNames::hrefAttr);
1839     else
1840         linkAttribute = getAttribute(HTMLNames::hrefAttr);
1841
1842     if (linkAttribute.isEmpty())
1843         return URL();
1844
1845     return document().completeURL(stripLeadingAndTrailingHTMLSpaces(linkAttribute));
1846 }
1847
1848 #if ENABLE(TOUCH_EVENTS)
1849 bool Element::allowsDoubleTapGesture() const
1850 {
1851 #if ENABLE(POINTER_EVENTS)
1852     if (renderStyle() && renderStyle()->touchActions() != TouchAction::Auto)
1853         return false;
1854 #endif
1855
1856     Element* parent = parentElement();
1857     return !parent || parent->allowsDoubleTapGesture();
1858 }
1859 #endif
1860
1861 StyleResolver& Element::styleResolver()
1862 {
1863     if (auto* shadowRoot = containingShadowRoot())
1864         return shadowRoot->styleScope().resolver();
1865
1866     return document().styleScope().resolver();
1867 }
1868
1869 ElementStyle Element::resolveStyle(const RenderStyle* parentStyle)
1870 {
1871     return styleResolver().styleForElement(*this, parentStyle);
1872 }
1873
1874 static void invalidateForSiblingCombinators(Element* sibling)
1875 {
1876     for (; sibling; sibling = sibling->nextElementSibling()) {
1877         if (sibling->styleIsAffectedByPreviousSibling())
1878             sibling->invalidateStyleInternal();
1879         if (sibling->descendantsAffectedByPreviousSibling()) {
1880             for (auto* siblingChild = sibling->firstElementChild(); siblingChild; siblingChild = siblingChild->nextElementSibling())
1881                 siblingChild->invalidateStyleForSubtreeInternal();
1882         }
1883         if (!sibling->affectsNextSiblingElementStyle())
1884             return;
1885     }
1886 }
1887
1888 static void invalidateSiblingsIfNeeded(Element& element)
1889 {
1890     if (!element.affectsNextSiblingElementStyle())
1891         return;
1892     auto* parent = element.parentElement();
1893     if (parent && parent->styleValidity() >= Style::Validity::SubtreeInvalid)
1894         return;
1895
1896     invalidateForSiblingCombinators(element.nextElementSibling());
1897 }
1898
1899 void Element::invalidateStyle()
1900 {
1901     Node::invalidateStyle(Style::Validity::ElementInvalid);
1902     invalidateSiblingsIfNeeded(*this);
1903 }
1904
1905 void Element::invalidateStyleAndLayerComposition()
1906 {
1907     Node::invalidateStyle(Style::Validity::ElementInvalid, Style::InvalidationMode::RecompositeLayer);
1908     invalidateSiblingsIfNeeded(*this);
1909 }
1910
1911 void Element::invalidateStyleForSubtree()
1912 {
1913     Node::invalidateStyle(Style::Validity::SubtreeInvalid);
1914     invalidateSiblingsIfNeeded(*this);
1915 }
1916
1917 void Element::invalidateStyleAndRenderersForSubtree()
1918 {
1919     Node::invalidateStyle(Style::Validity::SubtreeAndRenderersInvalid);
1920     invalidateSiblingsIfNeeded(*this);
1921 }
1922
1923 void Element::invalidateStyleInternal()
1924 {
1925     Node::invalidateStyle(Style::Validity::ElementInvalid);
1926 }
1927
1928 void Element::invalidateStyleForSubtreeInternal()
1929 {
1930     Node::invalidateStyle(Style::Validity::SubtreeInvalid);
1931 }
1932
1933 bool Element::hasDisplayContents() const
1934 {
1935     if (!hasRareData())
1936         return false;
1937
1938     const RenderStyle* style = elementRareData()->computedStyle();
1939     return style && style->display() == DisplayType::Contents;
1940 }
1941
1942 void Element::storeDisplayContentsStyle(std::unique_ptr<RenderStyle> style)
1943 {
1944     ASSERT(style && style->display() == DisplayType::Contents);
1945     ASSERT(!renderer() || isPseudoElement());
1946     ensureElementRareData().setComputedStyle(WTFMove(style));
1947 }
1948
1949 // Returns true is the given attribute is an event handler.
1950 // We consider an event handler any attribute that begins with "on".
1951 // It is a simple solution that has the advantage of not requiring any
1952 // code or configuration change if a new event handler is defined.
1953
1954 bool Element::isEventHandlerAttribute(const Attribute& attribute) const
1955 {
1956     return attribute.name().namespaceURI().isNull() && attribute.name().localName().startsWith("on");
1957 }
1958
1959 bool Element::isJavaScriptURLAttribute(const Attribute& attribute) const
1960 {
1961     return isURLAttribute(attribute) && WTF::protocolIsJavaScript(stripLeadingAndTrailingHTMLSpaces(attribute.value()));
1962 }
1963
1964 void Element::stripScriptingAttributes(Vector<Attribute>& attributeVector) const
1965 {
1966     attributeVector.removeAllMatching([this](auto& attribute) -> bool {
1967         return this->isEventHandlerAttribute(attribute)
1968             || this->isJavaScriptURLAttribute(attribute)
1969             || this->isHTMLContentAttribute(attribute);
1970     });
1971 }
1972
1973 void Element::parserSetAttributes(const Vector<Attribute>& attributeVector)
1974 {
1975     ASSERT(!isConnected());
1976     ASSERT(!parentNode());
1977     ASSERT(!m_elementData);
1978
1979     if (!attributeVector.isEmpty()) {
1980         if (document().sharedObjectPool())
1981             m_elementData = document().sharedObjectPool()->cachedShareableElementDataWithAttributes(attributeVector);
1982         else
1983             m_elementData = ShareableElementData::createWithAttributes(attributeVector);
1984
1985     }
1986
1987     parserDidSetAttributes();
1988
1989     // Use attributeVector instead of m_elementData because attributeChanged might modify m_elementData.
1990     for (const auto& attribute : attributeVector)
1991         attributeChanged(attribute.name(), nullAtom(), attribute.value(), ModifiedDirectly);
1992 }
1993
1994 void Element::parserDidSetAttributes()
1995 {
1996 }
1997
1998 void Element::didMoveToNewDocument(Document& oldDocument, Document& newDocument)
1999 {
2000     ASSERT_WITH_SECURITY_IMPLICATION(&document() == &newDocument);
2001
2002     if (oldDocument.inQuirksMode() != document().inQuirksMode()) {
2003         // ElementData::m_classNames or ElementData::m_idForStyleResolution need to be updated with the right case.
2004         if (hasID())
2005             attributeChanged(idAttr, nullAtom(), getIdAttribute());
2006         if (hasClass())
2007             attributeChanged(classAttr, nullAtom(), getAttribute(classAttr));
2008     }
2009
2010     if (UNLIKELY(isDefinedCustomElement()))
2011         CustomElementReactionQueue::enqueueAdoptedCallbackIfNeeded(*this, oldDocument, newDocument);
2012
2013 #if ENABLE(INTERSECTION_OBSERVER)
2014     if (auto* observerData = intersectionObserverData()) {
2015         for (const auto& observer : observerData->observers) {
2016             if (observer->hasObservationTargets()) {
2017                 oldDocument.removeIntersectionObserver(*observer);
2018                 newDocument.addIntersectionObserver(*observer);
2019             }
2020         }
2021     }
2022 #endif
2023 }
2024
2025 bool Element::hasAttributes() const
2026 {
2027     synchronizeAllAttributes();
2028     return elementData() && elementData()->length();
2029 }
2030
2031 bool Element::hasEquivalentAttributes(const Element& other) const
2032 {
2033     synchronizeAllAttributes();
2034     other.synchronizeAllAttributes();
2035     if (elementData() == other.elementData())
2036         return true;
2037     if (elementData())
2038         return elementData()->isEquivalent(other.elementData());
2039     if (other.elementData())
2040         return other.elementData()->isEquivalent(elementData());
2041     return true;
2042 }
2043
2044 String Element::nodeName() const
2045 {
2046     return m_tagName.toString();
2047 }
2048
2049 String Element::nodeNamePreservingCase() const
2050 {
2051     return m_tagName.toString();
2052 }
2053
2054 ExceptionOr<void> Element::setPrefix(const AtomString& prefix)
2055 {
2056     auto result = checkSetPrefix(prefix);
2057     if (result.hasException())
2058         return result.releaseException();
2059
2060     m_tagName.setPrefix(prefix.isEmpty() ? nullAtom() : prefix);
2061     return { };
2062 }
2063
2064 const AtomString& Element::imageSourceURL() const
2065 {
2066     return attributeWithoutSynchronization(srcAttr);
2067 }
2068
2069 bool Element::rendererIsNeeded(const RenderStyle& style)
2070 {
2071     return style.display() != DisplayType::None && style.display() != DisplayType::Contents;
2072 }
2073
2074 RenderPtr<RenderElement> Element::createElementRenderer(RenderStyle&& style, const RenderTreePosition&)
2075 {
2076     return RenderElement::createFor(*this, WTFMove(style));
2077 }
2078
2079 Node::InsertedIntoAncestorResult Element::insertedIntoAncestor(InsertionType insertionType, ContainerNode& parentOfInsertedTree)
2080 {
2081     ContainerNode::insertedIntoAncestor(insertionType, parentOfInsertedTree);
2082
2083 #if ENABLE(FULLSCREEN_API)
2084     if (containsFullScreenElement() && parentElement() && !parentElement()->containsFullScreenElement())
2085         setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(true);
2086 #endif
2087
2088     if (parentNode() == &parentOfInsertedTree) {
2089         if (auto* shadowRoot = parentNode()->shadowRoot())
2090             shadowRoot->hostChildElementDidChange(*this);
2091     }
2092
2093     if (!parentOfInsertedTree.isInTreeScope())
2094         return InsertedIntoAncestorResult::Done;
2095
2096     bool becomeConnected = insertionType.connectedToDocument;
2097     TreeScope* newScope = &parentOfInsertedTree.treeScope();
2098     HTMLDocument* newDocument = becomeConnected && is<HTMLDocument>(newScope->documentScope()) ? &downcast<HTMLDocument>(newScope->documentScope()) : nullptr;
2099     if (!insertionType.treeScopeChanged)
2100         newScope = nullptr;
2101
2102     const AtomString& idValue = getIdAttribute();
2103     if (!idValue.isNull()) {
2104         if (newScope)
2105             updateIdForTreeScope(*newScope, nullAtom(), idValue);
2106         if (newDocument)
2107             updateIdForDocument(*newDocument, nullAtom(), idValue, AlwaysUpdateHTMLDocumentNamedItemMaps);
2108     }
2109
2110     const AtomString& nameValue = getNameAttribute();
2111     if (!nameValue.isNull()) {
2112         if (newScope)
2113             updateNameForTreeScope(*newScope, nullAtom(), nameValue);
2114         if (newDocument)
2115             updateNameForDocument(*newDocument, nullAtom(), nameValue);
2116     }
2117
2118     if (newScope && hasTagName(labelTag)) {
2119         if (newScope->shouldCacheLabelsByForAttribute())
2120             updateLabel(*newScope, nullAtom(), attributeWithoutSynchronization(forAttr));
2121     }
2122
2123     if (becomeConnected) {
2124         if (UNLIKELY(isCustomElementUpgradeCandidate())) {
2125             ASSERT(isConnected());
2126             CustomElementReactionQueue::enqueueElementUpgradeIfDefined(*this);
2127         }
2128         if (UNLIKELY(isDefinedCustomElement()))
2129             CustomElementReactionQueue::enqueueConnectedCallbackIfNeeded(*this);
2130     }
2131
2132     if (UNLIKELY(hasTagName(articleTag) && newDocument))
2133         newDocument->registerArticleElement(*this);
2134
2135     return InsertedIntoAncestorResult::Done;
2136 }
2137
2138 void Element::removedFromAncestor(RemovalType removalType, ContainerNode& oldParentOfRemovedTree)
2139 {
2140 #if ENABLE(FULLSCREEN_API)
2141     if (containsFullScreenElement())
2142         setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false);
2143 #endif
2144 #if ENABLE(POINTER_LOCK)
2145     if (document().page())
2146         document().page()->pointerLockController().elementRemoved(*this);
2147 #endif
2148 #if ENABLE(POINTER_EVENTS)
2149     if (document().page() && RuntimeEnabledFeatures::sharedFeatures().pointerEventsEnabled())
2150         document().page()->pointerCaptureController().elementWasRemoved(*this);
2151 #endif
2152
2153     setSavedLayerScrollPosition(ScrollPosition());
2154
2155     if (oldParentOfRemovedTree.isInTreeScope()) {
2156         TreeScope* oldScope = &oldParentOfRemovedTree.treeScope();
2157         Document* oldDocument = removalType.disconnectedFromDocument ? &oldScope->documentScope() : nullptr;
2158         HTMLDocument* oldHTMLDocument = oldDocument && is<HTMLDocument>(*oldDocument) ? &downcast<HTMLDocument>(*oldDocument) : nullptr;
2159         if (!removalType.treeScopeChanged)
2160             oldScope = nullptr;
2161
2162         const AtomString& idValue = getIdAttribute();
2163         if (!idValue.isNull()) {
2164             if (oldScope)
2165                 updateIdForTreeScope(*oldScope, idValue, nullAtom());
2166             if (oldHTMLDocument)
2167                 updateIdForDocument(*oldHTMLDocument, idValue, nullAtom(), AlwaysUpdateHTMLDocumentNamedItemMaps);
2168         }
2169
2170         const AtomString& nameValue = getNameAttribute();
2171         if (!nameValue.isNull()) {
2172             if (oldScope)
2173                 updateNameForTreeScope(*oldScope, nameValue, nullAtom());
2174             if (oldHTMLDocument)
2175                 updateNameForDocument(*oldHTMLDocument, nameValue, nullAtom());
2176         }
2177
2178         if (oldScope && hasTagName(labelTag)) {
2179             if (oldScope->shouldCacheLabelsByForAttribute())
2180                 updateLabel(*oldScope, attributeWithoutSynchronization(forAttr), nullAtom());
2181         }
2182
2183         if (oldDocument) {
2184             if (oldDocument->cssTarget() == this)
2185                 oldDocument->setCSSTarget(nullptr);
2186             if (UNLIKELY(hasTagName(articleTag)))
2187                 oldDocument->unregisterArticleElement(*this);
2188         }
2189
2190         if (removalType.disconnectedFromDocument && UNLIKELY(isDefinedCustomElement()))
2191             CustomElementReactionQueue::enqueueDisconnectedCallbackIfNeeded(*this);
2192     }
2193
2194     if (!parentNode()) {
2195         if (auto* shadowRoot = oldParentOfRemovedTree.shadowRoot())
2196             shadowRoot->hostChildElementDidChange(*this);
2197     }
2198
2199     clearBeforePseudoElement();
2200     clearAfterPseudoElement();
2201
2202     ContainerNode::removedFromAncestor(removalType, oldParentOfRemovedTree);
2203
2204     if (hasPendingResources())
2205         document().accessSVGExtensions().removeElementFromPendingResources(*this);
2206
2207     RefPtr<Frame> frame = document().frame();
2208     if (auto* timeline = document().existingTimeline())
2209         timeline->elementWasRemoved(*this);
2210     if (frame)
2211         frame->animation().cancelAnimations(*this);
2212
2213 #if PLATFORM(MAC)
2214     if (frame && frame->page())
2215         frame->page()->removeLatchingStateForTarget(*this);
2216 #endif
2217
2218     if (hasRareData() && elementRareData()->hasElementIdentifier()) {
2219         document().identifiedElementWasRemovedFromDocument(*this);
2220         elementRareData()->setHasElementIdentifier(false);
2221     }
2222 }
2223
2224 ShadowRoot* Element::shadowRoot() const
2225 {
2226     return hasRareData() ? elementRareData()->shadowRoot() : nullptr;
2227 }
2228
2229 void Element::addShadowRoot(Ref<ShadowRoot>&& newShadowRoot)
2230 {
2231     ASSERT(!newShadowRoot->hasChildNodes());
2232     ASSERT(!shadowRoot());
2233
2234     ShadowRoot& shadowRoot = newShadowRoot;
2235     {
2236         ScriptDisallowedScope::InMainThread scriptDisallowedScope;
2237         if (renderer())
2238             RenderTreeUpdater::tearDownRenderers(*this);
2239
2240         ensureElementRareData().setShadowRoot(WTFMove(newShadowRoot));
2241
2242         shadowRoot.setHost(this);
2243         shadowRoot.setParentTreeScope(treeScope());
2244
2245 #if !ASSERT_DISABLED
2246         ASSERT(notifyChildNodeInserted(*this, shadowRoot).isEmpty());
2247 #else
2248         notifyChildNodeInserted(*this, shadowRoot);
2249 #endif
2250
2251         invalidateStyleAndRenderersForSubtree();
2252     }
2253
2254     if (shadowRoot.mode() == ShadowRootMode::UserAgent)
2255         didAddUserAgentShadowRoot(shadowRoot);
2256
2257     InspectorInstrumentation::didPushShadowRoot(*this, shadowRoot);
2258 }
2259
2260 void Element::removeShadowRoot()
2261 {
2262     RefPtr<ShadowRoot> oldRoot = shadowRoot();
2263     if (!oldRoot)
2264         return;
2265
2266     InspectorInstrumentation::willPopShadowRoot(*this, *oldRoot);
2267     document().adjustFocusedNodeOnNodeRemoval(*oldRoot);
2268
2269     ASSERT(!oldRoot->renderer());
2270
2271     elementRareData()->clearShadowRoot();
2272
2273     oldRoot->setHost(nullptr);
2274     oldRoot->setParentTreeScope(document());
2275 }
2276
2277 static bool canAttachAuthorShadowRoot(const Element& element)
2278 {
2279     static NeverDestroyed<HashSet<AtomString>> tagNames = [] {
2280         static const HTMLQualifiedName* const tagList[] = {
2281             &articleTag.get(),
2282             &asideTag.get(),
2283             &blockquoteTag.get(),
2284             &bodyTag.get(),
2285             &divTag.get(),
2286             &footerTag.get(),
2287             &h1Tag.get(),
2288             &h2Tag.get(),
2289             &h3Tag.get(),
2290             &h4Tag.get(),
2291             &h5Tag.get(),
2292             &h6Tag.get(),
2293             &headerTag.get(),
2294             &navTag.get(),
2295             &pTag.get(),
2296             &sectionTag.get(),
2297             &spanTag.get()
2298         };
2299         HashSet<AtomString> set;
2300         for (auto& name : tagList)
2301             set.add(name->localName());
2302         return set;
2303     }();
2304
2305     if (!is<HTMLElement>(element))
2306         return false;
2307
2308     const auto& localName = element.localName();
2309     return tagNames.get().contains(localName) || Document::validateCustomElementName(localName) == CustomElementNameValidationStatus::Valid;
2310 }
2311
2312 ExceptionOr<ShadowRoot&> Element::attachShadow(const ShadowRootInit& init)
2313 {
2314     if (!canAttachAuthorShadowRoot(*this))
2315         return Exception { NotSupportedError };
2316     if (shadowRoot())
2317         return Exception { InvalidStateError };
2318     if (init.mode == ShadowRootMode::UserAgent)
2319         return Exception { TypeError };
2320     auto shadow = ShadowRoot::create(document(), init.mode);
2321     auto& result = shadow.get();
2322     addShadowRoot(WTFMove(shadow));
2323     return result;
2324 }
2325
2326 ShadowRoot* Element::shadowRootForBindings(JSC::ExecState& state) const
2327 {
2328     auto* shadow = shadowRoot();
2329     if (!shadow)
2330         return nullptr;
2331     if (shadow->mode() == ShadowRootMode::Open)
2332         return shadow;
2333     if (JSC::jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject())->world().shadowRootIsAlwaysOpen())
2334         return shadow;
2335     return nullptr;
2336 }
2337
2338 RefPtr<ShadowRoot> Element::userAgentShadowRoot() const
2339 {
2340     ASSERT(!shadowRoot() || shadowRoot()->mode() == ShadowRootMode::UserAgent);
2341     return shadowRoot();
2342 }
2343
2344 ShadowRoot& Element::ensureUserAgentShadowRoot()
2345 {
2346     if (auto shadow = userAgentShadowRoot())
2347         return *shadow;
2348     auto newShadow = ShadowRoot::create(document(), ShadowRootMode::UserAgent);
2349     ShadowRoot& shadow = newShadow;
2350     addShadowRoot(WTFMove(newShadow));
2351     return shadow;
2352 }
2353
2354 void Element::setIsDefinedCustomElement(JSCustomElementInterface& elementInterface)
2355 {
2356     clearFlag(IsEditingTextOrUndefinedCustomElementFlag);
2357     setFlag(IsCustomElement);
2358     auto& data = ensureElementRareData();
2359     if (!data.customElementReactionQueue())
2360         data.setCustomElementReactionQueue(makeUnique<CustomElementReactionQueue>(elementInterface));
2361     invalidateStyleForSubtree();
2362     InspectorInstrumentation::didChangeCustomElementState(*this);
2363 }
2364
2365 void Element::setIsFailedCustomElement(JSCustomElementInterface&)
2366 {
2367     ASSERT(isUndefinedCustomElement());
2368     ASSERT(getFlag(IsEditingTextOrUndefinedCustomElementFlag));
2369     clearFlag(IsCustomElement);
2370
2371     if (hasRareData()) {
2372         // Clear the queue instead of deleting it since this function can be called inside CustomElementReactionQueue::invokeAll during upgrades.
2373         if (auto* queue = elementRareData()->customElementReactionQueue())
2374             queue->clear();
2375     }
2376     InspectorInstrumentation::didChangeCustomElementState(*this);
2377 }
2378
2379 void Element::setIsCustomElementUpgradeCandidate()
2380 {
2381     ASSERT(!getFlag(IsCustomElement));
2382     setFlag(IsCustomElement);
2383     setFlag(IsEditingTextOrUndefinedCustomElementFlag);
2384     InspectorInstrumentation::didChangeCustomElementState(*this);
2385 }
2386
2387 void Element::enqueueToUpgrade(JSCustomElementInterface& elementInterface)
2388 {
2389     ASSERT(!isDefinedCustomElement() && !isFailedCustomElement());
2390     setFlag(IsCustomElement);
2391     setFlag(IsEditingTextOrUndefinedCustomElementFlag);
2392     InspectorInstrumentation::didChangeCustomElementState(*this);
2393
2394     auto& data = ensureElementRareData();
2395     bool alreadyScheduledToUpgrade = data.customElementReactionQueue();
2396     if (!alreadyScheduledToUpgrade)
2397         data.setCustomElementReactionQueue(makeUnique<CustomElementReactionQueue>(elementInterface));
2398     data.customElementReactionQueue()->enqueueElementUpgrade(*this, alreadyScheduledToUpgrade);
2399 }
2400
2401 CustomElementReactionQueue* Element::reactionQueue() const
2402 {
2403     ASSERT(isDefinedCustomElement() || isCustomElementUpgradeCandidate());
2404     if (!hasRareData())
2405         return nullptr;
2406     return elementRareData()->customElementReactionQueue();
2407 }
2408
2409 const AtomString& Element::shadowPseudoId() const
2410 {
2411     return pseudo();
2412 }
2413
2414 bool Element::childTypeAllowed(NodeType type) const
2415 {
2416     switch (type) {
2417     case ELEMENT_NODE:
2418     case TEXT_NODE:
2419     case COMMENT_NODE:
2420     case PROCESSING_INSTRUCTION_NODE:
2421     case CDATA_SECTION_NODE:
2422         return true;
2423     default:
2424         break;
2425     }
2426     return false;
2427 }
2428
2429 static void checkForEmptyStyleChange(Element& element)
2430 {
2431     if (element.styleAffectedByEmpty()) {
2432         auto* style = element.renderStyle();
2433         if (!style || (!style->emptyState() || element.hasChildNodes()))
2434             element.invalidateStyleForSubtree();
2435     }
2436 }
2437
2438
2439 static void invalidateForForwardPositionalRules(Element& parent, Element* elementAfterChange)
2440 {
2441     bool childrenAffected = parent.childrenAffectedByForwardPositionalRules();
2442     bool descendantsAffected = parent.descendantsAffectedByForwardPositionalRules();
2443
2444     if (!childrenAffected && !descendantsAffected)
2445         return;
2446
2447     for (auto* sibling = elementAfterChange; sibling; sibling = sibling->nextElementSibling()) {
2448         if (childrenAffected)
2449             sibling->invalidateStyleInternal();
2450         if (descendantsAffected) {
2451             for (auto* siblingChild = sibling->firstElementChild(); siblingChild; siblingChild = siblingChild->nextElementSibling())
2452                 siblingChild->invalidateStyleForSubtreeInternal();
2453         }
2454     }
2455 }
2456
2457 static void invalidateForBackwardPositionalRules(Element& parent, Element* elementBeforeChange)
2458 {
2459     bool childrenAffected = parent.childrenAffectedByBackwardPositionalRules();
2460     bool descendantsAffected = parent.descendantsAffectedByBackwardPositionalRules();
2461
2462     if (!childrenAffected && !descendantsAffected)
2463         return;
2464
2465     for (auto* sibling = elementBeforeChange; sibling; sibling = sibling->previousElementSibling()) {
2466         if (childrenAffected)
2467             sibling->invalidateStyleInternal();
2468         if (descendantsAffected) {
2469             for (auto* siblingChild = sibling->firstElementChild(); siblingChild; siblingChild = siblingChild->nextElementSibling())
2470                 siblingChild->invalidateStyleForSubtreeInternal();
2471         }
2472     }
2473 }
2474
2475 enum SiblingCheckType { FinishedParsingChildren, SiblingElementRemoved, Other };
2476
2477 static void checkForSiblingStyleChanges(Element& parent, SiblingCheckType checkType, Element* elementBeforeChange, Element* elementAfterChange)
2478 {
2479     // :empty selector.
2480     checkForEmptyStyleChange(parent);
2481
2482     if (parent.styleValidity() >= Style::Validity::SubtreeInvalid)
2483         return;
2484
2485     // :first-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
2486     // In the DOM case, we only need to do something if |afterChange| is not 0.
2487     // |afterChange| is 0 in the parser case, so it works out that we'll skip this block.
2488     if (parent.childrenAffectedByFirstChildRules() && elementAfterChange) {
2489         // Find our new first child.
2490         RefPtr<Element> newFirstElement = ElementTraversal::firstChild(parent);
2491         // Find the first element node following |afterChange|
2492
2493         // This is the insert/append case.
2494         if (newFirstElement != elementAfterChange) {
2495             auto* style = elementAfterChange->renderStyle();
2496             if (!style || style->firstChildState())
2497                 elementAfterChange->invalidateStyleForSubtreeInternal();
2498         }
2499
2500         // We also have to handle node removal.
2501         if (checkType == SiblingElementRemoved && newFirstElement == elementAfterChange && newFirstElement) {
2502             auto* style = newFirstElement->renderStyle();
2503             if (!style || !style->firstChildState())
2504                 newFirstElement->invalidateStyleForSubtreeInternal();
2505         }
2506     }
2507
2508     // :last-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
2509     // In the DOM case, we only need to do something if |afterChange| is not 0.
2510     if (parent.childrenAffectedByLastChildRules() && elementBeforeChange) {
2511         // Find our new last child.
2512         RefPtr<Element> newLastElement = ElementTraversal::lastChild(parent);
2513
2514         if (newLastElement != elementBeforeChange) {
2515             auto* style = elementBeforeChange->renderStyle();
2516             if (!style || style->lastChildState())
2517                 elementBeforeChange->invalidateStyleForSubtreeInternal();
2518         }
2519
2520         // 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
2521         // to match now.
2522         if ((checkType == SiblingElementRemoved || checkType == FinishedParsingChildren) && newLastElement == elementBeforeChange && newLastElement) {
2523             auto* style = newLastElement->renderStyle();
2524             if (!style || !style->lastChildState())
2525                 newLastElement->invalidateStyleForSubtreeInternal();
2526         }
2527     }
2528
2529     invalidateForSiblingCombinators(elementAfterChange);
2530
2531     invalidateForForwardPositionalRules(parent, elementAfterChange);
2532     invalidateForBackwardPositionalRules(parent, elementBeforeChange);
2533 }
2534
2535 void Element::childrenChanged(const ChildChange& change)
2536 {
2537     ContainerNode::childrenChanged(change);
2538     if (change.source == ChildChangeSource::Parser)
2539         checkForEmptyStyleChange(*this);
2540     else {
2541         SiblingCheckType checkType = change.type == ElementRemoved ? SiblingElementRemoved : Other;
2542         checkForSiblingStyleChanges(*this, checkType, change.previousSiblingElement, change.nextSiblingElement);
2543     }
2544
2545     if (ShadowRoot* shadowRoot = this->shadowRoot()) {
2546         switch (change.type) {
2547         case ElementInserted:
2548         case ElementRemoved:
2549             // For elements, we notify shadowRoot in Element::insertedIntoAncestor and Element::removedFromAncestor.
2550             break;
2551         case AllChildrenRemoved:
2552         case AllChildrenReplaced:
2553             shadowRoot->didRemoveAllChildrenOfShadowHost();
2554             break;
2555         case TextInserted:
2556         case TextRemoved:
2557         case TextChanged:
2558             shadowRoot->didChangeDefaultSlot();
2559             break;
2560         case NonContentsChildInserted:
2561         case NonContentsChildRemoved:
2562             break;
2563         }
2564     }
2565 }
2566
2567 void Element::setAttributeEventListener(const AtomString& eventType, const QualifiedName& attributeName, const AtomString& attributeValue)
2568 {
2569     setAttributeEventListener(eventType, JSLazyEventListener::create(*this, attributeName, attributeValue), mainThreadNormalWorld());
2570 }
2571
2572 void Element::removeAllEventListeners()
2573 {
2574     ContainerNode::removeAllEventListeners();
2575     if (ShadowRoot* shadowRoot = this->shadowRoot())
2576         shadowRoot->removeAllEventListeners();
2577 }
2578
2579 void Element::beginParsingChildren()
2580 {
2581     clearIsParsingChildrenFinished();
2582 }
2583
2584 void Element::finishParsingChildren()
2585 {
2586     ContainerNode::finishParsingChildren();
2587     setIsParsingChildrenFinished();
2588     checkForSiblingStyleChanges(*this, FinishedParsingChildren, ElementTraversal::lastChild(*this), nullptr);
2589 }
2590
2591 #if ENABLE(TREE_DEBUGGING)
2592 void Element::formatForDebugger(char* buffer, unsigned length) const
2593 {
2594     StringBuilder result;
2595     String s;
2596
2597     result.append(nodeName());
2598
2599     s = getIdAttribute();
2600     if (s.length() > 0) {
2601         if (result.length() > 0)
2602             result.appendLiteral("; ");
2603         result.appendLiteral("id=");
2604         result.append(s);
2605     }
2606
2607     s = getAttribute(classAttr);
2608     if (s.length() > 0) {
2609         if (result.length() > 0)
2610             result.appendLiteral("; ");
2611         result.appendLiteral("class=");
2612         result.append(s);
2613     }
2614
2615     strncpy(buffer, result.toString().utf8().data(), length - 1);
2616 }
2617 #endif
2618
2619 const Vector<RefPtr<Attr>>& Element::attrNodeList()
2620 {
2621     ASSERT(hasSyntheticAttrChildNodes());
2622     return *attrNodeListForElement(*this);
2623 }
2624
2625 void Element::attachAttributeNodeIfNeeded(Attr& attrNode)
2626 {
2627     ASSERT(!attrNode.ownerElement() || attrNode.ownerElement() == this);
2628     if (attrNode.ownerElement() == this)
2629         return;
2630
2631     ScriptDisallowedScope::InMainThread scriptDisallowedScope;
2632
2633     attrNode.attachToElement(*this);
2634     ensureAttrNodeListForElement(*this).append(&attrNode);
2635 }
2636
2637 ExceptionOr<RefPtr<Attr>> Element::setAttributeNode(Attr& attrNode)
2638 {
2639     RefPtr<Attr> oldAttrNode = attrIfExists(attrNode.localName(), shouldIgnoreAttributeCase(*this));
2640     if (oldAttrNode.get() == &attrNode)
2641         return oldAttrNode;
2642
2643     // InUseAttributeError: Raised if node is an Attr that is already an attribute of another Element object.
2644     // The DOM user must explicitly clone Attr nodes to re-use them in other elements.
2645     if (attrNode.ownerElement() && attrNode.ownerElement() != this)
2646         return Exception { InUseAttributeError };
2647
2648     {
2649         ScriptDisallowedScope::InMainThread scriptDisallowedScope;
2650         synchronizeAllAttributes();
2651     }
2652
2653     auto& elementData = ensureUniqueElementData();
2654
2655     auto existingAttributeIndex = elementData.findAttributeIndexByName(attrNode.localName(), shouldIgnoreAttributeCase(*this));
2656
2657     // Attr::value() will return its 'm_standaloneValue' member any time its Element is set to nullptr. We need to cache this value
2658     // before making changes to attrNode's Element connections.
2659     auto attrNodeValue = attrNode.value();
2660
2661     if (existingAttributeIndex == ElementData::attributeNotFound) {
2662         attachAttributeNodeIfNeeded(attrNode);
2663         setAttributeInternal(elementData.findAttributeIndexByName(attrNode.qualifiedName()), attrNode.qualifiedName(), attrNodeValue, NotInSynchronizationOfLazyAttribute);
2664     } else {
2665         const Attribute& attribute = attributeAt(existingAttributeIndex);
2666         if (oldAttrNode)
2667             detachAttrNodeFromElementWithValue(oldAttrNode.get(), attribute.value());
2668         else
2669             oldAttrNode = Attr::create(document(), attrNode.qualifiedName(), attribute.value());
2670
2671         attachAttributeNodeIfNeeded(attrNode);
2672
2673         if (attribute.name().matches(attrNode.qualifiedName()))
2674             setAttributeInternal(existingAttributeIndex, attrNode.qualifiedName(), attrNodeValue, NotInSynchronizationOfLazyAttribute);
2675         else {
2676             removeAttributeInternal(existingAttributeIndex, NotInSynchronizationOfLazyAttribute);
2677             setAttributeInternal(ensureUniqueElementData().findAttributeIndexByName(attrNode.qualifiedName()), attrNode.qualifiedName(), attrNodeValue, NotInSynchronizationOfLazyAttribute);
2678         }
2679     }
2680
2681     return oldAttrNode;
2682 }
2683
2684 ExceptionOr<RefPtr<Attr>> Element::setAttributeNodeNS(Attr& attrNode)
2685 {
2686     RefPtr<Attr> oldAttrNode = attrIfExists(attrNode.qualifiedName());
2687     if (oldAttrNode.get() == &attrNode)
2688         return oldAttrNode;
2689
2690     // InUseAttributeError: Raised if node is an Attr that is already an attribute of another Element object.
2691     // The DOM user must explicitly clone Attr nodes to re-use them in other elements.
2692     if (attrNode.ownerElement() && attrNode.ownerElement() != this)
2693         return Exception { InUseAttributeError };
2694
2695     // Attr::value() will return its 'm_standaloneValue' member any time its Element is set to nullptr. We need to cache this value
2696     // before making changes to attrNode's Element connections.
2697     auto attrNodeValue = attrNode.value();
2698     unsigned index = 0;
2699     {
2700         ScriptDisallowedScope::InMainThread scriptDisallowedScope;
2701         synchronizeAllAttributes();
2702         auto& elementData = ensureUniqueElementData();
2703
2704         index = elementData.findAttributeIndexByName(attrNode.qualifiedName());
2705
2706         if (index != ElementData::attributeNotFound) {
2707             if (oldAttrNode)
2708                 detachAttrNodeFromElementWithValue(oldAttrNode.get(), elementData.attributeAt(index).value());
2709             else
2710                 oldAttrNode = Attr::create(document(), attrNode.qualifiedName(), elementData.attributeAt(index).value());
2711         }
2712     }
2713
2714     attachAttributeNodeIfNeeded(attrNode);
2715     setAttributeInternal(index, attrNode.qualifiedName(), attrNodeValue, NotInSynchronizationOfLazyAttribute);
2716
2717     return oldAttrNode;
2718 }
2719
2720 ExceptionOr<Ref<Attr>> Element::removeAttributeNode(Attr& attr)
2721 {
2722     if (attr.ownerElement() != this)
2723         return Exception { NotFoundError };
2724
2725     ASSERT(&document() == &attr.document());
2726
2727     synchronizeAllAttributes();
2728
2729     if (!m_elementData)
2730         return Exception { NotFoundError };
2731
2732     auto existingAttributeIndex = m_elementData->findAttributeIndexByName(attr.qualifiedName());
2733     if (existingAttributeIndex == ElementData::attributeNotFound)
2734         return Exception { NotFoundError };
2735
2736     Ref<Attr> oldAttrNode { attr };
2737
2738     detachAttrNodeFromElementWithValue(&attr, m_elementData->attributeAt(existingAttributeIndex).value());
2739     removeAttributeInternal(existingAttributeIndex, NotInSynchronizationOfLazyAttribute);
2740
2741     return oldAttrNode;
2742 }
2743
2744 ExceptionOr<QualifiedName> Element::parseAttributeName(const AtomString& namespaceURI, const AtomString& qualifiedName)
2745 {
2746     auto parseResult = Document::parseQualifiedName(namespaceURI, qualifiedName);
2747     if (parseResult.hasException())
2748         return parseResult.releaseException();
2749     QualifiedName parsedAttributeName { parseResult.releaseReturnValue() };
2750     if (!Document::hasValidNamespaceForAttributes(parsedAttributeName))
2751         return Exception { NamespaceError };
2752     return parsedAttributeName;
2753 }
2754
2755 ExceptionOr<void> Element::setAttributeNS(const AtomString& namespaceURI, const AtomString& qualifiedName, const AtomString& value)
2756 {
2757     auto result = parseAttributeName(namespaceURI, qualifiedName);
2758     if (result.hasException())
2759         return result.releaseException();
2760     setAttribute(result.releaseReturnValue(), value);
2761     return { };
2762 }
2763
2764 void Element::removeAttributeInternal(unsigned index, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
2765 {
2766     ASSERT_WITH_SECURITY_IMPLICATION(index < attributeCount());
2767
2768     UniqueElementData& elementData = ensureUniqueElementData();
2769
2770     QualifiedName name = elementData.attributeAt(index).name();
2771     AtomString valueBeingRemoved = elementData.attributeAt(index).value();
2772
2773     if (RefPtr<Attr> attrNode = attrIfExists(name))
2774         detachAttrNodeFromElementWithValue(attrNode.get(), elementData.attributeAt(index).value());
2775
2776     if (inSynchronizationOfLazyAttribute) {
2777         elementData.removeAttribute(index);
2778         return;
2779     }
2780
2781     ASSERT(!valueBeingRemoved.isNull());
2782     willModifyAttribute(name, valueBeingRemoved, nullAtom());
2783     {
2784         Style::AttributeChangeInvalidation styleInvalidation(*this, name, valueBeingRemoved, nullAtom());
2785         elementData.removeAttribute(index);
2786     }
2787
2788     didRemoveAttribute(name, valueBeingRemoved);
2789 }
2790
2791 void Element::addAttributeInternal(const QualifiedName& name, const AtomString& value, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
2792 {
2793     if (inSynchronizationOfLazyAttribute) {
2794         ensureUniqueElementData().addAttribute(name, value);
2795         return;
2796     }
2797
2798     willModifyAttribute(name, nullAtom(), value);
2799     {
2800         Style::AttributeChangeInvalidation styleInvalidation(*this, name, nullAtom(), value);
2801         ensureUniqueElementData().addAttribute(name, value);
2802     }
2803     didAddAttribute(name, value);
2804 }
2805
2806 bool Element::removeAttribute(const AtomString& qualifiedName)
2807 {
2808     if (!elementData())
2809         return false;
2810
2811     AtomString caseAdjustedQualifiedName = shouldIgnoreAttributeCase(*this) ? qualifiedName.convertToASCIILowercase() : qualifiedName;
2812     unsigned index = elementData()->findAttributeIndexByName(caseAdjustedQualifiedName, false);
2813     if (index == ElementData::attributeNotFound) {
2814         if (UNLIKELY(caseAdjustedQualifiedName == styleAttr) && elementData()->styleAttributeIsDirty() && is<StyledElement>(*this))
2815             downcast<StyledElement>(*this).removeAllInlineStyleProperties();
2816         return false;
2817     }
2818
2819     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
2820     return true;
2821 }
2822
2823 bool Element::removeAttributeNS(const AtomString& namespaceURI, const AtomString& localName)
2824 {
2825     return removeAttribute(QualifiedName(nullAtom(), localName, namespaceURI));
2826 }
2827
2828 RefPtr<Attr> Element::getAttributeNode(const AtomString& qualifiedName)
2829 {
2830     if (!elementData())
2831         return nullptr;
2832     synchronizeAttribute(qualifiedName);
2833     const Attribute* attribute = elementData()->findAttributeByName(qualifiedName, shouldIgnoreAttributeCase(*this));
2834     if (!attribute)
2835         return nullptr;
2836     return ensureAttr(attribute->name());
2837 }
2838
2839 RefPtr<Attr> Element::getAttributeNodeNS(const AtomString& namespaceURI, const AtomString& localName)
2840 {
2841     if (!elementData())
2842         return 0;
2843     QualifiedName qName(nullAtom(), localName, namespaceURI);
2844     synchronizeAttribute(qName);
2845     const Attribute* attribute = elementData()->findAttributeByName(qName);
2846     if (!attribute)
2847         return 0;
2848     return ensureAttr(attribute->name());
2849 }
2850
2851 bool Element::hasAttribute(const AtomString& qualifiedName) const
2852 {
2853     if (!elementData())
2854         return false;
2855     synchronizeAttribute(qualifiedName);
2856     return elementData()->findAttributeByName(qualifiedName, shouldIgnoreAttributeCase(*this));
2857 }
2858
2859 bool Element::hasAttributeNS(const AtomString& namespaceURI, const AtomString& localName) const
2860 {
2861     if (!elementData())
2862         return false;
2863     QualifiedName qName(nullAtom(), localName, namespaceURI);
2864     synchronizeAttribute(qName);
2865     return elementData()->findAttributeByName(qName);
2866 }
2867
2868 void Element::focus(bool restorePreviousSelection, FocusDirection direction)
2869 {
2870     if (!isConnected())
2871         return;
2872
2873     if (document().focusedElement() == this) {
2874         if (document().page())
2875             document().page()->chrome().client().elementDidRefocus(*this);
2876
2877         return;
2878     }
2879
2880     // If the stylesheets have already been loaded we can reliably check isFocusable.
2881     // If not, we continue and set the focused node on the focus controller below so
2882     // that it can be updated soon after attach. 
2883     if (document().haveStylesheetsLoaded()) {
2884         document().updateStyleIfNeeded();
2885         if (!isFocusable())
2886             return;
2887     }
2888
2889     if (!supportsFocus())
2890         return;
2891
2892     RefPtr<Node> protect;
2893     if (Page* page = document().page()) {
2894         auto& frame = *document().frame();
2895         if (!frame.hasHadUserInteraction() && !frame.isMainFrame() && !document().topDocument().securityOrigin().canAccess(document().securityOrigin()))
2896             return;
2897
2898         // Focus and change event handlers can cause us to lose our last ref.
2899         // If a focus event handler changes the focus to a different node it
2900         // does not make sense to continue and update appearence.
2901         protect = this;
2902         if (!page->focusController().setFocusedElement(this, *document().frame(), direction))
2903             return;
2904     }
2905
2906     SelectionRevealMode revealMode = SelectionRevealMode::Reveal;
2907 #if PLATFORM(IOS_FAMILY)
2908     // Focusing a form element triggers animation in UIKit to scroll to the right position.
2909     // Calling updateFocusAppearance() would generate an unnecessary call to ScrollView::setScrollPosition(),
2910     // which would jump us around during this animation. See <rdar://problem/6699741>.
2911     bool isFormControl = is<HTMLFormControlElement>(*this);
2912     if (isFormControl)
2913         revealMode = SelectionRevealMode::RevealUpToMainFrame;
2914 #endif
2915
2916     auto target = focusAppearanceUpdateTarget();
2917     if (!target)
2918         return;
2919
2920     target->updateFocusAppearance(restorePreviousSelection ? SelectionRestorationMode::Restore : SelectionRestorationMode::SetDefault, revealMode);
2921 }
2922
2923 RefPtr<Element> Element::focusAppearanceUpdateTarget()
2924 {
2925     return this;
2926 }
2927
2928 void Element::updateFocusAppearance(SelectionRestorationMode, SelectionRevealMode revealMode)
2929 {
2930     if (isRootEditableElement()) {
2931         // Keep frame alive in this method, since setSelection() may release the last reference to |frame|.
2932         RefPtr<Frame> frame = document().frame();
2933         if (!frame)
2934             return;
2935         
2936         // When focusing an editable element in an iframe, don't reset the selection if it already contains a selection.
2937         if (this == frame->selection().selection().rootEditableElement())
2938             return;
2939
2940         // FIXME: We should restore the previous selection if there is one.
2941         VisibleSelection newSelection = VisibleSelection(firstPositionInOrBeforeNode(this), DOWNSTREAM);
2942         
2943         if (frame->selection().shouldChangeSelection(newSelection)) {
2944             frame->selection().setSelection(newSelection, FrameSelection::defaultSetSelectionOptions(), Element::defaultFocusTextStateChangeIntent());
2945             frame->selection().revealSelection(revealMode);
2946             return;
2947         }
2948     }
2949
2950     if (RefPtr<FrameView> view = document().view())
2951         view->scheduleScrollToFocusedElement(revealMode);
2952 }
2953
2954 void Element::blur()
2955 {
2956     if (treeScope().focusedElementInScope() == this) {
2957         if (Frame* frame = document().frame())
2958             frame->page()->focusController().setFocusedElement(nullptr, *frame);
2959         else
2960             document().setFocusedElement(nullptr);
2961     }
2962 }
2963
2964 void Element::dispatchFocusInEvent(const AtomString& eventType, RefPtr<Element>&& oldFocusedElement)
2965 {
2966     ASSERT_WITH_SECURITY_IMPLICATION(ScriptDisallowedScope::InMainThread::isScriptAllowed());
2967     ASSERT(eventType == eventNames().focusinEvent || eventType == eventNames().DOMFocusInEvent);
2968     dispatchScopedEvent(FocusEvent::create(eventType, Event::CanBubble::Yes, Event::IsCancelable::No, document().windowProxy(), 0, WTFMove(oldFocusedElement)));
2969 }
2970
2971 void Element::dispatchFocusOutEvent(const AtomString& eventType, RefPtr<Element>&& newFocusedElement)
2972 {
2973     ASSERT_WITH_SECURITY_IMPLICATION(ScriptDisallowedScope::InMainThread::isScriptAllowed());
2974     ASSERT(eventType == eventNames().focusoutEvent || eventType == eventNames().DOMFocusOutEvent);
2975     dispatchScopedEvent(FocusEvent::create(eventType, Event::CanBubble::Yes, Event::IsCancelable::No, document().windowProxy(), 0, WTFMove(newFocusedElement)));
2976 }
2977
2978 void Element::dispatchFocusEvent(RefPtr<Element>&& oldFocusedElement, FocusDirection)
2979 {
2980     if (auto* page = document().page())
2981         page->chrome().client().elementDidFocus(*this);
2982     dispatchEvent(FocusEvent::create(eventNames().focusEvent, Event::CanBubble::No, Event::IsCancelable::No, document().windowProxy(), 0, WTFMove(oldFocusedElement)));
2983 }
2984
2985 void Element::dispatchBlurEvent(RefPtr<Element>&& newFocusedElement)
2986 {
2987     if (auto* page = document().page())
2988         page->chrome().client().elementDidBlur(*this);
2989     dispatchEvent(FocusEvent::create(eventNames().blurEvent, Event::CanBubble::No, Event::IsCancelable::No, document().windowProxy(), 0, WTFMove(newFocusedElement)));
2990 }
2991
2992 void Element::dispatchWebKitImageReadyEventForTesting()
2993 {
2994     if (document().settings().webkitImageReadyEventEnabled())
2995         dispatchEvent(Event::create("webkitImageFrameReady", Event::CanBubble::Yes, Event::IsCancelable::Yes));
2996 }
2997
2998 bool Element::dispatchMouseForceWillBegin()
2999 {
3000 #if ENABLE(MOUSE_FORCE_EVENTS)
3001     if (!document().hasListenerType(Document::FORCEWILLBEGIN_LISTENER))
3002         return false;
3003
3004     Frame* frame = document().frame();
3005     if (!frame)
3006         return false;
3007
3008     PlatformMouseEvent platformMouseEvent { frame->eventHandler().lastKnownMousePosition(), frame->eventHandler().lastKnownMouseGlobalPosition(), NoButton, PlatformEvent::NoType, 1, false, false, false, false, WallTime::now(), ForceAtClick, NoTap };
3009     auto mouseForceWillBeginEvent = MouseEvent::create(eventNames().webkitmouseforcewillbeginEvent, document().windowProxy(), platformMouseEvent, 0, nullptr);
3010     mouseForceWillBeginEvent->setTarget(this);
3011     dispatchEvent(mouseForceWillBeginEvent);
3012
3013     if (mouseForceWillBeginEvent->defaultHandled() || mouseForceWillBeginEvent->defaultPrevented())
3014         return true;
3015 #endif
3016
3017     return false;
3018 }
3019
3020 ExceptionOr<void> Element::mergeWithNextTextNode(Text& node)
3021 {
3022     auto* next = node.nextSibling();
3023     if (!is<Text>(next))
3024         return { };
3025     Ref<Text> textNext { downcast<Text>(*next) };
3026     node.appendData(textNext->data());
3027     return textNext->remove();
3028 }
3029
3030 String Element::innerHTML() const
3031 {
3032     return serializeFragment(*this, SerializedNodes::SubtreesOfChildren);
3033 }
3034
3035 String Element::outerHTML() const
3036 {
3037     return serializeFragment(*this, SerializedNodes::SubtreeIncludingNode);
3038 }
3039
3040 ExceptionOr<void> Element::setOuterHTML(const String& html)
3041 {
3042     auto* parentElement = this->parentElement();
3043     if (!is<HTMLElement>(parentElement))
3044         return Exception { NoModificationAllowedError };
3045
3046     Ref<HTMLElement> parent = downcast<HTMLElement>(*parentElement);
3047     RefPtr<Node> prev = previousSibling();
3048     RefPtr<Node> next = nextSibling();
3049
3050     auto fragment = createFragmentForInnerOuterHTML(parent, html, AllowScriptingContent);
3051     if (fragment.hasException())
3052         return fragment.releaseException();
3053
3054     auto replaceResult = parent->replaceChild(fragment.releaseReturnValue().get(), *this);
3055     if (replaceResult.hasException())
3056         return replaceResult.releaseException();
3057
3058     RefPtr<Node> node = next ? next->previousSibling() : nullptr;
3059     if (is<Text>(node)) {
3060         auto result = mergeWithNextTextNode(downcast<Text>(*node));
3061         if (result.hasException())
3062             return result.releaseException();
3063     }
3064     if (is<Text>(prev)) {
3065         auto result = mergeWithNextTextNode(downcast<Text>(*prev));
3066         if (result.hasException())
3067             return result.releaseException();
3068     }
3069     return { };
3070 }
3071
3072
3073 ExceptionOr<void> Element::setInnerHTML(const String& html)
3074 {
3075     auto fragment = createFragmentForInnerOuterHTML(*this, html, AllowScriptingContent);
3076     if (fragment.hasException())
3077         return fragment.releaseException();
3078
3079     ContainerNode* container;
3080     if (!is<HTMLTemplateElement>(*this))
3081         container = this;
3082     else
3083         container = &downcast<HTMLTemplateElement>(*this).content();
3084
3085     return replaceChildrenWithFragment(*container, fragment.releaseReturnValue());
3086 }
3087
3088 String Element::innerText()
3089 {
3090     // We need to update layout, since plainText uses line boxes in the render tree.
3091     document().updateLayoutIgnorePendingStylesheets();
3092
3093     if (!renderer())
3094         return textContent(true);
3095
3096     return plainText(rangeOfContents(*this).ptr());
3097 }
3098
3099 String Element::outerText()
3100 {
3101     // Getting outerText is the same as getting innerText, only
3102     // setting is different. You would think this should get the plain
3103     // text for the outer range, but this is wrong, <br> for instance
3104     // would return different values for inner and outer text by such
3105     // a rule, but it doesn't in WinIE, and we want to match that.
3106     return innerText();
3107 }
3108
3109 String Element::title() const
3110 {
3111     return String();
3112 }
3113
3114 const AtomString& Element::pseudo() const
3115 {
3116     return attributeWithoutSynchronization(pseudoAttr);
3117 }
3118
3119 void Element::setPseudo(const AtomString& value)
3120 {
3121     setAttributeWithoutSynchronization(pseudoAttr, value);
3122 }
3123
3124 LayoutSize Element::minimumSizeForResizing() const
3125 {
3126     return hasRareData() ? elementRareData()->minimumSizeForResizing() : defaultMinimumSizeForResizing();
3127 }
3128
3129 void Element::setMinimumSizeForResizing(const LayoutSize& size)
3130 {
3131     if (!hasRareData() && size == defaultMinimumSizeForResizing())
3132         return;
3133     ensureElementRareData().setMinimumSizeForResizing(size);
3134 }
3135
3136 void Element::willBecomeFullscreenElement()
3137 {
3138     for (auto& child : descendantsOfType<Element>(*this))
3139         child.ancestorWillEnterFullscreen();
3140 }
3141
3142 static PseudoElement* beforeOrAfterPseudoElement(Element& host, PseudoId pseudoElementSpecifier)
3143 {
3144     switch (pseudoElementSpecifier) {
3145     case PseudoId::Before:
3146         return host.beforePseudoElement();
3147     case PseudoId::After:
3148         return host.afterPseudoElement();
3149     default:
3150         return nullptr;
3151     }
3152 }
3153
3154 const RenderStyle* Element::existingComputedStyle() const
3155 {
3156     if (hasRareData()) {
3157         if (auto* style = elementRareData()->computedStyle())
3158             return style;
3159     }
3160
3161     return renderStyle();
3162 }
3163
3164 const RenderStyle* Element::renderOrDisplayContentsStyle() const
3165 {
3166     if (auto* style = renderStyle())
3167         return style;
3168
3169     if (!hasRareData())
3170         return nullptr;
3171     auto* style = elementRareData()->computedStyle();
3172     if (style && style->display() == DisplayType::Contents)
3173         return style;
3174
3175     return nullptr;
3176 }
3177
3178 const RenderStyle& Element::resolveComputedStyle()
3179 {
3180     ASSERT(isConnected());
3181     ASSERT(!existingComputedStyle());
3182
3183     Deque<RefPtr<Element>, 32> elementsRequiringComputedStyle({ this });
3184     const RenderStyle* computedStyle = nullptr;
3185
3186     // Collect ancestors until we find one that has style.
3187     auto composedAncestors = composedTreeAncestors(*this);
3188     for (auto& ancestor : composedAncestors) {
3189         if (auto* existingStyle = ancestor.existingComputedStyle()) {
3190             computedStyle = existingStyle;
3191             break;
3192         }
3193         elementsRequiringComputedStyle.prepend(&ancestor);
3194     }
3195
3196     // Resolve and cache styles starting from the most distant ancestor.
3197     for (auto& element : elementsRequiringComputedStyle) {
3198         auto style = document().styleForElementIgnoringPendingStylesheets(*element, computedStyle);
3199         computedStyle = style.get();
3200         ElementRareData& rareData = element->ensureElementRareData();
3201         rareData.setComputedStyle(WTFMove(style));
3202     }
3203
3204     return *computedStyle;
3205 }
3206
3207 const RenderStyle& Element::resolvePseudoElementStyle(PseudoId pseudoElementSpecifier)
3208 {
3209     ASSERT(!isPseudoElement());
3210
3211     auto* parentStyle = existingComputedStyle();
3212     ASSERT(parentStyle);
3213     ASSERT(!parentStyle->getCachedPseudoStyle(pseudoElementSpecifier));
3214
3215     auto style = document().styleForElementIgnoringPendingStylesheets(*this, parentStyle, pseudoElementSpecifier);
3216     if (!style) {
3217         style = RenderStyle::createPtr();
3218         style->inheritFrom(*parentStyle);
3219         style->setStyleType(pseudoElementSpecifier);
3220     }
3221
3222     auto* computedStyle = style.get();
3223     const_cast<RenderStyle*>(parentStyle)->addCachedPseudoStyle(WTFMove(style));
3224     return *computedStyle;
3225 }
3226
3227 const RenderStyle* Element::computedStyle(PseudoId pseudoElementSpecifier)
3228 {
3229     if (!isConnected())
3230         return nullptr;
3231
3232     if (PseudoElement* pseudoElement = beforeOrAfterPseudoElement(*this, pseudoElementSpecifier))
3233         return pseudoElement->computedStyle();
3234
3235     auto* style = existingComputedStyle();
3236     if (!style)
3237         style = &resolveComputedStyle();
3238
3239     if (pseudoElementSpecifier != PseudoId::None) {
3240         if (auto* cachedPseudoStyle = style->getCachedPseudoStyle(pseudoElementSpecifier))
3241             return cachedPseudoStyle;
3242         return &resolvePseudoElementStyle(pseudoElementSpecifier);
3243     }
3244
3245     return style;
3246 }
3247
3248 bool Element::needsStyleInvalidation() const
3249 {
3250     if (!inRenderedDocument())
3251         return false;
3252     if (styleValidity() >= Style::Validity::SubtreeInvalid)
3253         return false;
3254     if (document().hasPendingFullStyleRebuild())
3255         return false;
3256
3257     return true;
3258 }
3259
3260 void Element::setChildIndex(unsigned index)
3261 {
3262     ElementRareData& rareData = ensureElementRareData();
3263     rareData.setChildIndex(index);
3264 }
3265
3266 bool Element::hasFlagsSetDuringStylingOfChildren() const
3267 {
3268     return styleAffectedByActive()
3269         || childrenAffectedByHover()
3270         || childrenAffectedByFirstChildRules()
3271         || childrenAffectedByLastChildRules()
3272         || childrenAffectedByDrag()
3273         || childrenAffectedByForwardPositionalRules()
3274         || descendantsAffectedByForwardPositionalRules()
3275         || childrenAffectedByBackwardPositionalRules()
3276         || descendantsAffectedByBackwardPositionalRules()
3277         || childrenAffectedByPropertyBasedBackwardPositionalRules();
3278 }
3279
3280 unsigned Element::rareDataChildIndex() const
3281 {
3282     ASSERT(hasRareData());
3283     return elementRareData()->childIndex();
3284 }
3285
3286 AtomString Element::computeInheritedLanguage() const
3287 {
3288     if (const ElementData* elementData = this->elementData()) {
3289         if (const Attribute* attribute = elementData->findLanguageAttribute())
3290             return attribute->value();
3291     }
3292
3293     // The language property is inherited, so we iterate over the parents to find the first language.
3294     const Node* currentNode = this;
3295     while ((currentNode = currentNode->parentNode())) {
3296         if (is<Element>(*currentNode)) {
3297             if (const ElementData* elementData = downcast<Element>(*currentNode).elementData()) {
3298                 if (const Attribute* attribute = elementData->findLanguageAttribute())
3299                     return attribute->value();
3300             }
3301         } else if (is<Document>(*currentNode)) {
3302             // checking the MIME content-language
3303             return downcast<Document>(*currentNode).contentLanguage();
3304         }
3305     }
3306
3307     return nullAtom();
3308 }
3309
3310 Locale& Element::locale() const
3311 {
3312     return document().getCachedLocale(computeInheritedLanguage());
3313 }
3314
3315 void Element::normalizeAttributes()
3316 {
3317     if (!hasAttributes())
3318         return;
3319
3320     auto* attrNodeList = attrNodeListForElement(*this);
3321     if (!attrNodeList)
3322         return;
3323
3324     // Copy the Attr Vector because Node::normalize() can fire synchronous JS
3325     // events (e.g. DOMSubtreeModified) and a JS listener could add / remove
3326     // attributes while we are iterating.
3327     auto copyOfAttrNodeList = *attrNodeList;
3328     for (auto& attrNode : copyOfAttrNodeList)
3329         attrNode->normalize();
3330 }
3331
3332 PseudoElement* Element::beforePseudoElement() const
3333 {
3334     return hasRareData() ? elementRareData()->beforePseudoElement() : nullptr;
3335 }
3336
3337 PseudoElement* Element::afterPseudoElement() const
3338 {
3339     return hasRareData() ? elementRareData()->afterPseudoElement() : nullptr;
3340 }
3341
3342 void Element::setBeforePseudoElement(Ref<PseudoElement>&& element)
3343 {
3344     ensureElementRareData().setBeforePseudoElement(WTFMove(element));
3345 }
3346
3347 void Element::setAfterPseudoElement(Ref<PseudoElement>&& element)
3348 {
3349     ensureElementRareData().setAfterPseudoElement(WTFMove(element));
3350 }
3351
3352 static void disconnectPseudoElement(PseudoElement* pseudoElement)
3353 {
3354     if (!pseudoElement)
3355         return;
3356     ASSERT(!pseudoElement->renderer());
3357     ASSERT(pseudoElement->hostElement());
3358     pseudoElement->clearHostElement();
3359 }
3360
3361 void Element::clearBeforePseudoElement()
3362 {
3363     if (!hasRareData())
3364         return;
3365     disconnectPseudoElement(elementRareData()->beforePseudoElement());
3366     elementRareData()->setBeforePseudoElement(nullptr);
3367 }
3368
3369 void Element::clearAfterPseudoElement()
3370 {
3371     if (!hasRareData())
3372         return;
3373     disconnectPseudoElement(elementRareData()->afterPseudoElement());
3374     elementRareData()->setAfterPseudoElement(nullptr);
3375 }
3376
3377 bool Element::matchesValidPseudoClass() const
3378 {
3379     return false;
3380 }
3381
3382 bool Element::matchesInvalidPseudoClass() const
3383 {
3384     return false;
3385 }
3386
3387 bool Element::matchesReadWritePseudoClass() const
3388 {
3389     return false;
3390 }
3391
3392 bool Element::matchesIndeterminatePseudoClass() const
3393 {
3394     return shouldAppearIndeterminate();
3395 }
3396
3397 bool Element::matchesDefaultPseudoClass() const
3398 {
3399     return false;
3400 }
3401
3402 ExceptionOr<bool> Element::matches(const String& selector)
3403 {
3404     auto query = document().selectorQueryForString(selector);
3405     if (query.hasException())
3406         return query.releaseException();
3407     return query.releaseReturnValue().matches(*this);
3408 }
3409
3410 ExceptionOr<Element*> Element::closest(const String& selector)
3411 {
3412     auto query = document().selectorQueryForString(selector);
3413     if (query.hasException())
3414         return query.releaseException();
3415     return query.releaseReturnValue().closest(*this);
3416 }
3417
3418 bool Element::shouldAppearIndeterminate() const
3419 {
3420     return false;
3421 }
3422
3423 bool Element::mayCauseRepaintInsideViewport(const IntRect* visibleRect) const
3424 {
3425     return renderer() && renderer()->mayCauseRepaintInsideViewport(visibleRect);
3426 }
3427
3428 DOMTokenList& Element::classList()
3429 {
3430     ElementRareData& data = ensureElementRareData();
3431     if (!data.classList())
3432         data.setClassList(makeUnique<DOMTokenList>(*this, HTMLNames::classAttr));
3433     return *data.classList();
3434 }
3435
3436 inline SpaceSplitString Element::partNames() const
3437 {
3438     return elementRareData() ? elementRareData()->partNames() : SpaceSplitString();
3439 }
3440
3441 DOMTokenList& Element::part()
3442 {
3443     auto& data = ensureElementRareData();
3444     if (!data.partList())
3445         data.setPartList(makeUnique<DOMTokenList>(*this, HTMLNames::partAttr));
3446     return *data.partList();
3447 }
3448
3449 DatasetDOMStringMap& Element::dataset()
3450 {
3451     ElementRareData& data = ensureElementRareData();
3452     if (!data.dataset())
3453         data.setDataset(makeUnique<DatasetDOMStringMap>(*this));
3454     return *data.dataset();
3455 }
3456
3457 URL Element::getURLAttribute(const QualifiedName& name) const
3458 {
3459 #if !ASSERT_DISABLED
3460     if (elementData()) {
3461         if (const Attribute* attribute = findAttributeByName(name))
3462             ASSERT(isURLAttribute(*attribute));
3463     }
3464 #endif
3465     return document().completeURL(stripLeadingAndTrailingHTMLSpaces(getAttribute(name)));
3466 }
3467
3468 URL Element::getNonEmptyURLAttribute(const QualifiedName& name) const
3469 {
3470 #if !ASSERT_DISABLED
3471     if (elementData()) {
3472         if (const Attribute* attribute = findAttributeByName(name))
3473             ASSERT(isURLAttribute(*attribute));
3474     }
3475 #endif
3476     String value = stripLeadingAndTrailingHTMLSpaces(getAttribute(name));
3477     if (value.isEmpty())
3478         return URL();
3479     return document().completeURL(value);
3480 }
3481
3482 int Element::getIntegralAttribute(const QualifiedName& attributeName) const
3483 {
3484     return parseHTMLInteger(getAttribute(attributeName)).value_or(0);
3485 }
3486
3487 void Element::setIntegralAttribute(const QualifiedName& attributeName, int value)
3488 {
3489     setAttribute(attributeName, AtomString::number(value));
3490 }
3491
3492 unsigned Element::getUnsignedIntegralAttribute(const QualifiedName& attributeName) const
3493 {
3494     return parseHTMLNonNegativeInteger(getAttribute(attributeName)).value_or(0);
3495 }
3496
3497 void Element::setUnsignedIntegralAttribute(const QualifiedName& attributeName, unsigned value)
3498 {
3499     setAttribute(attributeName, AtomString::number(limitToOnlyHTMLNonNegative(value)));
3500 }
3501
3502 bool Element::childShouldCreateRenderer(const Node& child) const
3503 {
3504     // Only create renderers for SVG elements whose parents are SVG elements, or for proper <svg xmlns="svgNS"> subdocuments.
3505     if (child.isSVGElement()) {
3506         ASSERT(!isSVGElement());
3507         const SVGElement& childElement = downcast<SVGElement>(child);
3508         return is<SVGSVGElement>(childElement) && childElement.isValid();
3509     }
3510     return true;
3511 }
3512
3513 #if ENABLE(FULLSCREEN_API)
3514 static Element* parentCrossingFrameBoundaries(const Element* element)
3515 {
3516     ASSERT(element);
3517     if (auto* parent = element->parentElementInComposedTree())
3518         return parent;
3519     return element->document().ownerElement();
3520 }
3521
3522 void Element::webkitRequestFullscreen()
3523 {
3524     document().fullscreenManager().requestFullscreenForElement(this, FullscreenManager::EnforceIFrameAllowFullscreenRequirement);
3525 }
3526
3527 bool Element::containsFullScreenElement() const
3528 {
3529     return hasRareData() && elementRareData()->containsFullScreenElement();
3530 }
3531
3532 void Element::setContainsFullScreenElement(bool flag)
3533 {
3534     ensureElementRareData().setContainsFullScreenElement(flag);
3535     invalidateStyleAndLayerComposition();
3536 }
3537
3538 void Element::setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(bool flag)
3539 {
3540     Element* element = this;
3541     while ((element = parentCrossingFrameBoundaries(element)))
3542         element->setContainsFullScreenElement(flag);
3543 }
3544 #endif
3545
3546 #if ENABLE(POINTER_EVENTS)
3547 ExceptionOr<void> Element::setPointerCapture(int32_t pointerId)
3548 {
3549     if (document().page())
3550         return document().page()->pointerCaptureController().setPointerCapture(this, pointerId);
3551     return { };
3552 }
3553
3554 ExceptionOr<void> Element::releasePointerCapture(int32_t pointerId)
3555 {
3556     if (document().page())
3557         return document().page()->pointerCaptureController().releasePointerCapture(this, pointerId);
3558     return { };
3559 }
3560
3561 bool Element::hasPointerCapture(int32_t pointerId)
3562 {
3563     if (document().page())
3564         return document().page()->pointerCaptureController().hasPointerCapture(this, pointerId);
3565     return false;
3566 }
3567 #endif
3568
3569 #if ENABLE(POINTER_LOCK)
3570 void Element::requestPointerLock()
3571 {
3572     if (document().page())
3573         document().page()->pointerLockController().requestPointerLock(this);
3574 }
3575 #endif
3576
3577 #if ENABLE(INTERSECTION_OBSERVER)
3578 void Element::disconnectFromIntersectionObservers()
3579 {
3580     auto* observerData = intersectionObserverData();
3581     if (!observerData)
3582         return;
3583
3584     for (const auto& registration : observerData->registrations)
3585         registration.observer->targetDestroyed(*this);
3586     observerData->registrations.clear();
3587
3588     for (const auto& observer : observerData->observers)
3589         observer->rootDestroyed();
3590     observerData->observers.clear();
3591 }
3592
3593 IntersectionObserverData& Element::ensureIntersectionObserverData()
3594 {
3595     auto& rareData = ensureElementRareData();
3596     if (!rareData.intersectionObserverData())
3597         rareData.setIntersectionObserverData(makeUnique<IntersectionObserverData>());
3598     return *rareData.intersectionObserverData();
3599 }
3600
3601 IntersectionObserverData* Element::intersectionObserverData()
3602 {
3603     return hasRareData() ? elementRareData()->intersectionObserverData() : nullptr;
3604 }
3605 #endif
3606
3607 #if ENABLE(RESIZE_OBSERVER)
3608 void Element::disconnectFromResizeObservers()
3609 {
3610     auto* observerData = resizeObserverData();
3611     if (!observerData)
3612         return;
3613
3614     for (const auto& observer : observerData->observers)
3615         observer->targetDestroyed(*this);
3616     observerData->observers.clear();
3617 }
3618
3619 ResizeObserverData& Element::ensureResizeObserverData()
3620 {
3621     auto& rareData = ensureElementRareData();
3622     if (!rareData.resizeObserverData())
3623         rareData.setResizeObserverData(makeUnique<ResizeObserverData>());
3624     return *rareData.resizeObserverData();
3625 }
3626
3627 ResizeObserverData* Element::resizeObserverData()
3628 {
3629     return hasRareData() ? elementRareData()->resizeObserverData() : nullptr;
3630 }
3631 #endif
3632
3633 SpellcheckAttributeState Element::spellcheckAttributeState() const
3634 {
3635     const AtomString& value = attributeWithoutSynchronization(HTMLNames::spellcheckAttr);
3636     if (value.isNull())
3637         return SpellcheckAttributeDefault;
3638     if (value.isEmpty() || equalLettersIgnoringASCIICase(value, "true"))
3639         return SpellcheckAttributeTrue;
3640     if (equalLettersIgnoringASCIICase(value, "false"))
3641         return SpellcheckAttributeFalse;
3642     return SpellcheckAttributeDefault;
3643 }
3644
3645 bool Element::isSpellCheckingEnabled() const
3646 {
3647     for (const Element* element = this; element; element = element->parentOrShadowHostElement()) {
3648         switch (element->spellcheckAttributeState()) {
3649         case SpellcheckAttributeTrue:
3650             return true;
3651         case SpellcheckAttributeFalse:
3652             return false;
3653         case SpellcheckAttributeDefault:
3654          &nb