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