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