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