Rename Document::body() to Document::bodyOrFrameset() for clarity
[WebKit.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-2014 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 "CSSParser.h"
32 #include "Chrome.h"
33 #include "ChromeClient.h"
34 #include "ClientRect.h"
35 #include "ClientRectList.h"
36 #include "ContainerNodeAlgorithms.h"
37 #include "DOMTokenList.h"
38 #include "DocumentSharedObjectPool.h"
39 #include "ElementIterator.h"
40 #include "ElementRareData.h"
41 #include "EventDispatcher.h"
42 #include "FlowThreadController.h"
43 #include "FocusController.h"
44 #include "FocusEvent.h"
45 #include "FrameSelection.h"
46 #include "FrameView.h"
47 #include "HTMLCanvasElement.h"
48 #include "HTMLCollection.h"
49 #include "HTMLDocument.h"
50 #include "HTMLFormControlsCollection.h"
51 #include "HTMLLabelElement.h"
52 #include "HTMLNameCollection.h"
53 #include "HTMLOptionsCollection.h"
54 #include "HTMLParserIdioms.h"
55 #include "HTMLSelectElement.h"
56 #include "HTMLTableRowsCollection.h"
57 #include "HTMLTemplateElement.h"
58 #include "InsertionPoint.h"
59 #include "KeyboardEvent.h"
60 #include "MutationObserverInterestGroup.h"
61 #include "MutationRecord.h"
62 #include "NodeRenderStyle.h"
63 #include "PlatformWheelEvent.h"
64 #include "PointerLockController.h"
65 #include "RenderLayer.h"
66 #include "RenderNamedFlowFragment.h"
67 #include "RenderRegion.h"
68 #include "RenderTheme.h"
69 #include "RenderView.h"
70 #include "RenderWidget.h"
71 #include "SVGDocumentExtensions.h"
72 #include "SVGElement.h"
73 #include "SVGNames.h"
74 #include "SelectorQuery.h"
75 #include "Settings.h"
76 #include "StyleProperties.h"
77 #include "StyleResolver.h"
78 #include "TextIterator.h"
79 #include "VoidCallback.h"
80 #include "WheelEvent.h"
81 #include "XLinkNames.h"
82 #include "XMLNSNames.h"
83 #include "XMLNames.h"
84 #include "htmlediting.h"
85 #include "markup.h"
86 #include <wtf/BitVector.h>
87 #include <wtf/CurrentTime.h>
88 #include <wtf/text/CString.h>
89
90 namespace WebCore {
91
92 using namespace HTMLNames;
93 using namespace XMLNames;
94
95 static inline bool shouldIgnoreAttributeCase(const Element& element)
96 {
97     return element.isHTMLElement() && element.document().isHTMLDocument();
98 }
99
100 static HashMap<Element*, Vector<RefPtr<Attr>>>& attrNodeListMap()
101 {
102     static NeverDestroyed<HashMap<Element*, Vector<RefPtr<Attr>>>> map;
103     return map;
104 }
105
106 static Vector<RefPtr<Attr>>* attrNodeListForElement(Element& element)
107 {
108     if (!element.hasSyntheticAttrChildNodes())
109         return nullptr;
110     ASSERT(attrNodeListMap().contains(&element));
111     return &attrNodeListMap().find(&element)->value;
112 }
113
114 static Vector<RefPtr<Attr>>& ensureAttrNodeListForElement(Element& element)
115 {
116     if (element.hasSyntheticAttrChildNodes()) {
117         ASSERT(attrNodeListMap().contains(&element));
118         return attrNodeListMap().find(&element)->value;
119     }
120     ASSERT(!attrNodeListMap().contains(&element));
121     element.setHasSyntheticAttrChildNodes(true);
122     return attrNodeListMap().add(&element, Vector<RefPtr<Attr>>()).iterator->value;
123 }
124
125 static void removeAttrNodeListForElement(Element& element)
126 {
127     ASSERT(element.hasSyntheticAttrChildNodes());
128     ASSERT(attrNodeListMap().contains(&element));
129     attrNodeListMap().remove(&element);
130     element.setHasSyntheticAttrChildNodes(false);
131 }
132
133 static Attr* findAttrNodeInList(Vector<RefPtr<Attr>>& attrNodeList, const QualifiedName& name)
134 {
135     for (auto& node : attrNodeList) {
136         if (node->qualifiedName() == name)
137             return node.get();
138     }
139     return nullptr;
140 }
141
142 Ref<Element> Element::create(const QualifiedName& tagName, Document& document)
143 {
144     return adoptRef(*new Element(tagName, document, CreateElement));
145 }
146
147 Element::Element(const QualifiedName& tagName, Document& document, ConstructionType type)
148     : ContainerNode(document, type)
149     , m_tagName(tagName)
150 {
151 }
152
153 Element::~Element()
154 {
155 #ifndef NDEBUG
156     if (document().hasLivingRenderTree()) {
157         // When the document is not destroyed, an element that was part of a named flow
158         // content nodes should have been removed from the content nodes collection
159         // and the isNamedFlowContentNode flag reset.
160         ASSERT_WITH_SECURITY_IMPLICATION(!isNamedFlowContentNode());
161     }
162 #endif
163
164     ASSERT(!beforePseudoElement());
165     ASSERT(!afterPseudoElement());
166
167     removeShadowRoot();
168
169     if (hasSyntheticAttrChildNodes())
170         detachAllAttrNodesFromElement();
171
172     if (hasPendingResources()) {
173         document().accessSVGExtensions().removeElementFromPendingResources(this);
174         ASSERT(!hasPendingResources());
175     }
176 }
177
178 inline ElementRareData* Element::elementRareData() const
179 {
180     ASSERT_WITH_SECURITY_IMPLICATION(hasRareData());
181     return static_cast<ElementRareData*>(rareData());
182 }
183
184 inline ElementRareData& Element::ensureElementRareData()
185 {
186     return static_cast<ElementRareData&>(ensureRareData());
187 }
188
189 void Element::clearTabIndexExplicitlyIfNeeded()
190 {
191     if (hasRareData())
192         elementRareData()->clearTabIndexExplicitly();
193 }
194
195 void Element::setTabIndexExplicitly(short tabIndex)
196 {
197     ensureElementRareData().setTabIndexExplicitly(tabIndex);
198 }
199
200 bool Element::supportsFocus() const
201 {
202     return hasRareData() && elementRareData()->tabIndexSetExplicitly();
203 }
204
205 Element* Element::focusDelegate()
206 {
207     return this;
208 }
209
210 short Element::tabIndex() const
211 {
212     return hasRareData() ? elementRareData()->tabIndex() : 0;
213 }
214
215 void Element::setTabIndex(int value)
216 {
217     setIntegralAttribute(tabindexAttr, value);
218 }
219
220 bool Element::isKeyboardFocusable(KeyboardEvent*) const
221 {
222     return isFocusable() && tabIndex() >= 0;
223 }
224
225 bool Element::isMouseFocusable() const
226 {
227     return isFocusable();
228 }
229
230 bool Element::shouldUseInputMethod()
231 {
232     return isContentEditable(UserSelectAllIsAlwaysNonEditable);
233 }
234
235 bool Element::dispatchMouseEvent(const PlatformMouseEvent& platformEvent, const AtomicString& eventType, int detail, Element* relatedTarget)
236 {
237     if (isDisabledFormControl())
238         return false;
239
240     RefPtr<MouseEvent> mouseEvent = MouseEvent::create(eventType, document().defaultView(), platformEvent, detail, relatedTarget);
241
242     if (mouseEvent->type().isEmpty())
243         return true; // Shouldn't happen.
244
245     ASSERT(!mouseEvent->target() || mouseEvent->target() != relatedTarget);
246     bool didNotSwallowEvent = dispatchEvent(mouseEvent) && !mouseEvent->defaultHandled();
247
248     if (mouseEvent->type() == eventNames().clickEvent && mouseEvent->detail() == 2) {
249         // Special case: If it's a double click event, we also send the dblclick event. This is not part
250         // of the DOM specs, but is used for compatibility with the ondblclick="" attribute. This is treated
251         // as a separate event in other DOM-compliant browsers like Firefox, and so we do the same.
252         RefPtr<MouseEvent> doubleClickEvent = MouseEvent::create();
253         doubleClickEvent->initMouseEvent(eventNames().dblclickEvent,
254             mouseEvent->bubbles(), mouseEvent->cancelable(), mouseEvent->view(), mouseEvent->detail(),
255             mouseEvent->screenX(), mouseEvent->screenY(), mouseEvent->clientX(), mouseEvent->clientY(),
256             mouseEvent->ctrlKey(), mouseEvent->altKey(), mouseEvent->shiftKey(), mouseEvent->metaKey(),
257             mouseEvent->button(), relatedTarget);
258
259         if (mouseEvent->defaultHandled())
260             doubleClickEvent->setDefaultHandled();
261
262         dispatchEvent(doubleClickEvent);
263         if (doubleClickEvent->defaultHandled() || doubleClickEvent->defaultPrevented())
264             return false;
265     }
266     return didNotSwallowEvent;
267 }
268
269
270 bool Element::dispatchWheelEvent(const PlatformWheelEvent& event)
271 {
272     RefPtr<WheelEvent> wheelEvent = WheelEvent::create(event, document().defaultView());
273     return EventDispatcher::dispatchEvent(this, wheelEvent) && !wheelEvent->defaultHandled();
274 }
275
276 bool Element::dispatchKeyEvent(const PlatformKeyboardEvent& platformEvent)
277 {
278     RefPtr<KeyboardEvent> event = KeyboardEvent::create(platformEvent, document().defaultView());
279     return EventDispatcher::dispatchEvent(this, event) && !event->defaultHandled();
280 }
281
282 void Element::dispatchSimulatedClick(Event* underlyingEvent, SimulatedClickMouseEventOptions eventOptions, SimulatedClickVisualOptions visualOptions)
283 {
284     EventDispatcher::dispatchSimulatedClick(this, underlyingEvent, eventOptions, visualOptions);
285 }
286
287 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, blur);
288 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, error);
289 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, focus);
290 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, load);
291
292 RefPtr<Node> Element::cloneNodeInternal(Document& targetDocument, CloningOperation type)
293 {
294     switch (type) {
295     case CloningOperation::OnlySelf:
296     case CloningOperation::SelfWithTemplateContent:
297         return cloneElementWithoutChildren(targetDocument);
298     case CloningOperation::Everything:
299         return cloneElementWithChildren(targetDocument);
300     }
301     ASSERT_NOT_REACHED();
302     return nullptr;
303 }
304
305 RefPtr<Element> Element::cloneElementWithChildren(Document& targetDocument)
306 {
307     RefPtr<Element> clone = cloneElementWithoutChildren(targetDocument);
308     cloneChildNodes(clone.get());
309     return clone.release();
310 }
311
312 RefPtr<Element> Element::cloneElementWithoutChildren(Document& targetDocument)
313 {
314     RefPtr<Element> clone = cloneElementWithoutAttributesAndChildren(targetDocument);
315     // This will catch HTML elements in the wrong namespace that are not correctly copied.
316     // This is a sanity check as HTML overloads some of the DOM methods.
317     ASSERT(isHTMLElement() == clone->isHTMLElement());
318
319     clone->cloneDataFromElement(*this);
320     return clone.release();
321 }
322
323 RefPtr<Element> Element::cloneElementWithoutAttributesAndChildren(Document& targetDocument)
324 {
325     return targetDocument.createElement(tagQName(), false);
326 }
327
328 RefPtr<Attr> Element::detachAttribute(unsigned index)
329 {
330     ASSERT(elementData());
331
332     const Attribute& attribute = elementData()->attributeAt(index);
333
334     RefPtr<Attr> attrNode = attrIfExists(attribute.name());
335     if (attrNode)
336         detachAttrNodeFromElementWithValue(attrNode.get(), attribute.value());
337     else
338         attrNode = Attr::create(document(), attribute.name(), attribute.value());
339
340     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
341     return attrNode.release();
342 }
343
344 bool Element::removeAttribute(const QualifiedName& name)
345 {
346     if (!elementData())
347         return false;
348
349     unsigned index = elementData()->findAttributeIndexByName(name);
350     if (index == ElementData::attributeNotFound)
351         return false;
352
353     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
354     return true;
355 }
356
357 void Element::setBooleanAttribute(const QualifiedName& name, bool value)
358 {
359     if (value)
360         setAttribute(name, emptyAtom);
361     else
362         removeAttribute(name);
363 }
364
365 NamedNodeMap& Element::attributes() const
366 {
367     ElementRareData& rareData = const_cast<Element*>(this)->ensureElementRareData();
368     if (NamedNodeMap* attributeMap = rareData.attributeMap())
369         return *attributeMap;
370
371     rareData.setAttributeMap(NamedNodeMap::create(const_cast<Element&>(*this)));
372     return *rareData.attributeMap();
373 }
374
375 Node::NodeType Element::nodeType() const
376 {
377     return ELEMENT_NODE;
378 }
379
380 bool Element::hasAttribute(const QualifiedName& name) const
381 {
382     return hasAttributeNS(name.namespaceURI(), name.localName());
383 }
384
385 void Element::synchronizeAllAttributes() const
386 {
387     if (!elementData())
388         return;
389     if (elementData()->styleAttributeIsDirty()) {
390         ASSERT(isStyledElement());
391         static_cast<const StyledElement*>(this)->synchronizeStyleAttributeInternal();
392     }
393
394     if (elementData()->animatedSVGAttributesAreDirty()) {
395         ASSERT(isSVGElement());
396         downcast<SVGElement>(*this).synchronizeAnimatedSVGAttribute(anyQName());
397     }
398 }
399
400 ALWAYS_INLINE void Element::synchronizeAttribute(const QualifiedName& name) const
401 {
402     if (!elementData())
403         return;
404     if (UNLIKELY(name == styleAttr && elementData()->styleAttributeIsDirty())) {
405         ASSERT_WITH_SECURITY_IMPLICATION(isStyledElement());
406         static_cast<const StyledElement*>(this)->synchronizeStyleAttributeInternal();
407         return;
408     }
409
410     if (UNLIKELY(elementData()->animatedSVGAttributesAreDirty())) {
411         ASSERT(isSVGElement());
412         downcast<SVGElement>(*this).synchronizeAnimatedSVGAttribute(name);
413     }
414 }
415
416 ALWAYS_INLINE void Element::synchronizeAttribute(const AtomicString& localName) const
417 {
418     // This version of synchronizeAttribute() is streamlined for the case where you don't have a full QualifiedName,
419     // e.g when called from DOM API.
420     if (!elementData())
421         return;
422     if (elementData()->styleAttributeIsDirty() && equalPossiblyIgnoringCase(localName, styleAttr.localName(), shouldIgnoreAttributeCase(*this))) {
423         ASSERT_WITH_SECURITY_IMPLICATION(isStyledElement());
424         static_cast<const StyledElement*>(this)->synchronizeStyleAttributeInternal();
425         return;
426     }
427
428     if (elementData()->animatedSVGAttributesAreDirty()) {
429         // We're not passing a namespace argument on purpose. SVGNames::*Attr are defined w/o namespaces as well.
430         ASSERT_WITH_SECURITY_IMPLICATION(isSVGElement());
431         downcast<SVGElement>(*this).synchronizeAnimatedSVGAttribute(QualifiedName(nullAtom, localName, nullAtom));
432     }
433 }
434
435 const AtomicString& Element::getAttribute(const QualifiedName& name) const
436 {
437     if (!elementData())
438         return nullAtom;
439     synchronizeAttribute(name);
440     if (const Attribute* attribute = findAttributeByName(name))
441         return attribute->value();
442     return nullAtom;
443 }
444
445 bool Element::isFocusable() const
446 {
447     if (!inDocument() || !supportsFocus())
448         return false;
449
450     if (!renderer()) {
451         // If the node is in a display:none tree it might say it needs style recalc but
452         // the whole document is actually up to date.
453         ASSERT(!needsStyleRecalc() || !document().childNeedsStyleRecalc());
454
455         // Elements in canvas fallback content are not rendered, but they are allowed to be
456         // focusable as long as their canvas is displayed and visible.
457         if (auto* canvas = ancestorsOfType<HTMLCanvasElement>(*this).first())
458             return canvas->renderer() && canvas->renderer()->style().visibility() == VISIBLE;
459     }
460
461     // FIXME: Even if we are not visible, we might have a child that is visible.
462     // Hyatt wants to fix that some day with a "has visible content" flag or the like.
463     if (!renderer() || renderer()->style().visibility() != VISIBLE)
464         return false;
465
466     return true;
467 }
468
469 bool Element::isUserActionElementInActiveChain() const
470 {
471     ASSERT(isUserActionElement());
472     return document().userActionElements().isInActiveChain(this);
473 }
474
475 bool Element::isUserActionElementActive() const
476 {
477     ASSERT(isUserActionElement());
478     return document().userActionElements().isActive(this);
479 }
480
481 bool Element::isUserActionElementFocused() const
482 {
483     ASSERT(isUserActionElement());
484     return document().userActionElements().isFocused(this);
485 }
486
487 bool Element::isUserActionElementHovered() const
488 {
489     ASSERT(isUserActionElement());
490     return document().userActionElements().isHovered(this);
491 }
492
493 void Element::setActive(bool flag, bool pause)
494 {
495     if (flag == active())
496         return;
497
498     document().userActionElements().setActive(this, flag);
499
500     if (!renderer())
501         return;
502
503     bool reactsToPress = renderStyle()->affectedByActive() || childrenAffectedByActive();
504     if (reactsToPress)
505         setNeedsStyleRecalc();
506
507     if (renderer()->style().hasAppearance() && renderer()->theme().stateChanged(*renderer(), ControlStates::PressedState))
508         reactsToPress = true;
509
510     // The rest of this function implements a feature that only works if the
511     // platform supports immediate invalidations on the ChromeClient, so bail if
512     // that isn't supported.
513     if (!document().page()->chrome().client().supportsImmediateInvalidation())
514         return;
515
516     if (reactsToPress && pause) {
517         // The delay here is subtle. It relies on an assumption, namely that the amount of time it takes
518         // to repaint the "down" state of the control is about the same time as it would take to repaint the
519         // "up" state. Once you assume this, you can just delay for 100ms - that time (assuming that after you
520         // leave this method, it will be about that long before the flush of the up state happens again).
521 #ifdef HAVE_FUNC_USLEEP
522         double startTime = monotonicallyIncreasingTime();
523 #endif
524
525         document().updateStyleIfNeeded();
526
527         // Do an immediate repaint.
528         if (renderer())
529             renderer()->repaint();
530
531         // FIXME: Come up with a less ridiculous way of doing this.
532 #ifdef HAVE_FUNC_USLEEP
533         // Now pause for a small amount of time (1/10th of a second from before we repainted in the pressed state)
534         double remainingTime = 0.1 - (monotonicallyIncreasingTime() - startTime);
535         if (remainingTime > 0)
536             usleep(static_cast<useconds_t>(remainingTime * 1000000.0));
537 #endif
538     }
539 }
540
541 void Element::setFocus(bool flag)
542 {
543     if (flag == focused())
544         return;
545
546     document().userActionElements().setFocused(this, flag);
547     setNeedsStyleRecalc();
548 }
549
550 void Element::setHovered(bool flag)
551 {
552     if (flag == hovered())
553         return;
554
555     document().userActionElements().setHovered(this, flag);
556
557     if (!renderer()) {
558         // When setting hover to false, the style needs to be recalc'd even when
559         // there's no renderer (imagine setting display:none in the :hover class,
560         // if a nil renderer would prevent this element from recalculating its
561         // style, it would never go back to its normal style and remain
562         // stuck in its hovered style).
563         if (!flag)
564             setNeedsStyleRecalc();
565
566         return;
567     }
568
569     if (renderer()->style().affectedByHover() || childrenAffectedByHover())
570         setNeedsStyleRecalc();
571
572     if (renderer()->style().hasAppearance())
573         renderer()->theme().stateChanged(*renderer(), ControlStates::HoverState);
574 }
575
576 void Element::scrollIntoView(bool alignToTop) 
577 {
578     document().updateLayoutIgnorePendingStylesheets();
579
580     if (!renderer())
581         return;
582
583     LayoutRect bounds = renderer()->anchorRect();
584     // Align to the top / bottom and to the closest edge.
585     if (alignToTop)
586         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
587     else
588         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignBottomAlways);
589 }
590
591 void Element::scrollIntoViewIfNeeded(bool centerIfNeeded)
592 {
593     document().updateLayoutIgnorePendingStylesheets();
594
595     if (!renderer())
596         return;
597
598     LayoutRect bounds = renderer()->anchorRect();
599     if (centerIfNeeded)
600         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignCenterIfNeeded, ScrollAlignment::alignCenterIfNeeded);
601     else
602         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
603 }
604
605 void Element::scrollByUnits(int units, ScrollGranularity granularity)
606 {
607     document().updateLayoutIgnorePendingStylesheets();
608
609     if (!renderer())
610         return;
611
612     if (!renderer()->hasOverflowClip())
613         return;
614
615     ScrollDirection direction = ScrollDown;
616     if (units < 0) {
617         direction = ScrollUp;
618         units = -units;
619     }
620     Element* stopElement = this;
621     downcast<RenderBox>(*renderer()).scroll(direction, granularity, units, &stopElement);
622 }
623
624 void Element::scrollByLines(int lines)
625 {
626     scrollByUnits(lines, ScrollByLine);
627 }
628
629 void Element::scrollByPages(int pages)
630 {
631     scrollByUnits(pages, ScrollByPage);
632 }
633
634 static double localZoomForRenderer(const RenderElement& renderer)
635 {
636     // FIXME: This does the wrong thing if two opposing zooms are in effect and canceled each
637     // other out, but the alternative is that we'd have to crawl up the whole render tree every
638     // time (or store an additional bit in the RenderStyle to indicate that a zoom was specified).
639     double zoomFactor = 1;
640     if (renderer.style().effectiveZoom() != 1) {
641         // Need to find the nearest enclosing RenderElement that set up
642         // a differing zoom, and then we divide our result by it to eliminate the zoom.
643         const RenderElement* prev = &renderer;
644         for (RenderElement* curr = prev->parent(); curr; curr = curr->parent()) {
645             if (curr->style().effectiveZoom() != prev->style().effectiveZoom()) {
646                 zoomFactor = prev->style().zoom();
647                 break;
648             }
649             prev = curr;
650         }
651         if (prev->isRenderView())
652             zoomFactor = prev->style().zoom();
653     }
654     return zoomFactor;
655 }
656
657 static double adjustForLocalZoom(LayoutUnit value, const RenderElement& renderer, double& zoomFactor)
658 {
659     zoomFactor = localZoomForRenderer(renderer);
660     if (zoomFactor == 1)
661         return value.toDouble();
662     return value.toDouble() / zoomFactor;
663 }
664
665 enum LegacyCSSOMElementMetricsRoundingStrategy { Round, Floor };
666
667 static bool subpixelMetricsEnabled(const Document& document)
668 {
669     return document.settings() && document.settings()->subpixelCSSOMElementMetricsEnabled();
670 }
671
672 static double convertToNonSubpixelValueIfNeeded(double value, const Document& document, LegacyCSSOMElementMetricsRoundingStrategy roundStrategy = Round)
673 {
674     return subpixelMetricsEnabled(document) ? value : roundStrategy == Round ? round(value) : floor(value);
675 }
676
677 double Element::offsetLeft()
678 {
679     document().updateLayoutIgnorePendingStylesheets();
680     if (RenderBoxModelObject* renderer = renderBoxModelObject()) {
681         LayoutUnit offsetLeft = subpixelMetricsEnabled(renderer->document()) ? renderer->offsetLeft() : LayoutUnit(renderer->pixelSnappedOffsetLeft());
682         double zoomFactor = 1;
683         double offsetLeftAdjustedWithZoom = adjustForLocalZoom(offsetLeft, *renderer, zoomFactor);
684         return convertToNonSubpixelValueIfNeeded(offsetLeftAdjustedWithZoom, renderer->document(), zoomFactor == 1 ? Floor : Round);
685     }
686     return 0;
687 }
688
689 double Element::offsetTop()
690 {
691     document().updateLayoutIgnorePendingStylesheets();
692     if (RenderBoxModelObject* renderer = renderBoxModelObject()) {
693         LayoutUnit offsetTop = subpixelMetricsEnabled(renderer->document()) ? renderer->offsetTop() : LayoutUnit(renderer->pixelSnappedOffsetTop());
694         double zoomFactor = 1;
695         double offsetTopAdjustedWithZoom = adjustForLocalZoom(offsetTop, *renderer, zoomFactor);
696         return convertToNonSubpixelValueIfNeeded(offsetTopAdjustedWithZoom, renderer->document(), zoomFactor == 1 ? Floor : Round);
697     }
698     return 0;
699 }
700
701 double Element::offsetWidth()
702 {
703     document().updateLayoutIgnorePendingStylesheets();
704     if (RenderBoxModelObject* renderer = renderBoxModelObject()) {
705         LayoutUnit offsetWidth = subpixelMetricsEnabled(renderer->document()) ? renderer->offsetWidth() : LayoutUnit(renderer->pixelSnappedOffsetWidth());
706         return convertToNonSubpixelValueIfNeeded(adjustLayoutUnitForAbsoluteZoom(offsetWidth, *renderer).toDouble(), renderer->document());
707     }
708     return 0;
709 }
710
711 double Element::offsetHeight()
712 {
713     document().updateLayoutIgnorePendingStylesheets();
714     if (RenderBoxModelObject* renderer = renderBoxModelObject()) {
715         LayoutUnit offsetHeight = subpixelMetricsEnabled(renderer->document()) ? renderer->offsetHeight() : LayoutUnit(renderer->pixelSnappedOffsetHeight());
716         return convertToNonSubpixelValueIfNeeded(adjustLayoutUnitForAbsoluteZoom(offsetHeight, *renderer).toDouble(), renderer->document());
717     }
718     return 0;
719 }
720
721 Element* Element::bindingsOffsetParent()
722 {
723     Element* element = offsetParent();
724     if (!element || !element->isInShadowTree())
725         return element;
726     return element->containingShadowRoot()->type() == ShadowRoot::UserAgentShadowRoot ? 0 : element;
727 }
728
729 Element* Element::offsetParent()
730 {
731     document().updateLayoutIgnorePendingStylesheets();
732     auto renderer = this->renderer();
733     if (!renderer)
734         return nullptr;
735     auto offsetParent = renderer->offsetParent();
736     if (!offsetParent)
737         return nullptr;
738     return offsetParent->element();
739 }
740
741 double Element::clientLeft()
742 {
743     document().updateLayoutIgnorePendingStylesheets();
744
745     if (RenderBox* renderer = renderBox()) {
746         LayoutUnit clientLeft = subpixelMetricsEnabled(renderer->document()) ? renderer->clientLeft() : LayoutUnit(roundToInt(renderer->clientLeft()));
747         return convertToNonSubpixelValueIfNeeded(adjustLayoutUnitForAbsoluteZoom(clientLeft, *renderer).toDouble(), renderer->document());
748     }
749     return 0;
750 }
751
752 double Element::clientTop()
753 {
754     document().updateLayoutIgnorePendingStylesheets();
755
756     if (RenderBox* renderer = renderBox()) {
757         LayoutUnit clientTop = subpixelMetricsEnabled(renderer->document()) ? renderer->clientTop() : LayoutUnit(roundToInt(renderer->clientTop()));
758         return convertToNonSubpixelValueIfNeeded(adjustLayoutUnitForAbsoluteZoom(clientTop, *renderer).toDouble(), renderer->document());
759     }
760     return 0;
761 }
762
763 double Element::clientWidth()
764 {
765     document().updateLayoutIgnorePendingStylesheets();
766
767     if (!document().hasLivingRenderTree())
768         return 0;
769     RenderView& renderView = *document().renderView();
770
771     // When in strict mode, clientWidth for the document element should return the width of the containing frame.
772     // When in quirks mode, clientWidth for the body element should return the width of the containing frame.
773     bool inQuirksMode = document().inQuirksMode();
774     if ((!inQuirksMode && document().documentElement() == this) || (inQuirksMode && isHTMLElement() && document().bodyOrFrameset() == this))
775         return adjustForAbsoluteZoom(renderView.frameView().layoutWidth(), renderView);
776     
777     if (RenderBox* renderer = renderBox()) {
778         LayoutUnit clientWidth = subpixelMetricsEnabled(renderer->document()) ? renderer->clientWidth() : LayoutUnit(renderer->pixelSnappedClientWidth());
779         return convertToNonSubpixelValueIfNeeded(adjustLayoutUnitForAbsoluteZoom(clientWidth, *renderer).toDouble(), renderer->document());
780     }
781     return 0;
782 }
783
784 double Element::clientHeight()
785 {
786     document().updateLayoutIgnorePendingStylesheets();
787
788     if (!document().hasLivingRenderTree())
789         return 0;
790     RenderView& renderView = *document().renderView();
791
792     // When in strict mode, clientHeight for the document element should return the height of the containing frame.
793     // When in quirks mode, clientHeight for the body element should return the height of the containing frame.
794     bool inQuirksMode = document().inQuirksMode();
795     if ((!inQuirksMode && document().documentElement() == this) || (inQuirksMode && isHTMLElement() && document().bodyOrFrameset() == this))
796         return adjustForAbsoluteZoom(renderView.frameView().layoutHeight(), renderView);
797
798     if (RenderBox* renderer = renderBox()) {
799         LayoutUnit clientHeight = subpixelMetricsEnabled(renderer->document()) ? renderer->clientHeight() : LayoutUnit(renderer->pixelSnappedClientHeight());
800         return convertToNonSubpixelValueIfNeeded(adjustLayoutUnitForAbsoluteZoom(clientHeight, *renderer).toDouble(), renderer->document());
801     }
802     return 0;
803 }
804
805 int Element::scrollLeft()
806 {
807     document().updateLayoutIgnorePendingStylesheets();
808
809     if (RenderBox* rend = renderBox())
810         return adjustForAbsoluteZoom(rend->scrollLeft(), *rend);
811     return 0;
812 }
813
814 int Element::scrollTop()
815 {
816     document().updateLayoutIgnorePendingStylesheets();
817
818     if (RenderBox* rend = renderBox())
819         return adjustForAbsoluteZoom(rend->scrollTop(), *rend);
820     return 0;
821 }
822
823 void Element::setScrollLeft(int newLeft)
824 {
825     document().updateLayoutIgnorePendingStylesheets();
826
827     if (RenderBox* renderer = renderBox()) {
828         renderer->setScrollLeft(static_cast<int>(newLeft * renderer->style().effectiveZoom()));
829         if (auto* scrollableArea = renderer->layer())
830             scrollableArea->setScrolledProgrammatically(true);
831     }
832 }
833
834 void Element::setScrollTop(int newTop)
835 {
836     document().updateLayoutIgnorePendingStylesheets();
837
838     if (RenderBox* renderer = renderBox()) {
839         renderer->setScrollTop(static_cast<int>(newTop * renderer->style().effectiveZoom()));
840         if (auto* scrollableArea = renderer->layer())
841             scrollableArea->setScrolledProgrammatically(true);
842     }
843 }
844
845 int Element::scrollWidth()
846 {
847     document().updateLayoutIgnorePendingStylesheets();
848     if (RenderBox* rend = renderBox())
849         return adjustForAbsoluteZoom(rend->scrollWidth(), *rend);
850     return 0;
851 }
852
853 int Element::scrollHeight()
854 {
855     document().updateLayoutIgnorePendingStylesheets();
856     if (RenderBox* rend = renderBox())
857         return adjustForAbsoluteZoom(rend->scrollHeight(), *rend);
858     return 0;
859 }
860
861 IntRect Element::boundsInRootViewSpace()
862 {
863     document().updateLayoutIgnorePendingStylesheets();
864
865     FrameView* view = document().view();
866     if (!view)
867         return IntRect();
868
869     Vector<FloatQuad> quads;
870
871     if (isSVGElement() && renderer()) {
872         // Get the bounding rectangle from the SVG model.
873         SVGElement& svgElement = downcast<SVGElement>(*this);
874         FloatRect localRect;
875         if (svgElement.getBoundingBox(localRect))
876             quads.append(renderer()->localToAbsoluteQuad(localRect));
877     } else {
878         // Get the bounding rectangle from the box model.
879         if (renderBoxModelObject())
880             renderBoxModelObject()->absoluteQuads(quads);
881     }
882
883     if (quads.isEmpty())
884         return IntRect();
885
886     IntRect result = quads[0].enclosingBoundingBox();
887     for (size_t i = 1; i < quads.size(); ++i)
888         result.unite(quads[i].enclosingBoundingBox());
889
890     result = view->contentsToRootView(result);
891     return result;
892 }
893
894 Ref<ClientRectList> Element::getClientRects()
895 {
896     document().updateLayoutIgnorePendingStylesheets();
897
898     RenderBoxModelObject* renderBoxModelObject = this->renderBoxModelObject();
899     if (!renderBoxModelObject)
900         return ClientRectList::create();
901
902     // FIXME: Handle SVG elements.
903     // FIXME: Handle table/inline-table with a caption.
904
905     Vector<FloatQuad> quads;
906     renderBoxModelObject->absoluteQuads(quads);
907     document().adjustFloatQuadsForScrollAndAbsoluteZoomAndFrameScale(quads, renderBoxModelObject->style());
908     return ClientRectList::create(quads);
909 }
910
911 Ref<ClientRect> Element::getBoundingClientRect()
912 {
913     document().updateLayoutIgnorePendingStylesheets();
914
915     Vector<FloatQuad> quads;
916     if (isSVGElement() && renderer() && !renderer()->isSVGRoot()) {
917         // Get the bounding rectangle from the SVG model.
918         SVGElement& svgElement = downcast<SVGElement>(*this);
919         FloatRect localRect;
920         if (svgElement.getBoundingBox(localRect))
921             quads.append(renderer()->localToAbsoluteQuad(localRect));
922     } else {
923         // Get the bounding rectangle from the box model.
924         if (renderBoxModelObject())
925             renderBoxModelObject()->absoluteQuads(quads);
926     }
927
928     if (quads.isEmpty())
929         return ClientRect::create();
930
931     FloatRect result = quads[0].boundingBox();
932     for (size_t i = 1; i < quads.size(); ++i)
933         result.unite(quads[i].boundingBox());
934
935     document().adjustFloatRectForScrollAndAbsoluteZoomAndFrameScale(result, renderer()->style());
936     return ClientRect::create(result);
937 }
938
939 IntRect Element::clientRect() const
940 {
941     if (RenderObject* renderer = this->renderer())
942         return document().view()->contentsToRootView(renderer->absoluteBoundingBoxRect());
943     return IntRect();
944 }
945     
946 IntRect Element::screenRect() const
947 {
948     if (RenderObject* renderer = this->renderer())
949         return document().view()->contentsToScreen(renderer->absoluteBoundingBoxRect());
950     return IntRect();
951 }
952
953 const AtomicString& Element::getAttribute(const AtomicString& localName) const
954 {
955     if (!elementData())
956         return nullAtom;
957     synchronizeAttribute(localName);
958     if (const Attribute* attribute = elementData()->findAttributeByName(localName, shouldIgnoreAttributeCase(*this)))
959         return attribute->value();
960     return nullAtom;
961 }
962
963 const AtomicString& Element::getAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const
964 {
965     return getAttribute(QualifiedName(nullAtom, localName, namespaceURI));
966 }
967
968 void Element::setAttribute(const AtomicString& localName, const AtomicString& value, ExceptionCode& ec)
969 {
970     if (!Document::isValidName(localName)) {
971         ec = INVALID_CHARACTER_ERR;
972         return;
973     }
974
975     synchronizeAttribute(localName);
976     const AtomicString& caseAdjustedLocalName = shouldIgnoreAttributeCase(*this) ? localName.lower() : localName;
977
978     unsigned index = elementData() ? elementData()->findAttributeIndexByName(caseAdjustedLocalName, false) : ElementData::attributeNotFound;
979     const QualifiedName& qName = index != ElementData::attributeNotFound ? attributeAt(index).name() : QualifiedName(nullAtom, caseAdjustedLocalName, nullAtom);
980     setAttributeInternal(index, qName, value, NotInSynchronizationOfLazyAttribute);
981 }
982
983 void Element::setAttribute(const QualifiedName& name, const AtomicString& value)
984 {
985     synchronizeAttribute(name);
986     unsigned index = elementData() ? elementData()->findAttributeIndexByName(name) : ElementData::attributeNotFound;
987     setAttributeInternal(index, name, value, NotInSynchronizationOfLazyAttribute);
988 }
989
990 void Element::setAttributeWithoutSynchronization(const QualifiedName& name, const AtomicString& value)
991 {
992     unsigned index = elementData() ? elementData()->findAttributeIndexByName(name) : ElementData::attributeNotFound;
993     setAttributeInternal(index, name, value, NotInSynchronizationOfLazyAttribute);
994 }
995
996 void Element::setSynchronizedLazyAttribute(const QualifiedName& name, const AtomicString& value)
997 {
998     unsigned index = elementData() ? elementData()->findAttributeIndexByName(name) : ElementData::attributeNotFound;
999     setAttributeInternal(index, name, value, InSynchronizationOfLazyAttribute);
1000 }
1001
1002 inline void Element::setAttributeInternal(unsigned index, const QualifiedName& name, const AtomicString& newValue, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
1003 {
1004     if (newValue.isNull()) {
1005         if (index != ElementData::attributeNotFound)
1006             removeAttributeInternal(index, inSynchronizationOfLazyAttribute);
1007         return;
1008     }
1009
1010     if (index == ElementData::attributeNotFound) {
1011         addAttributeInternal(name, newValue, inSynchronizationOfLazyAttribute);
1012         return;
1013     }
1014
1015     const Attribute& attribute = attributeAt(index);
1016     AtomicString oldValue = attribute.value();
1017     bool valueChanged = newValue != oldValue;
1018     QualifiedName attributeName = (!inSynchronizationOfLazyAttribute || valueChanged) ? attribute.name() : name;
1019
1020     if (!inSynchronizationOfLazyAttribute)
1021         willModifyAttribute(attributeName, oldValue, newValue);
1022
1023     if (valueChanged) {
1024         // If there is an Attr node hooked to this attribute, the Attr::setValue() call below
1025         // will write into the ElementData.
1026         // FIXME: Refactor this so it makes some sense.
1027         if (RefPtr<Attr> attrNode = inSynchronizationOfLazyAttribute ? 0 : attrIfExists(attributeName))
1028             attrNode->setValue(newValue);
1029         else
1030             ensureUniqueElementData().attributeAt(index).setValue(newValue);
1031     }
1032
1033     if (!inSynchronizationOfLazyAttribute)
1034         didModifyAttribute(attributeName, oldValue, newValue);
1035 }
1036
1037 static inline AtomicString makeIdForStyleResolution(const AtomicString& value, bool inQuirksMode)
1038 {
1039     if (inQuirksMode)
1040         return value.lower();
1041     return value;
1042 }
1043
1044 static bool checkNeedsStyleInvalidationForIdChange(const AtomicString& oldId, const AtomicString& newId, StyleResolver* styleResolver)
1045 {
1046     ASSERT(newId != oldId);
1047     if (!oldId.isEmpty() && styleResolver->hasSelectorForId(oldId))
1048         return true;
1049     if (!newId.isEmpty() && styleResolver->hasSelectorForId(newId))
1050         return true;
1051     return false;
1052 }
1053
1054 void Element::attributeChanged(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue, AttributeModificationReason)
1055 {
1056     parseAttribute(name, newValue);
1057
1058     document().incDOMTreeVersion();
1059
1060     if (oldValue == newValue)
1061         return;
1062
1063     StyleResolver* styleResolver = document().styleResolverIfExists();
1064     bool testShouldInvalidateStyle = inRenderedDocument() && styleResolver && styleChangeType() < FullStyleChange;
1065     bool shouldInvalidateStyle = false;
1066
1067     if (name == HTMLNames::idAttr) {
1068         AtomicString oldId = elementData()->idForStyleResolution();
1069         AtomicString newId = makeIdForStyleResolution(newValue, document().inQuirksMode());
1070         if (newId != oldId) {
1071             elementData()->setIdForStyleResolution(newId);
1072             shouldInvalidateStyle = testShouldInvalidateStyle && checkNeedsStyleInvalidationForIdChange(oldId, newId, styleResolver);
1073         }
1074     } else if (name == classAttr)
1075         classAttributeChanged(newValue);
1076     else if (name == HTMLNames::nameAttr)
1077         elementData()->setHasNameAttribute(!newValue.isNull());
1078     else if (name == HTMLNames::pseudoAttr)
1079         shouldInvalidateStyle |= testShouldInvalidateStyle && isInShadowTree();
1080
1081
1082     invalidateNodeListAndCollectionCachesInAncestors(&name, this);
1083
1084     // If there is currently no StyleResolver, we can't be sure that this attribute change won't affect style.
1085     shouldInvalidateStyle |= !styleResolver;
1086
1087     if (shouldInvalidateStyle)
1088         setNeedsStyleRecalc();
1089
1090     if (AXObjectCache* cache = document().existingAXObjectCache())
1091         cache->handleAttributeChanged(name, this);
1092 }
1093
1094 template <typename CharacterType>
1095 static inline bool classStringHasClassName(const CharacterType* characters, unsigned length)
1096 {
1097     ASSERT(length > 0);
1098
1099     unsigned i = 0;
1100     do {
1101         if (isNotHTMLSpace(characters[i]))
1102             break;
1103         ++i;
1104     } while (i < length);
1105
1106     return i < length;
1107 }
1108
1109 static inline bool classStringHasClassName(const AtomicString& newClassString)
1110 {
1111     unsigned length = newClassString.length();
1112
1113     if (!length)
1114         return false;
1115
1116     if (newClassString.is8Bit())
1117         return classStringHasClassName(newClassString.characters8(), length);
1118     return classStringHasClassName(newClassString.characters16(), length);
1119 }
1120
1121 static bool checkSelectorForClassChange(const SpaceSplitString& changedClasses, const StyleResolver& styleResolver)
1122 {
1123     unsigned changedSize = changedClasses.size();
1124     for (unsigned i = 0; i < changedSize; ++i) {
1125         if (styleResolver.hasSelectorForClass(changedClasses[i]))
1126             return true;
1127     }
1128     return false;
1129 }
1130
1131 static bool checkSelectorForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, const StyleResolver& styleResolver)
1132 {
1133     unsigned oldSize = oldClasses.size();
1134     if (!oldSize)
1135         return checkSelectorForClassChange(newClasses, styleResolver);
1136     BitVector remainingClassBits;
1137     remainingClassBits.ensureSize(oldSize);
1138     // Class vectors tend to be very short. This is faster than using a hash table.
1139     unsigned newSize = newClasses.size();
1140     for (unsigned i = 0; i < newSize; ++i) {
1141         bool foundFromBoth = false;
1142         for (unsigned j = 0; j < oldSize; ++j) {
1143             if (newClasses[i] == oldClasses[j]) {
1144                 remainingClassBits.quickSet(j);
1145                 foundFromBoth = true;
1146             }
1147         }
1148         if (foundFromBoth)
1149             continue;
1150         if (styleResolver.hasSelectorForClass(newClasses[i]))
1151             return true;
1152     }
1153     for (unsigned i = 0; i < oldSize; ++i) {
1154         // If the bit is not set the the corresponding class has been removed.
1155         if (remainingClassBits.quickGet(i))
1156             continue;
1157         if (styleResolver.hasSelectorForClass(oldClasses[i]))
1158             return true;
1159     }
1160     return false;
1161 }
1162
1163 void Element::classAttributeChanged(const AtomicString& newClassString)
1164 {
1165     StyleResolver* styleResolver = document().styleResolverIfExists();
1166     bool testShouldInvalidateStyle = inRenderedDocument() && styleResolver && styleChangeType() < FullStyleChange;
1167     bool shouldInvalidateStyle = false;
1168
1169     if (classStringHasClassName(newClassString)) {
1170         const bool shouldFoldCase = document().inQuirksMode();
1171         // Note: We'll need ElementData, but it doesn't have to be UniqueElementData.
1172         if (!elementData())
1173             ensureUniqueElementData();
1174         const SpaceSplitString oldClasses = elementData()->classNames();
1175         elementData()->setClass(newClassString, shouldFoldCase);
1176         const SpaceSplitString& newClasses = elementData()->classNames();
1177         shouldInvalidateStyle = testShouldInvalidateStyle && checkSelectorForClassChange(oldClasses, newClasses, *styleResolver);
1178     } else if (elementData()) {
1179         const SpaceSplitString& oldClasses = elementData()->classNames();
1180         shouldInvalidateStyle = testShouldInvalidateStyle && checkSelectorForClassChange(oldClasses, *styleResolver);
1181         elementData()->clearClass();
1182     }
1183
1184     if (hasRareData())
1185         elementRareData()->clearClassListValueForQuirksMode();
1186
1187     if (shouldInvalidateStyle)
1188         setNeedsStyleRecalc();
1189 }
1190
1191 URL Element::absoluteLinkURL() const
1192 {
1193     if (!isLink())
1194         return URL();
1195
1196     AtomicString linkAttribute;
1197     if (hasTagName(SVGNames::aTag))
1198         linkAttribute = getAttribute(XLinkNames::hrefAttr);
1199     else
1200         linkAttribute = getAttribute(HTMLNames::hrefAttr);
1201
1202     if (linkAttribute.isEmpty())
1203         return URL();
1204
1205     return document().completeURL(stripLeadingAndTrailingHTMLSpaces(linkAttribute));
1206 }
1207
1208 WeakPtr<Element> Element::createWeakPtr()
1209 {
1210     return ensureElementRareData().weakPtrFactory().createWeakPtr();
1211 }
1212
1213 // Returns true is the given attribute is an event handler.
1214 // We consider an event handler any attribute that begins with "on".
1215 // It is a simple solution that has the advantage of not requiring any
1216 // code or configuration change if a new event handler is defined.
1217
1218 static inline bool isEventHandlerAttribute(const Attribute& attribute)
1219 {
1220     return attribute.name().namespaceURI().isNull() && attribute.name().localName().startsWith("on");
1221 }
1222
1223 bool Element::isJavaScriptURLAttribute(const Attribute& attribute) const
1224 {
1225     return isURLAttribute(attribute) && protocolIsJavaScript(stripLeadingAndTrailingHTMLSpaces(attribute.value()));
1226 }
1227
1228 void Element::stripScriptingAttributes(Vector<Attribute>& attributeVector) const
1229 {
1230     size_t destination = 0;
1231     for (size_t source = 0; source < attributeVector.size(); ++source) {
1232         if (isEventHandlerAttribute(attributeVector[source])
1233             || isJavaScriptURLAttribute(attributeVector[source])
1234             || isHTMLContentAttribute(attributeVector[source]))
1235             continue;
1236
1237         if (source != destination)
1238             attributeVector[destination] = attributeVector[source];
1239
1240         ++destination;
1241     }
1242     attributeVector.shrink(destination);
1243 }
1244
1245 void Element::parserSetAttributes(const Vector<Attribute>& attributeVector)
1246 {
1247     ASSERT(!inDocument());
1248     ASSERT(!parentNode());
1249     ASSERT(!m_elementData);
1250
1251     if (!attributeVector.isEmpty()) {
1252         if (document().sharedObjectPool())
1253             m_elementData = document().sharedObjectPool()->cachedShareableElementDataWithAttributes(attributeVector);
1254         else
1255             m_elementData = ShareableElementData::createWithAttributes(attributeVector);
1256
1257     }
1258
1259     parserDidSetAttributes();
1260
1261     // Use attributeVector instead of m_elementData because attributeChanged might modify m_elementData.
1262     for (const auto& attribute : attributeVector)
1263         attributeChanged(attribute.name(), nullAtom, attribute.value(), ModifiedDirectly);
1264 }
1265
1266 void Element::parserDidSetAttributes()
1267 {
1268 }
1269
1270 bool Element::hasAttributes() const
1271 {
1272     synchronizeAllAttributes();
1273     return elementData() && elementData()->length();
1274 }
1275
1276 bool Element::hasEquivalentAttributes(const Element* other) const
1277 {
1278     synchronizeAllAttributes();
1279     other->synchronizeAllAttributes();
1280     if (elementData() == other->elementData())
1281         return true;
1282     if (elementData())
1283         return elementData()->isEquivalent(other->elementData());
1284     if (other->elementData())
1285         return other->elementData()->isEquivalent(elementData());
1286     return true;
1287 }
1288
1289 String Element::nodeName() const
1290 {
1291     return m_tagName.toString();
1292 }
1293
1294 String Element::nodeNamePreservingCase() const
1295 {
1296     return m_tagName.toString();
1297 }
1298
1299 void Element::setPrefix(const AtomicString& prefix, ExceptionCode& ec)
1300 {
1301     ec = 0;
1302     checkSetPrefix(prefix, ec);
1303     if (ec)
1304         return;
1305
1306     m_tagName.setPrefix(prefix.isEmpty() ? AtomicString() : prefix);
1307 }
1308
1309 URL Element::baseURI() const
1310 {
1311     const AtomicString& baseAttribute = getAttribute(baseAttr);
1312     URL base(URL(), baseAttribute);
1313     if (!base.protocol().isEmpty())
1314         return base;
1315
1316     ContainerNode* parent = parentNode();
1317     if (!parent)
1318         return base;
1319
1320     const URL& parentBase = parent->baseURI();
1321     if (parentBase.isNull())
1322         return base;
1323
1324     return URL(parentBase, baseAttribute);
1325 }
1326
1327 const AtomicString& Element::imageSourceURL() const
1328 {
1329     return fastGetAttribute(srcAttr);
1330 }
1331
1332 bool Element::rendererIsNeeded(const RenderStyle& style)
1333 {
1334     return style.display() != NONE;
1335 }
1336
1337 RenderPtr<RenderElement> Element::createElementRenderer(Ref<RenderStyle>&& style)
1338 {
1339     return RenderElement::createFor(*this, WTF::move(style));
1340 }
1341
1342 Node::InsertionNotificationRequest Element::insertedInto(ContainerNode& insertionPoint)
1343 {
1344     bool wasInDocument = inDocument();
1345     // need to do superclass processing first so inDocument() is true
1346     // by the time we reach updateId
1347     ContainerNode::insertedInto(insertionPoint);
1348     ASSERT(!wasInDocument || inDocument());
1349
1350 #if ENABLE(FULLSCREEN_API)
1351     if (containsFullScreenElement() && parentElement() && !parentElement()->containsFullScreenElement())
1352         setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(true);
1353 #endif
1354
1355     if (!insertionPoint.isInTreeScope())
1356         return InsertionDone;
1357
1358     if (hasRareData())
1359         elementRareData()->clearClassListValueForQuirksMode();
1360
1361     TreeScope* newScope = &insertionPoint.treeScope();
1362     HTMLDocument* newDocument = !wasInDocument && inDocument() && is<HTMLDocument>(newScope->documentScope()) ? &downcast<HTMLDocument>(newScope->documentScope()) : nullptr;
1363     if (newScope != &treeScope())
1364         newScope = nullptr;
1365
1366     const AtomicString& idValue = getIdAttribute();
1367     if (!idValue.isNull()) {
1368         if (newScope)
1369             updateIdForTreeScope(*newScope, nullAtom, idValue);
1370         if (newDocument)
1371             updateIdForDocument(*newDocument, nullAtom, idValue, AlwaysUpdateHTMLDocumentNamedItemMaps);
1372     }
1373
1374     const AtomicString& nameValue = getNameAttribute();
1375     if (!nameValue.isNull()) {
1376         if (newScope)
1377             updateNameForTreeScope(*newScope, nullAtom, nameValue);
1378         if (newDocument)
1379             updateNameForDocument(*newDocument, nullAtom, nameValue);
1380     }
1381
1382     if (newScope && hasTagName(labelTag)) {
1383         if (newScope->shouldCacheLabelsByForAttribute())
1384             updateLabel(*newScope, nullAtom, fastGetAttribute(forAttr));
1385     }
1386
1387     return InsertionDone;
1388 }
1389
1390 void Element::removedFrom(ContainerNode& insertionPoint)
1391 {
1392 #if ENABLE(FULLSCREEN_API)
1393     if (containsFullScreenElement())
1394         setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false);
1395 #endif
1396 #if ENABLE(POINTER_LOCK)
1397     if (document().page())
1398         document().page()->pointerLockController().elementRemoved(this);
1399 #endif
1400
1401     setSavedLayerScrollOffset(IntSize());
1402
1403     if (insertionPoint.isInTreeScope()) {
1404         TreeScope* oldScope = &insertionPoint.treeScope();
1405         HTMLDocument* oldDocument = inDocument() && is<HTMLDocument>(oldScope->documentScope()) ? &downcast<HTMLDocument>(oldScope->documentScope()) : nullptr;
1406         if (oldScope != &treeScope() || !isInTreeScope())
1407             oldScope = nullptr;
1408
1409         const AtomicString& idValue = getIdAttribute();
1410         if (!idValue.isNull()) {
1411             if (oldScope)
1412                 updateIdForTreeScope(*oldScope, idValue, nullAtom);
1413             if (oldDocument)
1414                 updateIdForDocument(*oldDocument, idValue, nullAtom, AlwaysUpdateHTMLDocumentNamedItemMaps);
1415         }
1416
1417         const AtomicString& nameValue = getNameAttribute();
1418         if (!nameValue.isNull()) {
1419             if (oldScope)
1420                 updateNameForTreeScope(*oldScope, nameValue, nullAtom);
1421             if (oldDocument)
1422                 updateNameForDocument(*oldDocument, nameValue, nullAtom);
1423         }
1424
1425         if (oldScope && hasTagName(labelTag)) {
1426             if (oldScope->shouldCacheLabelsByForAttribute())
1427                 updateLabel(*oldScope, fastGetAttribute(forAttr), nullAtom);
1428         }
1429     }
1430
1431     ContainerNode::removedFrom(insertionPoint);
1432
1433     if (hasPendingResources())
1434         document().accessSVGExtensions().removeElementFromPendingResources(this);
1435 }
1436
1437 void Element::unregisterNamedFlowContentElement()
1438 {
1439     if (document().cssRegionsEnabled() && isNamedFlowContentNode() && document().renderView())
1440         document().renderView()->flowThreadController().unregisterNamedFlowContentElement(*this);
1441 }
1442
1443 ShadowRoot* Element::shadowRoot() const
1444 {
1445     return hasRareData() ? elementRareData()->shadowRoot() : 0;
1446 }
1447
1448 static bool shouldUseNodeRenderingTraversalSlowPath(const Element& element)
1449 {
1450     if (element.isShadowRoot())
1451         return true;
1452     return element.isInsertionPoint() || element.shadowRoot();
1453 }
1454
1455 void Element::resetNeedsNodeRenderingTraversalSlowPath()
1456 {
1457     setNeedsNodeRenderingTraversalSlowPath(shouldUseNodeRenderingTraversalSlowPath(*this));
1458 }
1459
1460 void Element::addShadowRoot(Ref<ShadowRoot>&& newShadowRoot)
1461 {
1462     ASSERT(!shadowRoot());
1463
1464     ShadowRoot& shadowRoot = newShadowRoot.get();
1465     ensureElementRareData().setShadowRoot(WTF::move(newShadowRoot));
1466
1467     shadowRoot.setHostElement(this);
1468     shadowRoot.setParentTreeScope(&treeScope());
1469     shadowRoot.distributor().didShadowBoundaryChange(this);
1470
1471     ChildNodeInsertionNotifier(*this).notify(shadowRoot);
1472
1473     resetNeedsNodeRenderingTraversalSlowPath();
1474
1475     setNeedsStyleRecalc(ReconstructRenderTree);
1476
1477     InspectorInstrumentation::didPushShadowRoot(*this, shadowRoot);
1478 }
1479
1480 void Element::removeShadowRoot()
1481 {
1482     RefPtr<ShadowRoot> oldRoot = shadowRoot();
1483     if (!oldRoot)
1484         return;
1485     InspectorInstrumentation::willPopShadowRoot(*this, *oldRoot);
1486     document().removeFocusedNodeOfSubtree(oldRoot.get());
1487
1488     ASSERT(!oldRoot->renderer());
1489
1490     elementRareData()->clearShadowRoot();
1491
1492     oldRoot->setHostElement(0);
1493     oldRoot->setParentTreeScope(&document());
1494
1495     ChildNodeRemovalNotifier(*this).notify(*oldRoot);
1496
1497     oldRoot->distributor().invalidateDistribution(this);
1498 }
1499
1500 RefPtr<ShadowRoot> Element::createShadowRoot(ExceptionCode& ec)
1501 {
1502     if (alwaysCreateUserAgentShadowRoot())
1503         ensureUserAgentShadowRoot();
1504
1505     ec = HIERARCHY_REQUEST_ERR;
1506     return nullptr;
1507 }
1508
1509 ShadowRoot* Element::userAgentShadowRoot() const
1510 {
1511     if (ShadowRoot* shadowRoot = this->shadowRoot()) {
1512         ASSERT(shadowRoot->type() == ShadowRoot::UserAgentShadowRoot);
1513         return shadowRoot;
1514     }
1515     return nullptr;
1516 }
1517
1518 ShadowRoot& Element::ensureUserAgentShadowRoot()
1519 {
1520     ShadowRoot* shadowRoot = userAgentShadowRoot();
1521     if (!shadowRoot) {
1522         addShadowRoot(ShadowRoot::create(document(), ShadowRoot::UserAgentShadowRoot));
1523         shadowRoot = userAgentShadowRoot();
1524         didAddUserAgentShadowRoot(shadowRoot);
1525     }
1526     return *shadowRoot;
1527 }
1528
1529 const AtomicString& Element::shadowPseudoId() const
1530 {
1531     return pseudo();
1532 }
1533
1534 bool Element::childTypeAllowed(NodeType type) const
1535 {
1536     switch (type) {
1537     case ELEMENT_NODE:
1538     case TEXT_NODE:
1539     case COMMENT_NODE:
1540     case PROCESSING_INSTRUCTION_NODE:
1541     case CDATA_SECTION_NODE:
1542     case ENTITY_REFERENCE_NODE:
1543         return true;
1544     default:
1545         break;
1546     }
1547     return false;
1548 }
1549
1550 static void checkForEmptyStyleChange(Element& element)
1551 {
1552     if (element.styleAffectedByEmpty()) {
1553         RenderStyle* style = element.renderStyle();
1554         if (!style || (!style->emptyState() || element.hasChildNodes()))
1555             element.setNeedsStyleRecalc();
1556     }
1557 }
1558
1559 enum SiblingCheckType { FinishedParsingChildren, SiblingElementRemoved, Other };
1560
1561 static void checkForSiblingStyleChanges(Element& parent, SiblingCheckType checkType, Element* elementBeforeChange, Element* elementAfterChange)
1562 {
1563     // :empty selector.
1564     checkForEmptyStyleChange(parent);
1565
1566     if (parent.styleChangeType() >= FullStyleChange)
1567         return;
1568
1569     // :first-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
1570     // In the DOM case, we only need to do something if |afterChange| is not 0.
1571     // |afterChange| is 0 in the parser case, so it works out that we'll skip this block.
1572     if (parent.childrenAffectedByFirstChildRules() && elementAfterChange) {
1573         // Find our new first child.
1574         Element* newFirstElement = ElementTraversal::firstChild(parent);
1575         // Find the first element node following |afterChange|
1576
1577         // This is the insert/append case.
1578         if (newFirstElement != elementAfterChange) {
1579             RenderStyle* style = elementAfterChange->renderStyle();
1580             if (!style || style->firstChildState())
1581                 elementAfterChange->setNeedsStyleRecalc();
1582         }
1583
1584         // We also have to handle node removal.
1585         if (checkType == SiblingElementRemoved && newFirstElement == elementAfterChange && newFirstElement) {
1586             RenderStyle* style = newFirstElement->renderStyle();
1587             if (!style || !style->firstChildState())
1588                 newFirstElement->setNeedsStyleRecalc();
1589         }
1590     }
1591
1592     // :last-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
1593     // In the DOM case, we only need to do something if |afterChange| is not 0.
1594     if (parent.childrenAffectedByLastChildRules() && elementBeforeChange) {
1595         // Find our new last child.
1596         Element* newLastElement = ElementTraversal::lastChild(parent);
1597
1598         if (newLastElement != elementBeforeChange) {
1599             RenderStyle* style = elementBeforeChange->renderStyle();
1600             if (!style || style->lastChildState())
1601                 elementBeforeChange->setNeedsStyleRecalc();
1602         }
1603
1604         // 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
1605         // to match now.
1606         if ((checkType == SiblingElementRemoved || checkType == FinishedParsingChildren) && newLastElement == elementBeforeChange && newLastElement) {
1607             RenderStyle* style = newLastElement->renderStyle();
1608             if (!style || !style->lastChildState())
1609                 newLastElement->setNeedsStyleRecalc();
1610         }
1611     }
1612
1613     if (elementAfterChange) {
1614         if (elementAfterChange->styleIsAffectedByPreviousSibling())
1615             elementAfterChange->setNeedsStyleRecalc();
1616         else if (elementAfterChange->affectsNextSiblingElementStyle()) {
1617             Element* elementToInvalidate = elementAfterChange;
1618             do {
1619                 elementToInvalidate = elementToInvalidate->nextElementSibling();
1620             } while (elementToInvalidate && !elementToInvalidate->styleIsAffectedByPreviousSibling());
1621
1622             if (elementToInvalidate)
1623                 elementToInvalidate->setNeedsStyleRecalc();
1624         }
1625     }
1626
1627     // Backward positional selectors include nth-last-child, nth-last-of-type, last-of-type and only-of-type.
1628     // We have to invalidate everything following the insertion point in the forward case, and everything before the insertion point in the
1629     // backward case.
1630     // |afterChange| is 0 in the parser callback case, so we won't do any work for the forward case if we don't have to.
1631     // For performance reasons we just mark the parent node as changed, since we don't want to make childrenChanged O(n^2) by crawling all our kids
1632     // here.  recalcStyle will then force a walk of the children when it sees that this has happened.
1633     if (parent.childrenAffectedByBackwardPositionalRules() && elementBeforeChange)
1634         parent.setNeedsStyleRecalc();
1635 }
1636
1637 void Element::childrenChanged(const ChildChange& change)
1638 {
1639     ContainerNode::childrenChanged(change);
1640     if (change.source == ChildChangeSourceParser)
1641         checkForEmptyStyleChange(*this);
1642     else {
1643         SiblingCheckType checkType = change.type == ElementRemoved ? SiblingElementRemoved : Other;
1644         checkForSiblingStyleChanges(*this, checkType, change.previousSiblingElement, change.nextSiblingElement);
1645     }
1646
1647     if (ShadowRoot* shadowRoot = this->shadowRoot())
1648         shadowRoot->invalidateDistribution();
1649 }
1650
1651 void Element::removeAllEventListeners()
1652 {
1653     ContainerNode::removeAllEventListeners();
1654     if (ShadowRoot* shadowRoot = this->shadowRoot())
1655         shadowRoot->removeAllEventListeners();
1656 }
1657
1658 void Element::beginParsingChildren()
1659 {
1660     clearIsParsingChildrenFinished();
1661     if (auto styleResolver = document().styleResolverIfExists())
1662         styleResolver->pushParentElement(this);
1663 }
1664
1665 void Element::finishParsingChildren()
1666 {
1667     ContainerNode::finishParsingChildren();
1668     setIsParsingChildrenFinished();
1669     checkForSiblingStyleChanges(*this, FinishedParsingChildren, ElementTraversal::lastChild(*this), nullptr);
1670     if (auto styleResolver = document().styleResolverIfExists())
1671         styleResolver->popParentElement(this);
1672 }
1673
1674 #ifndef NDEBUG
1675 void Element::formatForDebugger(char* buffer, unsigned length) const
1676 {
1677     StringBuilder result;
1678     String s;
1679
1680     result.append(nodeName());
1681
1682     s = getIdAttribute();
1683     if (s.length() > 0) {
1684         if (result.length() > 0)
1685             result.appendLiteral("; ");
1686         result.appendLiteral("id=");
1687         result.append(s);
1688     }
1689
1690     s = getAttribute(classAttr);
1691     if (s.length() > 0) {
1692         if (result.length() > 0)
1693             result.appendLiteral("; ");
1694         result.appendLiteral("class=");
1695         result.append(s);
1696     }
1697
1698     strncpy(buffer, result.toString().utf8().data(), length - 1);
1699 }
1700 #endif
1701
1702 const Vector<RefPtr<Attr>>& Element::attrNodeList()
1703 {
1704     ASSERT(hasSyntheticAttrChildNodes());
1705     return *attrNodeListForElement(*this);
1706 }
1707
1708 RefPtr<Attr> Element::setAttributeNode(Attr* attrNode, ExceptionCode& ec)
1709 {
1710     if (!attrNode) {
1711         ec = TYPE_MISMATCH_ERR;
1712         return 0;
1713     }
1714
1715     RefPtr<Attr> oldAttrNode = attrIfExists(attrNode->qualifiedName());
1716     if (oldAttrNode.get() == attrNode)
1717         return attrNode; // This Attr is already attached to the element.
1718
1719     // INUSE_ATTRIBUTE_ERR: Raised if node is an Attr that is already an attribute of another Element object.
1720     // The DOM user must explicitly clone Attr nodes to re-use them in other elements.
1721     if (attrNode->ownerElement()) {
1722         ec = INUSE_ATTRIBUTE_ERR;
1723         return 0;
1724     }
1725
1726     synchronizeAllAttributes();
1727     UniqueElementData& elementData = ensureUniqueElementData();
1728
1729     unsigned index = elementData.findAttributeIndexByNameForAttributeNode(attrNode, shouldIgnoreAttributeCase(*this));
1730     if (index != ElementData::attributeNotFound) {
1731         if (oldAttrNode)
1732             detachAttrNodeFromElementWithValue(oldAttrNode.get(), elementData.attributeAt(index).value());
1733         else
1734             oldAttrNode = Attr::create(document(), attrNode->qualifiedName(), elementData.attributeAt(index).value());
1735     }
1736
1737     setAttributeInternal(index, attrNode->qualifiedName(), attrNode->value(), NotInSynchronizationOfLazyAttribute);
1738
1739     attrNode->attachToElement(this);
1740     treeScope().adoptIfNeeded(attrNode);
1741     ensureAttrNodeListForElement(*this).append(attrNode);
1742
1743     return oldAttrNode.release();
1744 }
1745
1746 RefPtr<Attr> Element::setAttributeNodeNS(Attr* attr, ExceptionCode& ec)
1747 {
1748     return setAttributeNode(attr, ec);
1749 }
1750
1751 RefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionCode& ec)
1752 {
1753     if (!attr) {
1754         ec = TYPE_MISMATCH_ERR;
1755         return 0;
1756     }
1757     if (attr->ownerElement() != this) {
1758         ec = NOT_FOUND_ERR;
1759         return 0;
1760     }
1761
1762     ASSERT(&document() == &attr->document());
1763
1764     synchronizeAttribute(attr->qualifiedName());
1765
1766     unsigned index = elementData()->findAttributeIndexByNameForAttributeNode(attr);
1767     if (index == ElementData::attributeNotFound) {
1768         ec = NOT_FOUND_ERR;
1769         return 0;
1770     }
1771
1772     RefPtr<Attr> attrNode = attr;
1773     detachAttrNodeFromElementWithValue(attr, elementData()->attributeAt(index).value());
1774     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
1775     return attrNode.release();
1776 }
1777
1778 bool Element::parseAttributeName(QualifiedName& out, const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionCode& ec)
1779 {
1780     String prefix, localName;
1781     if (!Document::parseQualifiedName(qualifiedName, prefix, localName, ec))
1782         return false;
1783     ASSERT(!ec);
1784
1785     QualifiedName qName(prefix, localName, namespaceURI);
1786
1787     if (!Document::hasValidNamespaceForAttributes(qName)) {
1788         ec = NAMESPACE_ERR;
1789         return false;
1790     }
1791
1792     out = qName;
1793     return true;
1794 }
1795
1796 void Element::setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode& ec)
1797 {
1798     QualifiedName parsedName = anyName;
1799     if (!parseAttributeName(parsedName, namespaceURI, qualifiedName, ec))
1800         return;
1801     setAttribute(parsedName, value);
1802 }
1803
1804 void Element::removeAttributeInternal(unsigned index, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
1805 {
1806     ASSERT_WITH_SECURITY_IMPLICATION(index < attributeCount());
1807
1808     UniqueElementData& elementData = ensureUniqueElementData();
1809
1810     QualifiedName name = elementData.attributeAt(index).name();
1811     AtomicString valueBeingRemoved = elementData.attributeAt(index).value();
1812
1813     if (!inSynchronizationOfLazyAttribute) {
1814         if (!valueBeingRemoved.isNull())
1815             willModifyAttribute(name, valueBeingRemoved, nullAtom);
1816     }
1817
1818     if (RefPtr<Attr> attrNode = attrIfExists(name))
1819         detachAttrNodeFromElementWithValue(attrNode.get(), elementData.attributeAt(index).value());
1820
1821     elementData.removeAttribute(index);
1822
1823     if (!inSynchronizationOfLazyAttribute)
1824         didRemoveAttribute(name, valueBeingRemoved);
1825 }
1826
1827 void Element::addAttributeInternal(const QualifiedName& name, const AtomicString& value, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
1828 {
1829     if (!inSynchronizationOfLazyAttribute)
1830         willModifyAttribute(name, nullAtom, value);
1831     ensureUniqueElementData().addAttribute(name, value);
1832     if (!inSynchronizationOfLazyAttribute)
1833         didAddAttribute(name, value);
1834 }
1835
1836 bool Element::removeAttribute(const AtomicString& name)
1837 {
1838     if (!elementData())
1839         return false;
1840
1841     AtomicString localName = shouldIgnoreAttributeCase(*this) ? name.lower() : name;
1842     unsigned index = elementData()->findAttributeIndexByName(localName, false);
1843     if (index == ElementData::attributeNotFound) {
1844         if (UNLIKELY(localName == styleAttr) && elementData()->styleAttributeIsDirty() && is<StyledElement>(*this))
1845             downcast<StyledElement>(*this).removeAllInlineStyleProperties();
1846         return false;
1847     }
1848
1849     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
1850     return true;
1851 }
1852
1853 bool Element::removeAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName)
1854 {
1855     return removeAttribute(QualifiedName(nullAtom, localName, namespaceURI));
1856 }
1857
1858 RefPtr<Attr> Element::getAttributeNode(const AtomicString& localName)
1859 {
1860     if (!elementData())
1861         return 0;
1862     synchronizeAttribute(localName);
1863     const Attribute* attribute = elementData()->findAttributeByName(localName, shouldIgnoreAttributeCase(*this));
1864     if (!attribute)
1865         return 0;
1866     return ensureAttr(attribute->name());
1867 }
1868
1869 RefPtr<Attr> Element::getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName)
1870 {
1871     if (!elementData())
1872         return 0;
1873     QualifiedName qName(nullAtom, localName, namespaceURI);
1874     synchronizeAttribute(qName);
1875     const Attribute* attribute = elementData()->findAttributeByName(qName);
1876     if (!attribute)
1877         return 0;
1878     return ensureAttr(attribute->name());
1879 }
1880
1881 bool Element::hasAttribute(const AtomicString& localName) const
1882 {
1883     if (!elementData())
1884         return false;
1885     synchronizeAttribute(localName);
1886     return elementData()->findAttributeByName(shouldIgnoreAttributeCase(*this) ? localName.lower() : localName, false);
1887 }
1888
1889 bool Element::hasAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const
1890 {
1891     if (!elementData())
1892         return false;
1893     QualifiedName qName(nullAtom, localName, namespaceURI);
1894     synchronizeAttribute(qName);
1895     return elementData()->findAttributeByName(qName);
1896 }
1897
1898 CSSStyleDeclaration *Element::style()
1899 {
1900     return 0;
1901 }
1902
1903 void Element::focus(bool restorePreviousSelection, FocusDirection direction)
1904 {
1905     if (!inDocument())
1906         return;
1907
1908     if (document().focusedElement() == this)
1909         return;
1910
1911     // If the stylesheets have already been loaded we can reliably check isFocusable.
1912     // If not, we continue and set the focused node on the focus controller below so
1913     // that it can be updated soon after attach. 
1914     if (document().haveStylesheetsLoaded()) {
1915         document().updateLayoutIgnorePendingStylesheets();
1916         if (!isFocusable())
1917             return;
1918     }
1919
1920     if (!supportsFocus())
1921         return;
1922
1923     RefPtr<Node> protect;
1924     if (Page* page = document().page()) {
1925         // Focus and change event handlers can cause us to lose our last ref.
1926         // If a focus event handler changes the focus to a different node it
1927         // does not make sense to continue and update appearence.
1928         protect = this;
1929         if (!page->focusController().setFocusedElement(this, document().frame(), direction))
1930             return;
1931     }
1932
1933     // Setting the focused node above might have invalidated the layout due to scripts.
1934     document().updateLayoutIgnorePendingStylesheets();
1935
1936     if (!isFocusable()) {
1937         ensureElementRareData().setNeedsFocusAppearanceUpdateSoonAfterAttach(true);
1938         return;
1939     }
1940         
1941     cancelFocusAppearanceUpdate();
1942 #if PLATFORM(IOS)
1943     // Focusing a form element triggers animation in UIKit to scroll to the right position.
1944     // Calling updateFocusAppearance() would generate an unnecessary call to ScrollView::setScrollPosition(),
1945     // which would jump us around during this animation. See <rdar://problem/6699741>.
1946     FrameView* view = document().view();
1947     bool isFormControl = view && is<HTMLFormControlElement>(*this);
1948     if (isFormControl)
1949         view->setProhibitsScrolling(true);
1950 #endif
1951     updateFocusAppearance(restorePreviousSelection);
1952 #if PLATFORM(IOS)
1953     if (isFormControl)
1954         view->setProhibitsScrolling(false);
1955 #endif
1956 }
1957
1958 void Element::updateFocusAppearanceAfterAttachIfNeeded()
1959 {
1960     if (!hasRareData())
1961         return;
1962     ElementRareData* data = elementRareData();
1963     if (!data->needsFocusAppearanceUpdateSoonAfterAttach())
1964         return;
1965     if (isFocusable() && document().focusedElement() == this)
1966         document().updateFocusAppearanceSoon(false /* don't restore selection */);
1967     data->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
1968 }
1969
1970 void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
1971 {
1972     if (isRootEditableElement()) {
1973         Frame* frame = document().frame();
1974         if (!frame)
1975             return;
1976         
1977         // When focusing an editable element in an iframe, don't reset the selection if it already contains a selection.
1978         if (this == frame->selection().selection().rootEditableElement())
1979             return;
1980
1981         // FIXME: We should restore the previous selection if there is one.
1982         VisibleSelection newSelection = VisibleSelection(firstPositionInOrBeforeNode(this), DOWNSTREAM);
1983         
1984         if (frame->selection().shouldChangeSelection(newSelection)) {
1985             frame->selection().setSelection(newSelection);
1986             frame->selection().revealSelection();
1987         }
1988     } else if (renderer() && !renderer()->isWidget())
1989         renderer()->scrollRectToVisible(renderer()->anchorRect());
1990 }
1991
1992 void Element::blur()
1993 {
1994     cancelFocusAppearanceUpdate();
1995     if (treeScope().focusedElement() == this) {
1996         if (Frame* frame = document().frame())
1997             frame->page()->focusController().setFocusedElement(0, frame);
1998         else
1999             document().setFocusedElement(0);
2000     }
2001 }
2002
2003 void Element::dispatchFocusInEvent(const AtomicString& eventType, RefPtr<Element>&& oldFocusedElement)
2004 {
2005     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
2006     ASSERT(eventType == eventNames().focusinEvent || eventType == eventNames().DOMFocusInEvent);
2007     dispatchScopedEvent(FocusEvent::create(eventType, true, false, document().defaultView(), 0, WTF::move(oldFocusedElement)));
2008 }
2009
2010 void Element::dispatchFocusOutEvent(const AtomicString& eventType, RefPtr<Element>&& newFocusedElement)
2011 {
2012     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
2013     ASSERT(eventType == eventNames().focusoutEvent || eventType == eventNames().DOMFocusOutEvent);
2014     dispatchScopedEvent(FocusEvent::create(eventType, true, false, document().defaultView(), 0, WTF::move(newFocusedElement)));
2015 }
2016
2017 void Element::dispatchFocusEvent(RefPtr<Element>&& oldFocusedElement, FocusDirection)
2018 {
2019     if (document().page())
2020         document().page()->chrome().client().elementDidFocus(this);
2021
2022     EventDispatcher::dispatchEvent(this, FocusEvent::create(eventNames().focusEvent, false, false, document().defaultView(), 0, WTF::move(oldFocusedElement)));
2023 }
2024
2025 void Element::dispatchBlurEvent(RefPtr<Element>&& newFocusedElement)
2026 {
2027     if (document().page())
2028         document().page()->chrome().client().elementDidBlur(this);
2029
2030     EventDispatcher::dispatchEvent(this, FocusEvent::create(eventNames().blurEvent, false, false, document().defaultView(), 0, WTF::move(newFocusedElement)));
2031 }
2032
2033 void Element::mergeWithNextTextNode(Text& node, ExceptionCode& ec)
2034 {
2035     Node* next = node.nextSibling();
2036     if (!is<Text>(next))
2037         return;
2038
2039     Ref<Text> textNode(node);
2040     Ref<Text> textNext(downcast<Text>(*next));
2041     textNode->appendData(textNext->data(), ec);
2042     if (ec)
2043         return;
2044     textNext->remove(ec);
2045 }
2046
2047 String Element::innerHTML() const
2048 {
2049     return createMarkup(*this, ChildrenOnly);
2050 }
2051
2052 String Element::outerHTML() const
2053 {
2054     return createMarkup(*this);
2055 }
2056
2057 void Element::setOuterHTML(const String& html, ExceptionCode& ec)
2058 {
2059     Element* p = parentElement();
2060     if (!is<HTMLElement>(p)) {
2061         ec = NO_MODIFICATION_ALLOWED_ERR;
2062         return;
2063     }
2064     RefPtr<HTMLElement> parent = downcast<HTMLElement>(p);
2065     RefPtr<Node> prev = previousSibling();
2066     RefPtr<Node> next = nextSibling();
2067
2068     RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, parent.get(), AllowScriptingContent, ec);
2069     if (ec)
2070         return;
2071     
2072     parent->replaceChild(fragment.release(), this, ec);
2073     RefPtr<Node> node = next ? next->previousSibling() : nullptr;
2074     if (!ec && is<Text>(node.get()))
2075         mergeWithNextTextNode(downcast<Text>(*node), ec);
2076     if (!ec && is<Text>(prev.get()))
2077         mergeWithNextTextNode(downcast<Text>(*prev), ec);
2078 }
2079
2080
2081 void Element::setInnerHTML(const String& html, ExceptionCode& ec)
2082 {
2083     if (RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, this, AllowScriptingContent, ec)) {
2084         ContainerNode* container = this;
2085
2086 #if ENABLE(TEMPLATE_ELEMENT)
2087         if (is<HTMLTemplateElement>(*this))
2088             container = downcast<HTMLTemplateElement>(*this).content();
2089 #endif
2090
2091         replaceChildrenWithFragment(*container, fragment.release(), ec);
2092     }
2093 }
2094
2095 String Element::innerText()
2096 {
2097     // We need to update layout, since plainText uses line boxes in the render tree.
2098     document().updateLayoutIgnorePendingStylesheets();
2099
2100     if (!renderer())
2101         return textContent(true);
2102
2103     return plainText(rangeOfContents(*this).ptr());
2104 }
2105
2106 String Element::outerText()
2107 {
2108     // Getting outerText is the same as getting innerText, only
2109     // setting is different. You would think this should get the plain
2110     // text for the outer range, but this is wrong, <br> for instance
2111     // would return different values for inner and outer text by such
2112     // a rule, but it doesn't in WinIE, and we want to match that.
2113     return innerText();
2114 }
2115
2116 String Element::title() const
2117 {
2118     return String();
2119 }
2120
2121 const AtomicString& Element::pseudo() const
2122 {
2123     return fastGetAttribute(pseudoAttr);
2124 }
2125
2126 void Element::setPseudo(const AtomicString& value)
2127 {
2128     setAttributeWithoutSynchronization(pseudoAttr, value);
2129 }
2130
2131 LayoutSize Element::minimumSizeForResizing() const
2132 {
2133     return hasRareData() ? elementRareData()->minimumSizeForResizing() : defaultMinimumSizeForResizing();
2134 }
2135
2136 void Element::setMinimumSizeForResizing(const LayoutSize& size)
2137 {
2138     if (!hasRareData() && size == defaultMinimumSizeForResizing())
2139         return;
2140     ensureElementRareData().setMinimumSizeForResizing(size);
2141 }
2142
2143 static PseudoElement* beforeOrAfterPseudoElement(Element* host, PseudoId pseudoElementSpecifier)
2144 {
2145     switch (pseudoElementSpecifier) {
2146     case BEFORE:
2147         return host->beforePseudoElement();
2148     case AFTER:
2149         return host->afterPseudoElement();
2150     default:
2151         return 0;
2152     }
2153 }
2154
2155 RenderStyle* Element::computedStyle(PseudoId pseudoElementSpecifier)
2156 {
2157     if (PseudoElement* pseudoElement = beforeOrAfterPseudoElement(this, pseudoElementSpecifier))
2158         return pseudoElement->computedStyle();
2159
2160     // FIXME: Find and use the renderer from the pseudo element instead of the actual element so that the 'length'
2161     // properties, which are only known by the renderer because it did the layout, will be correct and so that the
2162     // values returned for the ":selection" pseudo-element will be correct.
2163     if (RenderStyle* usedStyle = renderStyle()) {
2164         if (pseudoElementSpecifier) {
2165             RenderStyle* cachedPseudoStyle = usedStyle->getCachedPseudoStyle(pseudoElementSpecifier);
2166             return cachedPseudoStyle ? cachedPseudoStyle : usedStyle;
2167         }
2168         return usedStyle;
2169     }
2170
2171     if (!inDocument()) {
2172         // FIXME: Try to do better than this. Ensure that styleForElement() works for elements that are not in the
2173         // document tree and figure out when to destroy the computed style for such elements.
2174         return nullptr;
2175     }
2176
2177     ElementRareData& data = ensureElementRareData();
2178     if (!data.computedStyle())
2179         data.setComputedStyle(document().styleForElementIgnoringPendingStylesheets(this));
2180     return pseudoElementSpecifier ? data.computedStyle()->getCachedPseudoStyle(pseudoElementSpecifier) : data.computedStyle();
2181 }
2182
2183 void Element::setStyleAffectedByEmpty()
2184 {
2185     ensureElementRareData().setStyleAffectedByEmpty(true);
2186 }
2187
2188 void Element::setChildrenAffectedByActive()
2189 {
2190     ensureElementRareData().setChildrenAffectedByActive(true);
2191 }
2192
2193 void Element::setChildrenAffectedByDrag()
2194 {
2195     ensureElementRareData().setChildrenAffectedByDrag(true);
2196 }
2197
2198 void Element::setChildrenAffectedByBackwardPositionalRules()
2199 {
2200     ensureElementRareData().setChildrenAffectedByBackwardPositionalRules(true);
2201 }
2202
2203 void Element::setChildrenAffectedByPropertyBasedBackwardPositionalRules()
2204 {
2205     ensureElementRareData().setChildrenAffectedByPropertyBasedBackwardPositionalRules(true);
2206 }
2207
2208 void Element::setChildIndex(unsigned index)
2209 {
2210     ElementRareData& rareData = ensureElementRareData();
2211     if (RenderStyle* style = renderStyle())
2212         style->setUnique();
2213     rareData.setChildIndex(index);
2214 }
2215
2216 bool Element::hasFlagsSetDuringStylingOfChildren() const
2217 {
2218     if (childrenAffectedByHover() || childrenAffectedByFirstChildRules() || childrenAffectedByLastChildRules())
2219         return true;
2220
2221     if (!hasRareData())
2222         return false;
2223     return rareDataChildrenAffectedByActive()
2224         || rareDataChildrenAffectedByDrag()
2225         || rareDataChildrenAffectedByBackwardPositionalRules()
2226         || rareDataChildrenAffectedByPropertyBasedBackwardPositionalRules();
2227 }
2228
2229 bool Element::rareDataStyleAffectedByEmpty() const
2230 {
2231     ASSERT(hasRareData());
2232     return elementRareData()->styleAffectedByEmpty();
2233 }
2234
2235 bool Element::rareDataChildrenAffectedByActive() const
2236 {
2237     ASSERT(hasRareData());
2238     return elementRareData()->childrenAffectedByActive();
2239 }
2240
2241 bool Element::rareDataChildrenAffectedByDrag() const
2242 {
2243     ASSERT(hasRareData());
2244     return elementRareData()->childrenAffectedByDrag();
2245 }
2246
2247 bool Element::rareDataChildrenAffectedByBackwardPositionalRules() const
2248 {
2249     ASSERT(hasRareData());
2250     return elementRareData()->childrenAffectedByBackwardPositionalRules();
2251 }
2252
2253 bool Element::rareDataChildrenAffectedByPropertyBasedBackwardPositionalRules() const
2254 {
2255     ASSERT(hasRareData());
2256     return elementRareData()->childrenAffectedByPropertyBasedBackwardPositionalRules();
2257 }
2258
2259 unsigned Element::rareDataChildIndex() const
2260 {
2261     ASSERT(hasRareData());
2262     return elementRareData()->childIndex();
2263 }
2264
2265 void Element::setRegionOversetState(RegionOversetState state)
2266 {
2267     ensureElementRareData().setRegionOversetState(state);
2268 }
2269
2270 RegionOversetState Element::regionOversetState() const
2271 {
2272     return hasRareData() ? elementRareData()->regionOversetState() : RegionUndefined;
2273 }
2274
2275 AtomicString Element::computeInheritedLanguage() const
2276 {
2277     if (const ElementData* elementData = this->elementData()) {
2278         if (const Attribute* attribute = elementData->findLanguageAttribute())
2279             return attribute->value();
2280     }
2281
2282     // The language property is inherited, so we iterate over the parents to find the first language.
2283     const Node* currentNode = this;
2284     while ((currentNode = currentNode->parentNode())) {
2285         if (is<Element>(*currentNode)) {
2286             if (const ElementData* elementData = downcast<Element>(*currentNode).elementData()) {
2287                 if (const Attribute* attribute = elementData->findLanguageAttribute())
2288                     return attribute->value();
2289             }
2290         } else if (is<Document>(*currentNode)) {
2291             // checking the MIME content-language
2292             return downcast<Document>(*currentNode).contentLanguage();
2293         }
2294     }
2295
2296     return nullAtom;
2297 }
2298
2299 Locale& Element::locale() const
2300 {
2301     return document().getCachedLocale(computeInheritedLanguage());
2302 }
2303
2304 void Element::cancelFocusAppearanceUpdate()
2305 {
2306     if (hasRareData())
2307         elementRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
2308     if (document().focusedElement() == this)
2309         document().cancelFocusAppearanceUpdate();
2310 }
2311
2312 void Element::normalizeAttributes()
2313 {
2314     if (!hasAttributes())
2315         return;
2316
2317     auto* attrNodeList = attrNodeListForElement(*this);
2318     if (!attrNodeList)
2319         return;
2320
2321     // Copy the Attr Vector because Node::normalize() can fire synchronous JS
2322     // events (e.g. DOMSubtreeModified) and a JS listener could add / remove
2323     // attributes while we are iterating.
2324     auto copyOfAttrNodeList = *attrNodeList;
2325     for (auto& attrNode : copyOfAttrNodeList)
2326         attrNode->normalize();
2327 }
2328
2329 PseudoElement* Element::beforePseudoElement() const
2330 {
2331     return hasRareData() ? elementRareData()->beforePseudoElement() : 0;
2332 }
2333
2334 PseudoElement* Element::afterPseudoElement() const
2335 {
2336     return hasRareData() ? elementRareData()->afterPseudoElement() : 0;
2337 }
2338
2339 void Element::setBeforePseudoElement(Ref<PseudoElement>&& element)
2340 {
2341     ensureElementRareData().setBeforePseudoElement(WTF::move(element));
2342 }
2343
2344 void Element::setAfterPseudoElement(Ref<PseudoElement>&& element)
2345 {
2346     ensureElementRareData().setAfterPseudoElement(WTF::move(element));
2347 }
2348
2349 static void disconnectPseudoElement(PseudoElement* pseudoElement)
2350 {
2351     if (!pseudoElement)
2352         return;
2353     if (pseudoElement->renderer())
2354         Style::detachRenderTree(*pseudoElement);
2355     ASSERT(pseudoElement->hostElement());
2356     pseudoElement->clearHostElement();
2357 }
2358
2359 void Element::clearBeforePseudoElement()
2360 {
2361     if (!hasRareData())
2362         return;
2363     disconnectPseudoElement(elementRareData()->beforePseudoElement());
2364     elementRareData()->setBeforePseudoElement(nullptr);
2365 }
2366
2367 void Element::clearAfterPseudoElement()
2368 {
2369     if (!hasRareData())
2370         return;
2371     disconnectPseudoElement(elementRareData()->afterPseudoElement());
2372     elementRareData()->setAfterPseudoElement(nullptr);
2373 }
2374
2375 // ElementTraversal API
2376 Element* Element::firstElementChild() const
2377 {
2378     return ElementTraversal::firstChild(*this);
2379 }
2380
2381 Element* Element::lastElementChild() const
2382 {
2383     return ElementTraversal::lastChild(*this);
2384 }
2385
2386 Element* Element::previousElementSibling() const
2387 {
2388     return ElementTraversal::previousSibling(*this);
2389 }
2390
2391 Element* Element::nextElementSibling() const
2392 {
2393     return ElementTraversal::nextSibling(*this);
2394 }
2395
2396 unsigned Element::childElementCount() const
2397 {
2398     unsigned count = 0;
2399     Node* n = firstChild();
2400     while (n) {
2401         count += n->isElementNode();
2402         n = n->nextSibling();
2403     }
2404     return count;
2405 }
2406
2407 bool Element::matchesReadWritePseudoClass() const
2408 {
2409     return false;
2410 }
2411
2412 bool Element::matches(const String& selector, ExceptionCode& ec)
2413 {
2414     SelectorQuery* selectorQuery = document().selectorQueryForString(selector, ec);
2415     return selectorQuery && selectorQuery->matches(*this);
2416 }
2417
2418 Element* Element::closest(const String& selector, ExceptionCode& ec)
2419 {
2420     SelectorQuery* selectorQuery = document().selectorQueryForString(selector, ec);
2421     if (selectorQuery)
2422         return selectorQuery->closest(*this);
2423     return nullptr;
2424 }
2425
2426 bool Element::shouldAppearIndeterminate() const
2427 {
2428     return false;
2429 }
2430
2431 bool Element::mayCauseRepaintInsideViewport(const IntRect* visibleRect) const
2432 {
2433     return renderer() && renderer()->mayCauseRepaintInsideViewport(visibleRect);
2434 }
2435
2436 DOMTokenList& Element::classList()
2437 {
2438     ElementRareData& data = ensureElementRareData();
2439     if (!data.classList())
2440         data.setClassList(std::make_unique<ClassList>(*this));
2441     return *data.classList();
2442 }
2443
2444 DatasetDOMStringMap& Element::dataset()
2445 {
2446     ElementRareData& data = ensureElementRareData();
2447     if (!data.dataset())
2448         data.setDataset(std::make_unique<DatasetDOMStringMap>(*this));
2449     return *data.dataset();
2450 }
2451
2452 URL Element::getURLAttribute(const QualifiedName& name) const
2453 {
2454 #if !ASSERT_DISABLED
2455     if (elementData()) {
2456         if (const Attribute* attribute = findAttributeByName(name))
2457             ASSERT(isURLAttribute(*attribute));
2458     }
2459 #endif
2460     return document().completeURL(stripLeadingAndTrailingHTMLSpaces(getAttribute(name)));
2461 }
2462
2463 URL Element::getNonEmptyURLAttribute(const QualifiedName& name) const
2464 {
2465 #if !ASSERT_DISABLED
2466     if (elementData()) {
2467         if (const Attribute* attribute = findAttributeByName(name))
2468             ASSERT(isURLAttribute(*attribute));
2469     }
2470 #endif
2471     String value = stripLeadingAndTrailingHTMLSpaces(getAttribute(name));
2472     if (value.isEmpty())
2473         return URL();
2474     return document().completeURL(value);
2475 }
2476
2477 int Element::getIntegralAttribute(const QualifiedName& attributeName) const
2478 {
2479     return getAttribute(attributeName).string().toInt();
2480 }
2481
2482 void Element::setIntegralAttribute(const QualifiedName& attributeName, int value)
2483 {
2484     setAttribute(attributeName, AtomicString::number(value));
2485 }
2486
2487 unsigned Element::getUnsignedIntegralAttribute(const QualifiedName& attributeName) const
2488 {
2489     return getAttribute(attributeName).string().toUInt();
2490 }
2491
2492 void Element::setUnsignedIntegralAttribute(const QualifiedName& attributeName, unsigned value)
2493 {
2494     setAttribute(attributeName, AtomicString::number(value));
2495 }
2496
2497 #if ENABLE(INDIE_UI)
2498 void Element::setUIActions(const AtomicString& actions)
2499 {
2500     setAttribute(uiactionsAttr, actions);
2501 }
2502
2503 const AtomicString& Element::UIActions() const
2504 {
2505     return getAttribute(uiactionsAttr);
2506 }
2507 #endif
2508
2509 bool Element::childShouldCreateRenderer(const Node& child) const
2510 {
2511     // Only create renderers for SVG elements whose parents are SVG elements, or for proper <svg xmlns="svgNS"> subdocuments.
2512     if (child.isSVGElement()) {
2513         ASSERT(!isSVGElement());
2514         const SVGElement& childElement = downcast<SVGElement>(child);
2515         return is<SVGSVGElement>(childElement) && childElement.isValid();
2516     }
2517     return true;
2518 }
2519
2520 #if ENABLE(FULLSCREEN_API)
2521 void Element::webkitRequestFullscreen()
2522 {
2523     document().requestFullScreenForElement(this, ALLOW_KEYBOARD_INPUT, Document::EnforceIFrameAllowFullScreenRequirement);
2524 }
2525
2526 void Element::webkitRequestFullScreen(unsigned short flags)
2527 {
2528     document().requestFullScreenForElement(this, (flags | LEGACY_MOZILLA_REQUEST), Document::EnforceIFrameAllowFullScreenRequirement);
2529 }
2530
2531 bool Element::containsFullScreenElement() const
2532 {
2533     return hasRareData() && elementRareData()->containsFullScreenElement();
2534 }
2535
2536 void Element::setContainsFullScreenElement(bool flag)
2537 {
2538     ensureElementRareData().setContainsFullScreenElement(flag);
2539     setNeedsStyleRecalc(SyntheticStyleChange);
2540 }
2541
2542 static Element* parentCrossingFrameBoundaries(Element* element)
2543 {
2544     ASSERT(element);
2545     return element->parentElement() ? element->parentElement() : element->document().ownerElement();
2546 }
2547
2548 void Element::setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(bool flag)
2549 {
2550     Element* element = this;
2551     while ((element = parentCrossingFrameBoundaries(element)))
2552         element->setContainsFullScreenElement(flag);
2553 }
2554 #endif
2555
2556 #if ENABLE(POINTER_LOCK)
2557 void Element::requestPointerLock()
2558 {
2559     if (document().page())
2560         document().page()->pointerLockController().requestPointerLock(this);
2561 }
2562 #endif
2563
2564 SpellcheckAttributeState Element::spellcheckAttributeState() const
2565 {
2566     const AtomicString& value = fastGetAttribute(HTMLNames::spellcheckAttr);
2567     if (value == nullAtom)
2568         return SpellcheckAttributeDefault;
2569     if (equalIgnoringCase(value, "true") || equalIgnoringCase(value, ""))
2570         return SpellcheckAttributeTrue;
2571     if (equalIgnoringCase(value, "false"))
2572         return SpellcheckAttributeFalse;
2573
2574     return SpellcheckAttributeDefault;
2575 }
2576
2577 bool Element::isSpellCheckingEnabled() const
2578 {
2579     for (const Element* element = this; element; element = element->parentOrShadowHostElement()) {
2580         switch (element->spellcheckAttributeState()) {
2581         case SpellcheckAttributeTrue:
2582             return true;
2583         case SpellcheckAttributeFalse:
2584             return false;
2585         case SpellcheckAttributeDefault:
2586             break;
2587         }
2588     }
2589
2590     return true;
2591 }
2592
2593 RenderNamedFlowFragment* Element::renderNamedFlowFragment() const
2594 {
2595     if (renderer() && renderer()->isRenderNamedFlowFragmentContainer())
2596         return downcast<RenderBlockFlow>(*renderer()).renderNamedFlowFragment();
2597
2598     return nullptr;
2599 }
2600
2601 #if ENABLE(CSS_REGIONS)
2602
2603 bool Element::shouldMoveToFlowThread(const RenderStyle& styleToUse) const
2604 {
2605 #if ENABLE(FULLSCREEN_API)
2606     if (document().webkitIsFullScreen() && document().webkitCurrentFullScreenElement() == this)
2607         return false;
2608 #endif
2609
2610     if (isInShadowTree())
2611         return false;
2612
2613     if (!styleToUse.hasFlowInto())
2614         return false;
2615
2616     return true;
2617 }
2618
2619 const AtomicString& Element::webkitRegionOverset() const
2620 {
2621     document().updateLayoutIgnorePendingStylesheets();
2622
2623     DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, undefinedState, ("undefined", AtomicString::ConstructFromLiteral));
2624     if (!document().cssRegionsEnabled() || !renderNamedFlowFragment())
2625         return undefinedState;
2626
2627     switch (regionOversetState()) {
2628     case RegionFit: {
2629         DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, fitState, ("fit", AtomicString::ConstructFromLiteral));
2630         return fitState;
2631     }
2632     case RegionEmpty: {
2633         DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, emptyState, ("empty", AtomicString::ConstructFromLiteral));
2634         return emptyState;
2635     }
2636     case RegionOverset: {
2637         DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, overflowState, ("overset", AtomicString::ConstructFromLiteral));
2638         return overflowState;
2639     }
2640     case RegionUndefined:
2641         return undefinedState;
2642     }
2643
2644     ASSERT_NOT_REACHED();
2645     return undefinedState;
2646 }
2647
2648 Vector<RefPtr<Range>> Element::webkitGetRegionFlowRanges() const
2649 {
2650     Vector<RefPtr<Range>> rangeObjects;
2651     if (!document().cssRegionsEnabled())
2652         return rangeObjects;
2653
2654     document().updateLayoutIgnorePendingStylesheets();
2655     if (renderer() && renderer()->isRenderNamedFlowFragmentContainer()) {
2656         RenderNamedFlowFragment& namedFlowFragment = *downcast<RenderBlockFlow>(*renderer()).renderNamedFlowFragment();
2657         if (namedFlowFragment.isValid())
2658             namedFlowFragment.getRanges(rangeObjects);
2659     }
2660
2661     return rangeObjects;
2662 }
2663
2664 #endif
2665
2666 #ifndef NDEBUG
2667 bool Element::fastAttributeLookupAllowed(const QualifiedName& name) const
2668 {
2669     if (name == HTMLNames::styleAttr)
2670         return false;
2671
2672     if (isSVGElement())
2673         return !downcast<SVGElement>(*this).isAnimatableAttribute(name);
2674
2675     return true;
2676 }
2677 #endif
2678
2679 #ifdef DUMP_NODE_STATISTICS
2680 bool Element::hasNamedNodeMap() const
2681 {
2682     return hasRareData() && elementRareData()->attributeMap();
2683 }
2684 #endif
2685
2686 inline void Element::updateName(const AtomicString& oldName, const AtomicString& newName)
2687 {
2688     if (!isInTreeScope())
2689         return;
2690
2691     if (oldName == newName)
2692         return;
2693
2694     updateNameForTreeScope(treeScope(), oldName, newName);
2695
2696     if (!inDocument())
2697         return;
2698     if (!is<HTMLDocument>(document()))
2699         return;
2700     updateNameForDocument(downcast<HTMLDocument>(document()), oldName, newName);
2701 }
2702
2703 void Element::updateNameForTreeScope(TreeScope& scope, const AtomicString& oldName, const AtomicString& newName)
2704 {
2705     ASSERT(oldName != newName);
2706
2707     if (!oldName.isEmpty())
2708         scope.removeElementByName(*oldName.impl(), *this);
2709     if (!newName.isEmpty())
2710         scope.addElementByName(*newName.impl(), *this);
2711 }
2712
2713 void Element::updateNameForDocument(HTMLDocument& document, const AtomicString& oldName, const AtomicString& newName)
2714 {
2715     ASSERT(oldName != newName);
2716
2717     if (WindowNameCollection::elementMatchesIfNameAttributeMatch(*this)) {
2718         const AtomicString& id = WindowNameCollection::elementMatchesIfIdAttributeMatch(*this) ? getIdAttribute() : nullAtom;
2719         if (!oldName.isEmpty() && oldName != id)
2720             document.removeWindowNamedItem(*oldName.impl(), *this);
2721         if (!newName.isEmpty() && newName != id)
2722             document.addWindowNamedItem(*newName.impl(), *this);
2723     }
2724
2725     if (DocumentNameCollection::elementMatchesIfNameAttributeMatch(*this)) {
2726         const AtomicString& id = DocumentNameCollection::elementMatchesIfIdAttributeMatch(*this) ? getIdAttribute() : nullAtom;
2727         if (!oldName.isEmpty() && oldName != id)
2728             document.removeDocumentNamedItem(*oldName.impl(), *this);
2729         if (!newName.isEmpty() && newName != id)
2730             document.addDocumentNamedItem(*newName.impl(), *this);
2731     }
2732 }
2733
2734 inline void Element::updateId(const AtomicString& oldId, const AtomicString& newId)
2735 {
2736     if (!isInTreeScope())
2737         return;
2738
2739     if (oldId == newId)
2740         return;
2741
2742     updateIdForTreeScope(treeScope(), oldId, newId);
2743
2744     if (!inDocument())
2745         return;
2746     if (!is<HTMLDocument>(document()))
2747         return;
2748     updateIdForDocument(downcast<HTMLDocument>(document()), oldId, newId, UpdateHTMLDocumentNamedItemMapsOnlyIfDiffersFromNameAttribute);
2749 }
2750
2751 void Element::updateIdForTreeScope(TreeScope& scope, const AtomicString& oldId, const AtomicString& newId)
2752 {
2753     ASSERT(isInTreeScope());
2754     ASSERT(oldId != newId);
2755
2756     if (!oldId.isEmpty())
2757         scope.removeElementById(*oldId.impl(), *this);
2758     if (!newId.isEmpty())
2759         scope.addElementById(*newId.impl(), *this);
2760 }
2761
2762 void Element::updateIdForDocument(HTMLDocument& document, const AtomicString& oldId, const AtomicString& newId, HTMLDocumentNamedItemMapsUpdatingCondition condition)
2763 {
2764     ASSERT(inDocument());
2765     ASSERT(oldId != newId);
2766
2767     if (WindowNameCollection::elementMatchesIfIdAttributeMatch(*this)) {
2768         const AtomicString& name = condition == UpdateHTMLDocumentNamedItemMapsOnlyIfDiffersFromNameAttribute && WindowNameCollection::elementMatchesIfNameAttributeMatch(*this) ? getNameAttribute() : nullAtom;
2769         if (!oldId.isEmpty() && oldId != name)
2770             document.removeWindowNamedItem(*oldId.impl(), *this);
2771         if (!newId.isEmpty() && newId != name)
2772             document.addWindowNamedItem(*newId.impl(), *this);
2773     }
2774
2775     if (DocumentNameCollection::elementMatchesIfIdAttributeMatch(*this)) {
2776         const AtomicString& name = condition == UpdateHTMLDocumentNamedItemMapsOnlyIfDiffersFromNameAttribute && DocumentNameCollection::elementMatchesIfNameAttributeMatch(*this) ? getNameAttribute() : nullAtom;
2777         if (!oldId.isEmpty() && oldId != name)
2778             document.removeDocumentNamedItem(*oldId.impl(), *this);
2779         if (!newId.isEmpty() && newId != name)
2780             document.addDocumentNamedItem(*newId.impl(), *this);
2781     }
2782 }
2783
2784 void Element::updateLabel(TreeScope& scope, const AtomicString& oldForAttributeValue, const AtomicString& newForAttributeValue)
2785 {
2786     ASSERT(hasTagName(labelTag));
2787
2788     if (!inDocument())
2789         return;
2790
2791     if (oldForAttributeValue == newForAttributeValue)
2792         return;
2793
2794     if (!oldForAttributeValue.isEmpty())
2795         scope.removeLabel(*oldForAttributeValue.impl(), downcast<HTMLLabelElement>(*this));
2796     if (!newForAttributeValue.isEmpty())
2797         scope.addLabel(*newForAttributeValue.impl(), downcast<HTMLLabelElement>(*this));
2798 }
2799
2800 void Element::willModifyAttribute(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue)
2801 {
2802     if (name == HTMLNames::idAttr)
2803         updateId(oldValue, newValue);
2804     else if (name == HTMLNames::nameAttr)
2805         updateName(oldValue, newValue);
2806     else if (name == HTMLNames::forAttr && hasTagName(labelTag)) {
2807         if (treeScope().shouldCacheLabelsByForAttribute())
2808             updateLabel(treeScope(), oldValue, newValue);
2809     }
2810
2811     if (oldValue != newValue) {
2812         auto styleResolver = document().styleResolverIfExists();
2813         if (styleResolver && styleResolver->hasSelectorForAttribute(*this, name.localName()))
2814             setNeedsStyleRecalc();
2815     }
2816
2817     if (std::unique_ptr<MutationObserverInterestGroup> recipients = MutationObserverInterestGroup::createForAttributesMutation(*this, name))
2818         recipients->enqueueMutationRecord(MutationRecord::createAttributes(*this, name, oldValue));
2819
2820     InspectorInstrumentation::willModifyDOMAttr(document(), *this, oldValue, newValue);
2821 }
2822
2823 void Element::didAddAttribute(const QualifiedName& name, const AtomicString& value)
2824 {
2825     attributeChanged(name, nullAtom, value);
2826     InspectorInstrumentation::didModifyDOMAttr(document(), *this, name.localName(), value);
2827     dispatchSubtreeModifiedEvent();
2828 }
2829
2830 void Element::didModifyAttribute(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue)
2831 {
2832     attributeChanged(name, oldValue, newValue);
2833     InspectorInstrumentation::didModifyDOMAttr(document(), *this, name.localName(), newValue);
2834     // Do not dispatch a DOMSubtreeModified event here; see bug 81141.
2835 }
2836
2837 void Element::didRemoveAttribute(const QualifiedName& name, const AtomicString& oldValue)
2838 {
2839     attributeChanged(name, oldValue, nullAtom);
2840     InspectorInstrumentation::didRemoveDOMAttr(document(), *this, name.localName());
2841     dispatchSubtreeModifiedEvent();
2842 }
2843
2844 RefPtr<HTMLCollection> Element::ensureCachedHTMLCollection(CollectionType type)
2845 {
2846     if (HTMLCollection* collection = cachedHTMLCollection(type))
2847         return collection;
2848
2849     if (type == TableRows) {
2850         return ensureRareData().ensureNodeLists().addCachedCollection<HTMLTableRowsCollection>(downcast<HTMLTableElement>(*this), type);
2851     } else if (type == SelectOptions) {
2852         return ensureRareData().ensureNodeLists().addCachedCollection<HTMLOptionsCollection>(downcast<HTMLSelectElement>(*this), type);
2853     } else if (type == FormControls) {
2854         ASSERT(hasTagName(formTag) || hasTagName(fieldsetTag));
2855         return ensureRareData().ensureNodeLists().addCachedCollection<HTMLFormControlsCollection>(*this, type);
2856     }
2857     return ensureRareData().ensureNodeLists().addCachedCollection<HTMLCollection>(*this, type);
2858 }
2859
2860 HTMLCollection* Element::cachedHTMLCollection(CollectionType type)
2861 {
2862     return hasRareData() && rareData()->nodeLists() ? rareData()->nodeLists()->cachedCollection<HTMLCollection>(type) : 0;
2863 }
2864
2865 IntSize Element::savedLayerScrollOffset() const
2866 {
2867     return hasRareData() ? elementRareData()->savedLayerScrollOffset() : IntSize();
2868 }
2869
2870 void Element::setSavedLayerScrollOffset(const IntSize& size)
2871 {
2872     if (size.isZero() && !hasRareData())
2873         return;
2874     ensureElementRareData().setSavedLayerScrollOffset(size);
2875 }
2876
2877 RefPtr<Attr> Element::attrIfExists(const QualifiedName& name)
2878 {
2879     if (auto* attrNodeList = attrNodeListForElement(*this))
2880         return findAttrNodeInList(*attrNodeList, name);
2881     return nullptr;
2882 }
2883
2884 RefPtr<Attr> Element::ensureAttr(const QualifiedName& name)
2885 {
2886     auto& attrNodeList = ensureAttrNodeListForElement(*this);
2887     RefPtr<Attr> attrNode = findAttrNodeInList(attrNodeList, name);
2888     if (!attrNode) {
2889         attrNode = Attr::create(this, name);
2890         treeScope().adoptIfNeeded(attrNode.get());
2891         attrNodeList.append(attrNode);
2892     }
2893     return attrNode.release();
2894 }
2895
2896 void Element::detachAttrNodeFromElementWithValue(Attr* attrNode, const AtomicString& value)
2897 {
2898     ASSERT(hasSyntheticAttrChildNodes());
2899     attrNode->detachFromElementWithValue(value);
2900
2901     auto* attrNodeList = attrNodeListForElement(*this);
2902     for (unsigned i = 0; i < attrNodeList->size(); ++i) {
2903         if (attrNodeList->at(i)->qualifiedName() == attrNode->qualifiedName()) {
2904             attrNodeList->remove(i);
2905             if (attrNodeList->isEmpty())
2906                 removeAttrNodeListForElement(*this);
2907             return;
2908         }
2909     }
2910     ASSERT_NOT_REACHED();
2911 }
2912
2913 void Element::detachAllAttrNodesFromElement()
2914 {
2915     auto* attrNodeList = attrNodeListForElement(*this);
2916     ASSERT(attrNodeList);
2917
2918     for (const Attribute& attribute : attributesIterator()) {
2919         if (RefPtr<Attr> attrNode = findAttrNodeInList(*attrNodeList, attribute.name()))
2920             attrNode->detachFromElementWithValue(attribute.value());
2921     }
2922
2923     removeAttrNodeListForElement(*this);
2924 }
2925
2926 void Element::resetComputedStyle()
2927 {
2928     if (!hasRareData() || !elementRareData()->computedStyle())
2929         return;
2930
2931     auto reset = [](Element& element) {
2932         if (!element.hasRareData() || !element.elementRareData()->computedStyle())
2933             return;
2934         if (element.hasCustomStyleResolveCallbacks())
2935             element.willResetComputedStyle();
2936         element.elementRareData()->resetComputedStyle();
2937     };
2938     reset(*this);
2939     for (auto& child : descendantsOfType<Element>(*this))
2940         reset(child);
2941 }
2942
2943 void Element::clearStyleDerivedDataBeforeDetachingRenderer()
2944 {
2945     unregisterNamedFlowContentElement();
2946     cancelFocusAppearanceUpdate();
2947     clearBeforePseudoElement();
2948     clearAfterPseudoElement();
2949     if (!hasRareData())
2950         return;
2951     ElementRareData* data = elementRareData();
2952     data->resetComputedStyle();
2953     data->resetDynamicRestyleObservations();
2954 }
2955
2956 void Element::clearHoverAndActiveStatusBeforeDetachingRenderer()
2957 {
2958     if (!isUserActionElement())
2959         return;
2960     if (hovered())
2961         document().hoveredElementDidDetach(this);
2962     if (inActiveChain())
2963         document().elementInActiveChainDidDetach(this);
2964     document().userActionElements().didDetach(this);
2965 }
2966
2967 bool Element::willRecalcStyle(Style::Change)
2968 {
2969     ASSERT(hasCustomStyleResolveCallbacks());
2970     return true;
2971 }
2972
2973 void Element::didRecalcStyle(Style::Change)
2974 {
2975     ASSERT(hasCustomStyleResolveCallbacks());
2976 }
2977
2978 void Element::willResetComputedStyle()
2979 {
2980     ASSERT(hasCustomStyleResolveCallbacks());
2981 }
2982
2983 void Element::willAttachRenderers()
2984 {
2985     ASSERT(hasCustomStyleResolveCallbacks());
2986 }
2987
2988 void Element::didAttachRenderers()
2989 {
2990     ASSERT(hasCustomStyleResolveCallbacks());
2991 }
2992
2993 void Element::willDetachRenderers()
2994 {
2995     ASSERT(hasCustomStyleResolveCallbacks());
2996 }
2997
2998 void Element::didDetachRenderers()
2999 {
3000     ASSERT(hasCustomStyleResolveCallbacks());
3001 }
3002
3003 RefPtr<RenderStyle> Element::customStyleForRenderer(RenderStyle&)
3004 {
3005     ASSERT(hasCustomStyleResolveCallbacks());
3006     return nullptr;
3007 }
3008
3009 void Element::cloneAttributesFromElement(const Element& other)
3010 {
3011     if (hasSyntheticAttrChildNodes())
3012         detachAllAttrNodesFromElement();
3013
3014     other.synchronizeAllAttributes();
3015     if (!other.m_elementData) {
3016         m_elementData.clear();
3017         return;
3018     }
3019
3020     // 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.
3021     // Fortunately, those named item maps are only updated when this element is in the document, which should never be the case.
3022     ASSERT(!inDocument());
3023
3024     const AtomicString& oldID = getIdAttribute();
3025     const AtomicString& newID = other.getIdAttribute();
3026
3027     if (!oldID.isNull() || !newID.isNull())
3028         updateId(oldID, newID);
3029
3030     const AtomicString& oldName = getNameAttribute();
3031     const AtomicString& newName = other.getNameAttribute();
3032
3033     if (!oldName.isNull() || !newName.isNull())
3034         updateName(oldName, newName);
3035
3036     // If 'other' has a mutable ElementData, convert it to an immutable one so we can share it between both elements.
3037     // We can only do this if there is no CSSOM wrapper for other's inline style, and there are no presentation attributes.
3038     if (is<UniqueElementData>(*other.m_elementData)
3039         && !other.m_elementData->presentationAttributeStyle()
3040         && (!other.m_elementData->inlineStyle() || !other.m_elementData->inlineStyle()->hasCSSOMWrapper()))
3041         const_cast<Element&>(other).m_elementData = downcast<UniqueElementData>(*other.m_elementData).makeShareableCopy();
3042
3043     if (!other.m_elementData->isUnique())
3044         m_elementData = other.m_elementData;
3045     else
3046         m_elementData = other.m_elementData->makeUniqueCopy();
3047
3048     for (const Attribute& attribute : attributesIterator())
3049         attributeChanged(attribute.name(), nullAtom, attribute.value(), ModifiedByCloning);
3050 }
3051
3052 void Element::cloneDataFromElement(const Element& other)
3053 {
3054     cloneAttributesFromElement(other);
3055     copyNonAttributePropertiesFromElement(other);
3056 }
3057
3058 void Element::createUniqueElementData()
3059 {
3060     if (!m_elementData)
3061         m_elementData = UniqueElementData::create();
3062     else
3063         m_elementData = downcast<ShareableElementData>(*m_elementData).makeUniqueCopy();
3064 }
3065
3066 bool Element::hasPendingResources() const
3067 {
3068     return hasRareData() && elementRareData()->hasPendingResources();
3069 }
3070
3071 void Element::setHasPendingResources()
3072 {
3073     ensureElementRareData().setHasPendingResources(true);
3074 }
3075
3076 void Element::clearHasPendingResources()
3077 {
3078     ensureElementRareData().setHasPendingResources(false);
3079 }
3080
3081 bool Element::canContainRangeEndPoint() const
3082 {
3083     return !equalIgnoringCase(fastGetAttribute(roleAttr), "img");
3084 }
3085
3086 String Element::completeURLsInAttributeValue(const URL& base, const Attribute& attribute) const
3087 {
3088     return URL(base, attribute.value()).string();
3089 }
3090
3091 } // namespace WebCore