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