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