NodeRenderingContext is slow due to ComposedShadowTreeWalker
[WebKit-https.git] / Source / WebCore / dom / Element.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2001 Peter Kelly (pmk@post.com)
5  *           (C) 2001 Dirk Mueller (mueller@kde.org)
6  *           (C) 2007 David Smith (catfish.man@gmail.com)
7  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
8  *           (C) 2007 Eric Seidel (eric@webkit.org)
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public License
21  * along with this library; see the file COPYING.LIB.  If not, write to
22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23  * Boston, MA 02110-1301, USA.
24  */
25
26 #include "config.h"
27 #include "Element.h"
28
29 #include "AXObjectCache.h"
30 #include "Attr.h"
31 #include "CSSParser.h"
32 #include "CSSSelectorList.h"
33 #include "ClassList.h"
34 #include "ClientRect.h"
35 #include "ClientRectList.h"
36 #include "DOMTokenList.h"
37 #include "DatasetDOMStringMap.h"
38 #include "Document.h"
39 #include "DocumentFragment.h"
40 #include "DocumentSharedObjectPool.h"
41 #include "ElementRareData.h"
42 #include "ExceptionCode.h"
43 #include "FlowThreadController.h"
44 #include "FocusController.h"
45 #include "Frame.h"
46 #include "FrameView.h"
47 #include "HTMLCollection.h"
48 #include "HTMLDocument.h"
49 #include "HTMLElement.h"
50 #include "HTMLFormControlsCollection.h"
51 #include "HTMLFrameOwnerElement.h"
52 #include "HTMLLabelElement.h"
53 #include "HTMLNames.h"
54 #include "HTMLOptionsCollection.h"
55 #include "HTMLParserIdioms.h"
56 #include "HTMLTableRowsCollection.h"
57 #include "InsertionPoint.h"
58 #include "InspectorInstrumentation.h"
59 #include "MutationObserverInterestGroup.h"
60 #include "MutationRecord.h"
61 #include "NamedNodeMap.h"
62 #include "NodeList.h"
63 #include "NodeRenderStyle.h"
64 #include "NodeRenderingContext.h"
65 #include "NodeTraversal.h"
66 #include "Page.h"
67 #include "PointerLockController.h"
68 #include "PseudoElement.h"
69 #include "RenderRegion.h"
70 #include "RenderView.h"
71 #include "RenderWidget.h"
72 #include "SelectorQuery.h"
73 #include "Settings.h"
74 #include "ShadowRoot.h"
75 #include "StyleResolver.h"
76 #include "Text.h"
77 #include "TextIterator.h"
78 #include "VoidCallback.h"
79 #include "WebCoreMemoryInstrumentation.h"
80 #include "XMLNSNames.h"
81 #include "XMLNames.h"
82 #include "htmlediting.h"
83 #include <wtf/BitVector.h>
84 #include <wtf/text/CString.h>
85
86 #if ENABLE(SVG)
87 #include "SVGElement.h"
88 #include "SVGNames.h"
89 #endif
90
91 namespace WebCore {
92
93 using namespace HTMLNames;
94 using namespace XMLNames;
95     
96 class StyleResolverParentPusher {
97 public:
98     StyleResolverParentPusher(Element* parent)
99         : m_parent(parent)
100         , m_pushedStyleResolver(0)
101     {
102     }
103     void push()
104     {
105         if (m_pushedStyleResolver)
106             return;
107         m_pushedStyleResolver = m_parent->document()->styleResolver();
108         m_pushedStyleResolver->pushParentElement(m_parent);
109     }
110     ~StyleResolverParentPusher()
111     {
112
113         if (!m_pushedStyleResolver)
114             return;
115
116         // This tells us that our pushed style selector is in a bad state,
117         // so we should just bail out in that scenario.
118         ASSERT(m_pushedStyleResolver == m_parent->document()->styleResolver());
119         if (m_pushedStyleResolver != m_parent->document()->styleResolver())
120             return;
121
122         m_pushedStyleResolver->popParentElement(m_parent);
123     }
124
125 private:
126     Element* m_parent;
127     StyleResolver* m_pushedStyleResolver;
128 };
129
130 typedef Vector<RefPtr<Attr> > AttrNodeList;
131 typedef HashMap<Element*, OwnPtr<AttrNodeList> > AttrNodeListMap;
132
133 static AttrNodeListMap& attrNodeListMap()
134 {
135     DEFINE_STATIC_LOCAL(AttrNodeListMap, map, ());
136     return map;
137 }
138
139 static AttrNodeList* attrNodeListForElement(Element* element)
140 {
141     if (!element->hasSyntheticAttrChildNodes())
142         return 0;
143     ASSERT(attrNodeListMap().contains(element));
144     return attrNodeListMap().get(element);
145 }
146
147 static AttrNodeList* ensureAttrNodeListForElement(Element* element)
148 {
149     if (element->hasSyntheticAttrChildNodes()) {
150         ASSERT(attrNodeListMap().contains(element));
151         return attrNodeListMap().get(element);
152     }
153     ASSERT(!attrNodeListMap().contains(element));
154     element->setHasSyntheticAttrChildNodes(true);
155     AttrNodeListMap::AddResult result = attrNodeListMap().add(element, adoptPtr(new AttrNodeList));
156     return result.iterator->value.get();
157 }
158
159 static void removeAttrNodeListForElement(Element* element)
160 {
161     ASSERT(element->hasSyntheticAttrChildNodes());
162     ASSERT(attrNodeListMap().contains(element));
163     attrNodeListMap().remove(element);
164     element->setHasSyntheticAttrChildNodes(false);
165 }
166
167 static Attr* findAttrNodeInList(AttrNodeList* attrNodeList, const QualifiedName& name)
168 {
169     for (unsigned i = 0; i < attrNodeList->size(); ++i) {
170         if (attrNodeList->at(i)->qualifiedName() == name)
171             return attrNodeList->at(i).get();
172     }
173     return 0;
174 }
175
176 PassRefPtr<Element> Element::create(const QualifiedName& tagName, Document* document)
177 {
178     return adoptRef(new Element(tagName, document, CreateElement));
179 }
180
181 Element::~Element()
182 {
183 #ifndef NDEBUG
184     if (document() && document()->renderer()) {
185         // When the document is not destroyed, an element that was part of a named flow
186         // content nodes should have been removed from the content nodes collection
187         // and the inNamedFlow flag reset.
188         ASSERT(!inNamedFlow());
189     }
190 #endif
191
192     if (hasRareData()) {
193         ElementRareData* data = elementRareData();
194         data->setPseudoElement(BEFORE, 0);
195         data->setPseudoElement(AFTER, 0);
196     }
197
198     if (ElementShadow* elementShadow = shadow()) {
199         elementShadow->removeAllShadowRoots();
200         elementRareData()->setShadow(nullptr);
201     }
202
203     if (hasSyntheticAttrChildNodes())
204         detachAllAttrNodesFromElement();
205 }
206
207 inline ElementRareData* Element::elementRareData() const
208 {
209     ASSERT(hasRareData());
210     return static_cast<ElementRareData*>(rareData());
211 }
212
213 inline ElementRareData* Element::ensureElementRareData()
214 {
215     return static_cast<ElementRareData*>(ensureRareData());
216 }
217
218 PassOwnPtr<NodeRareData> Element::createRareData()
219 {
220     return adoptPtr(new ElementRareData(documentInternal()));
221 }
222
223 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, blur);
224 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, error);
225 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, focus);
226 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, load);
227
228 PassRefPtr<Node> Element::cloneNode(bool deep)
229 {
230     return deep ? cloneElementWithChildren() : cloneElementWithoutChildren();
231 }
232
233 PassRefPtr<Element> Element::cloneElementWithChildren()
234 {
235     RefPtr<Element> clone = cloneElementWithoutChildren();
236     cloneChildNodes(clone.get());
237     return clone.release();
238 }
239
240 PassRefPtr<Element> Element::cloneElementWithoutChildren()
241 {
242     RefPtr<Element> clone = cloneElementWithoutAttributesAndChildren();
243     // This will catch HTML elements in the wrong namespace that are not correctly copied.
244     // This is a sanity check as HTML overloads some of the DOM methods.
245     ASSERT(isHTMLElement() == clone->isHTMLElement());
246
247     clone->cloneDataFromElement(*this);
248     return clone.release();
249 }
250
251 PassRefPtr<Element> Element::cloneElementWithoutAttributesAndChildren()
252 {
253     return document()->createElement(tagQName(), false);
254 }
255
256 PassRefPtr<Attr> Element::detachAttribute(size_t index)
257 {
258     ASSERT(attributeData());
259
260     const Attribute* attribute = attributeData()->attributeItem(index);
261     ASSERT(attribute);
262
263     RefPtr<Attr> attrNode = attrIfExists(attribute->name());
264     if (attrNode)
265         detachAttrNodeFromElementWithValue(attrNode.get(), attribute->value());
266     else
267         attrNode = Attr::create(document(), attribute->name(), attribute->value());
268
269     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
270     return attrNode.release();
271 }
272
273 void Element::removeAttribute(const QualifiedName& name)
274 {
275     if (!attributeData())
276         return;
277
278     size_t index = attributeData()->getAttributeItemIndex(name);
279     if (index == notFound)
280         return;
281
282     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
283 }
284
285 void Element::setBooleanAttribute(const QualifiedName& name, bool value)
286 {
287     if (value)
288         setAttribute(name, emptyAtom);
289     else
290         removeAttribute(name);
291 }
292
293 NamedNodeMap* Element::attributes() const
294 {
295     ensureUpdatedAttributeData();
296     ElementRareData* rareData = const_cast<Element*>(this)->ensureElementRareData();
297     if (NamedNodeMap* attributeMap = rareData->attributeMap())
298         return attributeMap;
299
300     rareData->setAttributeMap(NamedNodeMap::create(const_cast<Element*>(this)));
301     return rareData->attributeMap();
302 }
303
304 Node::NodeType Element::nodeType() const
305 {
306     return ELEMENT_NODE;
307 }
308
309 bool Element::hasAttribute(const QualifiedName& name) const
310 {
311     return hasAttributeNS(name.namespaceURI(), name.localName());
312 }
313
314 const AtomicString& Element::getAttribute(const QualifiedName& name) const
315 {
316     if (!attributeData())
317         return nullAtom;
318
319     if (UNLIKELY(name == styleAttr && attributeData()->m_styleAttributeIsDirty))
320         updateStyleAttribute();
321
322 #if ENABLE(SVG)
323     if (UNLIKELY(attributeData()->m_animatedSVGAttributesAreDirty))
324         updateAnimatedSVGAttribute(name);
325 #endif
326
327     if (const Attribute* attribute = getAttributeItem(name))
328         return attribute->value();
329     return nullAtom;
330 }
331
332 void Element::scrollIntoView(bool alignToTop) 
333 {
334     document()->updateLayoutIgnorePendingStylesheets();
335
336     if (!renderer())
337         return;
338
339     LayoutRect bounds = boundingBox();
340     // Align to the top / bottom and to the closest edge.
341     if (alignToTop)
342         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
343     else
344         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignBottomAlways);
345 }
346
347 void Element::scrollIntoViewIfNeeded(bool centerIfNeeded)
348 {
349     document()->updateLayoutIgnorePendingStylesheets();
350
351     if (!renderer())
352         return;
353
354     LayoutRect bounds = boundingBox();
355     if (centerIfNeeded)
356         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignCenterIfNeeded, ScrollAlignment::alignCenterIfNeeded);
357     else
358         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
359 }
360
361 void Element::scrollByUnits(int units, ScrollGranularity granularity)
362 {
363     document()->updateLayoutIgnorePendingStylesheets();
364
365     if (!renderer())
366         return;
367
368     if (!renderer()->hasOverflowClip())
369         return;
370
371     ScrollDirection direction = ScrollDown;
372     if (units < 0) {
373         direction = ScrollUp;
374         units = -units;
375     }
376     Node* stopNode = this;
377     toRenderBox(renderer())->scroll(direction, granularity, units, &stopNode);
378 }
379
380 void Element::scrollByLines(int lines)
381 {
382     scrollByUnits(lines, ScrollByLine);
383 }
384
385 void Element::scrollByPages(int pages)
386 {
387     scrollByUnits(pages, ScrollByPage);
388 }
389
390 static float localZoomForRenderer(RenderObject* renderer)
391 {
392     // FIXME: This does the wrong thing if two opposing zooms are in effect and canceled each
393     // other out, but the alternative is that we'd have to crawl up the whole render tree every
394     // time (or store an additional bit in the RenderStyle to indicate that a zoom was specified).
395     float zoomFactor = 1;
396     if (renderer->style()->effectiveZoom() != 1) {
397         // Need to find the nearest enclosing RenderObject that set up
398         // a differing zoom, and then we divide our result by it to eliminate the zoom.
399         RenderObject* prev = renderer;
400         for (RenderObject* curr = prev->parent(); curr; curr = curr->parent()) {
401             if (curr->style()->effectiveZoom() != prev->style()->effectiveZoom()) {
402                 zoomFactor = prev->style()->zoom();
403                 break;
404             }
405             prev = curr;
406         }
407         if (prev->isRenderView())
408             zoomFactor = prev->style()->zoom();
409     }
410     return zoomFactor;
411 }
412
413 static int adjustForLocalZoom(LayoutUnit value, RenderObject* renderer)
414 {
415     float zoomFactor = localZoomForRenderer(renderer);
416     if (zoomFactor == 1)
417         return value;
418 #if ENABLE(SUBPIXEL_LAYOUT)
419     return lroundf(value / zoomFactor);
420 #else
421     // Needed because computeLengthInt truncates (rather than rounds) when scaling up.
422     if (zoomFactor > 1)
423         value++;
424     return static_cast<int>(value / zoomFactor);
425 #endif
426 }
427
428 int Element::offsetLeft()
429 {
430     document()->updateLayoutIgnorePendingStylesheets();
431     if (RenderBoxModelObject* renderer = renderBoxModelObject())
432         return adjustForLocalZoom(renderer->pixelSnappedOffsetLeft(), renderer);
433     return 0;
434 }
435
436 int Element::offsetTop()
437 {
438     document()->updateLayoutIgnorePendingStylesheets();
439     if (RenderBoxModelObject* renderer = renderBoxModelObject())
440         return adjustForLocalZoom(renderer->pixelSnappedOffsetTop(), renderer);
441     return 0;
442 }
443
444 int Element::offsetWidth()
445 {
446     document()->updateLayoutIgnorePendingStylesheets();
447     if (RenderBoxModelObject* renderer = renderBoxModelObject())
448         return adjustForAbsoluteZoom(renderer->pixelSnappedOffsetWidth(), renderer);
449     return 0;
450 }
451
452 int Element::offsetHeight()
453 {
454     document()->updateLayoutIgnorePendingStylesheets();
455     if (RenderBoxModelObject* renderer = renderBoxModelObject())
456         return adjustForAbsoluteZoom(renderer->pixelSnappedOffsetHeight(), renderer);
457     return 0;
458 }
459
460 Element* Element::offsetParent()
461 {
462     document()->updateLayoutIgnorePendingStylesheets();
463     if (RenderObject* rend = renderer())
464         if (RenderObject* offsetParent = rend->offsetParent())
465             return static_cast<Element*>(offsetParent->node());
466     return 0;
467 }
468
469 int Element::clientLeft()
470 {
471     document()->updateLayoutIgnorePendingStylesheets();
472
473     if (RenderBox* renderer = renderBox())
474         return adjustForAbsoluteZoom(roundToInt(renderer->clientLeft()), renderer);
475     return 0;
476 }
477
478 int Element::clientTop()
479 {
480     document()->updateLayoutIgnorePendingStylesheets();
481
482     if (RenderBox* renderer = renderBox())
483         return adjustForAbsoluteZoom(roundToInt(renderer->clientTop()), renderer);
484     return 0;
485 }
486
487 int Element::clientWidth()
488 {
489     document()->updateLayoutIgnorePendingStylesheets();
490
491     // When in strict mode, clientWidth for the document element should return the width of the containing frame.
492     // When in quirks mode, clientWidth for the body element should return the width of the containing frame.
493     bool inQuirksMode = document()->inQuirksMode();
494     if ((!inQuirksMode && document()->documentElement() == this) ||
495         (inQuirksMode && isHTMLElement() && document()->body() == this)) {
496         if (FrameView* view = document()->view()) {
497             if (RenderView* renderView = document()->renderView())
498                 return adjustForAbsoluteZoom(view->layoutWidth(), renderView);
499         }
500     }
501     
502     if (RenderBox* renderer = renderBox())
503         return adjustForAbsoluteZoom(renderer->pixelSnappedClientWidth(), renderer);
504     return 0;
505 }
506
507 int Element::clientHeight()
508 {
509     document()->updateLayoutIgnorePendingStylesheets();
510
511     // When in strict mode, clientHeight for the document element should return the height of the containing frame.
512     // When in quirks mode, clientHeight for the body element should return the height of the containing frame.
513     bool inQuirksMode = document()->inQuirksMode();     
514
515     if ((!inQuirksMode && document()->documentElement() == this) ||
516         (inQuirksMode && isHTMLElement() && document()->body() == this)) {
517         if (FrameView* view = document()->view()) {
518             if (RenderView* renderView = document()->renderView())
519                 return adjustForAbsoluteZoom(view->layoutHeight(), renderView);
520         }
521     }
522     
523     if (RenderBox* renderer = renderBox())
524         return adjustForAbsoluteZoom(renderer->pixelSnappedClientHeight(), renderer);
525     return 0;
526 }
527
528 int Element::scrollLeft()
529 {
530     document()->updateLayoutIgnorePendingStylesheets();
531     if (RenderBox* rend = renderBox())
532         return adjustForAbsoluteZoom(rend->scrollLeft(), rend);
533     return 0;
534 }
535
536 int Element::scrollTop()
537 {
538     document()->updateLayoutIgnorePendingStylesheets();
539     if (RenderBox* rend = renderBox())
540         return adjustForAbsoluteZoom(rend->scrollTop(), rend);
541     return 0;
542 }
543
544 void Element::setScrollLeft(int newLeft)
545 {
546     document()->updateLayoutIgnorePendingStylesheets();
547     if (RenderBox* rend = renderBox())
548         rend->setScrollLeft(static_cast<int>(newLeft * rend->style()->effectiveZoom()));
549 }
550
551 void Element::setScrollTop(int newTop)
552 {
553     document()->updateLayoutIgnorePendingStylesheets();
554     if (RenderBox* rend = renderBox())
555         rend->setScrollTop(static_cast<int>(newTop * rend->style()->effectiveZoom()));
556 }
557
558 int Element::scrollWidth()
559 {
560     document()->updateLayoutIgnorePendingStylesheets();
561     if (RenderBox* rend = renderBox())
562         return adjustForAbsoluteZoom(rend->scrollWidth(), rend);
563     return 0;
564 }
565
566 int Element::scrollHeight()
567 {
568     document()->updateLayoutIgnorePendingStylesheets();
569     if (RenderBox* rend = renderBox())
570         return adjustForAbsoluteZoom(rend->scrollHeight(), rend);
571     return 0;
572 }
573
574 IntRect Element::boundsInRootViewSpace()
575 {
576     document()->updateLayoutIgnorePendingStylesheets();
577
578     FrameView* view = document()->view();
579     if (!view)
580         return IntRect();
581
582     Vector<FloatQuad> quads;
583 #if ENABLE(SVG)
584     if (isSVGElement() && renderer()) {
585         // Get the bounding rectangle from the SVG model.
586         SVGElement* svgElement = static_cast<SVGElement*>(this);
587         FloatRect localRect;
588         if (svgElement->getBoundingBox(localRect))
589             quads.append(renderer()->localToAbsoluteQuad(localRect));
590     } else
591 #endif
592     {
593         // Get the bounding rectangle from the box model.
594         if (renderBoxModelObject())
595             renderBoxModelObject()->absoluteQuads(quads);
596     }
597
598     if (quads.isEmpty())
599         return IntRect();
600
601     IntRect result = quads[0].enclosingBoundingBox();
602     for (size_t i = 1; i < quads.size(); ++i)
603         result.unite(quads[i].enclosingBoundingBox());
604
605     result = view->contentsToRootView(result);
606     return result;
607 }
608
609 PassRefPtr<ClientRectList> Element::getClientRects()
610 {
611     document()->updateLayoutIgnorePendingStylesheets();
612
613     RenderBoxModelObject* renderBoxModelObject = this->renderBoxModelObject();
614     if (!renderBoxModelObject)
615         return ClientRectList::create();
616
617     // FIXME: Handle SVG elements.
618     // FIXME: Handle table/inline-table with a caption.
619
620     Vector<FloatQuad> quads;
621     renderBoxModelObject->absoluteQuads(quads);
622     document()->adjustFloatQuadsForScrollAndAbsoluteZoomAndFrameScale(quads, renderBoxModelObject);
623     return ClientRectList::create(quads);
624 }
625
626 PassRefPtr<ClientRect> Element::getBoundingClientRect()
627 {
628     document()->updateLayoutIgnorePendingStylesheets();
629
630     Vector<FloatQuad> quads;
631 #if ENABLE(SVG)
632     if (isSVGElement() && renderer() && !renderer()->isSVGRoot()) {
633         // Get the bounding rectangle from the SVG model.
634         SVGElement* svgElement = static_cast<SVGElement*>(this);
635         FloatRect localRect;
636         if (svgElement->getBoundingBox(localRect))
637             quads.append(renderer()->localToAbsoluteQuad(localRect));
638     } else
639 #endif
640     {
641         // Get the bounding rectangle from the box model.
642         if (renderBoxModelObject())
643             renderBoxModelObject()->absoluteQuads(quads);
644     }
645
646     if (quads.isEmpty())
647         return ClientRect::create();
648
649     FloatRect result = quads[0].boundingBox();
650     for (size_t i = 1; i < quads.size(); ++i)
651         result.unite(quads[i].boundingBox());
652
653     document()->adjustFloatRectForScrollAndAbsoluteZoomAndFrameScale(result, renderer());
654     return ClientRect::create(result);
655 }
656     
657 IntRect Element::screenRect() const
658 {
659     if (!renderer())
660         return IntRect();
661     // FIXME: this should probably respect transforms
662     return document()->view()->contentsToScreen(renderer()->absoluteBoundingBoxRectIgnoringTransforms());
663 }
664
665 static inline bool shouldIgnoreAttributeCase(const Element* e)
666 {
667     return e && e->document()->isHTMLDocument() && e->isHTMLElement();
668 }
669
670 const AtomicString& Element::getAttribute(const AtomicString& name) const
671 {
672     if (!attributeData())
673         return nullAtom;
674
675     bool ignoreCase = shouldIgnoreAttributeCase(this);
676
677     // Update the 'style' attribute if it's invalid and being requested:
678     if (attributeData()->m_styleAttributeIsDirty && equalPossiblyIgnoringCase(name, styleAttr.localName(), ignoreCase))
679         updateStyleAttribute();
680
681 #if ENABLE(SVG)
682     if (attributeData()->m_animatedSVGAttributesAreDirty) {
683         // We're not passing a namespace argument on purpose. SVGNames::*Attr are defined w/o namespaces as well.
684         updateAnimatedSVGAttribute(QualifiedName(nullAtom, name, nullAtom));
685     }
686 #endif
687
688     if (const Attribute* attribute = attributeData()->getAttributeItem(name, ignoreCase))
689         return attribute->value();
690     return nullAtom;
691 }
692
693 const AtomicString& Element::getAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const
694 {
695     return getAttribute(QualifiedName(nullAtom, localName, namespaceURI));
696 }
697
698 void Element::setAttribute(const AtomicString& name, const AtomicString& value, ExceptionCode& ec)
699 {
700     if (!Document::isValidName(name)) {
701         ec = INVALID_CHARACTER_ERR;
702         return;
703     }
704
705     const AtomicString& localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
706
707     size_t index = ensureUpdatedAttributeData()->getAttributeItemIndex(localName, false);
708     const QualifiedName& qName = index != notFound ? attributeItem(index)->name() : QualifiedName(nullAtom, localName, nullAtom);
709     setAttributeInternal(index, qName, value, NotInSynchronizationOfLazyAttribute);
710 }
711
712 void Element::setAttribute(const QualifiedName& name, const AtomicString& value)
713 {
714     setAttributeInternal(ensureUpdatedAttributeData()->getAttributeItemIndex(name), name, value, NotInSynchronizationOfLazyAttribute);
715 }
716
717 void Element::setSynchronizedLazyAttribute(const QualifiedName& name, const AtomicString& value)
718 {
719     setAttributeInternal(mutableAttributeData()->getAttributeItemIndex(name), name, value, InSynchronizationOfLazyAttribute);
720 }
721
722 inline void Element::setAttributeInternal(size_t index, const QualifiedName& name, const AtomicString& newValue, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
723 {
724     if (newValue.isNull()) {
725         if (index != notFound)
726             removeAttributeInternal(index, inSynchronizationOfLazyAttribute);
727         return;
728     }
729
730     if (index == notFound) {
731         addAttributeInternal(name, newValue, inSynchronizationOfLazyAttribute);
732         return;
733     }
734
735     if (!inSynchronizationOfLazyAttribute)
736         willModifyAttribute(name, attributeItem(index)->value(), newValue);
737
738     if (newValue != attributeItem(index)->value()) {
739         // If there is an Attr node hooked to this attribute, the Attr::setValue() call below
740         // will write into the ElementAttributeData.
741         // FIXME: Refactor this so it makes some sense.
742         if (RefPtr<Attr> attrNode = attrIfExists(name))
743             attrNode->setValue(newValue);
744         else
745             mutableAttributeData()->attributeItem(index)->setValue(newValue);
746     }
747
748     if (!inSynchronizationOfLazyAttribute)
749         didModifyAttribute(name, newValue);
750 }
751
752 static inline AtomicString makeIdForStyleResolution(const AtomicString& value, bool inQuirksMode)
753 {
754     if (inQuirksMode)
755         return value.lower();
756     return value;
757 }
758
759 static bool checkNeedsStyleInvalidationForIdChange(const AtomicString& oldId, const AtomicString& newId, StyleResolver* styleResolver)
760 {
761     ASSERT(newId != oldId);
762     if (!oldId.isEmpty() && styleResolver->hasSelectorForId(oldId))
763         return true;
764     if (!newId.isEmpty() && styleResolver->hasSelectorForId(newId))
765         return true;
766     return false;
767 }
768
769 void Element::attributeChanged(const QualifiedName& name, const AtomicString& newValue)
770 {
771     if (ElementShadow* parentElementShadow = shadowOfParentForDistribution(this)) {
772         if (shouldInvalidateDistributionWhenAttributeChanged(parentElementShadow, name, newValue))
773             parentElementShadow->invalidateDistribution();
774     }
775
776     parseAttribute(name, newValue);
777
778     document()->incDOMTreeVersion();
779
780     StyleResolver* styleResolver = document()->styleResolverIfExists();
781     bool testShouldInvalidateStyle = attached() && styleResolver && styleChangeType() < FullStyleChange;
782     bool shouldInvalidateStyle = false;
783
784     if (isIdAttributeName(name)) {
785         AtomicString oldId = attributeData()->idForStyleResolution();
786         AtomicString newId = makeIdForStyleResolution(newValue, document()->inQuirksMode());
787         if (newId != oldId) {
788             attributeData()->setIdForStyleResolution(newId);
789             shouldInvalidateStyle = testShouldInvalidateStyle && checkNeedsStyleInvalidationForIdChange(oldId, newId, styleResolver);
790         }
791     } else if (name == classAttr)
792         classAttributeChanged(newValue);
793     else if (name == HTMLNames::nameAttr)
794         setHasName(!newValue.isNull());
795     else if (name == HTMLNames::pseudoAttr)
796         shouldInvalidateStyle |= testShouldInvalidateStyle && isInShadowTree();
797
798     shouldInvalidateStyle |= testShouldInvalidateStyle && styleResolver->hasSelectorForAttribute(name.localName());
799
800     invalidateNodeListCachesInAncestors(&name, this);
801
802     // If there is currently no StyleResolver, we can't be sure that this attribute change won't affect style.
803     shouldInvalidateStyle |= !styleResolver;
804
805     if (shouldInvalidateStyle)
806         setNeedsStyleRecalc();
807
808     if (AXObjectCache::accessibilityEnabled())
809         document()->axObjectCache()->handleAttributeChanged(name, this);
810 }
811
812 template <typename CharacterType>
813 static inline bool classStringHasClassName(const CharacterType* characters, unsigned length)
814 {
815     ASSERT(length > 0);
816
817     unsigned i = 0;
818     do {
819         if (isNotHTMLSpace(characters[i]))
820             break;
821         ++i;
822     } while (i < length);
823
824     return i < length;
825 }
826
827 static inline bool classStringHasClassName(const AtomicString& newClassString)
828 {
829     unsigned length = newClassString.length();
830
831     if (!length)
832         return false;
833
834     if (newClassString.is8Bit())
835         return classStringHasClassName(newClassString.characters8(), length);
836     return classStringHasClassName(newClassString.characters16(), length);
837 }
838
839 template<typename Checker>
840 static bool checkSelectorForClassChange(const SpaceSplitString& changedClasses, const Checker& checker)
841 {
842     unsigned changedSize = changedClasses.size();
843     for (unsigned i = 0; i < changedSize; ++i) {
844         if (checker.hasSelectorForClass(changedClasses[i]))
845             return true;
846     }
847     return false;
848 }
849
850 template<typename Checker>
851 static bool checkSelectorForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, const Checker& checker)
852 {
853     unsigned oldSize = oldClasses.size();
854     if (!oldSize)
855         return checkSelectorForClassChange(newClasses, checker);
856     BitVector remainingClassBits;
857     remainingClassBits.ensureSize(oldSize);
858     // Class vectors tend to be very short. This is faster than using a hash table.
859     unsigned newSize = newClasses.size();
860     for (unsigned i = 0; i < newSize; ++i) {
861         for (unsigned j = 0; j < oldSize; ++j) {
862             if (newClasses[i] == oldClasses[j]) {
863                 remainingClassBits.quickSet(j);
864                 continue;
865             }
866         }
867         if (checker.hasSelectorForClass(newClasses[i]))
868             return true;
869     }
870     for (unsigned i = 0; i < oldSize; ++i) {
871         // If the bit is not set the the corresponding class has been removed.
872         if (remainingClassBits.quickGet(i))
873             continue;
874         if (checker.hasSelectorForClass(oldClasses[i]))
875             return true;
876     }
877     return false;
878 }
879
880 void Element::classAttributeChanged(const AtomicString& newClassString)
881 {
882     StyleResolver* styleResolver = document()->styleResolverIfExists();
883     bool testShouldInvalidateStyle = attached() && styleResolver && styleChangeType() < FullStyleChange;
884     bool shouldInvalidateStyle = false;
885
886     if (classStringHasClassName(newClassString)) {
887         const ElementAttributeData* attributeData = ensureAttributeData();
888         const bool shouldFoldCase = document()->inQuirksMode();
889         const SpaceSplitString oldClasses = attributeData->classNames();
890
891         attributeData->setClass(newClassString, shouldFoldCase);
892
893         const SpaceSplitString& newClasses = attributeData->classNames();
894         shouldInvalidateStyle = testShouldInvalidateStyle && checkSelectorForClassChange(oldClasses, newClasses, *styleResolver);
895     } else if (const ElementAttributeData* attributeData = this->attributeData()) {
896         const SpaceSplitString& oldClasses = attributeData->classNames();
897         shouldInvalidateStyle = testShouldInvalidateStyle && checkSelectorForClassChange(oldClasses, *styleResolver);
898
899         attributeData->clearClass();
900     }
901
902     if (DOMTokenList* classList = optionalClassList())
903         static_cast<ClassList*>(classList)->reset(newClassString);
904
905     if (shouldInvalidateStyle)
906         setNeedsStyleRecalc();
907 }
908
909 bool Element::shouldInvalidateDistributionWhenAttributeChanged(ElementShadow* elementShadow, const QualifiedName& name, const AtomicString& newValue)
910 {
911     ASSERT(elementShadow);
912     elementShadow->ensureSelectFeatureSetCollected();
913
914     if (isIdAttributeName(name)) {
915         AtomicString oldId = attributeData()->idForStyleResolution();
916         AtomicString newId = makeIdForStyleResolution(newValue, document()->inQuirksMode());
917         if (newId != oldId) {
918             if (!oldId.isEmpty() && elementShadow->selectRuleFeatureSet().hasSelectorForId(oldId))
919                 return true;
920             if (!newId.isEmpty() && elementShadow->selectRuleFeatureSet().hasSelectorForId(newId))
921                 return true;
922         }
923     }
924
925     if (name == HTMLNames::classAttr) {
926         const AtomicString& newClassString = newValue;
927         if (classStringHasClassName(newClassString)) {
928             const ElementAttributeData* attributeData = ensureAttributeData();
929             const bool shouldFoldCase = document()->inQuirksMode();
930             const SpaceSplitString& oldClasses = attributeData->classNames();
931             const SpaceSplitString newClasses(newClassString, shouldFoldCase);
932             if (checkSelectorForClassChange(oldClasses, newClasses, elementShadow->selectRuleFeatureSet()))
933                 return true;
934         } else if (const ElementAttributeData* attributeData = this->attributeData()) {
935             const SpaceSplitString& oldClasses = attributeData->classNames();
936             if (checkSelectorForClassChange(oldClasses, elementShadow->selectRuleFeatureSet()))
937                 return true;
938         }
939     }
940
941     return elementShadow->selectRuleFeatureSet().hasSelectorForAttribute(name.localName());
942 }
943
944 // Returns true is the given attribute is an event handler.
945 // We consider an event handler any attribute that begins with "on".
946 // It is a simple solution that has the advantage of not requiring any
947 // code or configuration change if a new event handler is defined.
948
949 static bool isEventHandlerAttribute(const QualifiedName& name)
950 {
951     return name.namespaceURI().isNull() && name.localName().startsWith("on");
952 }
953
954 // FIXME: Share code with Element::isURLAttribute.
955 static bool isAttributeToRemove(const QualifiedName& name, const AtomicString& value)
956 {
957     return (name.localName() == hrefAttr.localName() || name.localName() == nohrefAttr.localName()
958         || name == srcAttr || name == actionAttr || name == formactionAttr) && protocolIsJavaScript(stripLeadingAndTrailingHTMLSpaces(value));
959 }
960
961 void Element::parserSetAttributes(const Vector<Attribute>& attributeVector, FragmentScriptingPermission scriptingPermission)
962 {
963     ASSERT(!inDocument());
964     ASSERT(!parentNode());
965
966     ASSERT(!m_attributeData);
967
968     if (attributeVector.isEmpty())
969         return;
970
971     Vector<Attribute> filteredAttributes = attributeVector;
972
973     // If the element is created as result of a paste or drag-n-drop operation
974     // we want to remove all the script and event handlers.
975     if (scriptingPermission == DisallowScriptingContent) {
976         unsigned i = 0;
977         while (i < filteredAttributes.size()) {
978             Attribute& attribute = filteredAttributes[i];
979             if (isEventHandlerAttribute(attribute.name())) {
980                 filteredAttributes.remove(i);
981                 continue;
982             }
983
984             if (isAttributeToRemove(attribute.name(), attribute.value()))
985                 attribute.setValue(emptyAtom);
986             i++;
987         }
988     }
989
990     if (document() && document()->sharedObjectPool())
991         m_attributeData = document()->sharedObjectPool()->cachedImmutableElementAttributeData(filteredAttributes);
992     else
993         m_attributeData = ElementAttributeData::createImmutable(filteredAttributes);
994
995     // Iterate over the set of attributes we already have on the stack in case
996     // attributeChanged mutates m_attributeData.
997     // FIXME: Find a way so we don't have to do this.
998     for (unsigned i = 0; i < filteredAttributes.size(); ++i)
999         attributeChanged(filteredAttributes[i].name(), filteredAttributes[i].value());
1000 }
1001
1002 bool Element::hasAttributes() const
1003 {
1004     updateInvalidAttributes();
1005     return attributeData() && attributeData()->length();
1006 }
1007
1008 bool Element::hasEquivalentAttributes(const Element* other) const
1009 {
1010     const ElementAttributeData* attributeData = updatedAttributeData();
1011     const ElementAttributeData* otherAttributeData = other->updatedAttributeData();
1012     if (attributeData == otherAttributeData)
1013         return true;
1014     if (attributeData)
1015         return attributeData->isEquivalent(otherAttributeData);
1016     if (otherAttributeData)
1017         return otherAttributeData->isEquivalent(attributeData);
1018     return true;
1019 }
1020
1021 String Element::nodeName() const
1022 {
1023     return m_tagName.toString();
1024 }
1025
1026 String Element::nodeNamePreservingCase() const
1027 {
1028     return m_tagName.toString();
1029 }
1030
1031 void Element::setPrefix(const AtomicString& prefix, ExceptionCode& ec)
1032 {
1033     ec = 0;
1034     checkSetPrefix(prefix, ec);
1035     if (ec)
1036         return;
1037
1038     m_tagName.setPrefix(prefix.isEmpty() ? AtomicString() : prefix);
1039 }
1040
1041 KURL Element::baseURI() const
1042 {
1043     const AtomicString& baseAttribute = getAttribute(baseAttr);
1044     KURL base(KURL(), baseAttribute);
1045     if (!base.protocol().isEmpty())
1046         return base;
1047
1048     ContainerNode* parent = parentNode();
1049     if (!parent)
1050         return base;
1051
1052     const KURL& parentBase = parent->baseURI();
1053     if (parentBase.isNull())
1054         return base;
1055
1056     return KURL(parentBase, baseAttribute);
1057 }
1058
1059 const QualifiedName& Element::imageSourceAttributeName() const
1060 {
1061     return srcAttr;
1062 }
1063
1064 bool Element::rendererIsNeeded(const NodeRenderingContext& context)
1065 {
1066     return context.style()->display() != NONE;
1067 }
1068
1069 RenderObject* Element::createRenderer(RenderArena*, RenderStyle* style)
1070 {
1071     return RenderObject::createObject(this, style);
1072 }
1073
1074 #if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
1075 bool Element::isDateTimeFieldElement() const
1076 {
1077     return false;
1078 }
1079 #endif
1080
1081 bool Element::wasChangedSinceLastFormControlChangeEvent() const
1082 {
1083     return false;
1084 }
1085
1086 void Element::setChangedSinceLastFormControlChangeEvent(bool)
1087 {
1088 }
1089
1090 Node::InsertionNotificationRequest Element::insertedInto(ContainerNode* insertionPoint)
1091 {
1092     // need to do superclass processing first so inDocument() is true
1093     // by the time we reach updateId
1094     ContainerNode::insertedInto(insertionPoint);
1095
1096 #if ENABLE(FULLSCREEN_API)
1097     if (containsFullScreenElement() && parentElement() && !parentElement()->containsFullScreenElement())
1098         setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(true);
1099 #endif
1100
1101     if (!insertionPoint->inDocument())
1102         return InsertionDone;
1103
1104     const AtomicString& idValue = getIdAttribute();
1105     if (!idValue.isNull())
1106         updateId(nullAtom, idValue);
1107
1108     const AtomicString& nameValue = getNameAttribute();
1109     if (!nameValue.isNull())
1110         updateName(nullAtom, nameValue);
1111
1112     if (hasTagName(labelTag)) {
1113         TreeScope* scope = treeScope();
1114         if (scope->shouldCacheLabelsByForAttribute())
1115             updateLabel(scope, nullAtom, fastGetAttribute(forAttr));
1116     }
1117
1118     return InsertionDone;
1119 }
1120
1121 void Element::removedFrom(ContainerNode* insertionPoint)
1122 {
1123 #if ENABLE(DIALOG_ELEMENT)
1124     setIsInTopLayer(false);
1125 #endif
1126 #if ENABLE(FULLSCREEN_API)
1127     if (containsFullScreenElement())
1128         setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false);
1129 #endif
1130 #if ENABLE(POINTER_LOCK)
1131     if (document()->page())
1132         document()->page()->pointerLockController()->elementRemoved(this);
1133 #endif
1134
1135     setSavedLayerScrollOffset(IntSize());
1136
1137     if (insertionPoint->inDocument()) {
1138         const AtomicString& idValue = getIdAttribute();
1139         if (!idValue.isNull() && inDocument())
1140             updateId(insertionPoint->treeScope(), idValue, nullAtom);
1141
1142         const AtomicString& nameValue = getNameAttribute();
1143         if (!nameValue.isNull())
1144             updateName(nameValue, nullAtom);
1145
1146         if (hasTagName(labelTag)) {
1147             TreeScope* treeScope = insertionPoint->treeScope();
1148             if (treeScope->shouldCacheLabelsByForAttribute())
1149                 updateLabel(treeScope, fastGetAttribute(forAttr), nullAtom);
1150         }
1151     }
1152
1153     ContainerNode::removedFrom(insertionPoint);
1154 }
1155
1156 void Element::createRendererIfNeeded()
1157 {
1158     NodeRenderingContext(this).createRendererForElementIfNeeded();
1159 }
1160
1161 void Element::attach()
1162 {
1163     PostAttachCallbackDisabler callbackDisabler(this);
1164     StyleResolverParentPusher parentPusher(this);
1165     WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
1166
1167     createRendererIfNeeded();
1168
1169     if (parentElement() && parentElement()->isInCanvasSubtree())
1170         setIsInCanvasSubtree(true);
1171
1172     updatePseudoElement(BEFORE);
1173
1174     // When a shadow root exists, it does the work of attaching the children.
1175     if (ElementShadow* shadow = this->shadow()) {
1176         parentPusher.push();
1177         shadow->attach();
1178     } else if (firstChild())
1179         parentPusher.push();
1180
1181     ContainerNode::attach();
1182
1183     updatePseudoElement(AFTER);
1184
1185     if (hasRareData()) {   
1186         ElementRareData* data = elementRareData();
1187         if (data->needsFocusAppearanceUpdateSoonAfterAttach()) {
1188             if (isFocusable() && document()->focusedNode() == this)
1189                 document()->updateFocusAppearanceSoon(false /* don't restore selection */);
1190             data->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
1191         }
1192     }
1193 }
1194
1195 void Element::unregisterNamedFlowContentNode()
1196 {
1197     if (document()->cssRegionsEnabled() && inNamedFlow() && document()->renderView())
1198         document()->renderView()->flowThreadController()->unregisterNamedFlowContentNode(this);
1199 }
1200
1201 void Element::detach()
1202 {
1203     WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
1204     unregisterNamedFlowContentNode();
1205     cancelFocusAppearanceUpdate();
1206     if (hasRareData()) {
1207         ElementRareData* data = elementRareData();
1208         data->setPseudoElement(BEFORE, 0);
1209         data->setPseudoElement(AFTER, 0);
1210         data->setIsInCanvasSubtree(false);
1211         data->resetComputedStyle();
1212         data->resetDynamicRestyleObservations();
1213     }
1214
1215     if (ElementShadow* shadow = this->shadow()) {
1216         detachChildrenIfNeeded();
1217         shadow->detach();
1218     }
1219     ContainerNode::detach();
1220 }
1221
1222 bool Element::pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderStyle* newStyle)
1223 {
1224     ASSERT(currentStyle == renderStyle());
1225     ASSERT(renderer());
1226
1227     if (!currentStyle)
1228         return false;
1229
1230     const PseudoStyleCache* pseudoStyleCache = currentStyle->cachedPseudoStyles();
1231     if (!pseudoStyleCache)
1232         return false;
1233
1234     size_t cacheSize = pseudoStyleCache->size();
1235     for (size_t i = 0; i < cacheSize; ++i) {
1236         RefPtr<RenderStyle> newPseudoStyle;
1237         PseudoId pseudoId = pseudoStyleCache->at(i)->styleType();
1238         if (pseudoId == FIRST_LINE || pseudoId == FIRST_LINE_INHERITED)
1239             newPseudoStyle = renderer()->uncachedFirstLineStyle(newStyle);
1240         else
1241             newPseudoStyle = renderer()->getUncachedPseudoStyle(pseudoId, newStyle, newStyle);
1242         if (!newPseudoStyle)
1243             return true;
1244         if (*newPseudoStyle != *pseudoStyleCache->at(i)) {
1245             if (pseudoId < FIRST_INTERNAL_PSEUDOID)
1246                 newStyle->setHasPseudoStyle(pseudoId);
1247             newStyle->addCachedPseudoStyle(newPseudoStyle);
1248             if (pseudoId == FIRST_LINE || pseudoId == FIRST_LINE_INHERITED) {
1249                 // FIXME: We should do an actual diff to determine whether a repaint vs. layout
1250                 // is needed, but for now just assume a layout will be required.  The diff code
1251                 // in RenderObject::setStyle would need to be factored out so that it could be reused.
1252                 renderer()->setNeedsLayoutAndPrefWidthsRecalc();
1253             }
1254             return true;
1255         }
1256     }
1257     return false;
1258 }
1259
1260 PassRefPtr<RenderStyle> Element::styleForRenderer()
1261 {
1262     if (hasCustomCallbacks()) {
1263         if (RefPtr<RenderStyle> style = customStyleForRenderer())
1264             return style.release();
1265     }
1266
1267     return document()->styleResolver()->styleForElement(this);
1268 }
1269
1270 void Element::recalcStyle(StyleChange change)
1271 {
1272     if (hasCustomCallbacks()) {
1273         if (!willRecalcStyle(change))
1274             return;
1275     }
1276
1277     // Ref currentStyle in case it would otherwise be deleted when setting the new style in the renderer.
1278     RefPtr<RenderStyle> currentStyle(renderStyle());
1279     bool hasParentStyle = parentNodeForRenderingAndStyle() ? static_cast<bool>(parentNodeForRenderingAndStyle()->renderStyle()) : false;
1280     bool hasDirectAdjacentRules = childrenAffectedByDirectAdjacentRules();
1281     bool hasIndirectAdjacentRules = childrenAffectedByForwardPositionalRules();
1282
1283     if ((change > NoChange || needsStyleRecalc())) {
1284         if (hasRareData())
1285             elementRareData()->resetComputedStyle();
1286     }
1287     if (hasParentStyle && (change >= Inherit || needsStyleRecalc())) {
1288         RefPtr<RenderStyle> newStyle = styleForRenderer();
1289         StyleChange ch = Node::diff(currentStyle.get(), newStyle.get(), document());
1290         if (ch == Detach || !currentStyle) {
1291             // FIXME: The style gets computed twice by calling attach. We could do better if we passed the style along.
1292             reattach();
1293             // attach recalculates the style for all children. No need to do it twice.
1294             clearNeedsStyleRecalc();
1295             clearChildNeedsStyleRecalc();
1296
1297             if (hasCustomCallbacks())
1298                 didRecalcStyle(change);
1299             return;
1300         }
1301
1302         if (RenderObject* renderer = this->renderer()) {
1303             if (ch != NoChange || pseudoStyleCacheIsInvalid(currentStyle.get(), newStyle.get()) || (change == Force && renderer->requiresForcedStyleRecalcPropagation()) || styleChangeType() == SyntheticStyleChange)
1304                 renderer->setAnimatableStyle(newStyle.get());
1305             else if (needsStyleRecalc()) {
1306                 // Although no change occurred, we use the new style so that the cousin style sharing code won't get
1307                 // fooled into believing this style is the same.
1308                 renderer->setStyleInternal(newStyle.get());
1309             }
1310         }
1311
1312         // 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
1313         // 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).
1314         if (document()->styleSheetCollection()->usesRemUnits() && document()->documentElement() == this && ch != NoChange && currentStyle && newStyle && currentStyle->fontSize() != newStyle->fontSize()) {
1315             // Cached RenderStyles may depend on the re units.
1316             document()->styleResolver()->invalidateMatchedPropertiesCache();
1317             change = Force;
1318         }
1319
1320         if (change != Force) {
1321             if (styleChangeType() >= FullStyleChange)
1322                 change = Force;
1323             else
1324                 change = ch;
1325         }
1326     }
1327     StyleResolverParentPusher parentPusher(this);
1328
1329     // FIXME: This does not care about sibling combinators. Will be necessary in XBL2 world.
1330     if (ElementShadow* shadow = this->shadow()) {
1331         if (change >= Inherit || shadow->childNeedsStyleRecalc() || shadow->needsStyleRecalc()) {
1332             parentPusher.push();
1333             shadow->recalcStyle(change);
1334         }
1335     }
1336
1337     updatePseudoElement(BEFORE, change);
1338
1339     // FIXME: This check is good enough for :hover + foo, but it is not good enough for :hover + foo + bar.
1340     // For now we will just worry about the common case, since it's a lot trickier to get the second case right
1341     // without doing way too much re-resolution.
1342     bool forceCheckOfNextElementSibling = false;
1343     bool forceCheckOfAnyElementSibling = false;
1344     for (Node *n = firstChild(); n; n = n->nextSibling()) {
1345         if (n->isTextNode()) {
1346             toText(n)->recalcTextStyle(change);
1347             continue;
1348         } 
1349         if (!n->isElementNode()) 
1350             continue;
1351         Element* element = static_cast<Element*>(n);
1352         bool childRulesChanged = element->needsStyleRecalc() && element->styleChangeType() == FullStyleChange;
1353         if ((forceCheckOfNextElementSibling || forceCheckOfAnyElementSibling))
1354             element->setNeedsStyleRecalc();
1355         if (change >= Inherit || element->childNeedsStyleRecalc() || element->needsStyleRecalc()) {
1356             parentPusher.push();
1357             element->recalcStyle(change);
1358         }
1359         forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentRules;
1360         forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules);
1361     }
1362
1363     updatePseudoElement(AFTER, change);
1364
1365     clearNeedsStyleRecalc();
1366     clearChildNeedsStyleRecalc();
1367     
1368     if (hasCustomCallbacks())
1369         didRecalcStyle(change);
1370 }
1371
1372 ElementShadow* Element::shadow() const
1373 {
1374     if (!hasRareData())
1375         return 0;
1376
1377     return elementRareData()->shadow();
1378 }
1379
1380 ElementShadow* Element::ensureShadow()
1381 {
1382     if (ElementShadow* shadow = ensureElementRareData()->shadow())
1383         return shadow;
1384
1385     ElementRareData* data = elementRareData();
1386     data->setShadow(adoptPtr(new ElementShadow()));
1387     return data->shadow();
1388 }
1389
1390 PassRefPtr<ShadowRoot> Element::createShadowRoot(ExceptionCode& ec)
1391 {
1392     return ShadowRoot::create(this, ec);
1393 }
1394
1395 ShadowRoot* Element::shadowRoot() const
1396 {
1397     ElementShadow* elementShadow = shadow();
1398     if (!elementShadow)
1399         return 0;
1400     ShadowRoot* shadowRoot = elementShadow->youngestShadowRoot();
1401     if (!shadowRoot->isAccessible())
1402         return 0;
1403     return shadowRoot;
1404 }
1405
1406 ShadowRoot* Element::userAgentShadowRoot() const
1407 {
1408     if (ElementShadow* elementShadow = shadow()) {
1409         if (ShadowRoot* shadowRoot = elementShadow->oldestShadowRoot()) {
1410             ASSERT(shadowRoot->type() == ShadowRoot::UserAgentShadowRoot);
1411             return shadowRoot;
1412         }
1413     }
1414
1415     return 0;
1416 }
1417
1418 const AtomicString& Element::shadowPseudoId() const
1419 {
1420     return pseudo();
1421 }
1422
1423 bool Element::childTypeAllowed(NodeType type) const
1424 {
1425     switch (type) {
1426     case ELEMENT_NODE:
1427     case TEXT_NODE:
1428     case COMMENT_NODE:
1429     case PROCESSING_INSTRUCTION_NODE:
1430     case CDATA_SECTION_NODE:
1431     case ENTITY_REFERENCE_NODE:
1432         return true;
1433     default:
1434         break;
1435     }
1436     return false;
1437 }
1438
1439 static void checkForEmptyStyleChange(Element* element, RenderStyle* style)
1440 {
1441     if (!style && !element->styleAffectedByEmpty())
1442         return;
1443
1444     if (!style || (element->styleAffectedByEmpty() && (!style->emptyState() || element->hasChildNodes())))
1445         element->setNeedsStyleRecalc();
1446 }
1447
1448 static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool finishedParsingCallback,
1449                                         Node* beforeChange, Node* afterChange, int childCountDelta)
1450 {
1451     // :empty selector.
1452     checkForEmptyStyleChange(e, style);
1453     
1454     if (!style || (e->needsStyleRecalc() && e->childrenAffectedByPositionalRules()))
1455         return;
1456
1457     // :first-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
1458     // In the DOM case, we only need to do something if |afterChange| is not 0.
1459     // |afterChange| is 0 in the parser case, so it works out that we'll skip this block.
1460     if (e->childrenAffectedByFirstChildRules() && afterChange) {
1461         // Find our new first child.
1462         Node* newFirstChild = 0;
1463         for (newFirstChild = e->firstChild(); newFirstChild && !newFirstChild->isElementNode(); newFirstChild = newFirstChild->nextSibling()) {};
1464         
1465         // Find the first element node following |afterChange|
1466         Node* firstElementAfterInsertion = 0;
1467         for (firstElementAfterInsertion = afterChange;
1468              firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode();
1469              firstElementAfterInsertion = firstElementAfterInsertion->nextSibling()) {};
1470         
1471         // This is the insert/append case.
1472         if (newFirstChild != firstElementAfterInsertion && firstElementAfterInsertion && firstElementAfterInsertion->attached() &&
1473             firstElementAfterInsertion->renderStyle() && firstElementAfterInsertion->renderStyle()->firstChildState())
1474             firstElementAfterInsertion->setNeedsStyleRecalc();
1475             
1476         // We also have to handle node removal.
1477         if (childCountDelta < 0 && newFirstChild == firstElementAfterInsertion && newFirstChild && (!newFirstChild->renderStyle() || !newFirstChild->renderStyle()->firstChildState()))
1478             newFirstChild->setNeedsStyleRecalc();
1479     }
1480
1481     // :last-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
1482     // In the DOM case, we only need to do something if |afterChange| is not 0.
1483     if (e->childrenAffectedByLastChildRules() && beforeChange) {
1484         // Find our new last child.
1485         Node* newLastChild = 0;
1486         for (newLastChild = e->lastChild(); newLastChild && !newLastChild->isElementNode(); newLastChild = newLastChild->previousSibling()) {};
1487         
1488         // Find the last element node going backwards from |beforeChange|
1489         Node* lastElementBeforeInsertion = 0;
1490         for (lastElementBeforeInsertion = beforeChange;
1491              lastElementBeforeInsertion && !lastElementBeforeInsertion->isElementNode();
1492              lastElementBeforeInsertion = lastElementBeforeInsertion->previousSibling()) {};
1493         
1494         if (newLastChild != lastElementBeforeInsertion && lastElementBeforeInsertion && lastElementBeforeInsertion->attached() &&
1495             lastElementBeforeInsertion->renderStyle() && lastElementBeforeInsertion->renderStyle()->lastChildState())
1496             lastElementBeforeInsertion->setNeedsStyleRecalc();
1497             
1498         // 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
1499         // to match now.
1500         if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild == lastElementBeforeInsertion && newLastChild && (!newLastChild->renderStyle() || !newLastChild->renderStyle()->lastChildState()))
1501             newLastChild->setNeedsStyleRecalc();
1502     }
1503
1504     // The + selector.  We need to invalidate the first element following the insertion point.  It is the only possible element
1505     // that could be affected by this DOM change.
1506     if (e->childrenAffectedByDirectAdjacentRules() && afterChange) {
1507         Node* firstElementAfterInsertion = 0;
1508         for (firstElementAfterInsertion = afterChange;
1509              firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode();
1510              firstElementAfterInsertion = firstElementAfterInsertion->nextSibling()) {};
1511         if (firstElementAfterInsertion && firstElementAfterInsertion->attached())
1512             firstElementAfterInsertion->setNeedsStyleRecalc();
1513     }
1514
1515     // Forward positional selectors include the ~ selector, nth-child, nth-of-type, first-of-type and only-of-type.
1516     // Backward positional selectors include nth-last-child, nth-last-of-type, last-of-type and only-of-type.
1517     // We have to invalidate everything following the insertion point in the forward case, and everything before the insertion point in the
1518     // backward case.
1519     // |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.
1520     // 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
1521     // here.  recalcStyle will then force a walk of the children when it sees that this has happened.
1522     if ((e->childrenAffectedByForwardPositionalRules() && afterChange)
1523         || (e->childrenAffectedByBackwardPositionalRules() && beforeChange))
1524         e->setNeedsStyleRecalc();
1525 }
1526
1527 void Element::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
1528 {
1529     ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
1530     if (changedByParser)
1531         checkForEmptyStyleChange(this, renderStyle());
1532     else
1533         checkForSiblingStyleChanges(this, renderStyle(), false, beforeChange, afterChange, childCountDelta);
1534
1535     if (ElementShadow * shadow = this->shadow())
1536         shadow->invalidateDistribution();
1537 }
1538
1539 void Element::beginParsingChildren()
1540 {
1541     clearIsParsingChildrenFinished();
1542     StyleResolver* styleResolver = document()->styleResolverIfExists();
1543     if (styleResolver && attached())
1544         styleResolver->pushParentElement(this);
1545 }
1546
1547 void Element::finishParsingChildren()
1548 {
1549     ContainerNode::finishParsingChildren();
1550     setIsParsingChildrenFinished();
1551     checkForSiblingStyleChanges(this, renderStyle(), true, lastChild(), 0, 0);
1552     if (StyleResolver* styleResolver = document()->styleResolverIfExists())
1553         styleResolver->popParentElement(this);
1554 }
1555
1556 #ifndef NDEBUG
1557 void Element::formatForDebugger(char* buffer, unsigned length) const
1558 {
1559     StringBuilder result;
1560     String s;
1561
1562     result.append(nodeName());
1563
1564     s = getIdAttribute();
1565     if (s.length() > 0) {
1566         if (result.length() > 0)
1567             result.appendLiteral("; ");
1568         result.appendLiteral("id=");
1569         result.append(s);
1570     }
1571
1572     s = getAttribute(classAttr);
1573     if (s.length() > 0) {
1574         if (result.length() > 0)
1575             result.appendLiteral("; ");
1576         result.appendLiteral("class=");
1577         result.append(s);
1578     }
1579
1580     strncpy(buffer, result.toString().utf8().data(), length - 1);
1581 }
1582 #endif
1583
1584 PassRefPtr<Attr> Element::setAttributeNode(Attr* attrNode, ExceptionCode& ec)
1585 {
1586     if (!attrNode) {
1587         ec = TYPE_MISMATCH_ERR;
1588         return 0;
1589     }
1590
1591     RefPtr<Attr> oldAttrNode = attrIfExists(attrNode->qualifiedName());
1592     if (oldAttrNode.get() == attrNode)
1593         return attrNode; // This Attr is already attached to the element.
1594
1595     // INUSE_ATTRIBUTE_ERR: Raised if node is an Attr that is already an attribute of another Element object.
1596     // The DOM user must explicitly clone Attr nodes to re-use them in other elements.
1597     if (attrNode->ownerElement()) {
1598         ec = INUSE_ATTRIBUTE_ERR;
1599         return 0;
1600     }
1601
1602     updateInvalidAttributes();
1603     ElementAttributeData* attributeData = mutableAttributeData();
1604
1605     size_t index = attributeData->getAttributeItemIndex(attrNode->qualifiedName());
1606     if (index != notFound) {
1607         if (oldAttrNode)
1608             detachAttrNodeFromElementWithValue(oldAttrNode.get(), attributeData->attributeItem(index)->value());
1609         else
1610             oldAttrNode = Attr::create(document(), attrNode->qualifiedName(), attributeData->attributeItem(index)->value());
1611     }
1612
1613     setAttributeInternal(index, attrNode->qualifiedName(), attrNode->value(), NotInSynchronizationOfLazyAttribute);
1614
1615     attrNode->attachToElement(this);
1616     ensureAttrNodeListForElement(this)->append(attrNode);
1617
1618     return oldAttrNode.release();
1619 }
1620
1621 PassRefPtr<Attr> Element::setAttributeNodeNS(Attr* attr, ExceptionCode& ec)
1622 {
1623     return setAttributeNode(attr, ec);
1624 }
1625
1626 PassRefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionCode& ec)
1627 {
1628     if (!attr) {
1629         ec = TYPE_MISMATCH_ERR;
1630         return 0;
1631     }
1632     if (attr->ownerElement() != this) {
1633         ec = NOT_FOUND_ERR;
1634         return 0;
1635     }
1636
1637     ASSERT(document() == attr->document());
1638
1639     const ElementAttributeData* attributeData = updatedAttributeData();
1640     ASSERT(attributeData);
1641
1642     size_t index = attributeData->getAttributeItemIndex(attr->qualifiedName());
1643     if (index == notFound) {
1644         ec = NOT_FOUND_ERR;
1645         return 0;
1646     }
1647
1648     return detachAttribute(index);
1649 }
1650
1651 bool Element::parseAttributeName(QualifiedName& out, const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionCode& ec)
1652 {
1653     String prefix, localName;
1654     if (!Document::parseQualifiedName(qualifiedName, prefix, localName, ec))
1655         return false;
1656     ASSERT(!ec);
1657
1658     QualifiedName qName(prefix, localName, namespaceURI);
1659
1660     if (!Document::hasValidNamespaceForAttributes(qName)) {
1661         ec = NAMESPACE_ERR;
1662         return false;
1663     }
1664
1665     out = qName;
1666     return true;
1667 }
1668
1669 void Element::setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode& ec)
1670 {
1671     QualifiedName parsedName = anyName;
1672     if (!parseAttributeName(parsedName, namespaceURI, qualifiedName, ec))
1673         return;
1674     setAttribute(parsedName, value);
1675 }
1676
1677 void Element::removeAttributeInternal(size_t index, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
1678 {
1679     ASSERT(index < attributeCount());
1680
1681     ElementAttributeData* attributeData = mutableAttributeData();
1682
1683     QualifiedName name = attributeData->attributeItem(index)->name();
1684     AtomicString valueBeingRemoved = attributeData->attributeItem(index)->value();
1685
1686     if (!inSynchronizationOfLazyAttribute) {
1687         if (!valueBeingRemoved.isNull())
1688             willModifyAttribute(name, valueBeingRemoved, nullAtom);
1689     }
1690
1691     if (RefPtr<Attr> attrNode = attrIfExists(name))
1692         detachAttrNodeFromElementWithValue(attrNode.get(), attributeData->attributeItem(index)->value());
1693
1694     attributeData->removeAttribute(index);
1695
1696     if (!inSynchronizationOfLazyAttribute)
1697         didRemoveAttribute(name);
1698 }
1699
1700 void Element::addAttributeInternal(const QualifiedName& name, const AtomicString& value, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
1701 {
1702     if (!inSynchronizationOfLazyAttribute)
1703         willModifyAttribute(name, nullAtom, value);
1704     mutableAttributeData()->addAttribute(Attribute(name, value));
1705     if (!inSynchronizationOfLazyAttribute)
1706         didAddAttribute(name, value);
1707 }
1708
1709 void Element::removeAttribute(const AtomicString& name)
1710 {
1711     if (!attributeData())
1712         return;
1713
1714     AtomicString localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
1715     size_t index = attributeData()->getAttributeItemIndex(localName, false);
1716     if (index == notFound) {
1717         if (UNLIKELY(localName == styleAttr) && attributeData()->m_styleAttributeIsDirty && isStyledElement())
1718             static_cast<StyledElement*>(this)->removeAllInlineStyleProperties();
1719         return;
1720     }
1721
1722     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
1723 }
1724
1725 void Element::removeAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName)
1726 {
1727     removeAttribute(QualifiedName(nullAtom, localName, namespaceURI));
1728 }
1729
1730 PassRefPtr<Attr> Element::getAttributeNode(const AtomicString& name)
1731 {
1732     const ElementAttributeData* attributeData = updatedAttributeData();
1733     if (!attributeData)
1734         return 0;
1735     const Attribute* attribute = attributeData->getAttributeItem(name, shouldIgnoreAttributeCase(this));
1736     if (!attribute)
1737         return 0;
1738     return ensureAttr(attribute->name());
1739 }
1740
1741 PassRefPtr<Attr> Element::getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName)
1742 {
1743     const ElementAttributeData* attributeData = updatedAttributeData();
1744     if (!attributeData)
1745         return 0;
1746     const Attribute* attribute = attributeData->getAttributeItem(QualifiedName(nullAtom, localName, namespaceURI));
1747     if (!attribute)
1748         return 0;
1749     return ensureAttr(attribute->name());
1750 }
1751
1752 bool Element::hasAttribute(const AtomicString& name) const
1753 {
1754     if (!attributeData())
1755         return false;
1756
1757     // This call to String::lower() seems to be required but
1758     // there may be a way to remove it.
1759     AtomicString localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
1760     return updatedAttributeData()->getAttributeItem(localName, false);
1761 }
1762
1763 bool Element::hasAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const
1764 {
1765     const ElementAttributeData* attributeData = updatedAttributeData();
1766     if (!attributeData)
1767         return false;
1768     return attributeData->getAttributeItem(QualifiedName(nullAtom, localName, namespaceURI));
1769 }
1770
1771 CSSStyleDeclaration *Element::style()
1772 {
1773     return 0;
1774 }
1775
1776 void Element::focus(bool restorePreviousSelection)
1777 {
1778     if (!inDocument())
1779         return;
1780
1781     Document* doc = document();
1782     if (doc->focusedNode() == this)
1783         return;
1784
1785     // If the stylesheets have already been loaded we can reliably check isFocusable.
1786     // If not, we continue and set the focused node on the focus controller below so
1787     // that it can be updated soon after attach. 
1788     if (doc->haveStylesheetsLoaded()) {
1789         doc->updateLayoutIgnorePendingStylesheets();
1790         if (!isFocusable())
1791             return;
1792     }
1793
1794     if (!supportsFocus())
1795         return;
1796
1797     RefPtr<Node> protect;
1798     if (Page* page = doc->page()) {
1799         // Focus and change event handlers can cause us to lose our last ref.
1800         // If a focus event handler changes the focus to a different node it
1801         // does not make sense to continue and update appearence.
1802         protect = this;
1803         if (!page->focusController()->setFocusedNode(this, doc->frame()))
1804             return;
1805     }
1806
1807     // Setting the focused node above might have invalidated the layout due to scripts.
1808     doc->updateLayoutIgnorePendingStylesheets();
1809
1810     if (!isFocusable()) {
1811         ensureElementRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(true);
1812         return;
1813     }
1814         
1815     cancelFocusAppearanceUpdate();
1816     updateFocusAppearance(restorePreviousSelection);
1817 }
1818
1819 void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
1820 {
1821     if (isRootEditableElement()) {
1822         Frame* frame = document()->frame();
1823         if (!frame)
1824             return;
1825         
1826         // When focusing an editable element in an iframe, don't reset the selection if it already contains a selection.
1827         if (this == frame->selection()->rootEditableElement())
1828             return;
1829
1830         // FIXME: We should restore the previous selection if there is one.
1831         VisibleSelection newSelection = VisibleSelection(firstPositionInOrBeforeNode(this), DOWNSTREAM);
1832         
1833         if (frame->selection()->shouldChangeSelection(newSelection)) {
1834             frame->selection()->setSelection(newSelection);
1835             frame->selection()->revealSelection();
1836         }
1837     } else if (renderer() && !renderer()->isWidget())
1838         renderer()->scrollRectToVisible(boundingBox());
1839 }
1840
1841 void Element::blur()
1842 {
1843     cancelFocusAppearanceUpdate();
1844     Document* doc = document();
1845     if (treeScope()->focusedNode() == this) {
1846         if (doc->frame())
1847             doc->frame()->page()->focusController()->setFocusedNode(0, doc->frame());
1848         else
1849             doc->setFocusedNode(0);
1850     }
1851 }
1852
1853 String Element::innerText()
1854 {
1855     // We need to update layout, since plainText uses line boxes in the render tree.
1856     document()->updateLayoutIgnorePendingStylesheets();
1857
1858     if (!renderer())
1859         return textContent(true);
1860
1861     return plainText(rangeOfContents(const_cast<Element*>(this)).get());
1862 }
1863
1864 String Element::outerText()
1865 {
1866     // Getting outerText is the same as getting innerText, only
1867     // setting is different. You would think this should get the plain
1868     // text for the outer range, but this is wrong, <br> for instance
1869     // would return different values for inner and outer text by such
1870     // a rule, but it doesn't in WinIE, and we want to match that.
1871     return innerText();
1872 }
1873
1874 String Element::title() const
1875 {
1876     return String();
1877 }
1878
1879 const AtomicString& Element::pseudo() const
1880 {
1881     return getAttribute(pseudoAttr);
1882 }
1883
1884 void Element::setPseudo(const AtomicString& value)
1885 {
1886     setAttribute(pseudoAttr, value);
1887 }
1888
1889 LayoutSize Element::minimumSizeForResizing() const
1890 {
1891     return hasRareData() ? elementRareData()->minimumSizeForResizing() : defaultMinimumSizeForResizing();
1892 }
1893
1894 void Element::setMinimumSizeForResizing(const LayoutSize& size)
1895 {
1896     if (!hasRareData() && size == defaultMinimumSizeForResizing())
1897         return;
1898     ensureElementRareData()->setMinimumSizeForResizing(size);
1899 }
1900
1901 RenderStyle* Element::computedStyle(PseudoId pseudoElementSpecifier)
1902 {
1903     // FIXME: Find and use the renderer from the pseudo element instead of the actual element so that the 'length'
1904     // properties, which are only known by the renderer because it did the layout, will be correct and so that the
1905     // values returned for the ":selection" pseudo-element will be correct.
1906     if (RenderStyle* usedStyle = renderStyle()) {
1907         if (pseudoElementSpecifier) {
1908             RenderStyle* cachedPseudoStyle = usedStyle->getCachedPseudoStyle(pseudoElementSpecifier);
1909             return cachedPseudoStyle ? cachedPseudoStyle : usedStyle;
1910          } else
1911             return usedStyle;
1912     }
1913
1914     if (!attached())
1915         // FIXME: Try to do better than this. Ensure that styleForElement() works for elements that are not in the
1916         // document tree and figure out when to destroy the computed style for such elements.
1917         return 0;
1918
1919     ElementRareData* data = ensureElementRareData();
1920     if (!data->computedStyle())
1921         data->setComputedStyle(document()->styleForElementIgnoringPendingStylesheets(this));
1922     return pseudoElementSpecifier ? data->computedStyle()->getCachedPseudoStyle(pseudoElementSpecifier) : data->computedStyle();
1923 }
1924
1925 void Element::setStyleAffectedByEmpty()
1926 {
1927     ensureElementRareData()->setStyleAffectedByEmpty(true);
1928 }
1929
1930 void Element::setChildrenAffectedByHover(bool value)
1931 {
1932     if (value || hasRareData())
1933         ensureElementRareData()->setChildrenAffectedByHover(value);
1934 }
1935
1936 void Element::setChildrenAffectedByActive(bool value)
1937 {
1938     if (value || hasRareData())
1939         ensureElementRareData()->setChildrenAffectedByActive(value);
1940 }
1941
1942 void Element::setChildrenAffectedByDrag(bool value)
1943 {
1944     if (value || hasRareData())
1945         ensureElementRareData()->setChildrenAffectedByDrag(value);
1946 }
1947
1948 void Element::setChildrenAffectedByFirstChildRules()
1949 {
1950     ensureElementRareData()->setChildrenAffectedByFirstChildRules(true);
1951 }
1952
1953 void Element::setChildrenAffectedByLastChildRules()
1954 {
1955     ensureElementRareData()->setChildrenAffectedByLastChildRules(true);
1956 }
1957
1958 void Element::setChildrenAffectedByDirectAdjacentRules()
1959 {
1960     ensureElementRareData()->setChildrenAffectedByDirectAdjacentRules(true);
1961 }
1962
1963 void Element::setChildrenAffectedByForwardPositionalRules()
1964 {
1965     ensureElementRareData()->setChildrenAffectedByForwardPositionalRules(true);
1966 }
1967
1968 void Element::setChildrenAffectedByBackwardPositionalRules()
1969 {
1970     ensureElementRareData()->setChildrenAffectedByBackwardPositionalRules(true);
1971 }
1972
1973 void Element::setChildIndex(unsigned index)
1974 {
1975     ElementRareData* rareData = ensureElementRareData();
1976     if (RenderStyle* style = renderStyle())
1977         style->setUnique();
1978     rareData->setChildIndex(index);
1979 }
1980
1981 bool Element::rareDataStyleAffectedByEmpty() const
1982 {
1983     ASSERT(hasRareData());
1984     return elementRareData()->styleAffectedByEmpty();
1985 }
1986
1987 bool Element::rareDataChildrenAffectedByHover() const
1988 {
1989     ASSERT(hasRareData());
1990     return elementRareData()->childrenAffectedByHover();
1991 }
1992
1993 bool Element::rareDataChildrenAffectedByActive() const
1994 {
1995     ASSERT(hasRareData());
1996     return elementRareData()->childrenAffectedByActive();
1997 }
1998
1999 bool Element::rareDataChildrenAffectedByDrag() const
2000 {
2001     ASSERT(hasRareData());
2002     return elementRareData()->childrenAffectedByDrag();
2003 }
2004
2005 bool Element::rareDataChildrenAffectedByFirstChildRules() const
2006 {
2007     ASSERT(hasRareData());
2008     return elementRareData()->childrenAffectedByFirstChildRules();
2009 }
2010
2011 bool Element::rareDataChildrenAffectedByLastChildRules() const
2012 {
2013     ASSERT(hasRareData());
2014     return elementRareData()->childrenAffectedByLastChildRules();
2015 }
2016
2017 bool Element::rareDataChildrenAffectedByDirectAdjacentRules() const
2018 {
2019     ASSERT(hasRareData());
2020     return elementRareData()->childrenAffectedByDirectAdjacentRules();
2021 }
2022
2023 bool Element::rareDataChildrenAffectedByForwardPositionalRules() const
2024 {
2025     ASSERT(hasRareData());
2026     return elementRareData()->childrenAffectedByForwardPositionalRules();
2027 }
2028
2029 bool Element::rareDataChildrenAffectedByBackwardPositionalRules() const
2030 {
2031     ASSERT(hasRareData());
2032     return elementRareData()->childrenAffectedByBackwardPositionalRules();
2033 }
2034
2035 unsigned Element::rareDataChildIndex() const
2036 {
2037     ASSERT(hasRareData());
2038     return elementRareData()->childIndex();
2039 }
2040
2041 void Element::setIsInCanvasSubtree(bool isInCanvasSubtree)
2042 {
2043     ensureElementRareData()->setIsInCanvasSubtree(isInCanvasSubtree);
2044 }
2045
2046 bool Element::isInCanvasSubtree() const
2047 {
2048     return hasRareData() && elementRareData()->isInCanvasSubtree();
2049 }
2050
2051 AtomicString Element::computeInheritedLanguage() const
2052 {
2053     const Node* n = this;
2054     AtomicString value;
2055     // The language property is inherited, so we iterate over the parents to find the first language.
2056     do {
2057         if (n->isElementNode()) {
2058             if (const ElementAttributeData* attributeData = static_cast<const Element*>(n)->attributeData()) {
2059                 // Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7
2060                 if (const Attribute* attribute = attributeData->getAttributeItem(XMLNames::langAttr))
2061                     value = attribute->value();
2062                 else if (const Attribute* attribute = attributeData->getAttributeItem(HTMLNames::langAttr))
2063                     value = attribute->value();
2064             }
2065         } else if (n->isDocumentNode()) {
2066             // checking the MIME content-language
2067             value = static_cast<const Document*>(n)->contentLanguage();
2068         }
2069
2070         n = n->parentNode();
2071     } while (n && value.isNull());
2072
2073     return value;
2074 }
2075
2076 Locale& Element::locale() const
2077 {
2078     return document()->getCachedLocale(computeInheritedLanguage());
2079 }
2080
2081 void Element::cancelFocusAppearanceUpdate()
2082 {
2083     if (hasRareData())
2084         elementRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
2085     if (document()->focusedNode() == this)
2086         document()->cancelFocusAppearanceUpdate();
2087 }
2088
2089 void Element::normalizeAttributes()
2090 {
2091     if (!hasAttributes())
2092         return;
2093     for (unsigned i = 0; i < attributeCount(); ++i) {
2094         if (RefPtr<Attr> attr = attrIfExists(attributeItem(i)->name()))
2095             attr->normalize();
2096     }
2097 }
2098
2099 void Element::updatePseudoElement(PseudoId pseudoId, StyleChange change)
2100 {
2101     PseudoElement* existing = pseudoElement(pseudoId);
2102     if (existing) {
2103         // PseudoElement styles hang off their parent element's style so if we needed
2104         // a style recalc we should Force one on the pseudo.
2105         existing->recalcStyle(needsStyleRecalc() ? Force : change);
2106
2107         // Wait until our parent is not displayed or pseudoElementRendererIsNeeded
2108         // is false, otherwise we could continously create and destroy PseudoElements
2109         // when RenderObject::isChildAllowed on our parent returns false for the
2110         // PseudoElement's renderer for each style recalc.
2111         if (!renderer() || !pseudoElementRendererIsNeeded(renderer()->getCachedPseudoStyle(pseudoId)))
2112             setPseudoElement(pseudoId, 0);
2113     } else if (RefPtr<PseudoElement> element = createPseudoElementIfNeeded(pseudoId)) {
2114         element->attach();
2115         setPseudoElement(pseudoId, element.release());
2116     }
2117 }
2118
2119 PassRefPtr<PseudoElement> Element::createPseudoElementIfNeeded(PseudoId pseudoId)
2120 {
2121     if (!document()->styleSheetCollection()->usesBeforeAfterRules())
2122         return 0;
2123
2124     if (!renderer() || !renderer()->canHaveGeneratedChildren())
2125         return 0;
2126
2127     if (isPseudoElement())
2128         return 0;
2129
2130     if (!pseudoElementRendererIsNeeded(renderer()->getCachedPseudoStyle(pseudoId)))
2131         return 0;
2132
2133     return PseudoElement::create(this, pseudoId);
2134 }
2135
2136 bool Element::hasPseudoElements() const
2137 {
2138     return hasRareData() && elementRareData()->hasPseudoElements();
2139 }
2140
2141 PseudoElement* Element::pseudoElement(PseudoId pseudoId) const
2142 {
2143     return hasRareData() ? elementRareData()->pseudoElement(pseudoId) : 0;
2144 }
2145
2146 void Element::setPseudoElement(PseudoId pseudoId, PassRefPtr<PseudoElement> element)
2147 {
2148     ensureElementRareData()->setPseudoElement(pseudoId, element);
2149     resetNeedsShadowTreeWalker();
2150 }
2151
2152
2153 // ElementTraversal API
2154 Element* Element::firstElementChild() const
2155 {
2156     return ElementTraversal::firstWithin(this);
2157 }
2158
2159 Element* Element::lastElementChild() const
2160 {
2161     Node* n = lastChild();
2162     while (n && !n->isElementNode())
2163         n = n->previousSibling();
2164     return static_cast<Element*>(n);
2165 }
2166
2167 unsigned Element::childElementCount() const
2168 {
2169     unsigned count = 0;
2170     Node* n = firstChild();
2171     while (n) {
2172         count += n->isElementNode();
2173         n = n->nextSibling();
2174     }
2175     return count;
2176 }
2177
2178 bool Element::matchesReadOnlyPseudoClass() const
2179 {
2180     return false;
2181 }
2182
2183 bool Element::matchesReadWritePseudoClass() const
2184 {
2185     return false;
2186 }
2187
2188 bool Element::webkitMatchesSelector(const String& selector, ExceptionCode& ec)
2189 {
2190     if (selector.isEmpty()) {
2191         ec = SYNTAX_ERR;
2192         return false;
2193     }
2194
2195     SelectorQuery* selectorQuery = document()->selectorQueryCache()->add(selector, document(), ec);
2196     if (!selectorQuery)
2197         return false;
2198     return selectorQuery->matches(this);
2199 }
2200
2201 DOMTokenList* Element::classList()
2202 {
2203     ElementRareData* data = ensureElementRareData();
2204     if (!data->classList())
2205         data->setClassList(ClassList::create(this));
2206     return data->classList();
2207 }
2208
2209 DOMTokenList* Element::optionalClassList() const
2210 {
2211     if (!hasRareData())
2212         return 0;
2213     return elementRareData()->classList();
2214 }
2215
2216 DOMStringMap* Element::dataset()
2217 {
2218     ElementRareData* data = ensureElementRareData();
2219     if (!data->dataset())
2220         data->setDataset(DatasetDOMStringMap::create(this));
2221     return data->dataset();
2222 }
2223
2224 KURL Element::getURLAttribute(const QualifiedName& name) const
2225 {
2226 #if !ASSERT_DISABLED
2227     if (attributeData()) {
2228         if (const Attribute* attribute = getAttributeItem(name))
2229             ASSERT(isURLAttribute(*attribute));
2230     }
2231 #endif
2232     return document()->completeURL(stripLeadingAndTrailingHTMLSpaces(getAttribute(name)));
2233 }
2234
2235 KURL Element::getNonEmptyURLAttribute(const QualifiedName& name) const
2236 {
2237 #if !ASSERT_DISABLED
2238     if (attributeData()) {
2239         if (const Attribute* attribute = getAttributeItem(name))
2240             ASSERT(isURLAttribute(*attribute));
2241     }
2242 #endif
2243     String value = stripLeadingAndTrailingHTMLSpaces(getAttribute(name));
2244     if (value.isEmpty())
2245         return KURL();
2246     return document()->completeURL(value);
2247 }
2248
2249 int Element::getIntegralAttribute(const QualifiedName& attributeName) const
2250 {
2251     return getAttribute(attributeName).string().toInt();
2252 }
2253
2254 void Element::setIntegralAttribute(const QualifiedName& attributeName, int value)
2255 {
2256     // FIXME: Need an AtomicString version of String::number.
2257     setAttribute(attributeName, String::number(value));
2258 }
2259
2260 unsigned Element::getUnsignedIntegralAttribute(const QualifiedName& attributeName) const
2261 {
2262     return getAttribute(attributeName).string().toUInt();
2263 }
2264
2265 void Element::setUnsignedIntegralAttribute(const QualifiedName& attributeName, unsigned value)
2266 {
2267     // FIXME: Need an AtomicString version of String::number.
2268     setAttribute(attributeName, String::number(value));
2269 }
2270
2271 #if ENABLE(SVG)
2272 bool Element::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
2273 {
2274     // Only create renderers for SVG elements whose parents are SVG elements, or for proper <svg xmlns="svgNS"> subdocuments.
2275     if (childContext.node()->isSVGElement())
2276         return childContext.node()->hasTagName(SVGNames::svgTag) || isSVGElement();
2277
2278     return ContainerNode::childShouldCreateRenderer(childContext);
2279 }
2280 #endif
2281     
2282 #if ENABLE(FULLSCREEN_API)
2283 void Element::webkitRequestFullscreen()
2284 {
2285     document()->requestFullScreenForElement(this, ALLOW_KEYBOARD_INPUT, Document::EnforceIFrameAllowFullScreenRequirement);
2286 }
2287
2288 void Element::webkitRequestFullScreen(unsigned short flags)
2289 {
2290     document()->requestFullScreenForElement(this, (flags | LEGACY_MOZILLA_REQUEST), Document::EnforceIFrameAllowFullScreenRequirement);
2291 }
2292
2293 bool Element::containsFullScreenElement() const
2294 {
2295     return hasRareData() && elementRareData()->containsFullScreenElement();
2296 }
2297
2298 void Element::setContainsFullScreenElement(bool flag)
2299 {
2300     ensureElementRareData()->setContainsFullScreenElement(flag);
2301     setNeedsStyleRecalc(SyntheticStyleChange);
2302 }
2303
2304 static Element* parentCrossingFrameBoundaries(Element* element)
2305 {
2306     ASSERT(element);
2307     return element->parentElement() ? element->parentElement() : element->document()->ownerElement();
2308 }
2309
2310 void Element::setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(bool flag)
2311 {
2312     Element* element = this;
2313     while ((element = parentCrossingFrameBoundaries(element)))
2314         element->setContainsFullScreenElement(flag);
2315 }
2316 #endif    
2317
2318 #if ENABLE(DIALOG_ELEMENT)
2319 bool Element::isInTopLayer() const
2320 {
2321     return hasRareData() && elementRareData()->isInTopLayer();
2322 }
2323
2324 void Element::setIsInTopLayer(bool inTopLayer)
2325 {
2326     ensureElementRareData()->setIsInTopLayer(inTopLayer);
2327     setNeedsStyleRecalc(SyntheticStyleChange);
2328 }
2329 #endif
2330
2331 #if ENABLE(POINTER_LOCK)
2332 void Element::webkitRequestPointerLock()
2333 {
2334     if (document()->page())
2335         document()->page()->pointerLockController()->requestPointerLock(this);
2336 }
2337 #endif
2338
2339 SpellcheckAttributeState Element::spellcheckAttributeState() const
2340 {
2341     const AtomicString& value = getAttribute(HTMLNames::spellcheckAttr);
2342     if (value == nullAtom)
2343         return SpellcheckAttributeDefault;
2344     if (equalIgnoringCase(value, "true") || equalIgnoringCase(value, ""))
2345         return SpellcheckAttributeTrue;
2346     if (equalIgnoringCase(value, "false"))
2347         return SpellcheckAttributeFalse;
2348
2349     return SpellcheckAttributeDefault;
2350 }
2351
2352 bool Element::isSpellCheckingEnabled() const
2353 {
2354     for (const Element* element = this; element; element = element->parentOrHostElement()) {
2355         switch (element->spellcheckAttributeState()) {
2356         case SpellcheckAttributeTrue:
2357             return true;
2358         case SpellcheckAttributeFalse:
2359             return false;
2360         case SpellcheckAttributeDefault:
2361             break;
2362         }
2363     }
2364
2365     return true;
2366 }
2367
2368 RenderRegion* Element::renderRegion() const
2369 {
2370     if (renderer() && renderer()->isRenderRegion())
2371         return toRenderRegion(renderer());
2372
2373     return 0;
2374 }
2375
2376 #if ENABLE(CSS_REGIONS)
2377
2378 const AtomicString& Element::webkitRegionOverset() const
2379 {
2380     document()->updateLayoutIgnorePendingStylesheets();
2381
2382     DEFINE_STATIC_LOCAL(AtomicString, undefinedState, ("undefined", AtomicString::ConstructFromLiteral));
2383     if (!document()->cssRegionsEnabled() || !renderRegion())
2384         return undefinedState;
2385
2386     switch (renderRegion()->regionState()) {
2387     case RenderRegion::RegionFit: {
2388         DEFINE_STATIC_LOCAL(AtomicString, fitState, ("fit", AtomicString::ConstructFromLiteral));
2389         return fitState;
2390     }
2391     case RenderRegion::RegionEmpty: {
2392         DEFINE_STATIC_LOCAL(AtomicString, emptyState, ("empty", AtomicString::ConstructFromLiteral));
2393         return emptyState;
2394     }
2395     case RenderRegion::RegionOverset: {
2396         DEFINE_STATIC_LOCAL(AtomicString, overflowState, ("overset", AtomicString::ConstructFromLiteral));
2397         return overflowState;
2398     }
2399     case RenderRegion::RegionUndefined:
2400         return undefinedState;
2401     }
2402
2403     ASSERT_NOT_REACHED();
2404     return undefinedState;
2405 }
2406
2407 Vector<RefPtr<Range> > Element::webkitGetRegionFlowRanges() const
2408 {
2409     document()->updateLayoutIgnorePendingStylesheets();
2410
2411     Vector<RefPtr<Range> > rangeObjects;
2412     if (document()->cssRegionsEnabled() && renderer() && renderer()->isRenderRegion()) {
2413         RenderRegion* region = toRenderRegion(renderer());
2414         if (region->isValid())
2415             region->getRanges(rangeObjects);
2416     }
2417
2418     return rangeObjects;
2419 }
2420
2421 #endif
2422
2423 #ifndef NDEBUG
2424 bool Element::fastAttributeLookupAllowed(const QualifiedName& name) const
2425 {
2426     if (name == HTMLNames::styleAttr)
2427         return false;
2428
2429 #if ENABLE(SVG)
2430     if (isSVGElement())
2431         return !SVGElement::isAnimatableAttribute(name);
2432 #endif
2433
2434     return true;
2435 }
2436 #endif
2437
2438 #ifdef DUMP_NODE_STATISTICS
2439 bool Element::hasNamedNodeMap() const
2440 {
2441     return hasRareData() && elementRareData()->attributeMap();
2442 }
2443 #endif
2444
2445 void Element::updateLabel(TreeScope* scope, const AtomicString& oldForAttributeValue, const AtomicString& newForAttributeValue)
2446 {
2447     ASSERT(hasTagName(labelTag));
2448
2449     if (!inDocument())
2450         return;
2451
2452     if (oldForAttributeValue == newForAttributeValue)
2453         return;
2454
2455     if (!oldForAttributeValue.isEmpty())
2456         scope->removeLabel(oldForAttributeValue, static_cast<HTMLLabelElement*>(this));
2457     if (!newForAttributeValue.isEmpty())
2458         scope->addLabel(newForAttributeValue, static_cast<HTMLLabelElement*>(this));
2459 }
2460
2461 void Element::willModifyAttribute(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue)
2462 {
2463     if (isIdAttributeName(name))
2464         updateId(oldValue, newValue);
2465     else if (name == HTMLNames::nameAttr)
2466         updateName(oldValue, newValue);
2467     else if (name == HTMLNames::forAttr && hasTagName(labelTag)) {
2468         TreeScope* scope = treeScope();
2469         if (scope->shouldCacheLabelsByForAttribute())
2470             updateLabel(scope, oldValue, newValue);
2471     }
2472
2473 #if ENABLE(MUTATION_OBSERVERS)
2474     if (OwnPtr<MutationObserverInterestGroup> recipients = MutationObserverInterestGroup::createForAttributesMutation(this, name))
2475         recipients->enqueueMutationRecord(MutationRecord::createAttributes(this, name, oldValue));
2476 #endif
2477
2478 #if ENABLE(INSPECTOR)
2479     InspectorInstrumentation::willModifyDOMAttr(document(), this, oldValue, newValue);
2480 #endif
2481 }
2482
2483 void Element::didAddAttribute(const QualifiedName& name, const AtomicString& value)
2484 {
2485     attributeChanged(name, value);
2486     InspectorInstrumentation::didModifyDOMAttr(document(), this, name.localName(), value);
2487     dispatchSubtreeModifiedEvent();
2488 }
2489
2490 void Element::didModifyAttribute(const QualifiedName& name, const AtomicString& value)
2491 {
2492     attributeChanged(name, value);
2493     InspectorInstrumentation::didModifyDOMAttr(document(), this, name.localName(), value);
2494     // Do not dispatch a DOMSubtreeModified event here; see bug 81141.
2495 }
2496
2497 void Element::didRemoveAttribute(const QualifiedName& name)
2498 {
2499     attributeChanged(name, nullAtom);
2500     InspectorInstrumentation::didRemoveDOMAttr(document(), this, name.localName());
2501     dispatchSubtreeModifiedEvent();
2502 }
2503
2504
2505 void Element::updateNamedItemRegistration(const AtomicString& oldName, const AtomicString& newName)
2506 {
2507     if (!document()->isHTMLDocument())
2508         return;
2509
2510     if (!oldName.isEmpty())
2511         static_cast<HTMLDocument*>(document())->removeNamedItem(oldName);
2512
2513     if (!newName.isEmpty())
2514         static_cast<HTMLDocument*>(document())->addNamedItem(newName);
2515 }
2516
2517 void Element::updateExtraNamedItemRegistration(const AtomicString& oldId, const AtomicString& newId)
2518 {
2519     if (!document()->isHTMLDocument())
2520         return;
2521
2522     if (!oldId.isEmpty())
2523         static_cast<HTMLDocument*>(document())->removeExtraNamedItem(oldId);
2524
2525     if (!newId.isEmpty())
2526         static_cast<HTMLDocument*>(document())->addExtraNamedItem(newId);
2527 }
2528
2529 PassRefPtr<HTMLCollection> Element::ensureCachedHTMLCollection(CollectionType type)
2530 {
2531     if (HTMLCollection* collection = cachedHTMLCollection(type))
2532         return collection;
2533
2534     RefPtr<HTMLCollection> collection;
2535     if (type == TableRows) {
2536         ASSERT(hasTagName(tableTag));
2537         return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLTableRowsCollection>(this, type);
2538     } else if (type == SelectOptions) {
2539         ASSERT(hasTagName(selectTag));
2540         return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLOptionsCollection>(this, type);
2541     } else if (type == FormControls) {
2542         ASSERT(hasTagName(formTag) || hasTagName(fieldsetTag));
2543         return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLFormControlsCollection>(this, type);
2544 #if ENABLE(MICRODATA)
2545     } else if (type == ItemProperties) {
2546         return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLPropertiesCollection>(this, type);
2547 #endif
2548     }
2549     return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLCollection>(this, type);
2550 }
2551
2552 HTMLCollection* Element::cachedHTMLCollection(CollectionType type)
2553 {
2554     return hasRareData() && rareData()->nodeLists() ? rareData()->nodeLists()->cacheWithAtomicName<HTMLCollection>(type) : 0;
2555 }
2556
2557 IntSize Element::savedLayerScrollOffset() const
2558 {
2559     return hasRareData() ? elementRareData()->savedLayerScrollOffset() : IntSize();
2560 }
2561
2562 void Element::setSavedLayerScrollOffset(const IntSize& size)
2563 {
2564     if (size.isZero() && !hasRareData())
2565         return;
2566     ensureElementRareData()->setSavedLayerScrollOffset(size);
2567 }
2568
2569 PassRefPtr<Attr> Element::attrIfExists(const QualifiedName& name)
2570 {
2571     if (AttrNodeList* attrNodeList = attrNodeListForElement(this))
2572         return findAttrNodeInList(attrNodeList, name);
2573     return 0;
2574 }
2575
2576 PassRefPtr<Attr> Element::ensureAttr(const QualifiedName& name)
2577 {
2578     AttrNodeList* attrNodeList = ensureAttrNodeListForElement(this);
2579     RefPtr<Attr> attrNode = findAttrNodeInList(attrNodeList, name);
2580     if (!attrNode) {
2581         attrNode = Attr::create(this, name);
2582         attrNodeList->append(attrNode);
2583     }
2584     return attrNode.release();
2585 }
2586
2587 void Element::detachAttrNodeFromElementWithValue(Attr* attrNode, const AtomicString& value)
2588 {
2589     ASSERT(hasSyntheticAttrChildNodes());
2590     attrNode->detachFromElementWithValue(value);
2591
2592     AttrNodeList* attrNodeList = attrNodeListForElement(this);
2593     for (unsigned i = 0; i < attrNodeList->size(); ++i) {
2594         if (attrNodeList->at(i)->qualifiedName() == attrNode->qualifiedName()) {
2595             attrNodeList->remove(i);
2596             if (attrNodeList->isEmpty())
2597                 removeAttrNodeListForElement(this);
2598             return;
2599         }
2600     }
2601     ASSERT_NOT_REACHED();
2602 }
2603
2604 void Element::detachAllAttrNodesFromElement()
2605 {
2606     AttrNodeList* attrNodeList = attrNodeListForElement(this);
2607     ASSERT(attrNodeList);
2608
2609     for (unsigned i = 0; i < attributeCount(); ++i) {
2610         const Attribute* attribute = attributeItem(i);
2611         if (RefPtr<Attr> attrNode = findAttrNodeInList(attrNodeList, attribute->name()))
2612             attrNode->detachFromElementWithValue(attribute->value());
2613     }
2614
2615     removeAttrNodeListForElement(this);
2616 }
2617
2618 bool Element::willRecalcStyle(StyleChange)
2619 {
2620     ASSERT(hasCustomCallbacks());
2621     return true;
2622 }
2623
2624 void Element::didRecalcStyle(StyleChange)
2625 {
2626     ASSERT(hasCustomCallbacks());
2627 }
2628
2629
2630 PassRefPtr<RenderStyle> Element::customStyleForRenderer()
2631 {
2632     ASSERT(hasCustomCallbacks());
2633     return 0;
2634 }
2635
2636 void Element::cloneAttributesFromElement(const Element& other)
2637 {
2638     if (hasSyntheticAttrChildNodes())
2639         detachAllAttrNodesFromElement();
2640
2641     other.updateInvalidAttributes();
2642     if (!other.m_attributeData) {
2643         m_attributeData.clear();
2644         return;
2645     }
2646
2647     const AtomicString& oldID = getIdAttribute();
2648     const AtomicString& newID = other.getIdAttribute();
2649
2650     if (!oldID.isNull() || !newID.isNull())
2651         updateId(oldID, newID);
2652
2653     const AtomicString& oldName = getNameAttribute();
2654     const AtomicString& newName = other.getNameAttribute();
2655
2656     if (!oldName.isNull() || !newName.isNull())
2657         updateName(oldName, newName);
2658
2659     // If 'other' has a mutable ElementAttributeData, convert it to an immutable one so we can share it between both elements.
2660     // We can only do this if there is no CSSOM wrapper for other's inline style, and there are no presentation attributes.
2661     if (other.m_attributeData->isMutable()
2662         && !other.m_attributeData->presentationAttributeStyle()
2663         && (!other.m_attributeData->inlineStyle() || !other.m_attributeData->inlineStyle()->hasCSSOMWrapper()))
2664         const_cast<Element&>(other).m_attributeData = other.m_attributeData->makeImmutableCopy();
2665
2666     if (!other.m_attributeData->isMutable())
2667         m_attributeData = other.m_attributeData;
2668     else
2669         m_attributeData = other.m_attributeData->makeMutableCopy();
2670
2671     for (unsigned i = 0; i < m_attributeData->length(); ++i) {
2672         const Attribute* attribute = const_cast<const ElementAttributeData*>(m_attributeData.get())->attributeItem(i);
2673         attributeChanged(attribute->name(), attribute->value());
2674     }
2675 }
2676
2677 void Element::cloneDataFromElement(const Element& other)
2678 {
2679     cloneAttributesFromElement(other);
2680     copyNonAttributePropertiesFromElement(other);
2681 }
2682
2683 void Element::createMutableAttributeData()
2684 {
2685     if (!m_attributeData)
2686         m_attributeData = ElementAttributeData::create();
2687     else
2688         m_attributeData = m_attributeData->makeMutableCopy();
2689 }
2690
2691 void Element::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
2692 {
2693     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM);
2694     ContainerNode::reportMemoryUsage(memoryObjectInfo);
2695     info.addMember(m_tagName);
2696     info.addMember(m_attributeData);
2697 }
2698
2699 } // namespace WebCore