NodeLists should not invalidate on irreleavnt attribute changes
[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 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 "ClassList.h"
34 #include "ClientRect.h"
35 #include "ClientRectList.h"
36 #include "DOMTokenList.h"
37 #include "DatasetDOMStringMap.h"
38 #include "Document.h"
39 #include "DocumentFragment.h"
40 #include "ElementRareData.h"
41 #include "ExceptionCode.h"
42 #include "FlowThreadController.h"
43 #include "FocusController.h"
44 #include "Frame.h"
45 #include "FrameView.h"
46 #include "HTMLCollection.h"
47 #include "HTMLDocument.h"
48 #include "HTMLElement.h"
49 #include "HTMLFormCollection.h"
50 #include "HTMLFrameOwnerElement.h"
51 #include "HTMLNames.h"
52 #include "HTMLOptionsCollection.h"
53 #include "HTMLParserIdioms.h"
54 #include "HTMLTableRowsCollection.h"
55 #include "InspectorInstrumentation.h"
56 #include "MutationObserverInterestGroup.h"
57 #include "MutationRecord.h"
58 #include "NamedNodeMap.h"
59 #include "NodeList.h"
60 #include "NodeRenderStyle.h"
61 #include "NodeRenderingContext.h"
62 #include "Page.h"
63 #include "PointerLockController.h"
64 #include "RenderRegion.h"
65 #include "RenderView.h"
66 #include "RenderWidget.h"
67 #include "SelectorQuery.h"
68 #include "Settings.h"
69 #include "ShadowRoot.h"
70 #include "StyleResolver.h"
71 #include "Text.h"
72 #include "TextIterator.h"
73 #include "VoidCallback.h"
74 #include "WebKitAnimationList.h"
75 #include "XMLNSNames.h"
76 #include "XMLNames.h"
77 #include "htmlediting.h"
78 #include <wtf/text/CString.h>
79
80 #if ENABLE(SVG)
81 #include "SVGElement.h"
82 #include "SVGNames.h"
83 #endif
84
85 namespace WebCore {
86
87 using namespace HTMLNames;
88 using namespace XMLNames;
89     
90 class StyleResolverParentPusher {
91 public:
92     StyleResolverParentPusher(Element* parent)
93         : m_parent(parent)
94         , m_pushedStyleResolver(0)
95     {
96     }
97     void push()
98     {
99         if (m_pushedStyleResolver)
100             return;
101         m_pushedStyleResolver = m_parent->document()->styleResolver();
102         m_pushedStyleResolver->pushParentElement(m_parent);
103     }
104     ~StyleResolverParentPusher()
105     {
106
107         if (!m_pushedStyleResolver)
108             return;
109
110         // This tells us that our pushed style selector is in a bad state,
111         // so we should just bail out in that scenario.
112         ASSERT(m_pushedStyleResolver == m_parent->document()->styleResolver());
113         if (m_pushedStyleResolver != m_parent->document()->styleResolver())
114             return;
115
116         m_pushedStyleResolver->popParentElement(m_parent);
117     }
118
119 private:
120     Element* m_parent;
121     StyleResolver* m_pushedStyleResolver;
122 };
123
124 PassRefPtr<Element> Element::create(const QualifiedName& tagName, Document* document)
125 {
126     return adoptRef(new Element(tagName, document, CreateElement));
127 }
128
129 Element::~Element()
130 {
131 #ifndef NDEBUG
132     if (document() && document()->renderer()) {
133         // When the document is not destroyed, an element that was part of a named flow
134         // content nodes should have been removed from the content nodes collection
135         // and the inNamedFlow flag reset.
136         ASSERT(!inNamedFlow());
137     }
138 #endif
139
140     if (ElementShadow* elementShadow = shadow()) {
141         elementShadow->removeAllShadowRoots();
142         elementRareData()->m_shadow.clear();
143     }
144
145     if (hasAttrList()) {
146         ASSERT(m_attributeData);
147         m_attributeData->detachAttrObjectsFromElement(this);
148     }
149 }
150
151 inline ElementRareData* Element::elementRareData() const
152 {
153     ASSERT(hasRareData());
154     return static_cast<ElementRareData*>(NodeRareData::rareDataFromMap(this));
155 }
156     
157 inline ElementRareData* Element::ensureElementRareData()
158 {
159     return static_cast<ElementRareData*>(ensureRareData());
160 }
161     
162 OwnPtr<NodeRareData> Element::createRareData()
163 {
164     return adoptPtr(new ElementRareData);
165 }
166
167 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, blur);
168 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, error);
169 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, focus);
170 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, load);
171
172 PassRefPtr<Node> Element::cloneNode(bool deep)
173 {
174     return deep ? cloneElementWithChildren() : cloneElementWithoutChildren();
175 }
176
177 PassRefPtr<Element> Element::cloneElementWithChildren()
178 {
179     RefPtr<Element> clone = cloneElementWithoutChildren();
180     cloneChildNodes(clone.get());
181     return clone.release();
182 }
183
184 PassRefPtr<Element> Element::cloneElementWithoutChildren()
185 {
186     RefPtr<Element> clone = cloneElementWithoutAttributesAndChildren();
187     // This will catch HTML elements in the wrong namespace that are not correctly copied.
188     // This is a sanity check as HTML overloads some of the DOM methods.
189     ASSERT(isHTMLElement() == clone->isHTMLElement());
190
191     clone->cloneDataFromElement(*this);
192     return clone.release();
193 }
194
195 PassRefPtr<Element> Element::cloneElementWithoutAttributesAndChildren()
196 {
197     return document()->createElement(tagQName(), false);
198 }
199
200 PassRefPtr<Attr> Element::detachAttribute(size_t index)
201 {
202     ASSERT(attributeData());
203
204     Attribute* attribute = attributeData()->attributeItem(index);
205     ASSERT(attribute);
206
207     RefPtr<Attr> attr = attrIfExists(attribute->name());
208     if (attr)
209         attr->detachFromElementWithValue(attribute->value());
210     else
211         attr = Attr::create(document(), attribute->name(), attribute->value());
212
213     attributeData()->removeAttribute(index, this);
214     return attr.release();
215 }
216
217 void Element::removeAttribute(const QualifiedName& name)
218 {
219     if (!attributeData())
220         return;
221
222     if (RefPtr<Attr> attr = attrIfExists(name))
223         attr->detachFromElementWithValue(attr->value());
224
225     attributeData()->removeAttribute(name, this);
226 }
227
228 void Element::setBooleanAttribute(const QualifiedName& name, bool value)
229 {
230     if (value)
231         setAttribute(name, emptyAtom);
232     else
233         removeAttribute(name);
234 }
235
236 NamedNodeMap* Element::attributes() const
237 {
238     ensureUpdatedAttributeData();
239     ElementRareData* rareData = const_cast<Element*>(this)->ensureElementRareData();
240     if (NamedNodeMap* attributeMap = rareData->m_attributeMap.get())
241         return attributeMap;
242
243     rareData->m_attributeMap = NamedNodeMap::create(const_cast<Element*>(this));
244     return rareData->m_attributeMap.get();
245 }
246
247 Node::NodeType Element::nodeType() const
248 {
249     return ELEMENT_NODE;
250 }
251
252 bool Element::hasAttribute(const QualifiedName& name) const
253 {
254     return hasAttributeNS(name.namespaceURI(), name.localName());
255 }
256
257 const AtomicString& Element::getAttribute(const QualifiedName& name) const
258 {
259     if (UNLIKELY(name == styleAttr) && !isStyleAttributeValid())
260         updateStyleAttribute();
261
262 #if ENABLE(SVG)
263     if (UNLIKELY(!areSVGAttributesValid()))
264         updateAnimatedSVGAttribute(name);
265 #endif
266
267     if (m_attributeData) {
268         if (Attribute* attribute = getAttributeItem(name))
269             return attribute->value();
270     }
271     return nullAtom;
272 }
273
274 void Element::scrollIntoView(bool alignToTop) 
275 {
276     document()->updateLayoutIgnorePendingStylesheets();
277
278     if (!renderer())
279         return;
280
281     LayoutRect bounds = getRect();
282     // Align to the top / bottom and to the closest edge.
283     if (alignToTop)
284         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
285     else
286         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignBottomAlways);
287 }
288
289 void Element::scrollIntoViewIfNeeded(bool centerIfNeeded)
290 {
291     document()->updateLayoutIgnorePendingStylesheets();
292
293     if (!renderer())
294         return;
295
296     LayoutRect bounds = getRect();
297     if (centerIfNeeded)
298         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignCenterIfNeeded, ScrollAlignment::alignCenterIfNeeded);
299     else
300         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
301 }
302
303 void Element::scrollByUnits(int units, ScrollGranularity granularity)
304 {
305     document()->updateLayoutIgnorePendingStylesheets();
306
307     if (!renderer())
308         return;
309
310     if (!renderer()->hasOverflowClip())
311         return;
312
313     ScrollDirection direction = ScrollDown;
314     if (units < 0) {
315         direction = ScrollUp;
316         units = -units;
317     }
318     Node* stopNode = this;
319     toRenderBox(renderer())->scroll(direction, granularity, units, &stopNode);
320 }
321
322 void Element::scrollByLines(int lines)
323 {
324     scrollByUnits(lines, ScrollByLine);
325 }
326
327 void Element::scrollByPages(int pages)
328 {
329     scrollByUnits(pages, ScrollByPage);
330 }
331
332 static float localZoomForRenderer(RenderObject* renderer)
333 {
334     // FIXME: This does the wrong thing if two opposing zooms are in effect and canceled each
335     // other out, but the alternative is that we'd have to crawl up the whole render tree every
336     // time (or store an additional bit in the RenderStyle to indicate that a zoom was specified).
337     float zoomFactor = 1;
338     if (renderer->style()->effectiveZoom() != 1) {
339         // Need to find the nearest enclosing RenderObject that set up
340         // a differing zoom, and then we divide our result by it to eliminate the zoom.
341         RenderObject* prev = renderer;
342         for (RenderObject* curr = prev->parent(); curr; curr = curr->parent()) {
343             if (curr->style()->effectiveZoom() != prev->style()->effectiveZoom()) {
344                 zoomFactor = prev->style()->zoom();
345                 break;
346             }
347             prev = curr;
348         }
349         if (prev->isRenderView())
350             zoomFactor = prev->style()->zoom();
351     }
352     return zoomFactor;
353 }
354
355 static int adjustForLocalZoom(LayoutUnit value, RenderObject* renderer)
356 {
357     float zoomFactor = localZoomForRenderer(renderer);
358     if (zoomFactor == 1)
359         return value;
360 #if ENABLE(SUBPIXEL_LAYOUT)
361     return lroundf(value / zoomFactor);
362 #else
363     // Needed because computeLengthInt truncates (rather than rounds) when scaling up.
364     if (zoomFactor > 1)
365         value++;
366     return static_cast<int>(value / zoomFactor);
367 #endif
368 }
369
370 int Element::offsetLeft()
371 {
372     document()->updateLayoutIgnorePendingStylesheets();
373     if (RenderBoxModelObject* renderer = renderBoxModelObject())
374         return adjustForLocalZoom(renderer->pixelSnappedOffsetLeft(), renderer);
375     return 0;
376 }
377
378 int Element::offsetTop()
379 {
380     document()->updateLayoutIgnorePendingStylesheets();
381     if (RenderBoxModelObject* renderer = renderBoxModelObject())
382         return adjustForLocalZoom(renderer->pixelSnappedOffsetTop(), renderer);
383     return 0;
384 }
385
386 int Element::offsetWidth()
387 {
388     document()->updateLayoutIgnorePendingStylesheets();
389     if (RenderBoxModelObject* renderer = renderBoxModelObject())
390         return adjustForAbsoluteZoom(renderer->pixelSnappedOffsetWidth(), renderer);
391     return 0;
392 }
393
394 int Element::offsetHeight()
395 {
396     document()->updateLayoutIgnorePendingStylesheets();
397     if (RenderBoxModelObject* renderer = renderBoxModelObject())
398         return adjustForAbsoluteZoom(renderer->pixelSnappedOffsetHeight(), renderer);
399     return 0;
400 }
401
402 Element* Element::offsetParent()
403 {
404     document()->updateLayoutIgnorePendingStylesheets();
405     if (RenderObject* rend = renderer())
406         if (RenderObject* offsetParent = rend->offsetParent())
407             return static_cast<Element*>(offsetParent->node());
408     return 0;
409 }
410
411 int Element::clientLeft()
412 {
413     document()->updateLayoutIgnorePendingStylesheets();
414
415     if (RenderBox* renderer = renderBox())
416         return adjustForAbsoluteZoom(roundToInt(renderer->clientLeft()), renderer);
417     return 0;
418 }
419
420 int Element::clientTop()
421 {
422     document()->updateLayoutIgnorePendingStylesheets();
423
424     if (RenderBox* renderer = renderBox())
425         return adjustForAbsoluteZoom(roundToInt(renderer->clientTop()), renderer);
426     return 0;
427 }
428
429 int Element::clientWidth()
430 {
431     document()->updateLayoutIgnorePendingStylesheets();
432
433     // When in strict mode, clientWidth for the document element should return the width of the containing frame.
434     // When in quirks mode, clientWidth for the body element should return the width of the containing frame.
435     bool inQuirksMode = document()->inQuirksMode();
436     if ((!inQuirksMode && document()->documentElement() == this) ||
437         (inQuirksMode && isHTMLElement() && document()->body() == this)) {
438         if (FrameView* view = document()->view()) {
439             if (RenderView* renderView = document()->renderView())
440                 return adjustForAbsoluteZoom(view->layoutWidth(), renderView);
441         }
442     }
443     
444     if (RenderBox* renderer = renderBox())
445         return adjustForAbsoluteZoom(renderer->pixelSnappedClientWidth(), renderer);
446     return 0;
447 }
448
449 int Element::clientHeight()
450 {
451     document()->updateLayoutIgnorePendingStylesheets();
452
453     // When in strict mode, clientHeight for the document element should return the height of the containing frame.
454     // When in quirks mode, clientHeight for the body element should return the height of the containing frame.
455     bool inQuirksMode = document()->inQuirksMode();     
456
457     if ((!inQuirksMode && document()->documentElement() == this) ||
458         (inQuirksMode && isHTMLElement() && document()->body() == this)) {
459         if (FrameView* view = document()->view()) {
460             if (RenderView* renderView = document()->renderView())
461                 return adjustForAbsoluteZoom(view->layoutHeight(), renderView);
462         }
463     }
464     
465     if (RenderBox* renderer = renderBox())
466         return adjustForAbsoluteZoom(renderer->pixelSnappedClientHeight(), renderer);
467     return 0;
468 }
469
470 int Element::scrollLeft()
471 {
472     document()->updateLayoutIgnorePendingStylesheets();
473     if (RenderBox* rend = renderBox())
474         return adjustForAbsoluteZoom(rend->scrollLeft(), rend);
475     return 0;
476 }
477
478 int Element::scrollTop()
479 {
480     document()->updateLayoutIgnorePendingStylesheets();
481     if (RenderBox* rend = renderBox())
482         return adjustForAbsoluteZoom(rend->scrollTop(), rend);
483     return 0;
484 }
485
486 void Element::setScrollLeft(int newLeft)
487 {
488     document()->updateLayoutIgnorePendingStylesheets();
489     if (RenderBox* rend = renderBox())
490         rend->setScrollLeft(static_cast<int>(newLeft * rend->style()->effectiveZoom()));
491 }
492
493 void Element::setScrollTop(int newTop)
494 {
495     document()->updateLayoutIgnorePendingStylesheets();
496     if (RenderBox* rend = renderBox())
497         rend->setScrollTop(static_cast<int>(newTop * rend->style()->effectiveZoom()));
498 }
499
500 int Element::scrollWidth()
501 {
502     document()->updateLayoutIgnorePendingStylesheets();
503     if (RenderBox* rend = renderBox())
504         return adjustForAbsoluteZoom(rend->scrollWidth(), rend);
505     return 0;
506 }
507
508 int Element::scrollHeight()
509 {
510     document()->updateLayoutIgnorePendingStylesheets();
511     if (RenderBox* rend = renderBox())
512         return adjustForAbsoluteZoom(rend->scrollHeight(), rend);
513     return 0;
514 }
515
516 IntRect Element::boundsInRootViewSpace()
517 {
518     document()->updateLayoutIgnorePendingStylesheets();
519
520     FrameView* view = document()->view();
521     if (!view)
522         return IntRect();
523
524     Vector<FloatQuad> quads;
525 #if ENABLE(SVG)
526     if (isSVGElement() && renderer()) {
527         // Get the bounding rectangle from the SVG model.
528         SVGElement* svgElement = static_cast<SVGElement*>(this);
529         FloatRect localRect;
530         if (svgElement->boundingBox(localRect))
531             quads.append(renderer()->localToAbsoluteQuad(localRect));
532     } else
533 #endif
534     {
535         // Get the bounding rectangle from the box model.
536         if (renderBoxModelObject())
537             renderBoxModelObject()->absoluteQuads(quads);
538     }
539
540     if (quads.isEmpty())
541         return IntRect();
542
543     IntRect result = quads[0].enclosingBoundingBox();
544     for (size_t i = 1; i < quads.size(); ++i)
545         result.unite(quads[i].enclosingBoundingBox());
546
547     result = view->contentsToRootView(result);
548     return result;
549 }
550
551 PassRefPtr<ClientRectList> Element::getClientRects()
552 {
553     document()->updateLayoutIgnorePendingStylesheets();
554
555     RenderBoxModelObject* renderBoxModelObject = this->renderBoxModelObject();
556     if (!renderBoxModelObject)
557         return ClientRectList::create();
558
559     // FIXME: Handle SVG elements.
560     // FIXME: Handle table/inline-table with a caption.
561
562     Vector<FloatQuad> quads;
563     renderBoxModelObject->absoluteQuads(quads);
564     document()->adjustFloatQuadsForScrollAndAbsoluteZoomAndFrameScale(quads, renderBoxModelObject);
565     return ClientRectList::create(quads);
566 }
567
568 PassRefPtr<ClientRect> Element::getBoundingClientRect()
569 {
570     document()->updateLayoutIgnorePendingStylesheets();
571
572     Vector<FloatQuad> quads;
573 #if ENABLE(SVG)
574     if (isSVGElement() && renderer() && !renderer()->isSVGRoot()) {
575         // Get the bounding rectangle from the SVG model.
576         SVGElement* svgElement = static_cast<SVGElement*>(this);
577         FloatRect localRect;
578         if (svgElement->boundingBox(localRect))
579             quads.append(renderer()->localToAbsoluteQuad(localRect));
580     } else
581 #endif
582     {
583         // Get the bounding rectangle from the box model.
584         if (renderBoxModelObject())
585             renderBoxModelObject()->absoluteQuads(quads);
586     }
587
588     if (quads.isEmpty())
589         return ClientRect::create();
590
591     FloatRect result = quads[0].boundingBox();
592     for (size_t i = 1; i < quads.size(); ++i)
593         result.unite(quads[i].boundingBox());
594
595     document()->adjustFloatRectForScrollAndAbsoluteZoomAndFrameScale(result, renderer());
596     return ClientRect::create(result);
597 }
598     
599 IntRect Element::screenRect() const
600 {
601     if (!renderer())
602         return IntRect();
603     // FIXME: this should probably respect transforms
604     return renderer()->view()->frameView()->contentsToScreen(renderer()->absoluteBoundingBoxRectIgnoringTransforms());
605 }
606
607 static inline bool shouldIgnoreAttributeCase(const Element* e)
608 {
609     return e && e->document()->isHTMLDocument() && e->isHTMLElement();
610 }
611
612 const AtomicString& Element::getAttribute(const AtomicString& name) const
613 {
614     bool ignoreCase = shouldIgnoreAttributeCase(this);
615
616     // Update the 'style' attribute if it's invalid and being requested:
617     if (!isStyleAttributeValid() && equalPossiblyIgnoringCase(name, styleAttr.localName(), ignoreCase))
618         updateStyleAttribute();
619
620 #if ENABLE(SVG)
621     if (!areSVGAttributesValid()) {
622         // We're not passing a namespace argument on purpose. SVGNames::*Attr are defined w/o namespaces as well.
623         updateAnimatedSVGAttribute(QualifiedName(nullAtom, name, nullAtom));
624     }
625 #endif
626
627     if (m_attributeData) {
628         if (Attribute* attribute = m_attributeData->getAttributeItem(name, ignoreCase))
629             return attribute->value();
630     }
631
632     return nullAtom;
633 }
634
635 const AtomicString& Element::getAttributeNS(const String& namespaceURI, const String& localName) const
636 {
637     return getAttribute(QualifiedName(nullAtom, localName, namespaceURI));
638 }
639
640 void Element::setAttribute(const AtomicString& name, const AtomicString& value, ExceptionCode& ec)
641 {
642     if (!Document::isValidName(name)) {
643         ec = INVALID_CHARACTER_ERR;
644         return;
645     }
646
647     const AtomicString& localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
648
649     size_t index = ensureUpdatedAttributeData()->getAttributeItemIndex(localName, false);
650     const QualifiedName& qName = index != notFound ? attributeItem(index)->name() : QualifiedName(nullAtom, localName, nullAtom);
651     setAttributeInternal(index, qName, value, NotInUpdateStyleAttribute);
652 }
653
654 void Element::setAttribute(const QualifiedName& name, const AtomicString& value, EInUpdateStyleAttribute inUpdateStyleAttribute)
655 {
656     setAttributeInternal(ensureUpdatedAttributeData()->getAttributeItemIndex(name), name, value, inUpdateStyleAttribute);
657 }
658
659 inline void Element::setAttributeInternal(size_t index, const QualifiedName& name, const AtomicString& value, EInUpdateStyleAttribute inUpdateStyleAttribute)
660 {
661     Attribute* old = index != notFound ? m_attributeData->attributeItem(index) : 0;
662     if (value.isNull()) {
663         if (old)
664             m_attributeData->removeAttribute(index, this, inUpdateStyleAttribute);
665         return;
666     }
667
668     if (!old) {
669         m_attributeData->addAttribute(Attribute(name, value), this, inUpdateStyleAttribute);
670         return;
671     }
672
673     if (inUpdateStyleAttribute == NotInUpdateStyleAttribute)
674         willModifyAttribute(name, old->value(), value);
675
676     if (RefPtr<Attr> attrNode = attrIfExists(name))
677         attrNode->setValue(value);
678     else
679         old->setValue(value);
680
681     if (inUpdateStyleAttribute == NotInUpdateStyleAttribute)
682         didModifyAttribute(Attribute(old->name(), old->value()));
683 }
684
685 void Element::attributeChanged(const Attribute& attribute)
686 {
687     document()->incDOMTreeVersion();
688
689     if (isIdAttributeName(attribute.name())) {
690         if (attribute.value() != attributeData()->idForStyleResolution()) {
691             if (attribute.isNull())
692                 attributeData()->setIdForStyleResolution(nullAtom);
693             else if (document()->inQuirksMode())
694                 attributeData()->setIdForStyleResolution(attribute.value().lower());
695             else
696                 attributeData()->setIdForStyleResolution(attribute.value());
697             setNeedsStyleRecalc();
698         }
699     } else if (attribute.name() == HTMLNames::nameAttr)
700         setHasName(!attribute.isNull());
701
702     if (!needsStyleRecalc() && document()->attached()) {
703         StyleResolver* styleResolver = document()->styleResolverIfExists();
704         if (!styleResolver || styleResolver->hasSelectorForAttribute(attribute.name().localName()))
705             setNeedsStyleRecalc();
706     }
707
708     invalidateNodeListCachesInAncestors(&attribute.name(), this);
709
710     if (!AXObjectCache::accessibilityEnabled())
711         return;
712
713     const QualifiedName& attrName = attribute.name();
714     if (attrName == aria_activedescendantAttr) {
715         // any change to aria-activedescendant attribute triggers accessibility focus change, but document focus remains intact
716         document()->axObjectCache()->handleActiveDescendantChanged(renderer());
717     } else if (attrName == roleAttr) {
718         // the role attribute can change at any time, and the AccessibilityObject must pick up these changes
719         document()->axObjectCache()->handleAriaRoleChanged(renderer());
720     } else if (attrName == aria_valuenowAttr) {
721         // If the valuenow attribute changes, AX clients need to be notified.
722         document()->axObjectCache()->postNotification(renderer(), AXObjectCache::AXValueChanged, true);
723     } else if (attrName == aria_labelAttr || attrName == aria_labeledbyAttr || attrName == altAttr || attrName == titleAttr) {
724         // If the content of an element changes due to an attribute change, notify accessibility.
725         document()->axObjectCache()->contentChanged(renderer());
726     } else if (attrName == aria_checkedAttr)
727         document()->axObjectCache()->checkedStateChanged(renderer());
728     else if (attrName == aria_selectedAttr)
729         document()->axObjectCache()->selectedChildrenChanged(renderer());
730     else if (attrName == aria_expandedAttr)
731         document()->axObjectCache()->handleAriaExpandedChange(renderer());
732     else if (attrName == aria_hiddenAttr)
733         document()->axObjectCache()->childrenChanged(renderer());
734     else if (attrName == aria_invalidAttr)
735         document()->axObjectCache()->postNotification(renderer(), AXObjectCache::AXInvalidStatusChanged, true);
736 }
737
738 // Returns true is the given attribute is an event handler.
739 // We consider an event handler any attribute that begins with "on".
740 // It is a simple solution that has the advantage of not requiring any
741 // code or configuration change if a new event handler is defined.
742
743 static bool isEventHandlerAttribute(const QualifiedName& name)
744 {
745     return name.namespaceURI().isNull() && name.localName().startsWith("on");
746 }
747
748 static bool isAttributeToRemove(const QualifiedName& name, const AtomicString& value)
749 {    
750     return (name.localName().endsWith(hrefAttr.localName()) || name == srcAttr || name == actionAttr) && protocolIsJavaScript(stripLeadingAndTrailingHTMLSpaces(value));       
751 }
752
753 void Element::parserSetAttributes(const Vector<Attribute>& attributeVector, FragmentScriptingPermission scriptingPermission)
754 {
755     ASSERT(!inDocument());
756     ASSERT(!parentNode());
757
758     ASSERT(!m_attributeData);
759
760     if (attributeVector.isEmpty())
761         return;
762
763     createAttributeData();
764     m_attributeData->m_attributes = attributeVector;
765     m_attributeData->m_attributes.shrinkToFit();
766
767     // If the element is created as result of a paste or drag-n-drop operation
768     // we want to remove all the script and event handlers.
769     if (scriptingPermission == DisallowScriptingContent) {
770         unsigned i = 0;
771         while (i < m_attributeData->length()) {
772             const QualifiedName& attributeName = m_attributeData->m_attributes[i].name();
773             if (isEventHandlerAttribute(attributeName)) {
774                 m_attributeData->m_attributes.remove(i);
775                 continue;
776             }
777
778             if (isAttributeToRemove(attributeName, m_attributeData->m_attributes[i].value()))
779                 m_attributeData->m_attributes[i].setValue(nullAtom);
780             i++;
781         }
782     }
783
784     // Store the set of attributes that changed on the stack in case
785     // attributeChanged mutates m_attributeData.
786     Vector<Attribute> clonedAttributes = m_attributeData->clonedAttributeVector();
787     for (unsigned i = 0; i < clonedAttributes.size(); ++i)
788         attributeChanged(clonedAttributes[i]);
789 }
790
791 bool Element::hasAttributes() const
792 {
793     updateInvalidAttributes();
794     return m_attributeData && m_attributeData->length();
795 }
796
797 bool Element::hasEquivalentAttributes(const Element* other) const
798 {
799     ElementAttributeData* attributeData = updatedAttributeData();
800     ElementAttributeData* otherAttributeData = other->updatedAttributeData();
801     if (attributeData)
802         return attributeData->isEquivalent(otherAttributeData);
803     if (otherAttributeData)
804         return otherAttributeData->isEquivalent(attributeData);
805     return true;
806 }
807
808 String Element::nodeName() const
809 {
810     return m_tagName.toString();
811 }
812
813 String Element::nodeNamePreservingCase() const
814 {
815     return m_tagName.toString();
816 }
817
818 void Element::setPrefix(const AtomicString& prefix, ExceptionCode& ec)
819 {
820     ec = 0;
821     checkSetPrefix(prefix, ec);
822     if (ec)
823         return;
824
825     m_tagName.setPrefix(prefix.isEmpty() ? AtomicString() : prefix);
826 }
827
828 KURL Element::baseURI() const
829 {
830     const AtomicString& baseAttribute = getAttribute(baseAttr);
831     KURL base(KURL(), baseAttribute);
832     if (!base.protocol().isEmpty())
833         return base;
834
835     ContainerNode* parent = parentNode();
836     if (!parent)
837         return base;
838
839     const KURL& parentBase = parent->baseURI();
840     if (parentBase.isNull())
841         return base;
842
843     return KURL(parentBase, baseAttribute);
844 }
845
846 void Element::createAttributeData() const
847 {
848     m_attributeData = ElementAttributeData::create();
849 }
850
851 const QualifiedName& Element::imageSourceAttributeName() const
852 {
853     return srcAttr;
854 }
855
856 RenderObject* Element::createRenderer(RenderArena* arena, RenderStyle* style)
857 {
858     if (document()->documentElement() == this && style->display() == NONE) {
859         // Ignore display: none on root elements.  Force a display of block in that case.
860         RenderBlock* result = new (arena) RenderBlock(this);
861         if (result)
862             result->setAnimatableStyle(style);
863         return result;
864     }
865     return RenderObject::createObject(this, style);
866 }
867
868 bool Element::wasChangedSinceLastFormControlChangeEvent() const
869 {
870     return false;
871 }
872
873 void Element::setChangedSinceLastFormControlChangeEvent(bool)
874 {
875 }
876
877 Node::InsertionNotificationRequest Element::insertedInto(ContainerNode* insertionPoint)
878 {
879     // need to do superclass processing first so inDocument() is true
880     // by the time we reach updateId
881     ContainerNode::insertedInto(insertionPoint);
882
883 #if ENABLE(FULLSCREEN_API)
884     if (containsFullScreenElement() && parentElement() && !parentElement()->containsFullScreenElement())
885         setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(true);
886 #endif
887
888     if (!insertionPoint->inDocument())
889         return InsertionDone;
890
891     const AtomicString& idValue = getIdAttribute();
892     if (!idValue.isNull())
893         updateId(nullAtom, idValue);
894
895     const AtomicString& nameValue = getNameAttribute();
896     if (!nameValue.isNull())
897         updateName(nullAtom, nameValue);
898
899     return InsertionDone;
900 }
901
902 static inline TreeScope* treeScopeOfParent(Node* node, ContainerNode* insertionPoint)
903 {
904     if (Node* parent = node->parentNode())
905         parent->treeScope();
906     return insertionPoint->treeScope();
907 }
908
909
910 void Element::removedFrom(ContainerNode* insertionPoint)
911 {
912 #if ENABLE(FULLSCREEN_API)
913     if (containsFullScreenElement())
914         setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false);
915 #endif
916 #if ENABLE(POINTER_LOCK)
917     if (document()->page())
918         document()->page()->pointerLockController()->elementRemoved(this);
919 #endif
920
921     setSavedLayerScrollOffset(IntSize());
922
923     if (insertionPoint->inDocument()) {
924         const AtomicString& idValue = getIdAttribute();
925         if (!idValue.isNull() && inDocument())
926             updateId(treeScopeOfParent(this, insertionPoint), idValue, nullAtom);
927
928         const AtomicString& nameValue = getNameAttribute();
929         if (!nameValue.isNull())
930             updateName(nameValue, nullAtom);
931     }
932
933     ContainerNode::removedFrom(insertionPoint);
934 }
935
936 void Element::attach()
937 {
938     suspendPostAttachCallbacks();
939     RenderWidget::suspendWidgetHierarchyUpdates();
940
941     createRendererIfNeeded();
942     StyleResolverParentPusher parentPusher(this);
943
944     if (parentElement() && parentElement()->isInCanvasSubtree())
945         setIsInCanvasSubtree(true);
946
947     // When a shadow root exists, it does the work of attaching the children.
948     if (ElementShadow* shadow = this->shadow()) {
949         parentPusher.push();
950         shadow->attach();
951         attachChildrenIfNeeded();
952         attachAsNode();
953     } else {
954         if (firstChild())
955             parentPusher.push();
956         ContainerNode::attach();
957     }
958
959     if (hasRareData()) {   
960         ElementRareData* data = elementRareData();
961         if (data->needsFocusAppearanceUpdateSoonAfterAttach()) {
962             if (isFocusable() && document()->focusedNode() == this)
963                 document()->updateFocusAppearanceSoon(false /* don't restore selection */);
964             data->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
965         }
966     }
967
968     RenderWidget::resumeWidgetHierarchyUpdates();
969     resumePostAttachCallbacks();
970 }
971
972 void Element::unregisterNamedFlowContentNode()
973 {
974     if (document()->cssRegionsEnabled() && inNamedFlow()) {
975         if (document()->renderer() && document()->renderer()->view())
976             document()->renderer()->view()->flowThreadController()->unregisterNamedFlowContentNode(this);
977     }
978 }
979
980 void Element::detach()
981 {
982     RenderWidget::suspendWidgetHierarchyUpdates();
983     unregisterNamedFlowContentNode();
984     cancelFocusAppearanceUpdate();
985     if (hasRareData()) {
986         setIsInCanvasSubtree(false);
987         elementRareData()->resetComputedStyle();
988     }
989
990     if (ElementShadow* shadow = this->shadow()) {
991         detachChildrenIfNeeded();
992         shadow->detach();
993         detachAsNode();
994     } else
995         ContainerNode::detach();
996
997     RenderWidget::resumeWidgetHierarchyUpdates();
998 }
999
1000 bool Element::pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderStyle* newStyle)
1001 {
1002     ASSERT(currentStyle == renderStyle());
1003
1004     if (!renderer() || !currentStyle)
1005         return false;
1006
1007     const PseudoStyleCache* pseudoStyleCache = currentStyle->cachedPseudoStyles();
1008     if (!pseudoStyleCache)
1009         return false;
1010
1011     size_t cacheSize = pseudoStyleCache->size();
1012     for (size_t i = 0; i < cacheSize; ++i) {
1013         RefPtr<RenderStyle> newPseudoStyle;
1014         PseudoId pseudoId = pseudoStyleCache->at(i)->styleType();
1015         if (pseudoId == FIRST_LINE || pseudoId == FIRST_LINE_INHERITED)
1016             newPseudoStyle = renderer()->uncachedFirstLineStyle(newStyle);
1017         else
1018             newPseudoStyle = renderer()->getUncachedPseudoStyle(pseudoId, newStyle, newStyle);
1019         if (!newPseudoStyle)
1020             return true;
1021         if (*newPseudoStyle != *pseudoStyleCache->at(i)) {
1022             if (pseudoId < FIRST_INTERNAL_PSEUDOID)
1023                 newStyle->setHasPseudoStyle(pseudoId);
1024             newStyle->addCachedPseudoStyle(newPseudoStyle);
1025             if (pseudoId == FIRST_LINE || pseudoId == FIRST_LINE_INHERITED) {
1026                 // FIXME: We should do an actual diff to determine whether a repaint vs. layout
1027                 // is needed, but for now just assume a layout will be required.  The diff code
1028                 // in RenderObject::setStyle would need to be factored out so that it could be reused.
1029                 renderer()->setNeedsLayoutAndPrefWidthsRecalc();
1030             }
1031             return true;
1032         }
1033     }
1034     return false;
1035 }
1036
1037 PassRefPtr<RenderStyle> Element::styleForRenderer()
1038 {
1039     if (hasCustomCallbacks()) {
1040         if (RefPtr<RenderStyle> style = customStyleForRenderer())
1041             return style.release();
1042     }
1043
1044     return document()->styleResolver()->styleForElement(this);
1045 }
1046
1047 void Element::recalcStyle(StyleChange change)
1048 {
1049     if (hasCustomCallbacks()) {
1050         if (!willRecalcStyle(change))
1051             return;
1052     }
1053
1054     // Ref currentStyle in case it would otherwise be deleted when setRenderStyle() is called.
1055     RefPtr<RenderStyle> currentStyle(renderStyle());
1056     bool hasParentStyle = parentNodeForRenderingAndStyle() ? static_cast<bool>(parentNodeForRenderingAndStyle()->renderStyle()) : false;
1057     bool hasDirectAdjacentRules = currentStyle && currentStyle->childrenAffectedByDirectAdjacentRules();
1058     bool hasIndirectAdjacentRules = currentStyle && currentStyle->childrenAffectedByForwardPositionalRules();
1059
1060     if ((change > NoChange || needsStyleRecalc())) {
1061         if (hasRareData()) {
1062             ElementRareData* data = elementRareData();
1063             data->resetComputedStyle();
1064             data->m_styleAffectedByEmpty = false;
1065         }
1066     }
1067     if (hasParentStyle && (change >= Inherit || needsStyleRecalc())) {
1068         RefPtr<RenderStyle> newStyle = styleForRenderer();
1069         StyleChange ch = Node::diff(currentStyle.get(), newStyle.get(), document());
1070         if (ch == Detach || !currentStyle) {
1071             // FIXME: The style gets computed twice by calling attach. We could do better if we passed the style along.
1072             reattach();
1073             // attach recalculates the style for all children. No need to do it twice.
1074             clearNeedsStyleRecalc();
1075             clearChildNeedsStyleRecalc();
1076
1077             if (hasCustomCallbacks())
1078                 didRecalcStyle(change);
1079             return;
1080         }
1081
1082         if (currentStyle) {
1083             // Preserve "affected by" bits that were propagated to us from descendants in the case where we didn't do a full
1084             // style change (e.g., only inline style changed).
1085             if (currentStyle->affectedByHoverRules())
1086                 newStyle->setAffectedByHoverRules(true);
1087             if (currentStyle->affectedByActiveRules())
1088                 newStyle->setAffectedByActiveRules(true);
1089             if (currentStyle->affectedByDragRules())
1090                 newStyle->setAffectedByDragRules(true);
1091             if (currentStyle->childrenAffectedByForwardPositionalRules())
1092                 newStyle->setChildrenAffectedByForwardPositionalRules();
1093             if (currentStyle->childrenAffectedByBackwardPositionalRules())
1094                 newStyle->setChildrenAffectedByBackwardPositionalRules();
1095             if (currentStyle->childrenAffectedByFirstChildRules())
1096                 newStyle->setChildrenAffectedByFirstChildRules();
1097             if (currentStyle->childrenAffectedByLastChildRules())
1098                 newStyle->setChildrenAffectedByLastChildRules();
1099             if (currentStyle->childrenAffectedByDirectAdjacentRules())
1100                 newStyle->setChildrenAffectedByDirectAdjacentRules();
1101         }
1102
1103         if (ch != NoChange || pseudoStyleCacheIsInvalid(currentStyle.get(), newStyle.get()) || (change == Force && renderer() && renderer()->requiresForcedStyleRecalcPropagation())) {
1104             setRenderStyle(newStyle);
1105         } else if (needsStyleRecalc() && styleChangeType() != SyntheticStyleChange) {
1106             // Although no change occurred, we use the new style so that the cousin style sharing code won't get
1107             // fooled into believing this style is the same.
1108             if (renderer())
1109                 renderer()->setStyleInternal(newStyle.get());
1110             else
1111                 setRenderStyle(newStyle);
1112         } else if (styleChangeType() == SyntheticStyleChange)
1113              setRenderStyle(newStyle);
1114
1115         // If "rem" units are used anywhere in the document, and if the document element's font size changes, then go ahead and force font updating
1116         // all the way down the tree. This is simpler than having to maintain a cache of objects (and such font size changes should be rare anyway).
1117         if (document()->usesRemUnits() && document()->documentElement() == this && ch != NoChange && currentStyle && newStyle && currentStyle->fontSize() != newStyle->fontSize()) {
1118             // Cached RenderStyles may depend on the rem units.
1119             document()->styleResolver()->invalidateMatchedPropertiesCache();
1120             change = Force;
1121         }
1122
1123         if (change != Force) {
1124             if (styleChangeType() >= FullStyleChange)
1125                 change = Force;
1126             else
1127                 change = ch;
1128         }
1129     }
1130     StyleResolverParentPusher parentPusher(this);
1131
1132     // FIXME: This does not care about sibling combinators. Will be necessary in XBL2 world.
1133     if (ElementShadow* shadow = this->shadow()) {
1134         if (change >= Inherit || shadow->childNeedsStyleRecalc() || shadow->needsStyleRecalc()) {
1135             parentPusher.push();
1136             shadow->recalcStyle(change);
1137         }
1138     }
1139
1140     // FIXME: This check is good enough for :hover + foo, but it is not good enough for :hover + foo + bar.
1141     // For now we will just worry about the common case, since it's a lot trickier to get the second case right
1142     // without doing way too much re-resolution.
1143     bool forceCheckOfNextElementSibling = false;
1144     bool forceCheckOfAnyElementSibling = false;
1145     for (Node *n = firstChild(); n; n = n->nextSibling()) {
1146         if (n->isTextNode()) {
1147             toText(n)->recalcTextStyle(change);
1148             continue;
1149         } 
1150         if (!n->isElementNode()) 
1151             continue;
1152         Element* element = static_cast<Element*>(n);
1153         bool childRulesChanged = element->needsStyleRecalc() && element->styleChangeType() == FullStyleChange;
1154         if ((forceCheckOfNextElementSibling || forceCheckOfAnyElementSibling))
1155             element->setNeedsStyleRecalc();
1156         if (change >= Inherit || element->childNeedsStyleRecalc() || element->needsStyleRecalc()) {
1157             parentPusher.push();
1158             element->recalcStyle(change);
1159         }
1160         forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentRules;
1161         forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules);
1162     }
1163
1164     clearNeedsStyleRecalc();
1165     clearChildNeedsStyleRecalc();
1166     
1167     if (hasCustomCallbacks())
1168         didRecalcStyle(change);
1169 }
1170
1171 ElementShadow* Element::shadow() const
1172 {
1173     if (!hasRareData())
1174         return 0;
1175
1176     return elementRareData()->m_shadow.get();
1177 }
1178
1179 ElementShadow* Element::ensureShadow()
1180 {
1181     if (ElementShadow* shadow = ensureElementRareData()->m_shadow.get())
1182         return shadow;
1183
1184     elementRareData()->m_shadow = adoptPtr(new ElementShadow());
1185     return elementRareData()->m_shadow.get();
1186 }
1187
1188 ShadowRoot* Element::ensureShadowRoot()
1189 {
1190     if (ElementShadow* shadow = this->shadow())
1191         return shadow->oldestShadowRoot();
1192
1193     return ShadowRoot::create(this, ShadowRoot::UserAgentShadowRoot).get();
1194 }
1195
1196 const AtomicString& Element::shadowPseudoId() const
1197 {
1198     return hasRareData() ? elementRareData()->m_shadowPseudoId : nullAtom;
1199 }
1200
1201 void Element::setShadowPseudoId(const AtomicString& id, ExceptionCode& ec)
1202 {
1203     if (!hasRareData() && id == nullAtom)
1204         return;
1205
1206     if (!CSSSelector::isUnknownPseudoType(id)) {
1207         ec = SYNTAX_ERR;
1208         return;
1209     }
1210
1211     ensureElementRareData()->m_shadowPseudoId = id;
1212 }
1213
1214 bool Element::childTypeAllowed(NodeType type) const
1215 {
1216     switch (type) {
1217     case ELEMENT_NODE:
1218     case TEXT_NODE:
1219     case COMMENT_NODE:
1220     case PROCESSING_INSTRUCTION_NODE:
1221     case CDATA_SECTION_NODE:
1222     case ENTITY_REFERENCE_NODE:
1223         return true;
1224     default:
1225         break;
1226     }
1227     return false;
1228 }
1229
1230 static void checkForEmptyStyleChange(Element* element, RenderStyle* style)
1231 {
1232     if (!style && !element->styleAffectedByEmpty())
1233         return;
1234
1235     if (!style || (style->affectedByEmpty() && (!style->emptyState() || element->hasChildNodes())))
1236         element->setNeedsStyleRecalc();
1237 }
1238
1239 static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool finishedParsingCallback,
1240                                         Node* beforeChange, Node* afterChange, int childCountDelta)
1241 {
1242     // :empty selector.
1243     checkForEmptyStyleChange(e, style);
1244     
1245     if (!style || (e->needsStyleRecalc() && style->childrenAffectedByPositionalRules()))
1246         return;
1247
1248     // :first-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
1249     // In the DOM case, we only need to do something if |afterChange| is not 0.
1250     // |afterChange| is 0 in the parser case, so it works out that we'll skip this block.
1251     if (style->childrenAffectedByFirstChildRules() && afterChange) {
1252         // Find our new first child.
1253         Node* newFirstChild = 0;
1254         for (newFirstChild = e->firstChild(); newFirstChild && !newFirstChild->isElementNode(); newFirstChild = newFirstChild->nextSibling()) {};
1255         
1256         // Find the first element node following |afterChange|
1257         Node* firstElementAfterInsertion = 0;
1258         for (firstElementAfterInsertion = afterChange;
1259              firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode();
1260              firstElementAfterInsertion = firstElementAfterInsertion->nextSibling()) {};
1261         
1262         // This is the insert/append case.
1263         if (newFirstChild != firstElementAfterInsertion && firstElementAfterInsertion && firstElementAfterInsertion->attached() &&
1264             firstElementAfterInsertion->renderStyle() && firstElementAfterInsertion->renderStyle()->firstChildState())
1265             firstElementAfterInsertion->setNeedsStyleRecalc();
1266             
1267         // We also have to handle node removal.
1268         if (childCountDelta < 0 && newFirstChild == firstElementAfterInsertion && newFirstChild && (!newFirstChild->renderStyle() || !newFirstChild->renderStyle()->firstChildState()))
1269             newFirstChild->setNeedsStyleRecalc();
1270     }
1271
1272     // :last-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
1273     // In the DOM case, we only need to do something if |afterChange| is not 0.
1274     if (style->childrenAffectedByLastChildRules() && beforeChange) {
1275         // Find our new last child.
1276         Node* newLastChild = 0;
1277         for (newLastChild = e->lastChild(); newLastChild && !newLastChild->isElementNode(); newLastChild = newLastChild->previousSibling()) {};
1278         
1279         // Find the last element node going backwards from |beforeChange|
1280         Node* lastElementBeforeInsertion = 0;
1281         for (lastElementBeforeInsertion = beforeChange;
1282              lastElementBeforeInsertion && !lastElementBeforeInsertion->isElementNode();
1283              lastElementBeforeInsertion = lastElementBeforeInsertion->previousSibling()) {};
1284         
1285         if (newLastChild != lastElementBeforeInsertion && lastElementBeforeInsertion && lastElementBeforeInsertion->attached() &&
1286             lastElementBeforeInsertion->renderStyle() && lastElementBeforeInsertion->renderStyle()->lastChildState())
1287             lastElementBeforeInsertion->setNeedsStyleRecalc();
1288             
1289         // 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
1290         // to match now.
1291         if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild == lastElementBeforeInsertion && newLastChild && (!newLastChild->renderStyle() || !newLastChild->renderStyle()->lastChildState()))
1292             newLastChild->setNeedsStyleRecalc();
1293     }
1294
1295     // The + selector.  We need to invalidate the first element following the insertion point.  It is the only possible element
1296     // that could be affected by this DOM change.
1297     if (style->childrenAffectedByDirectAdjacentRules() && afterChange) {
1298         Node* firstElementAfterInsertion = 0;
1299         for (firstElementAfterInsertion = afterChange;
1300              firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode();
1301              firstElementAfterInsertion = firstElementAfterInsertion->nextSibling()) {};
1302         if (firstElementAfterInsertion && firstElementAfterInsertion->attached())
1303             firstElementAfterInsertion->setNeedsStyleRecalc();
1304     }
1305
1306     // Forward positional selectors include the ~ selector, nth-child, nth-of-type, first-of-type and only-of-type.
1307     // Backward positional selectors include nth-last-child, nth-last-of-type, last-of-type and only-of-type.
1308     // We have to invalidate everything following the insertion point in the forward case, and everything before the insertion point in the
1309     // backward case.
1310     // |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.
1311     // 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
1312     // here.  recalcStyle will then force a walk of the children when it sees that this has happened.
1313     if ((style->childrenAffectedByForwardPositionalRules() && afterChange) ||
1314         (style->childrenAffectedByBackwardPositionalRules() && beforeChange))
1315         e->setNeedsStyleRecalc();
1316 }
1317
1318 void Element::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
1319 {
1320     ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
1321     if (changedByParser)
1322         checkForEmptyStyleChange(this, renderStyle());
1323     else
1324         checkForSiblingStyleChanges(this, renderStyle(), false, beforeChange, afterChange, childCountDelta);
1325
1326     if (ElementShadow * shadow = this->shadow())
1327         shadow->invalidateDistribution();
1328 }
1329
1330 void Element::beginParsingChildren()
1331 {
1332     clearIsParsingChildrenFinished();
1333     StyleResolver* styleResolver = document()->styleResolverIfExists();
1334     if (styleResolver && attached())
1335         styleResolver->pushParentElement(this);
1336 }
1337
1338 void Element::finishParsingChildren()
1339 {
1340     ContainerNode::finishParsingChildren();
1341     setIsParsingChildrenFinished();
1342     checkForSiblingStyleChanges(this, renderStyle(), true, lastChild(), 0, 0);
1343     if (StyleResolver* styleResolver = document()->styleResolverIfExists())
1344         styleResolver->popParentElement(this);
1345 }
1346
1347 #ifndef NDEBUG
1348 void Element::formatForDebugger(char* buffer, unsigned length) const
1349 {
1350     String result;
1351     String s;
1352     
1353     s = nodeName();
1354     if (s.length() > 0) {
1355         result += s;
1356     }
1357           
1358     s = getIdAttribute();
1359     if (s.length() > 0) {
1360         if (result.length() > 0)
1361             result += "; ";
1362         result += "id=";
1363         result += s;
1364     }
1365           
1366     s = getAttribute(classAttr);
1367     if (s.length() > 0) {
1368         if (result.length() > 0)
1369             result += "; ";
1370         result += "class=";
1371         result += s;
1372     }
1373           
1374     strncpy(buffer, result.utf8().data(), length - 1);
1375 }
1376 #endif
1377
1378 PassRefPtr<Attr> Element::setAttributeNode(Attr* attr, ExceptionCode& ec)
1379 {
1380     if (!attr) {
1381         ec = TYPE_MISMATCH_ERR;
1382         return 0;
1383     }
1384
1385     ElementAttributeData* attributeData = ensureUpdatedAttributeData();
1386
1387     RefPtr<Attr> oldAttr = attrIfExists(attr->qualifiedName());
1388     if (oldAttr.get() == attr)
1389         return attr; // This Attr is already attached to the element.
1390
1391     // INUSE_ATTRIBUTE_ERR: Raised if node is an Attr that is already an attribute of another Element object.
1392     // The DOM user must explicitly clone Attr nodes to re-use them in other elements.
1393     if (attr->ownerElement()) {
1394         ec = INUSE_ATTRIBUTE_ERR;
1395         return 0;
1396     }
1397
1398     size_t index = attributeData->getAttributeItemIndex(attr->qualifiedName());
1399     Attribute* oldAttribute = index != notFound ? attributeData->attributeItem(index) : 0;
1400
1401     if (!oldAttribute) {
1402         attributeData->addAttribute(Attribute(attr->qualifiedName(), attr->value()), this);
1403         attributeData->setAttr(this, attr->qualifiedName(), attr);
1404         return 0;
1405     }
1406
1407     if (oldAttr)
1408         oldAttr->detachFromElementWithValue(oldAttribute->value());
1409     else
1410         oldAttr = Attr::create(document(), oldAttribute->name(), oldAttribute->value());
1411
1412     attributeData->replaceAttribute(index, Attribute(attr->name(), attr->value()), this);
1413     attributeData->setAttr(this, attr->qualifiedName(), attr);
1414     return oldAttr.release();
1415 }
1416
1417 PassRefPtr<Attr> Element::setAttributeNodeNS(Attr* attr, ExceptionCode& ec)
1418 {
1419     return setAttributeNode(attr, ec);
1420 }
1421
1422 PassRefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionCode& ec)
1423 {
1424     if (!attr) {
1425         ec = TYPE_MISMATCH_ERR;
1426         return 0;
1427     }
1428     if (attr->ownerElement() != this) {
1429         ec = NOT_FOUND_ERR;
1430         return 0;
1431     }
1432
1433     ASSERT(document() == attr->document());
1434
1435     ElementAttributeData* attributeData = updatedAttributeData();
1436     ASSERT(attributeData);
1437
1438     size_t index = attributeData->getAttributeItemIndex(attr->qualifiedName());
1439     if (index == notFound) {
1440         ec = NOT_FOUND_ERR;
1441         return 0;
1442     }
1443
1444     return detachAttribute(index);
1445 }
1446
1447 void Element::setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode& ec, FragmentScriptingPermission scriptingPermission)
1448 {
1449     String prefix, localName;
1450     if (!Document::parseQualifiedName(qualifiedName, prefix, localName, ec))
1451         return;
1452
1453     QualifiedName qName(prefix, localName, namespaceURI);
1454
1455     if (!Document::hasValidNamespaceForAttributes(qName)) {
1456         ec = NAMESPACE_ERR;
1457         return;
1458     }
1459
1460     if (scriptingPermission == DisallowScriptingContent && (isEventHandlerAttribute(qName) || isAttributeToRemove(qName, value)))
1461         return;
1462
1463     setAttribute(qName, value);
1464 }
1465
1466 void Element::removeAttribute(size_t index)
1467 {
1468     ASSERT(attributeData());
1469     ASSERT(index <= attributeCount());
1470     attributeData()->removeAttribute(index, this);
1471 }
1472
1473 void Element::removeAttribute(const String& name)
1474 {
1475     ElementAttributeData* attributeData = this->attributeData();
1476     if (!attributeData)
1477         return;
1478
1479     String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
1480     size_t index = attributeData->getAttributeItemIndex(localName, false);
1481     if (index == notFound)
1482         return;
1483
1484     attributeData->removeAttribute(index, this);
1485 }
1486
1487 void Element::removeAttributeNS(const String& namespaceURI, const String& localName)
1488 {
1489     removeAttribute(QualifiedName(nullAtom, localName, namespaceURI));
1490 }
1491
1492 PassRefPtr<Attr> Element::getAttributeNode(const String& name)
1493 {
1494     ElementAttributeData* attributeData = updatedAttributeData();
1495     if (!attributeData)
1496         return 0;
1497     return attributeData->getAttributeNode(name, shouldIgnoreAttributeCase(this), this);
1498 }
1499
1500 PassRefPtr<Attr> Element::getAttributeNodeNS(const String& namespaceURI, const String& localName)
1501 {
1502     ElementAttributeData* attributeData = updatedAttributeData();
1503     if (!attributeData)
1504         return 0;
1505     return attributeData->getAttributeNode(QualifiedName(nullAtom, localName, namespaceURI), this);
1506 }
1507
1508 bool Element::hasAttribute(const String& name) const
1509 {
1510     ElementAttributeData* attributeData = updatedAttributeData();
1511     if (!attributeData)
1512         return false;
1513
1514     // This call to String::lower() seems to be required but
1515     // there may be a way to remove it.
1516     String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
1517     return attributeData->getAttributeItem(localName, false);
1518 }
1519
1520 bool Element::hasAttributeNS(const String& namespaceURI, const String& localName) const
1521 {
1522     ElementAttributeData* attributeData = updatedAttributeData();
1523     if (!attributeData)
1524         return false;
1525     return attributeData->getAttributeItem(QualifiedName(nullAtom, localName, namespaceURI));
1526 }
1527
1528 CSSStyleDeclaration *Element::style()
1529 {
1530     return 0;
1531 }
1532
1533 void Element::focus(bool restorePreviousSelection)
1534 {
1535     if (!inDocument())
1536         return;
1537
1538     Document* doc = document();
1539     if (doc->focusedNode() == this)
1540         return;
1541
1542     // If the stylesheets have already been loaded we can reliably check isFocusable.
1543     // If not, we continue and set the focused node on the focus controller below so
1544     // that it can be updated soon after attach. 
1545     if (doc->haveStylesheetsLoaded()) {
1546         doc->updateLayoutIgnorePendingStylesheets();
1547         if (!isFocusable())
1548             return;
1549     }
1550
1551     if (!supportsFocus())
1552         return;
1553
1554     RefPtr<Node> protect;
1555     if (Page* page = doc->page()) {
1556         // Focus and change event handlers can cause us to lose our last ref.
1557         // If a focus event handler changes the focus to a different node it
1558         // does not make sense to continue and update appearence.
1559         protect = this;
1560         if (!page->focusController()->setFocusedNode(this, doc->frame()))
1561             return;
1562     }
1563
1564     // Setting the focused node above might have invalidated the layout due to scripts.
1565     doc->updateLayoutIgnorePendingStylesheets();
1566
1567     if (!isFocusable()) {
1568         ensureElementRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(true);
1569         return;
1570     }
1571         
1572     cancelFocusAppearanceUpdate();
1573     updateFocusAppearance(restorePreviousSelection);
1574 }
1575
1576 void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
1577 {
1578     if (isRootEditableElement()) {
1579         Frame* frame = document()->frame();
1580         if (!frame)
1581             return;
1582         
1583         // When focusing an editable element in an iframe, don't reset the selection if it already contains a selection.
1584         if (this == frame->selection()->rootEditableElement())
1585             return;
1586
1587         // FIXME: We should restore the previous selection if there is one.
1588         VisibleSelection newSelection = VisibleSelection(firstPositionInOrBeforeNode(this), DOWNSTREAM);
1589         
1590         if (frame->selection()->shouldChangeSelection(newSelection)) {
1591             frame->selection()->setSelection(newSelection);
1592             frame->selection()->revealSelection();
1593         }
1594     } else if (renderer() && !renderer()->isWidget())
1595         renderer()->scrollRectToVisible(getRect());
1596 }
1597
1598 void Element::blur()
1599 {
1600     cancelFocusAppearanceUpdate();
1601     Document* doc = document();
1602     if (treeScope()->focusedNode() == this) {
1603         if (doc->frame())
1604             doc->frame()->page()->focusController()->setFocusedNode(0, doc->frame());
1605         else
1606             doc->setFocusedNode(0);
1607     }
1608 }
1609
1610 String Element::innerText()
1611 {
1612     // We need to update layout, since plainText uses line boxes in the render tree.
1613     document()->updateLayoutIgnorePendingStylesheets();
1614
1615     if (!renderer())
1616         return textContent(true);
1617
1618     return plainText(rangeOfContents(const_cast<Element*>(this)).get());
1619 }
1620
1621 String Element::outerText()
1622 {
1623     // Getting outerText is the same as getting innerText, only
1624     // setting is different. You would think this should get the plain
1625     // text for the outer range, but this is wrong, <br> for instance
1626     // would return different values for inner and outer text by such
1627     // a rule, but it doesn't in WinIE, and we want to match that.
1628     return innerText();
1629 }
1630
1631 String Element::title() const
1632 {
1633     return String();
1634 }
1635
1636 LayoutSize Element::minimumSizeForResizing() const
1637 {
1638     return hasRareData() ? elementRareData()->m_minimumSizeForResizing : defaultMinimumSizeForResizing();
1639 }
1640
1641 void Element::setMinimumSizeForResizing(const LayoutSize& size)
1642 {
1643     if (size == defaultMinimumSizeForResizing() && !hasRareData())
1644         return;
1645     ensureElementRareData()->m_minimumSizeForResizing = size;
1646 }
1647
1648 RenderStyle* Element::computedStyle(PseudoId pseudoElementSpecifier)
1649 {
1650     // FIXME: Find and use the renderer from the pseudo element instead of the actual element so that the 'length'
1651     // properties, which are only known by the renderer because it did the layout, will be correct and so that the
1652     // values returned for the ":selection" pseudo-element will be correct.
1653     if (RenderStyle* usedStyle = renderStyle()) {
1654         if (pseudoElementSpecifier) {
1655             RenderStyle* cachedPseudoStyle = usedStyle->getCachedPseudoStyle(pseudoElementSpecifier);
1656             return cachedPseudoStyle ? cachedPseudoStyle : usedStyle;
1657          } else
1658             return usedStyle;
1659     }
1660
1661     if (!attached())
1662         // FIXME: Try to do better than this. Ensure that styleForElement() works for elements that are not in the
1663         // document tree and figure out when to destroy the computed style for such elements.
1664         return 0;
1665
1666     ElementRareData* data = ensureElementRareData();
1667     if (!data->m_computedStyle)
1668         data->m_computedStyle = document()->styleForElementIgnoringPendingStylesheets(this);
1669     return pseudoElementSpecifier ? data->m_computedStyle->getCachedPseudoStyle(pseudoElementSpecifier) : data->m_computedStyle.get();
1670 }
1671
1672 void Element::setStyleAffectedByEmpty()
1673 {
1674     ElementRareData* data = ensureElementRareData();
1675     data->m_styleAffectedByEmpty = true;
1676 }
1677
1678 bool Element::styleAffectedByEmpty() const
1679 {
1680     return hasRareData() && elementRareData()->m_styleAffectedByEmpty;
1681 }
1682
1683 void Element::setIsInCanvasSubtree(bool isInCanvasSubtree)
1684 {
1685     ElementRareData* data = ensureElementRareData();
1686     data->m_isInCanvasSubtree = isInCanvasSubtree;
1687 }
1688
1689 bool Element::isInCanvasSubtree() const
1690 {
1691     return hasRareData() && elementRareData()->m_isInCanvasSubtree;
1692 }
1693
1694 AtomicString Element::computeInheritedLanguage() const
1695 {
1696     const Node* n = this;
1697     AtomicString value;
1698     // The language property is inherited, so we iterate over the parents to find the first language.
1699     while (n && value.isNull()) {
1700         if (n->isElementNode()) {
1701             // Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7
1702             value = static_cast<const Element*>(n)->fastGetAttribute(XMLNames::langAttr);
1703             if (value.isNull())
1704                 value = static_cast<const Element*>(n)->fastGetAttribute(HTMLNames::langAttr);
1705         } else if (n->isDocumentNode()) {
1706             // checking the MIME content-language
1707             value = static_cast<const Document*>(n)->contentLanguage();
1708         }
1709
1710         n = n->parentNode();
1711     }
1712
1713     return value;
1714 }
1715
1716 void Element::cancelFocusAppearanceUpdate()
1717 {
1718     if (hasRareData())
1719         elementRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
1720     if (document()->focusedNode() == this)
1721         document()->cancelFocusAppearanceUpdate();
1722 }
1723
1724 void Element::normalizeAttributes()
1725 {
1726     if (!hasAttrList())
1727         return;
1728
1729     ElementAttributeData* attributeData = updatedAttributeData();
1730     ASSERT(attributeData);
1731
1732     const Vector<Attribute>& attributes = attributeData->attributeVector();
1733     for (size_t i = 0; i < attributes.size(); ++i) {
1734         if (RefPtr<Attr> attr = attrIfExists(attributes[i].name()))
1735             attr->normalize();
1736     }
1737 }
1738
1739 // ElementTraversal API
1740 Element* Element::firstElementChild() const
1741 {
1742     return WebCore::firstElementChild(this);
1743 }
1744
1745 Element* Element::lastElementChild() const
1746 {
1747     Node* n = lastChild();
1748     while (n && !n->isElementNode())
1749         n = n->previousSibling();
1750     return static_cast<Element*>(n);
1751 }
1752
1753 unsigned Element::childElementCount() const
1754 {
1755     unsigned count = 0;
1756     Node* n = firstChild();
1757     while (n) {
1758         count += n->isElementNode();
1759         n = n->nextSibling();
1760     }
1761     return count;
1762 }
1763
1764 bool Element::webkitMatchesSelector(const String& selector, ExceptionCode& ec)
1765 {
1766     if (selector.isEmpty()) {
1767         ec = SYNTAX_ERR;
1768         return false;
1769     }
1770
1771     SelectorQuery* selectorQuery = document()->selectorQueryCache()->add(selector, document(), ec);
1772     if (!selectorQuery)
1773         return false;
1774     return selectorQuery->matches(this);
1775 }
1776
1777 DOMTokenList* Element::classList()
1778 {
1779     ElementRareData* data = ensureElementRareData();
1780     if (!data->m_classList)
1781         data->m_classList = ClassList::create(this);
1782     return data->m_classList.get();
1783 }
1784
1785 DOMTokenList* Element::optionalClassList() const
1786 {
1787     if (!hasRareData())
1788         return 0;
1789     return elementRareData()->m_classList.get();
1790 }
1791
1792 DOMStringMap* Element::dataset()
1793 {
1794     ElementRareData* data = ensureElementRareData();
1795     if (!data->m_datasetDOMStringMap)
1796         data->m_datasetDOMStringMap = DatasetDOMStringMap::create(this);
1797     return data->m_datasetDOMStringMap.get();
1798 }
1799
1800 KURL Element::getURLAttribute(const QualifiedName& name) const
1801 {
1802 #if !ASSERT_DISABLED
1803     if (m_attributeData) {
1804         if (Attribute* attribute = getAttributeItem(name))
1805             ASSERT(isURLAttribute(*attribute));
1806     }
1807 #endif
1808     return document()->completeURL(stripLeadingAndTrailingHTMLSpaces(getAttribute(name)));
1809 }
1810
1811 KURL Element::getNonEmptyURLAttribute(const QualifiedName& name) const
1812 {
1813 #if !ASSERT_DISABLED
1814     if (m_attributeData) {
1815         if (Attribute* attribute = getAttributeItem(name))
1816             ASSERT(isURLAttribute(*attribute));
1817     }
1818 #endif
1819     String value = stripLeadingAndTrailingHTMLSpaces(getAttribute(name));
1820     if (value.isEmpty())
1821         return KURL();
1822     return document()->completeURL(value);
1823 }
1824
1825 int Element::getIntegralAttribute(const QualifiedName& attributeName) const
1826 {
1827     return getAttribute(attributeName).string().toInt();
1828 }
1829
1830 void Element::setIntegralAttribute(const QualifiedName& attributeName, int value)
1831 {
1832     // FIXME: Need an AtomicString version of String::number.
1833     setAttribute(attributeName, String::number(value));
1834 }
1835
1836 unsigned Element::getUnsignedIntegralAttribute(const QualifiedName& attributeName) const
1837 {
1838     return getAttribute(attributeName).string().toUInt();
1839 }
1840
1841 void Element::setUnsignedIntegralAttribute(const QualifiedName& attributeName, unsigned value)
1842 {
1843     // FIXME: Need an AtomicString version of String::number.
1844     setAttribute(attributeName, String::number(value));
1845 }
1846
1847 #if ENABLE(SVG)
1848 bool Element::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
1849 {
1850     // Only create renderers for SVG elements whose parents are SVG elements, or for proper <svg xmlns="svgNS"> subdocuments.
1851     if (childContext.node()->isSVGElement())
1852         return childContext.node()->hasTagName(SVGNames::svgTag) || isSVGElement();
1853
1854     return Node::childShouldCreateRenderer(childContext);
1855 }
1856 #endif
1857     
1858 #if ENABLE(FULLSCREEN_API)
1859 void Element::webkitRequestFullscreen()
1860 {
1861     document()->requestFullScreenForElement(this, ALLOW_KEYBOARD_INPUT, Document::EnforceIFrameAllowFulScreenRequirement);
1862 }
1863
1864 void Element::webkitRequestFullScreen(unsigned short flags)
1865 {
1866     document()->requestFullScreenForElement(this, (flags | LEGACY_MOZILLA_REQUEST), Document::EnforceIFrameAllowFulScreenRequirement);
1867 }
1868
1869 bool Element::containsFullScreenElement() const
1870 {
1871     return hasRareData() ? elementRareData()->m_containsFullScreenElement : false;
1872 }
1873
1874 void Element::setContainsFullScreenElement(bool flag)
1875 {
1876     ensureElementRareData()->m_containsFullScreenElement = flag;
1877     setNeedsStyleRecalc(SyntheticStyleChange);
1878 }
1879
1880 static Element* parentCrossingFrameBoundaries(Element* element)
1881 {
1882     ASSERT(element);
1883     return element->parentElement() ? element->parentElement() : element->document()->ownerElement();
1884 }
1885
1886 void Element::setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(bool flag)
1887 {
1888     Element* element = this;
1889     while ((element = parentCrossingFrameBoundaries(element)))
1890         element->setContainsFullScreenElement(flag);
1891 }
1892 #endif    
1893
1894 #if ENABLE(POINTER_LOCK)
1895 void Element::webkitRequestPointerLock()
1896 {
1897     if (document()->page())
1898         document()->page()->pointerLockController()->requestPointerLock(this, 0, 0);
1899 }
1900 #endif
1901
1902 SpellcheckAttributeState Element::spellcheckAttributeState() const
1903 {
1904     const AtomicString& value = getAttribute(HTMLNames::spellcheckAttr);
1905     if (value == nullAtom)
1906         return SpellcheckAttributeDefault;
1907     if (equalIgnoringCase(value, "true") || equalIgnoringCase(value, ""))
1908         return SpellcheckAttributeTrue;
1909     if (equalIgnoringCase(value, "false"))
1910         return SpellcheckAttributeFalse;
1911
1912     return SpellcheckAttributeDefault;
1913 }
1914
1915 bool Element::isSpellCheckingEnabled() const
1916 {
1917     const Element* element = this;
1918     while (element) {
1919         switch (element->spellcheckAttributeState()) {
1920         case SpellcheckAttributeTrue:
1921             return true;
1922         case SpellcheckAttributeFalse:
1923             return false;
1924         case SpellcheckAttributeDefault:
1925             break;
1926         }
1927
1928         ContainerNode* parent = const_cast<Element*>(element)->parentOrHostNode();
1929         if (parent && parent->isElementNode())
1930             element = toElement(parent);
1931         else if (parent && parent->isShadowRoot())
1932             element = toElement(parent->parentOrHostNode());
1933         else
1934             element = 0;
1935     }
1936
1937     return true;
1938 }
1939
1940 PassRefPtr<WebKitAnimationList> Element::webkitGetAnimations() const
1941 {
1942     if (!renderer())
1943         return 0;
1944
1945     AnimationController* animController = renderer()->animation();
1946
1947     if (!animController)
1948         return 0;
1949     
1950     return animController->animationsForRenderer(renderer());
1951 }
1952
1953 const AtomicString& Element::webkitRegionOverflow() const
1954 {
1955     document()->updateLayoutIgnorePendingStylesheets();
1956
1957     if (document()->cssRegionsEnabled() && renderer() && renderer()->isRenderRegion()) {
1958         RenderRegion* region = toRenderRegion(renderer());
1959         switch (region->regionState()) {
1960         case RenderRegion::RegionFit: {
1961             DEFINE_STATIC_LOCAL(AtomicString, fitState, ("fit"));
1962             return fitState;
1963         }
1964         case RenderRegion::RegionEmpty: {
1965             DEFINE_STATIC_LOCAL(AtomicString, emptyState, ("empty"));
1966             return emptyState;
1967         }
1968         case RenderRegion::RegionOverflow: {
1969             DEFINE_STATIC_LOCAL(AtomicString, overflowState, ("overflow"));
1970             return overflowState;
1971         }
1972         default:
1973             break;
1974         }
1975     }
1976     DEFINE_STATIC_LOCAL(AtomicString, undefinedState, ("undefined"));
1977     return undefinedState;
1978 }
1979
1980 #ifndef NDEBUG
1981 bool Element::fastAttributeLookupAllowed(const QualifiedName& name) const
1982 {
1983     if (name == HTMLNames::styleAttr)
1984         return false;
1985
1986 #if ENABLE(SVG)
1987     if (isSVGElement())
1988         return !SVGElement::isAnimatableAttribute(name);
1989 #endif
1990
1991     return true;
1992 }
1993 #endif
1994
1995 #ifdef DUMP_NODE_STATISTICS
1996 bool Element::hasNamedNodeMap() const
1997 {
1998     return hasRareData() && elementRareData()->m_attributeMap;
1999 }
2000 #endif
2001
2002 void Element::willModifyAttribute(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue)
2003 {
2004     if (isIdAttributeName(name))
2005         updateId(oldValue, newValue);
2006     else if (name == HTMLNames::nameAttr)
2007         updateName(oldValue, newValue);
2008
2009 #if ENABLE(MUTATION_OBSERVERS)
2010     if (OwnPtr<MutationObserverInterestGroup> recipients = MutationObserverInterestGroup::createForAttributesMutation(this, name))
2011         recipients->enqueueMutationRecord(MutationRecord::createAttributes(this, name, oldValue));
2012 #endif
2013
2014 #if ENABLE(INSPECTOR)
2015     InspectorInstrumentation::willModifyDOMAttr(document(), this, oldValue, newValue);
2016 #endif
2017 }
2018
2019 void Element::didAddAttribute(const Attribute& attribute)
2020 {
2021     attributeChanged(attribute);
2022     InspectorInstrumentation::didModifyDOMAttr(document(), this, attribute.localName(), attribute.value());
2023     dispatchSubtreeModifiedEvent();
2024 }
2025
2026 void Element::didModifyAttribute(const Attribute& attribute)
2027 {
2028     attributeChanged(attribute);
2029     InspectorInstrumentation::didModifyDOMAttr(document(), this, attribute.localName(), attribute.value());
2030     // Do not dispatch a DOMSubtreeModified event here; see bug 81141.
2031 }
2032
2033 void Element::didRemoveAttribute(const QualifiedName& name)
2034 {
2035     attributeChanged(Attribute(name, nullAtom));
2036     InspectorInstrumentation::didRemoveDOMAttr(document(), this, name.localName());
2037     dispatchSubtreeModifiedEvent();
2038 }
2039
2040
2041 void Element::updateNamedItemRegistration(const AtomicString& oldName, const AtomicString& newName)
2042 {
2043     if (!document()->isHTMLDocument())
2044         return;
2045
2046     if (!oldName.isEmpty())
2047         static_cast<HTMLDocument*>(document())->removeNamedItem(oldName);
2048
2049     if (!newName.isEmpty())
2050         static_cast<HTMLDocument*>(document())->addNamedItem(newName);
2051 }
2052
2053 void Element::updateExtraNamedItemRegistration(const AtomicString& oldId, const AtomicString& newId)
2054 {
2055     if (!document()->isHTMLDocument())
2056         return;
2057
2058     if (!oldId.isEmpty())
2059         static_cast<HTMLDocument*>(document())->removeExtraNamedItem(oldId);
2060
2061     if (!newId.isEmpty())
2062         static_cast<HTMLDocument*>(document())->addExtraNamedItem(newId);
2063 }
2064
2065 PassRefPtr<HTMLCollection> Element::ensureCachedHTMLCollection(CollectionType type)
2066 {
2067     return ensureElementRareData()->ensureCachedHTMLCollection(this, type);
2068 }
2069
2070 PassRefPtr<HTMLCollection> ElementRareData::ensureCachedHTMLCollection(Element* element, CollectionType type)
2071 {
2072     if (!m_cachedCollections) {
2073         m_cachedCollections = adoptPtr(new CachedHTMLCollectionArray);
2074         for (unsigned i = 0; i < NumNodeCollectionTypes; i++)
2075             (*m_cachedCollections)[i] = 0;
2076     }
2077
2078     if (HTMLCollection* collection = (*m_cachedCollections)[type - FirstNodeCollectionType])
2079         return collection;
2080
2081     RefPtr<HTMLCollection> collection;
2082     if (type == TableRows) {
2083         ASSERT(element->hasTagName(tableTag));
2084         collection = HTMLTableRowsCollection::create(element);
2085     } else if (type == SelectOptions) {
2086         ASSERT(element->hasTagName(selectTag));
2087         collection = HTMLOptionsCollection::create(element);
2088     } else if (type == FormControls) {
2089         ASSERT(element->hasTagName(formTag) || element->hasTagName(fieldsetTag));
2090         collection = HTMLFormCollection::create(element);
2091 #if ENABLE(MICRODATA)
2092     } else if (type == ItemProperties) {
2093         collection = HTMLPropertiesCollection::create(element);
2094 #endif
2095     } else
2096         collection = HTMLCollection::create(element, type);
2097     (*m_cachedCollections)[type - FirstNodeCollectionType] = collection.get();
2098     return collection.release();
2099 }
2100
2101 HTMLCollection* Element::cachedHTMLCollection(CollectionType type)
2102 {
2103     return hasRareData() ? elementRareData()->cachedHTMLCollection(type) : 0;
2104 }
2105
2106 void Element::removeCachedHTMLCollection(HTMLCollection* collection, CollectionType type)
2107 {
2108     ASSERT(hasRareData());
2109     elementRareData()->removeCachedHTMLCollection(collection, type);
2110 }
2111
2112 IntSize Element::savedLayerScrollOffset() const
2113 {
2114     return hasRareData() ? elementRareData()->m_savedLayerScrollOffset : IntSize();
2115 }
2116
2117 void Element::setSavedLayerScrollOffset(const IntSize& size)
2118 {
2119     if (size.isZero() && !hasRareData())
2120         return;
2121     ensureElementRareData()->m_savedLayerScrollOffset = size;
2122 }
2123
2124 PassRefPtr<Attr> Element::attrIfExists(const QualifiedName& name)
2125 {
2126     if (!hasAttrList())
2127         return 0;
2128     ASSERT(attributeData());
2129     return attributeData()->attrIfExists(this, name);
2130 }
2131
2132 PassRefPtr<Attr> Element::ensureAttr(const QualifiedName& name)
2133 {
2134     ASSERT(attributeData());
2135     return attributeData()->ensureAttr(this, name);
2136 }
2137
2138 bool Element::willRecalcStyle(StyleChange)
2139 {
2140     ASSERT(hasCustomCallbacks());
2141     return true;
2142 }
2143
2144 void Element::didRecalcStyle(StyleChange)
2145 {
2146     ASSERT(hasCustomCallbacks());
2147 }
2148
2149
2150 PassRefPtr<RenderStyle> Element::customStyleForRenderer()
2151 {
2152     ASSERT(hasCustomCallbacks());
2153     return 0;
2154 }
2155
2156
2157 void Element::cloneAttributesFromElement(const Element& other)
2158 {
2159     if (ElementAttributeData* attributeData = other.updatedAttributeData())
2160         ensureUpdatedAttributeData()->cloneDataFrom(*attributeData, other, *this);
2161     else if (m_attributeData) {
2162         m_attributeData->clearAttributes(this);
2163         m_attributeData.clear();
2164     }
2165 }
2166
2167 void Element::cloneDataFromElement(const Element& other)
2168 {
2169     cloneAttributesFromElement(other);
2170     copyNonAttributePropertiesFromElement(other);
2171 }
2172
2173 } // namespace WebCore