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