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, 2012, 2013 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 "core/dom/Element.h"
     28 
     29 #include "CSSValueKeywords.h"
     30 #include "RuntimeEnabledFeatures.h"
     31 #include "SVGNames.h"
     32 #include "XMLNames.h"
     33 #include "bindings/v8/ExceptionState.h"
     34 #include "core/accessibility/AXObjectCache.h"
     35 #include "core/animation/DocumentTimeline.h"
     36 #include "core/animation/css/CSSAnimations.h"
     37 #include "core/css/CSSParser.h"
     38 #include "core/css/CSSStyleSheet.h"
     39 #include "core/css/CSSValuePool.h"
     40 #include "core/css/PropertySetCSSStyleDeclaration.h"
     41 #include "core/css/StylePropertySet.h"
     42 #include "core/css/resolver/StyleResolver.h"
     43 #include "core/dom/Attr.h"
     44 #include "core/dom/CSSSelectorWatch.h"
     45 #include "core/dom/ClientRect.h"
     46 #include "core/dom/ClientRectList.h"
     47 #include "core/dom/DatasetDOMStringMap.h"
     48 #include "core/dom/DocumentSharedObjectPool.h"
     49 #include "core/dom/ElementRareData.h"
     50 #include "core/dom/ExceptionCode.h"
     51 #include "core/dom/FullscreenElementStack.h"
     52 #include "core/dom/MutationObserverInterestGroup.h"
     53 #include "core/dom/MutationRecord.h"
     54 #include "core/dom/NamedNodeMap.h"
     55 #include "core/dom/NodeRenderStyle.h"
     56 #include "core/dom/NodeRenderingContext.h"
     57 #include "core/dom/PostAttachCallbacks.h"
     58 #include "core/dom/PresentationAttributeStyle.h"
     59 #include "core/dom/PseudoElement.h"
     60 #include "core/dom/ScriptableDocumentParser.h"
     61 #include "core/dom/SelectorQuery.h"
     62 #include "core/dom/Text.h"
     63 #include "core/dom/custom/CustomElement.h"
     64 #include "core/dom/custom/CustomElementRegistrationContext.h"
     65 #include "core/dom/shadow/InsertionPoint.h"
     66 #include "core/dom/shadow/ShadowRoot.h"
     67 #include "core/editing/FrameSelection.h"
     68 #include "core/editing/TextIterator.h"
     69 #include "core/editing/htmlediting.h"
     70 #include "core/editing/markup.h"
     71 #include "core/events/EventDispatcher.h"
     72 #include "core/events/FocusEvent.h"
     73 #include "core/frame/ContentSecurityPolicy.h"
     74 #include "core/frame/Frame.h"
     75 #include "core/frame/FrameView.h"
     76 #include "core/html/ClassList.h"
     77 #include "core/html/HTMLCollection.h"
     78 #include "core/html/HTMLDocument.h"
     79 #include "core/html/HTMLElement.h"
     80 #include "core/html/HTMLFormControlsCollection.h"
     81 #include "core/html/HTMLFrameOwnerElement.h"
     82 #include "core/html/HTMLLabelElement.h"
     83 #include "core/html/HTMLOptionsCollection.h"
     84 #include "core/html/HTMLTableRowsCollection.h"
     85 #include "core/html/HTMLTemplateElement.h"
     86 #include "core/html/parser/HTMLParserIdioms.h"
     87 #include "core/inspector/InspectorInstrumentation.h"
     88 #include "core/page/FocusController.h"
     89 #include "core/page/Page.h"
     90 #include "core/page/PointerLockController.h"
     91 #include "core/rendering/FlowThreadController.h"
     92 #include "core/rendering/RenderNamedFlowFragment.h"
     93 #include "core/rendering/RenderView.h"
     94 #include "core/rendering/RenderWidget.h"
     95 #include "core/svg/SVGDocumentExtensions.h"
     96 #include "core/svg/SVGElement.h"
     97 #include "wtf/BitVector.h"
     98 #include "wtf/HashFunctions.h"
     99 #include "wtf/text/CString.h"
    100 #include "wtf/text/TextPosition.h"
    101 
    102 namespace WebCore {
    103 
    104 using namespace HTMLNames;
    105 using namespace XMLNames;
    106 
    107 class StyleResolverParentPusher {
    108 public:
    109     explicit StyleResolverParentPusher(Element& parent)
    110         : m_parent(parent)
    111         , m_pushedStyleResolver(0)
    112     {
    113     }
    114     void push()
    115     {
    116         if (m_pushedStyleResolver)
    117             return;
    118         m_pushedStyleResolver = &m_parent.document().ensureStyleResolver();
    119         m_pushedStyleResolver->pushParentElement(m_parent);
    120     }
    121     ~StyleResolverParentPusher()
    122     {
    123 
    124         if (!m_pushedStyleResolver)
    125             return;
    126 
    127         // This tells us that our pushed style selector is in a bad state,
    128         // so we should just bail out in that scenario.
    129         ASSERT(m_pushedStyleResolver == m_parent.document().styleResolver());
    130         if (m_pushedStyleResolver != m_parent.document().styleResolver())
    131             return;
    132 
    133         m_pushedStyleResolver->popParentElement(m_parent);
    134     }
    135 
    136 private:
    137     Element& m_parent;
    138     StyleResolver* m_pushedStyleResolver;
    139 };
    140 
    141 typedef Vector<RefPtr<Attr> > AttrNodeList;
    142 typedef HashMap<Element*, OwnPtr<AttrNodeList> > AttrNodeListMap;
    143 
    144 static AttrNodeListMap& attrNodeListMap()
    145 {
    146     DEFINE_STATIC_LOCAL(AttrNodeListMap, map, ());
    147     return map;
    148 }
    149 
    150 static AttrNodeList* attrNodeListForElement(Element* element)
    151 {
    152     if (!element->hasSyntheticAttrChildNodes())
    153         return 0;
    154     ASSERT(attrNodeListMap().contains(element));
    155     return attrNodeListMap().get(element);
    156 }
    157 
    158 static AttrNodeList& ensureAttrNodeListForElement(Element* element)
    159 {
    160     if (element->hasSyntheticAttrChildNodes()) {
    161         ASSERT(attrNodeListMap().contains(element));
    162         return *attrNodeListMap().get(element);
    163     }
    164     ASSERT(!attrNodeListMap().contains(element));
    165     element->setHasSyntheticAttrChildNodes(true);
    166     AttrNodeListMap::AddResult result = attrNodeListMap().add(element, adoptPtr(new AttrNodeList));
    167     return *result.iterator->value;
    168 }
    169 
    170 static void removeAttrNodeListForElement(Element* element)
    171 {
    172     ASSERT(element->hasSyntheticAttrChildNodes());
    173     ASSERT(attrNodeListMap().contains(element));
    174     attrNodeListMap().remove(element);
    175     element->setHasSyntheticAttrChildNodes(false);
    176 }
    177 
    178 static Attr* findAttrNodeInList(const AttrNodeList& attrNodeList, const QualifiedName& name)
    179 {
    180     AttrNodeList::const_iterator end = attrNodeList.end();
    181     for (AttrNodeList::const_iterator it = attrNodeList.begin(); it != end; ++it) {
    182         if ((*it)->qualifiedName() == name)
    183             return it->get();
    184     }
    185     return 0;
    186 }
    187 
    188 PassRefPtr<Element> Element::create(const QualifiedName& tagName, Document* document)
    189 {
    190     return adoptRef(new Element(tagName, document, CreateElement));
    191 }
    192 
    193 Element::~Element()
    194 {
    195     // When the document is not destroyed, an element that was part of a named flow
    196     // content nodes should have been removed from the content nodes collection
    197     // and the inNamedFlow flag reset.
    198     ASSERT(!document().renderView() || !inNamedFlow());
    199 
    200     if (PropertySetCSSStyleDeclaration* cssomWrapper = inlineStyleCSSOMWrapper())
    201         cssomWrapper->clearParentElement();
    202 
    203     if (hasRareData()) {
    204         ElementRareData* data = elementRareData();
    205         data->setPseudoElement(BEFORE, 0);
    206         data->setPseudoElement(AFTER, 0);
    207         data->setPseudoElement(BACKDROP, 0);
    208         data->clearShadow();
    209 
    210         if (RuntimeEnabledFeatures::webAnimationsCSSEnabled()) {
    211             if (ActiveAnimations* activeAnimations = data->activeAnimations())
    212                 activeAnimations->cssAnimations().cancel();
    213         }
    214     }
    215 
    216     if (isCustomElement())
    217         CustomElement::wasDestroyed(this);
    218 
    219     if (hasSyntheticAttrChildNodes())
    220         detachAllAttrNodesFromElement();
    221 
    222     if (hasPendingResources()) {
    223         document().accessSVGExtensions()->removeElementFromPendingResources(this);
    224         ASSERT(!hasPendingResources());
    225     }
    226 }
    227 
    228 inline ElementRareData* Element::elementRareData() const
    229 {
    230     ASSERT(hasRareData());
    231     return static_cast<ElementRareData*>(rareData());
    232 }
    233 
    234 inline ElementRareData& Element::ensureElementRareData()
    235 {
    236     return static_cast<ElementRareData&>(ensureRareData());
    237 }
    238 
    239 void Element::clearTabIndexExplicitlyIfNeeded()
    240 {
    241     if (hasRareData())
    242         elementRareData()->clearTabIndexExplicitly();
    243 }
    244 
    245 void Element::setTabIndexExplicitly(short tabIndex)
    246 {
    247     ensureElementRareData().setTabIndexExplicitly(tabIndex);
    248 }
    249 
    250 bool Element::supportsFocus() const
    251 {
    252     return hasRareData() && elementRareData()->tabIndexSetExplicitly();
    253 }
    254 
    255 short Element::tabIndex() const
    256 {
    257     return hasRareData() ? elementRareData()->tabIndex() : 0;
    258 }
    259 
    260 bool Element::rendererIsFocusable() const
    261 {
    262     // Elements in canvas fallback content are not rendered, but they are allowed to be
    263     // focusable as long as their canvas is displayed and visible.
    264     if (isInCanvasSubtree()) {
    265         const Element* e = this;
    266         while (e && !e->hasLocalName(canvasTag))
    267             e = e->parentElement();
    268         ASSERT(e);
    269         return e->renderer() && e->renderer()->style()->visibility() == VISIBLE;
    270     }
    271 
    272     // FIXME: These asserts should be in Node::isFocusable, but there are some
    273     // callsites like Document::setFocusedElement that would currently fail on
    274     // them. See crbug.com/251163
    275     if (renderer()) {
    276         ASSERT(!renderer()->needsLayout());
    277     } else {
    278         // We can't just use needsStyleRecalc() because if the node is in a
    279         // display:none tree it might say it needs style recalc but the whole
    280         // document is actually up to date.
    281         ASSERT(!document().childNeedsStyleRecalc());
    282     }
    283 
    284     // FIXME: Even if we are not visible, we might have a child that is visible.
    285     // Hyatt wants to fix that some day with a "has visible content" flag or the like.
    286     if (!renderer() || renderer()->style()->visibility() != VISIBLE)
    287         return false;
    288 
    289     return true;
    290 }
    291 
    292 PassRefPtr<Node> Element::cloneNode(bool deep)
    293 {
    294     return deep ? cloneElementWithChildren() : cloneElementWithoutChildren();
    295 }
    296 
    297 PassRefPtr<Element> Element::cloneElementWithChildren()
    298 {
    299     RefPtr<Element> clone = cloneElementWithoutChildren();
    300     cloneChildNodes(clone.get());
    301     return clone.release();
    302 }
    303 
    304 PassRefPtr<Element> Element::cloneElementWithoutChildren()
    305 {
    306     RefPtr<Element> clone = cloneElementWithoutAttributesAndChildren();
    307     // This will catch HTML elements in the wrong namespace that are not correctly copied.
    308     // This is a sanity check as HTML overloads some of the DOM methods.
    309     ASSERT(isHTMLElement() == clone->isHTMLElement());
    310 
    311     clone->cloneDataFromElement(*this);
    312     return clone.release();
    313 }
    314 
    315 PassRefPtr<Element> Element::cloneElementWithoutAttributesAndChildren()
    316 {
    317     return document().createElement(tagQName(), false);
    318 }
    319 
    320 PassRefPtr<Attr> Element::detachAttribute(size_t index)
    321 {
    322     ASSERT(elementData());
    323     const Attribute* attribute = elementData()->attributeItem(index);
    324     RefPtr<Attr> attrNode = attrIfExists(attribute->name());
    325     if (attrNode)
    326         detachAttrNodeAtIndex(attrNode.get(), index);
    327     else {
    328         attrNode = Attr::create(document(), attribute->name(), attribute->value());
    329         removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
    330     }
    331     return attrNode.release();
    332 }
    333 
    334 void Element::detachAttrNodeAtIndex(Attr* attr, size_t index)
    335 {
    336     ASSERT(attr);
    337     ASSERT(elementData());
    338 
    339     const Attribute* attribute = elementData()->attributeItem(index);
    340     ASSERT(attribute);
    341     ASSERT(attribute->name() == attr->qualifiedName());
    342     detachAttrNodeFromElementWithValue(attr, attribute->value());
    343     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
    344 }
    345 
    346 void Element::removeAttribute(const QualifiedName& name)
    347 {
    348     if (!elementData())
    349         return;
    350 
    351     size_t index = elementData()->getAttributeItemIndex(name);
    352     if (index == kNotFound)
    353         return;
    354 
    355     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
    356 }
    357 
    358 void Element::setBooleanAttribute(const QualifiedName& name, bool value)
    359 {
    360     if (value)
    361         setAttribute(name, emptyAtom);
    362     else
    363         removeAttribute(name);
    364 }
    365 
    366 NamedNodeMap* Element::attributes() const
    367 {
    368     ElementRareData& rareData = const_cast<Element*>(this)->ensureElementRareData();
    369     if (NamedNodeMap* attributeMap = rareData.attributeMap())
    370         return attributeMap;
    371 
    372     rareData.setAttributeMap(NamedNodeMap::create(const_cast<Element*>(this)));
    373     return rareData.attributeMap();
    374 }
    375 
    376 ActiveAnimations* Element::activeAnimations() const
    377 {
    378     if (hasRareData())
    379         return elementRareData()->activeAnimations();
    380     return 0;
    381 }
    382 
    383 ActiveAnimations* Element::ensureActiveAnimations()
    384 {
    385     ElementRareData& rareData = ensureElementRareData();
    386     if (!rareData.activeAnimations())
    387         rareData.setActiveAnimations(adoptPtr(new ActiveAnimations()));
    388     return rareData.activeAnimations();
    389 }
    390 
    391 bool Element::hasActiveAnimations() const
    392 {
    393     if (!RuntimeEnabledFeatures::webAnimationsCSSEnabled())
    394         return false;
    395 
    396     if (!hasRareData())
    397         return false;
    398 
    399     ActiveAnimations* activeAnimations = elementRareData()->activeAnimations();
    400     return activeAnimations && !activeAnimations->isEmpty();
    401 }
    402 
    403 Node::NodeType Element::nodeType() const
    404 {
    405     return ELEMENT_NODE;
    406 }
    407 
    408 bool Element::hasAttribute(const QualifiedName& name) const
    409 {
    410     return hasAttributeNS(name.namespaceURI(), name.localName());
    411 }
    412 
    413 void Element::synchronizeAllAttributes() const
    414 {
    415     if (!elementData())
    416         return;
    417     if (elementData()->m_styleAttributeIsDirty) {
    418         ASSERT(isStyledElement());
    419         synchronizeStyleAttributeInternal();
    420     }
    421     if (elementData()->m_animatedSVGAttributesAreDirty) {
    422         ASSERT(isSVGElement());
    423         toSVGElement(this)->synchronizeAnimatedSVGAttribute(anyQName());
    424     }
    425 }
    426 
    427 inline void Element::synchronizeAttribute(const QualifiedName& name) const
    428 {
    429     if (!elementData())
    430         return;
    431     if (UNLIKELY(name == styleAttr && elementData()->m_styleAttributeIsDirty)) {
    432         ASSERT(isStyledElement());
    433         synchronizeStyleAttributeInternal();
    434         return;
    435     }
    436     if (UNLIKELY(elementData()->m_animatedSVGAttributesAreDirty)) {
    437         ASSERT(isSVGElement());
    438         toSVGElement(this)->synchronizeAnimatedSVGAttribute(name);
    439     }
    440 }
    441 
    442 void Element::synchronizeAttribute(const AtomicString& localName) const
    443 {
    444     // This version of synchronizeAttribute() is streamlined for the case where you don't have a full QualifiedName,
    445     // e.g when called from DOM API.
    446     if (!elementData())
    447         return;
    448     if (elementData()->m_styleAttributeIsDirty && equalPossiblyIgnoringCase(localName, styleAttr.localName(), shouldIgnoreAttributeCase())) {
    449         ASSERT(isStyledElement());
    450         synchronizeStyleAttributeInternal();
    451         return;
    452     }
    453     if (elementData()->m_animatedSVGAttributesAreDirty) {
    454         // We're not passing a namespace argument on purpose. SVGNames::*Attr are defined w/o namespaces as well.
    455         toSVGElement(this)->synchronizeAnimatedSVGAttribute(QualifiedName(nullAtom, localName, nullAtom));
    456     }
    457 }
    458 
    459 const AtomicString& Element::getAttribute(const QualifiedName& name) const
    460 {
    461     if (!elementData())
    462         return nullAtom;
    463     synchronizeAttribute(name);
    464     if (const Attribute* attribute = getAttributeItem(name))
    465         return attribute->value();
    466     return nullAtom;
    467 }
    468 
    469 void Element::scrollIntoView(bool alignToTop)
    470 {
    471     document().updateLayoutIgnorePendingStylesheets();
    472 
    473     if (!renderer())
    474         return;
    475 
    476     LayoutRect bounds = boundingBox();
    477     // Align to the top / bottom and to the closest edge.
    478     if (alignToTop)
    479         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
    480     else
    481         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignBottomAlways);
    482 }
    483 
    484 void Element::scrollIntoViewIfNeeded(bool centerIfNeeded)
    485 {
    486     document().updateLayoutIgnorePendingStylesheets();
    487 
    488     if (!renderer())
    489         return;
    490 
    491     LayoutRect bounds = boundingBox();
    492     if (centerIfNeeded)
    493         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignCenterIfNeeded, ScrollAlignment::alignCenterIfNeeded);
    494     else
    495         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
    496 }
    497 
    498 void Element::scrollByUnits(int units, ScrollGranularity granularity)
    499 {
    500     document().updateLayoutIgnorePendingStylesheets();
    501 
    502     if (!renderer())
    503         return;
    504 
    505     if (!renderer()->hasOverflowClip())
    506         return;
    507 
    508     ScrollDirection direction = ScrollDown;
    509     if (units < 0) {
    510         direction = ScrollUp;
    511         units = -units;
    512     }
    513     toRenderBox(renderer())->scroll(direction, granularity, units);
    514 }
    515 
    516 void Element::scrollByLines(int lines)
    517 {
    518     scrollByUnits(lines, ScrollByLine);
    519 }
    520 
    521 void Element::scrollByPages(int pages)
    522 {
    523     scrollByUnits(pages, ScrollByPage);
    524 }
    525 
    526 static float localZoomForRenderer(RenderObject& renderer)
    527 {
    528     // FIXME: This does the wrong thing if two opposing zooms are in effect and canceled each
    529     // other out, but the alternative is that we'd have to crawl up the whole render tree every
    530     // time (or store an additional bit in the RenderStyle to indicate that a zoom was specified).
    531     float zoomFactor = 1;
    532     if (renderer.style()->effectiveZoom() != 1) {
    533         // Need to find the nearest enclosing RenderObject that set up
    534         // a differing zoom, and then we divide our result by it to eliminate the zoom.
    535         RenderObject* prev = &renderer;
    536         for (RenderObject* curr = prev->parent(); curr; curr = curr->parent()) {
    537             if (curr->style()->effectiveZoom() != prev->style()->effectiveZoom()) {
    538                 zoomFactor = prev->style()->zoom();
    539                 break;
    540             }
    541             prev = curr;
    542         }
    543         if (prev->isRenderView())
    544             zoomFactor = prev->style()->zoom();
    545     }
    546     return zoomFactor;
    547 }
    548 
    549 static int adjustForLocalZoom(LayoutUnit value, RenderObject& renderer)
    550 {
    551     float zoomFactor = localZoomForRenderer(renderer);
    552     if (zoomFactor == 1)
    553         return value;
    554     return lroundf(value / zoomFactor);
    555 }
    556 
    557 int Element::offsetLeft()
    558 {
    559     document().partialUpdateLayoutIgnorePendingStylesheets(this);
    560     if (RenderBoxModelObject* renderer = renderBoxModelObject())
    561         return adjustForLocalZoom(renderer->pixelSnappedOffsetLeft(), *renderer);
    562     return 0;
    563 }
    564 
    565 int Element::offsetTop()
    566 {
    567     document().partialUpdateLayoutIgnorePendingStylesheets(this);
    568     if (RenderBoxModelObject* renderer = renderBoxModelObject())
    569         return adjustForLocalZoom(renderer->pixelSnappedOffsetTop(), *renderer);
    570     return 0;
    571 }
    572 
    573 int Element::offsetWidth()
    574 {
    575     document().updateStyleForNodeIfNeeded(this);
    576 
    577     if (RenderBox* renderer = renderBox()) {
    578         if (renderer->canDetermineWidthWithoutLayout())
    579             return adjustLayoutUnitForAbsoluteZoom(renderer->fixedOffsetWidth(), *renderer).round();
    580     }
    581 
    582     document().partialUpdateLayoutIgnorePendingStylesheets(this);
    583     if (RenderBoxModelObject* renderer = renderBoxModelObject())
    584         return adjustLayoutUnitForAbsoluteZoom(renderer->pixelSnappedOffsetWidth(), *renderer).round();
    585     return 0;
    586 }
    587 
    588 int Element::offsetHeight()
    589 {
    590     document().partialUpdateLayoutIgnorePendingStylesheets(this);
    591     if (RenderBoxModelObject* renderer = renderBoxModelObject())
    592         return adjustLayoutUnitForAbsoluteZoom(renderer->pixelSnappedOffsetHeight(), *renderer).round();
    593     return 0;
    594 }
    595 
    596 Element* Element::bindingsOffsetParent()
    597 {
    598     Element* element = offsetParent();
    599     if (!element || !element->isInShadowTree())
    600         return element;
    601     return element->containingShadowRoot()->shouldExposeToBindings() ? element : 0;
    602 }
    603 
    604 Element* Element::offsetParent()
    605 {
    606     document().updateLayoutIgnorePendingStylesheets();
    607     if (RenderObject* renderer = this->renderer())
    608         return renderer->offsetParent();
    609     return 0;
    610 }
    611 
    612 int Element::clientLeft()
    613 {
    614     document().updateLayoutIgnorePendingStylesheets();
    615 
    616     if (RenderBox* renderer = renderBox())
    617         return adjustForAbsoluteZoom(roundToInt(renderer->clientLeft()), renderer);
    618     return 0;
    619 }
    620 
    621 int Element::clientTop()
    622 {
    623     document().updateLayoutIgnorePendingStylesheets();
    624 
    625     if (RenderBox* renderer = renderBox())
    626         return adjustForAbsoluteZoom(roundToInt(renderer->clientTop()), renderer);
    627     return 0;
    628 }
    629 
    630 int Element::clientWidth()
    631 {
    632     document().updateLayoutIgnorePendingStylesheets();
    633 
    634     // When in strict mode, clientWidth for the document element should return the width of the containing frame.
    635     // When in quirks mode, clientWidth for the body element should return the width of the containing frame.
    636     bool inQuirksMode = document().inQuirksMode();
    637     if ((!inQuirksMode && document().documentElement() == this)
    638         || (inQuirksMode && isHTMLElement() && document().body() == this)) {
    639         if (FrameView* view = document().view()) {
    640             if (RenderView* renderView = document().renderView())
    641                 return adjustForAbsoluteZoom(view->layoutSize().width(), renderView);
    642         }
    643     }
    644 
    645     if (RenderBox* renderer = renderBox())
    646         return adjustLayoutUnitForAbsoluteZoom(renderer->pixelSnappedClientWidth(), *renderer).round();
    647     return 0;
    648 }
    649 
    650 int Element::clientHeight()
    651 {
    652     document().updateLayoutIgnorePendingStylesheets();
    653 
    654     // When in strict mode, clientHeight for the document element should return the height of the containing frame.
    655     // When in quirks mode, clientHeight for the body element should return the height of the containing frame.
    656     bool inQuirksMode = document().inQuirksMode();
    657 
    658     if ((!inQuirksMode && document().documentElement() == this)
    659         || (inQuirksMode && isHTMLElement() && document().body() == this)) {
    660         if (FrameView* view = document().view()) {
    661             if (RenderView* renderView = document().renderView())
    662                 return adjustForAbsoluteZoom(view->layoutSize().height(), renderView);
    663         }
    664     }
    665 
    666     if (RenderBox* renderer = renderBox())
    667         return adjustLayoutUnitForAbsoluteZoom(renderer->pixelSnappedClientHeight(), *renderer).round();
    668     return 0;
    669 }
    670 
    671 int Element::scrollLeft()
    672 {
    673     document().updateLayoutIgnorePendingStylesheets();
    674 
    675     if (document().documentElement() != this) {
    676         if (RenderBox* rend = renderBox())
    677             return adjustForAbsoluteZoom(rend->scrollLeft(), rend);
    678         return 0;
    679     }
    680 
    681     if (RuntimeEnabledFeatures::scrollTopLeftInteropEnabled()) {
    682         if (document().inQuirksMode())
    683             return 0;
    684 
    685         if (FrameView* view = document().view()) {
    686             if (RenderView* renderView = document().renderView())
    687                 return adjustForAbsoluteZoom(view->scrollX(), renderView);
    688         }
    689     }
    690 
    691     return 0;
    692 }
    693 
    694 int Element::scrollTop()
    695 {
    696     document().updateLayoutIgnorePendingStylesheets();
    697 
    698     if (document().documentElement() != this) {
    699         if (RenderBox* rend = renderBox())
    700             return adjustForAbsoluteZoom(rend->scrollTop(), rend);
    701         return 0;
    702     }
    703 
    704     if (RuntimeEnabledFeatures::scrollTopLeftInteropEnabled()) {
    705         if (document().inQuirksMode())
    706             return 0;
    707 
    708         if (FrameView* view = document().view()) {
    709             if (RenderView* renderView = document().renderView())
    710                 return adjustForAbsoluteZoom(view->scrollY(), renderView);
    711         }
    712     }
    713 
    714     return 0;
    715 }
    716 
    717 void Element::setScrollLeft(int newLeft)
    718 {
    719     document().updateLayoutIgnorePendingStylesheets();
    720 
    721     if (document().documentElement() != this) {
    722         if (RenderBox* rend = renderBox())
    723             rend->setScrollLeft(static_cast<int>(newLeft * rend->style()->effectiveZoom()));
    724         return;
    725     }
    726 
    727     if (RuntimeEnabledFeatures::scrollTopLeftInteropEnabled()) {
    728         if (document().inQuirksMode())
    729             return;
    730 
    731         Frame* frame = document().frame();
    732         if (!frame)
    733             return;
    734         FrameView* view = frame->view();
    735         if (!view)
    736             return;
    737 
    738         view->setScrollPosition(IntPoint(static_cast<int>(newLeft * frame->pageZoomFactor()), view->scrollY()));
    739     }
    740 }
    741 
    742 void Element::setScrollTop(int newTop)
    743 {
    744     document().updateLayoutIgnorePendingStylesheets();
    745 
    746     if (document().documentElement() != this) {
    747         if (RenderBox* rend = renderBox())
    748             rend->setScrollTop(static_cast<int>(newTop * rend->style()->effectiveZoom()));
    749         return;
    750     }
    751 
    752     if (RuntimeEnabledFeatures::scrollTopLeftInteropEnabled()) {
    753         if (document().inQuirksMode())
    754             return;
    755 
    756         Frame* frame = document().frame();
    757         if (!frame)
    758             return;
    759         FrameView* view = frame->view();
    760         if (!view)
    761             return;
    762 
    763         view->setScrollPosition(IntPoint(view->scrollX(), static_cast<int>(newTop * frame->pageZoomFactor())));
    764     }
    765 }
    766 
    767 int Element::scrollWidth()
    768 {
    769     document().updateLayoutIgnorePendingStylesheets();
    770     if (RenderBox* rend = renderBox())
    771         return adjustForAbsoluteZoom(rend->scrollWidth(), rend);
    772     return 0;
    773 }
    774 
    775 int Element::scrollHeight()
    776 {
    777     document().updateLayoutIgnorePendingStylesheets();
    778     if (RenderBox* rend = renderBox())
    779         return adjustForAbsoluteZoom(rend->scrollHeight(), rend);
    780     return 0;
    781 }
    782 
    783 IntRect Element::boundsInRootViewSpace()
    784 {
    785     document().updateLayoutIgnorePendingStylesheets();
    786 
    787     FrameView* view = document().view();
    788     if (!view)
    789         return IntRect();
    790 
    791     Vector<FloatQuad> quads;
    792     if (isSVGElement() && renderer()) {
    793         // Get the bounding rectangle from the SVG model.
    794         SVGElement* svgElement = toSVGElement(this);
    795         FloatRect localRect;
    796         if (svgElement->getBoundingBox(localRect))
    797             quads.append(renderer()->localToAbsoluteQuad(localRect));
    798     } else {
    799         // Get the bounding rectangle from the box model.
    800         if (renderBoxModelObject())
    801             renderBoxModelObject()->absoluteQuads(quads);
    802     }
    803 
    804     if (quads.isEmpty())
    805         return IntRect();
    806 
    807     IntRect result = quads[0].enclosingBoundingBox();
    808     for (size_t i = 1; i < quads.size(); ++i)
    809         result.unite(quads[i].enclosingBoundingBox());
    810 
    811     result = view->contentsToRootView(result);
    812     return result;
    813 }
    814 
    815 PassRefPtr<ClientRectList> Element::getClientRects()
    816 {
    817     document().updateLayoutIgnorePendingStylesheets();
    818 
    819     RenderBoxModelObject* renderBoxModelObject = this->renderBoxModelObject();
    820     if (!renderBoxModelObject)
    821         return ClientRectList::create();
    822 
    823     // FIXME: Handle SVG elements.
    824     // FIXME: Handle table/inline-table with a caption.
    825 
    826     Vector<FloatQuad> quads;
    827     renderBoxModelObject->absoluteQuads(quads);
    828     document().adjustFloatQuadsForScrollAndAbsoluteZoom(quads, *renderBoxModelObject);
    829     return ClientRectList::create(quads);
    830 }
    831 
    832 PassRefPtr<ClientRect> Element::getBoundingClientRect()
    833 {
    834     document().updateLayoutIgnorePendingStylesheets();
    835 
    836     Vector<FloatQuad> quads;
    837     if (isSVGElement() && renderer() && !renderer()->isSVGRoot()) {
    838         // Get the bounding rectangle from the SVG model.
    839         SVGElement* svgElement = toSVGElement(this);
    840         FloatRect localRect;
    841         if (svgElement->getBoundingBox(localRect))
    842             quads.append(renderer()->localToAbsoluteQuad(localRect));
    843     } else {
    844         // Get the bounding rectangle from the box model.
    845         if (renderBoxModelObject())
    846             renderBoxModelObject()->absoluteQuads(quads);
    847     }
    848 
    849     if (quads.isEmpty())
    850         return ClientRect::create();
    851 
    852     FloatRect result = quads[0].boundingBox();
    853     for (size_t i = 1; i < quads.size(); ++i)
    854         result.unite(quads[i].boundingBox());
    855 
    856     ASSERT(renderer());
    857     document().adjustFloatRectForScrollAndAbsoluteZoom(result, *renderer());
    858     return ClientRect::create(result);
    859 }
    860 
    861 IntRect Element::screenRect() const
    862 {
    863     if (!renderer())
    864         return IntRect();
    865     // FIXME: this should probably respect transforms
    866     return document().view()->contentsToScreen(renderer()->absoluteBoundingBoxRectIgnoringTransforms());
    867 }
    868 
    869 const AtomicString& Element::getAttribute(const AtomicString& localName) const
    870 {
    871     if (!elementData())
    872         return nullAtom;
    873     synchronizeAttribute(localName);
    874     if (const Attribute* attribute = elementData()->getAttributeItem(localName, shouldIgnoreAttributeCase()))
    875         return attribute->value();
    876     return nullAtom;
    877 }
    878 
    879 const AtomicString& Element::getAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const
    880 {
    881     return getAttribute(QualifiedName(nullAtom, localName, namespaceURI));
    882 }
    883 
    884 void Element::setAttribute(const AtomicString& localName, const AtomicString& value, ExceptionState& exceptionState)
    885 {
    886     if (!Document::isValidName(localName)) {
    887         exceptionState.throwUninformativeAndGenericDOMException(InvalidCharacterError);
    888         return;
    889     }
    890 
    891     synchronizeAttribute(localName);
    892     const AtomicString& caseAdjustedLocalName = shouldIgnoreAttributeCase() ? localName.lower() : localName;
    893 
    894     size_t index = elementData() ? elementData()->getAttributeItemIndex(caseAdjustedLocalName, false) : kNotFound;
    895     const QualifiedName& qName = index != kNotFound ? attributeItem(index)->name() : QualifiedName(nullAtom, caseAdjustedLocalName, nullAtom);
    896     setAttributeInternal(index, qName, value, NotInSynchronizationOfLazyAttribute);
    897 }
    898 
    899 void Element::setAttribute(const QualifiedName& name, const AtomicString& value)
    900 {
    901     synchronizeAttribute(name);
    902     size_t index = elementData() ? elementData()->getAttributeItemIndex(name) : kNotFound;
    903     setAttributeInternal(index, name, value, NotInSynchronizationOfLazyAttribute);
    904 }
    905 
    906 void Element::setSynchronizedLazyAttribute(const QualifiedName& name, const AtomicString& value)
    907 {
    908     size_t index = elementData() ? elementData()->getAttributeItemIndex(name) : kNotFound;
    909     setAttributeInternal(index, name, value, InSynchronizationOfLazyAttribute);
    910 }
    911 
    912 ALWAYS_INLINE void Element::setAttributeInternal(size_t index, const QualifiedName& name, const AtomicString& newValue, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
    913 {
    914     if (newValue.isNull()) {
    915         if (index != kNotFound)
    916             removeAttributeInternal(index, inSynchronizationOfLazyAttribute);
    917         return;
    918     }
    919 
    920     if (index == kNotFound) {
    921         addAttributeInternal(name, newValue, inSynchronizationOfLazyAttribute);
    922         return;
    923     }
    924 
    925     const Attribute* existingAttribute = attributeItem(index);
    926     QualifiedName existingAttributeName = existingAttribute->name();
    927 
    928     if (!inSynchronizationOfLazyAttribute)
    929         willModifyAttribute(existingAttributeName, existingAttribute->value(), newValue);
    930 
    931     if (newValue != existingAttribute->value()) {
    932         // If there is an Attr node hooked to this attribute, the Attr::setValue() call below
    933         // will write into the ElementData.
    934         // FIXME: Refactor this so it makes some sense.
    935         if (RefPtr<Attr> attrNode = inSynchronizationOfLazyAttribute ? 0 : attrIfExists(existingAttributeName))
    936             attrNode->setValue(newValue);
    937         else
    938             ensureUniqueElementData()->attributeItem(index)->setValue(newValue);
    939     }
    940 
    941     if (!inSynchronizationOfLazyAttribute)
    942         didModifyAttribute(existingAttributeName, newValue);
    943 }
    944 
    945 static inline AtomicString makeIdForStyleResolution(const AtomicString& value, bool inQuirksMode)
    946 {
    947     if (inQuirksMode)
    948         return value.lower();
    949     return value;
    950 }
    951 
    952 static bool checkNeedsStyleInvalidationForIdChange(const AtomicString& oldId, const AtomicString& newId, const RuleFeatureSet& features)
    953 {
    954     ASSERT(newId != oldId);
    955     if (!oldId.isEmpty() && features.hasSelectorForId(oldId))
    956         return true;
    957     if (!newId.isEmpty() && features.hasSelectorForId(newId))
    958         return true;
    959     return false;
    960 }
    961 
    962 void Element::attributeChanged(const QualifiedName& name, const AtomicString& newValue, AttributeModificationReason reason)
    963 {
    964     if (ElementShadow* parentElementShadow = shadowWhereNodeCanBeDistributed(*this)) {
    965         if (shouldInvalidateDistributionWhenAttributeChanged(parentElementShadow, name, newValue))
    966             parentElementShadow->setNeedsDistributionRecalc();
    967     }
    968 
    969     parseAttribute(name, newValue);
    970 
    971     document().incDOMTreeVersion();
    972 
    973     StyleResolver* styleResolver = document().styleResolver();
    974     bool testShouldInvalidateStyle = inActiveDocument() && styleResolver && styleChangeType() < SubtreeStyleChange;
    975     bool shouldInvalidateStyle = false;
    976 
    977     if (isStyledElement() && name == styleAttr) {
    978         styleAttributeChanged(newValue, reason);
    979     } else if (isStyledElement() && isPresentationAttribute(name)) {
    980         elementData()->m_presentationAttributeStyleIsDirty = true;
    981         setNeedsStyleRecalc(LocalStyleChange);
    982     }
    983 
    984     if (isIdAttributeName(name)) {
    985         AtomicString oldId = elementData()->idForStyleResolution();
    986         AtomicString newId = makeIdForStyleResolution(newValue, document().inQuirksMode());
    987         if (newId != oldId) {
    988             elementData()->setIdForStyleResolution(newId);
    989             shouldInvalidateStyle = testShouldInvalidateStyle && checkNeedsStyleInvalidationForIdChange(oldId, newId, styleResolver->ensureRuleFeatureSet());
    990         }
    991     } else if (name == classAttr) {
    992         classAttributeChanged(newValue);
    993     } else if (name == HTMLNames::nameAttr) {
    994         setHasName(!newValue.isNull());
    995     } else if (name == HTMLNames::pseudoAttr) {
    996         shouldInvalidateStyle |= testShouldInvalidateStyle && isInShadowTree();
    997     }
    998 
    999     invalidateNodeListCachesInAncestors(&name, this);
   1000 
   1001     // If there is currently no StyleResolver, we can't be sure that this attribute change won't affect style.
   1002     shouldInvalidateStyle |= !styleResolver;
   1003 
   1004     if (shouldInvalidateStyle)
   1005         setNeedsStyleRecalc();
   1006 
   1007     if (AXObjectCache* cache = document().existingAXObjectCache())
   1008         cache->handleAttributeChanged(name, this);
   1009 }
   1010 
   1011 inline void Element::attributeChangedFromParserOrByCloning(const QualifiedName& name, const AtomicString& newValue, AttributeModificationReason reason)
   1012 {
   1013     if (name == isAttr)
   1014         CustomElementRegistrationContext::setTypeExtension(this, newValue);
   1015     attributeChanged(name, newValue, reason);
   1016 }
   1017 
   1018 template <typename CharacterType>
   1019 static inline bool classStringHasClassName(const CharacterType* characters, unsigned length)
   1020 {
   1021     ASSERT(length > 0);
   1022 
   1023     unsigned i = 0;
   1024     do {
   1025         if (isNotHTMLSpace<CharacterType>(characters[i]))
   1026             break;
   1027         ++i;
   1028     } while (i < length);
   1029 
   1030     return i < length;
   1031 }
   1032 
   1033 static inline bool classStringHasClassName(const AtomicString& newClassString)
   1034 {
   1035     unsigned length = newClassString.length();
   1036 
   1037     if (!length)
   1038         return false;
   1039 
   1040     if (newClassString.is8Bit())
   1041         return classStringHasClassName(newClassString.characters8(), length);
   1042     return classStringHasClassName(newClassString.characters16(), length);
   1043 }
   1044 
   1045 template<typename Checker>
   1046 static bool checkSelectorForClassChange(const SpaceSplitString& changedClasses, const Checker& checker)
   1047 {
   1048     unsigned changedSize = changedClasses.size();
   1049     for (unsigned i = 0; i < changedSize; ++i) {
   1050         if (checker.hasSelectorForClass(changedClasses[i]))
   1051             return true;
   1052     }
   1053     return false;
   1054 }
   1055 
   1056 template<typename Checker>
   1057 static bool checkSelectorForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, const Checker& checker)
   1058 {
   1059     if (!oldClasses.size())
   1060         return checkSelectorForClassChange(newClasses, checker);
   1061 
   1062     // Class vectors tend to be very short. This is faster than using a hash table.
   1063     BitVector remainingClassBits;
   1064     remainingClassBits.ensureSize(oldClasses.size());
   1065 
   1066     for (unsigned i = 0; i < newClasses.size(); ++i) {
   1067         bool found = false;
   1068         for (unsigned j = 0; j < oldClasses.size(); ++j) {
   1069             if (newClasses[i] == oldClasses[j]) {
   1070                 // Mark each class that is still in the newClasses so we can skip doing
   1071                 // an n^2 search below when looking for removals. We can't break from
   1072                 // this loop early since a class can appear more than once.
   1073                 remainingClassBits.quickSet(j);
   1074                 found = true;
   1075             }
   1076         }
   1077         // Class was added.
   1078         if (!found && checker.hasSelectorForClass(newClasses[i]))
   1079             return true;
   1080     }
   1081 
   1082     for (unsigned i = 0; i < oldClasses.size(); ++i) {
   1083         if (remainingClassBits.quickGet(i))
   1084             continue;
   1085         // Class was removed.
   1086         if (checker.hasSelectorForClass(oldClasses[i]))
   1087             return true;
   1088     }
   1089 
   1090     return false;
   1091 }
   1092 
   1093 void Element::classAttributeChanged(const AtomicString& newClassString)
   1094 {
   1095     StyleResolver* styleResolver = document().styleResolver();
   1096     bool testShouldInvalidateStyle = inActiveDocument() && styleResolver && styleChangeType() < SubtreeStyleChange;
   1097     bool shouldInvalidateStyle = false;
   1098 
   1099     if (classStringHasClassName(newClassString)) {
   1100         const bool shouldFoldCase = document().inQuirksMode();
   1101         const SpaceSplitString oldClasses = elementData()->classNames();
   1102         elementData()->setClass(newClassString, shouldFoldCase);
   1103         const SpaceSplitString& newClasses = elementData()->classNames();
   1104         shouldInvalidateStyle = testShouldInvalidateStyle && checkSelectorForClassChange(oldClasses, newClasses, styleResolver->ensureRuleFeatureSet());
   1105     } else {
   1106         const SpaceSplitString& oldClasses = elementData()->classNames();
   1107         shouldInvalidateStyle = testShouldInvalidateStyle && checkSelectorForClassChange(oldClasses, styleResolver->ensureRuleFeatureSet());
   1108         elementData()->clearClass();
   1109     }
   1110 
   1111     if (hasRareData())
   1112         elementRareData()->clearClassListValueForQuirksMode();
   1113 
   1114     if (shouldInvalidateStyle)
   1115         setNeedsStyleRecalc();
   1116 }
   1117 
   1118 bool Element::shouldInvalidateDistributionWhenAttributeChanged(ElementShadow* elementShadow, const QualifiedName& name, const AtomicString& newValue)
   1119 {
   1120     ASSERT(elementShadow);
   1121     const SelectRuleFeatureSet& featureSet = elementShadow->ensureSelectFeatureSet();
   1122 
   1123     if (isIdAttributeName(name)) {
   1124         AtomicString oldId = elementData()->idForStyleResolution();
   1125         AtomicString newId = makeIdForStyleResolution(newValue, document().inQuirksMode());
   1126         if (newId != oldId) {
   1127             if (!oldId.isEmpty() && featureSet.hasSelectorForId(oldId))
   1128                 return true;
   1129             if (!newId.isEmpty() && featureSet.hasSelectorForId(newId))
   1130                 return true;
   1131         }
   1132     }
   1133 
   1134     if (name == HTMLNames::classAttr) {
   1135         const AtomicString& newClassString = newValue;
   1136         if (classStringHasClassName(newClassString)) {
   1137             const bool shouldFoldCase = document().inQuirksMode();
   1138             const SpaceSplitString& oldClasses = elementData()->classNames();
   1139             const SpaceSplitString newClasses(newClassString, shouldFoldCase);
   1140             if (checkSelectorForClassChange(oldClasses, newClasses, featureSet))
   1141                 return true;
   1142         } else {
   1143             const SpaceSplitString& oldClasses = elementData()->classNames();
   1144             if (checkSelectorForClassChange(oldClasses, featureSet))
   1145                 return true;
   1146         }
   1147     }
   1148 
   1149     return featureSet.hasSelectorForAttribute(name.localName());
   1150 }
   1151 
   1152 // Returns true is the given attribute is an event handler.
   1153 // We consider an event handler any attribute that begins with "on".
   1154 // It is a simple solution that has the advantage of not requiring any
   1155 // code or configuration change if a new event handler is defined.
   1156 
   1157 static inline bool isEventHandlerAttribute(const Attribute& attribute)
   1158 {
   1159     return attribute.name().namespaceURI().isNull() && attribute.name().localName().startsWith("on");
   1160 }
   1161 
   1162 bool Element::isJavaScriptURLAttribute(const Attribute& attribute) const
   1163 {
   1164     return isURLAttribute(attribute) && protocolIsJavaScript(stripLeadingAndTrailingHTMLSpaces(attribute.value()));
   1165 }
   1166 
   1167 void Element::stripScriptingAttributes(Vector<Attribute>& attributeVector) const
   1168 {
   1169     size_t destination = 0;
   1170     for (size_t source = 0; source < attributeVector.size(); ++source) {
   1171         if (isEventHandlerAttribute(attributeVector[source])
   1172             || isJavaScriptURLAttribute(attributeVector[source])
   1173             || isHTMLContentAttribute(attributeVector[source]))
   1174             continue;
   1175 
   1176         if (source != destination)
   1177             attributeVector[destination] = attributeVector[source];
   1178 
   1179         ++destination;
   1180     }
   1181     attributeVector.shrink(destination);
   1182 }
   1183 
   1184 void Element::parserSetAttributes(const Vector<Attribute>& attributeVector)
   1185 {
   1186     ASSERT(!inDocument());
   1187     ASSERT(!parentNode());
   1188     ASSERT(!m_elementData);
   1189 
   1190     if (attributeVector.isEmpty())
   1191         return;
   1192 
   1193     if (document().sharedObjectPool())
   1194         m_elementData = document().sharedObjectPool()->cachedShareableElementDataWithAttributes(attributeVector);
   1195     else
   1196         m_elementData = ShareableElementData::createWithAttributes(attributeVector);
   1197 
   1198     // Use attributeVector instead of m_elementData because attributeChanged might modify m_elementData.
   1199     for (unsigned i = 0; i < attributeVector.size(); ++i)
   1200         attributeChangedFromParserOrByCloning(attributeVector[i].name(), attributeVector[i].value(), ModifiedDirectly);
   1201 }
   1202 
   1203 bool Element::hasAttributes() const
   1204 {
   1205     synchronizeAllAttributes();
   1206     return elementData() && elementData()->length();
   1207 }
   1208 
   1209 bool Element::hasEquivalentAttributes(const Element* other) const
   1210 {
   1211     synchronizeAllAttributes();
   1212     other->synchronizeAllAttributes();
   1213     if (elementData() == other->elementData())
   1214         return true;
   1215     if (elementData())
   1216         return elementData()->isEquivalent(other->elementData());
   1217     if (other->elementData())
   1218         return other->elementData()->isEquivalent(elementData());
   1219     return true;
   1220 }
   1221 
   1222 String Element::nodeName() const
   1223 {
   1224     return m_tagName.toString();
   1225 }
   1226 
   1227 String Element::nodeNamePreservingCase() const
   1228 {
   1229     return m_tagName.toString();
   1230 }
   1231 
   1232 void Element::setPrefix(const AtomicString& prefix, ExceptionState& exceptionState)
   1233 {
   1234     checkSetPrefix(prefix, exceptionState);
   1235     if (exceptionState.hadException())
   1236         return;
   1237 
   1238     m_tagName.setPrefix(prefix.isEmpty() ? AtomicString() : prefix);
   1239 }
   1240 
   1241 KURL Element::baseURI() const
   1242 {
   1243     const AtomicString& baseAttribute = getAttribute(baseAttr);
   1244     KURL base(KURL(), baseAttribute);
   1245     if (!base.protocol().isEmpty())
   1246         return base;
   1247 
   1248     ContainerNode* parent = parentNode();
   1249     if (!parent)
   1250         return base;
   1251 
   1252     const KURL& parentBase = parent->baseURI();
   1253     if (parentBase.isNull())
   1254         return base;
   1255 
   1256     return KURL(parentBase, baseAttribute);
   1257 }
   1258 
   1259 const AtomicString Element::imageSourceURL() const
   1260 {
   1261     return getAttribute(srcAttr);
   1262 }
   1263 
   1264 bool Element::rendererIsNeeded(const RenderStyle& style)
   1265 {
   1266     return style.display() != NONE;
   1267 }
   1268 
   1269 RenderObject* Element::createRenderer(RenderStyle* style)
   1270 {
   1271     return RenderObject::createObject(this, style);
   1272 }
   1273 
   1274 Node::InsertionNotificationRequest Element::insertedInto(ContainerNode* insertionPoint)
   1275 {
   1276     // need to do superclass processing first so inDocument() is true
   1277     // by the time we reach updateId
   1278     ContainerNode::insertedInto(insertionPoint);
   1279 
   1280     if (containsFullScreenElement() && parentElement() && !parentElement()->containsFullScreenElement())
   1281         setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(true);
   1282 
   1283     ASSERT(!hasRareData() || !elementRareData()->hasPseudoElements());
   1284 
   1285     if (!insertionPoint->isInTreeScope())
   1286         return InsertionDone;
   1287 
   1288     if (hasRareData())
   1289         elementRareData()->clearClassListValueForQuirksMode();
   1290 
   1291     if (isUpgradedCustomElement() && inDocument())
   1292         CustomElement::didEnterDocument(this, document());
   1293 
   1294     TreeScope& scope = insertionPoint->treeScope();
   1295     if (scope != treeScope())
   1296         return InsertionDone;
   1297 
   1298     const AtomicString& idValue = getIdAttribute();
   1299     if (!idValue.isNull())
   1300         updateId(scope, nullAtom, idValue);
   1301 
   1302     const AtomicString& nameValue = getNameAttribute();
   1303     if (!nameValue.isNull())
   1304         updateName(nullAtom, nameValue);
   1305 
   1306     if (hasTagName(labelTag)) {
   1307         if (scope.shouldCacheLabelsByForAttribute())
   1308             updateLabel(scope, nullAtom, fastGetAttribute(forAttr));
   1309     }
   1310 
   1311     if (parentElement() && parentElement()->isInCanvasSubtree())
   1312         setIsInCanvasSubtree(true);
   1313 
   1314     return InsertionDone;
   1315 }
   1316 
   1317 void Element::removedFrom(ContainerNode* insertionPoint)
   1318 {
   1319     bool wasInDocument = insertionPoint->inDocument();
   1320 
   1321     ASSERT(!hasRareData() || !elementRareData()->hasPseudoElements());
   1322 
   1323     if (containsFullScreenElement())
   1324         setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false);
   1325 
   1326     if (document().page())
   1327         document().page()->pointerLockController().elementRemoved(this);
   1328 
   1329     setSavedLayerScrollOffset(IntSize());
   1330 
   1331     if (insertionPoint->isInTreeScope() && treeScope() == document()) {
   1332         const AtomicString& idValue = getIdAttribute();
   1333         if (!idValue.isNull())
   1334             updateId(insertionPoint->treeScope(), idValue, nullAtom);
   1335 
   1336         const AtomicString& nameValue = getNameAttribute();
   1337         if (!nameValue.isNull())
   1338             updateName(nameValue, nullAtom);
   1339 
   1340         if (hasTagName(labelTag)) {
   1341             TreeScope& treeScope = insertionPoint->treeScope();
   1342             if (treeScope.shouldCacheLabelsByForAttribute())
   1343                 updateLabel(treeScope, fastGetAttribute(forAttr), nullAtom);
   1344         }
   1345     }
   1346 
   1347     ContainerNode::removedFrom(insertionPoint);
   1348     if (wasInDocument) {
   1349         if (hasPendingResources())
   1350             document().accessSVGExtensions()->removeElementFromPendingResources(this);
   1351 
   1352         if (isUpgradedCustomElement())
   1353             CustomElement::didLeaveDocument(this, insertionPoint->document());
   1354     }
   1355 
   1356     document().removeFromTopLayer(this);
   1357 
   1358     if (hasRareData())
   1359         elementRareData()->setIsInCanvasSubtree(false);
   1360 }
   1361 
   1362 void Element::attach(const AttachContext& context)
   1363 {
   1364     ASSERT(document().inStyleRecalc());
   1365 
   1366     StyleResolverParentPusher parentPusher(*this);
   1367 
   1368     // We've already been through detach when doing an attach, but we might
   1369     // need to clear any state that's been added since then.
   1370     if (hasRareData() && styleChangeType() == NeedsReattachStyleChange) {
   1371         ElementRareData* data = elementRareData();
   1372         data->clearComputedStyle();
   1373         data->resetDynamicRestyleObservations();
   1374         // Only clear the style state if we're not going to reuse the style from recalcStyle.
   1375         if (!context.resolvedStyle)
   1376             data->resetStyleState();
   1377     }
   1378 
   1379     NodeRenderingContext(this, context.resolvedStyle).createRendererForElementIfNeeded();
   1380 
   1381     addCallbackSelectors();
   1382 
   1383     createPseudoElementIfNeeded(BEFORE);
   1384 
   1385     // When a shadow root exists, it does the work of attaching the children.
   1386     if (ElementShadow* shadow = this->shadow()) {
   1387         parentPusher.push();
   1388         shadow->attach(context);
   1389     } else if (firstChild()) {
   1390         parentPusher.push();
   1391     }
   1392 
   1393     ContainerNode::attach(context);
   1394 
   1395     createPseudoElementIfNeeded(AFTER);
   1396     createPseudoElementIfNeeded(BACKDROP);
   1397 
   1398     if (hasRareData()) {
   1399         ElementRareData* data = elementRareData();
   1400         if (data->needsFocusAppearanceUpdateSoonAfterAttach()) {
   1401             if (isFocusable() && document().focusedElement() == this)
   1402                 document().updateFocusAppearanceSoon(false /* don't restore selection */);
   1403             data->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
   1404         }
   1405         if (RuntimeEnabledFeatures::webAnimationsCSSEnabled() && !renderer()) {
   1406             if (ActiveAnimations* activeAnimations = data->activeAnimations())
   1407                 activeAnimations->cssAnimations().cancel();
   1408         }
   1409     }
   1410 
   1411     InspectorInstrumentation::didRecalculateStyleForElement(this);
   1412 }
   1413 
   1414 void Element::unregisterNamedFlowContentNode()
   1415 {
   1416     if (RuntimeEnabledFeatures::cssRegionsEnabled() && inNamedFlow() && document().renderView())
   1417         document().renderView()->flowThreadController()->unregisterNamedFlowContentNode(this);
   1418 }
   1419 
   1420 void Element::detach(const AttachContext& context)
   1421 {
   1422     RenderWidget::UpdateSuspendScope suspendWidgetHierarchyUpdates;
   1423     unregisterNamedFlowContentNode();
   1424     cancelFocusAppearanceUpdate();
   1425     removeCallbackSelectors();
   1426     if (hasRareData()) {
   1427         ElementRareData* data = elementRareData();
   1428         data->setPseudoElement(BEFORE, 0);
   1429         data->setPseudoElement(AFTER, 0);
   1430         data->setPseudoElement(BACKDROP, 0);
   1431         data->setIsInsideRegion(false);
   1432 
   1433         // attach() will perform the below steps for us when inside recalcStyle.
   1434         if (!document().inStyleRecalc()) {
   1435             data->resetStyleState();
   1436             data->clearComputedStyle();
   1437             data->resetDynamicRestyleObservations();
   1438         }
   1439 
   1440         if (RuntimeEnabledFeatures::webAnimationsCSSEnabled()) {
   1441             if (ActiveAnimations* activeAnimations = data->activeAnimations()) {
   1442                 if (context.performingReattach) {
   1443                     // FIXME: restart compositor animations rather than pull back to the main thread
   1444                     activeAnimations->cancelAnimationOnCompositor();
   1445                 } else {
   1446                     activeAnimations->cssAnimations().cancel();
   1447                 }
   1448             }
   1449         }
   1450     }
   1451     if (ElementShadow* shadow = this->shadow())
   1452         shadow->detach(context);
   1453     ContainerNode::detach(context);
   1454 }
   1455 
   1456 bool Element::pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderStyle* newStyle)
   1457 {
   1458     ASSERT(currentStyle == renderStyle());
   1459     ASSERT(renderer());
   1460 
   1461     if (!currentStyle)
   1462         return false;
   1463 
   1464     const PseudoStyleCache* pseudoStyleCache = currentStyle->cachedPseudoStyles();
   1465     if (!pseudoStyleCache)
   1466         return false;
   1467 
   1468     size_t cacheSize = pseudoStyleCache->size();
   1469     for (size_t i = 0; i < cacheSize; ++i) {
   1470         RefPtr<RenderStyle> newPseudoStyle;
   1471         PseudoId pseudoId = pseudoStyleCache->at(i)->styleType();
   1472         if (pseudoId == FIRST_LINE || pseudoId == FIRST_LINE_INHERITED)
   1473             newPseudoStyle = renderer()->uncachedFirstLineStyle(newStyle);
   1474         else
   1475             newPseudoStyle = renderer()->getUncachedPseudoStyle(PseudoStyleRequest(pseudoId), newStyle, newStyle);
   1476         if (!newPseudoStyle)
   1477             return true;
   1478         if (*newPseudoStyle != *pseudoStyleCache->at(i)) {
   1479             if (pseudoId < FIRST_INTERNAL_PSEUDOID)
   1480                 newStyle->setHasPseudoStyle(pseudoId);
   1481             newStyle->addCachedPseudoStyle(newPseudoStyle);
   1482             if (pseudoId == FIRST_LINE || pseudoId == FIRST_LINE_INHERITED) {
   1483                 // FIXME: We should do an actual diff to determine whether a repaint vs. layout
   1484                 // is needed, but for now just assume a layout will be required. The diff code
   1485                 // in RenderObject::setStyle would need to be factored out so that it could be reused.
   1486                 renderer()->setNeedsLayoutAndPrefWidthsRecalc();
   1487             }
   1488             return true;
   1489         }
   1490     }
   1491     return false;
   1492 }
   1493 
   1494 PassRefPtr<RenderStyle> Element::styleForRenderer()
   1495 {
   1496     ASSERT(document().inStyleRecalc());
   1497 
   1498     RefPtr<RenderStyle> style;
   1499 
   1500     // FIXME: Instead of clearing updates that may have been added from calls to styleForElement
   1501     // outside recalcStyle, we should just never set them if we're not inside recalcStyle.
   1502     if (ActiveAnimations* activeAnimations = this->activeAnimations())
   1503         activeAnimations->cssAnimations().setPendingUpdate(nullptr);
   1504 
   1505     if (hasCustomStyleCallbacks())
   1506         style = customStyleForRenderer();
   1507     if (!style)
   1508         style = originalStyleForRenderer();
   1509 
   1510     // styleForElement() might add active animations so we need to get it again.
   1511     if (ActiveAnimations* activeAnimations = this->activeAnimations())
   1512         activeAnimations->cssAnimations().maybeApplyPendingUpdate(this);
   1513 
   1514     ASSERT(style);
   1515     return style.release();
   1516 }
   1517 
   1518 PassRefPtr<RenderStyle> Element::originalStyleForRenderer()
   1519 {
   1520     ASSERT(document().inStyleRecalc());
   1521     return document().ensureStyleResolver().styleForElement(this);
   1522 }
   1523 
   1524 void Element::recalcStyle(StyleRecalcChange change, Text* nextTextSibling)
   1525 {
   1526     ASSERT(document().inStyleRecalc());
   1527     ASSERT(!parentOrShadowHostNode()->needsStyleRecalc());
   1528 
   1529     if (hasCustomStyleCallbacks())
   1530         willRecalcStyle(change);
   1531 
   1532     if (change >= Inherit || needsStyleRecalc()) {
   1533         if (hasRareData()) {
   1534             ElementRareData* data = elementRareData();
   1535             data->resetStyleState();
   1536             data->clearComputedStyle();
   1537 
   1538             if (change >= Inherit) {
   1539                 if (ActiveAnimations* activeAnimations = data->activeAnimations())
   1540                     activeAnimations->setAnimationStyleChange(false);
   1541             }
   1542         }
   1543         if (parentRenderStyle())
   1544             change = recalcOwnStyle(change);
   1545         clearNeedsStyleRecalc();
   1546     }
   1547 
   1548     // If we reattached we don't need to recalc the style of our descendants anymore.
   1549     if ((change >= Inherit && change < Reattach) || childNeedsStyleRecalc())
   1550         recalcChildStyle(change);
   1551     clearChildNeedsStyleRecalc();
   1552 
   1553     if (hasCustomStyleCallbacks())
   1554         didRecalcStyle(change);
   1555 
   1556     if (change == Reattach)
   1557         reattachWhitespaceSiblings(nextTextSibling);
   1558 }
   1559 
   1560 StyleRecalcChange Element::recalcOwnStyle(StyleRecalcChange change)
   1561 {
   1562     ASSERT(document().inStyleRecalc());
   1563     ASSERT(!parentOrShadowHostNode()->needsStyleRecalc());
   1564     ASSERT(change >= Inherit || needsStyleRecalc());
   1565     ASSERT(parentRenderStyle());
   1566 
   1567     RefPtr<RenderStyle> oldStyle = renderStyle();
   1568     RefPtr<RenderStyle> newStyle = styleForRenderer();
   1569     StyleRecalcChange localChange = RenderStyle::compare(oldStyle.get(), newStyle.get());
   1570 
   1571     ASSERT(newStyle);
   1572 
   1573     if (localChange == Reattach) {
   1574         AttachContext reattachContext;
   1575         reattachContext.resolvedStyle = newStyle.get();
   1576         reattach(reattachContext);
   1577         return Reattach;
   1578     }
   1579 
   1580     ASSERT(oldStyle);
   1581 
   1582     InspectorInstrumentation::didRecalculateStyleForElement(this);
   1583 
   1584     if (localChange != NoChange)
   1585         updateCallbackSelectors(oldStyle.get(), newStyle.get());
   1586 
   1587     if (RenderObject* renderer = this->renderer()) {
   1588         if (localChange != NoChange || pseudoStyleCacheIsInvalid(oldStyle.get(), newStyle.get()) || shouldNotifyRendererWithIdenticalStyles()) {
   1589             renderer->setAnimatableStyle(newStyle.get());
   1590         } else {
   1591             // Although no change occurred, we use the new style so that the cousin style sharing code won't get
   1592             // fooled into believing this style is the same.
   1593             // FIXME: We may be able to remove this hack, see discussion in
   1594             // https://codereview.chromium.org/30453002/
   1595             renderer->setStyleInternal(newStyle.get());
   1596         }
   1597     }
   1598 
   1599     // 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
   1600     // 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).
   1601     if (document().styleEngine()->usesRemUnits() && document().documentElement() == this && oldStyle->fontSize() != newStyle->fontSize()) {
   1602         // Cached RenderStyles may depend on the re units.
   1603         document().ensureStyleResolver().invalidateMatchedPropertiesCache();
   1604         return Force;
   1605     }
   1606 
   1607     if (styleChangeType() >= SubtreeStyleChange)
   1608         return Force;
   1609 
   1610     return max(localChange, change);
   1611 }
   1612 
   1613 void Element::recalcChildStyle(StyleRecalcChange change)
   1614 {
   1615     ASSERT(document().inStyleRecalc());
   1616     ASSERT(change >= Inherit || childNeedsStyleRecalc());
   1617     ASSERT(!needsStyleRecalc());
   1618 
   1619     StyleResolverParentPusher parentPusher(*this);
   1620 
   1621     for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
   1622         if (shouldRecalcStyle(change, root)) {
   1623             parentPusher.push();
   1624             root->recalcStyle(change);
   1625         }
   1626     }
   1627 
   1628     if (shouldRecalcStyle(change, this))
   1629         updatePseudoElement(BEFORE, change);
   1630 
   1631     if (change < Force && hasRareData() && childNeedsStyleRecalc())
   1632         checkForChildrenAdjacentRuleChanges();
   1633 
   1634     // This loop is deliberately backwards because we use insertBefore in the rendering tree, and want to avoid
   1635     // a potentially n^2 loop to find the insertion point while resolving style. Having us start from the last
   1636     // child and work our way back means in the common case, we'll find the insertion point in O(1) time.
   1637     // See crbug.com/288225
   1638     StyleResolver& styleResolver = document().ensureStyleResolver();
   1639     Text* lastTextNode = 0;
   1640     for (Node* child = lastChild(); child; child = child->previousSibling()) {
   1641         if (child->isTextNode()) {
   1642             toText(child)->recalcTextStyle(change, lastTextNode);
   1643             lastTextNode = toText(child);
   1644         } else if (child->isElementNode()) {
   1645             Element* element = toElement(child);
   1646             if (shouldRecalcStyle(change, element)) {
   1647                 parentPusher.push();
   1648                 element->recalcStyle(change, lastTextNode);
   1649             } else if (element->supportsStyleSharing()) {
   1650                 styleResolver.addToStyleSharingList(*element);
   1651             }
   1652             if (element->renderer())
   1653                 lastTextNode = 0;
   1654         }
   1655     }
   1656 
   1657     if (shouldRecalcStyle(change, this)) {
   1658         updatePseudoElement(AFTER, change);
   1659         updatePseudoElement(BACKDROP, change);
   1660     }
   1661 }
   1662 
   1663 void Element::checkForChildrenAdjacentRuleChanges()
   1664 {
   1665     bool hasDirectAdjacentRules = childrenAffectedByDirectAdjacentRules();
   1666     bool hasIndirectAdjacentRules = childrenAffectedByForwardPositionalRules();
   1667 
   1668     if (!hasDirectAdjacentRules && !hasIndirectAdjacentRules)
   1669         return;
   1670 
   1671     unsigned forceCheckOfNextElementCount = 0;
   1672     bool forceCheckOfAnyElementSibling = false;
   1673 
   1674     for (Node* child = firstChild(); child; child = child->nextSibling()) {
   1675         if (!child->isElementNode())
   1676             continue;
   1677         Element* element = toElement(child);
   1678         bool childRulesChanged = element->needsStyleRecalc() && element->styleChangeType() >= SubtreeStyleChange;
   1679 
   1680         if (forceCheckOfNextElementCount || forceCheckOfAnyElementSibling)
   1681             element->setNeedsStyleRecalc();
   1682 
   1683         if (forceCheckOfNextElementCount)
   1684             forceCheckOfNextElementCount--;
   1685 
   1686         if (childRulesChanged && hasDirectAdjacentRules)
   1687             forceCheckOfNextElementCount = document().styleEngine()->maxDirectAdjacentSelectors();
   1688 
   1689         forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules);
   1690     }
   1691 }
   1692 
   1693 void Element::updateCallbackSelectors(RenderStyle* oldStyle, RenderStyle* newStyle)
   1694 {
   1695     Vector<String> emptyVector;
   1696     const Vector<String>& oldCallbackSelectors = oldStyle ? oldStyle->callbackSelectors() : emptyVector;
   1697     const Vector<String>& newCallbackSelectors = newStyle ? newStyle->callbackSelectors() : emptyVector;
   1698     if (oldCallbackSelectors.isEmpty() && newCallbackSelectors.isEmpty())
   1699         return;
   1700     if (oldCallbackSelectors != newCallbackSelectors)
   1701         CSSSelectorWatch::from(document()).updateSelectorMatches(oldCallbackSelectors, newCallbackSelectors);
   1702 }
   1703 
   1704 void Element::addCallbackSelectors()
   1705 {
   1706     updateCallbackSelectors(0, renderStyle());
   1707 }
   1708 
   1709 void Element::removeCallbackSelectors()
   1710 {
   1711     updateCallbackSelectors(renderStyle(), 0);
   1712 }
   1713 
   1714 ElementShadow* Element::shadow() const
   1715 {
   1716     return hasRareData() ? elementRareData()->shadow() : 0;
   1717 }
   1718 
   1719 ElementShadow& Element::ensureShadow()
   1720 {
   1721     return ensureElementRareData().ensureShadow();
   1722 }
   1723 
   1724 void Element::didAffectSelector(AffectedSelectorMask mask)
   1725 {
   1726     setNeedsStyleRecalc();
   1727     if (ElementShadow* elementShadow = shadowWhereNodeCanBeDistributed(*this))
   1728         elementShadow->didAffectSelector(mask);
   1729 }
   1730 
   1731 void Element::setAnimationStyleChange(bool animationStyleChange)
   1732 {
   1733     if (ActiveAnimations* activeAnimations = elementRareData()->activeAnimations())
   1734         activeAnimations->setAnimationStyleChange(animationStyleChange);
   1735 }
   1736 
   1737 void Element::setNeedsAnimationStyleRecalc()
   1738 {
   1739     bool recalcPending = styleChangeType() != NoStyleChange;
   1740     setNeedsStyleRecalc(LocalStyleChange, StyleChangeFromRenderer);
   1741 
   1742     if (!recalcPending)
   1743         setAnimationStyleChange(true);
   1744 }
   1745 
   1746 PassRefPtr<ShadowRoot> Element::createShadowRoot(ExceptionState& exceptionState)
   1747 {
   1748     if (alwaysCreateUserAgentShadowRoot())
   1749         ensureUserAgentShadowRoot();
   1750 
   1751     if (RuntimeEnabledFeatures::authorShadowDOMForAnyElementEnabled())
   1752         return PassRefPtr<ShadowRoot>(ensureShadow().addShadowRoot(*this, ShadowRoot::AuthorShadowRoot));
   1753 
   1754     // Since some elements recreates shadow root dynamically, multiple shadow
   1755     // subtrees won't work well in that element. Until they are fixed, we disable
   1756     // adding author shadow root for them.
   1757     if (!areAuthorShadowsAllowed()) {
   1758         exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
   1759         return 0;
   1760     }
   1761     return PassRefPtr<ShadowRoot>(ensureShadow().addShadowRoot(*this, ShadowRoot::AuthorShadowRoot));
   1762 }
   1763 
   1764 ShadowRoot* Element::shadowRoot() const
   1765 {
   1766     ElementShadow* elementShadow = shadow();
   1767     if (!elementShadow)
   1768         return 0;
   1769     ShadowRoot* shadowRoot = elementShadow->youngestShadowRoot();
   1770     if (shadowRoot->type() == ShadowRoot::AuthorShadowRoot)
   1771         return shadowRoot;
   1772     return 0;
   1773 }
   1774 
   1775 void Element::didAddShadowRoot(ShadowRoot&)
   1776 {
   1777 }
   1778 
   1779 ShadowRoot* Element::userAgentShadowRoot() const
   1780 {
   1781     if (ElementShadow* elementShadow = shadow()) {
   1782         if (ShadowRoot* shadowRoot = elementShadow->oldestShadowRoot()) {
   1783             ASSERT(shadowRoot->type() == ShadowRoot::UserAgentShadowRoot);
   1784             return shadowRoot;
   1785         }
   1786     }
   1787 
   1788     return 0;
   1789 }
   1790 
   1791 ShadowRoot& Element::ensureUserAgentShadowRoot()
   1792 {
   1793     if (ShadowRoot* shadowRoot = userAgentShadowRoot())
   1794         return *shadowRoot;
   1795     ShadowRoot& shadowRoot = ensureShadow().addShadowRoot(*this, ShadowRoot::UserAgentShadowRoot);
   1796     didAddUserAgentShadowRoot(shadowRoot);
   1797     return shadowRoot;
   1798 }
   1799 
   1800 bool Element::childTypeAllowed(NodeType type) const
   1801 {
   1802     switch (type) {
   1803     case ELEMENT_NODE:
   1804     case TEXT_NODE:
   1805     case COMMENT_NODE:
   1806     case PROCESSING_INSTRUCTION_NODE:
   1807     case CDATA_SECTION_NODE:
   1808         return true;
   1809     default:
   1810         break;
   1811     }
   1812     return false;
   1813 }
   1814 
   1815 void Element::checkForEmptyStyleChange(RenderStyle* style)
   1816 {
   1817     if (!style && !styleAffectedByEmpty())
   1818         return;
   1819 
   1820     if (!style || (styleAffectedByEmpty() && (!style->emptyState() || hasChildNodes())))
   1821         setNeedsStyleRecalc();
   1822 }
   1823 
   1824 void Element::checkForSiblingStyleChanges(bool finishedParsingCallback, Node* beforeChange, Node* afterChange, int childCountDelta)
   1825 {
   1826     if (!inActiveDocument() || document().hasPendingForcedStyleRecalc() || styleChangeType() >= SubtreeStyleChange)
   1827         return;
   1828 
   1829     RenderStyle* style = renderStyle();
   1830 
   1831     // :empty selector.
   1832     checkForEmptyStyleChange(style);
   1833 
   1834     if (!style || (needsStyleRecalc() && childrenAffectedByPositionalRules()))
   1835         return;
   1836 
   1837     // Forward positional selectors include the ~ selector, nth-child, nth-of-type, first-of-type and only-of-type.
   1838     // Backward positional selectors include nth-last-child, nth-last-of-type, last-of-type and only-of-type.
   1839     // We have to invalidate everything following the insertion point in the forward case, and everything before the insertion point in the
   1840     // backward case.
   1841     // |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.
   1842     // 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
   1843     // here. recalcStyle will then force a walk of the children when it sees that this has happened.
   1844     if ((childrenAffectedByForwardPositionalRules() && afterChange) || (childrenAffectedByBackwardPositionalRules() && beforeChange)) {
   1845         setNeedsStyleRecalc();
   1846         return;
   1847     }
   1848 
   1849     // :first-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
   1850     // In the DOM case, we only need to do something if |afterChange| is not 0.
   1851     // |afterChange| is 0 in the parser case, so it works out that we'll skip this block.
   1852     if (childrenAffectedByFirstChildRules() && afterChange) {
   1853         // Find our new first child.
   1854         Node* newFirstChild = firstElementChild();
   1855         RenderStyle* newFirstChildStyle = newFirstChild ? newFirstChild->renderStyle() : 0;
   1856 
   1857         // Find the first element node following |afterChange|
   1858         Node* firstElementAfterInsertion = afterChange->isElementNode() ? afterChange : afterChange->nextElementSibling();
   1859         RenderStyle* firstElementAfterInsertionStyle = firstElementAfterInsertion ? firstElementAfterInsertion->renderStyle() : 0;
   1860 
   1861         // This is the insert/append case.
   1862         if (newFirstChild != firstElementAfterInsertion && firstElementAfterInsertionStyle && firstElementAfterInsertionStyle->firstChildState())
   1863             firstElementAfterInsertion->setNeedsStyleRecalc();
   1864 
   1865         // We also have to handle node removal.
   1866         if (childCountDelta < 0 && newFirstChild == firstElementAfterInsertion && newFirstChild && (!newFirstChildStyle || !newFirstChildStyle->firstChildState()))
   1867             newFirstChild->setNeedsStyleRecalc();
   1868     }
   1869 
   1870     // :last-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
   1871     // In the DOM case, we only need to do something if |afterChange| is not 0.
   1872     if (childrenAffectedByLastChildRules() && beforeChange) {
   1873         // Find our new last child.
   1874         Node* newLastChild = lastElementChild();
   1875         RenderStyle* newLastChildStyle = newLastChild ? newLastChild->renderStyle() : 0;
   1876 
   1877         // Find the last element node going backwards from |beforeChange|
   1878         Node* lastElementBeforeInsertion = beforeChange->isElementNode() ? beforeChange : beforeChange->previousElementSibling();
   1879         RenderStyle* lastElementBeforeInsertionStyle = lastElementBeforeInsertion ? lastElementBeforeInsertion->renderStyle() : 0;
   1880 
   1881         if (newLastChild != lastElementBeforeInsertion && lastElementBeforeInsertionStyle && lastElementBeforeInsertionStyle->lastChildState())
   1882             lastElementBeforeInsertion->setNeedsStyleRecalc();
   1883 
   1884         // 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
   1885         // to match now.
   1886         if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild == lastElementBeforeInsertion && newLastChild && (!newLastChildStyle || !newLastChildStyle->lastChildState()))
   1887             newLastChild->setNeedsStyleRecalc();
   1888     }
   1889 
   1890     // The + selector.  We need to invalidate the first element following the insertion point.  It is the only possible element
   1891     // that could be affected by this DOM change.
   1892     if (childrenAffectedByDirectAdjacentRules() && afterChange) {
   1893         if (Node* firstElementAfterInsertion = afterChange->isElementNode() ? afterChange : afterChange->nextElementSibling())
   1894             firstElementAfterInsertion->setNeedsStyleRecalc();
   1895     }
   1896 }
   1897 
   1898 void Element::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
   1899 {
   1900     ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
   1901     if (changedByParser)
   1902         checkForEmptyStyleChange(renderStyle());
   1903     else
   1904         checkForSiblingStyleChanges(false, beforeChange, afterChange, childCountDelta);
   1905 
   1906     if (ElementShadow* shadow = this->shadow())
   1907         shadow->setNeedsDistributionRecalc();
   1908 }
   1909 
   1910 void Element::removeAllEventListeners()
   1911 {
   1912     ContainerNode::removeAllEventListeners();
   1913     if (ElementShadow* shadow = this->shadow())
   1914         shadow->removeAllEventListeners();
   1915 }
   1916 
   1917 void Element::beginParsingChildren()
   1918 {
   1919     clearIsParsingChildrenFinished();
   1920 }
   1921 
   1922 void Element::finishParsingChildren()
   1923 {
   1924     setIsParsingChildrenFinished();
   1925     checkForSiblingStyleChanges(this, lastChild(), 0, 0);
   1926 }
   1927 
   1928 #ifndef NDEBUG
   1929 void Element::formatForDebugger(char* buffer, unsigned length) const
   1930 {
   1931     StringBuilder result;
   1932     String s;
   1933 
   1934     result.append(nodeName());
   1935 
   1936     s = getIdAttribute();
   1937     if (s.length() > 0) {
   1938         if (result.length() > 0)
   1939             result.appendLiteral("; ");
   1940         result.appendLiteral("id=");
   1941         result.append(s);
   1942     }
   1943 
   1944     s = getAttribute(classAttr);
   1945     if (s.length() > 0) {
   1946         if (result.length() > 0)
   1947             result.appendLiteral("; ");
   1948         result.appendLiteral("class=");
   1949         result.append(s);
   1950     }
   1951 
   1952     strncpy(buffer, result.toString().utf8().data(), length - 1);
   1953 }
   1954 #endif
   1955 
   1956 const Vector<RefPtr<Attr> >& Element::attrNodeList()
   1957 {
   1958     ASSERT(hasSyntheticAttrChildNodes());
   1959     return *attrNodeListForElement(this);
   1960 }
   1961 
   1962 PassRefPtr<Attr> Element::setAttributeNode(Attr* attrNode, ExceptionState& exceptionState)
   1963 {
   1964     if (!attrNode) {
   1965         exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
   1966         return 0;
   1967     }
   1968 
   1969     RefPtr<Attr> oldAttrNode = attrIfExists(attrNode->qualifiedName());
   1970     if (oldAttrNode.get() == attrNode)
   1971         return attrNode; // This Attr is already attached to the element.
   1972 
   1973     // InUseAttributeError: Raised if node is an Attr that is already an attribute of another Element object.
   1974     // The DOM user must explicitly clone Attr nodes to re-use them in other elements.
   1975     if (attrNode->ownerElement()) {
   1976         exceptionState.throwUninformativeAndGenericDOMException(InUseAttributeError);
   1977         return 0;
   1978     }
   1979 
   1980     synchronizeAllAttributes();
   1981     UniqueElementData* elementData = ensureUniqueElementData();
   1982 
   1983     size_t index = elementData->getAttributeItemIndex(attrNode->qualifiedName(), shouldIgnoreAttributeCase());
   1984     if (index != kNotFound) {
   1985         if (oldAttrNode)
   1986             detachAttrNodeFromElementWithValue(oldAttrNode.get(), elementData->attributeItem(index)->value());
   1987         else
   1988             oldAttrNode = Attr::create(document(), attrNode->qualifiedName(), elementData->attributeItem(index)->value());
   1989     }
   1990 
   1991     setAttributeInternal(index, attrNode->qualifiedName(), attrNode->value(), NotInSynchronizationOfLazyAttribute);
   1992 
   1993     attrNode->attachToElement(this);
   1994     treeScope().adoptIfNeeded(*attrNode);
   1995     ensureAttrNodeListForElement(this).append(attrNode);
   1996 
   1997     return oldAttrNode.release();
   1998 }
   1999 
   2000 PassRefPtr<Attr> Element::setAttributeNodeNS(Attr* attr, ExceptionState& exceptionState)
   2001 {
   2002     return setAttributeNode(attr, exceptionState);
   2003 }
   2004 
   2005 PassRefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionState& exceptionState)
   2006 {
   2007     if (!attr) {
   2008         exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
   2009         return 0;
   2010     }
   2011     if (attr->ownerElement() != this) {
   2012         exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
   2013         return 0;
   2014     }
   2015 
   2016     ASSERT(document() == attr->document());
   2017 
   2018     synchronizeAttribute(attr->qualifiedName());
   2019 
   2020     size_t index = elementData()->getAttrIndex(attr);
   2021     if (index == kNotFound) {
   2022         exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
   2023         return 0;
   2024     }
   2025 
   2026     RefPtr<Attr> guard(attr);
   2027     detachAttrNodeAtIndex(attr, index);
   2028     return guard.release();
   2029 }
   2030 
   2031 bool Element::parseAttributeName(QualifiedName& out, const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState& exceptionState)
   2032 {
   2033     AtomicString prefix, localName;
   2034     if (!Document::parseQualifiedName(qualifiedName, prefix, localName, exceptionState))
   2035         return false;
   2036     ASSERT(!exceptionState.hadException());
   2037 
   2038     QualifiedName qName(prefix, localName, namespaceURI);
   2039 
   2040     if (!Document::hasValidNamespaceForAttributes(qName)) {
   2041         exceptionState.throwUninformativeAndGenericDOMException(NamespaceError);
   2042         return false;
   2043     }
   2044 
   2045     out = qName;
   2046     return true;
   2047 }
   2048 
   2049 void Element::setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionState& exceptionState)
   2050 {
   2051     QualifiedName parsedName = anyName;
   2052     if (!parseAttributeName(parsedName, namespaceURI, qualifiedName, exceptionState))
   2053         return;
   2054     setAttribute(parsedName, value);
   2055 }
   2056 
   2057 void Element::removeAttributeInternal(size_t index, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
   2058 {
   2059     ASSERT_WITH_SECURITY_IMPLICATION(index < attributeCount());
   2060 
   2061     UniqueElementData* elementData = ensureUniqueElementData();
   2062 
   2063     QualifiedName name = elementData->attributeItem(index)->name();
   2064     AtomicString valueBeingRemoved = elementData->attributeItem(index)->value();
   2065 
   2066     if (!inSynchronizationOfLazyAttribute) {
   2067         if (!valueBeingRemoved.isNull())
   2068             willModifyAttribute(name, valueBeingRemoved, nullAtom);
   2069     }
   2070 
   2071     if (RefPtr<Attr> attrNode = attrIfExists(name))
   2072         detachAttrNodeFromElementWithValue(attrNode.get(), elementData->attributeItem(index)->value());
   2073 
   2074     elementData->removeAttribute(index);
   2075 
   2076     if (!inSynchronizationOfLazyAttribute)
   2077         didRemoveAttribute(name);
   2078 }
   2079 
   2080 void Element::addAttributeInternal(const QualifiedName& name, const AtomicString& value, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
   2081 {
   2082     if (!inSynchronizationOfLazyAttribute)
   2083         willModifyAttribute(name, nullAtom, value);
   2084     ensureUniqueElementData()->addAttribute(name, value);
   2085     if (!inSynchronizationOfLazyAttribute)
   2086         didAddAttribute(name, value);
   2087 }
   2088 
   2089 void Element::removeAttribute(const AtomicString& name)
   2090 {
   2091     if (!elementData())
   2092         return;
   2093 
   2094     AtomicString localName = shouldIgnoreAttributeCase() ? name.lower() : name;
   2095     size_t index = elementData()->getAttributeItemIndex(localName, false);
   2096     if (index == kNotFound) {
   2097         if (UNLIKELY(localName == styleAttr) && elementData()->m_styleAttributeIsDirty && isStyledElement())
   2098             removeAllInlineStyleProperties();
   2099         return;
   2100     }
   2101 
   2102     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
   2103 }
   2104 
   2105 void Element::removeAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName)
   2106 {
   2107     removeAttribute(QualifiedName(nullAtom, localName, namespaceURI));
   2108 }
   2109 
   2110 PassRefPtr<Attr> Element::getAttributeNode(const AtomicString& localName)
   2111 {
   2112     if (!elementData())
   2113         return 0;
   2114     synchronizeAttribute(localName);
   2115     const Attribute* attribute = elementData()->getAttributeItem(localName, shouldIgnoreAttributeCase());
   2116     if (!attribute)
   2117         return 0;
   2118     return ensureAttr(attribute->name());
   2119 }
   2120 
   2121 PassRefPtr<Attr> Element::getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName)
   2122 {
   2123     if (!elementData())
   2124         return 0;
   2125     QualifiedName qName(nullAtom, localName, namespaceURI);
   2126     synchronizeAttribute(qName);
   2127     const Attribute* attribute = elementData()->getAttributeItem(qName);
   2128     if (!attribute)
   2129         return 0;
   2130     return ensureAttr(attribute->name());
   2131 }
   2132 
   2133 bool Element::hasAttribute(const AtomicString& localName) const
   2134 {
   2135     if (!elementData())
   2136         return false;
   2137     synchronizeAttribute(localName);
   2138     return elementData()->getAttributeItem(shouldIgnoreAttributeCase() ? localName.lower() : localName, false);
   2139 }
   2140 
   2141 bool Element::hasAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const
   2142 {
   2143     if (!elementData())
   2144         return false;
   2145     QualifiedName qName(nullAtom, localName, namespaceURI);
   2146     synchronizeAttribute(qName);
   2147     return elementData()->getAttributeItem(qName);
   2148 }
   2149 
   2150 void Element::focus(bool restorePreviousSelection, FocusDirection direction)
   2151 {
   2152     if (!inDocument())
   2153         return;
   2154 
   2155     Document& doc = document();
   2156     if (doc.focusedElement() == this)
   2157         return;
   2158 
   2159     // If the stylesheets have already been loaded we can reliably check isFocusable.
   2160     // If not, we continue and set the focused node on the focus controller below so
   2161     // that it can be updated soon after attach.
   2162     if (doc.haveStylesheetsLoaded()) {
   2163         doc.updateLayoutIgnorePendingStylesheets();
   2164         if (!isFocusable())
   2165             return;
   2166     }
   2167 
   2168     if (!supportsFocus())
   2169         return;
   2170 
   2171     RefPtr<Node> protect;
   2172     if (Page* page = doc.page()) {
   2173         // Focus and change event handlers can cause us to lose our last ref.
   2174         // If a focus event handler changes the focus to a different node it
   2175         // does not make sense to continue and update appearence.
   2176         protect = this;
   2177         if (!page->focusController().setFocusedElement(this, doc.frame(), direction))
   2178             return;
   2179     }
   2180 
   2181     // Setting the focused node above might have invalidated the layout due to scripts.
   2182     doc.updateLayoutIgnorePendingStylesheets();
   2183 
   2184     if (!isFocusable()) {
   2185         ensureElementRareData().setNeedsFocusAppearanceUpdateSoonAfterAttach(true);
   2186         return;
   2187     }
   2188 
   2189     cancelFocusAppearanceUpdate();
   2190     updateFocusAppearance(restorePreviousSelection);
   2191 }
   2192 
   2193 void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
   2194 {
   2195     if (isRootEditableElement()) {
   2196         Frame* frame = document().frame();
   2197         if (!frame)
   2198             return;
   2199 
   2200         // When focusing an editable element in an iframe, don't reset the selection if it already contains a selection.
   2201         if (this == frame->selection().rootEditableElement())
   2202             return;
   2203 
   2204         // FIXME: We should restore the previous selection if there is one.
   2205         VisibleSelection newSelection = VisibleSelection(firstPositionInOrBeforeNode(this), DOWNSTREAM);
   2206         frame->selection().setSelection(newSelection);
   2207         frame->selection().revealSelection();
   2208     } else if (renderer() && !renderer()->isWidget())
   2209         renderer()->scrollRectToVisible(boundingBox());
   2210 }
   2211 
   2212 void Element::blur()
   2213 {
   2214     cancelFocusAppearanceUpdate();
   2215     if (treeScope().adjustedFocusedElement() == this) {
   2216         Document& doc = document();
   2217         if (doc.page())
   2218             doc.page()->focusController().setFocusedElement(0, doc.frame());
   2219         else
   2220             doc.setFocusedElement(0);
   2221     }
   2222 }
   2223 
   2224 bool Element::isFocusable() const
   2225 {
   2226     return inDocument() && supportsFocus() && !isInert() && rendererIsFocusable();
   2227 }
   2228 
   2229 bool Element::isKeyboardFocusable() const
   2230 {
   2231     return isFocusable() && tabIndex() >= 0;
   2232 }
   2233 
   2234 bool Element::isMouseFocusable() const
   2235 {
   2236     return isFocusable();
   2237 }
   2238 
   2239 void Element::dispatchFocusEvent(Element* oldFocusedElement, FocusDirection)
   2240 {
   2241     RefPtr<FocusEvent> event = FocusEvent::create(EventTypeNames::focus, false, false, document().domWindow(), 0, oldFocusedElement);
   2242     EventDispatcher::dispatchEvent(this, FocusEventDispatchMediator::create(event.release()));
   2243 }
   2244 
   2245 void Element::dispatchBlurEvent(Element* newFocusedElement)
   2246 {
   2247     RefPtr<FocusEvent> event = FocusEvent::create(EventTypeNames::blur, false, false, document().domWindow(), 0, newFocusedElement);
   2248     EventDispatcher::dispatchEvent(this, BlurEventDispatchMediator::create(event.release()));
   2249 }
   2250 
   2251 void Element::dispatchFocusInEvent(const AtomicString& eventType, Element* oldFocusedElement)
   2252 {
   2253     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
   2254     ASSERT(eventType == EventTypeNames::focusin || eventType == EventTypeNames::DOMFocusIn);
   2255     dispatchScopedEventDispatchMediator(FocusInEventDispatchMediator::create(FocusEvent::create(eventType, true, false, document().domWindow(), 0, oldFocusedElement)));
   2256 }
   2257 
   2258 void Element::dispatchFocusOutEvent(const AtomicString& eventType, Element* newFocusedElement)
   2259 {
   2260     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
   2261     ASSERT(eventType == EventTypeNames::focusout || eventType == EventTypeNames::DOMFocusOut);
   2262     dispatchScopedEventDispatchMediator(FocusOutEventDispatchMediator::create(FocusEvent::create(eventType, true, false, document().domWindow(), 0, newFocusedElement)));
   2263 }
   2264 
   2265 String Element::innerHTML() const
   2266 {
   2267     return createMarkup(this, ChildrenOnly);
   2268 }
   2269 
   2270 String Element::outerHTML() const
   2271 {
   2272     return createMarkup(this);
   2273 }
   2274 
   2275 void Element::setInnerHTML(const String& html, ExceptionState& exceptionState)
   2276 {
   2277     if (RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, this, AllowScriptingContent, "innerHTML", exceptionState)) {
   2278         ContainerNode* container = this;
   2279         if (hasTagName(templateTag))
   2280             container = toHTMLTemplateElement(this)->content();
   2281         replaceChildrenWithFragment(container, fragment.release(), exceptionState);
   2282     }
   2283 }
   2284 
   2285 void Element::setOuterHTML(const String& html, ExceptionState& exceptionState)
   2286 {
   2287     Node* p = parentNode();
   2288     if (!p || !p->isElementNode()) {
   2289         exceptionState.throwUninformativeAndGenericDOMException(NoModificationAllowedError);
   2290         return;
   2291     }
   2292     RefPtr<Element> parent = toElement(p);
   2293     RefPtr<Node> prev = previousSibling();
   2294     RefPtr<Node> next = nextSibling();
   2295 
   2296     RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, parent.get(), AllowScriptingContent, "outerHTML", exceptionState);
   2297     if (exceptionState.hadException())
   2298         return;
   2299 
   2300     parent->replaceChild(fragment.release(), this, exceptionState);
   2301     RefPtr<Node> node = next ? next->previousSibling() : 0;
   2302     if (!exceptionState.hadException() && node && node->isTextNode())
   2303         mergeWithNextTextNode(node.release(), exceptionState);
   2304 
   2305     if (!exceptionState.hadException() && prev && prev->isTextNode())
   2306         mergeWithNextTextNode(prev.release(), exceptionState);
   2307 }
   2308 
   2309 Node* Element::insertAdjacent(const String& where, Node* newChild, ExceptionState& exceptionState)
   2310 {
   2311     if (equalIgnoringCase(where, "beforeBegin")) {
   2312         if (ContainerNode* parent = this->parentNode()) {
   2313             parent->insertBefore(newChild, this, exceptionState);
   2314             if (!exceptionState.hadException())
   2315                 return newChild;
   2316         }
   2317         return 0;
   2318     }
   2319 
   2320     if (equalIgnoringCase(where, "afterBegin")) {
   2321         insertBefore(newChild, firstChild(), exceptionState);
   2322         return exceptionState.hadException() ? 0 : newChild;
   2323     }
   2324 
   2325     if (equalIgnoringCase(where, "beforeEnd")) {
   2326         appendChild(newChild, exceptionState);
   2327         return exceptionState.hadException() ? 0 : newChild;
   2328     }
   2329 
   2330     if (equalIgnoringCase(where, "afterEnd")) {
   2331         if (ContainerNode* parent = this->parentNode()) {
   2332             parent->insertBefore(newChild, nextSibling(), exceptionState);
   2333             if (!exceptionState.hadException())
   2334                 return newChild;
   2335         }
   2336         return 0;
   2337     }
   2338 
   2339     exceptionState.throwDOMException(SyntaxError, "The value provided ('" + where + "') is not one of 'beforeBegin', 'afterBegin', 'beforeEnd', or 'afterEnd'.");
   2340     return 0;
   2341 }
   2342 
   2343 // Step 1 of http://domparsing.spec.whatwg.org/#insertadjacenthtml()
   2344 static Element* contextElementForInsertion(const String& where, Element* element, ExceptionState& exceptionState)
   2345 {
   2346     if (equalIgnoringCase(where, "beforeBegin") || equalIgnoringCase(where, "afterEnd")) {
   2347         ContainerNode* parent = element->parentNode();
   2348         if (!parent || !parent->isElementNode()) {
   2349             exceptionState.throwDOMException(NoModificationAllowedError, "The element has no parent.");
   2350             return 0;
   2351         }
   2352         return toElement(parent);
   2353     }
   2354     if (equalIgnoringCase(where, "afterBegin") || equalIgnoringCase(where, "beforeEnd"))
   2355         return element;
   2356     exceptionState.throwDOMException(SyntaxError, "The value provided ('" + where + "') is not one of 'beforeBegin', 'afterBegin', 'beforeEnd', or 'afterEnd'.");
   2357     return 0;
   2358 }
   2359 
   2360 void Element::insertAdjacentHTML(const String& where, const String& markup, ExceptionState& exceptionState)
   2361 {
   2362     RefPtr<Element> contextElement = contextElementForInsertion(where, this, exceptionState);
   2363     if (!contextElement)
   2364         return;
   2365 
   2366     RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup, contextElement.get(), AllowScriptingContent, "insertAdjacentHTML", exceptionState);
   2367     if (!fragment)
   2368         return;
   2369     insertAdjacent(where, fragment.get(), exceptionState);
   2370 }
   2371 
   2372 String Element::innerText()
   2373 {
   2374     // We need to update layout, since plainText uses line boxes in the render tree.
   2375     document().updateLayoutIgnorePendingStylesheets();
   2376 
   2377     if (!renderer())
   2378         return textContent(true);
   2379 
   2380     return plainText(rangeOfContents(const_cast<Element*>(this)).get());
   2381 }
   2382 
   2383 String Element::outerText()
   2384 {
   2385     // Getting outerText is the same as getting innerText, only
   2386     // setting is different. You would think this should get the plain
   2387     // text for the outer range, but this is wrong, <br> for instance
   2388     // would return different values for inner and outer text by such
   2389     // a rule, but it doesn't in WinIE, and we want to match that.
   2390     return innerText();
   2391 }
   2392 
   2393 String Element::textFromChildren()
   2394 {
   2395     Text* firstTextNode = 0;
   2396     bool foundMultipleTextNodes = false;
   2397     unsigned totalLength = 0;
   2398 
   2399     for (Node* child = firstChild(); child; child = child->nextSibling()) {
   2400         if (!child->isTextNode())
   2401             continue;
   2402         Text* text = toText(child);
   2403         if (!firstTextNode)
   2404             firstTextNode = text;
   2405         else
   2406             foundMultipleTextNodes = true;
   2407         unsigned length = text->data().length();
   2408         if (length > std::numeric_limits<unsigned>::max() - totalLength)
   2409             return emptyString();
   2410         totalLength += length;
   2411     }
   2412 
   2413     if (!firstTextNode)
   2414         return emptyString();
   2415 
   2416     if (firstTextNode && !foundMultipleTextNodes) {
   2417         firstTextNode->atomize();
   2418         return firstTextNode->data();
   2419     }
   2420 
   2421     StringBuilder content;
   2422     content.reserveCapacity(totalLength);
   2423     for (Node* child = firstTextNode; child; child = child->nextSibling()) {
   2424         if (!child->isTextNode())
   2425             continue;
   2426         content.append(toText(child)->data());
   2427     }
   2428 
   2429     ASSERT(content.length() == totalLength);
   2430     return content.toString();
   2431 }
   2432 
   2433 // pseudo is used via shadowPseudoId.
   2434 const AtomicString& Element::pseudo() const
   2435 {
   2436     return getAttribute(pseudoAttr);
   2437 }
   2438 
   2439 void Element::setPseudo(const AtomicString& value)
   2440 {
   2441     setAttribute(pseudoAttr, value);
   2442 }
   2443 
   2444 bool Element::isInDescendantTreeOf(const Element* shadowHost) const
   2445 {
   2446     ASSERT(shadowHost);
   2447     ASSERT(isShadowHost(shadowHost));
   2448 
   2449     const ShadowRoot* shadowRoot = containingShadowRoot();
   2450     while (shadowRoot) {
   2451         const Element* ancestorShadowHost = shadowRoot->shadowHost();
   2452         if (ancestorShadowHost == shadowHost)
   2453             return true;
   2454         shadowRoot = ancestorShadowHost->containingShadowRoot();
   2455     }
   2456     return false;
   2457 }
   2458 
   2459 LayoutSize Element::minimumSizeForResizing() const
   2460 {
   2461     return hasRareData() ? elementRareData()->minimumSizeForResizing() : defaultMinimumSizeForResizing();
   2462 }
   2463 
   2464 void Element::setMinimumSizeForResizing(const LayoutSize& size)
   2465 {
   2466     if (!hasRareData() && size == defaultMinimumSizeForResizing())
   2467         return;
   2468     ensureElementRareData().setMinimumSizeForResizing(size);
   2469 }
   2470 
   2471 RenderStyle* Element::computedStyle(PseudoId pseudoElementSpecifier)
   2472 {
   2473     if (PseudoElement* element = pseudoElement(pseudoElementSpecifier))
   2474         return element->computedStyle();
   2475 
   2476     // FIXME: Find and use the renderer from the pseudo element instead of the actual element so that the 'length'
   2477     // properties, which are only known by the renderer because it did the layout, will be correct and so that the
   2478     // values returned for the ":selection" pseudo-element will be correct.
   2479     if (RenderStyle* usedStyle = renderStyle()) {
   2480         if (pseudoElementSpecifier) {
   2481             RenderStyle* cachedPseudoStyle = usedStyle->getCachedPseudoStyle(pseudoElementSpecifier);
   2482             return cachedPseudoStyle ? cachedPseudoStyle : usedStyle;
   2483          } else
   2484             return usedStyle;
   2485     }
   2486 
   2487     if (!inActiveDocument())
   2488         // FIXME: Try to do better than this. Ensure that styleForElement() works for elements that are not in the
   2489         // document tree and figure out when to destroy the computed style for such elements.
   2490         return 0;
   2491 
   2492     ElementRareData& rareData = ensureElementRareData();
   2493     if (!rareData.computedStyle())
   2494         rareData.setComputedStyle(document().styleForElementIgnoringPendingStylesheets(this));
   2495     return pseudoElementSpecifier ? rareData.computedStyle()->getCachedPseudoStyle(pseudoElementSpecifier) : rareData.computedStyle();
   2496 }
   2497 
   2498 void Element::setStyleAffectedByEmpty()
   2499 {
   2500     ensureElementRareData().setStyleAffectedByEmpty(true);
   2501 }
   2502 
   2503 void Element::setChildrenAffectedByFocus()
   2504 {
   2505     ensureElementRareData().setChildrenAffectedByFocus(true);
   2506 }
   2507 
   2508 void Element::setChildrenAffectedByHover()
   2509 {
   2510     ensureElementRareData().setChildrenAffectedByHover(true);
   2511 }
   2512 
   2513 void Element::setChildrenAffectedByActive()
   2514 {
   2515     ensureElementRareData().setChildrenAffectedByActive(true);
   2516 }
   2517 
   2518 void Element::setChildrenAffectedByDrag()
   2519 {
   2520     ensureElementRareData().setChildrenAffectedByDrag(true);
   2521 }
   2522 
   2523 void Element::setChildrenAffectedByFirstChildRules()
   2524 {
   2525     ensureElementRareData().setChildrenAffectedByFirstChildRules(true);
   2526 }
   2527 
   2528 void Element::setChildrenAffectedByLastChildRules()
   2529 {
   2530     ensureElementRareData().setChildrenAffectedByLastChildRules(true);
   2531 }
   2532 
   2533 void Element::setChildrenAffectedByDirectAdjacentRules()
   2534 {
   2535     ensureElementRareData().setChildrenAffectedByDirectAdjacentRules(true);
   2536 }
   2537 
   2538 void Element::setChildrenAffectedByForwardPositionalRules()
   2539 {
   2540     ensureElementRareData().setChildrenAffectedByForwardPositionalRules(true);
   2541 }
   2542 
   2543 void Element::setChildrenAffectedByBackwardPositionalRules()
   2544 {
   2545     ensureElementRareData().setChildrenAffectedByBackwardPositionalRules(true);
   2546 }
   2547 
   2548 void Element::setChildIndex(unsigned index)
   2549 {
   2550     ElementRareData& rareData = ensureElementRareData();
   2551     if (RenderStyle* style = renderStyle())
   2552         style->setUnique();
   2553     rareData.setChildIndex(index);
   2554 }
   2555 
   2556 bool Element::childrenSupportStyleSharing() const
   2557 {
   2558     if (!hasRareData())
   2559         return true;
   2560     return !rareDataChildrenAffectedByFocus()
   2561         && !rareDataChildrenAffectedByHover()
   2562         && !rareDataChildrenAffectedByActive()
   2563         && !rareDataChildrenAffectedByDrag()
   2564         && !rareDataChildrenAffectedByFirstChildRules()
   2565         && !rareDataChildrenAffectedByLastChildRules()
   2566         && !rareDataChildrenAffectedByDirectAdjacentRules()
   2567         && !rareDataChildrenAffectedByForwardPositionalRules()
   2568         && !rareDataChildrenAffectedByBackwardPositionalRules();
   2569 }
   2570 
   2571 bool Element::rareDataStyleAffectedByEmpty() const
   2572 {
   2573     ASSERT(hasRareData());
   2574     return elementRareData()->styleAffectedByEmpty();
   2575 }
   2576 
   2577 bool Element::rareDataChildrenAffectedByFocus() const
   2578 {
   2579     ASSERT(hasRareData());
   2580     return elementRareData()->childrenAffectedByFocus();
   2581 }
   2582 
   2583 bool Element::rareDataChildrenAffectedByHover() const
   2584 {
   2585     ASSERT(hasRareData());
   2586     return elementRareData()->childrenAffectedByHover();
   2587 }
   2588 
   2589 bool Element::rareDataChildrenAffectedByActive() const
   2590 {
   2591     ASSERT(hasRareData());
   2592     return elementRareData()->childrenAffectedByActive();
   2593 }
   2594 
   2595 bool Element::rareDataChildrenAffectedByDrag() const
   2596 {
   2597     ASSERT(hasRareData());
   2598     return elementRareData()->childrenAffectedByDrag();
   2599 }
   2600 
   2601 bool Element::rareDataChildrenAffectedByFirstChildRules() const
   2602 {
   2603     ASSERT(hasRareData());
   2604     return elementRareData()->childrenAffectedByFirstChildRules();
   2605 }
   2606 
   2607 bool Element::rareDataChildrenAffectedByLastChildRules() const
   2608 {
   2609     ASSERT(hasRareData());
   2610     return elementRareData()->childrenAffectedByLastChildRules();
   2611 }
   2612 
   2613 bool Element::rareDataChildrenAffectedByDirectAdjacentRules() const
   2614 {
   2615     ASSERT(hasRareData());
   2616     return elementRareData()->childrenAffectedByDirectAdjacentRules();
   2617 }
   2618 
   2619 bool Element::rareDataChildrenAffectedByForwardPositionalRules() const
   2620 {
   2621     ASSERT(hasRareData());
   2622     return elementRareData()->childrenAffectedByForwardPositionalRules();
   2623 }
   2624 
   2625 bool Element::rareDataChildrenAffectedByBackwardPositionalRules() const
   2626 {
   2627     ASSERT(hasRareData());
   2628     return elementRareData()->childrenAffectedByBackwardPositionalRules();
   2629 }
   2630 
   2631 unsigned Element::rareDataChildIndex() const
   2632 {
   2633     ASSERT(hasRareData());
   2634     return elementRareData()->childIndex();
   2635 }
   2636 
   2637 void Element::setIsInCanvasSubtree(bool isInCanvasSubtree)
   2638 {
   2639     ensureElementRareData().setIsInCanvasSubtree(isInCanvasSubtree);
   2640 }
   2641 
   2642 bool Element::isInCanvasSubtree() const
   2643 {
   2644     return hasRareData() && elementRareData()->isInCanvasSubtree();
   2645 }
   2646 
   2647 void Element::setIsInsideRegion(bool value)
   2648 {
   2649     if (value == isInsideRegion())
   2650         return;
   2651 
   2652     ensureElementRareData().setIsInsideRegion(value);
   2653 }
   2654 
   2655 bool Element::isInsideRegion() const
   2656 {
   2657     return hasRareData() ? elementRareData()->isInsideRegion() : false;
   2658 }
   2659 
   2660 void Element::setRegionOversetState(RegionOversetState state)
   2661 {
   2662     ensureElementRareData().setRegionOversetState(state);
   2663 }
   2664 
   2665 RegionOversetState Element::regionOversetState() const
   2666 {
   2667     return hasRareData() ? elementRareData()->regionOversetState() : RegionUndefined;
   2668 }
   2669 
   2670 AtomicString Element::computeInheritedLanguage() const
   2671 {
   2672     const Node* n = this;
   2673     AtomicString value;
   2674     // The language property is inherited, so we iterate over the parents to find the first language.
   2675     do {
   2676         if (n->isElementNode()) {
   2677             if (const ElementData* elementData = toElement(n)->elementData()) {
   2678                 // Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7
   2679                 if (const Attribute* attribute = elementData->getAttributeItem(XMLNames::langAttr))
   2680                     value = attribute->value();
   2681                 else if (const Attribute* attribute = elementData->getAttributeItem(HTMLNames::langAttr))
   2682                     value = attribute->value();
   2683             }
   2684         } else if (n->isDocumentNode()) {
   2685             // checking the MIME content-language
   2686             value = toDocument(n)->contentLanguage();
   2687         }
   2688 
   2689         n = n->parentNode();
   2690     } while (n && value.isNull());
   2691 
   2692     return value;
   2693 }
   2694 
   2695 Locale& Element::locale() const
   2696 {
   2697     return document().getCachedLocale(computeInheritedLanguage());
   2698 }
   2699 
   2700 void Element::cancelFocusAppearanceUpdate()
   2701 {
   2702     if (hasRareData())
   2703         elementRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
   2704     if (document().focusedElement() == this)
   2705         document().cancelFocusAppearanceUpdate();
   2706 }
   2707 
   2708 void Element::normalizeAttributes()
   2709 {
   2710     if (!hasAttributes())
   2711         return;
   2712     for (unsigned i = 0; i < attributeCount(); ++i) {
   2713         if (RefPtr<Attr> attr = attrIfExists(attributeItem(i)->name()))
   2714             attr->normalize();
   2715     }
   2716 }
   2717 
   2718 void Element::updatePseudoElement(PseudoId pseudoId, StyleRecalcChange change)
   2719 {
   2720     PseudoElement* element = pseudoElement(pseudoId);
   2721     if (element && (needsStyleRecalc() || shouldRecalcStyle(change, element))) {
   2722         // Need to clear the cached style if the PseudoElement wants a recalc so it
   2723         // computes a new style.
   2724         if (element->needsStyleRecalc())
   2725             renderer()->style()->removeCachedPseudoStyle(pseudoId);
   2726 
   2727         // PseudoElement styles hang off their parent element's style so if we needed
   2728         // a style recalc we should Force one on the pseudo.
   2729         // FIXME: We should figure out the right text sibling to pass.
   2730         element->recalcStyle(needsStyleRecalc() ? Force : change);
   2731 
   2732         // Wait until our parent is not displayed or pseudoElementRendererIsNeeded
   2733         // is false, otherwise we could continously create and destroy PseudoElements
   2734         // when RenderObject::isChildAllowed on our parent returns false for the
   2735         // PseudoElement's renderer for each style recalc.
   2736         if (!renderer() || !pseudoElementRendererIsNeeded(renderer()->getCachedPseudoStyle(pseudoId)))
   2737             elementRareData()->setPseudoElement(pseudoId, 0);
   2738     } else if (change >= Inherit || needsStyleRecalc())
   2739         createPseudoElementIfNeeded(pseudoId);
   2740 }
   2741 
   2742 bool Element::needsPseudoElement(PseudoId pseudoId, const RenderStyle& style) const
   2743 {
   2744     if (pseudoId == BACKDROP && !isInTopLayer())
   2745         return false;
   2746     if (!renderer() || !pseudoElementRendererIsNeeded(&style))
   2747         return false;
   2748     if (!renderer()->canHaveGeneratedChildren())
   2749         return false;
   2750     return true;
   2751 }
   2752 
   2753 void Element::createPseudoElementIfNeeded(PseudoId pseudoId)
   2754 {
   2755     if (isPseudoElement())
   2756         return;
   2757 
   2758     RefPtr<PseudoElement> element = document().ensureStyleResolver().createPseudoElementIfNeeded(*this, pseudoId);
   2759     if (!element)
   2760         return;
   2761 
   2762     if (pseudoId == BACKDROP)
   2763         document().addToTopLayer(element.get(), this);
   2764     element->insertedInto(this);
   2765     element->attach();
   2766 
   2767     InspectorInstrumentation::pseudoElementCreated(element.get());
   2768 
   2769     ensureElementRareData().setPseudoElement(pseudoId, element.release());
   2770 }
   2771 
   2772 PseudoElement* Element::pseudoElement(PseudoId pseudoId) const
   2773 {
   2774     return hasRareData() ? elementRareData()->pseudoElement(pseudoId) : 0;
   2775 }
   2776 
   2777 RenderObject* Element::pseudoElementRenderer(PseudoId pseudoId) const
   2778 {
   2779     if (PseudoElement* element = pseudoElement(pseudoId))
   2780         return element->renderer();
   2781     return 0;
   2782 }
   2783 
   2784 bool Element::webkitMatchesSelector(const String& selector, ExceptionState& exceptionState)
   2785 {
   2786     if (selector.isEmpty()) {
   2787         exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
   2788         return false;
   2789     }
   2790 
   2791     SelectorQuery* selectorQuery = document().selectorQueryCache().add(selector, document(), exceptionState);
   2792     if (!selectorQuery)
   2793         return false;
   2794     return selectorQuery->matches(*this);
   2795 }
   2796 
   2797 DOMTokenList* Element::classList()
   2798 {
   2799     ElementRareData& rareData = ensureElementRareData();
   2800     if (!rareData.classList())
   2801         rareData.setClassList(ClassList::create(this));
   2802     return rareData.classList();
   2803 }
   2804 
   2805 DOMStringMap* Element::dataset()
   2806 {
   2807     ElementRareData& rareData = ensureElementRareData();
   2808     if (!rareData.dataset())
   2809         rareData.setDataset(DatasetDOMStringMap::create(this));
   2810     return rareData.dataset();
   2811 }
   2812 
   2813 KURL Element::getURLAttribute(const QualifiedName& name) const
   2814 {
   2815 #if !ASSERT_DISABLED
   2816     if (elementData()) {
   2817         if (const Attribute* attribute = getAttributeItem(name))
   2818             ASSERT(isURLAttribute(*attribute));
   2819     }
   2820 #endif
   2821     return document().completeURL(stripLeadingAndTrailingHTMLSpaces(getAttribute(name)));
   2822 }
   2823 
   2824 KURL Element::getNonEmptyURLAttribute(const QualifiedName& name) const
   2825 {
   2826 #if !ASSERT_DISABLED
   2827     if (elementData()) {
   2828         if (const Attribute* attribute = getAttributeItem(name))
   2829             ASSERT(isURLAttribute(*attribute));
   2830     }
   2831 #endif
   2832     String value = stripLeadingAndTrailingHTMLSpaces(getAttribute(name));
   2833     if (value.isEmpty())
   2834         return KURL();
   2835     return document().completeURL(value);
   2836 }
   2837 
   2838 int Element::getIntegralAttribute(const QualifiedName& attributeName) const
   2839 {
   2840     return getAttribute(attributeName).string().toInt();
   2841 }
   2842 
   2843 void Element::setIntegralAttribute(const QualifiedName& attributeName, int value)
   2844 {
   2845     setAttribute(attributeName, AtomicString::number(value));
   2846 }
   2847 
   2848 unsigned Element::getUnsignedIntegralAttribute(const QualifiedName& attributeName) const
   2849 {
   2850     return getAttribute(attributeName).string().toUInt();
   2851 }
   2852 
   2853 void Element::setUnsignedIntegralAttribute(const QualifiedName& attributeName, unsigned value)
   2854 {
   2855     // Range restrictions are enforced for unsigned IDL attributes that
   2856     // reflect content attributes,
   2857     //   http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#reflecting-content-attributes-in-idl-attributes
   2858     if (value > 0x7fffffffu)
   2859         value = 0;
   2860     setAttribute(attributeName, AtomicString::number(value));
   2861 }
   2862 
   2863 double Element::getFloatingPointAttribute(const QualifiedName& attributeName, double fallbackValue) const
   2864 {
   2865     return parseToDoubleForNumberType(getAttribute(attributeName), fallbackValue);
   2866 }
   2867 
   2868 void Element::setFloatingPointAttribute(const QualifiedName& attributeName, double value)
   2869 {
   2870     setAttribute(attributeName, AtomicString::number(value));
   2871 }
   2872 
   2873 bool Element::childShouldCreateRenderer(const Node& child) const
   2874 {
   2875     // Only create renderers for SVG elements whose parents are SVG elements, or for proper <svg xmlns="svgNS"> subdocuments.
   2876     if (child.isSVGElement())
   2877         return child.hasTagName(SVGNames::svgTag) || isSVGElement();
   2878 
   2879     return ContainerNode::childShouldCreateRenderer(child);
   2880 }
   2881 
   2882 void Element::webkitRequestFullscreen()
   2883 {
   2884     FullscreenElementStack::from(&document())->requestFullScreenForElement(this, ALLOW_KEYBOARD_INPUT, FullscreenElementStack::EnforceIFrameAllowFullScreenRequirement);
   2885 }
   2886 
   2887 void Element::webkitRequestFullScreen(unsigned short flags)
   2888 {
   2889     FullscreenElementStack::from(&document())->requestFullScreenForElement(this, (flags | LEGACY_MOZILLA_REQUEST), FullscreenElementStack::EnforceIFrameAllowFullScreenRequirement);
   2890 }
   2891 
   2892 bool Element::containsFullScreenElement() const
   2893 {
   2894     return hasRareData() && elementRareData()->containsFullScreenElement();
   2895 }
   2896 
   2897 void Element::setContainsFullScreenElement(bool flag)
   2898 {
   2899     ensureElementRareData().setContainsFullScreenElement(flag);
   2900     setNeedsStyleRecalc(SubtreeStyleChange);
   2901 }
   2902 
   2903 static Element* parentCrossingFrameBoundaries(Element* element)
   2904 {
   2905     ASSERT(element);
   2906     return element->parentElement() ? element->parentElement() : element->document().ownerElement();
   2907 }
   2908 
   2909 void Element::setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(bool flag)
   2910 {
   2911     Element* element = this;
   2912     while ((element = parentCrossingFrameBoundaries(element)))
   2913         element->setContainsFullScreenElement(flag);
   2914 }
   2915 
   2916 bool Element::isInTopLayer() const
   2917 {
   2918     return hasRareData() && elementRareData()->isInTopLayer();
   2919 }
   2920 
   2921 void Element::setIsInTopLayer(bool inTopLayer)
   2922 {
   2923     if (isInTopLayer() == inTopLayer)
   2924         return;
   2925     ensureElementRareData().setIsInTopLayer(inTopLayer);
   2926 
   2927     // We must ensure a reattach occurs so the renderer is inserted in the correct sibling order under RenderView according to its
   2928     // top layer position, or in its usual place if not in the top layer.
   2929     lazyReattachIfAttached();
   2930 }
   2931 
   2932 void Element::webkitRequestPointerLock()
   2933 {
   2934     if (document().page())
   2935         document().page()->pointerLockController().requestPointerLock(this);
   2936 }
   2937 
   2938 SpellcheckAttributeState Element::spellcheckAttributeState() const
   2939 {
   2940     const AtomicString& value = getAttribute(HTMLNames::spellcheckAttr);
   2941     if (value == nullAtom)
   2942         return SpellcheckAttributeDefault;
   2943     if (equalIgnoringCase(value, "true") || equalIgnoringCase(value, ""))
   2944         return SpellcheckAttributeTrue;
   2945     if (equalIgnoringCase(value, "false"))
   2946         return SpellcheckAttributeFalse;
   2947 
   2948     return SpellcheckAttributeDefault;
   2949 }
   2950 
   2951 bool Element::isSpellCheckingEnabled() const
   2952 {
   2953     for (const Element* element = this; element; element = element->parentOrShadowHostElement()) {
   2954         switch (element->spellcheckAttributeState()) {
   2955         case SpellcheckAttributeTrue:
   2956             return true;
   2957         case SpellcheckAttributeFalse:
   2958             return false;
   2959         case SpellcheckAttributeDefault:
   2960             break;
   2961         }
   2962     }
   2963 
   2964     return true;
   2965 }
   2966 
   2967 RenderRegion* Element::renderRegion() const
   2968 {
   2969     if (renderer() && renderer()->isRenderNamedFlowFragmentContainer())
   2970         return toRenderBlockFlow(renderer())->renderNamedFlowFragment();
   2971 
   2972     return 0;
   2973 }
   2974 
   2975 bool Element::shouldMoveToFlowThread(RenderStyle* styleToUse) const
   2976 {
   2977     ASSERT(styleToUse);
   2978 
   2979     if (FullscreenElementStack::isActiveFullScreenElement(this))
   2980         return false;
   2981 
   2982     if (isInShadowTree())
   2983         return false;
   2984 
   2985     if (styleToUse->flowThread().isEmpty())
   2986         return false;
   2987 
   2988     return !isRegisteredWithNamedFlow();
   2989 }
   2990 
   2991 const AtomicString& Element::webkitRegionOverset() const
   2992 {
   2993     DEFINE_STATIC_LOCAL(AtomicString, undefinedState, ("undefined", AtomicString::ConstructFromLiteral));
   2994     if (!RuntimeEnabledFeatures::cssRegionsEnabled())
   2995         return undefinedState;
   2996 
   2997     document().updateLayoutIgnorePendingStylesheets();
   2998 
   2999     if (!renderRegion())
   3000         return undefinedState;
   3001 
   3002     switch (renderRegion()->regionOversetState()) {
   3003     case RegionFit: {
   3004         DEFINE_STATIC_LOCAL(AtomicString, fitState, ("fit", AtomicString::ConstructFromLiteral));
   3005         return fitState;
   3006     }
   3007     case RegionEmpty: {
   3008         DEFINE_STATIC_LOCAL(AtomicString, emptyState, ("empty", AtomicString::ConstructFromLiteral));
   3009         return emptyState;
   3010     }
   3011     case RegionOverset: {
   3012         DEFINE_STATIC_LOCAL(AtomicString, overflowState, ("overset", AtomicString::ConstructFromLiteral));
   3013         return overflowState;
   3014     }
   3015     case RegionUndefined:
   3016         return undefinedState;
   3017     }
   3018 
   3019     ASSERT_NOT_REACHED();
   3020     return undefinedState;
   3021 }
   3022 
   3023 Vector<RefPtr<Range> > Element::webkitGetRegionFlowRanges() const
   3024 {
   3025     Vector<RefPtr<Range> > rangeObjects;
   3026     if (!RuntimeEnabledFeatures::cssRegionsEnabled())
   3027         return rangeObjects;
   3028 
   3029     document().updateLayoutIgnorePendingStylesheets();
   3030 
   3031     if (renderer() && renderer()->isRenderNamedFlowFragmentContainer()) {
   3032         RenderNamedFlowFragment* region = toRenderBlockFlow(renderer())->renderNamedFlowFragment();
   3033         if (region->isValid())
   3034             region->getRanges(rangeObjects);
   3035     }
   3036 
   3037     return rangeObjects;
   3038 }
   3039 
   3040 #ifndef NDEBUG
   3041 bool Element::fastAttributeLookupAllowed(const QualifiedName& name) const
   3042 {
   3043     if (name == HTMLNames::styleAttr)
   3044         return false;
   3045 
   3046     if (isSVGElement())
   3047         return !toSVGElement(this)->isAnimatableAttribute(name);
   3048 
   3049     return true;
   3050 }
   3051 #endif
   3052 
   3053 #ifdef DUMP_NODE_STATISTICS
   3054 bool Element::hasNamedNodeMap() const
   3055 {
   3056     return hasRareData() && elementRareData()->attributeMap();
   3057 }
   3058 #endif
   3059 
   3060 inline void Element::updateName(const AtomicString& oldName, const AtomicString& newName)
   3061 {
   3062     if (!inDocument() || isInShadowTree())
   3063         return;
   3064 
   3065     if (oldName == newName)
   3066         return;
   3067 
   3068     if (shouldRegisterAsNamedItem())
   3069         updateNamedItemRegistration(oldName, newName);
   3070 }
   3071 
   3072 inline void Element::updateId(const AtomicString& oldId, const AtomicString& newId)
   3073 {
   3074     if (!isInTreeScope())
   3075         return;
   3076 
   3077     if (oldId == newId)
   3078         return;
   3079 
   3080     updateId(treeScope(), oldId, newId);
   3081 }
   3082 
   3083 inline void Element::updateId(TreeScope& scope, const AtomicString& oldId, const AtomicString& newId)
   3084 {
   3085     ASSERT(isInTreeScope());
   3086     ASSERT(oldId != newId);
   3087 
   3088     if (!oldId.isEmpty())
   3089         scope.removeElementById(oldId, this);
   3090     if (!newId.isEmpty())
   3091         scope.addElementById(newId, this);
   3092 
   3093     if (shouldRegisterAsExtraNamedItem())
   3094         updateExtraNamedItemRegistration(oldId, newId);
   3095 }
   3096 
   3097 void Element::updateLabel(TreeScope& scope, const AtomicString& oldForAttributeValue, const AtomicString& newForAttributeValue)
   3098 {
   3099     ASSERT(hasTagName(labelTag));
   3100 
   3101     if (!inDocument())
   3102         return;
   3103 
   3104     if (oldForAttributeValue == newForAttributeValue)
   3105         return;
   3106 
   3107     if (!oldForAttributeValue.isEmpty())
   3108         scope.removeLabel(oldForAttributeValue, toHTMLLabelElement(this));
   3109     if (!newForAttributeValue.isEmpty())
   3110         scope.addLabel(newForAttributeValue, toHTMLLabelElement(this));
   3111 }
   3112 
   3113 static bool hasSelectorForAttribute(Document* document, const AtomicString& localName)
   3114 {
   3115     return document->ensureStyleResolver().ensureRuleFeatureSet().hasSelectorForAttribute(localName);
   3116 }
   3117 
   3118 void Element::willModifyAttribute(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue)
   3119 {
   3120     if (isIdAttributeName(name))
   3121         updateId(oldValue, newValue);
   3122     else if (name == HTMLNames::nameAttr)
   3123         updateName(oldValue, newValue);
   3124     else if (name == HTMLNames::forAttr && hasTagName(labelTag)) {
   3125         TreeScope& scope = treeScope();
   3126         if (scope.shouldCacheLabelsByForAttribute())
   3127             updateLabel(scope, oldValue, newValue);
   3128     }
   3129 
   3130     if (oldValue != newValue) {
   3131         if (inActiveDocument() && hasSelectorForAttribute(&document(), name.localName()))
   3132            setNeedsStyleRecalc();
   3133 
   3134         if (isUpgradedCustomElement())
   3135             CustomElement::attributeDidChange(this, name.localName(), oldValue, newValue);
   3136     }
   3137 
   3138     if (OwnPtr<MutationObserverInterestGroup> recipients = MutationObserverInterestGroup::createForAttributesMutation(*this, name))
   3139         recipients->enqueueMutationRecord(MutationRecord::createAttributes(this, name, oldValue));
   3140 
   3141     InspectorInstrumentation::willModifyDOMAttr(this, oldValue, newValue);
   3142 }
   3143 
   3144 void Element::didAddAttribute(const QualifiedName& name, const AtomicString& value)
   3145 {
   3146     attributeChanged(name, value);
   3147     InspectorInstrumentation::didModifyDOMAttr(this, name.localName(), value);
   3148     dispatchSubtreeModifiedEvent();
   3149 }
   3150 
   3151 void Element::didModifyAttribute(const QualifiedName& name, const AtomicString& value)
   3152 {
   3153     attributeChanged(name, value);
   3154     InspectorInstrumentation::didModifyDOMAttr(this, name.localName(), value);
   3155     // Do not dispatch a DOMSubtreeModified event here; see bug 81141.
   3156 }
   3157 
   3158 void Element::didRemoveAttribute(const QualifiedName& name)
   3159 {
   3160     attributeChanged(name, nullAtom);
   3161     InspectorInstrumentation::didRemoveDOMAttr(this, name.localName());
   3162     dispatchSubtreeModifiedEvent();
   3163 }
   3164 
   3165 void Element::didMoveToNewDocument(Document& oldDocument)
   3166 {
   3167     Node::didMoveToNewDocument(oldDocument);
   3168 
   3169     // If the documents differ by quirks mode then they differ by case sensitivity
   3170     // for class and id names so we need to go through the attribute change logic
   3171     // to pick up the new casing in the ElementData.
   3172     if (oldDocument.inQuirksMode() != document().inQuirksMode()) {
   3173         if (hasID())
   3174             setIdAttribute(getIdAttribute());
   3175         if (hasClass())
   3176             setAttribute(HTMLNames::classAttr, getClassAttribute());
   3177     }
   3178 }
   3179 
   3180 void Element::updateNamedItemRegistration(const AtomicString& oldName, const AtomicString& newName)
   3181 {
   3182     if (!document().isHTMLDocument())
   3183         return;
   3184 
   3185     if (!oldName.isEmpty())
   3186         toHTMLDocument(document()).removeNamedItem(oldName);
   3187 
   3188     if (!newName.isEmpty())
   3189         toHTMLDocument(document()).addNamedItem(newName);
   3190 }
   3191 
   3192 void Element::updateExtraNamedItemRegistration(const AtomicString& oldId, const AtomicString& newId)
   3193 {
   3194     if (!document().isHTMLDocument())
   3195         return;
   3196 
   3197     if (!oldId.isEmpty())
   3198         toHTMLDocument(document()).removeExtraNamedItem(oldId);
   3199 
   3200     if (!newId.isEmpty())
   3201         toHTMLDocument(document()).addExtraNamedItem(newId);
   3202 }
   3203 
   3204 PassRefPtr<HTMLCollection> Element::ensureCachedHTMLCollection(CollectionType type)
   3205 {
   3206     if (HTMLCollection* collection = cachedHTMLCollection(type))
   3207         return collection;
   3208 
   3209     RefPtr<HTMLCollection> collection;
   3210     if (type == TableRows) {
   3211         ASSERT(hasTagName(tableTag));
   3212         return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLTableRowsCollection>(this, type);
   3213     } else if (type == SelectOptions) {
   3214         ASSERT(hasTagName(selectTag));
   3215         return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLOptionsCollection>(this, type);
   3216     } else if (type == FormControls) {
   3217         ASSERT(hasTagName(formTag) || hasTagName(fieldsetTag));
   3218         return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLFormControlsCollection>(this, type);
   3219     }
   3220     return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLCollection>(this, type);
   3221 }
   3222 
   3223 static void scheduleLayerUpdateCallback(Node* node)
   3224 {
   3225     // Notify the renderer even is the styles are identical since it may need to
   3226     // create or destroy a RenderLayer.
   3227     node->setNeedsStyleRecalc(LocalStyleChange, StyleChangeFromRenderer);
   3228 }
   3229 
   3230 void Element::scheduleLayerUpdate()
   3231 {
   3232     if (document().inStyleRecalc())
   3233         PostAttachCallbacks::queueCallback(scheduleLayerUpdateCallback, this);
   3234     else
   3235         scheduleLayerUpdateCallback(this);
   3236 }
   3237 
   3238 HTMLCollection* Element::cachedHTMLCollection(CollectionType type)
   3239 {
   3240     return hasRareData() && rareData()->nodeLists() ? rareData()->nodeLists()->cacheWithAtomicName<HTMLCollection>(type) : 0;
   3241 }
   3242 
   3243 IntSize Element::savedLayerScrollOffset() const
   3244 {
   3245     return hasRareData() ? elementRareData()->savedLayerScrollOffset() : IntSize();
   3246 }
   3247 
   3248 void Element::setSavedLayerScrollOffset(const IntSize& size)
   3249 {
   3250     if (size.isZero() && !hasRareData())
   3251         return;
   3252     ensureElementRareData().setSavedLayerScrollOffset(size);
   3253 }
   3254 
   3255 PassRefPtr<Attr> Element::attrIfExists(const QualifiedName& name)
   3256 {
   3257     if (AttrNodeList* attrNodeList = attrNodeListForElement(this))
   3258         return findAttrNodeInList(*attrNodeList, name);
   3259     return 0;
   3260 }
   3261 
   3262 PassRefPtr<Attr> Element::ensureAttr(const QualifiedName& name)
   3263 {
   3264     AttrNodeList& attrNodeList = ensureAttrNodeListForElement(this);
   3265     RefPtr<Attr> attrNode = findAttrNodeInList(attrNodeList, name);
   3266     if (!attrNode) {
   3267         attrNode = Attr::create(*this, name);
   3268         treeScope().adoptIfNeeded(*attrNode);
   3269         attrNodeList.append(attrNode);
   3270     }
   3271     return attrNode.release();
   3272 }
   3273 
   3274 void Element::detachAttrNodeFromElementWithValue(Attr* attrNode, const AtomicString& value)
   3275 {
   3276     ASSERT(hasSyntheticAttrChildNodes());
   3277     attrNode->detachFromElementWithValue(value);
   3278 
   3279     AttrNodeList* attrNodeList = attrNodeListForElement(this);
   3280     for (unsigned i = 0; i < attrNodeList->size(); ++i) {
   3281         if (attrNodeList->at(i)->qualifiedName() == attrNode->qualifiedName()) {
   3282             attrNodeList->remove(i);
   3283             if (attrNodeList->isEmpty())
   3284                 removeAttrNodeListForElement(this);
   3285             return;
   3286         }
   3287     }
   3288     ASSERT_NOT_REACHED();
   3289 }
   3290 
   3291 void Element::detachAllAttrNodesFromElement()
   3292 {
   3293     AttrNodeList* attrNodeList = attrNodeListForElement(this);
   3294     ASSERT(attrNodeList);
   3295 
   3296     for (unsigned i = 0; i < attributeCount(); ++i) {
   3297         const Attribute* attribute = attributeItem(i);
   3298         if (RefPtr<Attr> attrNode = findAttrNodeInList(*attrNodeList, attribute->name()))
   3299             attrNode->detachFromElementWithValue(attribute->value());
   3300     }
   3301 
   3302     removeAttrNodeListForElement(this);
   3303 }
   3304 
   3305 void Element::willRecalcStyle(StyleRecalcChange)
   3306 {
   3307     ASSERT(hasCustomStyleCallbacks());
   3308 }
   3309 
   3310 void Element::didRecalcStyle(StyleRecalcChange)
   3311 {
   3312     ASSERT(hasCustomStyleCallbacks());
   3313 }
   3314 
   3315 
   3316 PassRefPtr<RenderStyle> Element::customStyleForRenderer()
   3317 {
   3318     ASSERT(hasCustomStyleCallbacks());
   3319     return 0;
   3320 }
   3321 
   3322 void Element::cloneAttributesFromElement(const Element& other)
   3323 {
   3324     if (hasSyntheticAttrChildNodes())
   3325         detachAllAttrNodesFromElement();
   3326 
   3327     other.synchronizeAllAttributes();
   3328     if (!other.m_elementData) {
   3329         m_elementData.clear();
   3330         return;
   3331     }
   3332 
   3333     const AtomicString& oldID = getIdAttribute();
   3334     const AtomicString& newID = other.getIdAttribute();
   3335 
   3336     if (!oldID.isNull() || !newID.isNull())
   3337         updateId(oldID, newID);
   3338 
   3339     const AtomicString& oldName = getNameAttribute();
   3340     const AtomicString& newName = other.getNameAttribute();
   3341 
   3342     if (!oldName.isNull() || !newName.isNull())
   3343         updateName(oldName, newName);
   3344 
   3345     // Quirks mode makes class and id not case sensitive. We can't share the ElementData
   3346     // if the idForStyleResolution and the className need different casing.
   3347     bool ownerDocumentsHaveDifferentCaseSensitivity = false;
   3348     if (other.hasClass() || other.hasID())
   3349         ownerDocumentsHaveDifferentCaseSensitivity = other.document().inQuirksMode() != document().inQuirksMode();
   3350 
   3351     // If 'other' has a mutable ElementData, convert it to an immutable one so we can share it between both elements.
   3352     // We can only do this if there is no CSSOM wrapper for other's inline style, and there are no presentation attributes,
   3353     // and sharing the data won't result in different case sensitivity of class or id.
   3354     if (other.m_elementData->isUnique()
   3355         && !ownerDocumentsHaveDifferentCaseSensitivity
   3356         && !other.m_elementData->presentationAttributeStyle()
   3357         && (!other.m_elementData->inlineStyle() || !other.m_elementData->inlineStyle()->hasCSSOMWrapper()))
   3358         const_cast<Element&>(other).m_elementData = static_cast<const UniqueElementData*>(other.m_elementData.get())->makeShareableCopy();
   3359 
   3360     if (!other.m_elementData->isUnique() && !ownerDocumentsHaveDifferentCaseSensitivity)
   3361         m_elementData = other.m_elementData;
   3362     else
   3363         m_elementData = other.m_elementData->makeUniqueCopy();
   3364 
   3365     for (unsigned i = 0; i < m_elementData->length(); ++i) {
   3366         const Attribute* attribute = const_cast<const ElementData*>(m_elementData.get())->attributeItem(i);
   3367         attributeChangedFromParserOrByCloning(attribute->name(), attribute->value(), ModifiedByCloning);
   3368     }
   3369 }
   3370 
   3371 void Element::cloneDataFromElement(const Element& other)
   3372 {
   3373     cloneAttributesFromElement(other);
   3374     copyNonAttributePropertiesFromElement(other);
   3375 }
   3376 
   3377 void Element::createUniqueElementData()
   3378 {
   3379     if (!m_elementData)
   3380         m_elementData = UniqueElementData::create();
   3381     else {
   3382         ASSERT(!m_elementData->isUnique());
   3383         m_elementData = static_cast<ShareableElementData*>(m_elementData.get())->makeUniqueCopy();
   3384     }
   3385 }
   3386 
   3387 InputMethodContext* Element::inputMethodContext()
   3388 {
   3389     return ensureElementRareData().ensureInputMethodContext(toHTMLElement(this));
   3390 }
   3391 
   3392 bool Element::hasInputMethodContext() const
   3393 {
   3394     return hasRareData() && elementRareData()->hasInputMethodContext();
   3395 }
   3396 
   3397 bool Element::hasPendingResources() const
   3398 {
   3399     return hasRareData() && elementRareData()->hasPendingResources();
   3400 }
   3401 
   3402 void Element::setHasPendingResources()
   3403 {
   3404     ensureElementRareData().setHasPendingResources(true);
   3405 }
   3406 
   3407 void Element::clearHasPendingResources()
   3408 {
   3409     ensureElementRareData().setHasPendingResources(false);
   3410 }
   3411 
   3412 void Element::synchronizeStyleAttributeInternal() const
   3413 {
   3414     ASSERT(isStyledElement());
   3415     ASSERT(elementData());
   3416     ASSERT(elementData()->m_styleAttributeIsDirty);
   3417     elementData()->m_styleAttributeIsDirty = false;
   3418     if (const StylePropertySet* inlineStyle = this->inlineStyle())
   3419         const_cast<Element*>(this)->setSynchronizedLazyAttribute(styleAttr, inlineStyle->asText());
   3420 }
   3421 
   3422 CSSStyleDeclaration* Element::style()
   3423 {
   3424     if (!isStyledElement())
   3425         return 0;
   3426     return ensureMutableInlineStyle()->ensureInlineCSSStyleDeclaration(this);
   3427 }
   3428 
   3429 MutableStylePropertySet* Element::ensureMutableInlineStyle()
   3430 {
   3431     ASSERT(isStyledElement());
   3432     RefPtr<StylePropertySet>& inlineStyle = ensureUniqueElementData()->m_inlineStyle;
   3433     if (!inlineStyle) {
   3434         CSSParserMode mode = (!isHTMLElement() || document().inQuirksMode()) ? HTMLQuirksMode : HTMLStandardMode;
   3435         inlineStyle = MutableStylePropertySet::create(mode);
   3436     } else if (!inlineStyle->isMutable()) {
   3437         inlineStyle = inlineStyle->mutableCopy();
   3438     }
   3439     return toMutableStylePropertySet(inlineStyle);
   3440 }
   3441 
   3442 PropertySetCSSStyleDeclaration* Element::inlineStyleCSSOMWrapper()
   3443 {
   3444     if (!inlineStyle() || !inlineStyle()->hasCSSOMWrapper())
   3445         return 0;
   3446     PropertySetCSSStyleDeclaration* cssomWrapper = ensureMutableInlineStyle()->cssStyleDeclaration();
   3447     ASSERT(cssomWrapper && cssomWrapper->parentElement() == this);
   3448     return cssomWrapper;
   3449 }
   3450 
   3451 inline void Element::setInlineStyleFromString(const AtomicString& newStyleString)
   3452 {
   3453     ASSERT(isStyledElement());
   3454     RefPtr<StylePropertySet>& inlineStyle = elementData()->m_inlineStyle;
   3455 
   3456     // Avoid redundant work if we're using shared attribute data with already parsed inline style.
   3457     if (inlineStyle && !elementData()->isUnique())
   3458         return;
   3459 
   3460     // We reconstruct the property set instead of mutating if there is no CSSOM wrapper.
   3461     // This makes wrapperless property sets immutable and so cacheable.
   3462     if (inlineStyle && !inlineStyle->isMutable())
   3463         inlineStyle.clear();
   3464 
   3465     if (!inlineStyle) {
   3466         inlineStyle = CSSParser::parseInlineStyleDeclaration(newStyleString, this);
   3467     } else {
   3468         ASSERT(inlineStyle->isMutable());
   3469         static_pointer_cast<MutableStylePropertySet>(inlineStyle)->parseDeclaration(newStyleString, document().elementSheet()->contents());
   3470     }
   3471 }
   3472 
   3473 void Element::styleAttributeChanged(const AtomicString& newStyleString, AttributeModificationReason modificationReason)
   3474 {
   3475     ASSERT(isStyledElement());
   3476     WTF::OrdinalNumber startLineNumber = WTF::OrdinalNumber::beforeFirst();
   3477     if (document().scriptableDocumentParser() && !document().isInDocumentWrite())
   3478         startLineNumber = document().scriptableDocumentParser()->lineNumber();
   3479 
   3480     if (newStyleString.isNull()) {
   3481         if (PropertySetCSSStyleDeclaration* cssomWrapper = inlineStyleCSSOMWrapper())
   3482             cssomWrapper->clearParentElement();
   3483         ensureUniqueElementData()->m_inlineStyle.clear();
   3484     } else if (modificationReason == ModifiedByCloning || document().contentSecurityPolicy()->allowInlineStyle(document().url(), startLineNumber)) {
   3485         setInlineStyleFromString(newStyleString);
   3486     }
   3487 
   3488     elementData()->m_styleAttributeIsDirty = false;
   3489 
   3490     setNeedsStyleRecalc(LocalStyleChange);
   3491     InspectorInstrumentation::didInvalidateStyleAttr(this);
   3492 }
   3493 
   3494 void Element::inlineStyleChanged()
   3495 {
   3496     ASSERT(isStyledElement());
   3497     setNeedsStyleRecalc(LocalStyleChange);
   3498     ASSERT(elementData());
   3499     elementData()->m_styleAttributeIsDirty = true;
   3500     InspectorInstrumentation::didInvalidateStyleAttr(this);
   3501 }
   3502 
   3503 bool Element::setInlineStyleProperty(CSSPropertyID propertyID, CSSValueID identifier, bool important)
   3504 {
   3505     ASSERT(isStyledElement());
   3506     ensureMutableInlineStyle()->setProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important);
   3507     inlineStyleChanged();
   3508     return true;
   3509 }
   3510 
   3511 bool Element::setInlineStyleProperty(CSSPropertyID propertyID, CSSPropertyID identifier, bool important)
   3512 {
   3513     ASSERT(isStyledElement());
   3514     ensureMutableInlineStyle()->setProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important);
   3515     inlineStyleChanged();
   3516     return true;
   3517 }
   3518 
   3519 bool Element::setInlineStyleProperty(CSSPropertyID propertyID, double value, CSSPrimitiveValue::UnitTypes unit, bool important)
   3520 {
   3521     ASSERT(isStyledElement());
   3522     ensureMutableInlineStyle()->setProperty(propertyID, cssValuePool().createValue(value, unit), important);
   3523     inlineStyleChanged();
   3524     return true;
   3525 }
   3526 
   3527 bool Element::setInlineStyleProperty(CSSPropertyID propertyID, const String& value, bool important)
   3528 {
   3529     ASSERT(isStyledElement());
   3530     bool changes = ensureMutableInlineStyle()->setProperty(propertyID, value, important, document().elementSheet()->contents());
   3531     if (changes)
   3532         inlineStyleChanged();
   3533     return changes;
   3534 }
   3535 
   3536 bool Element::removeInlineStyleProperty(CSSPropertyID propertyID)
   3537 {
   3538     ASSERT(isStyledElement());
   3539     if (!inlineStyle())
   3540         return false;
   3541     bool changes = ensureMutableInlineStyle()->removeProperty(propertyID);
   3542     if (changes)
   3543         inlineStyleChanged();
   3544     return changes;
   3545 }
   3546 
   3547 void Element::removeAllInlineStyleProperties()
   3548 {
   3549     ASSERT(isStyledElement());
   3550     if (!inlineStyle() || inlineStyle()->isEmpty())
   3551         return;
   3552     ensureMutableInlineStyle()->clear();
   3553     inlineStyleChanged();
   3554 }
   3555 
   3556 void Element::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
   3557 {
   3558     ASSERT(isStyledElement());
   3559     if (const StylePropertySet* inlineStyle = elementData() ? elementData()->inlineStyle() : 0)
   3560         inlineStyle->addSubresourceStyleURLs(urls, document().elementSheet()->contents());
   3561 }
   3562 
   3563 void Element::updatePresentationAttributeStyle()
   3564 {
   3565     // ShareableElementData doesn't store presentation attribute style, so make sure we have a UniqueElementData.
   3566     UniqueElementData* elementData = ensureUniqueElementData();
   3567     elementData->m_presentationAttributeStyleIsDirty = false;
   3568     elementData->m_presentationAttributeStyle = computePresentationAttributeStyle(*this);
   3569 }
   3570 
   3571 void Element::addPropertyToPresentationAttributeStyle(MutableStylePropertySet* style, CSSPropertyID propertyID, CSSValueID identifier)
   3572 {
   3573     ASSERT(isStyledElement());
   3574     style->setProperty(propertyID, cssValuePool().createIdentifierValue(identifier));
   3575 }
   3576 
   3577 void Element::addPropertyToPresentationAttributeStyle(MutableStylePropertySet* style, CSSPropertyID propertyID, double value, CSSPrimitiveValue::UnitTypes unit)
   3578 {
   3579     ASSERT(isStyledElement());
   3580     style->setProperty(propertyID, cssValuePool().createValue(value, unit));
   3581 }
   3582 
   3583 void Element::addPropertyToPresentationAttributeStyle(MutableStylePropertySet* style, CSSPropertyID propertyID, const String& value)
   3584 {
   3585     ASSERT(isStyledElement());
   3586     style->setProperty(propertyID, value, false);
   3587 }
   3588 
   3589 bool Element::supportsStyleSharing() const
   3590 {
   3591     if (!isStyledElement() || !parentElement())
   3592         return false;
   3593     // If the element has inline style it is probably unique.
   3594     if (inlineStyle())
   3595         return false;
   3596     if (isSVGElement() && toSVGElement(this)->animatedSMILStyleProperties())
   3597         return false;
   3598     // Ids stop style sharing if they show up in the stylesheets.
   3599     if (hasID() && document().ensureStyleResolver().hasRulesForId(idForStyleResolution()))
   3600         return false;
   3601     // Active and hovered elements always make a chain towards the document node
   3602     // and no siblings or cousins will have the same state.
   3603     if (hovered())
   3604         return false;
   3605     if (active())
   3606         return false;
   3607     if (focused())
   3608         return false;
   3609     if (!parentElement()->childrenSupportStyleSharing())
   3610         return false;
   3611     if (hasScopedHTMLStyleChild())
   3612         return false;
   3613     if (this == document().cssTarget())
   3614         return false;
   3615     if (isHTMLElement() && toHTMLElement(this)->hasDirectionAuto())
   3616         return false;
   3617     if (hasActiveAnimations())
   3618         return false;
   3619     if (shadow() && shadow()->containsActiveStyles())
   3620         return false;
   3621     // Turn off style sharing for elements that can gain layers for reasons outside of the style system.
   3622     // See comments in RenderObject::setStyle().
   3623     // FIXME: Why does gaining a layer from outside the style system require disabling sharing?
   3624     if (hasTagName(iframeTag)
   3625         || hasTagName(frameTag)
   3626         || hasTagName(embedTag)
   3627         || hasTagName(objectTag)
   3628         || hasTagName(appletTag)
   3629         || hasTagName(canvasTag))
   3630         return false;
   3631     // FIXME: We should share style for option and optgroup whenever possible.
   3632     // Before doing so, we need to resolve issues in HTMLSelectElement::recalcListItems
   3633     // and RenderMenuList::setText. See also https://bugs.webkit.org/show_bug.cgi?id=88405
   3634     if (hasTagName(optionTag) || hasTagName(optgroupTag))
   3635         return false;
   3636     if (FullscreenElementStack::isActiveFullScreenElement(this))
   3637         return false;
   3638     return true;
   3639 }
   3640 
   3641 } // namespace WebCore
   3642