c1bed0ac2db59f4af6d18c456adf0ae1f0a83c25
[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 = attached() && 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 = attached() && 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     // FIXME(94905): ShadowHost should be reattached during recalcStyle.
1500     // Set some flag here and recreate shadow hosts' renderer in
1501     // Element::recalcStyle.
1502     if (attached())
1503         setNeedsStyleRecalc(ReconstructRenderTree);
1504
1505     InspectorInstrumentation::didPushShadowRoot(this, shadowRoot);
1506 }
1507
1508 void Element::removeShadowRoot()
1509 {
1510     RefPtr<ShadowRoot> oldRoot = shadowRoot();
1511     if (!oldRoot)
1512         return;
1513     InspectorInstrumentation::willPopShadowRoot(this, oldRoot.get());
1514     document().removeFocusedNodeOfSubtree(oldRoot.get());
1515
1516     ASSERT(!oldRoot->attached());
1517
1518     elementRareData()->clearShadowRoot();
1519
1520     oldRoot->setHostElement(0);
1521     oldRoot->setParentTreeScope(&document());
1522
1523     ChildNodeRemovalNotifier(*this).notify(*oldRoot);
1524
1525     oldRoot->distributor().invalidateDistribution(this);
1526 }
1527
1528 PassRefPtr<ShadowRoot> Element::createShadowRoot(ExceptionCode& ec)
1529 {
1530     if (alwaysCreateUserAgentShadowRoot())
1531         ensureUserAgentShadowRoot();
1532
1533 #if ENABLE(SHADOW_DOM)
1534     if (RuntimeEnabledFeatures::sharedFeatures().authorShadowDOMForAnyElementEnabled()) {
1535         addShadowRoot(ShadowRoot::create(document(), ShadowRoot::AuthorShadowRoot));
1536         return shadowRoot();
1537     }
1538 #endif
1539
1540     // Since some elements recreates shadow root dynamically, multiple shadow
1541     // subtrees won't work well in that element. Until they are fixed, we disable
1542     // adding author shadow root for them.
1543     if (!areAuthorShadowsAllowed()) {
1544         ec = HIERARCHY_REQUEST_ERR;
1545         return 0;
1546     }
1547     addShadowRoot(ShadowRoot::create(document(), ShadowRoot::AuthorShadowRoot));
1548
1549     return shadowRoot();
1550 }
1551
1552 ShadowRoot* Element::authorShadowRoot() const
1553 {
1554     ShadowRoot* shadowRoot = this->shadowRoot();
1555     if (shadowRoot->type() == ShadowRoot::AuthorShadowRoot)
1556         return shadowRoot;
1557     return 0;
1558 }
1559
1560 ShadowRoot* Element::userAgentShadowRoot() const
1561 {
1562     if (ShadowRoot* shadowRoot = this->shadowRoot()) {
1563         ASSERT(shadowRoot->type() == ShadowRoot::UserAgentShadowRoot);
1564         return shadowRoot;
1565     }
1566     return 0;
1567 }
1568
1569 ShadowRoot& Element::ensureUserAgentShadowRoot()
1570 {
1571     ShadowRoot* shadowRoot = userAgentShadowRoot();
1572     if (!shadowRoot) {
1573         addShadowRoot(ShadowRoot::create(document(), ShadowRoot::UserAgentShadowRoot));
1574         shadowRoot = userAgentShadowRoot();
1575         didAddUserAgentShadowRoot(shadowRoot);
1576     }
1577     return *shadowRoot;
1578 }
1579
1580 const AtomicString& Element::shadowPseudoId() const
1581 {
1582     return pseudo();
1583 }
1584
1585 bool Element::childTypeAllowed(NodeType type) const
1586 {
1587     switch (type) {
1588     case ELEMENT_NODE:
1589     case TEXT_NODE:
1590     case COMMENT_NODE:
1591     case PROCESSING_INSTRUCTION_NODE:
1592     case CDATA_SECTION_NODE:
1593     case ENTITY_REFERENCE_NODE:
1594         return true;
1595     default:
1596         break;
1597     }
1598     return false;
1599 }
1600
1601 static void checkForEmptyStyleChange(Element* element, RenderStyle* style)
1602 {
1603     if (!style && !element->styleAffectedByEmpty())
1604         return;
1605
1606     if (!style || (element->styleAffectedByEmpty() && (!style->emptyState() || element->hasChildNodes())))
1607         element->setNeedsStyleRecalc();
1608 }
1609
1610 enum SiblingCheckType { FinishedParsingChildren, SiblingElementRemoved, Other };
1611
1612 static void checkForSiblingStyleChanges(Element* parent, SiblingCheckType checkType, Element* elementBeforeChange, Element* elementAfterChange)
1613 {
1614     RenderStyle* style = parent->renderStyle();
1615     // :empty selector.
1616     checkForEmptyStyleChange(parent, style);
1617     
1618     if (!style || (parent->needsStyleRecalc() && parent->childrenAffectedByPositionalRules()))
1619         return;
1620
1621     // :first-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
1622     // In the DOM case, we only need to do something if |afterChange| is not 0.
1623     // |afterChange| is 0 in the parser case, so it works out that we'll skip this block.
1624     if (parent->childrenAffectedByFirstChildRules() && elementAfterChange) {
1625         // Find our new first child.
1626         Element* newFirstElement = ElementTraversal::firstChild(parent);
1627         // Find the first element node following |afterChange|
1628
1629         // This is the insert/append case.
1630         if (newFirstElement != elementAfterChange && elementAfterChange->attached()
1631             && elementAfterChange->renderStyle() && elementAfterChange->renderStyle()->firstChildState())
1632             elementAfterChange->setNeedsStyleRecalc();
1633             
1634         // We also have to handle node removal.
1635         if (checkType == SiblingElementRemoved && newFirstElement == elementAfterChange && newFirstElement && (!newFirstElement->renderStyle() || !newFirstElement->renderStyle()->firstChildState()))
1636             newFirstElement->setNeedsStyleRecalc();
1637     }
1638
1639     // :last-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
1640     // In the DOM case, we only need to do something if |afterChange| is not 0.
1641     if (parent->childrenAffectedByLastChildRules() && elementBeforeChange) {
1642         // Find our new last child.
1643         Element* newLastElement = ElementTraversal::lastChild(parent);
1644
1645         if (newLastElement != elementBeforeChange && elementBeforeChange->attached()
1646             && elementBeforeChange->renderStyle() && elementBeforeChange->renderStyle()->lastChildState())
1647             elementBeforeChange->setNeedsStyleRecalc();
1648             
1649         // 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
1650         // to match now.
1651         if ((checkType == SiblingElementRemoved || checkType == FinishedParsingChildren) && newLastElement == elementBeforeChange && newLastElement
1652             && (!newLastElement->renderStyle() || !newLastElement->renderStyle()->lastChildState()))
1653             newLastElement->setNeedsStyleRecalc();
1654     }
1655
1656     // The + selector.  We need to invalidate the first element following the insertion point.  It is the only possible element
1657     // that could be affected by this DOM change.
1658     if (parent->childrenAffectedByDirectAdjacentRules() && elementAfterChange) {
1659         if (elementAfterChange->attached())
1660             elementAfterChange->setNeedsStyleRecalc();
1661     }
1662
1663     // Forward positional selectors include the ~ selector, nth-child, nth-of-type, first-of-type and only-of-type.
1664     // Backward positional selectors include nth-last-child, nth-last-of-type, last-of-type and only-of-type.
1665     // We have to invalidate everything following the insertion point in the forward case, and everything before the insertion point in the
1666     // backward case.
1667     // |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.
1668     // 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
1669     // here.  recalcStyle will then force a walk of the children when it sees that this has happened.
1670     if (parent->childrenAffectedByForwardPositionalRules() && elementAfterChange)
1671         parent->setNeedsStyleRecalc();
1672     if (parent->childrenAffectedByBackwardPositionalRules() && elementBeforeChange)
1673         parent->setNeedsStyleRecalc();
1674 }
1675
1676 void Element::childrenChanged(const ChildChange& change)
1677 {
1678     ContainerNode::childrenChanged(change);
1679     if (change.source == ChildChangeSourceParser)
1680         checkForEmptyStyleChange(this, renderStyle());
1681     else {
1682         SiblingCheckType checkType = change.type == ElementRemoved ? SiblingElementRemoved : Other;
1683         checkForSiblingStyleChanges(this, checkType, change.previousSiblingElement, change.nextSiblingElement);
1684     }
1685
1686     if (ShadowRoot* shadowRoot = this->shadowRoot())
1687         shadowRoot->invalidateDistribution();
1688 }
1689
1690 void Element::removeAllEventListeners()
1691 {
1692     ContainerNode::removeAllEventListeners();
1693     if (ShadowRoot* shadowRoot = this->shadowRoot())
1694         shadowRoot->removeAllEventListeners();
1695 }
1696
1697 void Element::beginParsingChildren()
1698 {
1699     clearIsParsingChildrenFinished();
1700     StyleResolver* styleResolver = document().styleResolverIfExists();
1701     if (styleResolver && attached())
1702         styleResolver->pushParentElement(this);
1703 }
1704
1705 void Element::finishParsingChildren()
1706 {
1707     ContainerNode::finishParsingChildren();
1708     setIsParsingChildrenFinished();
1709     checkForSiblingStyleChanges(this, FinishedParsingChildren, ElementTraversal::lastChild(this), nullptr);
1710     if (StyleResolver* styleResolver = document().styleResolverIfExists())
1711         styleResolver->popParentElement(this);
1712 }
1713
1714 #ifndef NDEBUG
1715 void Element::formatForDebugger(char* buffer, unsigned length) const
1716 {
1717     StringBuilder result;
1718     String s;
1719
1720     result.append(nodeName());
1721
1722     s = getIdAttribute();
1723     if (s.length() > 0) {
1724         if (result.length() > 0)
1725             result.appendLiteral("; ");
1726         result.appendLiteral("id=");
1727         result.append(s);
1728     }
1729
1730     s = getAttribute(classAttr);
1731     if (s.length() > 0) {
1732         if (result.length() > 0)
1733             result.appendLiteral("; ");
1734         result.appendLiteral("class=");
1735         result.append(s);
1736     }
1737
1738     strncpy(buffer, result.toString().utf8().data(), length - 1);
1739 }
1740 #endif
1741
1742 const Vector<RefPtr<Attr>>& Element::attrNodeList()
1743 {
1744     ASSERT(hasSyntheticAttrChildNodes());
1745     return *attrNodeListForElement(this);
1746 }
1747
1748 PassRefPtr<Attr> Element::setAttributeNode(Attr* attrNode, ExceptionCode& ec)
1749 {
1750     if (!attrNode) {
1751         ec = TYPE_MISMATCH_ERR;
1752         return 0;
1753     }
1754
1755     RefPtr<Attr> oldAttrNode = attrIfExists(attrNode->qualifiedName());
1756     if (oldAttrNode.get() == attrNode)
1757         return attrNode; // This Attr is already attached to the element.
1758
1759     // INUSE_ATTRIBUTE_ERR: Raised if node is an Attr that is already an attribute of another Element object.
1760     // The DOM user must explicitly clone Attr nodes to re-use them in other elements.
1761     if (attrNode->ownerElement()) {
1762         ec = INUSE_ATTRIBUTE_ERR;
1763         return 0;
1764     }
1765
1766     synchronizeAllAttributes();
1767     UniqueElementData& elementData = ensureUniqueElementData();
1768
1769     unsigned index = elementData.findAttributeIndexByNameForAttributeNode(attrNode, shouldIgnoreAttributeCase(*this));
1770     if (index != ElementData::attributeNotFound) {
1771         if (oldAttrNode)
1772             detachAttrNodeFromElementWithValue(oldAttrNode.get(), elementData.attributeAt(index).value());
1773         else
1774             oldAttrNode = Attr::create(document(), attrNode->qualifiedName(), elementData.attributeAt(index).value());
1775     }
1776
1777     setAttributeInternal(index, attrNode->qualifiedName(), attrNode->value(), NotInSynchronizationOfLazyAttribute);
1778
1779     attrNode->attachToElement(this);
1780     treeScope().adoptIfNeeded(attrNode);
1781     ensureAttrNodeListForElement(this).append(attrNode);
1782
1783     return oldAttrNode.release();
1784 }
1785
1786 PassRefPtr<Attr> Element::setAttributeNodeNS(Attr* attr, ExceptionCode& ec)
1787 {
1788     return setAttributeNode(attr, ec);
1789 }
1790
1791 PassRefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionCode& ec)
1792 {
1793     if (!attr) {
1794         ec = TYPE_MISMATCH_ERR;
1795         return 0;
1796     }
1797     if (attr->ownerElement() != this) {
1798         ec = NOT_FOUND_ERR;
1799         return 0;
1800     }
1801
1802     ASSERT(&document() == &attr->document());
1803
1804     synchronizeAttribute(attr->qualifiedName());
1805
1806     unsigned index = elementData()->findAttributeIndexByNameForAttributeNode(attr);
1807     if (index == ElementData::attributeNotFound) {
1808         ec = NOT_FOUND_ERR;
1809         return 0;
1810     }
1811
1812     RefPtr<Attr> attrNode = attr;
1813     detachAttrNodeFromElementWithValue(attr, elementData()->attributeAt(index).value());
1814     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
1815     return attrNode.release();
1816 }
1817
1818 bool Element::parseAttributeName(QualifiedName& out, const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionCode& ec)
1819 {
1820     String prefix, localName;
1821     if (!Document::parseQualifiedName(qualifiedName, prefix, localName, ec))
1822         return false;
1823     ASSERT(!ec);
1824
1825     QualifiedName qName(prefix, localName, namespaceURI);
1826
1827     if (!Document::hasValidNamespaceForAttributes(qName)) {
1828         ec = NAMESPACE_ERR;
1829         return false;
1830     }
1831
1832     out = qName;
1833     return true;
1834 }
1835
1836 void Element::setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode& ec)
1837 {
1838     QualifiedName parsedName = anyName;
1839     if (!parseAttributeName(parsedName, namespaceURI, qualifiedName, ec))
1840         return;
1841     setAttribute(parsedName, value);
1842 }
1843
1844 void Element::removeAttributeInternal(unsigned index, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
1845 {
1846     ASSERT_WITH_SECURITY_IMPLICATION(index < attributeCount());
1847
1848     UniqueElementData& elementData = ensureUniqueElementData();
1849
1850     QualifiedName name = elementData.attributeAt(index).name();
1851     AtomicString valueBeingRemoved = elementData.attributeAt(index).value();
1852
1853     if (!inSynchronizationOfLazyAttribute) {
1854         if (!valueBeingRemoved.isNull())
1855             willModifyAttribute(name, valueBeingRemoved, nullAtom);
1856     }
1857
1858     if (RefPtr<Attr> attrNode = attrIfExists(name))
1859         detachAttrNodeFromElementWithValue(attrNode.get(), elementData.attributeAt(index).value());
1860
1861     elementData.removeAttribute(index);
1862
1863     if (!inSynchronizationOfLazyAttribute)
1864         didRemoveAttribute(name);
1865 }
1866
1867 void Element::addAttributeInternal(const QualifiedName& name, const AtomicString& value, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
1868 {
1869     if (!inSynchronizationOfLazyAttribute)
1870         willModifyAttribute(name, nullAtom, value);
1871     ensureUniqueElementData().addAttribute(name, value);
1872     if (!inSynchronizationOfLazyAttribute)
1873         didAddAttribute(name, value);
1874 }
1875
1876 void Element::removeAttribute(const AtomicString& name)
1877 {
1878     if (!elementData())
1879         return;
1880
1881     AtomicString localName = shouldIgnoreAttributeCase(*this) ? name.lower() : name;
1882     unsigned index = elementData()->findAttributeIndexByName(localName, false);
1883     if (index == ElementData::attributeNotFound) {
1884         if (UNLIKELY(localName == styleAttr) && elementData()->m_styleAttributeIsDirty && isStyledElement())
1885             toStyledElement(this)->removeAllInlineStyleProperties();
1886         return;
1887     }
1888
1889     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
1890 }
1891
1892 void Element::removeAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName)
1893 {
1894     removeAttribute(QualifiedName(nullAtom, localName, namespaceURI));
1895 }
1896
1897 PassRefPtr<Attr> Element::getAttributeNode(const AtomicString& localName)
1898 {
1899     if (!elementData())
1900         return 0;
1901     synchronizeAttribute(localName);
1902     const Attribute* attribute = elementData()->findAttributeByName(localName, shouldIgnoreAttributeCase(*this));
1903     if (!attribute)
1904         return 0;
1905     return ensureAttr(attribute->name());
1906 }
1907
1908 PassRefPtr<Attr> Element::getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName)
1909 {
1910     if (!elementData())
1911         return 0;
1912     QualifiedName qName(nullAtom, localName, namespaceURI);
1913     synchronizeAttribute(qName);
1914     const Attribute* attribute = elementData()->findAttributeByName(qName);
1915     if (!attribute)
1916         return 0;
1917     return ensureAttr(attribute->name());
1918 }
1919
1920 bool Element::hasAttribute(const AtomicString& localName) const
1921 {
1922     if (!elementData())
1923         return false;
1924     synchronizeAttribute(localName);
1925     return elementData()->findAttributeByName(shouldIgnoreAttributeCase(*this) ? localName.lower() : localName, false);
1926 }
1927
1928 bool Element::hasAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const
1929 {
1930     if (!elementData())
1931         return false;
1932     QualifiedName qName(nullAtom, localName, namespaceURI);
1933     synchronizeAttribute(qName);
1934     return elementData()->findAttributeByName(qName);
1935 }
1936
1937 CSSStyleDeclaration *Element::style()
1938 {
1939     return 0;
1940 }
1941
1942 void Element::focus(bool restorePreviousSelection, FocusDirection direction)
1943 {
1944     if (!inDocument())
1945         return;
1946
1947     if (document().focusedElement() == this)
1948         return;
1949
1950     // If the stylesheets have already been loaded we can reliably check isFocusable.
1951     // If not, we continue and set the focused node on the focus controller below so
1952     // that it can be updated soon after attach. 
1953     if (document().haveStylesheetsLoaded()) {
1954         document().updateLayoutIgnorePendingStylesheets();
1955         if (!isFocusable())
1956             return;
1957     }
1958
1959     if (!supportsFocus())
1960         return;
1961
1962     RefPtr<Node> protect;
1963     if (Page* page = document().page()) {
1964         // Focus and change event handlers can cause us to lose our last ref.
1965         // If a focus event handler changes the focus to a different node it
1966         // does not make sense to continue and update appearence.
1967         protect = this;
1968         if (!page->focusController().setFocusedElement(this, document().frame(), direction))
1969             return;
1970     }
1971
1972     // Setting the focused node above might have invalidated the layout due to scripts.
1973     document().updateLayoutIgnorePendingStylesheets();
1974
1975     if (!isFocusable()) {
1976         ensureElementRareData().setNeedsFocusAppearanceUpdateSoonAfterAttach(true);
1977         return;
1978     }
1979         
1980     cancelFocusAppearanceUpdate();
1981 #if PLATFORM(IOS)
1982     // Focusing a form element triggers animation in UIKit to scroll to the right position.
1983     // Calling updateFocusAppearance() would generate an unnecessary call to ScrollView::setScrollPosition(),
1984     // which would jump us around during this animation. See <rdar://problem/6699741>.
1985     FrameView* view = document().view();
1986     bool isFormControl = view && isFormControlElement();
1987     if (isFormControl)
1988         view->setProhibitsScrolling(true);
1989 #endif
1990     updateFocusAppearance(restorePreviousSelection);
1991 #if PLATFORM(IOS)
1992     if (isFormControl)
1993         view->setProhibitsScrolling(false);
1994 #endif
1995 }
1996
1997 void Element::updateFocusAppearanceAfterAttachIfNeeded()
1998 {
1999     if (!hasRareData())
2000         return;
2001     ElementRareData* data = elementRareData();
2002     if (!data->needsFocusAppearanceUpdateSoonAfterAttach())
2003         return;
2004     if (isFocusable() && document().focusedElement() == this)
2005         document().updateFocusAppearanceSoon(false /* don't restore selection */);
2006     data->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
2007 }
2008
2009 void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
2010 {
2011     if (isRootEditableElement()) {
2012         Frame* frame = document().frame();
2013         if (!frame)
2014             return;
2015         
2016         // When focusing an editable element in an iframe, don't reset the selection if it already contains a selection.
2017         if (this == frame->selection().rootEditableElement())
2018             return;
2019
2020         // FIXME: We should restore the previous selection if there is one.
2021         VisibleSelection newSelection = VisibleSelection(firstPositionInOrBeforeNode(this), DOWNSTREAM);
2022         
2023         if (frame->selection().shouldChangeSelection(newSelection)) {
2024             frame->selection().setSelection(newSelection);
2025             frame->selection().revealSelection();
2026         }
2027     } else if (renderer() && !renderer()->isWidget())
2028         renderer()->scrollRectToVisible(boundingBox());
2029 }
2030
2031 void Element::blur()
2032 {
2033     cancelFocusAppearanceUpdate();
2034     if (treeScope().focusedElement() == this) {
2035         if (Frame* frame = document().frame())
2036             frame->page()->focusController().setFocusedElement(0, frame);
2037         else
2038             document().setFocusedElement(0);
2039     }
2040 }
2041
2042 void Element::dispatchFocusInEvent(const AtomicString& eventType, PassRefPtr<Element> oldFocusedElement)
2043 {
2044     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
2045     ASSERT(eventType == eventNames().focusinEvent || eventType == eventNames().DOMFocusInEvent);
2046     dispatchScopedEvent(FocusEvent::create(eventType, true, false, document().defaultView(), 0, oldFocusedElement));
2047 }
2048
2049 void Element::dispatchFocusOutEvent(const AtomicString& eventType, PassRefPtr<Element> newFocusedElement)
2050 {
2051     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
2052     ASSERT(eventType == eventNames().focusoutEvent || eventType == eventNames().DOMFocusOutEvent);
2053     dispatchScopedEvent(FocusEvent::create(eventType, true, false, document().defaultView(), 0, newFocusedElement));
2054 }
2055
2056 void Element::dispatchFocusEvent(PassRefPtr<Element> oldFocusedElement, FocusDirection)
2057 {
2058     if (document().page())
2059         document().page()->chrome().client().elementDidFocus(this);
2060
2061     RefPtr<FocusEvent> event = FocusEvent::create(eventNames().focusEvent, false, false, document().defaultView(), 0, oldFocusedElement);
2062     EventDispatcher::dispatchEvent(this, event.release());
2063 }
2064
2065 void Element::dispatchBlurEvent(PassRefPtr<Element> newFocusedElement)
2066 {
2067     if (document().page())
2068         document().page()->chrome().client().elementDidBlur(this);
2069
2070     RefPtr<FocusEvent> event = FocusEvent::create(eventNames().blurEvent, false, false, document().defaultView(), 0, newFocusedElement);
2071     EventDispatcher::dispatchEvent(this, event.release());
2072 }
2073
2074
2075 String Element::innerText()
2076 {
2077     // We need to update layout, since plainText uses line boxes in the render tree.
2078     document().updateLayoutIgnorePendingStylesheets();
2079
2080     if (!renderer())
2081         return textContent(true);
2082
2083     return plainText(rangeOfContents(*this).get());
2084 }
2085
2086 String Element::outerText()
2087 {
2088     // Getting outerText is the same as getting innerText, only
2089     // setting is different. You would think this should get the plain
2090     // text for the outer range, but this is wrong, <br> for instance
2091     // would return different values for inner and outer text by such
2092     // a rule, but it doesn't in WinIE, and we want to match that.
2093     return innerText();
2094 }
2095
2096 String Element::title() const
2097 {
2098     return String();
2099 }
2100
2101 const AtomicString& Element::pseudo() const
2102 {
2103     return getAttribute(pseudoAttr);
2104 }
2105
2106 void Element::setPseudo(const AtomicString& value)
2107 {
2108     setAttribute(pseudoAttr, value);
2109 }
2110
2111 LayoutSize Element::minimumSizeForResizing() const
2112 {
2113     return hasRareData() ? elementRareData()->minimumSizeForResizing() : defaultMinimumSizeForResizing();
2114 }
2115
2116 void Element::setMinimumSizeForResizing(const LayoutSize& size)
2117 {
2118     if (!hasRareData() && size == defaultMinimumSizeForResizing())
2119         return;
2120     ensureElementRareData().setMinimumSizeForResizing(size);
2121 }
2122
2123 static PseudoElement* beforeOrAfterPseudoElement(Element* host, PseudoId pseudoElementSpecifier)
2124 {
2125     switch (pseudoElementSpecifier) {
2126     case BEFORE:
2127         return host->beforePseudoElement();
2128     case AFTER:
2129         return host->afterPseudoElement();
2130     default:
2131         return 0;
2132     }
2133 }
2134
2135 RenderStyle* Element::computedStyle(PseudoId pseudoElementSpecifier)
2136 {
2137     if (PseudoElement* pseudoElement = beforeOrAfterPseudoElement(this, pseudoElementSpecifier))
2138         return pseudoElement->computedStyle();
2139
2140     // FIXME: Find and use the renderer from the pseudo element instead of the actual element so that the 'length'
2141     // properties, which are only known by the renderer because it did the layout, will be correct and so that the
2142     // values returned for the ":selection" pseudo-element will be correct.
2143     if (RenderStyle* usedStyle = renderStyle()) {
2144         if (pseudoElementSpecifier) {
2145             RenderStyle* cachedPseudoStyle = usedStyle->getCachedPseudoStyle(pseudoElementSpecifier);
2146             return cachedPseudoStyle ? cachedPseudoStyle : usedStyle;
2147         }
2148         return usedStyle;
2149     }
2150
2151     if (!inDocument()) {
2152         // FIXME: Try to do better than this. Ensure that styleForElement() works for elements that are not in the
2153         // document tree and figure out when to destroy the computed style for such elements.
2154         return nullptr;
2155     }
2156
2157     ElementRareData& data = ensureElementRareData();
2158     if (!data.computedStyle())
2159         data.setComputedStyle(document().styleForElementIgnoringPendingStylesheets(this));
2160     return pseudoElementSpecifier ? data.computedStyle()->getCachedPseudoStyle(pseudoElementSpecifier) : data.computedStyle();
2161 }
2162
2163 void Element::setStyleAffectedByEmpty()
2164 {
2165     ensureElementRareData().setStyleAffectedByEmpty(true);
2166 }
2167
2168 void Element::setChildrenAffectedByActive()
2169 {
2170     ensureElementRareData().setChildrenAffectedByActive(true);
2171 }
2172
2173 void Element::setChildrenAffectedByDrag()
2174 {
2175     ensureElementRareData().setChildrenAffectedByDrag(true);
2176 }
2177
2178 void Element::setChildrenAffectedByDirectAdjacentRules(Element* element)
2179 {
2180     element->setChildrenAffectedByDirectAdjacentRules();
2181 }
2182
2183 void Element::setChildrenAffectedByForwardPositionalRules(Element* element)
2184 {
2185     element->ensureElementRareData().setChildrenAffectedByForwardPositionalRules(true);
2186 }
2187
2188 void Element::setChildrenAffectedByBackwardPositionalRules()
2189 {
2190     ensureElementRareData().setChildrenAffectedByBackwardPositionalRules(true);
2191 }
2192
2193 void Element::setChildIndex(unsigned index)
2194 {
2195     ElementRareData& rareData = ensureElementRareData();
2196     if (RenderStyle* style = renderStyle())
2197         style->setUnique();
2198     rareData.setChildIndex(index);
2199 }
2200
2201 bool Element::hasFlagsSetDuringStylingOfChildren() const
2202 {
2203     if (childrenAffectedByHover() || childrenAffectedByFirstChildRules() || childrenAffectedByLastChildRules() || childrenAffectedByDirectAdjacentRules())
2204         return true;
2205
2206     if (!hasRareData())
2207         return false;
2208     return rareDataChildrenAffectedByActive()
2209         || rareDataChildrenAffectedByDrag()
2210         || rareDataChildrenAffectedByForwardPositionalRules()
2211         || rareDataChildrenAffectedByBackwardPositionalRules();
2212 }
2213
2214 bool Element::rareDataStyleAffectedByEmpty() const
2215 {
2216     ASSERT(hasRareData());
2217     return elementRareData()->styleAffectedByEmpty();
2218 }
2219
2220 bool Element::rareDataChildrenAffectedByActive() const
2221 {
2222     ASSERT(hasRareData());
2223     return elementRareData()->childrenAffectedByActive();
2224 }
2225
2226 bool Element::rareDataChildrenAffectedByDrag() const
2227 {
2228     ASSERT(hasRareData());
2229     return elementRareData()->childrenAffectedByDrag();
2230 }
2231
2232 bool Element::rareDataChildrenAffectedByForwardPositionalRules() const
2233 {
2234     ASSERT(hasRareData());
2235     return elementRareData()->childrenAffectedByForwardPositionalRules();
2236 }
2237
2238 bool Element::rareDataChildrenAffectedByBackwardPositionalRules() const
2239 {
2240     ASSERT(hasRareData());
2241     return elementRareData()->childrenAffectedByBackwardPositionalRules();
2242 }
2243
2244 unsigned Element::rareDataChildIndex() const
2245 {
2246     ASSERT(hasRareData());
2247     return elementRareData()->childIndex();
2248 }
2249
2250 void Element::setIsInCanvasSubtree(bool isInCanvasSubtree)
2251 {
2252     ensureElementRareData().setIsInCanvasSubtree(isInCanvasSubtree);
2253 }
2254
2255 bool Element::isInCanvasSubtree() const
2256 {
2257     return hasRareData() && elementRareData()->isInCanvasSubtree();
2258 }
2259
2260 void Element::setIsInsideRegion(bool value)
2261 {
2262     if (value == isInsideRegion())
2263         return;
2264
2265     ensureElementRareData().setIsInsideRegion(value);
2266 }
2267
2268 bool Element::isInsideRegion() const
2269 {
2270     return hasRareData() ? elementRareData()->isInsideRegion() : false;
2271 }
2272
2273 void Element::setRegionOversetState(RegionOversetState state)
2274 {
2275     ensureElementRareData().setRegionOversetState(state);
2276 }
2277
2278 RegionOversetState Element::regionOversetState() const
2279 {
2280     return hasRareData() ? elementRareData()->regionOversetState() : RegionUndefined;
2281 }
2282
2283 AtomicString Element::computeInheritedLanguage() const
2284 {
2285     const Node* n = this;
2286     AtomicString value;
2287     // The language property is inherited, so we iterate over the parents to find the first language.
2288     do {
2289         if (n->isElementNode()) {
2290             if (const ElementData* elementData = toElement(n)->elementData()) {
2291                 // Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7
2292                 if (const Attribute* attribute = elementData->findAttributeByName(XMLNames::langAttr))
2293                     value = attribute->value();
2294                 else if (const Attribute* attribute = elementData->findAttributeByName(HTMLNames::langAttr))
2295                     value = attribute->value();
2296             }
2297         } else if (n->isDocumentNode()) {
2298             // checking the MIME content-language
2299             value = toDocument(n)->contentLanguage();
2300         }
2301
2302         n = n->parentNode();
2303     } while (n && value.isNull());
2304
2305     return value;
2306 }
2307
2308 Locale& Element::locale() const
2309 {
2310     return document().getCachedLocale(computeInheritedLanguage());
2311 }
2312
2313 void Element::cancelFocusAppearanceUpdate()
2314 {
2315     if (hasRareData())
2316         elementRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
2317     if (document().focusedElement() == this)
2318         document().cancelFocusAppearanceUpdate();
2319 }
2320
2321 void Element::normalizeAttributes()
2322 {
2323     if (!hasAttributes())
2324         return;
2325     for (unsigned i = 0; i < attributeCount(); ++i) {
2326         if (RefPtr<Attr> attr = attrIfExists(attributeAt(i).name()))
2327             attr->normalize();
2328     }
2329 }
2330
2331 PseudoElement* Element::beforePseudoElement() const
2332 {
2333     return hasRareData() ? elementRareData()->beforePseudoElement() : 0;
2334 }
2335
2336 PseudoElement* Element::afterPseudoElement() const
2337 {
2338     return hasRareData() ? elementRareData()->afterPseudoElement() : 0;
2339 }
2340
2341 void Element::setBeforePseudoElement(PassRefPtr<PseudoElement> element)
2342 {
2343     ensureElementRareData().setBeforePseudoElement(element);
2344     resetNeedsNodeRenderingTraversalSlowPath();
2345 }
2346
2347 void Element::setAfterPseudoElement(PassRefPtr<PseudoElement> element)
2348 {
2349     ensureElementRareData().setAfterPseudoElement(element);
2350     resetNeedsNodeRenderingTraversalSlowPath();
2351 }
2352
2353 static void disconnectPseudoElement(PseudoElement* pseudoElement)
2354 {
2355     if (!pseudoElement)
2356         return;
2357     if (pseudoElement->attached())
2358         Style::detachRenderTree(*pseudoElement);
2359     ASSERT(pseudoElement->hostElement());
2360     pseudoElement->clearHostElement();
2361 }
2362
2363 void Element::clearBeforePseudoElement()
2364 {
2365     if (!hasRareData())
2366         return;
2367     disconnectPseudoElement(elementRareData()->beforePseudoElement());
2368     elementRareData()->setBeforePseudoElement(nullptr);
2369     resetNeedsNodeRenderingTraversalSlowPath();
2370 }
2371
2372 void Element::clearAfterPseudoElement()
2373 {
2374     if (!hasRareData())
2375         return;
2376     disconnectPseudoElement(elementRareData()->afterPseudoElement());
2377     elementRareData()->setAfterPseudoElement(nullptr);
2378     resetNeedsNodeRenderingTraversalSlowPath();
2379 }
2380
2381 // ElementTraversal API
2382 Element* Element::firstElementChild() const
2383 {
2384     return ElementTraversal::firstChild(this);
2385 }
2386
2387 Element* Element::lastElementChild() const
2388 {
2389     return ElementTraversal::lastChild(this);
2390 }
2391
2392 Element* Element::previousElementSibling() const
2393 {
2394     return ElementTraversal::previousSibling(this);
2395 }
2396
2397 Element* Element::nextElementSibling() const
2398 {
2399     return ElementTraversal::nextSibling(this);
2400 }
2401
2402 unsigned Element::childElementCount() const
2403 {
2404     unsigned count = 0;
2405     Node* n = firstChild();
2406     while (n) {
2407         count += n->isElementNode();
2408         n = n->nextSibling();
2409     }
2410     return count;
2411 }
2412
2413 bool Element::matchesReadOnlyPseudoClass() const
2414 {
2415     return false;
2416 }
2417
2418 bool Element::matchesReadWritePseudoClass() const
2419 {
2420     return false;
2421 }
2422
2423 bool Element::webkitMatchesSelector(const String& selector, ExceptionCode& ec)
2424 {
2425     if (selector.isEmpty()) {
2426         ec = SYNTAX_ERR;
2427         return false;
2428     }
2429
2430     SelectorQuery* selectorQuery = document().selectorQueryCache().add(selector, document(), ec);
2431     return selectorQuery && selectorQuery->matches(*this);
2432 }
2433
2434 bool Element::shouldAppearIndeterminate() const
2435 {
2436     return false;
2437 }
2438
2439 DOMTokenList* Element::classList()
2440 {
2441     ElementRareData& data = ensureElementRareData();
2442     if (!data.classList())
2443         data.setClassList(std::make_unique<ClassList>(*this));
2444     return data.classList();
2445 }
2446
2447 DOMStringMap* Element::dataset()
2448 {
2449     ElementRareData& data = ensureElementRareData();
2450     if (!data.dataset())
2451         data.setDataset(std::make_unique<DatasetDOMStringMap>(*this));
2452     return data.dataset();
2453 }
2454
2455 URL Element::getURLAttribute(const QualifiedName& name) const
2456 {
2457 #if !ASSERT_DISABLED
2458     if (elementData()) {
2459         if (const Attribute* attribute = findAttributeByName(name))
2460             ASSERT(isURLAttribute(*attribute));
2461     }
2462 #endif
2463     return document().completeURL(stripLeadingAndTrailingHTMLSpaces(getAttribute(name)));
2464 }
2465
2466 URL Element::getNonEmptyURLAttribute(const QualifiedName& name) const
2467 {
2468 #if !ASSERT_DISABLED
2469     if (elementData()) {
2470         if (const Attribute* attribute = findAttributeByName(name))
2471             ASSERT(isURLAttribute(*attribute));
2472     }
2473 #endif
2474     String value = stripLeadingAndTrailingHTMLSpaces(getAttribute(name));
2475     if (value.isEmpty())
2476         return URL();
2477     return document().completeURL(value);
2478 }
2479
2480 int Element::getIntegralAttribute(const QualifiedName& attributeName) const
2481 {
2482     return getAttribute(attributeName).string().toInt();
2483 }
2484
2485 void Element::setIntegralAttribute(const QualifiedName& attributeName, int value)
2486 {
2487     setAttribute(attributeName, AtomicString::number(value));
2488 }
2489
2490 unsigned Element::getUnsignedIntegralAttribute(const QualifiedName& attributeName) const
2491 {
2492     return getAttribute(attributeName).string().toUInt();
2493 }
2494
2495 void Element::setUnsignedIntegralAttribute(const QualifiedName& attributeName, unsigned value)
2496 {
2497     setAttribute(attributeName, AtomicString::number(value));
2498 }
2499
2500 #if ENABLE(INDIE_UI)
2501 void Element::setUIActions(const AtomicString& actions)
2502 {
2503     setAttribute(uiactionsAttr, actions);
2504 }
2505
2506 const AtomicString& Element::UIActions() const
2507 {
2508     return getAttribute(uiactionsAttr);
2509 }
2510 #endif
2511
2512 bool Element::childShouldCreateRenderer(const Node& child) const
2513 {
2514 #if ENABLE(SVG)
2515     // Only create renderers for SVG elements whose parents are SVG elements, or for proper <svg xmlns="svgNS"> subdocuments.
2516     if (child.isSVGElement()) {
2517         ASSERT(!isSVGElement());
2518         return child.hasTagName(SVGNames::svgTag) && toSVGElement(child).isValid();
2519     }
2520 #endif
2521     return ContainerNode::childShouldCreateRenderer(child);
2522 }
2523
2524 #if ENABLE(FULLSCREEN_API)
2525 void Element::webkitRequestFullscreen()
2526 {
2527     document().requestFullScreenForElement(this, ALLOW_KEYBOARD_INPUT, Document::EnforceIFrameAllowFullScreenRequirement);
2528 }
2529
2530 void Element::webkitRequestFullScreen(unsigned short flags)
2531 {
2532     document().requestFullScreenForElement(this, (flags | LEGACY_MOZILLA_REQUEST), Document::EnforceIFrameAllowFullScreenRequirement);
2533 }
2534
2535 bool Element::containsFullScreenElement() const
2536 {
2537     return hasRareData() && elementRareData()->containsFullScreenElement();
2538 }
2539
2540 void Element::setContainsFullScreenElement(bool flag)
2541 {
2542     ensureElementRareData().setContainsFullScreenElement(flag);
2543     setNeedsStyleRecalc(SyntheticStyleChange);
2544 }
2545
2546 static Element* parentCrossingFrameBoundaries(Element* element)
2547 {
2548     ASSERT(element);
2549     return element->parentElement() ? element->parentElement() : element->document().ownerElement();
2550 }
2551
2552 void Element::setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(bool flag)
2553 {
2554     Element* element = this;
2555     while ((element = parentCrossingFrameBoundaries(element)))
2556         element->setContainsFullScreenElement(flag);
2557 }
2558 #endif
2559
2560 #if ENABLE(POINTER_LOCK)
2561 void Element::webkitRequestPointerLock()
2562 {
2563     if (document().page())
2564         document().page()->pointerLockController()->requestPointerLock(this);
2565 }
2566 #endif
2567
2568 SpellcheckAttributeState Element::spellcheckAttributeState() const
2569 {
2570     const AtomicString& value = getAttribute(HTMLNames::spellcheckAttr);
2571     if (value == nullAtom)
2572         return SpellcheckAttributeDefault;
2573     if (equalIgnoringCase(value, "true") || equalIgnoringCase(value, ""))
2574         return SpellcheckAttributeTrue;
2575     if (equalIgnoringCase(value, "false"))
2576         return SpellcheckAttributeFalse;
2577
2578     return SpellcheckAttributeDefault;
2579 }
2580
2581 bool Element::isSpellCheckingEnabled() const
2582 {
2583     for (const Element* element = this; element; element = element->parentOrShadowHostElement()) {
2584         switch (element->spellcheckAttributeState()) {
2585         case SpellcheckAttributeTrue:
2586             return true;
2587         case SpellcheckAttributeFalse:
2588             return false;
2589         case SpellcheckAttributeDefault:
2590             break;
2591         }
2592     }
2593
2594     return true;
2595 }
2596
2597 RenderRegion* Element::renderRegion() const
2598 {
2599     if (renderer() && renderer()->isRenderNamedFlowFragmentContainer())
2600         return toRenderBlockFlow(renderer())->renderNamedFlowFragment();
2601
2602     return 0;
2603 }
2604
2605 #if ENABLE(CSS_REGIONS)
2606
2607 bool Element::shouldMoveToFlowThread(const RenderStyle& styleToUse) const
2608 {
2609 #if ENABLE(FULLSCREEN_API)
2610     if (document().webkitIsFullScreen() && document().webkitCurrentFullScreenElement() == this)
2611         return false;
2612 #endif
2613
2614     if (isInShadowTree())
2615         return false;
2616
2617     if (styleToUse.flowThread().isEmpty())
2618         return false;
2619
2620     return !document().renderView()->flowThreadController().isContentElementRegisteredWithAnyNamedFlow(*this);
2621 }
2622
2623 const AtomicString& Element::webkitRegionOverset() const
2624 {
2625     document().updateLayoutIgnorePendingStylesheets();
2626
2627     DEFINE_STATIC_LOCAL(AtomicString, undefinedState, ("undefined", AtomicString::ConstructFromLiteral));
2628     if (!document().cssRegionsEnabled() || !renderRegion())
2629         return undefinedState;
2630
2631     switch (renderRegion()->regionOversetState()) {
2632     case RegionFit: {
2633         DEFINE_STATIC_LOCAL(AtomicString, fitState, ("fit", AtomicString::ConstructFromLiteral));
2634         return fitState;
2635     }
2636     case RegionEmpty: {
2637         DEFINE_STATIC_LOCAL(AtomicString, emptyState, ("empty", AtomicString::ConstructFromLiteral));
2638         return emptyState;
2639     }
2640     case RegionOverset: {
2641         DEFINE_STATIC_LOCAL(AtomicString, overflowState, ("overset", AtomicString::ConstructFromLiteral));
2642         return overflowState;
2643     }
2644     case RegionUndefined:
2645         return undefinedState;
2646     }
2647
2648     ASSERT_NOT_REACHED();
2649     return undefinedState;
2650 }
2651
2652 Vector<RefPtr<Range>> Element::webkitGetRegionFlowRanges() const
2653 {
2654     Vector<RefPtr<Range>> rangeObjects;
2655     if (!document().cssRegionsEnabled())
2656         return rangeObjects;
2657
2658     document().updateLayoutIgnorePendingStylesheets();
2659     if (renderer() && renderer()->isRenderNamedFlowFragmentContainer()) {
2660         RenderNamedFlowFragment* region = toRenderBlockFlow(renderer())->renderNamedFlowFragment();
2661         if (region->isValid())
2662             region->getRanges(rangeObjects);
2663     }
2664
2665     return rangeObjects;
2666 }
2667
2668 #endif
2669
2670 #ifndef NDEBUG
2671 bool Element::fastAttributeLookupAllowed(const QualifiedName& name) const
2672 {
2673     if (name == HTMLNames::styleAttr)
2674         return false;
2675
2676 #if ENABLE(SVG)
2677     if (isSVGElement())
2678         return !toSVGElement(this)->isAnimatableAttribute(name);
2679 #endif
2680
2681     return true;
2682 }
2683 #endif
2684
2685 #ifdef DUMP_NODE_STATISTICS
2686 bool Element::hasNamedNodeMap() const
2687 {
2688     return hasRareData() && elementRareData()->attributeMap();
2689 }
2690 #endif
2691
2692 inline void Element::updateName(const AtomicString& oldName, const AtomicString& newName)
2693 {
2694     if (!isInTreeScope())
2695         return;
2696
2697     if (oldName == newName)
2698         return;
2699
2700     updateNameForTreeScope(treeScope(), oldName, newName);
2701
2702     if (!inDocument())
2703         return;
2704     if (!document().isHTMLDocument())
2705         return;
2706     updateNameForDocument(toHTMLDocument(document()), oldName, newName);
2707 }
2708
2709 void Element::updateNameForTreeScope(TreeScope& scope, const AtomicString& oldName, const AtomicString& newName)
2710 {
2711     ASSERT(oldName != newName);
2712
2713     if (!oldName.isEmpty())
2714         scope.removeElementByName(*oldName.impl(), *this);
2715     if (!newName.isEmpty())
2716         scope.addElementByName(*newName.impl(), *this);
2717 }
2718
2719 void Element::updateNameForDocument(HTMLDocument& document, const AtomicString& oldName, const AtomicString& newName)
2720 {
2721     ASSERT(oldName != newName);
2722
2723     if (WindowNameCollection::nodeMatchesIfNameAttributeMatch(this)) {
2724         const AtomicString& id = WindowNameCollection::nodeMatchesIfIdAttributeMatch(this) ? getIdAttribute() : nullAtom;
2725         if (!oldName.isEmpty() && oldName != id)
2726             document.removeWindowNamedItem(*oldName.impl(), *this);
2727         if (!newName.isEmpty() && newName != id)
2728             document.addWindowNamedItem(*newName.impl(), *this);
2729     }
2730
2731     if (DocumentNameCollection::nodeMatchesIfNameAttributeMatch(this)) {
2732         const AtomicString& id = DocumentNameCollection::nodeMatchesIfIdAttributeMatch(this) ? getIdAttribute() : nullAtom;
2733         if (!oldName.isEmpty() && oldName != id)
2734             document.removeDocumentNamedItem(*oldName.impl(), *this);
2735         if (!newName.isEmpty() && newName != id)
2736             document.addDocumentNamedItem(*newName.impl(), *this);
2737     }
2738 }
2739
2740 inline void Element::updateId(const AtomicString& oldId, const AtomicString& newId)
2741 {
2742     if (!isInTreeScope())
2743         return;
2744
2745     if (oldId == newId)
2746         return;
2747
2748     updateIdForTreeScope(treeScope(), oldId, newId);
2749
2750     if (!inDocument())
2751         return;
2752     if (!document().isHTMLDocument())
2753         return;
2754     updateIdForDocument(toHTMLDocument(document()), oldId, newId, UpdateHTMLDocumentNamedItemMapsOnlyIfDiffersFromNameAttribute);
2755 }
2756
2757 void Element::updateIdForTreeScope(TreeScope& scope, const AtomicString& oldId, const AtomicString& newId)
2758 {
2759     ASSERT(isInTreeScope());
2760     ASSERT(oldId != newId);
2761
2762     if (!oldId.isEmpty())
2763         scope.removeElementById(*oldId.impl(), *this);
2764     if (!newId.isEmpty())
2765         scope.addElementById(*newId.impl(), *this);
2766 }
2767
2768 void Element::updateIdForDocument(HTMLDocument& document, const AtomicString& oldId, const AtomicString& newId, HTMLDocumentNamedItemMapsUpdatingCondition condition)
2769 {
2770     ASSERT(inDocument());
2771     ASSERT(oldId != newId);
2772
2773     if (WindowNameCollection::nodeMatchesIfIdAttributeMatch(this)) {
2774         const AtomicString& name = condition == UpdateHTMLDocumentNamedItemMapsOnlyIfDiffersFromNameAttribute && WindowNameCollection::nodeMatchesIfNameAttributeMatch(this) ? getNameAttribute() : nullAtom;
2775         if (!oldId.isEmpty() && oldId != name)
2776             document.removeWindowNamedItem(*oldId.impl(), *this);
2777         if (!newId.isEmpty() && newId != name)
2778             document.addWindowNamedItem(*newId.impl(), *this);
2779     }
2780
2781     if (DocumentNameCollection::nodeMatchesIfIdAttributeMatch(this)) {
2782         const AtomicString& name = condition == UpdateHTMLDocumentNamedItemMapsOnlyIfDiffersFromNameAttribute && DocumentNameCollection::nodeMatchesIfNameAttributeMatch(this) ? getNameAttribute() : nullAtom;
2783         if (!oldId.isEmpty() && oldId != name)
2784             document.removeDocumentNamedItem(*oldId.impl(), *this);
2785         if (!newId.isEmpty() && newId != name)
2786             document.addDocumentNamedItem(*newId.impl(), *this);
2787     }
2788 }
2789
2790 void Element::updateLabel(TreeScope& scope, const AtomicString& oldForAttributeValue, const AtomicString& newForAttributeValue)
2791 {
2792     ASSERT(hasTagName(labelTag));
2793
2794     if (!inDocument())
2795         return;
2796
2797     if (oldForAttributeValue == newForAttributeValue)
2798         return;
2799
2800     if (!oldForAttributeValue.isEmpty())
2801         scope.removeLabel(*oldForAttributeValue.impl(), *toHTMLLabelElement(this));
2802     if (!newForAttributeValue.isEmpty())
2803         scope.addLabel(*newForAttributeValue.impl(), *toHTMLLabelElement(this));
2804 }
2805
2806 void Element::willModifyAttribute(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue)
2807 {
2808     if (isIdAttributeName(name))
2809         updateId(oldValue, newValue);
2810     else if (name == HTMLNames::nameAttr)
2811         updateName(oldValue, newValue);
2812     else if (name == HTMLNames::forAttr && hasTagName(labelTag)) {
2813         if (treeScope().shouldCacheLabelsByForAttribute())
2814             updateLabel(treeScope(), oldValue, newValue);
2815     }
2816
2817     if (oldValue != newValue) {
2818         if (attached() && document().styleResolverIfExists() && document().styleResolverIfExists()->hasSelectorForAttribute(name.localName()))
2819             setNeedsStyleRecalc();
2820     }
2821
2822     if (OwnPtr<MutationObserverInterestGroup> recipients = MutationObserverInterestGroup::createForAttributesMutation(*this, name))
2823         recipients->enqueueMutationRecord(MutationRecord::createAttributes(*this, name, oldValue));
2824
2825 #if ENABLE(INSPECTOR)
2826     InspectorInstrumentation::willModifyDOMAttr(&document(), this, oldValue, newValue);
2827 #endif
2828 }
2829
2830 void Element::didAddAttribute(const QualifiedName& name, const AtomicString& value)
2831 {
2832     attributeChanged(name, value);
2833     InspectorInstrumentation::didModifyDOMAttr(&document(), this, name.localName(), value);
2834     dispatchSubtreeModifiedEvent();
2835 }
2836
2837 void Element::didModifyAttribute(const QualifiedName& name, const AtomicString& value)
2838 {
2839     attributeChanged(name, value);
2840     InspectorInstrumentation::didModifyDOMAttr(&document(), this, name.localName(), value);
2841     // Do not dispatch a DOMSubtreeModified event here; see bug 81141.
2842 }
2843
2844 void Element::didRemoveAttribute(const QualifiedName& name)
2845 {
2846     attributeChanged(name, nullAtom);
2847     InspectorInstrumentation::didRemoveDOMAttr(&document(), this, name.localName());
2848     dispatchSubtreeModifiedEvent();
2849 }
2850
2851 PassRefPtr<HTMLCollection> Element::ensureCachedHTMLCollection(CollectionType type)
2852 {
2853     if (HTMLCollection* collection = cachedHTMLCollection(type))
2854         return collection;
2855
2856     RefPtr<HTMLCollection> collection;
2857     if (type == TableRows) {
2858         return ensureRareData().ensureNodeLists().addCachedCollection<HTMLTableRowsCollection>(toHTMLTableElement(*this), type);
2859     } else if (type == SelectOptions) {
2860         return ensureRareData().ensureNodeLists().addCachedCollection<HTMLOptionsCollection>(toHTMLSelectElement(*this), type);
2861     } else if (type == FormControls) {
2862         ASSERT(hasTagName(formTag) || hasTagName(fieldsetTag));
2863         return ensureRareData().ensureNodeLists().addCachedCollection<HTMLFormControlsCollection>(*this, type);
2864     }
2865     return ensureRareData().ensureNodeLists().addCachedCollection<HTMLCollection>(*this, type);
2866 }
2867
2868 HTMLCollection* Element::cachedHTMLCollection(CollectionType type)
2869 {
2870     return hasRareData() && rareData()->nodeLists() ? rareData()->nodeLists()->cachedCollection<HTMLCollection>(type) : 0;
2871 }
2872
2873 IntSize Element::savedLayerScrollOffset() const
2874 {
2875     return hasRareData() ? elementRareData()->savedLayerScrollOffset() : IntSize();
2876 }
2877
2878 void Element::setSavedLayerScrollOffset(const IntSize& size)
2879 {
2880     if (size.isZero() && !hasRareData())
2881         return;
2882     ensureElementRareData().setSavedLayerScrollOffset(size);
2883 }
2884
2885 PassRefPtr<Attr> Element::attrIfExists(const QualifiedName& name)
2886 {
2887     if (AttrNodeList* attrNodeList = attrNodeListForElement(this))
2888         return findAttrNodeInList(*attrNodeList, name);
2889     return 0;
2890 }
2891
2892 PassRefPtr<Attr> Element::ensureAttr(const QualifiedName& name)
2893 {
2894     AttrNodeList& attrNodeList = ensureAttrNodeListForElement(this);
2895     RefPtr<Attr> attrNode = findAttrNodeInList(attrNodeList, name);
2896     if (!attrNode) {
2897         attrNode = Attr::create(this, name);
2898         treeScope().adoptIfNeeded(attrNode.get());
2899         attrNodeList.append(attrNode);
2900     }
2901     return attrNode.release();
2902 }
2903
2904 void Element::detachAttrNodeFromElementWithValue(Attr* attrNode, const AtomicString& value)
2905 {
2906     ASSERT(hasSyntheticAttrChildNodes());
2907     attrNode->detachFromElementWithValue(value);
2908
2909     AttrNodeList* attrNodeList = attrNodeListForElement(this);
2910     for (unsigned i = 0; i < attrNodeList->size(); ++i) {
2911         if (attrNodeList->at(i)->qualifiedName() == attrNode->qualifiedName()) {
2912             attrNodeList->remove(i);
2913             if (attrNodeList->isEmpty())
2914                 removeAttrNodeListForElement(this);
2915             return;
2916         }
2917     }
2918     ASSERT_NOT_REACHED();
2919 }
2920
2921 void Element::detachAllAttrNodesFromElement()
2922 {
2923     AttrNodeList* attrNodeList = attrNodeListForElement(this);
2924     ASSERT(attrNodeList);
2925
2926     for (unsigned i = 0; i < attributeCount(); ++i) {
2927         const Attribute& attribute = attributeAt(i);
2928         if (RefPtr<Attr> attrNode = findAttrNodeInList(*attrNodeList, attribute.name()))
2929             attrNode->detachFromElementWithValue(attribute.value());
2930     }
2931
2932     removeAttrNodeListForElement(this);
2933 }
2934
2935 void Element::resetComputedStyle()
2936 {
2937     if (!hasRareData() || !elementRareData()->computedStyle())
2938         return;
2939     elementRareData()->resetComputedStyle();
2940     for (auto& child : elementDescendants(*this)) {
2941         if (child.hasRareData())
2942             child.elementRareData()->resetComputedStyle();
2943     }
2944 }
2945
2946 void Element::clearStyleDerivedDataBeforeDetachingRenderer()
2947 {
2948     unregisterNamedFlowContentElement();
2949     cancelFocusAppearanceUpdate();
2950     clearBeforePseudoElement();
2951     clearAfterPseudoElement();
2952     if (!hasRareData())
2953         return;
2954     ElementRareData* data = elementRareData();
2955     data->setIsInCanvasSubtree(false);
2956     data->resetComputedStyle();
2957     data->resetDynamicRestyleObservations();
2958     data->setIsInsideRegion(false);
2959 }
2960
2961 void Element::clearHoverAndActiveStatusBeforeDetachingRenderer()
2962 {
2963     if (!isUserActionElement())
2964         return;
2965     if (hovered())
2966         document().hoveredElementDidDetach(this);
2967     if (inActiveChain())
2968         document().elementInActiveChainDidDetach(this);
2969     document().userActionElements().didDetach(this);
2970 }
2971
2972 bool Element::willRecalcStyle(Style::Change)
2973 {
2974     ASSERT(hasCustomStyleResolveCallbacks());
2975     return true;
2976 }
2977
2978 void Element::didRecalcStyle(Style::Change)
2979 {
2980     ASSERT(hasCustomStyleResolveCallbacks());
2981 }
2982
2983 void Element::willAttachRenderers()
2984 {
2985     ASSERT(hasCustomStyleResolveCallbacks());
2986 }
2987
2988 void Element::didAttachRenderers()
2989 {
2990     ASSERT(hasCustomStyleResolveCallbacks());
2991 }
2992
2993 void Element::willDetachRenderers()
2994 {
2995     ASSERT(hasCustomStyleResolveCallbacks());
2996 }
2997
2998 void Element::didDetachRenderers()
2999 {
3000     ASSERT(hasCustomStyleResolveCallbacks());
3001 }
3002
3003 PassRefPtr<RenderStyle> Element::customStyleForRenderer()
3004 {
3005     ASSERT(hasCustomStyleResolveCallbacks());
3006     return 0;
3007 }
3008
3009 void Element::cloneAttributesFromElement(const Element& other)
3010 {
3011     if (hasSyntheticAttrChildNodes())
3012         detachAllAttrNodesFromElement();
3013
3014     other.synchronizeAllAttributes();
3015     if (!other.m_elementData) {
3016         m_elementData.clear();
3017         return;
3018     }
3019
3020     // We can't update window and document's named item maps since the presence of image and object elements depend on other attributes and children.
3021     // Fortunately, those named item maps are only updated when this element is in the document, which should never be the case.
3022     ASSERT(!inDocument());
3023
3024     const AtomicString& oldID = getIdAttribute();
3025     const AtomicString& newID = other.getIdAttribute();
3026
3027     if (!oldID.isNull() || !newID.isNull())
3028         updateId(oldID, newID);
3029
3030     const AtomicString& oldName = getNameAttribute();
3031     const AtomicString& newName = other.getNameAttribute();
3032
3033     if (!oldName.isNull() || !newName.isNull())
3034         updateName(oldName, newName);
3035
3036     // If 'other' has a mutable ElementData, convert it to an immutable one so we can share it between both elements.
3037     // We can only do this if there is no CSSOM wrapper for other's inline style, and there are no presentation attributes.
3038     if (other.m_elementData->isUnique()
3039         && !other.m_elementData->presentationAttributeStyle()
3040         && (!other.m_elementData->inlineStyle() || !other.m_elementData->inlineStyle()->hasCSSOMWrapper()))
3041         const_cast<Element&>(other).m_elementData = static_cast<const UniqueElementData*>(other.m_elementData.get())->makeShareableCopy();
3042
3043     if (!other.m_elementData->isUnique())
3044         m_elementData = other.m_elementData;
3045     else
3046         m_elementData = other.m_elementData->makeUniqueCopy();
3047
3048     unsigned length = m_elementData->length();
3049     for (unsigned i = 0; i < length; ++i) {
3050         const Attribute& attribute = const_cast<const ElementData*>(m_elementData.get())->attributeAt(i);
3051         attributeChanged(attribute.name(), attribute.value(), ModifiedByCloning);
3052     }
3053 }
3054
3055 void Element::cloneDataFromElement(const Element& other)
3056 {
3057     cloneAttributesFromElement(other);
3058     copyNonAttributePropertiesFromElement(other);
3059 }
3060
3061 void Element::createUniqueElementData()
3062 {
3063     if (!m_elementData)
3064         m_elementData = UniqueElementData::create();
3065     else {
3066         ASSERT(!m_elementData->isUnique());
3067         m_elementData = static_cast<ShareableElementData*>(m_elementData.get())->makeUniqueCopy();
3068     }
3069 }
3070
3071 #if ENABLE(SVG)
3072 bool Element::hasPendingResources() const
3073 {
3074     return hasRareData() && elementRareData()->hasPendingResources();
3075 }
3076
3077 void Element::setHasPendingResources()
3078 {
3079     ensureElementRareData().setHasPendingResources(true);
3080 }
3081
3082 void Element::clearHasPendingResources()
3083 {
3084     ensureElementRareData().setHasPendingResources(false);
3085 }
3086 #endif
3087
3088 } // namespace WebCore