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