Set Attr.ownerDocument in Element#setAttributeNode()
[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     treeScope()->adoptIfNeeded(attrNode);
1938     ensureAttrNodeListForElement(this)->append(attrNode);
1939
1940     return oldAttrNode.release();
1941 }
1942
1943 PassRefPtr<Attr> Element::setAttributeNodeNS(Attr* attr, ExceptionCode& ec)
1944 {
1945     return setAttributeNode(attr, ec);
1946 }
1947
1948 PassRefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionCode& ec)
1949 {
1950     if (!attr) {
1951         ec = TYPE_MISMATCH_ERR;
1952         return 0;
1953     }
1954     if (attr->ownerElement() != this) {
1955         ec = NOT_FOUND_ERR;
1956         return 0;
1957     }
1958
1959     ASSERT(document() == attr->document());
1960
1961     synchronizeAttribute(attr->qualifiedName());
1962
1963     unsigned index = elementData()->getAttributeItemIndexForAttributeNode(attr);
1964     if (index == ElementData::attributeNotFound) {
1965         ec = NOT_FOUND_ERR;
1966         return 0;
1967     }
1968
1969     RefPtr<Attr> attrNode = attr;
1970     detachAttrNodeFromElementWithValue(attr, elementData()->attributeItem(index)->value());
1971     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
1972     return attrNode.release();
1973 }
1974
1975 bool Element::parseAttributeName(QualifiedName& out, const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionCode& ec)
1976 {
1977     String prefix, localName;
1978     if (!Document::parseQualifiedName(qualifiedName, prefix, localName, ec))
1979         return false;
1980     ASSERT(!ec);
1981
1982     QualifiedName qName(prefix, localName, namespaceURI);
1983
1984     if (!Document::hasValidNamespaceForAttributes(qName)) {
1985         ec = NAMESPACE_ERR;
1986         return false;
1987     }
1988
1989     out = qName;
1990     return true;
1991 }
1992
1993 void Element::setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode& ec)
1994 {
1995     QualifiedName parsedName = anyName;
1996     if (!parseAttributeName(parsedName, namespaceURI, qualifiedName, ec))
1997         return;
1998     setAttribute(parsedName, value);
1999 }
2000
2001 void Element::removeAttributeInternal(unsigned index, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
2002 {
2003     ASSERT_WITH_SECURITY_IMPLICATION(index < attributeCount());
2004
2005     UniqueElementData* elementData = ensureUniqueElementData();
2006
2007     QualifiedName name = elementData->attributeItem(index)->name();
2008     AtomicString valueBeingRemoved = elementData->attributeItem(index)->value();
2009
2010     if (!inSynchronizationOfLazyAttribute) {
2011         if (!valueBeingRemoved.isNull())
2012             willModifyAttribute(name, valueBeingRemoved, nullAtom);
2013     }
2014
2015     if (RefPtr<Attr> attrNode = attrIfExists(name))
2016         detachAttrNodeFromElementWithValue(attrNode.get(), elementData->attributeItem(index)->value());
2017
2018     elementData->removeAttribute(index);
2019
2020     if (!inSynchronizationOfLazyAttribute)
2021         didRemoveAttribute(name);
2022 }
2023
2024 void Element::addAttributeInternal(const QualifiedName& name, const AtomicString& value, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
2025 {
2026     if (!inSynchronizationOfLazyAttribute)
2027         willModifyAttribute(name, nullAtom, value);
2028     ensureUniqueElementData()->addAttribute(name, value);
2029     if (!inSynchronizationOfLazyAttribute)
2030         didAddAttribute(name, value);
2031 }
2032
2033 void Element::removeAttribute(const AtomicString& name)
2034 {
2035     if (!elementData())
2036         return;
2037
2038     AtomicString localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
2039     unsigned index = elementData()->getAttributeItemIndex(localName, false);
2040     if (index == ElementData::attributeNotFound) {
2041         if (UNLIKELY(localName == styleAttr) && elementData()->m_styleAttributeIsDirty && isStyledElement())
2042             static_cast<StyledElement*>(this)->removeAllInlineStyleProperties();
2043         return;
2044     }
2045
2046     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
2047 }
2048
2049 void Element::removeAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName)
2050 {
2051     removeAttribute(QualifiedName(nullAtom, localName, namespaceURI));
2052 }
2053
2054 PassRefPtr<Attr> Element::getAttributeNode(const AtomicString& localName)
2055 {
2056     if (!elementData())
2057         return 0;
2058     synchronizeAttribute(localName);
2059     const Attribute* attribute = elementData()->getAttributeItem(localName, shouldIgnoreAttributeCase(this));
2060     if (!attribute)
2061         return 0;
2062     return ensureAttr(attribute->name());
2063 }
2064
2065 PassRefPtr<Attr> Element::getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName)
2066 {
2067     if (!elementData())
2068         return 0;
2069     QualifiedName qName(nullAtom, localName, namespaceURI);
2070     synchronizeAttribute(qName);
2071     const Attribute* attribute = elementData()->getAttributeItem(qName);
2072     if (!attribute)
2073         return 0;
2074     return ensureAttr(attribute->name());
2075 }
2076
2077 bool Element::hasAttribute(const AtomicString& localName) const
2078 {
2079     if (!elementData())
2080         return false;
2081     synchronizeAttribute(localName);
2082     return elementData()->getAttributeItem(shouldIgnoreAttributeCase(this) ? localName.lower() : localName, false);
2083 }
2084
2085 bool Element::hasAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const
2086 {
2087     if (!elementData())
2088         return false;
2089     QualifiedName qName(nullAtom, localName, namespaceURI);
2090     synchronizeAttribute(qName);
2091     return elementData()->getAttributeItem(qName);
2092 }
2093
2094 CSSStyleDeclaration *Element::style()
2095 {
2096     return 0;
2097 }
2098
2099 void Element::focus(bool restorePreviousSelection, FocusDirection direction)
2100 {
2101     if (!inDocument())
2102         return;
2103
2104     Document* doc = document();
2105     if (doc->focusedElement() == this)
2106         return;
2107
2108     // If the stylesheets have already been loaded we can reliably check isFocusable.
2109     // If not, we continue and set the focused node on the focus controller below so
2110     // that it can be updated soon after attach. 
2111     if (doc->haveStylesheetsLoaded()) {
2112         doc->updateLayoutIgnorePendingStylesheets();
2113         if (!isFocusable())
2114             return;
2115     }
2116
2117     if (!supportsFocus())
2118         return;
2119
2120     RefPtr<Node> protect;
2121     if (Page* page = doc->page()) {
2122         // Focus and change event handlers can cause us to lose our last ref.
2123         // If a focus event handler changes the focus to a different node it
2124         // does not make sense to continue and update appearence.
2125         protect = this;
2126         if (!page->focusController()->setFocusedElement(this, doc->frame(), direction))
2127             return;
2128     }
2129
2130     // Setting the focused node above might have invalidated the layout due to scripts.
2131     doc->updateLayoutIgnorePendingStylesheets();
2132
2133     if (!isFocusable()) {
2134         ensureElementRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(true);
2135         return;
2136     }
2137         
2138     cancelFocusAppearanceUpdate();
2139     updateFocusAppearance(restorePreviousSelection);
2140 }
2141
2142 void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
2143 {
2144     if (isRootEditableElement()) {
2145         Frame* frame = document()->frame();
2146         if (!frame)
2147             return;
2148         
2149         // When focusing an editable element in an iframe, don't reset the selection if it already contains a selection.
2150         if (this == frame->selection()->rootEditableElement())
2151             return;
2152
2153         // FIXME: We should restore the previous selection if there is one.
2154         VisibleSelection newSelection = VisibleSelection(firstPositionInOrBeforeNode(this), DOWNSTREAM);
2155         
2156         if (frame->selection()->shouldChangeSelection(newSelection)) {
2157             frame->selection()->setSelection(newSelection);
2158             frame->selection()->revealSelection();
2159         }
2160     } else if (renderer() && !renderer()->isWidget())
2161         renderer()->scrollRectToVisible(boundingBox());
2162 }
2163
2164 void Element::blur()
2165 {
2166     cancelFocusAppearanceUpdate();
2167     Document* doc = document();
2168     if (treeScope()->focusedElement() == this) {
2169         if (doc->frame())
2170             doc->frame()->page()->focusController()->setFocusedElement(0, doc->frame());
2171         else
2172             doc->setFocusedElement(0);
2173     }
2174 }
2175
2176 void Element::dispatchFocusInEvent(const AtomicString& eventType, PassRefPtr<Element> oldFocusedElement)
2177 {
2178     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
2179     ASSERT(eventType == eventNames().focusinEvent || eventType == eventNames().DOMFocusInEvent);
2180     dispatchScopedEventDispatchMediator(FocusInEventDispatchMediator::create(FocusEvent::create(eventType, true, false, document()->defaultView(), 0, oldFocusedElement)));
2181 }
2182
2183 void Element::dispatchFocusOutEvent(const AtomicString& eventType, PassRefPtr<Element> newFocusedElement)
2184 {
2185     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
2186     ASSERT(eventType == eventNames().focusoutEvent || eventType == eventNames().DOMFocusOutEvent);
2187     dispatchScopedEventDispatchMediator(FocusOutEventDispatchMediator::create(FocusEvent::create(eventType, true, false, document()->defaultView(), 0, newFocusedElement)));
2188 }
2189
2190 void Element::dispatchFocusEvent(PassRefPtr<Element> oldFocusedElement, FocusDirection)
2191 {
2192     if (document()->page())
2193         document()->page()->chrome().client()->elementDidFocus(this);
2194
2195     RefPtr<FocusEvent> event = FocusEvent::create(eventNames().focusEvent, false, false, document()->defaultView(), 0, oldFocusedElement);
2196     EventDispatcher::dispatchEvent(this, FocusEventDispatchMediator::create(event.release()));
2197 }
2198
2199 void Element::dispatchBlurEvent(PassRefPtr<Element> newFocusedElement)
2200 {
2201     if (document()->page())
2202         document()->page()->chrome().client()->elementDidBlur(this);
2203
2204     RefPtr<FocusEvent> event = FocusEvent::create(eventNames().blurEvent, false, false, document()->defaultView(), 0, newFocusedElement);
2205     EventDispatcher::dispatchEvent(this, BlurEventDispatchMediator::create(event.release()));
2206 }
2207
2208
2209 String Element::innerText()
2210 {
2211     // We need to update layout, since plainText uses line boxes in the render tree.
2212     document()->updateLayoutIgnorePendingStylesheets();
2213
2214     if (!renderer())
2215         return textContent(true);
2216
2217     return plainText(rangeOfContents(const_cast<Element*>(this)).get());
2218 }
2219
2220 String Element::outerText()
2221 {
2222     // Getting outerText is the same as getting innerText, only
2223     // setting is different. You would think this should get the plain
2224     // text for the outer range, but this is wrong, <br> for instance
2225     // would return different values for inner and outer text by such
2226     // a rule, but it doesn't in WinIE, and we want to match that.
2227     return innerText();
2228 }
2229
2230 String Element::title() const
2231 {
2232     return String();
2233 }
2234
2235 const AtomicString& Element::pseudo() const
2236 {
2237     return getAttribute(pseudoAttr);
2238 }
2239
2240 void Element::setPseudo(const AtomicString& value)
2241 {
2242     setAttribute(pseudoAttr, value);
2243 }
2244
2245 LayoutSize Element::minimumSizeForResizing() const
2246 {
2247     return hasRareData() ? elementRareData()->minimumSizeForResizing() : defaultMinimumSizeForResizing();
2248 }
2249
2250 void Element::setMinimumSizeForResizing(const LayoutSize& size)
2251 {
2252     if (!hasRareData() && size == defaultMinimumSizeForResizing())
2253         return;
2254     ensureElementRareData()->setMinimumSizeForResizing(size);
2255 }
2256
2257 RenderStyle* Element::computedStyle(PseudoId pseudoElementSpecifier)
2258 {
2259     if (PseudoElement* element = pseudoElement(pseudoElementSpecifier))
2260         return element->computedStyle();
2261
2262     // FIXME: Find and use the renderer from the pseudo element instead of the actual element so that the 'length'
2263     // properties, which are only known by the renderer because it did the layout, will be correct and so that the
2264     // values returned for the ":selection" pseudo-element will be correct.
2265     if (RenderStyle* usedStyle = renderStyle()) {
2266         if (pseudoElementSpecifier) {
2267             RenderStyle* cachedPseudoStyle = usedStyle->getCachedPseudoStyle(pseudoElementSpecifier);
2268             return cachedPseudoStyle ? cachedPseudoStyle : usedStyle;
2269          } else
2270             return usedStyle;
2271     }
2272
2273     if (!attached())
2274         // FIXME: Try to do better than this. Ensure that styleForElement() works for elements that are not in the
2275         // document tree and figure out when to destroy the computed style for such elements.
2276         return 0;
2277
2278     ElementRareData* data = ensureElementRareData();
2279     if (!data->computedStyle())
2280         data->setComputedStyle(document()->styleForElementIgnoringPendingStylesheets(this));
2281     return pseudoElementSpecifier ? data->computedStyle()->getCachedPseudoStyle(pseudoElementSpecifier) : data->computedStyle();
2282 }
2283
2284 void Element::setStyleAffectedByEmpty()
2285 {
2286     ensureElementRareData()->setStyleAffectedByEmpty(true);
2287 }
2288
2289 void Element::setChildrenAffectedByHover(bool value)
2290 {
2291     if (value || hasRareData())
2292         ensureElementRareData()->setChildrenAffectedByHover(value);
2293 }
2294
2295 void Element::setChildrenAffectedByActive(bool value)
2296 {
2297     if (value || hasRareData())
2298         ensureElementRareData()->setChildrenAffectedByActive(value);
2299 }
2300
2301 void Element::setChildrenAffectedByDrag(bool value)
2302 {
2303     if (value || hasRareData())
2304         ensureElementRareData()->setChildrenAffectedByDrag(value);
2305 }
2306
2307 void Element::setChildrenAffectedByFirstChildRules()
2308 {
2309     ensureElementRareData()->setChildrenAffectedByFirstChildRules(true);
2310 }
2311
2312 void Element::setChildrenAffectedByLastChildRules()
2313 {
2314     ensureElementRareData()->setChildrenAffectedByLastChildRules(true);
2315 }
2316
2317 void Element::setChildrenAffectedByDirectAdjacentRules()
2318 {
2319     ensureElementRareData()->setChildrenAffectedByDirectAdjacentRules(true);
2320 }
2321
2322 void Element::setChildrenAffectedByForwardPositionalRules()
2323 {
2324     ensureElementRareData()->setChildrenAffectedByForwardPositionalRules(true);
2325 }
2326
2327 void Element::setChildrenAffectedByBackwardPositionalRules()
2328 {
2329     ensureElementRareData()->setChildrenAffectedByBackwardPositionalRules(true);
2330 }
2331
2332 void Element::setChildIndex(unsigned index)
2333 {
2334     ElementRareData* rareData = ensureElementRareData();
2335     if (RenderStyle* style = renderStyle())
2336         style->setUnique();
2337     rareData->setChildIndex(index);
2338 }
2339
2340 bool Element::hasFlagsSetDuringStylingOfChildren() const
2341 {
2342     if (!hasRareData())
2343         return false;
2344     return rareDataChildrenAffectedByHover()
2345         || rareDataChildrenAffectedByActive()
2346         || rareDataChildrenAffectedByDrag()
2347         || rareDataChildrenAffectedByFirstChildRules()
2348         || rareDataChildrenAffectedByLastChildRules()
2349         || rareDataChildrenAffectedByDirectAdjacentRules()
2350         || rareDataChildrenAffectedByForwardPositionalRules()
2351         || rareDataChildrenAffectedByBackwardPositionalRules();
2352 }
2353
2354 bool Element::rareDataStyleAffectedByEmpty() const
2355 {
2356     ASSERT(hasRareData());
2357     return elementRareData()->styleAffectedByEmpty();
2358 }
2359
2360 bool Element::rareDataChildrenAffectedByHover() const
2361 {
2362     ASSERT(hasRareData());
2363     return elementRareData()->childrenAffectedByHover();
2364 }
2365
2366 bool Element::rareDataChildrenAffectedByActive() const
2367 {
2368     ASSERT(hasRareData());
2369     return elementRareData()->childrenAffectedByActive();
2370 }
2371
2372 bool Element::rareDataChildrenAffectedByDrag() const
2373 {
2374     ASSERT(hasRareData());
2375     return elementRareData()->childrenAffectedByDrag();
2376 }
2377
2378 bool Element::rareDataChildrenAffectedByFirstChildRules() const
2379 {
2380     ASSERT(hasRareData());
2381     return elementRareData()->childrenAffectedByFirstChildRules();
2382 }
2383
2384 bool Element::rareDataChildrenAffectedByLastChildRules() const
2385 {
2386     ASSERT(hasRareData());
2387     return elementRareData()->childrenAffectedByLastChildRules();
2388 }
2389
2390 bool Element::rareDataChildrenAffectedByDirectAdjacentRules() const
2391 {
2392     ASSERT(hasRareData());
2393     return elementRareData()->childrenAffectedByDirectAdjacentRules();
2394 }
2395
2396 bool Element::rareDataChildrenAffectedByForwardPositionalRules() const
2397 {
2398     ASSERT(hasRareData());
2399     return elementRareData()->childrenAffectedByForwardPositionalRules();
2400 }
2401
2402 bool Element::rareDataChildrenAffectedByBackwardPositionalRules() const
2403 {
2404     ASSERT(hasRareData());
2405     return elementRareData()->childrenAffectedByBackwardPositionalRules();
2406 }
2407
2408 unsigned Element::rareDataChildIndex() const
2409 {
2410     ASSERT(hasRareData());
2411     return elementRareData()->childIndex();
2412 }
2413
2414 void Element::setIsInCanvasSubtree(bool isInCanvasSubtree)
2415 {
2416     ensureElementRareData()->setIsInCanvasSubtree(isInCanvasSubtree);
2417 }
2418
2419 bool Element::isInCanvasSubtree() const
2420 {
2421     return hasRareData() && elementRareData()->isInCanvasSubtree();
2422 }
2423
2424 void Element::setRegionOversetState(RegionOversetState state)
2425 {
2426     ensureElementRareData()->setRegionOversetState(state);
2427 }
2428
2429 RegionOversetState Element::regionOversetState() const
2430 {
2431     return hasRareData() ? elementRareData()->regionOversetState() : RegionUndefined;
2432 }
2433
2434 AtomicString Element::computeInheritedLanguage() const
2435 {
2436     const Node* n = this;
2437     AtomicString value;
2438     // The language property is inherited, so we iterate over the parents to find the first language.
2439     do {
2440         if (n->isElementNode()) {
2441             if (const ElementData* elementData = toElement(n)->elementData()) {
2442                 // Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7
2443                 if (const Attribute* attribute = elementData->getAttributeItem(XMLNames::langAttr))
2444                     value = attribute->value();
2445                 else if (const Attribute* attribute = elementData->getAttributeItem(HTMLNames::langAttr))
2446                     value = attribute->value();
2447             }
2448         } else if (n->isDocumentNode()) {
2449             // checking the MIME content-language
2450             value = toDocument(n)->contentLanguage();
2451         }
2452
2453         n = n->parentNode();
2454     } while (n && value.isNull());
2455
2456     return value;
2457 }
2458
2459 Locale& Element::locale() const
2460 {
2461     return document()->getCachedLocale(computeInheritedLanguage());
2462 }
2463
2464 void Element::cancelFocusAppearanceUpdate()
2465 {
2466     if (hasRareData())
2467         elementRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
2468     if (document()->focusedElement() == this)
2469         document()->cancelFocusAppearanceUpdate();
2470 }
2471
2472 void Element::normalizeAttributes()
2473 {
2474     if (!hasAttributes())
2475         return;
2476     for (unsigned i = 0; i < attributeCount(); ++i) {
2477         if (RefPtr<Attr> attr = attrIfExists(attributeItem(i)->name()))
2478             attr->normalize();
2479     }
2480 }
2481
2482 void Element::updatePseudoElement(PseudoId pseudoId, StyleChange change)
2483 {
2484     PseudoElement* existing = pseudoElement(pseudoId);
2485     if (existing) {
2486         // PseudoElement styles hang off their parent element's style so if we needed
2487         // a style recalc we should Force one on the pseudo.
2488         existing->recalcStyle(needsStyleRecalc() ? Force : change);
2489
2490         // Wait until our parent is not displayed or pseudoElementRendererIsNeeded
2491         // is false, otherwise we could continously create and destroy PseudoElements
2492         // when RenderObject::isChildAllowed on our parent returns false for the
2493         // PseudoElement's renderer for each style recalc.
2494         if (!renderer() || !pseudoElementRendererIsNeeded(renderer()->getCachedPseudoStyle(pseudoId)))
2495             setPseudoElement(pseudoId, 0);
2496     } else if (RefPtr<PseudoElement> element = createPseudoElementIfNeeded(pseudoId)) {
2497         element->attach();
2498         setPseudoElement(pseudoId, element.release());
2499     }
2500 }
2501
2502 PassRefPtr<PseudoElement> Element::createPseudoElementIfNeeded(PseudoId pseudoId)
2503 {
2504     if (!document()->styleSheetCollection()->usesBeforeAfterRules())
2505         return 0;
2506
2507     if (!renderer() || !renderer()->canHaveGeneratedChildren())
2508         return 0;
2509
2510     if (isPseudoElement())
2511         return 0;
2512
2513     if (!pseudoElementRendererIsNeeded(renderer()->getCachedPseudoStyle(pseudoId)))
2514         return 0;
2515
2516     return PseudoElement::create(this, pseudoId);
2517 }
2518
2519 bool Element::hasPseudoElements() const
2520 {
2521     return hasRareData() && elementRareData()->hasPseudoElements();
2522 }
2523
2524 PseudoElement* Element::pseudoElement(PseudoId pseudoId) const
2525 {
2526     return hasRareData() ? elementRareData()->pseudoElement(pseudoId) : 0;
2527 }
2528
2529 void Element::setPseudoElement(PseudoId pseudoId, PassRefPtr<PseudoElement> element)
2530 {
2531     ensureElementRareData()->setPseudoElement(pseudoId, element);
2532     resetNeedsShadowTreeWalker();
2533 }
2534
2535 RenderObject* Element::pseudoElementRenderer(PseudoId pseudoId) const
2536 {
2537     if (PseudoElement* element = pseudoElement(pseudoId))
2538         return element->renderer();
2539     return 0;
2540 }
2541
2542 // ElementTraversal API
2543 Element* Element::firstElementChild() const
2544 {
2545     return ElementTraversal::firstWithin(this);
2546 }
2547
2548 Element* Element::lastElementChild() const
2549 {
2550     Node* n = lastChild();
2551     while (n && !n->isElementNode())
2552         n = n->previousSibling();
2553     return toElement(n);
2554 }
2555
2556 unsigned Element::childElementCount() const
2557 {
2558     unsigned count = 0;
2559     Node* n = firstChild();
2560     while (n) {
2561         count += n->isElementNode();
2562         n = n->nextSibling();
2563     }
2564     return count;
2565 }
2566
2567 bool Element::matchesReadOnlyPseudoClass() const
2568 {
2569     return false;
2570 }
2571
2572 bool Element::matchesReadWritePseudoClass() const
2573 {
2574     return false;
2575 }
2576
2577 bool Element::webkitMatchesSelector(const String& selector, ExceptionCode& ec)
2578 {
2579     if (selector.isEmpty()) {
2580         ec = SYNTAX_ERR;
2581         return false;
2582     }
2583
2584     SelectorQuery* selectorQuery = document()->selectorQueryCache()->add(selector, document(), ec);
2585     if (!selectorQuery)
2586         return false;
2587     return selectorQuery->matches(this);
2588 }
2589
2590 bool Element::shouldAppearIndeterminate() const
2591 {
2592     return false;
2593 }
2594
2595 DOMTokenList* Element::classList()
2596 {
2597     ElementRareData* data = ensureElementRareData();
2598     if (!data->classList())
2599         data->setClassList(ClassList::create(this));
2600     return data->classList();
2601 }
2602
2603 DOMStringMap* Element::dataset()
2604 {
2605     ElementRareData* data = ensureElementRareData();
2606     if (!data->dataset())
2607         data->setDataset(DatasetDOMStringMap::create(this));
2608     return data->dataset();
2609 }
2610
2611 KURL Element::getURLAttribute(const QualifiedName& name) const
2612 {
2613 #if !ASSERT_DISABLED
2614     if (elementData()) {
2615         if (const Attribute* attribute = getAttributeItem(name))
2616             ASSERT(isURLAttribute(*attribute));
2617     }
2618 #endif
2619     return document()->completeURL(stripLeadingAndTrailingHTMLSpaces(getAttribute(name)));
2620 }
2621
2622 KURL Element::getNonEmptyURLAttribute(const QualifiedName& name) const
2623 {
2624 #if !ASSERT_DISABLED
2625     if (elementData()) {
2626         if (const Attribute* attribute = getAttributeItem(name))
2627             ASSERT(isURLAttribute(*attribute));
2628     }
2629 #endif
2630     String value = stripLeadingAndTrailingHTMLSpaces(getAttribute(name));
2631     if (value.isEmpty())
2632         return KURL();
2633     return document()->completeURL(value);
2634 }
2635
2636 int Element::getIntegralAttribute(const QualifiedName& attributeName) const
2637 {
2638     return getAttribute(attributeName).string().toInt();
2639 }
2640
2641 void Element::setIntegralAttribute(const QualifiedName& attributeName, int value)
2642 {
2643     // FIXME: Need an AtomicString version of String::number.
2644     setAttribute(attributeName, String::number(value));
2645 }
2646
2647 unsigned Element::getUnsignedIntegralAttribute(const QualifiedName& attributeName) const
2648 {
2649     return getAttribute(attributeName).string().toUInt();
2650 }
2651
2652 void Element::setUnsignedIntegralAttribute(const QualifiedName& attributeName, unsigned value)
2653 {
2654     // FIXME: Need an AtomicString version of String::number.
2655     setAttribute(attributeName, String::number(value));
2656 }
2657
2658 #if ENABLE(INDIE_UI)
2659 void Element::setUIActions(const AtomicString& actions)
2660 {
2661     setAttribute(uiactionsAttr, actions);
2662 }
2663
2664 const AtomicString& Element::UIActions() const
2665 {
2666     return getAttribute(uiactionsAttr);
2667 }
2668 #endif
2669
2670     
2671 #if ENABLE(SVG)
2672 bool Element::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
2673 {
2674     // Only create renderers for SVG elements whose parents are SVG elements, or for proper <svg xmlns="svgNS"> subdocuments.
2675     if (childContext.node()->isSVGElement())
2676         return childContext.node()->hasTagName(SVGNames::svgTag) || isSVGElement();
2677
2678     return ContainerNode::childShouldCreateRenderer(childContext);
2679 }
2680 #endif
2681
2682 #if ENABLE(FULLSCREEN_API)
2683 void Element::webkitRequestFullscreen()
2684 {
2685     document()->requestFullScreenForElement(this, ALLOW_KEYBOARD_INPUT, Document::EnforceIFrameAllowFullScreenRequirement);
2686 }
2687
2688 void Element::webkitRequestFullScreen(unsigned short flags)
2689 {
2690     document()->requestFullScreenForElement(this, (flags | LEGACY_MOZILLA_REQUEST), Document::EnforceIFrameAllowFullScreenRequirement);
2691 }
2692
2693 bool Element::containsFullScreenElement() const
2694 {
2695     return hasRareData() && elementRareData()->containsFullScreenElement();
2696 }
2697
2698 void Element::setContainsFullScreenElement(bool flag)
2699 {
2700     ensureElementRareData()->setContainsFullScreenElement(flag);
2701     setNeedsStyleRecalc(SyntheticStyleChange);
2702 }
2703
2704 static Element* parentCrossingFrameBoundaries(Element* element)
2705 {
2706     ASSERT(element);
2707     return element->parentElement() ? element->parentElement() : element->document()->ownerElement();
2708 }
2709
2710 void Element::setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(bool flag)
2711 {
2712     Element* element = this;
2713     while ((element = parentCrossingFrameBoundaries(element)))
2714         element->setContainsFullScreenElement(flag);
2715 }
2716 #endif    
2717
2718 #if ENABLE(DIALOG_ELEMENT)
2719 bool Element::isInTopLayer() const
2720 {
2721     return hasRareData() && elementRareData()->isInTopLayer();
2722 }
2723
2724 void Element::setIsInTopLayer(bool inTopLayer)
2725 {
2726     if (isInTopLayer() == inTopLayer)
2727         return;
2728     ensureElementRareData()->setIsInTopLayer(inTopLayer);
2729
2730     // We must ensure a reattach occurs so the renderer is inserted in the correct sibling order under RenderView according to its
2731     // top layer position, or in its usual place if not in the top layer.
2732     reattachIfAttached();
2733 }
2734 #endif
2735
2736 #if ENABLE(POINTER_LOCK)
2737 void Element::webkitRequestPointerLock()
2738 {
2739     if (document()->page())
2740         document()->page()->pointerLockController()->requestPointerLock(this);
2741 }
2742 #endif
2743
2744 SpellcheckAttributeState Element::spellcheckAttributeState() const
2745 {
2746     const AtomicString& value = getAttribute(HTMLNames::spellcheckAttr);
2747     if (value == nullAtom)
2748         return SpellcheckAttributeDefault;
2749     if (equalIgnoringCase(value, "true") || equalIgnoringCase(value, ""))
2750         return SpellcheckAttributeTrue;
2751     if (equalIgnoringCase(value, "false"))
2752         return SpellcheckAttributeFalse;
2753
2754     return SpellcheckAttributeDefault;
2755 }
2756
2757 bool Element::isSpellCheckingEnabled() const
2758 {
2759     for (const Element* element = this; element; element = element->parentOrShadowHostElement()) {
2760         switch (element->spellcheckAttributeState()) {
2761         case SpellcheckAttributeTrue:
2762             return true;
2763         case SpellcheckAttributeFalse:
2764             return false;
2765         case SpellcheckAttributeDefault:
2766             break;
2767         }
2768     }
2769
2770     return true;
2771 }
2772
2773 RenderRegion* Element::renderRegion() const
2774 {
2775     if (renderer() && renderer()->isRenderRegion())
2776         return toRenderRegion(renderer());
2777
2778     return 0;
2779 }
2780
2781 bool Element::moveToFlowThreadIsNeeded(RefPtr<RenderStyle>& cachedStyle)
2782 {
2783     Document* doc = document();
2784     
2785     if (!doc->cssRegionsEnabled())
2786         return false;
2787
2788 #if ENABLE(FULLSCREEN_API)
2789     if (doc->webkitIsFullScreen() && doc->webkitCurrentFullScreenElement() == this)
2790         return false;
2791 #endif
2792
2793     if (isInShadowTree())
2794         return false;
2795
2796     if (!cachedStyle)
2797         cachedStyle = styleForRenderer();
2798     if (!cachedStyle)
2799         return false;
2800
2801     if (cachedStyle->flowThread().isEmpty())
2802         return false;
2803
2804     return !document()->renderView()->flowThreadController()->isContentNodeRegisteredWithAnyNamedFlow(this);
2805 }
2806
2807 #if ENABLE(CSS_REGIONS)
2808
2809 const AtomicString& Element::webkitRegionOverset() const
2810 {
2811     document()->updateLayoutIgnorePendingStylesheets();
2812
2813     DEFINE_STATIC_LOCAL(AtomicString, undefinedState, ("undefined", AtomicString::ConstructFromLiteral));
2814     if (!document()->cssRegionsEnabled() || !renderRegion())
2815         return undefinedState;
2816
2817     switch (renderRegion()->regionOversetState()) {
2818     case RegionFit: {
2819         DEFINE_STATIC_LOCAL(AtomicString, fitState, ("fit", AtomicString::ConstructFromLiteral));
2820         return fitState;
2821     }
2822     case RegionEmpty: {
2823         DEFINE_STATIC_LOCAL(AtomicString, emptyState, ("empty", AtomicString::ConstructFromLiteral));
2824         return emptyState;
2825     }
2826     case RegionOverset: {
2827         DEFINE_STATIC_LOCAL(AtomicString, overflowState, ("overset", AtomicString::ConstructFromLiteral));
2828         return overflowState;
2829     }
2830     case RegionUndefined:
2831         return undefinedState;
2832     }
2833
2834     ASSERT_NOT_REACHED();
2835     return undefinedState;
2836 }
2837
2838 Vector<RefPtr<Range> > Element::webkitGetRegionFlowRanges() const
2839 {
2840     document()->updateLayoutIgnorePendingStylesheets();
2841
2842     Vector<RefPtr<Range> > rangeObjects;
2843     if (document()->cssRegionsEnabled() && renderer() && renderer()->isRenderRegion()) {
2844         RenderRegion* region = toRenderRegion(renderer());
2845         if (region->isValid())
2846             region->getRanges(rangeObjects);
2847     }
2848
2849     return rangeObjects;
2850 }
2851
2852 #endif
2853
2854 #ifndef NDEBUG
2855 bool Element::fastAttributeLookupAllowed(const QualifiedName& name) const
2856 {
2857     if (name == HTMLNames::styleAttr)
2858         return false;
2859
2860 #if ENABLE(SVG)
2861     if (isSVGElement())
2862         return !static_cast<const SVGElement*>(this)->isAnimatableAttribute(name);
2863 #endif
2864
2865     return true;
2866 }
2867 #endif
2868
2869 #ifdef DUMP_NODE_STATISTICS
2870 bool Element::hasNamedNodeMap() const
2871 {
2872     return hasRareData() && elementRareData()->attributeMap();
2873 }
2874 #endif
2875
2876 inline void Element::updateName(const AtomicString& oldName, const AtomicString& newName)
2877 {
2878     if (!isInTreeScope())
2879         return;
2880
2881     if (oldName == newName)
2882         return;
2883
2884     updateNameForTreeScope(treeScope(), oldName, newName);
2885
2886     if (!inDocument())
2887         return;
2888     Document* htmlDocument = document();
2889     if (!htmlDocument->isHTMLDocument())
2890         return;
2891     updateNameForDocument(toHTMLDocument(htmlDocument), oldName, newName);
2892 }
2893
2894 void Element::updateNameForTreeScope(TreeScope* scope, const AtomicString& oldName, const AtomicString& newName)
2895 {
2896     ASSERT(isInTreeScope());
2897     ASSERT(oldName != newName);
2898
2899     if (!oldName.isEmpty())
2900         scope->removeElementByName(oldName, this);
2901     if (!newName.isEmpty())
2902         scope->addElementByName(newName, this);
2903 }
2904
2905 void Element::updateNameForDocument(HTMLDocument* document, const AtomicString& oldName, const AtomicString& newName)
2906 {
2907     ASSERT(inDocument());
2908     ASSERT(oldName != newName);
2909
2910     if (WindowNameCollection::nodeMatchesIfNameAttributeMatch(this)) {
2911         const AtomicString& id = WindowNameCollection::nodeMatchesIfIdAttributeMatch(this) ? getIdAttribute() : nullAtom;
2912         if (!oldName.isEmpty() && oldName != id)
2913             document->windowNamedItemMap().remove(oldName.impl(), this);
2914         if (!newName.isEmpty() && newName != id)
2915             document->windowNamedItemMap().add(newName.impl(), this);
2916     }
2917
2918     if (DocumentNameCollection::nodeMatchesIfNameAttributeMatch(this)) {
2919         const AtomicString& id = DocumentNameCollection::nodeMatchesIfIdAttributeMatch(this) ? getIdAttribute() : nullAtom;
2920         if (!oldName.isEmpty() && oldName != id)
2921             document->documentNamedItemMap().remove(oldName.impl(), this);
2922         if (!newName.isEmpty() && newName != id)
2923             document->documentNamedItemMap().add(newName.impl(), this);
2924     }
2925 }
2926
2927 inline void Element::updateId(const AtomicString& oldId, const AtomicString& newId)
2928 {
2929     if (!isInTreeScope())
2930         return;
2931
2932     if (oldId == newId)
2933         return;
2934
2935     updateIdForTreeScope(treeScope(), oldId, newId);
2936
2937     if (!inDocument())
2938         return;
2939     Document* htmlDocument = document();
2940     if (!htmlDocument->isHTMLDocument())
2941         return;
2942     updateIdForDocument(toHTMLDocument(htmlDocument), oldId, newId, UpdateHTMLDocumentNamedItemMapsOnlyIfDiffersFromNameAttribute);
2943 }
2944
2945 void Element::updateIdForTreeScope(TreeScope* scope, const AtomicString& oldId, const AtomicString& newId)
2946 {
2947     ASSERT(isInTreeScope());
2948     ASSERT(oldId != newId);
2949
2950     if (!oldId.isEmpty())
2951         scope->removeElementById(oldId, this);
2952     if (!newId.isEmpty())
2953         scope->addElementById(newId, this);
2954 }
2955
2956 void Element::updateIdForDocument(HTMLDocument* document, const AtomicString& oldId, const AtomicString& newId, HTMLDocumentNamedItemMapsUpdatingCondition condition)
2957 {
2958     ASSERT(inDocument());
2959     ASSERT(oldId != newId);
2960
2961     if (WindowNameCollection::nodeMatchesIfIdAttributeMatch(this)) {
2962         const AtomicString& name = condition == UpdateHTMLDocumentNamedItemMapsOnlyIfDiffersFromNameAttribute && WindowNameCollection::nodeMatchesIfNameAttributeMatch(this) ? getNameAttribute() : nullAtom;
2963         if (!oldId.isEmpty() && oldId != name)
2964             document->windowNamedItemMap().remove(oldId.impl(), this);
2965         if (!newId.isEmpty() && newId != name)
2966             document->windowNamedItemMap().add(newId.impl(), this);
2967     }
2968
2969     if (DocumentNameCollection::nodeMatchesIfIdAttributeMatch(this)) {
2970         const AtomicString& name = condition == UpdateHTMLDocumentNamedItemMapsOnlyIfDiffersFromNameAttribute && DocumentNameCollection::nodeMatchesIfNameAttributeMatch(this) ? getNameAttribute() : nullAtom;
2971         if (!oldId.isEmpty() && oldId != name)
2972             document->documentNamedItemMap().remove(oldId.impl(), this);
2973         if (!newId.isEmpty() && newId != name)
2974             document->documentNamedItemMap().add(newId.impl(), this);
2975     }
2976 }
2977
2978 void Element::updateLabel(TreeScope* scope, const AtomicString& oldForAttributeValue, const AtomicString& newForAttributeValue)
2979 {
2980     ASSERT(hasTagName(labelTag));
2981
2982     if (!inDocument())
2983         return;
2984
2985     if (oldForAttributeValue == newForAttributeValue)
2986         return;
2987
2988     if (!oldForAttributeValue.isEmpty())
2989         scope->removeLabel(oldForAttributeValue, static_cast<HTMLLabelElement*>(this));
2990     if (!newForAttributeValue.isEmpty())
2991         scope->addLabel(newForAttributeValue, static_cast<HTMLLabelElement*>(this));
2992 }
2993
2994 void Element::willModifyAttribute(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue)
2995 {
2996     if (isIdAttributeName(name))
2997         updateId(oldValue, newValue);
2998     else if (name == HTMLNames::nameAttr)
2999         updateName(oldValue, newValue);
3000     else if (name == HTMLNames::forAttr && hasTagName(labelTag)) {
3001         TreeScope* scope = treeScope();
3002         if (scope->shouldCacheLabelsByForAttribute())
3003             updateLabel(scope, oldValue, newValue);
3004     }
3005
3006     if (oldValue != newValue) {
3007         if (attached() && document()->styleResolverIfExists() && document()->styleResolverIfExists()->hasSelectorForAttribute(name.localName()))
3008             setNeedsStyleRecalc();
3009     }
3010
3011     if (OwnPtr<MutationObserverInterestGroup> recipients = MutationObserverInterestGroup::createForAttributesMutation(this, name))
3012         recipients->enqueueMutationRecord(MutationRecord::createAttributes(this, name, oldValue));
3013
3014 #if ENABLE(INSPECTOR)
3015     InspectorInstrumentation::willModifyDOMAttr(document(), this, oldValue, newValue);
3016 #endif
3017 }
3018
3019 void Element::didAddAttribute(const QualifiedName& name, const AtomicString& value)
3020 {
3021     attributeChanged(name, value);
3022     InspectorInstrumentation::didModifyDOMAttr(document(), this, name.localName(), value);
3023     dispatchSubtreeModifiedEvent();
3024 }
3025
3026 void Element::didModifyAttribute(const QualifiedName& name, const AtomicString& value)
3027 {
3028     attributeChanged(name, value);
3029     InspectorInstrumentation::didModifyDOMAttr(document(), this, name.localName(), value);
3030     // Do not dispatch a DOMSubtreeModified event here; see bug 81141.
3031 }
3032
3033 void Element::didRemoveAttribute(const QualifiedName& name)
3034 {
3035     attributeChanged(name, nullAtom);
3036     InspectorInstrumentation::didRemoveDOMAttr(document(), this, name.localName());
3037     dispatchSubtreeModifiedEvent();
3038 }
3039
3040 PassRefPtr<HTMLCollection> Element::ensureCachedHTMLCollection(CollectionType type)
3041 {
3042     if (HTMLCollection* collection = cachedHTMLCollection(type))
3043         return collection;
3044
3045     RefPtr<HTMLCollection> collection;
3046     if (type == TableRows) {
3047         ASSERT(hasTagName(tableTag));
3048         return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLTableRowsCollection>(this, type);
3049     } else if (type == SelectOptions) {
3050         ASSERT(hasTagName(selectTag));
3051         return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLOptionsCollection>(this, type);
3052     } else if (type == FormControls) {
3053         ASSERT(hasTagName(formTag) || hasTagName(fieldsetTag));
3054         return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLFormControlsCollection>(this, type);
3055 #if ENABLE(MICRODATA)
3056     } else if (type == ItemProperties) {
3057         return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLPropertiesCollection>(this, type);
3058 #endif
3059     }
3060     return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLCollection>(this, type);
3061 }
3062
3063 HTMLCollection* Element::cachedHTMLCollection(CollectionType type)
3064 {
3065     return hasRareData() && rareData()->nodeLists() ? rareData()->nodeLists()->cacheWithAtomicName<HTMLCollection>(type) : 0;
3066 }
3067
3068 IntSize Element::savedLayerScrollOffset() const
3069 {
3070     return hasRareData() ? elementRareData()->savedLayerScrollOffset() : IntSize();
3071 }
3072
3073 void Element::setSavedLayerScrollOffset(const IntSize& size)
3074 {
3075     if (size.isZero() && !hasRareData())
3076         return;
3077     ensureElementRareData()->setSavedLayerScrollOffset(size);
3078 }
3079
3080 PassRefPtr<Attr> Element::attrIfExists(const QualifiedName& name)
3081 {
3082     if (AttrNodeList* attrNodeList = attrNodeListForElement(this))
3083         return findAttrNodeInList(attrNodeList, name);
3084     return 0;
3085 }
3086
3087 PassRefPtr<Attr> Element::ensureAttr(const QualifiedName& name)
3088 {
3089     AttrNodeList* attrNodeList = ensureAttrNodeListForElement(this);
3090     RefPtr<Attr> attrNode = findAttrNodeInList(attrNodeList, name);
3091     if (!attrNode) {
3092         attrNode = Attr::create(this, name);
3093         treeScope()->adoptIfNeeded(attrNode.get());
3094         attrNodeList->append(attrNode);
3095     }
3096     return attrNode.release();
3097 }
3098
3099 void Element::detachAttrNodeFromElementWithValue(Attr* attrNode, const AtomicString& value)
3100 {
3101     ASSERT(hasSyntheticAttrChildNodes());
3102     attrNode->detachFromElementWithValue(value);
3103
3104     AttrNodeList* attrNodeList = attrNodeListForElement(this);
3105     for (unsigned i = 0; i < attrNodeList->size(); ++i) {
3106         if (attrNodeList->at(i)->qualifiedName() == attrNode->qualifiedName()) {
3107             attrNodeList->remove(i);
3108             if (attrNodeList->isEmpty())
3109                 removeAttrNodeListForElement(this);
3110             return;
3111         }
3112     }
3113     ASSERT_NOT_REACHED();
3114 }
3115
3116 void Element::detachAllAttrNodesFromElement()
3117 {
3118     AttrNodeList* attrNodeList = attrNodeListForElement(this);
3119     ASSERT(attrNodeList);
3120
3121     for (unsigned i = 0; i < attributeCount(); ++i) {
3122         const Attribute* attribute = attributeItem(i);
3123         if (RefPtr<Attr> attrNode = findAttrNodeInList(attrNodeList, attribute->name()))
3124             attrNode->detachFromElementWithValue(attribute->value());
3125     }
3126
3127     removeAttrNodeListForElement(this);
3128 }
3129
3130 bool Element::willRecalcStyle(StyleChange)
3131 {
3132     ASSERT(hasCustomStyleCallbacks());
3133     return true;
3134 }
3135
3136 void Element::didRecalcStyle(StyleChange)
3137 {
3138     ASSERT(hasCustomStyleCallbacks());
3139 }
3140
3141
3142 PassRefPtr<RenderStyle> Element::customStyleForRenderer()
3143 {
3144     ASSERT(hasCustomStyleCallbacks());
3145     return 0;
3146 }
3147
3148 void Element::cloneAttributesFromElement(const Element& other)
3149 {
3150     if (hasSyntheticAttrChildNodes())
3151         detachAllAttrNodesFromElement();
3152
3153     other.synchronizeAllAttributes();
3154     if (!other.m_elementData) {
3155         m_elementData.clear();
3156         return;
3157     }
3158
3159     // 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.
3160     // Fortunately, those named item maps are only updated when this element is in the document, which should never be the case.
3161     ASSERT(!inDocument());
3162
3163     const AtomicString& oldID = getIdAttribute();
3164     const AtomicString& newID = other.getIdAttribute();
3165
3166     if (!oldID.isNull() || !newID.isNull())
3167         updateId(oldID, newID);
3168
3169     const AtomicString& oldName = getNameAttribute();
3170     const AtomicString& newName = other.getNameAttribute();
3171
3172     if (!oldName.isNull() || !newName.isNull())
3173         updateName(oldName, newName);
3174
3175     // If 'other' has a mutable ElementData, convert it to an immutable one so we can share it between both elements.
3176     // We can only do this if there is no CSSOM wrapper for other's inline style, and there are no presentation attributes.
3177     if (other.m_elementData->isUnique()
3178         && !other.m_elementData->presentationAttributeStyle()
3179         && (!other.m_elementData->inlineStyle() || !other.m_elementData->inlineStyle()->hasCSSOMWrapper()))
3180         const_cast<Element&>(other).m_elementData = static_cast<const UniqueElementData*>(other.m_elementData.get())->makeShareableCopy();
3181
3182     if (!other.m_elementData->isUnique())
3183         m_elementData = other.m_elementData;
3184     else
3185         m_elementData = other.m_elementData->makeUniqueCopy();
3186
3187     for (unsigned i = 0; i < m_elementData->length(); ++i) {
3188         const Attribute* attribute = const_cast<const ElementData*>(m_elementData.get())->attributeItem(i);
3189         attributeChangedFromParserOrByCloning(attribute->name(), attribute->value(), ModifiedByCloning);
3190     }
3191 }
3192
3193 void Element::cloneDataFromElement(const Element& other)
3194 {
3195     cloneAttributesFromElement(other);
3196     copyNonAttributePropertiesFromElement(other);
3197 }
3198
3199 void Element::createUniqueElementData()
3200 {
3201     if (!m_elementData)
3202         m_elementData = UniqueElementData::create();
3203     else {
3204         ASSERT(!m_elementData->isUnique());
3205         m_elementData = static_cast<ShareableElementData*>(m_elementData.get())->makeUniqueCopy();
3206     }
3207 }
3208
3209 #if ENABLE(SVG)
3210 bool Element::hasPendingResources() const
3211 {
3212     return hasRareData() && elementRareData()->hasPendingResources();
3213 }
3214
3215 void Element::setHasPendingResources()
3216 {
3217     ensureElementRareData()->setHasPendingResources(true);
3218 }
3219
3220 void Element::clearHasPendingResources()
3221 {
3222     ensureElementRareData()->setHasPendingResources(false);
3223 }
3224 #endif
3225
3226 void ElementData::deref()
3227 {
3228     if (!derefBase())
3229         return;
3230
3231     if (m_isUnique)
3232         delete static_cast<UniqueElementData*>(this);
3233     else
3234         delete static_cast<ShareableElementData*>(this);
3235 }
3236
3237 ElementData::ElementData()
3238     : m_isUnique(true)
3239     , m_arraySize(0)
3240     , m_hasNameAttribute(false)
3241     , m_presentationAttributeStyleIsDirty(false)
3242     , m_styleAttributeIsDirty(false)
3243 #if ENABLE(SVG)
3244     , m_animatedSVGAttributesAreDirty(false)
3245 #endif
3246 {
3247 }
3248
3249 ElementData::ElementData(unsigned arraySize)
3250     : m_isUnique(false)
3251     , m_arraySize(arraySize)
3252     , m_hasNameAttribute(false)
3253     , m_presentationAttributeStyleIsDirty(false)
3254     , m_styleAttributeIsDirty(false)
3255 #if ENABLE(SVG)
3256     , m_animatedSVGAttributesAreDirty(false)
3257 #endif
3258 {
3259 }
3260
3261 struct SameSizeAsElementData : public RefCounted<SameSizeAsElementData> {
3262     unsigned bitfield;
3263     void* refPtrs[3];
3264 };
3265
3266 COMPILE_ASSERT(sizeof(ElementData) == sizeof(SameSizeAsElementData), element_attribute_data_should_stay_small);
3267
3268 static size_t sizeForShareableElementDataWithAttributeCount(unsigned count)
3269 {
3270     return sizeof(ShareableElementData) + sizeof(Attribute) * count;
3271 }
3272
3273 PassRefPtr<ShareableElementData> ShareableElementData::createWithAttributes(const Vector<Attribute>& attributes)
3274 {
3275     void* slot = WTF::fastMalloc(sizeForShareableElementDataWithAttributeCount(attributes.size()));
3276     return adoptRef(new (NotNull, slot) ShareableElementData(attributes));
3277 }
3278
3279 PassRefPtr<UniqueElementData> UniqueElementData::create()
3280 {
3281     return adoptRef(new UniqueElementData);
3282 }
3283
3284 ShareableElementData::ShareableElementData(const Vector<Attribute>& attributes)
3285     : ElementData(attributes.size())
3286 {
3287     for (unsigned i = 0; i < m_arraySize; ++i)
3288         new (NotNull, &m_attributeArray[i]) Attribute(attributes[i]);
3289 }
3290
3291 ShareableElementData::~ShareableElementData()
3292 {
3293     for (unsigned i = 0; i < m_arraySize; ++i)
3294         m_attributeArray[i].~Attribute();
3295 }
3296
3297 ShareableElementData::ShareableElementData(const UniqueElementData& other)
3298     : ElementData(other, false)
3299 {
3300     ASSERT(!other.m_presentationAttributeStyle);
3301
3302     if (other.m_inlineStyle) {
3303         ASSERT(!other.m_inlineStyle->hasCSSOMWrapper());
3304         m_inlineStyle = other.m_inlineStyle->immutableCopyIfNeeded();
3305     }
3306
3307     for (unsigned i = 0; i < m_arraySize; ++i)
3308         new (NotNull, &m_attributeArray[i]) Attribute(other.m_attributeVector.at(i));
3309 }
3310
3311 ElementData::ElementData(const ElementData& other, bool isUnique)
3312     : m_isUnique(isUnique)
3313     , m_arraySize(isUnique ? 0 : other.length())
3314     , m_hasNameAttribute(other.m_hasNameAttribute)
3315     , m_presentationAttributeStyleIsDirty(other.m_presentationAttributeStyleIsDirty)
3316     , m_styleAttributeIsDirty(other.m_styleAttributeIsDirty)
3317 #if ENABLE(SVG)
3318     , m_animatedSVGAttributesAreDirty(other.m_animatedSVGAttributesAreDirty)
3319 #endif
3320     , m_classNames(other.m_classNames)
3321     , m_idForStyleResolution(other.m_idForStyleResolution)
3322 {
3323     // NOTE: The inline style is copied by the subclass copy constructor since we don't know what to do with it here.
3324 }
3325
3326 UniqueElementData::UniqueElementData()
3327 {
3328 }
3329
3330 UniqueElementData::UniqueElementData(const UniqueElementData& other)
3331     : ElementData(other, true)
3332     , m_presentationAttributeStyle(other.m_presentationAttributeStyle)
3333     , m_attributeVector(other.m_attributeVector)
3334 {
3335     m_inlineStyle = other.m_inlineStyle ? other.m_inlineStyle->mutableCopy() : 0;
3336 }
3337
3338 UniqueElementData::UniqueElementData(const ShareableElementData& other)
3339     : ElementData(other, true)
3340 {
3341     // An ShareableElementData should never have a mutable inline StylePropertySet attached.
3342     ASSERT(!other.m_inlineStyle || !other.m_inlineStyle->isMutable());
3343     m_inlineStyle = other.m_inlineStyle;
3344
3345     m_attributeVector.reserveCapacity(other.length());
3346     for (unsigned i = 0; i < other.length(); ++i)
3347         m_attributeVector.uncheckedAppend(other.m_attributeArray[i]);
3348 }
3349
3350 PassRefPtr<UniqueElementData> ElementData::makeUniqueCopy() const
3351 {
3352     if (isUnique())
3353         return adoptRef(new UniqueElementData(static_cast<const UniqueElementData&>(*this)));
3354     return adoptRef(new UniqueElementData(static_cast<const ShareableElementData&>(*this)));
3355 }
3356
3357 PassRefPtr<ShareableElementData> UniqueElementData::makeShareableCopy() const
3358 {
3359     void* slot = WTF::fastMalloc(sizeForShareableElementDataWithAttributeCount(m_attributeVector.size()));
3360     return adoptRef(new (NotNull, slot) ShareableElementData(*this));
3361 }
3362
3363 void UniqueElementData::addAttribute(const QualifiedName& attributeName, const AtomicString& value)
3364 {
3365     m_attributeVector.append(Attribute(attributeName, value));
3366 }
3367
3368 void UniqueElementData::removeAttribute(unsigned index)
3369 {
3370     ASSERT_WITH_SECURITY_IMPLICATION(index < length());
3371     m_attributeVector.remove(index);
3372 }
3373
3374 bool ElementData::isEquivalent(const ElementData* other) const
3375 {
3376     if (!other)
3377         return isEmpty();
3378
3379     unsigned len = length();
3380     if (len != other->length())
3381         return false;
3382
3383     for (unsigned i = 0; i < len; i++) {
3384         const Attribute* attribute = attributeItem(i);
3385         const Attribute* otherAttr = other->getAttributeItem(attribute->name());
3386         if (!otherAttr || attribute->value() != otherAttr->value())
3387             return false;
3388     }
3389
3390     return true;
3391 }
3392
3393 unsigned ElementData::getAttributeItemIndexSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const
3394 {
3395     // Continue to checking case-insensitively and/or full namespaced names if necessary:
3396     for (unsigned i = 0; i < length(); ++i) {
3397         const Attribute* attribute = attributeItem(i);
3398         if (!attribute->name().hasPrefix()) {
3399             if (shouldIgnoreAttributeCase && equalIgnoringCase(name, attribute->localName()))
3400                 return i;
3401         } else {
3402             // FIXME: Would be faster to do this comparison without calling toString, which
3403             // generates a temporary string by concatenation. But this branch is only reached
3404             // if the attribute name has a prefix, which is rare in HTML.
3405             if (equalPossiblyIgnoringCase(name, attribute->name().toString(), shouldIgnoreAttributeCase))
3406                 return i;
3407         }
3408     }
3409     return attributeNotFound;
3410 }
3411
3412 unsigned ElementData::getAttributeItemIndexForAttributeNode(const Attr* attr) const
3413 {
3414     ASSERT(attr);
3415     const Attribute* attributes = attributeBase();
3416     unsigned count = length();
3417     for (unsigned i = 0; i < count; ++i) {
3418         if (attributes[i].name() == attr->qualifiedName())
3419             return i;
3420     }
3421     return attributeNotFound;
3422 }
3423
3424 Attribute* UniqueElementData::getAttributeItem(const QualifiedName& name)
3425 {
3426     unsigned count = length();
3427     for (unsigned i = 0; i < count; ++i) {
3428         if (m_attributeVector.at(i).name().matches(name))
3429             return &m_attributeVector.at(i);
3430     }
3431     return 0;
3432 }
3433
3434 Attribute* UniqueElementData::attributeItem(unsigned index)
3435 {
3436     ASSERT_WITH_SECURITY_IMPLICATION(index < length());
3437     return &m_attributeVector.at(index);
3438 }
3439
3440 } // namespace WebCore