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