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