f48fb112b7f353b71555c91e9d27e0569692f049
[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, 2013 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 "Chrome.h"
34 #include "ChromeClient.h"
35 #include "ClassList.h"
36 #include "ClientRect.h"
37 #include "ClientRectList.h"
38 #include "CustomElementRegistry.h"
39 #include "DOMTokenList.h"
40 #include "DatasetDOMStringMap.h"
41 #include "Document.h"
42 #include "DocumentFragment.h"
43 #include "DocumentSharedObjectPool.h"
44 #include "ElementRareData.h"
45 #include "EventDispatcher.h"
46 #include "ExceptionCode.h"
47 #include "FlowThreadController.h"
48 #include "FocusController.h"
49 #include "FocusEvent.h"
50 #include "Frame.h"
51 #include "FrameSelection.h"
52 #include "FrameView.h"
53 #include "HTMLCollection.h"
54 #include "HTMLDocument.h"
55 #include "HTMLElement.h"
56 #include "HTMLFormControlsCollection.h"
57 #include "HTMLFrameOwnerElement.h"
58 #include "HTMLLabelElement.h"
59 #include "HTMLNameCollection.h"
60 #include "HTMLNames.h"
61 #include "HTMLOptionsCollection.h"
62 #include "HTMLParserIdioms.h"
63 #include "HTMLTableRowsCollection.h"
64 #include "InsertionPoint.h"
65 #include "InspectorInstrumentation.h"
66 #include "MutationObserverInterestGroup.h"
67 #include "MutationRecord.h"
68 #include "NamedNodeMap.h"
69 #include "NodeList.h"
70 #include "NodeRenderStyle.h"
71 #include "NodeRenderingContext.h"
72 #include "NodeTraversal.h"
73 #include "Page.h"
74 #include "PointerLockController.h"
75 #include "PseudoElement.h"
76 #include "RenderRegion.h"
77 #include "RenderTheme.h"
78 #include "RenderView.h"
79 #include "RenderWidget.h"
80 #include "SelectorQuery.h"
81 #include "Settings.h"
82 #include "ShadowRoot.h"
83 #include "StylePropertySet.h"
84 #include "StyleResolver.h"
85 #include "Text.h"
86 #include "TextIterator.h"
87 #include "VoidCallback.h"
88 #include "XMLNSNames.h"
89 #include "XMLNames.h"
90 #include "htmlediting.h"
91 #include <wtf/BitVector.h>
92 #include <wtf/CurrentTime.h>
93 #include <wtf/text/CString.h>
94
95 #if ENABLE(SVG)
96 #include "SVGDocumentExtensions.h"
97 #include "SVGElement.h"
98 #include "SVGNames.h"
99 #endif
100
101 namespace WebCore {
102
103 using namespace HTMLNames;
104 using namespace XMLNames;
105
106 static inline bool shouldIgnoreAttributeCase(const Element* e)
107 {
108     return e && e->document()->isHTMLDocument() && e->isHTMLElement();
109 }
110     
111 class StyleResolverParentPusher {
112 public:
113     StyleResolverParentPusher(Element* parent)
114         : m_parent(parent)
115         , m_pushedStyleResolver(0)
116     {
117     }
118     void push()
119     {
120         if (m_pushedStyleResolver)
121             return;
122         m_pushedStyleResolver = m_parent->document()->ensureStyleResolver();
123         m_pushedStyleResolver->pushParentElement(m_parent);
124     }
125     ~StyleResolverParentPusher()
126     {
127
128         if (!m_pushedStyleResolver)
129             return;
130
131         // This tells us that our pushed style selector is in a bad state,
132         // so we should just bail out in that scenario.
133         ASSERT(m_pushedStyleResolver == m_parent->document()->ensureStyleResolver());
134         if (m_pushedStyleResolver != m_parent->document()->ensureStyleResolver())
135             return;
136
137         m_pushedStyleResolver->popParentElement(m_parent);
138     }
139
140 private:
141     Element* m_parent;
142     StyleResolver* m_pushedStyleResolver;
143 };
144
145 typedef Vector<RefPtr<Attr> > AttrNodeList;
146 typedef HashMap<Element*, OwnPtr<AttrNodeList> > AttrNodeListMap;
147
148 static AttrNodeListMap& attrNodeListMap()
149 {
150     DEFINE_STATIC_LOCAL(AttrNodeListMap, map, ());
151     return map;
152 }
153
154 static AttrNodeList* attrNodeListForElement(Element* element)
155 {
156     if (!element->hasSyntheticAttrChildNodes())
157         return 0;
158     ASSERT(attrNodeListMap().contains(element));
159     return attrNodeListMap().get(element);
160 }
161
162 static AttrNodeList* ensureAttrNodeListForElement(Element* element)
163 {
164     if (element->hasSyntheticAttrChildNodes()) {
165         ASSERT(attrNodeListMap().contains(element));
166         return attrNodeListMap().get(element);
167     }
168     ASSERT(!attrNodeListMap().contains(element));
169     element->setHasSyntheticAttrChildNodes(true);
170     AttrNodeListMap::AddResult result = attrNodeListMap().add(element, adoptPtr(new AttrNodeList));
171     return result.iterator->value.get();
172 }
173
174 static void removeAttrNodeListForElement(Element* element)
175 {
176     ASSERT(element->hasSyntheticAttrChildNodes());
177     ASSERT(attrNodeListMap().contains(element));
178     attrNodeListMap().remove(element);
179     element->setHasSyntheticAttrChildNodes(false);
180 }
181
182 static Attr* findAttrNodeInList(AttrNodeList* attrNodeList, const QualifiedName& name)
183 {
184     for (unsigned i = 0; i < attrNodeList->size(); ++i) {
185         if (attrNodeList->at(i)->qualifiedName() == name)
186             return attrNodeList->at(i).get();
187     }
188     return 0;
189 }
190
191 PassRefPtr<Element> Element::create(const QualifiedName& tagName, Document* document)
192 {
193     return adoptRef(new Element(tagName, document, CreateElement));
194 }
195
196 Element::~Element()
197 {
198 #ifndef NDEBUG
199     if (document() && document()->renderer()) {
200         // When the document is not destroyed, an element that was part of a named flow
201         // content nodes should have been removed from the content nodes collection
202         // and the inNamedFlow flag reset.
203         ASSERT(!inNamedFlow());
204     }
205 #endif
206
207     if (hasRareData()) {
208         ElementRareData* data = elementRareData();
209         data->setPseudoElement(BEFORE, 0);
210         data->setPseudoElement(AFTER, 0);
211         data->clearShadow();
212     }
213
214     if (hasSyntheticAttrChildNodes())
215         detachAllAttrNodesFromElement();
216
217 #if ENABLE(SVG)
218     if (hasPendingResources()) {
219         document()->accessSVGExtensions()->removeElementFromPendingResources(this);
220         ASSERT(!hasPendingResources());
221     }
222 #endif
223 }
224
225 inline ElementRareData* Element::elementRareData() const
226 {
227     ASSERT(hasRareData());
228     return static_cast<ElementRareData*>(rareData());
229 }
230
231 inline ElementRareData* Element::ensureElementRareData()
232 {
233     return static_cast<ElementRareData*>(ensureRareData());
234 }
235
236 void Element::clearTabIndexExplicitlyIfNeeded()
237 {
238     if (hasRareData())
239         elementRareData()->clearTabIndexExplicitly();
240 }
241
242 void Element::setTabIndexExplicitly(short tabIndex)
243 {
244     ensureElementRareData()->setTabIndexExplicitly(tabIndex);
245 }
246
247 bool Element::supportsFocus() const
248 {
249     return hasRareData() && elementRareData()->tabIndexSetExplicitly();
250 }
251
252 Element* Element::focusDelegate()
253 {
254     return this;
255 }
256
257 short Element::tabIndex() const
258 {
259     return hasRareData() ? elementRareData()->tabIndex() : 0;
260 }
261
262 bool Element::isKeyboardFocusable(KeyboardEvent*) const
263 {
264     return isFocusable() && tabIndex() >= 0;
265 }
266
267 bool Element::isMouseFocusable() const
268 {
269     return isFocusable();
270 }
271
272 bool Element::shouldUseInputMethod()
273 {
274     return isContentEditable(UserSelectAllIsAlwaysNonEditable);
275 }
276
277 void Element::dispatchSimulatedClick(Event* underlyingEvent, SimulatedClickMouseEventOptions eventOptions, SimulatedClickVisualOptions visualOptions)
278 {
279     EventDispatcher::dispatchSimulatedClick(this, underlyingEvent, eventOptions, visualOptions);
280 }
281
282 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, blur);
283 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, error);
284 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, focus);
285 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, load);
286
287 PassRefPtr<Node> Element::cloneNode(bool deep)
288 {
289     return deep ? cloneElementWithChildren() : cloneElementWithoutChildren();
290 }
291
292 PassRefPtr<Element> Element::cloneElementWithChildren()
293 {
294     RefPtr<Element> clone = cloneElementWithoutChildren();
295     cloneChildNodes(clone.get());
296     return clone.release();
297 }
298
299 PassRefPtr<Element> Element::cloneElementWithoutChildren()
300 {
301     RefPtr<Element> clone = cloneElementWithoutAttributesAndChildren();
302     // This will catch HTML elements in the wrong namespace that are not correctly copied.
303     // This is a sanity check as HTML overloads some of the DOM methods.
304     ASSERT(isHTMLElement() == clone->isHTMLElement());
305
306     clone->cloneDataFromElement(*this);
307     return clone.release();
308 }
309
310 PassRefPtr<Element> Element::cloneElementWithoutAttributesAndChildren()
311 {
312     return document()->createElement(tagQName(), false);
313 }
314
315 PassRefPtr<Attr> Element::detachAttribute(unsigned index)
316 {
317     ASSERT(elementData());
318
319     const Attribute* attribute = elementData()->attributeItem(index);
320     ASSERT(attribute);
321
322     RefPtr<Attr> attrNode = attrIfExists(attribute->name());
323     if (attrNode)
324         detachAttrNodeFromElementWithValue(attrNode.get(), attribute->value());
325     else
326         attrNode = Attr::create(document(), attribute->name(), attribute->value());
327
328     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
329     return attrNode.release();
330 }
331
332 void Element::removeAttribute(const QualifiedName& name)
333 {
334     if (!elementData())
335         return;
336
337     unsigned index = elementData()->getAttributeItemIndex(name);
338     if (index == ElementData::attributeNotFound)
339         return;
340
341     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
342 }
343
344 void Element::setBooleanAttribute(const QualifiedName& name, bool value)
345 {
346     if (value)
347         setAttribute(name, emptyAtom);
348     else
349         removeAttribute(name);
350 }
351
352 NamedNodeMap* Element::attributes() const
353 {
354     ElementRareData* rareData = const_cast<Element*>(this)->ensureElementRareData();
355     if (NamedNodeMap* attributeMap = rareData->attributeMap())
356         return attributeMap;
357
358     rareData->setAttributeMap(NamedNodeMap::create(const_cast<Element*>(this)));
359     return rareData->attributeMap();
360 }
361
362 Node::NodeType Element::nodeType() const
363 {
364     return ELEMENT_NODE;
365 }
366
367 bool Element::hasAttribute(const QualifiedName& name) const
368 {
369     return hasAttributeNS(name.namespaceURI(), name.localName());
370 }
371
372 void Element::synchronizeAllAttributes() const
373 {
374     if (!elementData())
375         return;
376     if (elementData()->m_styleAttributeIsDirty) {
377         ASSERT(isStyledElement());
378         static_cast<const StyledElement*>(this)->synchronizeStyleAttributeInternal();
379     }
380 #if ENABLE(SVG)
381     if (elementData()->m_animatedSVGAttributesAreDirty) {
382         ASSERT(isSVGElement());
383         toSVGElement(this)->synchronizeAnimatedSVGAttribute(anyQName());
384     }
385 #endif
386 }
387
388 inline void Element::synchronizeAttribute(const QualifiedName& name) const
389 {
390     if (!elementData())
391         return;
392     if (UNLIKELY(name == styleAttr && elementData()->m_styleAttributeIsDirty)) {
393         ASSERT(isStyledElement());
394         static_cast<const StyledElement*>(this)->synchronizeStyleAttributeInternal();
395         return;
396     }
397 #if ENABLE(SVG)
398     if (UNLIKELY(elementData()->m_animatedSVGAttributesAreDirty)) {
399         ASSERT(isSVGElement());
400         toSVGElement(this)->synchronizeAnimatedSVGAttribute(name);
401     }
402 #endif
403 }
404
405 inline void Element::synchronizeAttribute(const AtomicString& localName) const
406 {
407     // This version of synchronizeAttribute() is streamlined for the case where you don't have a full QualifiedName,
408     // e.g when called from DOM API.
409     if (!elementData())
410         return;
411     if (elementData()->m_styleAttributeIsDirty && equalPossiblyIgnoringCase(localName, styleAttr.localName(), shouldIgnoreAttributeCase(this))) {
412         ASSERT(isStyledElement());
413         static_cast<const StyledElement*>(this)->synchronizeStyleAttributeInternal();
414         return;
415     }
416 #if ENABLE(SVG)
417     if (elementData()->m_animatedSVGAttributesAreDirty) {
418         // We're not passing a namespace argument on purpose. SVGNames::*Attr are defined w/o namespaces as well.
419         ASSERT(isSVGElement());
420         static_cast<const SVGElement*>(this)->synchronizeAnimatedSVGAttribute(QualifiedName(nullAtom, localName, nullAtom));
421     }
422 #endif
423 }
424
425 const AtomicString& Element::getAttribute(const QualifiedName& name) const
426 {
427     if (!elementData())
428         return nullAtom;
429     synchronizeAttribute(name);
430     if (const Attribute* attribute = getAttributeItem(name))
431         return attribute->value();
432     return nullAtom;
433 }
434
435 bool Element::isFocusable() const
436 {
437     if (!inDocument() || !supportsFocus())
438         return false;
439
440     // Elements in canvas fallback content are not rendered, but they are allowed to be
441     // focusable as long as their canvas is displayed and visible.
442     if (isInCanvasSubtree()) {
443         const Element* e = this;
444         while (e && !e->hasLocalName(canvasTag))
445             e = e->parentElement();
446         ASSERT(e);
447         return e->renderer() && e->renderer()->style()->visibility() == VISIBLE;
448     }
449
450     if (renderer())
451         ASSERT(!renderer()->needsLayout());
452     else {
453         // If the node is in a display:none tree it might say it needs style recalc but
454         // the whole document is actually up to date.
455         ASSERT(!document()->childNeedsStyleRecalc());
456     }
457
458     // FIXME: Even if we are not visible, we might have a child that is visible.
459     // Hyatt wants to fix that some day with a "has visible content" flag or the like.
460     if (!renderer() || renderer()->style()->visibility() != VISIBLE)
461         return false;
462
463     return true;
464 }
465
466 bool Element::isUserActionElementInActiveChain() const
467 {
468     ASSERT(isUserActionElement());
469     return document()->userActionElements().isInActiveChain(this);
470 }
471
472 bool Element::isUserActionElementActive() const
473 {
474     ASSERT(isUserActionElement());
475     return document()->userActionElements().isActive(this);
476 }
477
478 bool Element::isUserActionElementFocused() const
479 {
480     ASSERT(isUserActionElement());
481     return document()->userActionElements().isFocused(this);
482 }
483
484 bool Element::isUserActionElementHovered() const
485 {
486     ASSERT(isUserActionElement());
487     return document()->userActionElements().isHovered(this);
488 }
489
490 void Element::setActive(bool flag, bool pause)
491 {
492     if (flag == active())
493         return;
494
495     if (Document* document = this->document())
496         document->userActionElements().setActive(this, flag);
497
498     if (!renderer())
499         return;
500
501     bool reactsToPress = renderStyle()->affectedByActive() || childrenAffectedByActive();
502     if (reactsToPress)
503         setNeedsStyleRecalc();
504
505     if (renderer()->style()->hasAppearance() && renderer()->theme()->stateChanged(renderer(), PressedState))
506         reactsToPress = true;
507
508     // The rest of this function implements a feature that only works if the
509     // platform supports immediate invalidations on the ChromeClient, so bail if
510     // that isn't supported.
511     if (!document()->page()->chrome().client()->supportsImmediateInvalidation())
512         return;
513
514     if (reactsToPress && pause) {
515         // The delay here is subtle. It relies on an assumption, namely that the amount of time it takes
516         // to repaint the "down" state of the control is about the same time as it would take to repaint the
517         // "up" state. Once you assume this, you can just delay for 100ms - that time (assuming that after you
518         // leave this method, it will be about that long before the flush of the up state happens again).
519 #ifdef HAVE_FUNC_USLEEP
520         double startTime = currentTime();
521 #endif
522
523         Document::updateStyleForAllDocuments();
524         // Do an immediate repaint.
525         if (renderer())
526             renderer()->repaint(true);
527
528         // FIXME: Come up with a less ridiculous way of doing this.
529 #ifdef HAVE_FUNC_USLEEP
530         // Now pause for a small amount of time (1/10th of a second from before we repainted in the pressed state)
531         double remainingTime = 0.1 - (currentTime() - startTime);
532         if (remainingTime > 0)
533             usleep(static_cast<useconds_t>(remainingTime * 1000000.0));
534 #endif
535     }
536 }
537
538 void Element::setFocus(bool flag)
539 {
540     if (flag == focused())
541         return;
542
543     if (Document* document = this->document())
544         document->userActionElements().setFocused(this, flag);
545
546     setNeedsStyleRecalc();
547 }
548
549 void Element::setHovered(bool flag)
550 {
551     if (flag == hovered())
552         return;
553
554     if (Document* document = this->document())
555         document->userActionElements().setHovered(this, flag);
556
557     if (!renderer()) {
558         // When setting hover to false, the style needs to be recalc'd even when
559         // there's no renderer (imagine setting display:none in the :hover class,
560         // if a nil renderer would prevent this element from recalculating its
561         // style, it would never go back to its normal style and remain
562         // stuck in its hovered style).
563         if (!flag)
564             setNeedsStyleRecalc();
565
566         return;
567     }
568
569     if (renderer()->style()->affectedByHover() || childrenAffectedByHover())
570         setNeedsStyleRecalc();
571
572     if (renderer()->style()->hasAppearance())
573         renderer()->theme()->stateChanged(renderer(), HoverState);
574 }
575
576 void Element::scrollIntoView(bool alignToTop) 
577 {
578     document()->updateLayoutIgnorePendingStylesheets();
579
580     if (!renderer())
581         return;
582
583     LayoutRect bounds = boundingBox();
584     // Align to the top / bottom and to the closest edge.
585     if (alignToTop)
586         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
587     else
588         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignBottomAlways);
589 }
590
591 void Element::scrollIntoViewIfNeeded(bool centerIfNeeded)
592 {
593     document()->updateLayoutIgnorePendingStylesheets();
594
595     if (!renderer())
596         return;
597
598     LayoutRect bounds = boundingBox();
599     if (centerIfNeeded)
600         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignCenterIfNeeded, ScrollAlignment::alignCenterIfNeeded);
601     else
602         renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
603 }
604
605 void Element::scrollByUnits(int units, ScrollGranularity granularity)
606 {
607     document()->updateLayoutIgnorePendingStylesheets();
608
609     if (!renderer())
610         return;
611
612     if (!renderer()->hasOverflowClip())
613         return;
614
615     ScrollDirection direction = ScrollDown;
616     if (units < 0) {
617         direction = ScrollUp;
618         units = -units;
619     }
620     Node* stopNode = this;
621     toRenderBox(renderer())->scroll(direction, granularity, units, &stopNode);
622 }
623
624 void Element::scrollByLines(int lines)
625 {
626     scrollByUnits(lines, ScrollByLine);
627 }
628
629 void Element::scrollByPages(int pages)
630 {
631     scrollByUnits(pages, ScrollByPage);
632 }
633
634 static float localZoomForRenderer(RenderObject* renderer)
635 {
636     // FIXME: This does the wrong thing if two opposing zooms are in effect and canceled each
637     // other out, but the alternative is that we'd have to crawl up the whole render tree every
638     // time (or store an additional bit in the RenderStyle to indicate that a zoom was specified).
639     float zoomFactor = 1;
640     if (renderer->style()->effectiveZoom() != 1) {
641         // Need to find the nearest enclosing RenderObject that set up
642         // a differing zoom, and then we divide our result by it to eliminate the zoom.
643         RenderObject* prev = renderer;
644         for (RenderObject* curr = prev->parent(); curr; curr = curr->parent()) {
645             if (curr->style()->effectiveZoom() != prev->style()->effectiveZoom()) {
646                 zoomFactor = prev->style()->zoom();
647                 break;
648             }
649             prev = curr;
650         }
651         if (prev->isRenderView())
652             zoomFactor = prev->style()->zoom();
653     }
654     return zoomFactor;
655 }
656
657 static int adjustForLocalZoom(LayoutUnit value, RenderObject* renderer)
658 {
659     float zoomFactor = localZoomForRenderer(renderer);
660     if (zoomFactor == 1)
661         return value;
662 #if ENABLE(SUBPIXEL_LAYOUT)
663     return lroundf(value / zoomFactor);
664 #else
665     // Needed because computeLengthInt truncates (rather than rounds) when scaling up.
666     if (zoomFactor > 1)
667         value++;
668     return static_cast<int>(value / zoomFactor);
669 #endif
670 }
671
672 int Element::offsetLeft()
673 {
674     document()->updateLayoutIgnorePendingStylesheets();
675     if (RenderBoxModelObject* renderer = renderBoxModelObject())
676         return adjustForLocalZoom(renderer->pixelSnappedOffsetLeft(), renderer);
677     return 0;
678 }
679
680 int Element::offsetTop()
681 {
682     document()->updateLayoutIgnorePendingStylesheets();
683     if (RenderBoxModelObject* renderer = renderBoxModelObject())
684         return adjustForLocalZoom(renderer->pixelSnappedOffsetTop(), renderer);
685     return 0;
686 }
687
688 int Element::offsetWidth()
689 {
690     document()->updateLayoutIgnorePendingStylesheets();
691     if (RenderBoxModelObject* renderer = renderBoxModelObject())
692 #if ENABLE(SUBPIXEL_LAYOUT)
693         return adjustLayoutUnitForAbsoluteZoom(renderer->pixelSnappedOffsetWidth(), renderer).round();
694 #else
695         return adjustForAbsoluteZoom(renderer->pixelSnappedOffsetWidth(), renderer);
696 #endif
697     return 0;
698 }
699
700 int Element::offsetHeight()
701 {
702     document()->updateLayoutIgnorePendingStylesheets();
703     if (RenderBoxModelObject* renderer = renderBoxModelObject())
704 #if ENABLE(SUBPIXEL_LAYOUT)
705         return adjustLayoutUnitForAbsoluteZoom(renderer->pixelSnappedOffsetHeight(), renderer).round();
706 #else
707         return adjustForAbsoluteZoom(renderer->pixelSnappedOffsetHeight(), renderer);
708 #endif
709     return 0;
710 }
711
712 Element* Element::bindingsOffsetParent()
713 {
714     Element* element = offsetParent();
715     if (!element || !element->isInShadowTree())
716         return element;
717     return element->containingShadowRoot()->type() == ShadowRoot::UserAgentShadowRoot ? 0 : element;
718 }
719
720 Element* Element::offsetParent()
721 {
722     document()->updateLayoutIgnorePendingStylesheets();
723     if (RenderObject* renderer = this->renderer()) {
724         if (RenderObject* offsetParent = renderer->offsetParent())
725             return toElement(offsetParent->node());
726     }
727     return 0;
728 }
729
730 int Element::clientLeft()
731 {
732     document()->updateLayoutIgnorePendingStylesheets();
733
734     if (RenderBox* renderer = renderBox())
735         return adjustForAbsoluteZoom(roundToInt(renderer->clientLeft()), renderer);
736     return 0;
737 }
738
739 int Element::clientTop()
740 {
741     document()->updateLayoutIgnorePendingStylesheets();
742
743     if (RenderBox* renderer = renderBox())
744         return adjustForAbsoluteZoom(roundToInt(renderer->clientTop()), renderer);
745     return 0;
746 }
747
748 int Element::clientWidth()
749 {
750     document()->updateLayoutIgnorePendingStylesheets();
751
752     // When in strict mode, clientWidth for the document element should return the width of the containing frame.
753     // When in quirks mode, clientWidth for the body element should return the width of the containing frame.
754     bool inQuirksMode = document()->inQuirksMode();
755     if ((!inQuirksMode && document()->documentElement() == this) ||
756         (inQuirksMode && isHTMLElement() && document()->body() == this)) {
757         if (FrameView* view = document()->view()) {
758             if (RenderView* renderView = document()->renderView())
759                 return adjustForAbsoluteZoom(view->layoutWidth(), renderView);
760         }
761     }
762     
763     if (RenderBox* renderer = renderBox())
764 #if ENABLE(SUBPIXEL_LAYOUT)
765         return adjustLayoutUnitForAbsoluteZoom(renderer->pixelSnappedClientWidth(), renderer).round();
766 #else
767         return adjustForAbsoluteZoom(renderer->pixelSnappedClientWidth(), renderer);
768 #endif
769     return 0;
770 }
771
772 int Element::clientHeight()
773 {
774     document()->updateLayoutIgnorePendingStylesheets();
775
776     // When in strict mode, clientHeight for the document element should return the height of the containing frame.
777     // When in quirks mode, clientHeight for the body element should return the height of the containing frame.
778     bool inQuirksMode = document()->inQuirksMode();     
779
780     if ((!inQuirksMode && document()->documentElement() == this) ||
781         (inQuirksMode && isHTMLElement() && document()->body() == this)) {
782         if (FrameView* view = document()->view()) {
783             if (RenderView* renderView = document()->renderView())
784                 return adjustForAbsoluteZoom(view->layoutHeight(), renderView);
785         }
786     }
787     
788     if (RenderBox* renderer = renderBox())
789 #if ENABLE(SUBPIXEL_LAYOUT)
790         return adjustLayoutUnitForAbsoluteZoom(renderer->pixelSnappedClientHeight(), renderer).round();
791 #else
792         return adjustForAbsoluteZoom(renderer->pixelSnappedClientHeight(), renderer);
793 #endif
794     return 0;
795 }
796
797 int Element::scrollLeft()
798 {
799     document()->updateLayoutIgnorePendingStylesheets();
800     if (RenderBox* rend = renderBox())
801         return adjustForAbsoluteZoom(rend->scrollLeft(), rend);
802     return 0;
803 }
804
805 int Element::scrollTop()
806 {
807     document()->updateLayoutIgnorePendingStylesheets();
808     if (RenderBox* rend = renderBox())
809         return adjustForAbsoluteZoom(rend->scrollTop(), rend);
810     return 0;
811 }
812
813 void Element::setScrollLeft(int newLeft)
814 {
815     document()->updateLayoutIgnorePendingStylesheets();
816     if (RenderBox* rend = renderBox())
817         rend->setScrollLeft(static_cast<int>(newLeft * rend->style()->effectiveZoom()));
818 }
819
820 void Element::setScrollTop(int newTop)
821 {
822     document()->updateLayoutIgnorePendingStylesheets();
823     if (RenderBox* rend = renderBox())
824         rend->setScrollTop(static_cast<int>(newTop * rend->style()->effectiveZoom()));
825 }
826
827 int Element::scrollWidth()
828 {
829     document()->updateLayoutIgnorePendingStylesheets();
830     if (RenderBox* rend = renderBox())
831         return adjustForAbsoluteZoom(rend->scrollWidth(), rend);
832     return 0;
833 }
834
835 int Element::scrollHeight()
836 {
837     document()->updateLayoutIgnorePendingStylesheets();
838     if (RenderBox* rend = renderBox())
839         return adjustForAbsoluteZoom(rend->scrollHeight(), rend);
840     return 0;
841 }
842
843 IntRect Element::boundsInRootViewSpace()
844 {
845     document()->updateLayoutIgnorePendingStylesheets();
846
847     FrameView* view = document()->view();
848     if (!view)
849         return IntRect();
850
851     Vector<FloatQuad> quads;
852 #if ENABLE(SVG)
853     if (isSVGElement() && renderer()) {
854         // Get the bounding rectangle from the SVG model.
855         SVGElement* svgElement = toSVGElement(this);
856         FloatRect localRect;
857         if (svgElement->getBoundingBox(localRect))
858             quads.append(renderer()->localToAbsoluteQuad(localRect));
859     } else
860 #endif
861     {
862         // Get the bounding rectangle from the box model.
863         if (renderBoxModelObject())
864             renderBoxModelObject()->absoluteQuads(quads);
865     }
866
867     if (quads.isEmpty())
868         return IntRect();
869
870     IntRect result = quads[0].enclosingBoundingBox();
871     for (size_t i = 1; i < quads.size(); ++i)
872         result.unite(quads[i].enclosingBoundingBox());
873
874     result = view->contentsToRootView(result);
875     return result;
876 }
877
878 PassRefPtr<ClientRectList> Element::getClientRects()
879 {
880     document()->updateLayoutIgnorePendingStylesheets();
881
882     RenderBoxModelObject* renderBoxModelObject = this->renderBoxModelObject();
883     if (!renderBoxModelObject)
884         return ClientRectList::create();
885
886     // FIXME: Handle SVG elements.
887     // FIXME: Handle table/inline-table with a caption.
888
889     Vector<FloatQuad> quads;
890     renderBoxModelObject->absoluteQuads(quads);
891     document()->adjustFloatQuadsForScrollAndAbsoluteZoomAndFrameScale(quads, renderBoxModelObject);
892     return ClientRectList::create(quads);
893 }
894
895 PassRefPtr<ClientRect> Element::getBoundingClientRect()
896 {
897     document()->updateLayoutIgnorePendingStylesheets();
898
899     Vector<FloatQuad> quads;
900 #if ENABLE(SVG)
901     if (isSVGElement() && renderer() && !renderer()->isSVGRoot()) {
902         // Get the bounding rectangle from the SVG model.
903         SVGElement* svgElement = toSVGElement(this);
904         FloatRect localRect;
905         if (svgElement->getBoundingBox(localRect))
906             quads.append(renderer()->localToAbsoluteQuad(localRect));
907     } else
908 #endif
909     {
910         // Get the bounding rectangle from the box model.
911         if (renderBoxModelObject())
912             renderBoxModelObject()->absoluteQuads(quads);
913     }
914
915     if (quads.isEmpty())
916         return ClientRect::create();
917
918     FloatRect result = quads[0].boundingBox();
919     for (size_t i = 1; i < quads.size(); ++i)
920         result.unite(quads[i].boundingBox());
921
922     document()->adjustFloatRectForScrollAndAbsoluteZoomAndFrameScale(result, renderer());
923     return ClientRect::create(result);
924 }
925     
926 IntRect Element::screenRect() const
927 {
928     if (!renderer())
929         return IntRect();
930     // FIXME: this should probably respect transforms
931     return document()->view()->contentsToScreen(renderer()->absoluteBoundingBoxRectIgnoringTransforms());
932 }
933
934 const AtomicString& Element::getAttribute(const AtomicString& localName) const
935 {
936     if (!elementData())
937         return nullAtom;
938     synchronizeAttribute(localName);
939     if (const Attribute* attribute = elementData()->getAttributeItem(localName, shouldIgnoreAttributeCase(this)))
940         return attribute->value();
941     return nullAtom;
942 }
943
944 const AtomicString& Element::getAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const
945 {
946     return getAttribute(QualifiedName(nullAtom, localName, namespaceURI));
947 }
948
949 void Element::setAttribute(const AtomicString& localName, const AtomicString& value, ExceptionCode& ec)
950 {
951     if (!Document::isValidName(localName)) {
952         ec = INVALID_CHARACTER_ERR;
953         return;
954     }
955
956     synchronizeAttribute(localName);
957     const AtomicString& caseAdjustedLocalName = shouldIgnoreAttributeCase(this) ? localName.lower() : localName;
958
959     unsigned index = elementData() ? elementData()->getAttributeItemIndex(caseAdjustedLocalName, false) : ElementData::attributeNotFound;
960     const QualifiedName& qName = index != ElementData::attributeNotFound ? attributeItem(index)->name() : QualifiedName(nullAtom, caseAdjustedLocalName, nullAtom);
961     setAttributeInternal(index, qName, value, NotInSynchronizationOfLazyAttribute);
962 }
963
964 void Element::setAttribute(const QualifiedName& name, const AtomicString& value)
965 {
966     synchronizeAttribute(name);
967     unsigned index = elementData() ? elementData()->getAttributeItemIndex(name) : ElementData::attributeNotFound;
968     setAttributeInternal(index, name, value, NotInSynchronizationOfLazyAttribute);
969 }
970
971 void Element::setSynchronizedLazyAttribute(const QualifiedName& name, const AtomicString& value)
972 {
973     unsigned index = elementData() ? elementData()->getAttributeItemIndex(name) : ElementData::attributeNotFound;
974     setAttributeInternal(index, name, value, InSynchronizationOfLazyAttribute);
975 }
976
977 inline void Element::setAttributeInternal(unsigned index, const QualifiedName& name, const AtomicString& newValue, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
978 {
979     if (newValue.isNull()) {
980         if (index != ElementData::attributeNotFound)
981             removeAttributeInternal(index, inSynchronizationOfLazyAttribute);
982         return;
983     }
984
985     if (index == ElementData::attributeNotFound) {
986         addAttributeInternal(name, newValue, inSynchronizationOfLazyAttribute);
987         return;
988     }
989
990     if (!inSynchronizationOfLazyAttribute)
991         willModifyAttribute(name, attributeItem(index)->value(), newValue);
992
993     if (newValue != attributeItem(index)->value()) {
994         // If there is an Attr node hooked to this attribute, the Attr::setValue() call below
995         // will write into the ElementData.
996         // FIXME: Refactor this so it makes some sense.
997         if (RefPtr<Attr> attrNode = inSynchronizationOfLazyAttribute ? 0 : attrIfExists(name))
998             attrNode->setValue(newValue);
999         else
1000             ensureUniqueElementData()->attributeItem(index)->setValue(newValue);
1001     }
1002
1003     if (!inSynchronizationOfLazyAttribute)
1004         didModifyAttribute(name, newValue);
1005 }
1006
1007 static inline AtomicString makeIdForStyleResolution(const AtomicString& value, bool inQuirksMode)
1008 {
1009     if (inQuirksMode)
1010         return value.lower();
1011     return value;
1012 }
1013
1014 static bool checkNeedsStyleInvalidationForIdChange(const AtomicString& oldId, const AtomicString& newId, StyleResolver* styleResolver)
1015 {
1016     ASSERT(newId != oldId);
1017     if (!oldId.isEmpty() && styleResolver->hasSelectorForId(oldId))
1018         return true;
1019     if (!newId.isEmpty() && styleResolver->hasSelectorForId(newId))
1020         return true;
1021     return false;
1022 }
1023
1024 void Element::attributeChanged(const QualifiedName& name, const AtomicString& newValue, AttributeModificationReason)
1025 {
1026     parseAttribute(name, newValue);
1027
1028     document()->incDOMTreeVersion();
1029
1030     StyleResolver* styleResolver = document()->styleResolverIfExists();
1031     bool testShouldInvalidateStyle = attached() && styleResolver && styleChangeType() < FullStyleChange;
1032     bool shouldInvalidateStyle = false;
1033
1034     if (isIdAttributeName(name)) {
1035         AtomicString oldId = elementData()->idForStyleResolution();
1036         AtomicString newId = makeIdForStyleResolution(newValue, document()->inQuirksMode());
1037         if (newId != oldId) {
1038             elementData()->setIdForStyleResolution(newId);
1039             shouldInvalidateStyle = testShouldInvalidateStyle && checkNeedsStyleInvalidationForIdChange(oldId, newId, styleResolver);
1040         }
1041     } else if (name == classAttr)
1042         classAttributeChanged(newValue);
1043     else if (name == HTMLNames::nameAttr)
1044         elementData()->m_hasNameAttribute = !newValue.isNull();
1045     else if (name == HTMLNames::pseudoAttr)
1046         shouldInvalidateStyle |= testShouldInvalidateStyle && isInShadowTree();
1047
1048
1049     invalidateNodeListCachesInAncestors(&name, this);
1050
1051     // If there is currently no StyleResolver, we can't be sure that this attribute change won't affect style.
1052     shouldInvalidateStyle |= !styleResolver;
1053
1054     if (shouldInvalidateStyle)
1055         setNeedsStyleRecalc();
1056
1057     if (AXObjectCache* cache = document()->existingAXObjectCache())
1058         cache->handleAttributeChanged(name, this);
1059 }
1060
1061 inline void Element::attributeChangedFromParserOrByCloning(const QualifiedName& name, const AtomicString& newValue, AttributeModificationReason reason)
1062 {
1063 #if ENABLE(CUSTOM_ELEMENTS)
1064     if (name == isAttr) {
1065         if (CustomElementRegistry* registry = document()->registry())
1066             registry->didGiveTypeExtension(this);
1067     }
1068 #endif
1069     attributeChanged(name, newValue, reason);
1070 }
1071
1072 template <typename CharacterType>
1073 static inline bool classStringHasClassName(const CharacterType* characters, unsigned length)
1074 {
1075     ASSERT(length > 0);
1076
1077     unsigned i = 0;
1078     do {
1079         if (isNotHTMLSpace(characters[i]))
1080             break;
1081         ++i;
1082     } while (i < length);
1083
1084     return i < length;
1085 }
1086
1087 static inline bool classStringHasClassName(const AtomicString& newClassString)
1088 {
1089     unsigned length = newClassString.length();
1090
1091     if (!length)
1092         return false;
1093
1094     if (newClassString.is8Bit())
1095         return classStringHasClassName(newClassString.characters8(), length);
1096     return classStringHasClassName(newClassString.characters16(), length);
1097 }
1098
1099 template<typename Checker>
1100 static bool checkSelectorForClassChange(const SpaceSplitString& changedClasses, const Checker& checker)
1101 {
1102     unsigned changedSize = changedClasses.size();
1103     for (unsigned i = 0; i < changedSize; ++i) {
1104         if (checker.hasSelectorForClass(changedClasses[i]))
1105             return true;
1106     }
1107     return false;
1108 }
1109
1110 template<typename Checker>
1111 static bool checkSelectorForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, const Checker& checker)
1112 {
1113     unsigned oldSize = oldClasses.size();
1114     if (!oldSize)
1115         return checkSelectorForClassChange(newClasses, checker);
1116     BitVector remainingClassBits;
1117     remainingClassBits.ensureSize(oldSize);
1118     // Class vectors tend to be very short. This is faster than using a hash table.
1119     unsigned newSize = newClasses.size();
1120     for (unsigned i = 0; i < newSize; ++i) {
1121         for (unsigned j = 0; j < oldSize; ++j) {
1122             if (newClasses[i] == oldClasses[j]) {
1123                 remainingClassBits.quickSet(j);
1124                 continue;
1125             }
1126         }
1127         if (checker.hasSelectorForClass(newClasses[i]))
1128             return true;
1129     }
1130     for (unsigned i = 0; i < oldSize; ++i) {
1131         // If the bit is not set the the corresponding class has been removed.
1132         if (remainingClassBits.quickGet(i))
1133             continue;
1134         if (checker.hasSelectorForClass(oldClasses[i]))
1135             return true;
1136     }
1137     return false;
1138 }
1139
1140 void Element::classAttributeChanged(const AtomicString& newClassString)
1141 {
1142     StyleResolver* styleResolver = document()->styleResolverIfExists();
1143     bool testShouldInvalidateStyle = attached() && styleResolver && styleChangeType() < FullStyleChange;
1144     bool shouldInvalidateStyle = false;
1145
1146     if (classStringHasClassName(newClassString)) {
1147         const bool shouldFoldCase = document()->inQuirksMode();
1148         const SpaceSplitString oldClasses = elementData()->classNames();
1149         elementData()->setClass(newClassString, shouldFoldCase);
1150         const SpaceSplitString& newClasses = elementData()->classNames();
1151         shouldInvalidateStyle = testShouldInvalidateStyle && checkSelectorForClassChange(oldClasses, newClasses, *styleResolver);
1152     } else {
1153         const SpaceSplitString& oldClasses = elementData()->classNames();
1154         shouldInvalidateStyle = testShouldInvalidateStyle && checkSelectorForClassChange(oldClasses, *styleResolver);
1155         elementData()->clearClass();
1156     }
1157
1158     if (hasRareData())
1159         elementRareData()->clearClassListValueForQuirksMode();
1160
1161     if (shouldInvalidateStyle)
1162         setNeedsStyleRecalc();
1163 }
1164
1165 // Returns true is the given attribute is an event handler.
1166 // We consider an event handler any attribute that begins with "on".
1167 // It is a simple solution that has the advantage of not requiring any
1168 // code or configuration change if a new event handler is defined.
1169
1170 static inline bool isEventHandlerAttribute(const Attribute& attribute)
1171 {
1172     return attribute.name().namespaceURI().isNull() && attribute.name().localName().startsWith("on");
1173 }
1174
1175 bool Element::isJavaScriptURLAttribute(const Attribute& attribute) const
1176 {
1177     return isURLAttribute(attribute) && protocolIsJavaScript(stripLeadingAndTrailingHTMLSpaces(attribute.value()));
1178 }
1179
1180 void Element::stripScriptingAttributes(Vector<Attribute>& attributeVector) const
1181 {
1182     size_t destination = 0;
1183     for (size_t source = 0; source < attributeVector.size(); ++source) {
1184         if (isEventHandlerAttribute(attributeVector[source])
1185             || isJavaScriptURLAttribute(attributeVector[source])
1186             || isHTMLContentAttribute(attributeVector[source]))
1187             continue;
1188
1189         if (source != destination)
1190             attributeVector[destination] = attributeVector[source];
1191
1192         ++destination;
1193     }
1194     attributeVector.shrink(destination);
1195 }
1196
1197 void Element::parserSetAttributes(const Vector<Attribute>& attributeVector)
1198 {
1199     ASSERT(!inDocument());
1200     ASSERT(!parentNode());
1201     ASSERT(!m_elementData);
1202
1203     if (attributeVector.isEmpty())
1204         return;
1205
1206     if (document() && document()->sharedObjectPool())
1207         m_elementData = document()->sharedObjectPool()->cachedShareableElementDataWithAttributes(attributeVector);
1208     else
1209         m_elementData = ShareableElementData::createWithAttributes(attributeVector);
1210
1211     // Use attributeVector instead of m_elementData because attributeChanged might modify m_elementData.
1212     for (unsigned i = 0; i < attributeVector.size(); ++i)
1213         attributeChangedFromParserOrByCloning(attributeVector[i].name(), attributeVector[i].value(), ModifiedDirectly);
1214 }
1215
1216 bool Element::hasAttributes() const
1217 {
1218     synchronizeAllAttributes();
1219     return elementData() && elementData()->length();
1220 }
1221
1222 bool Element::hasEquivalentAttributes(const Element* other) const
1223 {
1224     synchronizeAllAttributes();
1225     other->synchronizeAllAttributes();
1226     if (elementData() == other->elementData())
1227         return true;
1228     if (elementData())
1229         return elementData()->isEquivalent(other->elementData());
1230     if (other->elementData())
1231         return other->elementData()->isEquivalent(elementData());
1232     return true;
1233 }
1234
1235 String Element::nodeName() const
1236 {
1237     return m_tagName.toString();
1238 }
1239
1240 String Element::nodeNamePreservingCase() const
1241 {
1242     return m_tagName.toString();
1243 }
1244
1245 void Element::setPrefix(const AtomicString& prefix, ExceptionCode& ec)
1246 {
1247     ec = 0;
1248     checkSetPrefix(prefix, ec);
1249     if (ec)
1250         return;
1251
1252     m_tagName.setPrefix(prefix.isEmpty() ? AtomicString() : prefix);
1253 }
1254
1255 KURL Element::baseURI() const
1256 {
1257     const AtomicString& baseAttribute = getAttribute(baseAttr);
1258     KURL base(KURL(), baseAttribute);
1259     if (!base.protocol().isEmpty())
1260         return base;
1261
1262     ContainerNode* parent = parentNode();
1263     if (!parent)
1264         return base;
1265
1266     const KURL& parentBase = parent->baseURI();
1267     if (parentBase.isNull())
1268         return base;
1269
1270     return KURL(parentBase, baseAttribute);
1271 }
1272
1273 const AtomicString& Element::imageSourceURL() const
1274 {
1275     return getAttribute(srcAttr);
1276 }
1277
1278 bool Element::rendererIsNeeded(const NodeRenderingContext& context)
1279 {
1280     return context.style()->display() != NONE;
1281 }
1282
1283 RenderObject* Element::createRenderer(RenderArena*, RenderStyle* style)
1284 {
1285     return RenderObject::createObject(this, style);
1286 }
1287
1288 bool Element::isDisabledFormControl() const
1289 {
1290 #if ENABLE(DIALOG_ELEMENT)
1291     // FIXME: disabled and inert are separate concepts in the spec, but now we treat them as the same.
1292     // For example, an inert, non-disabled form control should not be grayed out.
1293     if (isInert())
1294         return true;
1295 #endif
1296     return false;
1297 }
1298
1299 #if ENABLE(DIALOG_ELEMENT)
1300 bool Element::isInert() const
1301 {
1302     Element* dialog = document()->activeModalDialog();
1303     return dialog && !containsIncludingShadowDOM(dialog) && !dialog->containsIncludingShadowDOM(this);
1304 }
1305 #endif
1306
1307 Node::InsertionNotificationRequest Element::insertedInto(ContainerNode* insertionPoint)
1308 {
1309     bool wasInDocument = inDocument();
1310     // need to do superclass processing first so inDocument() is true
1311     // by the time we reach updateId
1312     ContainerNode::insertedInto(insertionPoint);
1313     ASSERT(!wasInDocument || inDocument());
1314
1315 #if ENABLE(FULLSCREEN_API)
1316     if (containsFullScreenElement() && parentElement() && !parentElement()->containsFullScreenElement())
1317         setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(true);
1318 #endif
1319
1320     if (Element* before = pseudoElement(BEFORE))
1321         before->insertedInto(insertionPoint);
1322
1323     if (Element* after = pseudoElement(AFTER))
1324         after->insertedInto(insertionPoint);
1325
1326     if (!insertionPoint->isInTreeScope())
1327         return InsertionDone;
1328
1329     if (hasRareData())
1330         elementRareData()->clearClassListValueForQuirksMode();
1331
1332     TreeScope* newScope = insertionPoint->treeScope();
1333     HTMLDocument* newDocument = !wasInDocument && inDocument() && newScope->documentScope()->isHTMLDocument() ? toHTMLDocument(newScope->documentScope()) : 0;
1334     if (newScope != treeScope())
1335         newScope = 0;
1336
1337     const AtomicString& idValue = getIdAttribute();
1338     if (!idValue.isNull()) {
1339         if (newScope)
1340             updateIdForTreeScope(newScope, nullAtom, idValue);
1341         if (newDocument)
1342             updateIdForDocument(newDocument, nullAtom, idValue, AlwaysUpdateHTMLDocumentNamedItemMaps);
1343     }
1344
1345     const AtomicString& nameValue = getNameAttribute();
1346     if (!nameValue.isNull()) {
1347         if (newScope)
1348             updateNameForTreeScope(newScope, nullAtom, nameValue);
1349         if (newDocument)
1350             updateNameForDocument(newDocument, nullAtom, nameValue);
1351     }
1352
1353     if (newScope && hasTagName(labelTag)) {
1354         if (newScope->shouldCacheLabelsByForAttribute())
1355             updateLabel(newScope, nullAtom, fastGetAttribute(forAttr));
1356     }
1357
1358     return InsertionDone;
1359 }
1360
1361 void Element::removedFrom(ContainerNode* insertionPoint)
1362 {
1363 #if ENABLE(SVG)
1364     bool wasInDocument = insertionPoint->document();
1365 #endif
1366
1367     if (Element* before = pseudoElement(BEFORE))
1368         before->removedFrom(insertionPoint);
1369
1370     if (Element* after = pseudoElement(AFTER))
1371         after->removedFrom(insertionPoint);
1372
1373 #if ENABLE(DIALOG_ELEMENT)
1374     document()->removeFromTopLayer(this);
1375 #endif
1376 #if ENABLE(FULLSCREEN_API)
1377     if (containsFullScreenElement())
1378         setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false);
1379 #endif
1380 #if ENABLE(POINTER_LOCK)
1381     if (document()->page())
1382         document()->page()->pointerLockController()->elementRemoved(this);
1383 #endif
1384
1385     setSavedLayerScrollOffset(IntSize());
1386
1387     if (insertionPoint->isInTreeScope()) {
1388         TreeScope* oldScope = insertionPoint->treeScope();
1389         HTMLDocument* oldDocument = inDocument() && oldScope->documentScope()->isHTMLDocument() ? toHTMLDocument(oldScope->documentScope()) : 0;
1390         if (oldScope != treeScope())
1391             oldScope = 0;
1392
1393         const AtomicString& idValue = getIdAttribute();
1394         if (!idValue.isNull()) {
1395             if (oldScope)
1396                 updateIdForTreeScope(oldScope, idValue, nullAtom);
1397             if (oldDocument)
1398                 updateIdForDocument(oldDocument, idValue, nullAtom, AlwaysUpdateHTMLDocumentNamedItemMaps);
1399         }
1400
1401         const AtomicString& nameValue = getNameAttribute();
1402         if (!nameValue.isNull()) {
1403             if (oldScope)
1404                 updateNameForTreeScope(oldScope, nameValue, nullAtom);
1405             if (oldDocument)
1406                 updateNameForDocument(oldDocument, nameValue, nullAtom);
1407         }
1408
1409         if (oldScope && hasTagName(labelTag)) {
1410             if (oldScope->shouldCacheLabelsByForAttribute())
1411                 updateLabel(oldScope, fastGetAttribute(forAttr), nullAtom);
1412         }
1413     }
1414
1415     ContainerNode::removedFrom(insertionPoint);
1416 #if ENABLE(SVG)
1417     if (wasInDocument && hasPendingResources())
1418         document()->accessSVGExtensions()->removeElementFromPendingResources(this);
1419 #endif
1420 }
1421
1422 void Element::createRendererIfNeeded(const AttachContext& context)
1423 {
1424     NodeRenderingContext(this, context).createRendererForElementIfNeeded();
1425 }
1426
1427 void Element::attach(const AttachContext& context)
1428 {
1429     PostAttachCallbackDisabler callbackDisabler(this);
1430     StyleResolverParentPusher parentPusher(this);
1431     WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
1432
1433     createRendererIfNeeded(context);
1434
1435     if (parentElement() && parentElement()->isInCanvasSubtree())
1436         setIsInCanvasSubtree(true);
1437
1438     updatePseudoElement(BEFORE);
1439
1440     // When a shadow root exists, it does the work of attaching the children.
1441     if (ElementShadow* shadow = this->shadow()) {
1442         parentPusher.push();
1443         shadow->attach(context);
1444     } else if (firstChild())
1445         parentPusher.push();
1446
1447     ContainerNode::attach(context);
1448
1449     updatePseudoElement(AFTER);
1450
1451     if (hasRareData()) {   
1452         ElementRareData* data = elementRareData();
1453         if (data->needsFocusAppearanceUpdateSoonAfterAttach()) {
1454             if (isFocusable() && document()->focusedElement() == this)
1455                 document()->updateFocusAppearanceSoon(false /* don't restore selection */);
1456             data->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
1457         }
1458     }
1459 }
1460
1461 void Element::unregisterNamedFlowContentNode()
1462 {
1463     if (document()->cssRegionsEnabled() && inNamedFlow() && document()->renderView())
1464         document()->renderView()->flowThreadController()->unregisterNamedFlowContentNode(this);
1465 }
1466
1467 void Element::detach(const AttachContext& context)
1468 {
1469     WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
1470     unregisterNamedFlowContentNode();
1471     cancelFocusAppearanceUpdate();
1472     if (hasRareData()) {
1473         ElementRareData* data = elementRareData();
1474         data->setPseudoElement(BEFORE, 0);
1475         data->setPseudoElement(AFTER, 0);
1476         data->setIsInCanvasSubtree(false);
1477         data->resetComputedStyle();
1478         data->resetDynamicRestyleObservations();
1479     }
1480
1481     if (ElementShadow* shadow = this->shadow()) {
1482         detachChildrenIfNeeded(context);
1483         shadow->detach(context);
1484     }
1485
1486     // Do not remove the element's hovered and active status
1487     // if performing a reattach.
1488     if (!context.performingReattach) {
1489         if (isUserActionElement()) {
1490             if (hovered())
1491                 document()->hoveredElementDidDetach(this);
1492             if (inActiveChain())
1493                 document()->elementInActiveChainDidDetach(this);
1494             document()->userActionElements().didDetach(this);
1495         }
1496     }
1497
1498     ContainerNode::detach(context);
1499 }
1500
1501 bool Element::pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderStyle* newStyle)
1502 {
1503     ASSERT(currentStyle == renderStyle());
1504     ASSERT(renderer());
1505
1506     if (!currentStyle)
1507         return false;
1508
1509     const PseudoStyleCache* pseudoStyleCache = currentStyle->cachedPseudoStyles();
1510     if (!pseudoStyleCache)
1511         return false;
1512
1513     size_t cacheSize = pseudoStyleCache->size();
1514     for (size_t i = 0; i < cacheSize; ++i) {
1515         RefPtr<RenderStyle> newPseudoStyle;
1516         PseudoId pseudoId = pseudoStyleCache->at(i)->styleType();
1517         if (pseudoId == FIRST_LINE || pseudoId == FIRST_LINE_INHERITED)
1518             newPseudoStyle = renderer()->uncachedFirstLineStyle(newStyle);
1519         else
1520             newPseudoStyle = renderer()->getUncachedPseudoStyle(PseudoStyleRequest(pseudoId), newStyle, newStyle);
1521         if (!newPseudoStyle)
1522             return true;
1523         if (*newPseudoStyle != *pseudoStyleCache->at(i)) {
1524             if (pseudoId < FIRST_INTERNAL_PSEUDOID)
1525                 newStyle->setHasPseudoStyle(pseudoId);
1526             newStyle->addCachedPseudoStyle(newPseudoStyle);
1527             if (pseudoId == FIRST_LINE || pseudoId == FIRST_LINE_INHERITED) {
1528                 // FIXME: We should do an actual diff to determine whether a repaint vs. layout
1529                 // is needed, but for now just assume a layout will be required.  The diff code
1530                 // in RenderObject::setStyle would need to be factored out so that it could be reused.
1531                 renderer()->setNeedsLayoutAndPrefWidthsRecalc();
1532             }
1533             return true;
1534         }
1535     }
1536     return false;
1537 }
1538
1539 PassRefPtr<RenderStyle> Element::styleForRenderer()
1540 {
1541     if (hasCustomStyleCallbacks()) {
1542         if (RefPtr<RenderStyle> style = customStyleForRenderer())
1543             return style.release();
1544     }
1545
1546     return document()->ensureStyleResolver()->styleForElement(this);
1547 }
1548
1549 void Element::recalcStyle(StyleChange change)
1550 {
1551     if (hasCustomStyleCallbacks()) {
1552         if (!willRecalcStyle(change))
1553             return;
1554     }
1555
1556     // Ref currentStyle in case it would otherwise be deleted when setting the new style in the renderer.
1557     RefPtr<RenderStyle> currentStyle(renderStyle());
1558     bool hasParentStyle = parentNodeForRenderingAndStyle() ? static_cast<bool>(parentNodeForRenderingAndStyle()->renderStyle()) : false;
1559     bool hasDirectAdjacentRules = childrenAffectedByDirectAdjacentRules();
1560     bool hasIndirectAdjacentRules = childrenAffectedByForwardPositionalRules();
1561
1562     if ((change > NoChange || needsStyleRecalc())) {
1563         if (hasRareData())
1564             elementRareData()->resetComputedStyle();
1565     }
1566     if (hasParentStyle && (change >= Inherit || needsStyleRecalc())) {
1567         StyleChange localChange = Detach;
1568         RefPtr<RenderStyle> newStyle;
1569         if (currentStyle) {
1570             newStyle = styleForRenderer();
1571             localChange = Node::diff(currentStyle.get(), newStyle.get(), document());
1572         }
1573         if (localChange == Detach) {
1574             AttachContext reattachContext;
1575             reattachContext.resolvedStyle = newStyle.get();
1576             reattach(reattachContext);
1577
1578             // attach recalculates the style for all children. No need to do it twice.
1579             clearNeedsStyleRecalc();
1580             clearChildNeedsStyleRecalc();
1581
1582             if (hasCustomStyleCallbacks())
1583                 didRecalcStyle(change);
1584             return;
1585         }
1586
1587         if (RenderObject* renderer = this->renderer()) {
1588             if (localChange != NoChange || pseudoStyleCacheIsInvalid(currentStyle.get(), newStyle.get()) || (change == Force && renderer->requiresForcedStyleRecalcPropagation()) || styleChangeType() == SyntheticStyleChange)
1589                 renderer->setAnimatableStyle(newStyle.get());
1590             else if (needsStyleRecalc()) {
1591                 // Although no change occurred, we use the new style so that the cousin style sharing code won't get
1592                 // fooled into believing this style is the same.
1593                 renderer->setStyleInternal(newStyle.get());
1594             }
1595         }
1596
1597         // 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
1598         // 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).
1599         if (document()->styleSheetCollection()->usesRemUnits() && document()->documentElement() == this && localChange != NoChange && currentStyle && newStyle && currentStyle->fontSize() != newStyle->fontSize()) {
1600             // Cached RenderStyles may depend on the re units.
1601             if (StyleResolver* styleResolver = document()->styleResolverIfExists())
1602                 styleResolver->invalidateMatchedPropertiesCache();
1603             change = Force;
1604         }
1605
1606         if (change != Force) {
1607             if (styleChangeType() >= FullStyleChange)
1608                 change = Force;
1609             else
1610                 change = localChange;
1611         }
1612     }
1613     StyleResolverParentPusher parentPusher(this);
1614
1615     // FIXME: This does not care about sibling combinators. Will be necessary in XBL2 world.
1616     if (ElementShadow* shadow = this->shadow()) {
1617         if (change >= Inherit || shadow->childNeedsStyleRecalc() || shadow->needsStyleRecalc()) {
1618             parentPusher.push();
1619             shadow->recalcStyle(change);
1620         }
1621     }
1622
1623     updatePseudoElement(BEFORE, change);
1624
1625     // FIXME: This check is good enough for :hover + foo, but it is not good enough for :hover + foo + bar.
1626     // For now we will just worry about the common case, since it's a lot trickier to get the second case right
1627     // without doing way too much re-resolution.
1628     bool forceCheckOfNextElementSibling = false;
1629     bool forceCheckOfAnyElementSibling = false;
1630     for (Node *n = firstChild(); n; n = n->nextSibling()) {
1631         if (n->isTextNode()) {
1632             toText(n)->recalcTextStyle(change);
1633             continue;
1634         } 
1635         if (!n->isElementNode()) 
1636             continue;
1637         Element* element = toElement(n);
1638         bool childRulesChanged = element->needsStyleRecalc() && element->styleChangeType() == FullStyleChange;
1639         if ((forceCheckOfNextElementSibling || forceCheckOfAnyElementSibling))
1640             element->setNeedsStyleRecalc();
1641         if (change >= Inherit || element->childNeedsStyleRecalc() || element->needsStyleRecalc()) {
1642             parentPusher.push();
1643             element->recalcStyle(change);
1644         }
1645         forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentRules;
1646         forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules);
1647     }
1648
1649     updatePseudoElement(AFTER, change);
1650
1651     clearNeedsStyleRecalc();
1652     clearChildNeedsStyleRecalc();
1653     
1654     if (hasCustomStyleCallbacks())
1655         didRecalcStyle(change);
1656 }
1657
1658 ElementShadow* Element::shadow() const
1659 {
1660     return hasRareData() ? elementRareData()->shadow() : 0;
1661 }
1662
1663 ElementShadow* Element::ensureShadow()
1664 {
1665     return ensureElementRareData()->ensureShadow();
1666 }
1667
1668 void Element::didAffectSelector(AffectedSelectorMask)
1669 {
1670     setNeedsStyleRecalc();
1671 }
1672
1673 PassRefPtr<ShadowRoot> Element::createShadowRoot(ExceptionCode& ec)
1674 {
1675     if (alwaysCreateUserAgentShadowRoot())
1676         ensureUserAgentShadowRoot();
1677
1678 #if ENABLE(SHADOW_DOM)
1679     if (RuntimeEnabledFeatures::authorShadowDOMForAnyElementEnabled())
1680         return ensureShadow()->addShadowRoot(this, ShadowRoot::AuthorShadowRoot);
1681 #endif
1682
1683     // Since some elements recreates shadow root dynamically, multiple shadow
1684     // subtrees won't work well in that element. Until they are fixed, we disable
1685     // adding author shadow root for them.
1686     if (!areAuthorShadowsAllowed()) {
1687         ec = HIERARCHY_REQUEST_ERR;
1688         return 0;
1689     }
1690     return ensureShadow()->addShadowRoot(this, ShadowRoot::AuthorShadowRoot);
1691 }
1692
1693 ShadowRoot* Element::authorShadowRoot() const
1694 {
1695     ElementShadow* elementShadow = shadow();
1696     if (!elementShadow)
1697         return 0;
1698     ShadowRoot* shadowRoot = elementShadow->shadowRoot();
1699     if (shadowRoot->type() == ShadowRoot::AuthorShadowRoot)
1700         return shadowRoot;
1701     return 0;
1702 }
1703
1704 ShadowRoot* Element::userAgentShadowRoot() const
1705 {
1706     if (ElementShadow* elementShadow = shadow()) {
1707         if (ShadowRoot* shadowRoot = elementShadow->shadowRoot()) {
1708             ASSERT(shadowRoot->type() == ShadowRoot::UserAgentShadowRoot);
1709             return shadowRoot;
1710         }
1711     }
1712
1713     return 0;
1714 }
1715
1716 ShadowRoot* Element::ensureUserAgentShadowRoot()
1717 {
1718     ShadowRoot* shadowRoot = userAgentShadowRoot();
1719     if (!shadowRoot) {
1720         shadowRoot = ensureShadow()->addShadowRoot(this, ShadowRoot::UserAgentShadowRoot);
1721         didAddUserAgentShadowRoot(shadowRoot);
1722     }
1723     return shadowRoot;
1724 }
1725
1726 const AtomicString& Element::shadowPseudoId() const
1727 {
1728     return pseudo();
1729 }
1730
1731 bool Element::childTypeAllowed(NodeType type) const
1732 {
1733     switch (type) {
1734     case ELEMENT_NODE:
1735     case TEXT_NODE:
1736     case COMMENT_NODE:
1737     case PROCESSING_INSTRUCTION_NODE:
1738     case CDATA_SECTION_NODE:
1739     case ENTITY_REFERENCE_NODE:
1740         return true;
1741     default:
1742         break;
1743     }
1744     return false;
1745 }
1746
1747 static void checkForEmptyStyleChange(Element* element, RenderStyle* style)
1748 {
1749     if (!style && !element->styleAffectedByEmpty())
1750         return;
1751
1752     if (!style || (element->styleAffectedByEmpty() && (!style->emptyState() || element->hasChildNodes())))
1753         element->setNeedsStyleRecalc();
1754 }
1755
1756 static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool finishedParsingCallback,
1757                                         Node* beforeChange, Node* afterChange, int childCountDelta)
1758 {
1759     // :empty selector.
1760     checkForEmptyStyleChange(e, style);
1761     
1762     if (!style || (e->needsStyleRecalc() && e->childrenAffectedByPositionalRules()))
1763         return;
1764
1765     // :first-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
1766     // In the DOM case, we only need to do something if |afterChange| is not 0.
1767     // |afterChange| is 0 in the parser case, so it works out that we'll skip this block.
1768     if (e->childrenAffectedByFirstChildRules() && afterChange) {
1769         // Find our new first child.
1770         Node* newFirstChild = 0;
1771         for (newFirstChild = e->firstChild(); newFirstChild && !newFirstChild->isElementNode(); newFirstChild = newFirstChild->nextSibling()) {};
1772         
1773         // Find the first element node following |afterChange|
1774         Node* firstElementAfterInsertion = 0;
1775         for (firstElementAfterInsertion = afterChange;
1776              firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode();
1777              firstElementAfterInsertion = firstElementAfterInsertion->nextSibling()) {};
1778         
1779         // This is the insert/append case.
1780         if (newFirstChild != firstElementAfterInsertion && firstElementAfterInsertion && firstElementAfterInsertion->attached() &&
1781             firstElementAfterInsertion->renderStyle() && firstElementAfterInsertion->renderStyle()->firstChildState())
1782             firstElementAfterInsertion->setNeedsStyleRecalc();
1783             
1784         // We also have to handle node removal.
1785         if (childCountDelta < 0 && newFirstChild == firstElementAfterInsertion && newFirstChild && (!newFirstChild->renderStyle() || !newFirstChild->renderStyle()->firstChildState()))
1786             newFirstChild->setNeedsStyleRecalc();
1787     }
1788
1789     // :last-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
1790     // In the DOM case, we only need to do something if |afterChange| is not 0.
1791     if (e->childrenAffectedByLastChildRules() && beforeChange) {
1792         // Find our new last child.
1793         Node* newLastChild = 0;
1794         for (newLastChild = e->lastChild(); newLastChild && !newLastChild->isElementNode(); newLastChild = newLastChild->previousSibling()) {};
1795         
1796         // Find the last element node going backwards from |beforeChange|
1797         Node* lastElementBeforeInsertion = 0;
1798         for (lastElementBeforeInsertion = beforeChange;
1799              lastElementBeforeInsertion && !lastElementBeforeInsertion->isElementNode();
1800              lastElementBeforeInsertion = lastElementBeforeInsertion->previousSibling()) {};
1801         
1802         if (newLastChild != lastElementBeforeInsertion && lastElementBeforeInsertion && lastElementBeforeInsertion->attached() &&
1803             lastElementBeforeInsertion->renderStyle() && lastElementBeforeInsertion->renderStyle()->lastChildState())
1804             lastElementBeforeInsertion->setNeedsStyleRecalc();
1805             
1806         // 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
1807         // to match now.
1808         if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild == lastElementBeforeInsertion && newLastChild && (!newLastChild->renderStyle() || !newLastChild->renderStyle()->lastChildState()))
1809             newLastChild->setNeedsStyleRecalc();
1810     }
1811
1812     // The + selector.  We need to invalidate the first element following the insertion point.  It is the only possible element
1813     // that could be affected by this DOM change.
1814     if (e->childrenAffectedByDirectAdjacentRules() && afterChange) {
1815         Node* firstElementAfterInsertion = 0;
1816         for (firstElementAfterInsertion = afterChange;
1817              firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode();
1818              firstElementAfterInsertion = firstElementAfterInsertion->nextSibling()) {};
1819         if (firstElementAfterInsertion && firstElementAfterInsertion->attached())
1820             firstElementAfterInsertion->setNeedsStyleRecalc();
1821     }
1822
1823     // Forward positional selectors include the ~ selector, nth-child, nth-of-type, first-of-type and only-of-type.
1824     // Backward positional selectors include nth-last-child, nth-last-of-type, last-of-type and only-of-type.
1825     // We have to invalidate everything following the insertion point in the forward case, and everything before the insertion point in the
1826     // backward case.
1827     // |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.
1828     // 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
1829     // here.  recalcStyle will then force a walk of the children when it sees that this has happened.
1830     if ((e->childrenAffectedByForwardPositionalRules() && afterChange)
1831         || (e->childrenAffectedByBackwardPositionalRules() && beforeChange))
1832         e->setNeedsStyleRecalc();
1833 }
1834
1835 void Element::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
1836 {
1837     ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
1838     if (changedByParser)
1839         checkForEmptyStyleChange(this, renderStyle());
1840     else
1841         checkForSiblingStyleChanges(this, renderStyle(), false, beforeChange, afterChange, childCountDelta);
1842
1843     if (ElementShadow * shadow = this->shadow())
1844         shadow->invalidateDistribution();
1845 }
1846
1847 void Element::removeAllEventListeners()
1848 {
1849     ContainerNode::removeAllEventListeners();
1850     if (ElementShadow* shadow = this->shadow())
1851         shadow->removeAllEventListeners();
1852 }
1853
1854 void Element::beginParsingChildren()
1855 {
1856     clearIsParsingChildrenFinished();
1857     StyleResolver* styleResolver = document()->styleResolverIfExists();
1858     if (styleResolver && attached())
1859         styleResolver->pushParentElement(this);
1860 }
1861
1862 void Element::finishParsingChildren()
1863 {
1864     ContainerNode::finishParsingChildren();
1865     setIsParsingChildrenFinished();
1866     checkForSiblingStyleChanges(this, renderStyle(), true, lastChild(), 0, 0);
1867     if (StyleResolver* styleResolver = document()->styleResolverIfExists())
1868         styleResolver->popParentElement(this);
1869 }
1870
1871 #ifndef NDEBUG
1872 void Element::formatForDebugger(char* buffer, unsigned length) const
1873 {
1874     StringBuilder result;
1875     String s;
1876
1877     result.append(nodeName());
1878
1879     s = getIdAttribute();
1880     if (s.length() > 0) {
1881         if (result.length() > 0)
1882             result.appendLiteral("; ");
1883         result.appendLiteral("id=");
1884         result.append(s);
1885     }
1886
1887     s = getAttribute(classAttr);
1888     if (s.length() > 0) {
1889         if (result.length() > 0)
1890             result.appendLiteral("; ");
1891         result.appendLiteral("class=");
1892         result.append(s);
1893     }
1894
1895     strncpy(buffer, result.toString().utf8().data(), length - 1);
1896 }
1897 #endif
1898
1899 const Vector<RefPtr<Attr> >& Element::attrNodeList()
1900 {
1901     ASSERT(hasSyntheticAttrChildNodes());
1902     return *attrNodeListForElement(this);
1903 }
1904
1905 PassRefPtr<Attr> Element::setAttributeNode(Attr* attrNode, ExceptionCode& ec)
1906 {
1907     if (!attrNode) {
1908         ec = TYPE_MISMATCH_ERR;
1909         return 0;
1910     }
1911
1912     RefPtr<Attr> oldAttrNode = attrIfExists(attrNode->qualifiedName());
1913     if (oldAttrNode.get() == attrNode)
1914         return attrNode; // This Attr is already attached to the element.
1915
1916     // INUSE_ATTRIBUTE_ERR: Raised if node is an Attr that is already an attribute of another Element object.
1917     // The DOM user must explicitly clone Attr nodes to re-use them in other elements.
1918     if (attrNode->ownerElement()) {
1919         ec = INUSE_ATTRIBUTE_ERR;
1920         return 0;
1921     }
1922
1923     synchronizeAllAttributes();
1924     UniqueElementData* elementData = ensureUniqueElementData();
1925
1926     unsigned index = elementData->getAttributeItemIndexForAttributeNode(attrNode);
1927     if (index != ElementData::attributeNotFound) {
1928         if (oldAttrNode)
1929             detachAttrNodeFromElementWithValue(oldAttrNode.get(), elementData->attributeItem(index)->value());
1930         else
1931             oldAttrNode = Attr::create(document(), attrNode->qualifiedName(), elementData->attributeItem(index)->value());
1932     }
1933
1934     setAttributeInternal(index, attrNode->qualifiedName(), attrNode->value(), NotInSynchronizationOfLazyAttribute);
1935
1936     attrNode->attachToElement(this);
1937     ensureAttrNodeListForElement(this)->append(attrNode);
1938
1939     return oldAttrNode.release();
1940 }
1941
1942 PassRefPtr<Attr> Element::setAttributeNodeNS(Attr* attr, ExceptionCode& ec)
1943 {
1944     return setAttributeNode(attr, ec);
1945 }
1946
1947 PassRefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionCode& ec)
1948 {
1949     if (!attr) {
1950         ec = TYPE_MISMATCH_ERR;
1951         return 0;
1952     }
1953     if (attr->ownerElement() != this) {
1954         ec = NOT_FOUND_ERR;
1955         return 0;
1956     }
1957
1958     ASSERT(document() == attr->document());
1959
1960     synchronizeAttribute(attr->qualifiedName());
1961
1962     unsigned index = elementData()->getAttributeItemIndexForAttributeNode(attr);
1963     if (index == ElementData::attributeNotFound) {
1964         ec = NOT_FOUND_ERR;
1965         return 0;
1966     }
1967
1968     RefPtr<Attr> attrNode = attr;
1969     detachAttrNodeFromElementWithValue(attr, elementData()->attributeItem(index)->value());
1970     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
1971     return attrNode.release();
1972 }
1973
1974 bool Element::parseAttributeName(QualifiedName& out, const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionCode& ec)
1975 {
1976     String prefix, localName;
1977     if (!Document::parseQualifiedName(qualifiedName, prefix, localName, ec))
1978         return false;
1979     ASSERT(!ec);
1980
1981     QualifiedName qName(prefix, localName, namespaceURI);
1982
1983     if (!Document::hasValidNamespaceForAttributes(qName)) {
1984         ec = NAMESPACE_ERR;
1985         return false;
1986     }
1987
1988     out = qName;
1989     return true;
1990 }
1991
1992 void Element::setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode& ec)
1993 {
1994     QualifiedName parsedName = anyName;
1995     if (!parseAttributeName(parsedName, namespaceURI, qualifiedName, ec))
1996         return;
1997     setAttribute(parsedName, value);
1998 }
1999
2000 void Element::removeAttributeInternal(unsigned index, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
2001 {
2002     ASSERT_WITH_SECURITY_IMPLICATION(index < attributeCount());
2003
2004     UniqueElementData* elementData = ensureUniqueElementData();
2005
2006     QualifiedName name = elementData->attributeItem(index)->name();
2007     AtomicString valueBeingRemoved = elementData->attributeItem(index)->value();
2008
2009     if (!inSynchronizationOfLazyAttribute) {
2010         if (!valueBeingRemoved.isNull())
2011             willModifyAttribute(name, valueBeingRemoved, nullAtom);
2012     }
2013
2014     if (RefPtr<Attr> attrNode = attrIfExists(name))
2015         detachAttrNodeFromElementWithValue(attrNode.get(), elementData->attributeItem(index)->value());
2016
2017     elementData->removeAttribute(index);
2018
2019     if (!inSynchronizationOfLazyAttribute)
2020         didRemoveAttribute(name);
2021 }
2022
2023 void Element::addAttributeInternal(const QualifiedName& name, const AtomicString& value, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
2024 {
2025     if (!inSynchronizationOfLazyAttribute)
2026         willModifyAttribute(name, nullAtom, value);
2027     ensureUniqueElementData()->addAttribute(name, value);
2028     if (!inSynchronizationOfLazyAttribute)
2029         didAddAttribute(name, value);
2030 }
2031
2032 void Element::removeAttribute(const AtomicString& name)
2033 {
2034     if (!elementData())
2035         return;
2036
2037     AtomicString localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
2038     unsigned index = elementData()->getAttributeItemIndex(localName, false);
2039     if (index == ElementData::attributeNotFound) {
2040         if (UNLIKELY(localName == styleAttr) && elementData()->m_styleAttributeIsDirty && isStyledElement())
2041             static_cast<StyledElement*>(this)->removeAllInlineStyleProperties();
2042         return;
2043     }
2044
2045     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
2046 }
2047
2048 void Element::removeAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName)
2049 {
2050     removeAttribute(QualifiedName(nullAtom, localName, namespaceURI));
2051 }
2052
2053 PassRefPtr<Attr> Element::getAttributeNode(const AtomicString& localName)
2054 {
2055     if (!elementData())
2056         return 0;
2057     synchronizeAttribute(localName);
2058     const Attribute* attribute = elementData()->getAttributeItem(localName, shouldIgnoreAttributeCase(this));
2059     if (!attribute)
2060         return 0;
2061     return ensureAttr(attribute->name());
2062 }
2063
2064 PassRefPtr<Attr> Element::getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName)
2065 {
2066     if (!elementData())
2067         return 0;
2068     QualifiedName qName(nullAtom, localName, namespaceURI);
2069     synchronizeAttribute(qName);
2070     const Attribute* attribute = elementData()->getAttributeItem(qName);
2071     if (!attribute)
2072         return 0;
2073     return ensureAttr(attribute->name());
2074 }
2075
2076 bool Element::hasAttribute(const AtomicString& localName) const
2077 {
2078     if (!elementData())
2079         return false;
2080     synchronizeAttribute(localName);
2081     return elementData()->getAttributeItem(shouldIgnoreAttributeCase(this) ? localName.lower() : localName, false);
2082 }
2083
2084 bool Element::hasAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const
2085 {
2086     if (!elementData())
2087         return false;
2088     QualifiedName qName(nullAtom, localName, namespaceURI);
2089     synchronizeAttribute(qName);
2090     return elementData()->getAttributeItem(qName);
2091 }
2092
2093 CSSStyleDeclaration *Element::style()
2094 {
2095     return 0;
2096 }
2097
2098 void Element::focus(bool restorePreviousSelection, FocusDirection direction)
2099 {
2100     if (!inDocument())
2101         return;
2102
2103     Document* doc = document();
2104     if (doc->focusedElement() == this)
2105         return;
2106
2107     // If the stylesheets have already been loaded we can reliably check isFocusable.
2108     // If not, we continue and set the focused node on the focus controller below so
2109     // that it can be updated soon after attach. 
2110     if (doc->haveStylesheetsLoaded()) {
2111         doc->updateLayoutIgnorePendingStylesheets();
2112         if (!isFocusable())
2113             return;
2114     }
2115
2116     if (!supportsFocus())
2117         return;
2118
2119     RefPtr<Node> protect;
2120     if (Page* page = doc->page()) {
2121         // Focus and change event handlers can cause us to lose our last ref.
2122         // If a focus event handler changes the focus to a different node it
2123         // does not make sense to continue and update appearence.
2124         protect = this;
2125         if (!page->focusController()->setFocusedElement(this, doc->frame(), direction))
2126             return;
2127     }
2128
2129     // Setting the focused node above might have invalidated the layout due to scripts.
2130     doc->updateLayoutIgnorePendingStylesheets();
2131
2132     if (!isFocusable()) {
2133         ensureElementRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(true);
2134         return;
2135     }
2136         
2137     cancelFocusAppearanceUpdate();
2138     updateFocusAppearance(restorePreviousSelection);
2139 }
2140
2141 void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
2142 {
2143     if (isRootEditableElement()) {
2144         Frame* frame = document()->frame();
2145         if (!frame)
2146             return;
2147         
2148         // When focusing an editable element in an iframe, don't reset the selection if it already contains a selection.
2149         if (this == frame->selection()->rootEditableElement())
2150             return;
2151
2152         // FIXME: We should restore the previous selection if there is one.
2153         VisibleSelection newSelection = VisibleSelection(firstPositionInOrBeforeNode(this), DOWNSTREAM);
2154         
2155         if (frame->selection()->shouldChangeSelection(newSelection)) {
2156             frame->selection()->setSelection(newSelection);
2157             frame->selection()->revealSelection();
2158         }
2159     } else if (renderer() && !renderer()->isWidget())
2160         renderer()->scrollRectToVisible(boundingBox());
2161 }
2162
2163 void Element::blur()
2164 {
2165     cancelFocusAppearanceUpdate();
2166     Document* doc = document();
2167     if (treeScope()->focusedElement() == this) {
2168         if (doc->frame())
2169             doc->frame()->page()->focusController()->setFocusedElement(0, doc->frame());
2170         else
2171             doc->setFocusedElement(0);
2172     }
2173 }
2174
2175 void Element::dispatchFocusInEvent(const AtomicString& eventType, PassRefPtr<Element> oldFocusedElement)
2176 {
2177     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
2178     ASSERT(eventType == eventNames().focusinEvent || eventType == eventNames().DOMFocusInEvent);
2179     dispatchScopedEventDispatchMediator(FocusInEventDispatchMediator::create(FocusEvent::create(eventType, true, false, document()->defaultView(), 0, oldFocusedElement)));
2180 }
2181
2182 void Element::dispatchFocusOutEvent(const AtomicString& eventType, PassRefPtr<Element> newFocusedElement)
2183 {
2184     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
2185     ASSERT(eventType == eventNames().focusoutEvent || eventType == eventNames().DOMFocusOutEvent);
2186     dispatchScopedEventDispatchMediator(FocusOutEventDispatchMediator::create(FocusEvent::create(eventType, true, false, document()->defaultView(), 0, newFocusedElement)));
2187 }
2188
2189 void Element::dispatchFocusEvent(PassRefPtr<Element> oldFocusedElement, FocusDirection)
2190 {
2191     if (document()->page())
2192         document()->page()->chrome().client()->elementDidFocus(this);
2193
2194     RefPtr<FocusEvent> event = FocusEvent::create(eventNames().focusEvent, false, false, document()->defaultView(), 0, oldFocusedElement);
2195     EventDispatcher::dispatchEvent(this, FocusEventDispatchMediator::create(event.release()));
2196 }
2197
2198 void Element::dispatchBlurEvent(PassRefPtr<Element> newFocusedElement)
2199 {
2200     if (document()->page())
2201         document()->page()->chrome().client()->elementDidBlur(this);
2202
2203     RefPtr<FocusEvent> event = FocusEvent::create(eventNames().blurEvent, false, false, document()->defaultView(), 0, newFocusedElement);
2204     EventDispatcher::dispatchEvent(this, BlurEventDispatchMediator::create(event.release()));
2205 }
2206
2207
2208 String Element::innerText()
2209 {
2210     // We need to update layout, since plainText uses line boxes in the render tree.
2211     document()->updateLayoutIgnorePendingStylesheets();
2212
2213     if (!renderer())
2214         return textContent(true);
2215
2216     return plainText(rangeOfContents(const_cast<Element*>(this)).get());
2217 }
2218
2219 String Element::outerText()
2220 {
2221     // Getting outerText is the same as getting innerText, only
2222     // setting is different. You would think this should get the plain
2223     // text for the outer range, but this is wrong, <br> for instance
2224     // would return different values for inner and outer text by such
2225     // a rule, but it doesn't in WinIE, and we want to match that.
2226     return innerText();
2227 }
2228
2229 String Element::title() const
2230 {
2231     return String();
2232 }
2233
2234 const AtomicString& Element::pseudo() const
2235 {
2236     return getAttribute(pseudoAttr);
2237 }
2238
2239 void Element::setPseudo(const AtomicString& value)
2240 {
2241     setAttribute(pseudoAttr, value);
2242 }
2243
2244 LayoutSize Element::minimumSizeForResizing() const
2245 {
2246     return hasRareData() ? elementRareData()->minimumSizeForResizing() : defaultMinimumSizeForResizing();
2247 }
2248
2249 void Element::setMinimumSizeForResizing(const LayoutSize& size)
2250 {
2251     if (!hasRareData() && size == defaultMinimumSizeForResizing())
2252         return;
2253     ensureElementRareData()->setMinimumSizeForResizing(size);
2254 }
2255
2256 RenderStyle* Element::computedStyle(PseudoId pseudoElementSpecifier)
2257 {
2258     if (PseudoElement* element = pseudoElement(pseudoElementSpecifier))
2259         return element->computedStyle();
2260
2261     // FIXME: Find and use the renderer from the pseudo element instead of the actual element so that the 'length'
2262     // properties, which are only known by the renderer because it did the layout, will be correct and so that the
2263     // values returned for the ":selection" pseudo-element will be correct.
2264     if (RenderStyle* usedStyle = renderStyle()) {
2265         if (pseudoElementSpecifier) {
2266             RenderStyle* cachedPseudoStyle = usedStyle->getCachedPseudoStyle(pseudoElementSpecifier);
2267             return cachedPseudoStyle ? cachedPseudoStyle : usedStyle;
2268          } else
2269             return usedStyle;
2270     }
2271
2272     if (!attached())
2273         // FIXME: Try to do better than this. Ensure that styleForElement() works for elements that are not in the
2274         // document tree and figure out when to destroy the computed style for such elements.
2275         return 0;
2276
2277     ElementRareData* data = ensureElementRareData();
2278     if (!data->computedStyle())
2279         data->setComputedStyle(document()->styleForElementIgnoringPendingStylesheets(this));
2280     return pseudoElementSpecifier ? data->computedStyle()->getCachedPseudoStyle(pseudoElementSpecifier) : data->computedStyle();
2281 }
2282
2283 void Element::setStyleAffectedByEmpty()
2284 {
2285     ensureElementRareData()->setStyleAffectedByEmpty(true);
2286 }
2287
2288 void Element::setChildrenAffectedByHover(bool value)
2289 {
2290     if (value || hasRareData())
2291         ensureElementRareData()->setChildrenAffectedByHover(value);
2292 }
2293
2294 void Element::setChildrenAffectedByActive(bool value)
2295 {
2296     if (value || hasRareData())
2297         ensureElementRareData()->setChildrenAffectedByActive(value);
2298 }
2299
2300 void Element::setChildrenAffectedByDrag(bool value)
2301 {
2302     if (value || hasRareData())
2303         ensureElementRareData()->setChildrenAffectedByDrag(value);
2304 }
2305
2306 void Element::setChildrenAffectedByFirstChildRules()
2307 {
2308     ensureElementRareData()->setChildrenAffectedByFirstChildRules(true);
2309 }
2310
2311 void Element::setChildrenAffectedByLastChildRules()
2312 {
2313     ensureElementRareData()->setChildrenAffectedByLastChildRules(true);
2314 }
2315
2316 void Element::setChildrenAffectedByDirectAdjacentRules()
2317 {
2318     ensureElementRareData()->setChildrenAffectedByDirectAdjacentRules(true);
2319 }
2320
2321 void Element::setChildrenAffectedByForwardPositionalRules()
2322 {
2323     ensureElementRareData()->setChildrenAffectedByForwardPositionalRules(true);
2324 }
2325
2326 void Element::setChildrenAffectedByBackwardPositionalRules()
2327 {
2328     ensureElementRareData()->setChildrenAffectedByBackwardPositionalRules(true);
2329 }
2330
2331 void Element::setChildIndex(unsigned index)
2332 {
2333     ElementRareData* rareData = ensureElementRareData();
2334     if (RenderStyle* style = renderStyle())
2335         style->setUnique();
2336     rareData->setChildIndex(index);
2337 }
2338
2339 bool Element::hasFlagsSetDuringStylingOfChildren() const
2340 {
2341     if (!hasRareData())
2342         return false;
2343     return rareDataChildrenAffectedByHover()
2344         || rareDataChildrenAffectedByActive()
2345         || rareDataChildrenAffectedByDrag()
2346         || rareDataChildrenAffectedByFirstChildRules()
2347         || rareDataChildrenAffectedByLastChildRules()
2348         || rareDataChildrenAffectedByDirectAdjacentRules()
2349         || rareDataChildrenAffectedByForwardPositionalRules()
2350         || rareDataChildrenAffectedByBackwardPositionalRules();
2351 }
2352
2353 bool Element::rareDataStyleAffectedByEmpty() const
2354 {
2355     ASSERT(hasRareData());
2356     return elementRareData()->styleAffectedByEmpty();
2357 }
2358
2359 bool Element::rareDataChildrenAffectedByHover() const
2360 {
2361     ASSERT(hasRareData());
2362     return elementRareData()->childrenAffectedByHover();
2363 }
2364
2365 bool Element::rareDataChildrenAffectedByActive() const
2366 {
2367     ASSERT(hasRareData());
2368     return elementRareData()->childrenAffectedByActive();
2369 }
2370
2371 bool Element::rareDataChildrenAffectedByDrag() const
2372 {
2373     ASSERT(hasRareData());
2374     return elementRareData()->childrenAffectedByDrag();
2375 }
2376
2377 bool Element::rareDataChildrenAffectedByFirstChildRules() const
2378 {
2379     ASSERT(hasRareData());
2380     return elementRareData()->childrenAffectedByFirstChildRules();
2381 }
2382
2383 bool Element::rareDataChildrenAffectedByLastChildRules() const
2384 {
2385     ASSERT(hasRareData());
2386     return elementRareData()->childrenAffectedByLastChildRules();
2387 }
2388
2389 bool Element::rareDataChildrenAffectedByDirectAdjacentRules() const
2390 {
2391     ASSERT(hasRareData());
2392     return elementRareData()->childrenAffectedByDirectAdjacentRules();
2393 }
2394
2395 bool Element::rareDataChildrenAffectedByForwardPositionalRules() const
2396 {
2397     ASSERT(hasRareData());
2398     return elementRareData()->childrenAffectedByForwardPositionalRules();
2399 }
2400
2401 bool Element::rareDataChildrenAffectedByBackwardPositionalRules() const
2402 {
2403     ASSERT(hasRareData());
2404     return elementRareData()->childrenAffectedByBackwardPositionalRules();
2405 }
2406
2407 unsigned Element::rareDataChildIndex() const
2408 {
2409     ASSERT(hasRareData());
2410     return elementRareData()->childIndex();
2411 }
2412
2413 void Element::setIsInCanvasSubtree(bool isInCanvasSubtree)
2414 {
2415     ensureElementRareData()->setIsInCanvasSubtree(isInCanvasSubtree);
2416 }
2417
2418 bool Element::isInCanvasSubtree() const
2419 {
2420     return hasRareData() && elementRareData()->isInCanvasSubtree();
2421 }
2422
2423 void Element::setRegionOversetState(RegionOversetState state)
2424 {
2425     ensureElementRareData()->setRegionOversetState(state);
2426 }
2427
2428 RegionOversetState Element::regionOversetState() const
2429 {
2430     return hasRareData() ? elementRareData()->regionOversetState() : RegionUndefined;
2431 }
2432
2433 AtomicString Element::computeInheritedLanguage() const
2434 {
2435     const Node* n = this;
2436     AtomicString value;
2437     // The language property is inherited, so we iterate over the parents to find the first language.
2438     do {
2439         if (n->isElementNode()) {
2440             if (const ElementData* elementData = toElement(n)->elementData()) {
2441                 // Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7
2442                 if (const Attribute* attribute = elementData->getAttributeItem(XMLNames::langAttr))
2443                     value = attribute->value();
2444                 else if (const Attribute* attribute = elementData->getAttributeItem(HTMLNames::langAttr))
2445                     value = attribute->value();
2446             }
2447         } else if (n->isDocumentNode()) {
2448             // checking the MIME content-language
2449             value = toDocument(n)->contentLanguage();
2450         }
2451
2452         n = n->parentNode();
2453     } while (n && value.isNull());
2454
2455     return value;
2456 }
2457
2458 Locale& Element::locale() const
2459 {
2460     return document()->getCachedLocale(computeInheritedLanguage());
2461 }
2462
2463 void Element::cancelFocusAppearanceUpdate()
2464 {
2465     if (hasRareData())
2466         elementRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
2467     if (document()->focusedElement() == this)
2468         document()->cancelFocusAppearanceUpdate();
2469 }
2470
2471 void Element::normalizeAttributes()
2472 {
2473     if (!hasAttributes())
2474         return;
2475     for (unsigned i = 0; i < attributeCount(); ++i) {
2476         if (RefPtr<Attr> attr = attrIfExists(attributeItem(i)->name()))
2477             attr->normalize();
2478     }
2479 }
2480
2481 void Element::updatePseudoElement(PseudoId pseudoId, StyleChange change)
2482 {
2483     PseudoElement* existing = pseudoElement(pseudoId);
2484     if (existing) {
2485         // PseudoElement styles hang off their parent element's style so if we needed
2486         // a style recalc we should Force one on the pseudo.
2487         existing->recalcStyle(needsStyleRecalc() ? Force : change);
2488
2489         // Wait until our parent is not displayed or pseudoElementRendererIsNeeded
2490         // is false, otherwise we could continously create and destroy PseudoElements
2491         // when RenderObject::isChildAllowed on our parent returns false for the
2492         // PseudoElement's renderer for each style recalc.
2493         if (!renderer() || !pseudoElementRendererIsNeeded(renderer()->getCachedPseudoStyle(pseudoId)))
2494             setPseudoElement(pseudoId, 0);
2495     } else if (RefPtr<PseudoElement> element = createPseudoElementIfNeeded(pseudoId)) {
2496         element->attach();
2497         setPseudoElement(pseudoId, element.release());
2498     }
2499 }
2500
2501 PassRefPtr<PseudoElement> Element::createPseudoElementIfNeeded(PseudoId pseudoId)
2502 {
2503     if (!document()->styleSheetCollection()->usesBeforeAfterRules())
2504         return 0;
2505
2506     if (!renderer() || !renderer()->canHaveGeneratedChildren())
2507         return 0;
2508
2509     if (isPseudoElement())
2510         return 0;
2511
2512     if (!pseudoElementRendererIsNeeded(renderer()->getCachedPseudoStyle(pseudoId)))
2513         return 0;
2514
2515     return PseudoElement::create(this, pseudoId);
2516 }
2517
2518 bool Element::hasPseudoElements() const
2519 {
2520     return hasRareData() && elementRareData()->hasPseudoElements();
2521 }
2522
2523 PseudoElement* Element::pseudoElement(PseudoId pseudoId) const
2524 {
2525     return hasRareData() ? elementRareData()->pseudoElement(pseudoId) : 0;
2526 }
2527
2528 void Element::setPseudoElement(PseudoId pseudoId, PassRefPtr<PseudoElement> element)
2529 {
2530     ensureElementRareData()->setPseudoElement(pseudoId, element);
2531     resetNeedsShadowTreeWalker();
2532 }
2533
2534 RenderObject* Element::pseudoElementRenderer(PseudoId pseudoId) const
2535 {
2536     if (PseudoElement* element = pseudoElement(pseudoId))
2537         return element->renderer();
2538     return 0;
2539 }
2540
2541 // ElementTraversal API
2542 Element* Element::firstElementChild() const
2543 {
2544     return ElementTraversal::firstWithin(this);
2545 }
2546
2547 Element* Element::lastElementChild() const
2548 {
2549     Node* n = lastChild();
2550     while (n && !n->isElementNode())
2551         n = n->previousSibling();
2552     return toElement(n);
2553 }
2554
2555 unsigned Element::childElementCount() const
2556 {
2557     unsigned count = 0;
2558     Node* n = firstChild();
2559     while (n) {
2560         count += n->isElementNode();
2561         n = n->nextSibling();
2562     }
2563     return count;
2564 }
2565
2566 bool Element::matchesReadOnlyPseudoClass() const
2567 {
2568     return false;
2569 }
2570
2571 bool Element::matchesReadWritePseudoClass() const
2572 {
2573     return false;
2574 }
2575
2576 bool Element::webkitMatchesSelector(const String& selector, ExceptionCode& ec)
2577 {
2578     if (selector.isEmpty()) {
2579         ec = SYNTAX_ERR;
2580         return false;
2581     }
2582
2583     SelectorQuery* selectorQuery = document()->selectorQueryCache()->add(selector, document(), ec);
2584     if (!selectorQuery)
2585         return false;
2586     return selectorQuery->matches(this);
2587 }
2588
2589 bool Element::shouldAppearIndeterminate() const
2590 {
2591     return false;
2592 }
2593
2594 DOMTokenList* Element::classList()
2595 {
2596     ElementRareData* data = ensureElementRareData();
2597     if (!data->classList())
2598         data->setClassList(ClassList::create(this));
2599     return data->classList();
2600 }
2601
2602 DOMStringMap* Element::dataset()
2603 {
2604     ElementRareData* data = ensureElementRareData();
2605     if (!data->dataset())
2606         data->setDataset(DatasetDOMStringMap::create(this));
2607     return data->dataset();
2608 }
2609
2610 KURL Element::getURLAttribute(const QualifiedName& name) const
2611 {
2612 #if !ASSERT_DISABLED
2613     if (elementData()) {
2614         if (const Attribute* attribute = getAttributeItem(name))
2615             ASSERT(isURLAttribute(*attribute));
2616     }
2617 #endif
2618     return document()->completeURL(stripLeadingAndTrailingHTMLSpaces(getAttribute(name)));
2619 }
2620
2621 KURL Element::getNonEmptyURLAttribute(const QualifiedName& name) const
2622 {
2623 #if !ASSERT_DISABLED
2624     if (elementData()) {
2625         if (const Attribute* attribute = getAttributeItem(name))
2626             ASSERT(isURLAttribute(*attribute));
2627     }
2628 #endif
2629     String value = stripLeadingAndTrailingHTMLSpaces(getAttribute(name));
2630     if (value.isEmpty())
2631         return KURL();
2632     return document()->completeURL(value);
2633 }
2634
2635 int Element::getIntegralAttribute(const QualifiedName& attributeName) const
2636 {
2637     return getAttribute(attributeName).string().toInt();
2638 }
2639
2640 void Element::setIntegralAttribute(const QualifiedName& attributeName, int value)
2641 {
2642     // FIXME: Need an AtomicString version of String::number.
2643     setAttribute(attributeName, String::number(value));
2644 }
2645
2646 unsigned Element::getUnsignedIntegralAttribute(const QualifiedName& attributeName) const
2647 {
2648     return getAttribute(attributeName).string().toUInt();
2649 }
2650
2651 void Element::setUnsignedIntegralAttribute(const QualifiedName& attributeName, unsigned value)
2652 {
2653     // FIXME: Need an AtomicString version of String::number.
2654     setAttribute(attributeName, String::number(value));
2655 }
2656
2657 #if ENABLE(INDIE_UI)
2658 void Element::setUIActions(const AtomicString& actions)
2659 {
2660     setAttribute(uiactionsAttr, actions);
2661 }
2662
2663 const AtomicString& Element::UIActions() const
2664 {
2665     return getAttribute(uiactionsAttr);
2666 }
2667 #endif
2668
2669     
2670 #if ENABLE(SVG)
2671 bool Element::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
2672 {
2673     // Only create renderers for SVG elements whose parents are SVG elements, or for proper <svg xmlns="svgNS"> subdocuments.
2674     if (childContext.node()->isSVGElement())
2675         return childContext.node()->hasTagName(SVGNames::svgTag) || isSVGElement();
2676
2677     return ContainerNode::childShouldCreateRenderer(childContext);
2678 }
2679 #endif
2680
2681 #if ENABLE(FULLSCREEN_API)
2682 void Element::webkitRequestFullscreen()
2683 {
2684     document()->requestFullScreenForElement(this, ALLOW_KEYBOARD_INPUT, Document::EnforceIFrameAllowFullScreenRequirement);
2685 }
2686
2687 void Element::webkitRequestFullScreen(unsigned short flags)
2688 {
2689     document()->requestFullScreenForElement(this, (flags | LEGACY_MOZILLA_REQUEST), Document::EnforceIFrameAllowFullScreenRequirement);
2690 }
2691
2692 bool Element::containsFullScreenElement() const
2693 {
2694     return hasRareData() && elementRareData()->containsFullScreenElement();
2695 }
2696
2697 void Element::setContainsFullScreenElement(bool flag)
2698 {
2699     ensureElementRareData()->setContainsFullScreenElement(flag);
2700     setNeedsStyleRecalc(SyntheticStyleChange);
2701 }
2702
2703 static Element* parentCrossingFrameBoundaries(Element* element)
2704 {
2705     ASSERT(element);
2706     return element->parentElement() ? element->parentElement() : element->document()->ownerElement();
2707 }
2708
2709 void Element::setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(bool flag)
2710 {
2711     Element* element = this;
2712     while ((element = parentCrossingFrameBoundaries(element)))
2713         element->setContainsFullScreenElement(flag);
2714 }
2715 #endif    
2716
2717 #if ENABLE(DIALOG_ELEMENT)
2718 bool Element::isInTopLayer() const
2719 {
2720     return hasRareData() && elementRareData()->isInTopLayer();
2721 }
2722
2723 void Element::setIsInTopLayer(bool inTopLayer)
2724 {
2725     if (isInTopLayer() == inTopLayer)
2726         return;
2727     ensureElementRareData()->setIsInTopLayer(inTopLayer);
2728
2729     // We must ensure a reattach occurs so the renderer is inserted in the correct sibling order under RenderView according to its
2730     // top layer position, or in its usual place if not in the top layer.
2731     reattachIfAttached();
2732 }
2733 #endif
2734
2735 #if ENABLE(POINTER_LOCK)
2736 void Element::webkitRequestPointerLock()
2737 {
2738     if (document()->page())
2739         document()->page()->pointerLockController()->requestPointerLock(this);
2740 }
2741 #endif
2742
2743 SpellcheckAttributeState Element::spellcheckAttributeState() const
2744 {
2745     const AtomicString& value = getAttribute(HTMLNames::spellcheckAttr);
2746     if (value == nullAtom)
2747         return SpellcheckAttributeDefault;
2748     if (equalIgnoringCase(value, "true") || equalIgnoringCase(value, ""))
2749         return SpellcheckAttributeTrue;
2750     if (equalIgnoringCase(value, "false"))
2751         return SpellcheckAttributeFalse;
2752
2753     return SpellcheckAttributeDefault;
2754 }
2755
2756 bool Element::isSpellCheckingEnabled() const
2757 {
2758     for (const Element* element = this; element; element = element->parentOrShadowHostElement()) {
2759         switch (element->spellcheckAttributeState()) {
2760         case SpellcheckAttributeTrue:
2761             return true;
2762         case SpellcheckAttributeFalse:
2763             return false;
2764         case SpellcheckAttributeDefault:
2765             break;
2766         }
2767     }
2768
2769     return true;
2770 }
2771
2772 RenderRegion* Element::renderRegion() const
2773 {
2774     if (renderer() && renderer()->isRenderRegion())
2775         return toRenderRegion(renderer());
2776
2777     return 0;
2778 }
2779
2780 bool Element::moveToFlowThreadIsNeeded(RefPtr<RenderStyle>& cachedStyle)
2781 {
2782     Document* doc = document();
2783     
2784     if (!doc->cssRegionsEnabled())
2785         return false;
2786
2787 #if ENABLE(FULLSCREEN_API)
2788     if (doc->webkitIsFullScreen() && doc->webkitCurrentFullScreenElement() == this)
2789         return false;
2790 #endif
2791
2792     if (isInShadowTree())
2793         return false;
2794
2795     if (!cachedStyle)
2796         cachedStyle = styleForRenderer();
2797     if (!cachedStyle)
2798         return false;
2799
2800     if (cachedStyle->flowThread().isEmpty())
2801         return false;
2802
2803     return !document()->renderView()->flowThreadController()->isContentNodeRegisteredWithAnyNamedFlow(this);
2804 }
2805
2806 #if ENABLE(CSS_REGIONS)
2807
2808 const AtomicString& Element::webkitRegionOverset() const
2809 {
2810     document()->updateLayoutIgnorePendingStylesheets();
2811
2812     DEFINE_STATIC_LOCAL(AtomicString, undefinedState, ("undefined", AtomicString::ConstructFromLiteral));
2813     if (!document()->cssRegionsEnabled() || !renderRegion())
2814         return undefinedState;
2815
2816     switch (renderRegion()->regionOversetState()) {
2817     case RegionFit: {
2818         DEFINE_STATIC_LOCAL(AtomicString, fitState, ("fit", AtomicString::ConstructFromLiteral));
2819         return fitState;
2820     }
2821     case RegionEmpty: {
2822         DEFINE_STATIC_LOCAL(AtomicString, emptyState, ("empty", AtomicString::ConstructFromLiteral));
2823         return emptyState;
2824     }
2825     case RegionOverset: {
2826         DEFINE_STATIC_LOCAL(AtomicString, overflowState, ("overset", AtomicString::ConstructFromLiteral));
2827         return overflowState;
2828     }
2829     case RegionUndefined:
2830         return undefinedState;
2831     }
2832
2833     ASSERT_NOT_REACHED();
2834     return undefinedState;
2835 }
2836
2837 Vector<RefPtr<Range> > Element::webkitGetRegionFlowRanges() const
2838 {
2839     document()->updateLayoutIgnorePendingStylesheets();
2840
2841     Vector<RefPtr<Range> > rangeObjects;
2842     if (document()->cssRegionsEnabled() && renderer() && renderer()->isRenderRegion()) {
2843         RenderRegion* region = toRenderRegion(renderer());
2844         if (region->isValid())
2845             region->getRanges(rangeObjects);
2846     }
2847
2848     return rangeObjects;
2849 }
2850
2851 #endif
2852
2853 #ifndef NDEBUG
2854 bool Element::fastAttributeLookupAllowed(const QualifiedName& name) const
2855 {
2856     if (name == HTMLNames::styleAttr)
2857         return false;
2858
2859 #if ENABLE(SVG)
2860     if (isSVGElement())
2861         return !static_cast<const SVGElement*>(this)->isAnimatableAttribute(name);
2862 #endif
2863
2864     return true;
2865 }
2866 #endif
2867
2868 #ifdef DUMP_NODE_STATISTICS
2869 bool Element::hasNamedNodeMap() const
2870 {
2871     return hasRareData() && elementRareData()->attributeMap();
2872 }
2873 #endif
2874
2875 inline void Element::updateName(const AtomicString& oldName, const AtomicString& newName)
2876 {
2877     if (!isInTreeScope())
2878         return;
2879
2880     if (oldName == newName)
2881         return;
2882
2883     updateNameForTreeScope(treeScope(), oldName, newName);
2884
2885     if (!inDocument())
2886         return;
2887     Document* htmlDocument = document();
2888     if (!htmlDocument->isHTMLDocument())
2889         return;
2890     updateNameForDocument(toHTMLDocument(htmlDocument), oldName, newName);
2891 }
2892
2893 void Element::updateNameForTreeScope(TreeScope* scope, const AtomicString& oldName, const AtomicString& newName)
2894 {
2895     ASSERT(isInTreeScope());
2896     ASSERT(oldName != newName);
2897
2898     if (!oldName.isEmpty())
2899         scope->removeElementByName(oldName, this);
2900     if (!newName.isEmpty())
2901         scope->addElementByName(newName, this);
2902 }
2903
2904 void Element::updateNameForDocument(HTMLDocument* document, const AtomicString& oldName, const AtomicString& newName)
2905 {
2906     ASSERT(inDocument());
2907     ASSERT(oldName != newName);
2908
2909     if (WindowNameCollection::nodeMatchesIfNameAttributeMatch(this)) {
2910         const AtomicString& id = WindowNameCollection::nodeMatchesIfIdAttributeMatch(this) ? getIdAttribute() : nullAtom;
2911         if (!oldName.isEmpty() && oldName != id)
2912             document->windowNamedItemMap().remove(oldName.impl(), this);
2913         if (!newName.isEmpty() && newName != id)
2914             document->windowNamedItemMap().add(newName.impl(), this);
2915     }
2916
2917     if (DocumentNameCollection::nodeMatchesIfNameAttributeMatch(this)) {
2918         const AtomicString& id = DocumentNameCollection::nodeMatchesIfIdAttributeMatch(this) ? getIdAttribute() : nullAtom;
2919         if (!oldName.isEmpty() && oldName != id)
2920             document->documentNamedItemMap().remove(oldName.impl(), this);
2921         if (!newName.isEmpty() && newName != id)
2922             document->documentNamedItemMap().add(newName.impl(), this);
2923     }
2924 }
2925
2926 inline void Element::updateId(const AtomicString& oldId, const AtomicString& newId)
2927 {
2928     if (!isInTreeScope())
2929         return;
2930
2931     if (oldId == newId)
2932         return;
2933
2934     updateIdForTreeScope(treeScope(), oldId, newId);
2935
2936     if (!inDocument())
2937         return;
2938     Document* htmlDocument = document();
2939     if (!htmlDocument->isHTMLDocument())
2940         return;
2941     updateIdForDocument(toHTMLDocument(htmlDocument), oldId, newId, UpdateHTMLDocumentNamedItemMapsOnlyIfDiffersFromNameAttribute);
2942 }
2943
2944 void Element::updateIdForTreeScope(TreeScope* scope, const AtomicString& oldId, const AtomicString& newId)
2945 {
2946     ASSERT(isInTreeScope());
2947     ASSERT(oldId != newId);
2948
2949     if (!oldId.isEmpty())
2950         scope->removeElementById(oldId, this);
2951     if (!newId.isEmpty())
2952         scope->addElementById(newId, this);
2953 }
2954
2955 void Element::updateIdForDocument(HTMLDocument* document, const AtomicString& oldId, const AtomicString& newId, HTMLDocumentNamedItemMapsUpdatingCondition condition)
2956 {
2957     ASSERT(inDocument());
2958     ASSERT(oldId != newId);
2959
2960     if (WindowNameCollection::nodeMatchesIfIdAttributeMatch(this)) {
2961         const AtomicString& name = condition == UpdateHTMLDocumentNamedItemMapsOnlyIfDiffersFromNameAttribute && WindowNameCollection::nodeMatchesIfNameAttributeMatch(this) ? getNameAttribute() : nullAtom;
2962         if (!oldId.isEmpty() && oldId != name)
2963             document->windowNamedItemMap().remove(oldId.impl(), this);
2964         if (!newId.isEmpty() && newId != name)
2965             document->windowNamedItemMap().add(newId.impl(), this);
2966     }
2967
2968     if (DocumentNameCollection::nodeMatchesIfIdAttributeMatch(this)) {
2969         const AtomicString& name = condition == UpdateHTMLDocumentNamedItemMapsOnlyIfDiffersFromNameAttribute && DocumentNameCollection::nodeMatchesIfNameAttributeMatch(this) ? getNameAttribute() : nullAtom;
2970         if (!oldId.isEmpty() && oldId != name)
2971             document->documentNamedItemMap().remove(oldId.impl(), this);
2972         if (!newId.isEmpty() && newId != name)
2973             document->documentNamedItemMap().add(newId.impl(), this);
2974     }
2975 }
2976
2977 void Element::updateLabel(TreeScope* scope, const AtomicString& oldForAttributeValue, const AtomicString& newForAttributeValue)
2978 {
2979     ASSERT(hasTagName(labelTag));
2980
2981     if (!inDocument())
2982         return;
2983
2984     if (oldForAttributeValue == newForAttributeValue)
2985         return;
2986
2987     if (!oldForAttributeValue.isEmpty())
2988         scope->removeLabel(oldForAttributeValue, static_cast<HTMLLabelElement*>(this));
2989     if (!newForAttributeValue.isEmpty())
2990         scope->addLabel(newForAttributeValue, static_cast<HTMLLabelElement*>(this));
2991 }
2992
2993 void Element::willModifyAttribute(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue)
2994 {
2995     if (isIdAttributeName(name))
2996         updateId(oldValue, newValue);
2997     else if (name == HTMLNames::nameAttr)
2998         updateName(oldValue, newValue);
2999     else if (name == HTMLNames::forAttr && hasTagName(labelTag)) {
3000         TreeScope* scope = treeScope();
3001         if (scope->shouldCacheLabelsByForAttribute())
3002             updateLabel(scope, oldValue, newValue);
3003     }
3004
3005     if (oldValue != newValue) {
3006         if (attached() && document()->styleResolverIfExists() && document()->styleResolverIfExists()->hasSelectorForAttribute(name.localName()))
3007             setNeedsStyleRecalc();
3008     }
3009
3010     if (OwnPtr<MutationObserverInterestGroup> recipients = MutationObserverInterestGroup::createForAttributesMutation(this, name))
3011         recipients->enqueueMutationRecord(MutationRecord::createAttributes(this, name, oldValue));
3012
3013 #if ENABLE(INSPECTOR)
3014     InspectorInstrumentation::willModifyDOMAttr(document(), this, oldValue, newValue);
3015 #endif
3016 }
3017
3018 void Element::didAddAttribute(const QualifiedName& name, const AtomicString& value)
3019 {
3020     attributeChanged(name, value);
3021     InspectorInstrumentation::didModifyDOMAttr(document(), this, name.localName(), value);
3022     dispatchSubtreeModifiedEvent();
3023 }
3024
3025 void Element::didModifyAttribute(const QualifiedName& name, const AtomicString& value)
3026 {
3027     attributeChanged(name, value);
3028     InspectorInstrumentation::didModifyDOMAttr(document(), this, name.localName(), value);
3029     // Do not dispatch a DOMSubtreeModified event here; see bug 81141.
3030 }
3031
3032 void Element::didRemoveAttribute(const QualifiedName& name)
3033 {
3034     attributeChanged(name, nullAtom);
3035     InspectorInstrumentation::didRemoveDOMAttr(document(), this, name.localName());
3036     dispatchSubtreeModifiedEvent();
3037 }
3038
3039 PassRefPtr<HTMLCollection> Element::ensureCachedHTMLCollection(CollectionType type)
3040 {
3041     if (HTMLCollection* collection = cachedHTMLCollection(type))
3042         return collection;
3043
3044     RefPtr<HTMLCollection> collection;
3045     if (type == TableRows) {
3046         ASSERT(hasTagName(tableTag));
3047         return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLTableRowsCollection>(this, type);
3048     } else if (type == SelectOptions) {
3049         ASSERT(hasTagName(selectTag));
3050         return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLOptionsCollection>(this, type);
3051     } else if (type == FormControls) {
3052         ASSERT(hasTagName(formTag) || hasTagName(fieldsetTag));
3053         return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLFormControlsCollection>(this, type);
3054 #if ENABLE(MICRODATA)
3055     } else if (type == ItemProperties) {
3056         return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLPropertiesCollection>(this, type);
3057 #endif
3058     }
3059     return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLCollection>(this, type);
3060 }
3061
3062 HTMLCollection* Element::cachedHTMLCollection(CollectionType type)
3063 {
3064     return hasRareData() && rareData()->nodeLists() ? rareData()->nodeLists()->cacheWithAtomicName<HTMLCollection>(type) : 0;
3065 }
3066
3067 IntSize Element::savedLayerScrollOffset() const
3068 {
3069     return hasRareData() ? elementRareData()->savedLayerScrollOffset() : IntSize();
3070 }
3071
3072 void Element::setSavedLayerScrollOffset(const IntSize& size)
3073 {
3074     if (size.isZero() && !hasRareData())
3075         return;
3076     ensureElementRareData()->setSavedLayerScrollOffset(size);
3077 }
3078
3079 PassRefPtr<Attr> Element::attrIfExists(const QualifiedName& name)
3080 {
3081     if (AttrNodeList* attrNodeList = attrNodeListForElement(this))
3082         return findAttrNodeInList(attrNodeList, name);
3083     return 0;
3084 }
3085
3086 PassRefPtr<Attr> Element::ensureAttr(const QualifiedName& name)
3087 {
3088     AttrNodeList* attrNodeList = ensureAttrNodeListForElement(this);
3089     RefPtr<Attr> attrNode = findAttrNodeInList(attrNodeList, name);
3090     if (!attrNode) {
3091         attrNode = Attr::create(this, name);
3092         treeScope()->adoptIfNeeded(attrNode.get());
3093         attrNodeList->append(attrNode);
3094     }
3095     return attrNode.release();
3096 }
3097
3098 void Element::detachAttrNodeFromElementWithValue(Attr* attrNode, const AtomicString& value)
3099 {
3100     ASSERT(hasSyntheticAttrChildNodes());
3101     attrNode->detachFromElementWithValue(value);
3102
3103     AttrNodeList* attrNodeList = attrNodeListForElement(this);
3104     for (unsigned i = 0; i < attrNodeList->size(); ++i) {
3105         if (attrNodeList->at(i)->qualifiedName() == attrNode->qualifiedName()) {
3106             attrNodeList->remove(i);
3107             if (attrNodeList->isEmpty())
3108                 removeAttrNodeListForElement(this);
3109             return;
3110         }
3111     }
3112     ASSERT_NOT_REACHED();
3113 }
3114
3115 void Element::detachAllAttrNodesFromElement()
3116 {
3117     AttrNodeList* attrNodeList = attrNodeListForElement(this);
3118     ASSERT(attrNodeList);
3119
3120     for (unsigned i = 0; i < attributeCount(); ++i) {
3121         const Attribute* attribute = attributeItem(i);
3122         if (RefPtr<Attr> attrNode = findAttrNodeInList(attrNodeList, attribute->name()))
3123             attrNode->detachFromElementWithValue(attribute->value());
3124     }
3125
3126     removeAttrNodeListForElement(this);
3127 }
3128
3129 bool Element::willRecalcStyle(StyleChange)
3130 {
3131     ASSERT(hasCustomStyleCallbacks());
3132     return true;
3133 }
3134
3135 void Element::didRecalcStyle(StyleChange)
3136 {
3137     ASSERT(hasCustomStyleCallbacks());
3138 }
3139
3140
3141 PassRefPtr<RenderStyle> Element::customStyleForRenderer()
3142 {
3143     ASSERT(hasCustomStyleCallbacks());
3144     return 0;
3145 }
3146
3147 void Element::cloneAttributesFromElement(const Element& other)
3148 {
3149     if (hasSyntheticAttrChildNodes())
3150         detachAllAttrNodesFromElement();
3151
3152     other.synchronizeAllAttributes();
3153     if (!other.m_elementData) {
3154         m_elementData.clear();
3155         return;
3156     }
3157
3158     // We can't update window and document's named item maps since the presence of image and object elements depend on other attributes and children.
3159     // Fortunately, those named item maps are only updated when this element is in the document, which should never be the case.
3160     ASSERT(!inDocument());
3161
3162     const AtomicString& oldID = getIdAttribute();
3163     const AtomicString& newID = other.getIdAttribute();
3164
3165     if (!oldID.isNull() || !newID.isNull())
3166         updateId(oldID, newID);
3167
3168     const AtomicString& oldName = getNameAttribute();
3169     const AtomicString& newName = other.getNameAttribute();
3170
3171     if (!oldName.isNull() || !newName.isNull())
3172         updateName(oldName, newName);
3173
3174     // If 'other' has a mutable ElementData, convert it to an immutable one so we can share it between both elements.
3175     // We can only do this if there is no CSSOM wrapper for other's inline style, and there are no presentation attributes.
3176     if (other.m_elementData->isUnique()
3177         && !other.m_elementData->presentationAttributeStyle()
3178         && (!other.m_elementData->inlineStyle() || !other.m_elementData->inlineStyle()->hasCSSOMWrapper()))
3179         const_cast<Element&>(other).m_elementData = static_cast<const UniqueElementData*>(other.m_elementData.get())->makeShareableCopy();
3180
3181     if (!other.m_elementData->isUnique())
3182         m_elementData = other.m_elementData;
3183     else
3184         m_elementData = other.m_elementData->makeUniqueCopy();
3185
3186     for (unsigned i = 0; i < m_elementData->length(); ++i) {
3187         const Attribute* attribute = const_cast<const ElementData*>(m_elementData.get())->attributeItem(i);
3188         attributeChangedFromParserOrByCloning(attribute->name(), attribute->value(), ModifiedByCloning);
3189     }
3190 }
3191
3192 void Element::cloneDataFromElement(const Element& other)
3193 {
3194     cloneAttributesFromElement(other);
3195     copyNonAttributePropertiesFromElement(other);
3196 }
3197
3198 void Element::createUniqueElementData()
3199 {
3200     if (!m_elementData)
3201         m_elementData = UniqueElementData::create();
3202     else {
3203         ASSERT(!m_elementData->isUnique());
3204         m_elementData = static_cast<ShareableElementData*>(m_elementData.get())->makeUniqueCopy();
3205     }
3206 }
3207
3208 #if ENABLE(SVG)
3209 bool Element::hasPendingResources() const
3210 {
3211     return hasRareData() && elementRareData()->hasPendingResources();
3212 }
3213
3214 void Element::setHasPendingResources()
3215 {
3216     ensureElementRareData()->setHasPendingResources(true);
3217 }
3218
3219 void Element::clearHasPendingResources()
3220 {
3221     ensureElementRareData()->setHasPendingResources(false);
3222 }
3223 #endif
3224
3225 void ElementData::deref()
3226 {
3227     if (!derefBase())
3228         return;
3229
3230     if (m_isUnique)
3231         delete static_cast<UniqueElementData*>(this);
3232     else
3233         delete static_cast<ShareableElementData*>(this);
3234 }
3235
3236 ElementData::ElementData()
3237     : m_isUnique(true)
3238     , m_arraySize(0)
3239     , m_hasNameAttribute(false)
3240     , m_presentationAttributeStyleIsDirty(false)
3241     , m_styleAttributeIsDirty(false)
3242 #if ENABLE(SVG)
3243     , m_animatedSVGAttributesAreDirty(false)
3244 #endif
3245 {
3246 }
3247
3248 ElementData::ElementData(unsigned arraySize)
3249     : m_isUnique(false)
3250     , m_arraySize(arraySize)
3251     , m_hasNameAttribute(false)
3252     , m_presentationAttributeStyleIsDirty(false)
3253     , m_styleAttributeIsDirty(false)
3254 #if ENABLE(SVG)
3255     , m_animatedSVGAttributesAreDirty(false)
3256 #endif
3257 {
3258 }
3259
3260 struct SameSizeAsElementData : public RefCounted<SameSizeAsElementData> {
3261     unsigned bitfield;
3262     void* refPtrs[3];
3263 };
3264
3265 COMPILE_ASSERT(sizeof(ElementData) == sizeof(SameSizeAsElementData), element_attribute_data_should_stay_small);
3266
3267 static size_t sizeForShareableElementDataWithAttributeCount(unsigned count)
3268 {
3269     return sizeof(ShareableElementData) + sizeof(Attribute) * count;
3270 }
3271
3272 PassRefPtr<ShareableElementData> ShareableElementData::createWithAttributes(const Vector<Attribute>& attributes)
3273 {
3274     void* slot = WTF::fastMalloc(sizeForShareableElementDataWithAttributeCount(attributes.size()));
3275     return adoptRef(new (NotNull, slot) ShareableElementData(attributes));
3276 }
3277
3278 PassRefPtr<UniqueElementData> UniqueElementData::create()
3279 {
3280     return adoptRef(new UniqueElementData);
3281 }
3282
3283 ShareableElementData::ShareableElementData(const Vector<Attribute>& attributes)
3284     : ElementData(attributes.size())
3285 {
3286     for (unsigned i = 0; i < m_arraySize; ++i)
3287         new (NotNull, &m_attributeArray[i]) Attribute(attributes[i]);
3288 }
3289
3290 ShareableElementData::~ShareableElementData()
3291 {
3292     for (unsigned i = 0; i < m_arraySize; ++i)
3293         m_attributeArray[i].~Attribute();
3294 }
3295
3296 ShareableElementData::ShareableElementData(const UniqueElementData& other)
3297     : ElementData(other, false)
3298 {
3299     ASSERT(!other.m_presentationAttributeStyle);
3300
3301     if (other.m_inlineStyle) {
3302         ASSERT(!other.m_inlineStyle->hasCSSOMWrapper());
3303         m_inlineStyle = other.m_inlineStyle->immutableCopyIfNeeded();
3304     }
3305
3306     for (unsigned i = 0; i < m_arraySize; ++i)
3307         new (NotNull, &m_attributeArray[i]) Attribute(other.m_attributeVector.at(i));
3308 }
3309
3310 ElementData::ElementData(const ElementData& other, bool isUnique)
3311     : m_isUnique(isUnique)
3312     , m_arraySize(isUnique ? 0 : other.length())
3313     , m_hasNameAttribute(other.m_hasNameAttribute)
3314     , m_presentationAttributeStyleIsDirty(other.m_presentationAttributeStyleIsDirty)
3315     , m_styleAttributeIsDirty(other.m_styleAttributeIsDirty)
3316 #if ENABLE(SVG)
3317     , m_animatedSVGAttributesAreDirty(other.m_animatedSVGAttributesAreDirty)
3318 #endif
3319     , m_classNames(other.m_classNames)
3320     , m_idForStyleResolution(other.m_idForStyleResolution)
3321 {
3322     // NOTE: The inline style is copied by the subclass copy constructor since we don't know what to do with it here.
3323 }
3324
3325 UniqueElementData::UniqueElementData()
3326 {
3327 }
3328
3329 UniqueElementData::UniqueElementData(const UniqueElementData& other)
3330     : ElementData(other, true)
3331     , m_presentationAttributeStyle(other.m_presentationAttributeStyle)
3332     , m_attributeVector(other.m_attributeVector)
3333 {
3334     m_inlineStyle = other.m_inlineStyle ? other.m_inlineStyle->mutableCopy() : 0;
3335 }
3336
3337 UniqueElementData::UniqueElementData(const ShareableElementData& other)
3338     : ElementData(other, true)
3339 {
3340     // An ShareableElementData should never have a mutable inline StylePropertySet attached.
3341     ASSERT(!other.m_inlineStyle || !other.m_inlineStyle->isMutable());
3342     m_inlineStyle = other.m_inlineStyle;
3343
3344     m_attributeVector.reserveCapacity(other.length());
3345     for (unsigned i = 0; i < other.length(); ++i)
3346         m_attributeVector.uncheckedAppend(other.m_attributeArray[i]);
3347 }
3348
3349 PassRefPtr<UniqueElementData> ElementData::makeUniqueCopy() const
3350 {
3351     if (isUnique())
3352         return adoptRef(new UniqueElementData(static_cast<const UniqueElementData&>(*this)));
3353     return adoptRef(new UniqueElementData(static_cast<const ShareableElementData&>(*this)));
3354 }
3355
3356 PassRefPtr<ShareableElementData> UniqueElementData::makeShareableCopy() const
3357 {
3358     void* slot = WTF::fastMalloc(sizeForShareableElementDataWithAttributeCount(m_attributeVector.size()));
3359     return adoptRef(new (NotNull, slot) ShareableElementData(*this));
3360 }
3361
3362 void UniqueElementData::addAttribute(const QualifiedName& attributeName, const AtomicString& value)
3363 {
3364     m_attributeVector.append(Attribute(attributeName, value));
3365 }
3366
3367 void UniqueElementData::removeAttribute(unsigned index)
3368 {
3369     ASSERT_WITH_SECURITY_IMPLICATION(index < length());
3370     m_attributeVector.remove(index);
3371 }
3372
3373 bool ElementData::isEquivalent(const ElementData* other) const
3374 {
3375     if (!other)
3376         return isEmpty();
3377
3378     unsigned len = length();
3379     if (len != other->length())
3380         return false;
3381
3382     for (unsigned i = 0; i < len; i++) {
3383         const Attribute* attribute = attributeItem(i);
3384         const Attribute* otherAttr = other->getAttributeItem(attribute->name());
3385         if (!otherAttr || attribute->value() != otherAttr->value())
3386             return false;
3387     }
3388
3389     return true;
3390 }
3391
3392 unsigned ElementData::getAttributeItemIndexSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const
3393 {
3394     // Continue to checking case-insensitively and/or full namespaced names if necessary:
3395     for (unsigned i = 0; i < length(); ++i) {
3396         const Attribute* attribute = attributeItem(i);
3397         if (!attribute->name().hasPrefix()) {
3398             if (shouldIgnoreAttributeCase && equalIgnoringCase(name, attribute->localName()))
3399                 return i;
3400         } else {
3401             // FIXME: Would be faster to do this comparison without calling toString, which
3402             // generates a temporary string by concatenation. But this branch is only reached
3403             // if the attribute name has a prefix, which is rare in HTML.
3404             if (equalPossiblyIgnoringCase(name, attribute->name().toString(), shouldIgnoreAttributeCase))
3405                 return i;
3406         }
3407     }
3408     return attributeNotFound;
3409 }
3410
3411 unsigned ElementData::getAttributeItemIndexForAttributeNode(const Attr* attr) const
3412 {
3413     ASSERT(attr);
3414     const Attribute* attributes = attributeBase();
3415     unsigned count = length();
3416     for (unsigned i = 0; i < count; ++i) {
3417         if (attributes[i].name() == attr->qualifiedName())
3418             return i;
3419     }
3420     return attributeNotFound;
3421 }
3422
3423 Attribute* UniqueElementData::getAttributeItem(const QualifiedName& name)
3424 {
3425     unsigned count = length();
3426     for (unsigned i = 0; i < count; ++i) {
3427         if (m_attributeVector.at(i).name().matches(name))
3428             return &m_attributeVector.at(i);
3429     }
3430     return 0;
3431 }
3432
3433 Attribute* UniqueElementData::attributeItem(unsigned index)
3434 {
3435     ASSERT_WITH_SECURITY_IMPLICATION(index < length());
3436     return &m_attributeVector.at(index);
3437 }
3438
3439 } // namespace WebCore