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