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