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