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