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