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