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