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