<rdar://problem/9750062> REGRESSION: Button text missing in many iTunes Store pages
[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             ElementRareData* data = rareData();
1107             data->resetComputedStyle();
1108             data->m_styleAffectedByEmpty = false;
1109         }
1110     }
1111     if (hasParentStyle && (change >= Inherit || needsStyleRecalc())) {
1112         RefPtr<RenderStyle> newStyle = styleForRenderer(NodeRenderingContext(this, 0));
1113         StyleChange ch = diff(currentStyle.get(), newStyle.get());
1114         if (ch == Detach || !currentStyle) {
1115             // FIXME: The style gets computed twice by calling attach. We could do better if we passed the style along.
1116             reattach();
1117             // attach recalulates the style for all children. No need to do it twice.
1118             clearNeedsStyleRecalc();
1119             clearChildNeedsStyleRecalc();
1120             return;
1121         }
1122
1123         if (currentStyle) {
1124             // Preserve "affected by" bits that were propagated to us from descendants in the case where we didn't do a full
1125             // style change (e.g., only inline style changed).
1126             if (currentStyle->affectedByHoverRules())
1127                 newStyle->setAffectedByHoverRules(true);
1128             if (currentStyle->affectedByActiveRules())
1129                 newStyle->setAffectedByActiveRules(true);
1130             if (currentStyle->affectedByDragRules())
1131                 newStyle->setAffectedByDragRules(true);
1132             if (currentStyle->childrenAffectedByForwardPositionalRules())
1133                 newStyle->setChildrenAffectedByForwardPositionalRules();
1134             if (currentStyle->childrenAffectedByBackwardPositionalRules())
1135                 newStyle->setChildrenAffectedByBackwardPositionalRules();
1136             if (currentStyle->childrenAffectedByFirstChildRules())
1137                 newStyle->setChildrenAffectedByFirstChildRules();
1138             if (currentStyle->childrenAffectedByLastChildRules())
1139                 newStyle->setChildrenAffectedByLastChildRules();
1140             if (currentStyle->childrenAffectedByDirectAdjacentRules())
1141                 newStyle->setChildrenAffectedByDirectAdjacentRules();
1142         }
1143
1144         if (ch != NoChange || pseudoStyleCacheIsInvalid(currentStyle.get(), newStyle.get()) || (change == Force && renderer() && renderer()->requiresForcedStyleRecalcPropagation())) {
1145             setRenderStyle(newStyle);
1146         } else if (needsStyleRecalc() && styleChangeType() != SyntheticStyleChange) {
1147             // Although no change occurred, we use the new style so that the cousin style sharing code won't get
1148             // fooled into believing this style is the same.
1149             if (renderer())
1150                 renderer()->setStyleInternal(newStyle.get());
1151             else
1152                 setRenderStyle(newStyle);
1153         } else if (styleChangeType() == SyntheticStyleChange)
1154              setRenderStyle(newStyle);
1155
1156         if (change != Force) {
1157             // 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
1158             // 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).
1159             if (document()->usesRemUnits() && ch != NoChange && currentStyle && newStyle && currentStyle->fontSize() != newStyle->fontSize() && document()->documentElement() == this)
1160                 change = Force;
1161             else if (styleChangeType() >= FullStyleChange)
1162                 change = Force;
1163             else
1164                 change = ch;
1165         }
1166     }
1167     StyleSelectorParentPusher parentPusher(this);
1168     // FIXME: This check is good enough for :hover + foo, but it is not good enough for :hover + foo + bar.
1169     // For now we will just worry about the common case, since it's a lot trickier to get the second case right
1170     // without doing way too much re-resolution.
1171     bool forceCheckOfNextElementSibling = false;
1172     bool forceCheckOfAnyElementSibling = false;
1173     for (Node *n = firstChild(); n; n = n->nextSibling()) {
1174         bool childRulesChanged = n->needsStyleRecalc() && n->styleChangeType() == FullStyleChange;
1175         if ((forceCheckOfNextElementSibling || forceCheckOfAnyElementSibling) && n->isElementNode())
1176             n->setNeedsStyleRecalc();
1177         if (change >= Inherit || n->isTextNode() || n->childNeedsStyleRecalc() || n->needsStyleRecalc()) {
1178             parentPusher.push();
1179             n->recalcStyle(change);
1180         }
1181         if (n->isElementNode()) {
1182             forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentRules;
1183             forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules);
1184         }
1185     }
1186     // FIXME: This does not care about sibling combinators. Will be necessary in XBL2 world.
1187     if (ShadowRoot* shadow = shadowRoot()) {
1188         if (change >= Inherit || shadow->childNeedsStyleRecalc() || shadow->needsStyleRecalc()) {
1189             parentPusher.push();
1190             shadow->recalcStyle(change);
1191         }
1192     }
1193
1194     clearNeedsStyleRecalc();
1195     clearChildNeedsStyleRecalc();
1196 }
1197
1198 ShadowRoot* Element::shadowRoot() const
1199 {
1200     return hasRareData() ? rareData()->m_shadowRoot : 0;
1201 }
1202
1203 static bool validateShadowRoot(Document* document, ShadowRoot* shadowRoot, ExceptionCode& ec)
1204 {
1205     if (!shadowRoot)
1206         return true;
1207
1208     if (shadowRoot->shadowHost()) {
1209         ec = HIERARCHY_REQUEST_ERR;
1210         return false;
1211     }
1212
1213     if (shadowRoot->document() != document) {
1214         ec = WRONG_DOCUMENT_ERR;
1215         return false;
1216     }
1217
1218     return true;
1219 }
1220
1221 void Element::setShadowRoot(PassRefPtr<ShadowRoot> prpShadowRoot, ExceptionCode& ec)
1222 {
1223     RefPtr<ShadowRoot> shadowRoot = prpShadowRoot;
1224     if (!validateShadowRoot(document(), shadowRoot.get(), ec))
1225         return;
1226
1227     removeShadowRoot();
1228
1229     ensureRareData()->m_shadowRoot = shadowRoot.get();
1230     shadowRoot->setShadowHost(this);
1231     if (inDocument())
1232         shadowRoot->insertedIntoDocument();
1233     if (attached())
1234         shadowRoot->lazyAttach();
1235 }
1236
1237 ShadowRoot* Element::ensureShadowRoot()
1238 {
1239     if (ShadowRoot* existingRoot = shadowRoot())
1240         return existingRoot;
1241
1242     ExceptionCode ec = 0;
1243     setShadowRoot(ShadowRoot::create(document()), ec);
1244     ASSERT(!ec);
1245     return shadowRoot();
1246 }
1247
1248 void Element::removeShadowRoot()
1249 {
1250     if (!hasRareData())
1251         return;
1252
1253     ElementRareData* data = rareData();
1254     if (RefPtr<ShadowRoot> oldRoot = data->m_shadowRoot) {
1255         data->m_shadowRoot = 0;
1256         document()->removeFocusedNodeOfSubtree(oldRoot.get());
1257
1258         // Remove from rendering tree
1259         if (oldRoot->attached())
1260             oldRoot->detach();
1261
1262         oldRoot->setShadowHost(0);
1263
1264         if (oldRoot->inDocument())
1265             oldRoot->removedFromDocument();
1266         else
1267             oldRoot->removedFromTree(true);
1268     }
1269 }
1270
1271 const AtomicString& Element::shadowPseudoId() const
1272 {
1273     return hasRareData() ? rareData()->m_shadowPseudoId : nullAtom;
1274 }
1275
1276 void Element::setShadowPseudoId(const AtomicString& id, ExceptionCode& ec)
1277 {
1278     if (!hasRareData() && id == nullAtom)
1279         return;
1280
1281     if (!CSSSelector::isUnknownPseudoType(id)) {
1282         ec = SYNTAX_ERR;
1283         return;
1284     }
1285
1286     ensureRareData()->m_shadowPseudoId = id;
1287 }
1288
1289 bool Element::childTypeAllowed(NodeType type) const
1290 {
1291     switch (type) {
1292     case ELEMENT_NODE:
1293     case TEXT_NODE:
1294     case COMMENT_NODE:
1295     case PROCESSING_INSTRUCTION_NODE:
1296     case CDATA_SECTION_NODE:
1297     case ENTITY_REFERENCE_NODE:
1298         return true;
1299     default:
1300         break;
1301     }
1302     return false;
1303 }
1304
1305 static void checkForEmptyStyleChange(Element* element, RenderStyle* style)
1306 {
1307     if (!style && !element->styleAffectedByEmpty())
1308         return;
1309
1310     if (!style || (style->affectedByEmpty() && (!style->emptyState() || element->hasChildNodes())))
1311         element->setNeedsStyleRecalc();
1312 }
1313
1314 static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool finishedParsingCallback,
1315                                         Node* beforeChange, Node* afterChange, int childCountDelta)
1316 {
1317     if (!style || (e->needsStyleRecalc() && style->childrenAffectedByPositionalRules()))
1318         return;
1319
1320     // :first-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     // |afterChange| is 0 in the parser case, so it works out that we'll skip this block.
1323     if (style->childrenAffectedByFirstChildRules() && afterChange) {
1324         // Find our new first child.
1325         Node* newFirstChild = 0;
1326         for (newFirstChild = e->firstChild(); newFirstChild && !newFirstChild->isElementNode(); newFirstChild = newFirstChild->nextSibling()) {};
1327         
1328         // Find the first element node following |afterChange|
1329         Node* firstElementAfterInsertion = 0;
1330         for (firstElementAfterInsertion = afterChange;
1331              firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode();
1332              firstElementAfterInsertion = firstElementAfterInsertion->nextSibling()) {};
1333         
1334         // This is the insert/append case.
1335         if (newFirstChild != firstElementAfterInsertion && firstElementAfterInsertion && firstElementAfterInsertion->attached() &&
1336             firstElementAfterInsertion->renderStyle() && firstElementAfterInsertion->renderStyle()->firstChildState())
1337             firstElementAfterInsertion->setNeedsStyleRecalc();
1338             
1339         // We also have to handle node removal.
1340         if (childCountDelta < 0 && newFirstChild == firstElementAfterInsertion && newFirstChild && newFirstChild->renderStyle() && !newFirstChild->renderStyle()->firstChildState())
1341             newFirstChild->setNeedsStyleRecalc();
1342     }
1343
1344     // :last-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
1345     // In the DOM case, we only need to do something if |afterChange| is not 0.
1346     if (style->childrenAffectedByLastChildRules() && beforeChange) {
1347         // Find our new last child.
1348         Node* newLastChild = 0;
1349         for (newLastChild = e->lastChild(); newLastChild && !newLastChild->isElementNode(); newLastChild = newLastChild->previousSibling()) {};
1350         
1351         // Find the last element node going backwards from |beforeChange|
1352         Node* lastElementBeforeInsertion = 0;
1353         for (lastElementBeforeInsertion = beforeChange;
1354              lastElementBeforeInsertion && !lastElementBeforeInsertion->isElementNode();
1355              lastElementBeforeInsertion = lastElementBeforeInsertion->previousSibling()) {};
1356         
1357         if (newLastChild != lastElementBeforeInsertion && lastElementBeforeInsertion && lastElementBeforeInsertion->attached() &&
1358             lastElementBeforeInsertion->renderStyle() && lastElementBeforeInsertion->renderStyle()->lastChildState())
1359             lastElementBeforeInsertion->setNeedsStyleRecalc();
1360             
1361         // 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
1362         // to match now.
1363         if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild == lastElementBeforeInsertion && newLastChild && newLastChild->renderStyle() && !newLastChild->renderStyle()->lastChildState())
1364             newLastChild->setNeedsStyleRecalc();
1365     }
1366
1367     // The + selector.  We need to invalidate the first element following the insertion point.  It is the only possible element
1368     // that could be affected by this DOM change.
1369     if (style->childrenAffectedByDirectAdjacentRules() && afterChange) {
1370         Node* firstElementAfterInsertion = 0;
1371         for (firstElementAfterInsertion = afterChange;
1372              firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode();
1373              firstElementAfterInsertion = firstElementAfterInsertion->nextSibling()) {};
1374         if (firstElementAfterInsertion && firstElementAfterInsertion->attached())
1375             firstElementAfterInsertion->setNeedsStyleRecalc();
1376     }
1377
1378     // Forward positional selectors include the ~ selector, nth-child, nth-of-type, first-of-type and only-of-type.
1379     // Backward positional selectors include nth-last-child, nth-last-of-type, last-of-type and only-of-type.
1380     // We have to invalidate everything following the insertion point in the forward case, and everything before the insertion point in the
1381     // backward case.
1382     // |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.
1383     // 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
1384     // here.  recalcStyle will then force a walk of the children when it sees that this has happened.
1385     if ((style->childrenAffectedByForwardPositionalRules() && afterChange) ||
1386         (style->childrenAffectedByBackwardPositionalRules() && beforeChange))
1387         e->setNeedsStyleRecalc();
1388     
1389     // :empty selector.
1390     checkForEmptyStyleChange(e, style);
1391 }
1392
1393 void Element::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
1394 {
1395     ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
1396     if (changedByParser)
1397         checkForEmptyStyleChange(this, renderStyle());
1398     else
1399         checkForSiblingStyleChanges(this, renderStyle(), false, beforeChange, afterChange, childCountDelta);
1400 }
1401
1402 void Element::beginParsingChildren()
1403 {
1404     clearIsParsingChildrenFinished();
1405     CSSStyleSelector* styleSelector = document()->styleSelectorIfExists();
1406     if (styleSelector && attached())
1407         styleSelector->pushParent(this);
1408 }
1409
1410 void Element::finishParsingChildren()
1411 {
1412     ContainerNode::finishParsingChildren();
1413     setIsParsingChildrenFinished();
1414     checkForSiblingStyleChanges(this, renderStyle(), true, lastChild(), 0, 0);
1415     if (CSSStyleSelector* styleSelector = document()->styleSelectorIfExists())
1416         styleSelector->popParent(this);
1417 }
1418
1419 void Element::dispatchAttrRemovalEvent(Attribute*)
1420 {
1421     ASSERT(!eventDispatchForbidden());
1422
1423 #if 0
1424     if (!document()->hasListenerType(Document::DOMATTRMODIFIED_LISTENER))
1425         return;
1426     ExceptionCode ec = 0;
1427     dispatchScopedEvent(MutationEvent::create(DOMAttrModifiedEvent, true, attr, attr->value(),
1428         attr->value(), document()->attrName(attr->id()), MutationEvent::REMOVAL), ec);
1429 #endif
1430 }
1431
1432 void Element::dispatchAttrAdditionEvent(Attribute*)
1433 {
1434     ASSERT(!eventDispatchForbidden());
1435
1436 #if 0
1437     if (!document()->hasListenerType(Document::DOMATTRMODIFIED_LISTENER))
1438         return;
1439     ExceptionCode ec = 0;
1440     dispatchScopedEvent(MutationEvent::create(DOMAttrModifiedEvent, true, attr, attr->value(),
1441         attr->value(), document()->attrName(attr->id()), MutationEvent::ADDITION), ec);
1442 #endif
1443 }
1444
1445 String Element::openTagStartToString() const
1446 {
1447     String result = "<" + nodeName();
1448
1449     NamedNodeMap* attrMap = attributes(true);
1450
1451     if (attrMap) {
1452         unsigned numAttrs = attrMap->length();
1453         for (unsigned i = 0; i < numAttrs; i++) {
1454             result += " ";
1455
1456             Attribute *attribute = attrMap->attributeItem(i);
1457             result += attribute->name().toString();
1458             if (!attribute->value().isNull()) {
1459                 result += "=\"";
1460                 // FIXME: substitute entities for any instances of " or '
1461                 result += attribute->value();
1462                 result += "\"";
1463             }
1464         }
1465     }
1466
1467     return result;
1468 }
1469
1470 #ifndef NDEBUG
1471 void Element::formatForDebugger(char* buffer, unsigned length) const
1472 {
1473     String result;
1474     String s;
1475     
1476     s = nodeName();
1477     if (s.length() > 0) {
1478         result += s;
1479     }
1480           
1481     s = getIdAttribute();
1482     if (s.length() > 0) {
1483         if (result.length() > 0)
1484             result += "; ";
1485         result += "id=";
1486         result += s;
1487     }
1488           
1489     s = getAttribute(classAttr);
1490     if (s.length() > 0) {
1491         if (result.length() > 0)
1492             result += "; ";
1493         result += "class=";
1494         result += s;
1495     }
1496           
1497     strncpy(buffer, result.utf8().data(), length - 1);
1498 }
1499 #endif
1500
1501 PassRefPtr<Attr> Element::setAttributeNode(Attr* attr, ExceptionCode& ec)
1502 {
1503     if (!attr) {
1504         ec = TYPE_MISMATCH_ERR;
1505         return 0;
1506     }
1507     return static_pointer_cast<Attr>(attributes(false)->setNamedItem(attr, ec));
1508 }
1509
1510 PassRefPtr<Attr> Element::setAttributeNodeNS(Attr* attr, ExceptionCode& ec)
1511 {
1512     if (!attr) {
1513         ec = TYPE_MISMATCH_ERR;
1514         return 0;
1515     }
1516     return static_pointer_cast<Attr>(attributes(false)->setNamedItem(attr, ec));
1517 }
1518
1519 PassRefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionCode& ec)
1520 {
1521     if (!attr) {
1522         ec = TYPE_MISMATCH_ERR;
1523         return 0;
1524     }
1525     if (attr->ownerElement() != this) {
1526         ec = NOT_FOUND_ERR;
1527         return 0;
1528     }
1529
1530     ASSERT(document() == attr->document());
1531
1532     NamedNodeMap* attrs = attributes(true);
1533     if (!attrs)
1534         return 0;
1535
1536     return static_pointer_cast<Attr>(attrs->removeNamedItem(attr->qualifiedName(), ec));
1537 }
1538
1539 void Element::setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode& ec, FragmentScriptingPermission scriptingPermission)
1540 {
1541     String prefix, localName;
1542     if (!Document::parseQualifiedName(qualifiedName, prefix, localName, ec))
1543         return;
1544
1545     if (namespaceURI.isNull() && !prefix.isNull()) {
1546         ec = NAMESPACE_ERR;
1547         return;
1548     }
1549
1550     QualifiedName qName(prefix, localName, namespaceURI);
1551
1552     if (scriptingPermission == FragmentScriptingNotAllowed && (isEventHandlerAttribute(qName) || isAttributeToRemove(qName, value)))
1553         return;
1554
1555     setAttribute(qName, value, ec);
1556 }
1557
1558 void Element::removeAttribute(const String& name, ExceptionCode& ec)
1559 {
1560     InspectorInstrumentation::willModifyDOMAttr(document(), this);
1561
1562     String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
1563
1564     if (m_attributeMap) {
1565         m_attributeMap->removeNamedItem(localName, ec);
1566         if (ec == NOT_FOUND_ERR)
1567             ec = 0;
1568     }
1569     
1570     InspectorInstrumentation::didModifyDOMAttr(document(), this);
1571 }
1572
1573 void Element::removeAttributeNS(const String& namespaceURI, const String& localName, ExceptionCode& ec)
1574 {
1575     removeAttribute(QualifiedName(nullAtom, localName, namespaceURI), ec);
1576 }
1577
1578 PassRefPtr<Attr> Element::getAttributeNode(const String& name)
1579 {
1580     NamedNodeMap* attrs = attributes(true);
1581     if (!attrs)
1582         return 0;
1583     String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
1584     return static_pointer_cast<Attr>(attrs->getNamedItem(localName));
1585 }
1586
1587 PassRefPtr<Attr> Element::getAttributeNodeNS(const String& namespaceURI, const String& localName)
1588 {
1589     NamedNodeMap* attrs = attributes(true);
1590     if (!attrs)
1591         return 0;
1592     return static_pointer_cast<Attr>(attrs->getNamedItem(QualifiedName(nullAtom, localName, namespaceURI)));
1593 }
1594
1595 bool Element::hasAttribute(const String& name) const
1596 {
1597     NamedNodeMap* attrs = attributes(true);
1598     if (!attrs)
1599         return false;
1600
1601     // This call to String::lower() seems to be required but
1602     // there may be a way to remove it.
1603     String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
1604     return attrs->getAttributeItem(localName, false);
1605 }
1606
1607 bool Element::hasAttributeNS(const String& namespaceURI, const String& localName) const
1608 {
1609     NamedNodeMap* attrs = attributes(true);
1610     if (!attrs)
1611         return false;
1612     return attrs->getAttributeItem(QualifiedName(nullAtom, localName, namespaceURI));
1613 }
1614
1615 CSSStyleDeclaration *Element::style()
1616 {
1617     return 0;
1618 }
1619
1620 void Element::focus(bool restorePreviousSelection)
1621 {
1622     if (!inDocument())
1623         return;
1624
1625     Document* doc = document();
1626     if (doc->focusedNode() == this)
1627         return;
1628
1629     // If the stylesheets have already been loaded we can reliably check isFocusable.
1630     // If not, we continue and set the focused node on the focus controller below so
1631     // that it can be updated soon after attach. 
1632     if (doc->haveStylesheetsLoaded()) {
1633         doc->updateLayoutIgnorePendingStylesheets();
1634         if (!isFocusable())
1635             return;
1636     }
1637
1638     if (!supportsFocus())
1639         return;
1640
1641     RefPtr<Node> protect;
1642     if (Page* page = doc->page()) {
1643         // Focus and change event handlers can cause us to lose our last ref.
1644         // If a focus event handler changes the focus to a different node it
1645         // does not make sense to continue and update appearence.
1646         protect = this;
1647         if (shadowRoot() && page->focusController()->transferFocusToElementInShadowRoot(this, restorePreviousSelection))
1648             return;
1649         if (!page->focusController()->setFocusedNode(this, doc->frame()))
1650             return;
1651     }
1652
1653     // Setting the focused node above might have invalidated the layout due to scripts.
1654     doc->updateLayoutIgnorePendingStylesheets();
1655
1656     if (!isFocusable()) {
1657         ensureRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(true);
1658         return;
1659     }
1660         
1661     cancelFocusAppearanceUpdate();
1662     updateFocusAppearance(restorePreviousSelection);
1663 }
1664
1665 void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
1666 {
1667     if (this == rootEditableElement()) { 
1668         Frame* frame = document()->frame();
1669         if (!frame)
1670             return;
1671         
1672         // When focusing an editable element in an iframe, don't reset the selection if it already contains a selection.
1673         if (this == frame->selection()->rootEditableElement())
1674             return;
1675
1676         // FIXME: We should restore the previous selection if there is one.
1677         VisibleSelection newSelection = VisibleSelection(firstPositionInOrBeforeNode(this), DOWNSTREAM);
1678         
1679         if (frame->selection()->shouldChangeSelection(newSelection)) {
1680             frame->selection()->setSelection(newSelection);
1681             frame->selection()->revealSelection();
1682         }
1683     } else if (renderer() && !renderer()->isWidget())
1684         renderer()->enclosingLayer()->scrollRectToVisible(getRect());
1685 }
1686
1687 void Element::blur()
1688 {
1689     cancelFocusAppearanceUpdate();
1690     Document* doc = document();
1691     if (doc->focusedNode() == this) {
1692         if (doc->frame())
1693             doc->frame()->page()->focusController()->setFocusedNode(0, doc->frame());
1694         else
1695             doc->setFocusedNode(0);
1696     }
1697 }
1698
1699 String Element::innerText() const
1700 {
1701     // We need to update layout, since plainText uses line boxes in the render tree.
1702     document()->updateLayoutIgnorePendingStylesheets();
1703
1704     if (!renderer())
1705         return textContent(true);
1706
1707     return plainText(rangeOfContents(const_cast<Element*>(this)).get());
1708 }
1709
1710 String Element::outerText() const
1711 {
1712     // Getting outerText is the same as getting innerText, only
1713     // setting is different. You would think this should get the plain
1714     // text for the outer range, but this is wrong, <br> for instance
1715     // would return different values for inner and outer text by such
1716     // a rule, but it doesn't in WinIE, and we want to match that.
1717     return innerText();
1718 }
1719
1720 String Element::title() const
1721 {
1722     return String();
1723 }
1724
1725 IntSize Element::minimumSizeForResizing() const
1726 {
1727     return hasRareData() ? rareData()->m_minimumSizeForResizing : defaultMinimumSizeForResizing();
1728 }
1729
1730 void Element::setMinimumSizeForResizing(const IntSize& size)
1731 {
1732     if (size == defaultMinimumSizeForResizing() && !hasRareData())
1733         return;
1734     ensureRareData()->m_minimumSizeForResizing = size;
1735 }
1736
1737 RenderStyle* Element::computedStyle(PseudoId pseudoElementSpecifier)
1738 {
1739     // FIXME: Find and use the renderer from the pseudo element instead of the actual element so that the 'length'
1740     // properties, which are only known by the renderer because it did the layout, will be correct and so that the
1741     // values returned for the ":selection" pseudo-element will be correct.
1742     if (RenderStyle* usedStyle = renderStyle())
1743         return pseudoElementSpecifier ? usedStyle->getCachedPseudoStyle(pseudoElementSpecifier) : usedStyle;
1744
1745     if (!attached())
1746         // FIXME: Try to do better than this. Ensure that styleForElement() works for elements that are not in the
1747         // document tree and figure out when to destroy the computed style for such elements.
1748         return 0;
1749
1750     ElementRareData* data = ensureRareData();
1751     if (!data->m_computedStyle)
1752         data->m_computedStyle = document()->styleForElementIgnoringPendingStylesheets(this);
1753     return pseudoElementSpecifier ? data->m_computedStyle->getCachedPseudoStyle(pseudoElementSpecifier) : data->m_computedStyle.get();
1754 }
1755
1756 void Element::setStyleAffectedByEmpty()
1757 {
1758     ElementRareData* data = ensureRareData();
1759     data->m_styleAffectedByEmpty = true;
1760 }
1761
1762 bool Element::styleAffectedByEmpty() const
1763 {
1764     return hasRareData() && rareData()->m_styleAffectedByEmpty;
1765 }
1766
1767 AtomicString Element::computeInheritedLanguage() const
1768 {
1769     const Node* n = this;
1770     AtomicString value;
1771     // The language property is inherited, so we iterate over the parents to find the first language.
1772     while (n && value.isNull()) {
1773         if (n->isElementNode()) {
1774             // Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7
1775             value = static_cast<const Element*>(n)->fastGetAttribute(XMLNames::langAttr);
1776             if (value.isNull())
1777                 value = static_cast<const Element*>(n)->fastGetAttribute(HTMLNames::langAttr);
1778         } else if (n->isDocumentNode()) {
1779             // checking the MIME content-language
1780             value = static_cast<const Document*>(n)->contentLanguage();
1781         }
1782
1783         n = n->parentNode();
1784     }
1785
1786     return value;
1787 }
1788
1789 void Element::cancelFocusAppearanceUpdate()
1790 {
1791     if (hasRareData())
1792         rareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
1793     if (document()->focusedNode() == this)
1794         document()->cancelFocusAppearanceUpdate();
1795 }
1796
1797 void Element::normalizeAttributes()
1798 {
1799     // Normalize attributes.
1800     NamedNodeMap* attrs = attributes(true);
1801     if (!attrs)
1802         return;
1803
1804     if (attrs->isEmpty())
1805         return;
1806
1807     Vector<RefPtr<Attribute> > attributeVector;
1808     attrs->copyAttributesToVector(attributeVector);
1809     size_t numAttrs = attributeVector.size();
1810     for (size_t i = 0; i < numAttrs; ++i) {
1811         if (Attr* attr = attributeVector[i]->attr())
1812             attr->normalize();
1813     }
1814 }
1815
1816 // ElementTraversal API
1817 Element* Element::firstElementChild() const
1818 {
1819     return WebCore::firstElementChild(this);
1820 }
1821
1822 Element* Element::lastElementChild() const
1823 {
1824     Node* n = lastChild();
1825     while (n && !n->isElementNode())
1826         n = n->previousSibling();
1827     return static_cast<Element*>(n);
1828 }
1829
1830 Element* Element::previousElementSibling() const
1831 {
1832     Node* n = previousSibling();
1833     while (n && !n->isElementNode())
1834         n = n->previousSibling();
1835     return static_cast<Element*>(n);
1836 }
1837
1838 Element* Element::nextElementSibling() const
1839 {
1840     Node* n = nextSibling();
1841     while (n && !n->isElementNode())
1842         n = n->nextSibling();
1843     return static_cast<Element*>(n);
1844 }
1845
1846 unsigned Element::childElementCount() const
1847 {
1848     unsigned count = 0;
1849     Node* n = firstChild();
1850     while (n) {
1851         count += n->isElementNode();
1852         n = n->nextSibling();
1853     }
1854     return count;
1855 }
1856
1857 bool Element::webkitMatchesSelector(const String& selector, ExceptionCode& ec)
1858 {
1859     if (selector.isEmpty()) {
1860         ec = SYNTAX_ERR;
1861         return false;
1862     }
1863
1864     bool strictParsing = !document()->inQuirksMode();
1865     CSSParser p(strictParsing);
1866
1867     CSSSelectorList selectorList;
1868     p.parseSelector(selector, document(), selectorList);
1869
1870     if (!selectorList.first()) {
1871         ec = SYNTAX_ERR;
1872         return false;
1873     }
1874
1875     // Throw a NAMESPACE_ERR if the selector includes any namespace prefixes.
1876     if (selectorList.selectorsNeedNamespaceResolution()) {
1877         ec = NAMESPACE_ERR;
1878         return false;
1879     }
1880
1881     CSSStyleSelector::SelectorChecker selectorChecker(document(), strictParsing);
1882     for (CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector)) {
1883         if (selectorChecker.checkSelector(selector, this))
1884             return true;
1885     }
1886
1887     return false;
1888 }
1889
1890 DOMTokenList* Element::classList()
1891 {
1892     ElementRareData* data = ensureRareData();
1893     if (!data->m_classList)
1894         data->m_classList = ClassList::create(this);
1895     return data->m_classList.get();
1896 }
1897
1898 DOMTokenList* Element::optionalClassList() const
1899 {
1900     if (!hasRareData())
1901         return 0;
1902     return rareData()->m_classList.get();
1903 }
1904
1905 DOMStringMap* Element::dataset()
1906 {
1907     ElementRareData* data = ensureRareData();
1908     if (!data->m_datasetDOMStringMap)
1909         data->m_datasetDOMStringMap = DatasetDOMStringMap::create(this);
1910     return data->m_datasetDOMStringMap.get();
1911 }
1912
1913 KURL Element::getURLAttribute(const QualifiedName& name) const
1914 {
1915 #if !ASSERT_DISABLED
1916     if (m_attributeMap) {
1917         if (Attribute* attribute = m_attributeMap->getAttributeItem(name))
1918             ASSERT(isURLAttribute(attribute));
1919     }
1920 #endif
1921     return document()->completeURL(stripLeadingAndTrailingHTMLSpaces(getAttribute(name)));
1922 }
1923
1924 KURL Element::getNonEmptyURLAttribute(const QualifiedName& name) const
1925 {
1926 #if !ASSERT_DISABLED
1927     if (m_attributeMap) {
1928         if (Attribute* attribute = m_attributeMap->getAttributeItem(name))
1929             ASSERT(isURLAttribute(attribute));
1930     }
1931 #endif
1932     String value = stripLeadingAndTrailingHTMLSpaces(getAttribute(name));
1933     if (value.isEmpty())
1934         return KURL();
1935     return document()->completeURL(value);
1936 }
1937
1938 int Element::getIntegralAttribute(const QualifiedName& attributeName) const
1939 {
1940     return getAttribute(attributeName).string().toInt();
1941 }
1942
1943 void Element::setIntegralAttribute(const QualifiedName& attributeName, int value)
1944 {
1945     // FIXME: Need an AtomicString version of String::number.
1946     ExceptionCode ec;
1947     setAttribute(attributeName, String::number(value), ec);
1948 }
1949
1950 unsigned Element::getUnsignedIntegralAttribute(const QualifiedName& attributeName) const
1951 {
1952     return getAttribute(attributeName).string().toUInt();
1953 }
1954
1955 void Element::setUnsignedIntegralAttribute(const QualifiedName& attributeName, unsigned value)
1956 {
1957     // FIXME: Need an AtomicString version of String::number.
1958     ExceptionCode ec;
1959     setAttribute(attributeName, String::number(value), ec);
1960 }
1961
1962 #if ENABLE(SVG)
1963 bool Element::childShouldCreateRenderer(Node* child) const
1964 {
1965     // Only create renderers for SVG elements whose parents are SVG elements, or for proper <svg xmlns="svgNS"> subdocuments.
1966     if (child->isSVGElement())
1967         return child->hasTagName(SVGNames::svgTag) || isSVGElement();
1968
1969     return Node::childShouldCreateRenderer(child);
1970 }
1971 #endif
1972     
1973 #if ENABLE(FULLSCREEN_API)
1974 void Element::webkitRequestFullScreen(unsigned short flags)
1975 {
1976     document()->requestFullScreenForElement(this, flags, Document::EnforceIFrameAllowFulScreenRequirement);
1977 }
1978
1979 bool Element::containsFullScreenElement() const
1980 {
1981     return hasRareData() ? rareData()->m_containsFullScreenElement : false;
1982 }
1983
1984 void Element::setContainsFullScreenElement(bool flag)
1985 {
1986     ensureRareData()->m_containsFullScreenElement = flag;
1987     setNeedsStyleRecalc(SyntheticStyleChange);
1988 }
1989
1990 static Element* parentCrossingFrameBoundaries(Element* element)
1991 {
1992     ASSERT(element);
1993     return element->parentElement() ? element->parentElement() : element->document()->ownerElement();
1994 }
1995
1996 void Element::setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(bool flag)
1997 {
1998     Element* element = this;
1999     while ((element = parentCrossingFrameBoundaries(element)))
2000         element->setContainsFullScreenElement(flag);
2001 }
2002 #endif    
2003
2004 SpellcheckAttributeState Element::spellcheckAttributeState() const
2005 {
2006     if (!hasAttribute(HTMLNames::spellcheckAttr))
2007         return SpellcheckAttributeDefault;
2008
2009     const AtomicString& value = getAttribute(HTMLNames::spellcheckAttr);
2010     if (equalIgnoringCase(value, "true") || equalIgnoringCase(value, ""))
2011         return SpellcheckAttributeTrue;
2012     if (equalIgnoringCase(value, "false"))
2013         return SpellcheckAttributeFalse;
2014
2015     return SpellcheckAttributeDefault;
2016 }
2017
2018 bool Element::isSpellCheckingEnabled() const
2019 {
2020     const Element* element = this;
2021     while (element) {
2022         switch (element->spellcheckAttributeState()) {
2023         case SpellcheckAttributeTrue:
2024             return true;
2025         case SpellcheckAttributeFalse:
2026             return false;
2027         case SpellcheckAttributeDefault:
2028             break;
2029         }
2030
2031         ContainerNode* parent = const_cast<Element*>(element)->parentOrHostNode();
2032         if (parent && parent->isElementNode())
2033             element = toElement(parent);
2034         else if (parent && parent->isShadowRoot())
2035             element = toElement(parent->parentOrHostNode());
2036         else
2037             element = 0;
2038     }
2039
2040     return true;
2041 }
2042
2043 PassRefPtr<WebKitAnimationList> Element::webkitGetAnimations() const
2044 {
2045     if (!renderer())
2046         return 0;
2047
2048     AnimationController* animController = renderer()->animation();
2049
2050     if (!animController)
2051         return 0;
2052     
2053     return animController->animationsForRenderer(renderer());
2054 }
2055
2056 } // namespace WebCore