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