83e129e8e28cfa510ee0d8156d24385d1e93dcf9
[WebKit-https.git] / 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 "CSSStyleSelector.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 "FocusController.h"
43 #include "Frame.h"
44 #include "FrameView.h"
45 #include "HTMLElement.h"
46 #include "HTMLNames.h"
47 #include "HTMLParserIdioms.h"
48 #include "InspectorInstrumentation.h"
49 #include "NodeList.h"
50 #include "NodeRenderStyle.h"
51 #include "Page.h"
52 #include "RenderLayer.h"
53 #include "RenderView.h"
54 #include "RenderWidget.h"
55 #include "SVGStyledLocatableElement.h"
56 #include "Settings.h"
57 #include "TextIterator.h"
58 #include "XMLNames.h"
59 #include <wtf/text/CString.h>
60
61 #if ENABLE(SVG)
62 #include "SVGNames.h"
63 #endif
64
65 namespace WebCore {
66
67 using namespace HTMLNames;
68 using namespace XMLNames;
69     
70 PassRefPtr<Element> Element::create(const QualifiedName& tagName, Document* document)
71 {
72     return adoptRef(new Element(tagName, document, CreateElement));
73 }
74
75 Element::~Element()
76 {
77     if (m_attributeMap)
78         m_attributeMap->detachFromElement();
79 }
80
81 inline ElementRareData* Element::rareData() const
82 {
83     ASSERT(hasRareData());
84     return static_cast<ElementRareData*>(NodeRareData::rareDataFromMap(this));
85 }
86     
87 inline ElementRareData* Element::ensureRareData()
88 {
89     return static_cast<ElementRareData*>(Node::ensureRareData());
90 }
91     
92 NodeRareData* Element::createRareData()
93 {
94     return new ElementRareData;
95 }
96
97 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, blur);
98 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, error);
99 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, focus);
100 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, load);
101
102 PassRefPtr<DocumentFragment> Element::deprecatedCreateContextualFragment(const String& markup, FragmentScriptingPermission scriptingPermission)
103 {
104     RefPtr<DocumentFragment> fragment = document()->createDocumentFragment();
105
106     if (document()->isHTMLDocument())
107         fragment->parseHTML(markup, this, scriptingPermission);
108     else {
109         if (!fragment->parseXML(markup, this, scriptingPermission))
110             // FIXME: We should propagate a syntax error exception out here.
111             return 0;
112     }
113
114     // Exceptions are ignored because none ought to happen here.
115     ExceptionCode ignoredExceptionCode;
116
117     // We need to pop <html> and <body> elements and remove <head> to
118     // accommodate folks passing complete HTML documents to make the
119     // child of an element.
120
121     RefPtr<Node> nextNode;
122     for (RefPtr<Node> node = fragment->firstChild(); node; node = nextNode) {
123         nextNode = node->nextSibling();
124         if (node->hasTagName(htmlTag) || node->hasTagName(bodyTag)) {
125             HTMLElement* element = static_cast<HTMLElement*>(node.get());
126             Node* firstChild = element->firstChild();
127             if (firstChild)
128                 nextNode = firstChild;
129             RefPtr<Node> nextChild;
130             for (RefPtr<Node> child = firstChild; child; child = nextChild) {
131                 nextChild = child->nextSibling();
132                 element->removeChild(child.get(), ignoredExceptionCode);
133                 ASSERT(!ignoredExceptionCode);
134                 fragment->insertBefore(child, element, ignoredExceptionCode);
135                 ASSERT(!ignoredExceptionCode);
136             }
137             fragment->removeChild(element, ignoredExceptionCode);
138             ASSERT(!ignoredExceptionCode);
139         } else if (node->hasTagName(headTag)) {
140             fragment->removeChild(node.get(), ignoredExceptionCode);
141             ASSERT(!ignoredExceptionCode);
142         }
143     }
144     return fragment.release();
145 }
146     
147 PassRefPtr<Node> Element::cloneNode(bool deep)
148 {
149     return deep ? cloneElementWithChildren() : cloneElementWithoutChildren();
150 }
151
152 PassRefPtr<Element> Element::cloneElementWithChildren()
153 {
154     RefPtr<Element> clone = cloneElementWithoutChildren();
155     cloneChildNodes(clone.get());
156     return clone.release();
157 }
158
159 PassRefPtr<Element> Element::cloneElementWithoutChildren()
160 {
161     RefPtr<Element> clone = document()->createElement(tagQName(), false);
162     // This will catch HTML elements in the wrong namespace that are not correctly copied.
163     // This is a sanity check as HTML overloads some of the DOM methods.
164     ASSERT(isHTMLElement() == clone->isHTMLElement());
165
166     // Call attributes(true) to force attribute synchronization to occur for SVG and style attributes.
167     if (NamedNodeMap* attributeMap = attributes(true))
168         clone->attributes()->setAttributes(*attributeMap);
169
170     clone->copyNonAttributeProperties(this);
171
172     return clone.release();
173 }
174
175 void Element::removeAttribute(const QualifiedName& name, ExceptionCode& ec)
176 {
177     if (m_attributeMap) {
178         ec = 0;
179         m_attributeMap->removeNamedItem(name, ec);
180         if (ec == NOT_FOUND_ERR)
181             ec = 0;
182     }
183 }
184
185 void Element::setAttribute(const QualifiedName& name, const AtomicString& value)
186 {
187     ExceptionCode ec;
188     setAttribute(name, value, ec);
189 }
190     
191 void Element::setCStringAttribute(const QualifiedName& name, const char* cStringValue)
192 {
193     ExceptionCode ec;
194     setAttribute(name, AtomicString(cStringValue), ec);
195 }
196
197 void Element::setBooleanAttribute(const QualifiedName& name, bool b)
198 {
199     if (b)
200         setAttribute(name, emptyAtom);
201     else {
202         ExceptionCode ex;
203         removeAttribute(name, ex);
204     }
205 }
206
207 Node::NodeType Element::nodeType() const
208 {
209     return ELEMENT_NODE;
210 }
211
212 bool Element::hasAttribute(const QualifiedName& name) const
213 {
214     return hasAttributeNS(name.namespaceURI(), name.localName());
215 }
216
217 const AtomicString& Element::getAttribute(const QualifiedName& name) const
218 {
219     if (UNLIKELY(name == styleAttr) && !isStyleAttributeValid())
220         updateStyleAttribute();
221
222 #if ENABLE(SVG)
223     if (UNLIKELY(!areSVGAttributesValid()))
224         updateAnimatedSVGAttribute(name);
225 #endif
226
227     return fastGetAttribute(name);
228 }
229
230 void Element::scrollIntoView(bool alignToTop) 
231 {
232     document()->updateLayoutIgnorePendingStylesheets();
233     IntRect bounds = getRect();    
234     if (renderer()) {
235         // Align to the top / bottom and to the closest edge.
236         if (alignToTop)
237             renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
238         else
239             renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignBottomAlways);
240     }
241 }
242
243 void Element::scrollIntoViewIfNeeded(bool centerIfNeeded)
244 {
245     document()->updateLayoutIgnorePendingStylesheets();
246     IntRect bounds = getRect();    
247     if (renderer()) {
248         if (centerIfNeeded)
249             renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, ScrollAlignment::alignCenterIfNeeded, ScrollAlignment::alignCenterIfNeeded);
250         else
251             renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
252     }
253 }
254
255 void Element::scrollByUnits(int units, ScrollGranularity granularity)
256 {
257     document()->updateLayoutIgnorePendingStylesheets();
258     if (RenderObject *rend = renderer()) {
259         if (rend->hasOverflowClip()) {
260             ScrollDirection direction = ScrollDown;
261             if (units < 0) {
262                 direction = ScrollUp;
263                 units = -units;
264             }
265             toRenderBox(rend)->layer()->scroll(direction, granularity, units);
266         }
267     }
268 }
269
270 void Element::scrollByLines(int lines)
271 {
272     scrollByUnits(lines, ScrollByLine);
273 }
274
275 void Element::scrollByPages(int pages)
276 {
277     scrollByUnits(pages, ScrollByPage);
278 }
279
280 static float localZoomForRenderer(RenderObject* renderer)
281 {
282     // FIXME: This does the wrong thing if two opposing zooms are in effect and canceled each
283     // other out, but the alternative is that we'd have to crawl up the whole render tree every
284     // time (or store an additional bit in the RenderStyle to indicate that a zoom was specified).
285     float zoomFactor = 1;
286     if (renderer->style()->effectiveZoom() != 1) {
287         // Need to find the nearest enclosing RenderObject that set up
288         // a differing zoom, and then we divide our result by it to eliminate the zoom.
289         RenderObject* prev = renderer;
290         for (RenderObject* curr = prev->parent(); curr; curr = curr->parent()) {
291             if (curr->style()->effectiveZoom() != prev->style()->effectiveZoom()) {
292                 zoomFactor = prev->style()->zoom();
293                 break;
294             }
295             prev = curr;
296         }
297         if (prev->isRenderView())
298             zoomFactor = prev->style()->zoom();
299     }
300     return zoomFactor;
301 }
302
303 static int adjustForLocalZoom(int value, RenderObject* renderer)
304 {
305     float zoomFactor = localZoomForRenderer(renderer);
306     if (zoomFactor == 1)
307         return value;
308     // Needed because computeLengthInt truncates (rather than rounds) when scaling up.
309     if (zoomFactor > 1)
310         value++;
311     return static_cast<int>(value / zoomFactor);
312 }
313
314 int Element::offsetLeft()
315 {
316     document()->updateLayoutIgnorePendingStylesheets();
317     if (RenderBoxModelObject* rend = renderBoxModelObject())
318         return adjustForLocalZoom(rend->offsetLeft(), rend);
319     return 0;
320 }
321
322 int Element::offsetTop()
323 {
324     document()->updateLayoutIgnorePendingStylesheets();
325     if (RenderBoxModelObject* rend = renderBoxModelObject())
326         return adjustForLocalZoom(rend->offsetTop(), rend);
327     return 0;
328 }
329
330 int Element::offsetWidth()
331 {
332     document()->updateLayoutIgnorePendingStylesheets();
333     if (RenderBoxModelObject* rend = renderBoxModelObject())
334         return adjustForAbsoluteZoom(rend->offsetWidth(), rend);
335     return 0;
336 }
337
338 int Element::offsetHeight()
339 {
340     document()->updateLayoutIgnorePendingStylesheets();
341     if (RenderBoxModelObject* rend = renderBoxModelObject())
342         return adjustForAbsoluteZoom(rend->offsetHeight(), rend);
343     return 0;
344 }
345
346 Element* Element::offsetParent()
347 {
348     document()->updateLayoutIgnorePendingStylesheets();
349     if (RenderObject* rend = renderer())
350         if (RenderObject* offsetParent = rend->offsetParent())
351             return static_cast<Element*>(offsetParent->node());
352     return 0;
353 }
354
355 int Element::clientLeft()
356 {
357     document()->updateLayoutIgnorePendingStylesheets();
358
359     if (RenderBox* rend = renderBox())
360         return adjustForAbsoluteZoom(rend->clientLeft(), rend);
361     return 0;
362 }
363
364 int Element::clientTop()
365 {
366     document()->updateLayoutIgnorePendingStylesheets();
367
368     if (RenderBox* rend = renderBox())
369         return adjustForAbsoluteZoom(rend->clientTop(), rend);
370     return 0;
371 }
372
373 int Element::clientWidth()
374 {
375     document()->updateLayoutIgnorePendingStylesheets();
376
377     // When in strict mode, clientWidth for the document element should return the width of the containing frame.
378     // When in quirks mode, clientWidth for the body element should return the width of the containing frame.
379     bool inQuirksMode = document()->inQuirksMode();
380     if ((!inQuirksMode && document()->documentElement() == this) ||
381         (inQuirksMode && isHTMLElement() && document()->body() == this)) {
382         if (FrameView* view = document()->view()) {
383             if (RenderView* renderView = document()->renderView())
384                 return adjustForAbsoluteZoom(view->layoutWidth(), renderView);
385         }
386     }
387     
388     if (RenderBox* rend = renderBox())
389         return adjustForAbsoluteZoom(rend->clientWidth(), rend);
390     return 0;
391 }
392
393 int Element::clientHeight()
394 {
395     document()->updateLayoutIgnorePendingStylesheets();
396
397     // When in strict mode, clientHeight for the document element should return the height of the containing frame.
398     // When in quirks mode, clientHeight for the body element should return the height of the containing frame.
399     bool inQuirksMode = document()->inQuirksMode();     
400
401     if ((!inQuirksMode && document()->documentElement() == this) ||
402         (inQuirksMode && isHTMLElement() && document()->body() == this)) {
403         if (FrameView* view = document()->view()) {
404             if (RenderView* renderView = document()->renderView())
405                 return adjustForAbsoluteZoom(view->layoutHeight(), renderView);
406         }
407     }
408     
409     if (RenderBox* rend = renderBox())
410         return adjustForAbsoluteZoom(rend->clientHeight(), rend);
411     return 0;
412 }
413
414 int Element::scrollLeft() const
415 {
416     document()->updateLayoutIgnorePendingStylesheets();
417     if (RenderBox* rend = renderBox())
418         return adjustForAbsoluteZoom(rend->scrollLeft(), rend);
419     return 0;
420 }
421
422 int Element::scrollTop() const
423 {
424     document()->updateLayoutIgnorePendingStylesheets();
425     if (RenderBox* rend = renderBox())
426         return adjustForAbsoluteZoom(rend->scrollTop(), rend);
427     return 0;
428 }
429
430 void Element::setScrollLeft(int newLeft)
431 {
432     document()->updateLayoutIgnorePendingStylesheets();
433     if (RenderBox* rend = renderBox())
434         rend->setScrollLeft(static_cast<int>(newLeft * rend->style()->effectiveZoom()));
435 }
436
437 void Element::setScrollTop(int newTop)
438 {
439     document()->updateLayoutIgnorePendingStylesheets();
440     if (RenderBox* rend = renderBox())
441         rend->setScrollTop(static_cast<int>(newTop * rend->style()->effectiveZoom()));
442 }
443
444 int Element::scrollWidth() const
445 {
446     document()->updateLayoutIgnorePendingStylesheets();
447     if (RenderBox* rend = renderBox())
448         return adjustForAbsoluteZoom(rend->scrollWidth(), rend);
449     return 0;
450 }
451
452 int Element::scrollHeight() const
453 {
454     document()->updateLayoutIgnorePendingStylesheets();
455     if (RenderBox* rend = renderBox())
456         return adjustForAbsoluteZoom(rend->scrollHeight(), rend);
457     return 0;
458 }
459
460 PassRefPtr<ClientRectList> Element::getClientRects() const
461 {
462     document()->updateLayoutIgnorePendingStylesheets();
463
464     RenderBoxModelObject* renderBoxModelObject = this->renderBoxModelObject();
465     if (!renderBoxModelObject)
466         return ClientRectList::create();
467
468     // FIXME: Handle SVG elements.
469     // FIXME: Handle table/inline-table with a caption.
470
471     Vector<FloatQuad> quads;
472     renderBoxModelObject->absoluteQuads(quads);
473
474     if (FrameView* view = document()->view()) {
475         IntRect visibleContentRect = view->visibleContentRect();
476         for (size_t i = 0; i < quads.size(); ++i) {
477             quads[i].move(-visibleContentRect.x(), -visibleContentRect.y());
478             adjustFloatQuadForAbsoluteZoom(quads[i], renderBoxModelObject);
479         }
480     }
481
482     return ClientRectList::create(quads);
483 }
484
485 PassRefPtr<ClientRect> Element::getBoundingClientRect() const
486 {
487     document()->updateLayoutIgnorePendingStylesheets();
488
489     Vector<FloatQuad> quads;
490 #if ENABLE(SVG)
491     if (isSVGElement()) {
492         // Get the bounding rectangle from the SVG model.
493         const SVGElement* svgElement = static_cast<const SVGElement*>(this);
494         if (svgElement->isStyledLocatable()) {
495             if (renderer()) {
496                 const FloatRect& localRect = static_cast<const SVGStyledLocatableElement*>(svgElement)->getBBox();
497                 quads.append(renderer()->localToAbsoluteQuad(localRect));
498             }
499         }
500     } else
501 #endif
502     {
503         // Get the bounding rectangle from the box model.
504         if (renderBoxModelObject())
505             renderBoxModelObject()->absoluteQuads(quads);
506     }
507
508     if (quads.isEmpty())
509         return ClientRect::create();
510
511     IntRect result = quads[0].enclosingBoundingBox();
512     for (size_t i = 1; i < quads.size(); ++i)
513         result.unite(quads[i].enclosingBoundingBox());
514
515     if (FrameView* view = document()->view()) {
516         IntRect visibleContentRect = view->visibleContentRect();
517         result.move(-visibleContentRect.x(), -visibleContentRect.y());
518     }
519
520     if (renderBoxModelObject())
521         adjustIntRectForAbsoluteZoom(result, renderBoxModelObject());
522
523     return ClientRect::create(result);
524 }
525
526 static inline bool shouldIgnoreAttributeCase(const Element* e)
527 {
528     return e && e->document()->isHTMLDocument() && e->isHTMLElement();
529 }
530
531 const AtomicString& Element::getAttribute(const String& name) const
532 {
533     bool ignoreCase = shouldIgnoreAttributeCase(this);
534     
535     // Update the 'style' attribute if it's invalid and being requested:
536     if (!isStyleAttributeValid() && equalPossiblyIgnoringCase(name, styleAttr.localName(), ignoreCase))
537         updateStyleAttribute();
538
539 #if ENABLE(SVG)
540     if (!areSVGAttributesValid()) {
541         // We're not passing a namespace argument on purpose. SVGNames::*Attr are defined w/o namespaces as well.
542         updateAnimatedSVGAttribute(QualifiedName(nullAtom, name, nullAtom));
543     }
544 #endif
545
546     if (m_attributeMap) {
547         if (Attribute* attribute = m_attributeMap->getAttributeItem(name, ignoreCase))
548             return attribute->value();
549     }
550
551     return nullAtom;
552 }
553
554 const AtomicString& Element::getAttributeNS(const String& namespaceURI, const String& localName) const
555 {
556     return getAttribute(QualifiedName(nullAtom, localName, namespaceURI));
557 }
558
559 void Element::setAttribute(const AtomicString& name, const AtomicString& value, ExceptionCode& ec)
560 {
561     if (!Document::isValidName(name)) {
562         ec = INVALID_CHARACTER_ERR;
563         return;
564     }
565
566 #if ENABLE(INSPECTOR)
567     if (!isSynchronizingStyleAttribute())
568         InspectorInstrumentation::willModifyDOMAttr(document(), this);
569 #endif
570
571     const AtomicString& localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
572
573     // Allocate attribute map if necessary.
574     Attribute* old = attributes(false)->getAttributeItem(localName, false);
575
576     document()->incDOMTreeVersion();
577
578     // FIXME: This check is probably not correct for the case where the document has an id attribute
579     // with a non-null namespace, because it will return true if the local name happens to match
580     // but the namespace does not.
581     if (localName == document()->idAttributeName().localName())
582         updateId(old ? old->value() : nullAtom, value);
583
584     if (old && value.isNull())
585         m_attributeMap->removeAttribute(old->name());
586     else if (!old && !value.isNull())
587         m_attributeMap->addAttribute(createAttribute(QualifiedName(nullAtom, localName, nullAtom), value));
588     else if (old && !value.isNull()) {
589         if (Attr* attrNode = old->attr())
590             attrNode->setValue(value);
591         else
592             old->setValue(value);
593         attributeChanged(old);
594     }
595
596 #if ENABLE(INSPECTOR)
597     if (!isSynchronizingStyleAttribute())
598         InspectorInstrumentation::didModifyDOMAttr(document(), this);
599 #endif
600 }
601
602 void Element::setAttribute(const QualifiedName& name, const AtomicString& value, ExceptionCode&)
603 {
604 #if ENABLE(INSPECTOR)
605     if (!isSynchronizingStyleAttribute())
606         InspectorInstrumentation::willModifyDOMAttr(document(), this);
607 #endif
608
609     document()->incDOMTreeVersion();
610
611     // Allocate attribute map if necessary.
612     Attribute* old = attributes(false)->getAttributeItem(name);
613
614     if (isIdAttributeName(name))
615         updateId(old ? old->value() : nullAtom, value);
616
617     if (old && value.isNull())
618         m_attributeMap->removeAttribute(name);
619     else if (!old && !value.isNull())
620         m_attributeMap->addAttribute(createAttribute(name, value));
621     else if (old) {
622         if (Attr* attrNode = old->attr())
623             attrNode->setValue(value);
624         else
625             old->setValue(value);
626         attributeChanged(old);
627     }
628
629 #if ENABLE(INSPECTOR)
630     if (!isSynchronizingStyleAttribute())
631         InspectorInstrumentation::didModifyDOMAttr(document(), this);
632 #endif
633 }
634
635 PassRefPtr<Attribute> Element::createAttribute(const QualifiedName& name, const AtomicString& value)
636 {
637     return Attribute::create(name, value);
638 }
639
640 void Element::attributeChanged(Attribute* attr, bool)
641 {
642     recalcStyleIfNeededAfterAttributeChanged(attr);
643     updateAfterAttributeChanged(attr);
644 }
645
646 void Element::updateAfterAttributeChanged(Attribute* attr)
647 {
648     if (!AXObjectCache::accessibilityEnabled())
649         return;
650
651     const QualifiedName& attrName = attr->name();
652     if (attrName == aria_activedescendantAttr) {
653         // any change to aria-activedescendant attribute triggers accessibility focus change, but document focus remains intact
654         document()->axObjectCache()->handleActiveDescendantChanged(renderer());
655     } else if (attrName == roleAttr) {
656         // the role attribute can change at any time, and the AccessibilityObject must pick up these changes
657         document()->axObjectCache()->handleAriaRoleChanged(renderer());
658     } else if (attrName == aria_valuenowAttr) {
659         // If the valuenow attribute changes, AX clients need to be notified.
660         document()->axObjectCache()->postNotification(renderer(), AXObjectCache::AXValueChanged, true);
661     } else if (attrName == aria_labelAttr || attrName == aria_labeledbyAttr || attrName == altAttr || attrName == titleAttr) {
662         // If the content of an element changes due to an attribute change, notify accessibility.
663         document()->axObjectCache()->contentChanged(renderer());
664     } else if (attrName == aria_selectedAttr)
665         document()->axObjectCache()->selectedChildrenChanged(renderer());
666     else if (attrName == aria_expandedAttr)
667         document()->axObjectCache()->handleAriaExpandedChange(renderer());
668     else if (attrName == aria_hiddenAttr)
669         document()->axObjectCache()->childrenChanged(renderer());
670 }
671     
672 void Element::recalcStyleIfNeededAfterAttributeChanged(Attribute* attr)
673 {
674     if (document()->attached() && document()->styleSelector()->hasSelectorForAttribute(attr->name().localName()))
675         setNeedsStyleRecalc();
676 }
677
678 // Returns true is the given attribute is an event handler.
679 // We consider an event handler any attribute that begins with "on".
680 // It is a simple solution that has the advantage of not requiring any
681 // code or configuration change if a new event handler is defined.
682
683 static bool isEventHandlerAttribute(const QualifiedName& name)
684 {
685     return name.namespaceURI().isNull() && name.localName().startsWith("on");
686 }
687
688 static bool isAttributeToRemove(const QualifiedName& name, const AtomicString& value)
689 {    
690     return (name.localName().endsWith(hrefAttr.localName()) || name == srcAttr || name == actionAttr) && protocolIsJavaScript(stripLeadingAndTrailingHTMLSpaces(value));       
691 }
692
693 void Element::setAttributeMap(PassRefPtr<NamedNodeMap> list, FragmentScriptingPermission scriptingPermission)
694 {
695     document()->incDOMTreeVersion();
696
697     // If setting the whole map changes the id attribute, we need to call updateId.
698
699     const QualifiedName& idName = document()->idAttributeName();
700     Attribute* oldId = m_attributeMap ? m_attributeMap->getAttributeItem(idName) : 0;
701     Attribute* newId = list ? list->getAttributeItem(idName) : 0;
702
703     if (oldId || newId)
704         updateId(oldId ? oldId->value() : nullAtom, newId ? newId->value() : nullAtom);
705
706     if (m_attributeMap)
707         m_attributeMap->m_element = 0;
708
709     m_attributeMap = list;
710
711     if (m_attributeMap) {
712         m_attributeMap->m_element = this;
713         // If the element is created as result of a paste or drag-n-drop operation
714         // we want to remove all the script and event handlers.
715         if (scriptingPermission == FragmentScriptingNotAllowed) {
716             unsigned i = 0;
717             while (i < m_attributeMap->length()) {
718                 const QualifiedName& attributeName = m_attributeMap->m_attributes[i]->name();
719                 if (isEventHandlerAttribute(attributeName)) {
720                     m_attributeMap->m_attributes.remove(i);
721                     continue;
722                 }
723
724                 if (isAttributeToRemove(attributeName, m_attributeMap->m_attributes[i]->value()))
725                     m_attributeMap->m_attributes[i]->setValue(nullAtom);
726                 i++;
727             }
728         }
729         // Store the set of attributes that changed on the stack in case
730         // attributeChanged mutates m_attributeMap.
731         Vector<RefPtr<Attribute> > attributes;
732         m_attributeMap->copyAttributesToVector(attributes);
733         for (Vector<RefPtr<Attribute> >::iterator iter = attributes.begin(); iter != attributes.end(); ++iter)
734             attributeChanged(iter->get());
735         // FIXME: What about attributes that were in the old map that are not in the new map?
736     }
737 }
738
739 bool Element::hasAttributes() const
740 {
741     if (!isStyleAttributeValid())
742         updateStyleAttribute();
743
744 #if ENABLE(SVG)
745     if (!areSVGAttributesValid())
746         updateAnimatedSVGAttribute(anyQName());
747 #endif
748
749     return m_attributeMap && m_attributeMap->length();
750 }
751
752 String Element::nodeName() const
753 {
754     return m_tagName.toString();
755 }
756
757 String Element::nodeNamePreservingCase() const
758 {
759     return m_tagName.toString();
760 }
761
762 void Element::setPrefix(const AtomicString& prefix, ExceptionCode& ec)
763 {
764     ec = 0;
765     checkSetPrefix(prefix, ec);
766     if (ec)
767         return;
768
769     m_tagName.setPrefix(prefix.isEmpty() ? AtomicString() : prefix);
770 }
771
772 KURL Element::baseURI() const
773 {
774     const AtomicString& baseAttribute = getAttribute(baseAttr);
775     KURL base(KURL(), baseAttribute);
776     if (!base.protocol().isEmpty())
777         return base;
778
779     ContainerNode* parent = parentNode();
780     if (!parent)
781         return base;
782
783     const KURL& parentBase = parent->baseURI();
784     if (parentBase.isNull())
785         return base;
786
787     return KURL(parentBase, baseAttribute);
788 }
789
790 void Element::createAttributeMap() const
791 {
792     m_attributeMap = NamedNodeMap::create(const_cast<Element*>(this));
793 }
794
795 bool Element::isURLAttribute(Attribute*) const
796 {
797     return false;
798 }
799
800 const QualifiedName& Element::imageSourceAttributeName() const
801 {
802     return srcAttr;
803 }
804
805 RenderObject* Element::createRenderer(RenderArena* arena, RenderStyle* style)
806 {
807     if (document()->documentElement() == this && style->display() == NONE) {
808         // Ignore display: none on root elements.  Force a display of block in that case.
809         RenderBlock* result = new (arena) RenderBlock(this);
810         if (result)
811             result->setAnimatableStyle(style);
812         return result;
813     }
814     return RenderObject::createObject(this, style);
815 }
816
817
818 void Element::insertedIntoDocument()
819 {
820     // need to do superclass processing first so inDocument() is true
821     // by the time we reach updateId
822     ContainerNode::insertedIntoDocument();
823
824     if (hasID()) {
825         if (m_attributeMap) {
826             Attribute* idItem = m_attributeMap->getAttributeItem(document()->idAttributeName());
827             if (idItem && !idItem->isNull())
828                 updateId(nullAtom, idItem->value());
829         }
830     }
831 }
832
833 void Element::removedFromDocument()
834 {
835     if (hasID()) {
836         if (m_attributeMap) {
837             Attribute* idItem = m_attributeMap->getAttributeItem(document()->idAttributeName());
838             if (idItem && !idItem->isNull())
839                 updateId(idItem->value(), nullAtom);
840         }
841     }
842
843     ContainerNode::removedFromDocument();
844 }
845
846 void Element::attach()
847 {
848     suspendPostAttachCallbacks();
849     RenderWidget::suspendWidgetHierarchyUpdates();
850
851     createRendererIfNeeded();
852     ContainerNode::attach();
853     if (hasRareData()) {   
854         ElementRareData* data = rareData();
855         if (data->needsFocusAppearanceUpdateSoonAfterAttach()) {
856             if (isFocusable() && document()->focusedNode() == this)
857                 document()->updateFocusAppearanceSoon(false /* don't restore selection */);
858             data->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
859         }
860     }
861
862     RenderWidget::resumeWidgetHierarchyUpdates();
863     resumePostAttachCallbacks();
864 }
865
866 void Element::detach()
867 {
868     RenderWidget::suspendWidgetHierarchyUpdates();
869
870     cancelFocusAppearanceUpdate();
871     if (hasRareData())
872         rareData()->resetComputedStyle();
873     ContainerNode::detach();
874
875     RenderWidget::resumeWidgetHierarchyUpdates();
876 }
877
878 bool Element::pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderStyle* newStyle)
879 {
880     ASSERT(currentStyle == renderStyle());
881
882     if (!renderer() || !currentStyle)
883         return false;
884
885     const PseudoStyleCache* pseudoStyleCache = currentStyle->cachedPseudoStyles();
886     if (!pseudoStyleCache)
887         return false;
888
889     size_t cacheSize = pseudoStyleCache->size();
890     for (size_t i = 0; i < cacheSize; ++i) {
891         RefPtr<RenderStyle> newPseudoStyle;
892         PseudoId pseudoId = pseudoStyleCache->at(i)->styleType();
893         if (pseudoId == VISITED_LINK) {
894             newPseudoStyle =  newStyle->getCachedPseudoStyle(VISITED_LINK); // This pseudo-style was aggressively computed already when we first called styleForElement on the new style.
895             if (!newPseudoStyle || *newPseudoStyle != *pseudoStyleCache->at(i))
896                 return true;
897         } else if (pseudoId == FIRST_LINE || pseudoId == FIRST_LINE_INHERITED)
898             newPseudoStyle = renderer()->uncachedFirstLineStyle(newStyle);
899         else
900             newPseudoStyle = renderer()->getUncachedPseudoStyle(pseudoId, newStyle, newStyle);
901         if (!newPseudoStyle)
902             return true;
903         if (*newPseudoStyle != *pseudoStyleCache->at(i)) {
904             if (pseudoId < FIRST_INTERNAL_PSEUDOID)
905                 newStyle->setHasPseudoStyle(pseudoId);
906             newStyle->addCachedPseudoStyle(newPseudoStyle);
907             if (pseudoId == FIRST_LINE || pseudoId == FIRST_LINE_INHERITED) {
908                 // FIXME: We should do an actual diff to determine whether a repaint vs. layout
909                 // is needed, but for now just assume a layout will be required.  The diff code
910                 // in RenderObject::setStyle would need to be factored out so that it could be reused.
911                 renderer()->setNeedsLayoutAndPrefWidthsRecalc();
912             }
913             return true;
914         }
915     }
916     return false;
917 }
918
919 void Element::recalcStyle(StyleChange change)
920 {
921     // Ref currentStyle in case it would otherwise be deleted when setRenderStyle() is called.
922     RefPtr<RenderStyle> currentStyle(renderStyle());
923     bool hasParentStyle = parentNode() ? parentNode()->renderStyle() : false;
924     bool hasPositionalRules = needsStyleRecalc() && currentStyle && currentStyle->childrenAffectedByPositionalRules();
925     bool hasDirectAdjacentRules = currentStyle && currentStyle->childrenAffectedByDirectAdjacentRules();
926
927 #if ENABLE(SVG)
928     if (!hasParentStyle && isShadowNode() && isSVGElement())
929         hasParentStyle = true;
930 #endif
931
932     if ((change > NoChange || needsStyleRecalc())) {
933         if (hasRareData())
934             rareData()->resetComputedStyle();
935     }
936     if (hasParentStyle && (change >= Inherit || needsStyleRecalc())) {
937         RefPtr<RenderStyle> newStyle = document()->styleSelector()->styleForElement(this);
938         StyleChange ch = diff(currentStyle.get(), newStyle.get());
939         if (ch == Detach || !currentStyle) {
940             if (attached())
941                 detach();
942             attach(); // FIXME: The style gets computed twice by calling attach. We could do better if we passed the style along.
943             // attach recalulates the style for all children. No need to do it twice.
944             clearNeedsStyleRecalc();
945             clearChildNeedsStyleRecalc();
946             return;
947         }
948
949         if (currentStyle) {
950             // Preserve "affected by" bits that were propagated to us from descendants in the case where we didn't do a full
951             // style change (e.g., only inline style changed).
952             if (currentStyle->affectedByHoverRules())
953                 newStyle->setAffectedByHoverRules(true);
954             if (currentStyle->affectedByActiveRules())
955                 newStyle->setAffectedByActiveRules(true);
956             if (currentStyle->affectedByDragRules())
957                 newStyle->setAffectedByDragRules(true);
958             if (currentStyle->childrenAffectedByForwardPositionalRules())
959                 newStyle->setChildrenAffectedByForwardPositionalRules();
960             if (currentStyle->childrenAffectedByBackwardPositionalRules())
961                 newStyle->setChildrenAffectedByBackwardPositionalRules();
962             if (currentStyle->childrenAffectedByFirstChildRules())
963                 newStyle->setChildrenAffectedByFirstChildRules();
964             if (currentStyle->childrenAffectedByLastChildRules())
965                 newStyle->setChildrenAffectedByLastChildRules();
966             if (currentStyle->childrenAffectedByDirectAdjacentRules())
967                 newStyle->setChildrenAffectedByDirectAdjacentRules();
968         }
969
970         if (ch != NoChange || pseudoStyleCacheIsInvalid(currentStyle.get(), newStyle.get()) || (change == Force && renderer() && renderer()->requiresForcedStyleRecalcPropagation())) {
971             setRenderStyle(newStyle);
972         } else if (needsStyleRecalc() && (styleChangeType() != SyntheticStyleChange) && (document()->usesSiblingRules() || document()->usesDescendantRules())) {
973             // Although no change occurred, we use the new style so that the cousin style sharing code won't get
974             // fooled into believing this style is the same.  This is only necessary if the document actually uses
975             // sibling/descendant rules, since otherwise it isn't possible for ancestor styles to affect sharing of
976             // descendants.
977             if (renderer())
978                 renderer()->setStyleInternal(newStyle.get());
979             else
980                 setRenderStyle(newStyle);
981         } else if (styleChangeType() == SyntheticStyleChange)
982              setRenderStyle(newStyle);
983
984         if (change != Force) {
985             // 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
986             // 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).
987             if (document()->usesRemUnits() && ch != NoChange && currentStyle && newStyle && currentStyle->fontSize() != newStyle->fontSize() && document()->documentElement() == this)
988                 change = Force;
989             else if ((document()->usesDescendantRules() || hasPositionalRules) && styleChangeType() >= FullStyleChange)
990                 change = Force;
991             else
992                 change = ch;
993         }
994     }
995
996     // FIXME: This check is good enough for :hover + foo, but it is not good enough for :hover + foo + bar.
997     // For now we will just worry about the common case, since it's a lot trickier to get the second case right
998     // without doing way too much re-resolution.
999     bool forceCheckOfNextElementSibling = false;
1000     for (Node *n = firstChild(); n; n = n->nextSibling()) {
1001         bool childRulesChanged = n->needsStyleRecalc() && n->styleChangeType() == FullStyleChange;
1002         if (forceCheckOfNextElementSibling && n->isElementNode())
1003             n->setNeedsStyleRecalc();
1004         if (change >= Inherit || n->isTextNode() || n->childNeedsStyleRecalc() || n->needsStyleRecalc())
1005             n->recalcStyle(change);
1006         if (n->isElementNode())
1007             forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentRules;
1008     }
1009
1010     clearNeedsStyleRecalc();
1011     clearChildNeedsStyleRecalc();
1012 }
1013
1014 bool Element::childTypeAllowed(NodeType type)
1015 {
1016     switch (type) {
1017         case ELEMENT_NODE:
1018         case TEXT_NODE:
1019         case COMMENT_NODE:
1020         case PROCESSING_INSTRUCTION_NODE:
1021         case CDATA_SECTION_NODE:
1022         case ENTITY_REFERENCE_NODE:
1023             return true;
1024             break;
1025         default:
1026             return false;
1027     }
1028 }
1029
1030 static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool finishedParsingCallback,
1031                                         Node* beforeChange, Node* afterChange, int childCountDelta)
1032 {
1033     if (!style || (e->needsStyleRecalc() && style->childrenAffectedByPositionalRules()))
1034         return;
1035
1036     // :first-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
1037     // In the DOM case, we only need to do something if |afterChange| is not 0.
1038     // |afterChange| is 0 in the parser case, so it works out that we'll skip this block.
1039     if (style->childrenAffectedByFirstChildRules() && afterChange) {
1040         // Find our new first child.
1041         Node* newFirstChild = 0;
1042         for (newFirstChild = e->firstChild(); newFirstChild && !newFirstChild->isElementNode(); newFirstChild = newFirstChild->nextSibling()) {};
1043         
1044         // Find the first element node following |afterChange|
1045         Node* firstElementAfterInsertion = 0;
1046         for (firstElementAfterInsertion = afterChange;
1047              firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode();
1048              firstElementAfterInsertion = firstElementAfterInsertion->nextSibling()) {};
1049         
1050         // This is the insert/append case.
1051         if (newFirstChild != firstElementAfterInsertion && firstElementAfterInsertion && firstElementAfterInsertion->attached() &&
1052             firstElementAfterInsertion->renderStyle() && firstElementAfterInsertion->renderStyle()->firstChildState())
1053             firstElementAfterInsertion->setNeedsStyleRecalc();
1054             
1055         // We also have to handle node removal.
1056         if (childCountDelta < 0 && newFirstChild == firstElementAfterInsertion && newFirstChild && newFirstChild->renderStyle() && !newFirstChild->renderStyle()->firstChildState())
1057             newFirstChild->setNeedsStyleRecalc();
1058     }
1059
1060     // :last-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
1061     // In the DOM case, we only need to do something if |afterChange| is not 0.
1062     if (style->childrenAffectedByLastChildRules() && beforeChange) {
1063         // Find our new last child.
1064         Node* newLastChild = 0;
1065         for (newLastChild = e->lastChild(); newLastChild && !newLastChild->isElementNode(); newLastChild = newLastChild->previousSibling()) {};
1066         
1067         // Find the last element node going backwards from |beforeChange|
1068         Node* lastElementBeforeInsertion = 0;
1069         for (lastElementBeforeInsertion = beforeChange;
1070              lastElementBeforeInsertion && !lastElementBeforeInsertion->isElementNode();
1071              lastElementBeforeInsertion = lastElementBeforeInsertion->previousSibling()) {};
1072         
1073         if (newLastChild != lastElementBeforeInsertion && lastElementBeforeInsertion && lastElementBeforeInsertion->attached() &&
1074             lastElementBeforeInsertion->renderStyle() && lastElementBeforeInsertion->renderStyle()->lastChildState())
1075             lastElementBeforeInsertion->setNeedsStyleRecalc();
1076             
1077         // 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
1078         // to match now.
1079         if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild == lastElementBeforeInsertion && newLastChild && newLastChild->renderStyle() && !newLastChild->renderStyle()->lastChildState())
1080             newLastChild->setNeedsStyleRecalc();
1081     }
1082
1083     // The + selector.  We need to invalidate the first element following the insertion point.  It is the only possible element
1084     // that could be affected by this DOM change.
1085     if (style->childrenAffectedByDirectAdjacentRules() && afterChange) {
1086         Node* firstElementAfterInsertion = 0;
1087         for (firstElementAfterInsertion = afterChange;
1088              firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode();
1089              firstElementAfterInsertion = firstElementAfterInsertion->nextSibling()) {};
1090         if (firstElementAfterInsertion && firstElementAfterInsertion->attached())
1091             firstElementAfterInsertion->setNeedsStyleRecalc();
1092     }
1093
1094     // Forward positional selectors include the ~ selector, nth-child, nth-of-type, first-of-type and only-of-type.
1095     // Backward positional selectors include nth-last-child, nth-last-of-type, last-of-type and only-of-type.
1096     // We have to invalidate everything following the insertion point in the forward case, and everything before the insertion point in the
1097     // backward case.
1098     // |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.
1099     // 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
1100     // here.  recalcStyle will then force a walk of the children when it sees that this has happened.
1101     if ((style->childrenAffectedByForwardPositionalRules() && afterChange) ||
1102         (style->childrenAffectedByBackwardPositionalRules() && beforeChange))
1103         e->setNeedsStyleRecalc();
1104     
1105     // :empty selector.
1106     if (style->affectedByEmpty() && (!style->emptyState() || e->hasChildNodes()))
1107         e->setNeedsStyleRecalc();
1108 }
1109
1110 void Element::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
1111 {
1112     ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
1113     if (!changedByParser)
1114         checkForSiblingStyleChanges(this, renderStyle(), false, beforeChange, afterChange, childCountDelta);
1115 }
1116
1117 void Element::finishParsingChildren()
1118 {
1119     ContainerNode::finishParsingChildren();
1120     setIsParsingChildrenFinished();
1121     checkForSiblingStyleChanges(this, renderStyle(), true, lastChild(), 0, 0);
1122 }
1123
1124 void Element::dispatchAttrRemovalEvent(Attribute*)
1125 {
1126     ASSERT(!eventDispatchForbidden());
1127
1128 #if 0
1129     if (!document()->hasListenerType(Document::DOMATTRMODIFIED_LISTENER))
1130         return;
1131     ExceptionCode ec = 0;
1132     dispatchEvent(MutationEvent::create(DOMAttrModifiedEvent, true, attr, attr->value(),
1133         attr->value(), document()->attrName(attr->id()), MutationEvent::REMOVAL), ec);
1134 #endif
1135 }
1136
1137 void Element::dispatchAttrAdditionEvent(Attribute*)
1138 {
1139     ASSERT(!eventDispatchForbidden());
1140
1141 #if 0
1142     if (!document()->hasListenerType(Document::DOMATTRMODIFIED_LISTENER))
1143         return;
1144     ExceptionCode ec = 0;
1145     dispatchEvent(MutationEvent::create(DOMAttrModifiedEvent, true, attr, attr->value(),
1146         attr->value(), document()->attrName(attr->id()), MutationEvent::ADDITION), ec);
1147 #endif
1148 }
1149
1150 String Element::openTagStartToString() const
1151 {
1152     String result = "<" + nodeName();
1153
1154     NamedNodeMap* attrMap = attributes(true);
1155
1156     if (attrMap) {
1157         unsigned numAttrs = attrMap->length();
1158         for (unsigned i = 0; i < numAttrs; i++) {
1159             result += " ";
1160
1161             Attribute *attribute = attrMap->attributeItem(i);
1162             result += attribute->name().toString();
1163             if (!attribute->value().isNull()) {
1164                 result += "=\"";
1165                 // FIXME: substitute entities for any instances of " or '
1166                 result += attribute->value();
1167                 result += "\"";
1168             }
1169         }
1170     }
1171
1172     return result;
1173 }
1174
1175 #ifndef NDEBUG
1176 void Element::formatForDebugger(char* buffer, unsigned length) const
1177 {
1178     String result;
1179     String s;
1180     
1181     s = nodeName();
1182     if (s.length() > 0) {
1183         result += s;
1184     }
1185           
1186     s = getIdAttribute();
1187     if (s.length() > 0) {
1188         if (result.length() > 0)
1189             result += "; ";
1190         result += "id=";
1191         result += s;
1192     }
1193           
1194     s = getAttribute(classAttr);
1195     if (s.length() > 0) {
1196         if (result.length() > 0)
1197             result += "; ";
1198         result += "class=";
1199         result += s;
1200     }
1201           
1202     strncpy(buffer, result.utf8().data(), length - 1);
1203 }
1204 #endif
1205
1206 PassRefPtr<Attr> Element::setAttributeNode(Attr* attr, ExceptionCode& ec)
1207 {
1208     if (!attr) {
1209         ec = TYPE_MISMATCH_ERR;
1210         return 0;
1211     }
1212     return static_pointer_cast<Attr>(attributes(false)->setNamedItem(attr, ec));
1213 }
1214
1215 PassRefPtr<Attr> Element::setAttributeNodeNS(Attr* attr, ExceptionCode& ec)
1216 {
1217     if (!attr) {
1218         ec = TYPE_MISMATCH_ERR;
1219         return 0;
1220     }
1221     return static_pointer_cast<Attr>(attributes(false)->setNamedItem(attr, ec));
1222 }
1223
1224 PassRefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionCode& ec)
1225 {
1226     if (!attr) {
1227         ec = TYPE_MISMATCH_ERR;
1228         return 0;
1229     }
1230     if (attr->ownerElement() != this) {
1231         ec = NOT_FOUND_ERR;
1232         return 0;
1233     }
1234     if (document() != attr->document()) {
1235         ec = WRONG_DOCUMENT_ERR;
1236         return 0;
1237     }
1238
1239     NamedNodeMap* attrs = attributes(true);
1240     if (!attrs)
1241         return 0;
1242
1243     return static_pointer_cast<Attr>(attrs->removeNamedItem(attr->qualifiedName(), ec));
1244 }
1245
1246 void Element::setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode& ec, FragmentScriptingPermission scriptingPermission)
1247 {
1248     String prefix, localName;
1249     if (!Document::parseQualifiedName(qualifiedName, prefix, localName, ec))
1250         return;
1251
1252     if (namespaceURI.isNull() && !prefix.isNull()) {
1253         ec = NAMESPACE_ERR;
1254         return;
1255     }
1256
1257     QualifiedName qName(prefix, localName, namespaceURI);
1258
1259     if (scriptingPermission == FragmentScriptingNotAllowed && (isEventHandlerAttribute(qName) || isAttributeToRemove(qName, value)))
1260         return;
1261
1262     setAttribute(qName, value, ec);
1263 }
1264
1265 void Element::removeAttribute(const String& name, ExceptionCode& ec)
1266 {
1267     InspectorInstrumentation::willModifyDOMAttr(document(), this);
1268
1269     String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
1270
1271     if (m_attributeMap) {
1272         m_attributeMap->removeNamedItem(localName, ec);
1273         if (ec == NOT_FOUND_ERR)
1274             ec = 0;
1275     }
1276     
1277     InspectorInstrumentation::didModifyDOMAttr(document(), this);
1278 }
1279
1280 void Element::removeAttributeNS(const String& namespaceURI, const String& localName, ExceptionCode& ec)
1281 {
1282     removeAttribute(QualifiedName(nullAtom, localName, namespaceURI), ec);
1283 }
1284
1285 PassRefPtr<Attr> Element::getAttributeNode(const String& name)
1286 {
1287     NamedNodeMap* attrs = attributes(true);
1288     if (!attrs)
1289         return 0;
1290     String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
1291     return static_pointer_cast<Attr>(attrs->getNamedItem(localName));
1292 }
1293
1294 PassRefPtr<Attr> Element::getAttributeNodeNS(const String& namespaceURI, const String& localName)
1295 {
1296     NamedNodeMap* attrs = attributes(true);
1297     if (!attrs)
1298         return 0;
1299     return static_pointer_cast<Attr>(attrs->getNamedItem(QualifiedName(nullAtom, localName, namespaceURI)));
1300 }
1301
1302 bool Element::hasAttribute(const String& name) const
1303 {
1304     NamedNodeMap* attrs = attributes(true);
1305     if (!attrs)
1306         return false;
1307
1308     // This call to String::lower() seems to be required but
1309     // there may be a way to remove it.
1310     String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
1311     return attrs->getAttributeItem(localName, false);
1312 }
1313
1314 bool Element::hasAttributeNS(const String& namespaceURI, const String& localName) const
1315 {
1316     NamedNodeMap* attrs = attributes(true);
1317     if (!attrs)
1318         return false;
1319     return attrs->getAttributeItem(QualifiedName(nullAtom, localName, namespaceURI));
1320 }
1321
1322 CSSStyleDeclaration *Element::style()
1323 {
1324     return 0;
1325 }
1326
1327 void Element::focus(bool restorePreviousSelection)
1328 {
1329     Document* doc = document();
1330     if (doc->focusedNode() == this)
1331         return;
1332
1333     // If the stylesheets have already been loaded we can reliably check isFocusable.
1334     // If not, we continue and set the focused node on the focus controller below so
1335     // that it can be updated soon after attach. 
1336     if (doc->haveStylesheetsLoaded()) {
1337         doc->updateLayoutIgnorePendingStylesheets();
1338         if (!isFocusable())
1339             return;
1340     }
1341
1342     if (!supportsFocus())
1343         return;
1344
1345     RefPtr<Node> protect;
1346     if (Page* page = doc->page()) {
1347         // Focus and change event handlers can cause us to lose our last ref.
1348         // If a focus event handler changes the focus to a different node it
1349         // does not make sense to continue and update appearence.
1350         protect = this;
1351         if (!page->focusController()->setFocusedNode(this, doc->frame()))
1352             return;
1353     }
1354
1355     // Setting the focused node above might have invalidated the layout due to scripts.
1356     doc->updateLayoutIgnorePendingStylesheets();
1357
1358     if (!isFocusable()) {
1359         ensureRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(true);
1360         return;
1361     }
1362         
1363     cancelFocusAppearanceUpdate();
1364     updateFocusAppearance(restorePreviousSelection);
1365 }
1366
1367 void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
1368 {
1369     if (this == rootEditableElement()) { 
1370         Frame* frame = document()->frame();
1371         if (!frame)
1372             return;
1373         
1374         // When focusing an editable element in an iframe, don't reset the selection if it already contains a selection.
1375         if (this == frame->selection()->rootEditableElement())
1376             return;
1377
1378         // FIXME: We should restore the previous selection if there is one.
1379         VisibleSelection newSelection = VisibleSelection(Position(this, 0), DOWNSTREAM);
1380         
1381         if (frame->selection()->shouldChangeSelection(newSelection)) {
1382             frame->selection()->setSelection(newSelection);
1383             frame->selection()->revealSelection();
1384         }
1385     } else if (renderer() && !renderer()->isWidget())
1386         renderer()->enclosingLayer()->scrollRectToVisible(getRect());
1387 }
1388
1389 void Element::blur()
1390 {
1391     cancelFocusAppearanceUpdate();
1392     Document* doc = document();
1393     if (doc->focusedNode() == this) {
1394         if (doc->frame())
1395             doc->frame()->page()->focusController()->setFocusedNode(0, doc->frame());
1396         else
1397             doc->setFocusedNode(0);
1398     }
1399 }
1400
1401 String Element::innerText() const
1402 {
1403     // We need to update layout, since plainText uses line boxes in the render tree.
1404     document()->updateLayoutIgnorePendingStylesheets();
1405
1406     if (!renderer())
1407         return textContent(true);
1408
1409     return plainText(rangeOfContents(const_cast<Element*>(this)).get());
1410 }
1411
1412 String Element::outerText() const
1413 {
1414     // Getting outerText is the same as getting innerText, only
1415     // setting is different. You would think this should get the plain
1416     // text for the outer range, but this is wrong, <br> for instance
1417     // would return different values for inner and outer text by such
1418     // a rule, but it doesn't in WinIE, and we want to match that.
1419     return innerText();
1420 }
1421
1422 String Element::title() const
1423 {
1424     return String();
1425 }
1426
1427 IntSize Element::minimumSizeForResizing() const
1428 {
1429     return hasRareData() ? rareData()->m_minimumSizeForResizing : defaultMinimumSizeForResizing();
1430 }
1431
1432 void Element::setMinimumSizeForResizing(const IntSize& size)
1433 {
1434     if (size == defaultMinimumSizeForResizing() && !hasRareData())
1435         return;
1436     ensureRareData()->m_minimumSizeForResizing = size;
1437 }
1438
1439 RenderStyle* Element::computedStyle(PseudoId pseudoElementSpecifier)
1440 {
1441     // FIXME: Find and use the renderer from the pseudo element instead of the actual element so that the 'length'
1442     // properties, which are only known by the renderer because it did the layout, will be correct and so that the
1443     // values returned for the ":selection" pseudo-element will be correct.
1444     if (RenderStyle* usedStyle = renderStyle())
1445         return pseudoElementSpecifier ? usedStyle->getCachedPseudoStyle(pseudoElementSpecifier) : usedStyle;
1446
1447     if (!attached())
1448         // FIXME: Try to do better than this. Ensure that styleForElement() works for elements that are not in the
1449         // document tree and figure out when to destroy the computed style for such elements.
1450         return 0;
1451
1452     ElementRareData* data = ensureRareData();
1453     if (!data->m_computedStyle)
1454         data->m_computedStyle = document()->styleForElementIgnoringPendingStylesheets(this);
1455     return pseudoElementSpecifier ? data->m_computedStyle->getCachedPseudoStyle(pseudoElementSpecifier) : data->m_computedStyle.get();
1456 }
1457
1458 AtomicString Element::computeInheritedLanguage() const
1459 {
1460     const Node* n = this;
1461     AtomicString value;
1462     // The language property is inherited, so we iterate over the parents to find the first language.
1463     while (n && value.isNull()) {
1464         if (n->isElementNode()) {
1465             // Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7
1466             value = static_cast<const Element*>(n)->fastGetAttribute(XMLNames::langAttr);
1467             if (value.isNull())
1468                 value = static_cast<const Element*>(n)->fastGetAttribute(HTMLNames::langAttr);
1469         } else if (n->isDocumentNode()) {
1470             // checking the MIME content-language
1471             value = static_cast<const Document*>(n)->contentLanguage();
1472         }
1473
1474         n = n->parent();
1475     }
1476
1477     return value;
1478 }
1479
1480 void Element::cancelFocusAppearanceUpdate()
1481 {
1482     if (hasRareData())
1483         rareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
1484     if (document()->focusedNode() == this)
1485         document()->cancelFocusAppearanceUpdate();
1486 }
1487
1488 void Element::normalizeAttributes()
1489 {
1490     // Normalize attributes.
1491     NamedNodeMap* attrs = attributes(true);
1492     if (!attrs)
1493         return;
1494
1495     if (attrs->isEmpty())
1496         return;
1497
1498     Vector<RefPtr<Attribute> > attributeVector;
1499     attrs->copyAttributesToVector(attributeVector);
1500     size_t numAttrs = attributeVector.size();
1501     for (size_t i = 0; i < numAttrs; ++i) {
1502         if (Attr* attr = attributeVector[i]->attr())
1503             attr->normalize();
1504     }
1505 }
1506
1507 // ElementTraversal API
1508 Element* Element::firstElementChild() const
1509 {
1510     Node* n = firstChild();
1511     while (n && !n->isElementNode())
1512         n = n->nextSibling();
1513     return static_cast<Element*>(n);
1514 }
1515
1516 Element* Element::lastElementChild() const
1517 {
1518     Node* n = lastChild();
1519     while (n && !n->isElementNode())
1520         n = n->previousSibling();
1521     return static_cast<Element*>(n);
1522 }
1523
1524 Element* Element::previousElementSibling() const
1525 {
1526     Node* n = previousSibling();
1527     while (n && !n->isElementNode())
1528         n = n->previousSibling();
1529     return static_cast<Element*>(n);
1530 }
1531
1532 Element* Element::nextElementSibling() const
1533 {
1534     Node* n = nextSibling();
1535     while (n && !n->isElementNode())
1536         n = n->nextSibling();
1537     return static_cast<Element*>(n);
1538 }
1539
1540 unsigned Element::childElementCount() const
1541 {
1542     unsigned count = 0;
1543     Node* n = firstChild();
1544     while (n) {
1545         count += n->isElementNode();
1546         n = n->nextSibling();
1547     }
1548     return count;
1549 }
1550
1551 bool Element::webkitMatchesSelector(const String& selector, ExceptionCode& ec)
1552 {
1553     if (selector.isEmpty()) {
1554         ec = SYNTAX_ERR;
1555         return false;
1556     }
1557
1558     bool strictParsing = !document()->inQuirksMode();
1559     CSSParser p(strictParsing);
1560
1561     CSSSelectorList selectorList;
1562     p.parseSelector(selector, document(), selectorList);
1563
1564     if (!selectorList.first()) {
1565         ec = SYNTAX_ERR;
1566         return false;
1567     }
1568
1569     // Throw a NAMESPACE_ERR if the selector includes any namespace prefixes.
1570     if (selectorList.selectorsNeedNamespaceResolution()) {
1571         ec = NAMESPACE_ERR;
1572         return false;
1573     }
1574
1575     CSSStyleSelector::SelectorChecker selectorChecker(document(), strictParsing);
1576     for (CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector)) {
1577         if (selectorChecker.checkSelector(selector, this))
1578             return true;
1579     }
1580
1581     return false;
1582 }
1583
1584 DOMTokenList* Element::classList()
1585 {
1586     ElementRareData* data = ensureRareData();
1587     if (!data->m_classList)
1588         data->m_classList = DOMTokenList::create(this);
1589     return data->m_classList.get();
1590 }
1591
1592 DOMTokenList* Element::optionalClassList() const
1593 {
1594     if (!hasRareData())
1595         return 0;
1596     return rareData()->m_classList.get();
1597 }
1598
1599 DOMStringMap* Element::dataset()
1600 {
1601     ElementRareData* data = ensureRareData();
1602     if (!data->m_datasetDOMStringMap)
1603         data->m_datasetDOMStringMap = DatasetDOMStringMap::create(this);
1604     return data->m_datasetDOMStringMap.get();
1605 }
1606
1607 DOMStringMap* Element::optionalDataset() const
1608 {
1609     if (!hasRareData())
1610         return 0;
1611     return rareData()->m_datasetDOMStringMap.get();
1612 }
1613
1614 KURL Element::getURLAttribute(const QualifiedName& name) const
1615 {
1616 #if !ASSERT_DISABLED
1617     if (m_attributeMap) {
1618         if (Attribute* attribute = m_attributeMap->getAttributeItem(name))
1619             ASSERT(isURLAttribute(attribute));
1620     }
1621 #endif
1622     return document()->completeURL(stripLeadingAndTrailingHTMLSpaces(getAttribute(name)));
1623 }
1624
1625 KURL Element::getNonEmptyURLAttribute(const QualifiedName& name) const
1626 {
1627 #if !ASSERT_DISABLED
1628     if (m_attributeMap) {
1629         if (Attribute* attribute = m_attributeMap->getAttributeItem(name))
1630             ASSERT(isURLAttribute(attribute));
1631     }
1632 #endif
1633     String value = stripLeadingAndTrailingHTMLSpaces(getAttribute(name));
1634     if (value.isEmpty())
1635         return KURL();
1636     return document()->completeURL(value);
1637 }
1638
1639 int Element::getIntegralAttribute(const QualifiedName& attributeName) const
1640 {
1641     return getAttribute(attributeName).string().toInt();
1642 }
1643
1644 void Element::setIntegralAttribute(const QualifiedName& attributeName, int value)
1645 {
1646     // FIXME: Need an AtomicString version of String::number.
1647     ExceptionCode ec;
1648     setAttribute(attributeName, String::number(value), ec);
1649 }
1650
1651 unsigned Element::getUnsignedIntegralAttribute(const QualifiedName& attributeName) const
1652 {
1653     return getAttribute(attributeName).string().toUInt();
1654 }
1655
1656 void Element::setUnsignedIntegralAttribute(const QualifiedName& attributeName, unsigned value)
1657 {
1658     // FIXME: Need an AtomicString version of String::number.
1659     ExceptionCode ec;
1660     setAttribute(attributeName, String::number(value), ec);
1661 }
1662
1663 #if ENABLE(SVG)
1664 bool Element::childShouldCreateRenderer(Node* child) const
1665 {
1666     // Only create renderers for SVG elements whose parents are SVG elements, or for proper <svg xmlns="svgNS"> subdocuments.
1667     if (child->isSVGElement())
1668         return child->hasTagName(SVGNames::svgTag) || isSVGElement();
1669
1670     return Node::childShouldCreateRenderer(child);
1671 }
1672 #endif
1673     
1674 #if ENABLE(FULLSCREEN_API)
1675 void Element::webkitRequestFullScreen(unsigned short flags)
1676 {
1677     document()->webkitRequestFullScreenForElement(this, flags);
1678 }
1679 #endif    
1680
1681 } // namespace WebCore