WebCore:
[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 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 "CSSStyleSelector.h"
31 #include "CString.h"
32 #include "ClientRect.h"
33 #include "ClientRectList.h"
34 #include "Document.h"
35 #include "Editor.h"
36 #include "ElementRareData.h"
37 #include "ExceptionCode.h"
38 #include "FocusController.h"
39 #include "Frame.h"
40 #include "FrameView.h"
41 #include "HTMLElement.h"
42 #include "HTMLNames.h"
43 #include "NamedAttrMap.h"
44 #include "NodeList.h"
45 #include "NodeRenderStyle.h"
46 #include "Page.h"
47 #include "PlatformString.h"
48 #include "RenderBlock.h"
49 #if ENABLE(SVG)
50 #include "SVGNames.h"
51 #endif
52 #include "SelectionController.h"
53 #include "TextIterator.h"
54 #include "XMLNames.h"
55
56 namespace WebCore {
57
58 using namespace HTMLNames;
59 using namespace XMLNames;
60     
61 Element::Element(const QualifiedName& tagName, Document* doc)
62     : ContainerNode(doc, true)
63     , m_tagName(tagName)
64 {
65 }
66
67 Element::~Element()
68 {
69     if (namedAttrMap)
70         namedAttrMap->detachFromElement();
71 }
72
73 inline ElementRareData* Element::rareData() const
74 {
75     ASSERT(hasRareData());
76     return static_cast<ElementRareData*>(NodeRareData::rareDataFromMap(this));
77 }
78     
79 inline ElementRareData* Element::ensureRareData()
80 {
81     return static_cast<ElementRareData*>(Node::ensureRareData());
82 }
83     
84 NodeRareData* Element::createRareData()
85 {
86     return new ElementRareData;
87 }
88     
89 PassRefPtr<Node> Element::cloneNode(bool deep)
90 {
91     RefPtr<Element> clone = document()->createElement(tagQName(), false);
92     // This will catch HTML elements in the wrong namespace that are not correctly copied.
93     // This is a sanity check as HTML overloads some of the DOM methods.
94     ASSERT(isHTMLElement() == clone->isHTMLElement());
95
96     // Clone attributes.
97     if (namedAttrMap)
98         clone->attributes()->setAttributes(*namedAttrMap);
99
100     clone->copyNonAttributeProperties(this);
101     
102     if (deep)
103         cloneChildNodes(clone.get());
104
105     return clone.release();
106 }
107
108 PassRefPtr<Element> Element::cloneElement()
109 {
110     return static_pointer_cast<Element>(cloneNode(false));
111 }
112
113 void Element::removeAttribute(const QualifiedName& name, ExceptionCode& ec)
114 {
115     if (namedAttrMap) {
116         namedAttrMap->removeNamedItem(name, ec);
117         if (ec == NOT_FOUND_ERR)
118             ec = 0;
119     }
120 }
121
122 void Element::setAttribute(const QualifiedName& name, const AtomicString& value)
123 {
124     ExceptionCode ec;
125     setAttribute(name, value, ec);
126 }
127
128 void Element::setBooleanAttribute(const QualifiedName& name, bool b)
129 {
130     if (b)
131         setAttribute(name, name.localName());
132     else {
133         ExceptionCode ex;
134         removeAttribute(name, ex);
135     }
136 }
137
138 // Virtual function, defined in base class.
139 NamedAttrMap* Element::attributes() const
140 {
141     return attributes(false);
142 }
143
144 NamedAttrMap* Element::attributes(bool readonly) const
145 {
146     if (!m_isStyleAttributeValid)
147         updateStyleAttribute();
148
149 #if ENABLE(SVG)
150     if (!m_areSVGAttributesValid)
151         updateAnimatedSVGAttribute(String());
152 #endif
153
154     if (!readonly && !namedAttrMap)
155         createAttributeMap();
156     return namedAttrMap.get();
157 }
158
159 Node::NodeType Element::nodeType() const
160 {
161     return ELEMENT_NODE;
162 }
163
164 const AtomicString& Element::getIDAttribute() const
165 {
166     return namedAttrMap ? namedAttrMap->id() : nullAtom;
167 }
168
169 bool Element::hasAttribute(const QualifiedName& name) const
170 {
171     return hasAttributeNS(name.namespaceURI(), name.localName());
172 }
173
174 const AtomicString& Element::getAttribute(const QualifiedName& name) const
175 {
176     if (name == styleAttr && !m_isStyleAttributeValid)
177         updateStyleAttribute();
178
179 #if ENABLE(SVG)
180     if (!m_areSVGAttributesValid)
181         updateAnimatedSVGAttribute(name.localName());
182 #endif
183
184     if (namedAttrMap)
185         if (Attribute* a = namedAttrMap->getAttributeItem(name))
186             return a->value();
187
188     return nullAtom;
189 }
190
191 void Element::scrollIntoView(bool alignToTop) 
192 {
193     document()->updateLayoutIgnorePendingStylesheets();
194     IntRect bounds = getRect();    
195     if (renderer()) {
196         // Align to the top / bottom and to the closest edge.
197         if (alignToTop)
198             renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignTopAlways);
199         else
200             renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignBottomAlways);
201     }
202 }
203
204 void Element::scrollIntoViewIfNeeded(bool centerIfNeeded)
205 {
206     document()->updateLayoutIgnorePendingStylesheets();
207     IntRect bounds = getRect();    
208     if (renderer()) {
209         if (centerIfNeeded)
210             renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, RenderLayer::gAlignCenterIfNeeded, RenderLayer::gAlignCenterIfNeeded);
211         else
212             renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignToEdgeIfNeeded);
213     }
214 }
215
216 void Element::scrollByUnits(int units, ScrollGranularity granularity)
217 {
218     document()->updateLayoutIgnorePendingStylesheets();
219     if (RenderObject *rend = renderer()) {
220         if (rend->hasOverflowClip()) {
221             ScrollDirection direction = ScrollDown;
222             if (units < 0) {
223                 direction = ScrollUp;
224                 units = -units;
225             }
226             toRenderBox(rend)->layer()->scroll(direction, granularity, units);
227         }
228     }
229 }
230
231 void Element::scrollByLines(int lines)
232 {
233     scrollByUnits(lines, ScrollByLine);
234 }
235
236 void Element::scrollByPages(int pages)
237 {
238     scrollByUnits(pages, ScrollByPage);
239 }
240
241 static float localZoomForRenderer(RenderObject* renderer)
242 {
243     // FIXME: This does the wrong thing if two opposing zooms are in effect and canceled each
244     // other out, but the alternative is that we'd have to crawl up the whole render tree every
245     // time (or store an additional bit in the RenderStyle to indicate that a zoom was specified).
246     float zoomFactor = 1.0f;
247     if (renderer->style()->effectiveZoom() != 1.0f) {
248         // Need to find the nearest enclosing RenderObject that set up
249         // a differing zoom, and then we divide our result by it to eliminate the zoom.
250         RenderObject* prev = renderer;
251         for (RenderObject* curr = prev->parent(); curr; curr = curr->parent()) {
252             if (curr->style()->effectiveZoom() != prev->style()->effectiveZoom()) {
253                 zoomFactor = prev->style()->zoom();
254                 break;
255             }
256             prev = curr;
257         }
258         if (prev->isRenderView())
259             zoomFactor = prev->style()->zoom();
260     }
261     return zoomFactor;
262 }
263
264 static int adjustForLocalZoom(int value, RenderObject* renderer)
265 {
266     float zoomFactor = localZoomForRenderer(renderer);
267     if (zoomFactor == 1.0f)
268         return value;
269     return static_cast<int>(value / zoomFactor);
270 }
271
272 static int adjustForAbsoluteZoom(int value, RenderObject* renderer)
273 {
274     float zoomFactor = renderer->style()->effectiveZoom();
275     if (zoomFactor == 1.0f)
276         return value;
277     return static_cast<int>(value / zoomFactor);
278 }
279
280 int Element::offsetLeft()
281 {
282     document()->updateLayoutIgnorePendingStylesheets();
283     if (RenderBoxModelObject* rend = renderBoxModelObject())
284         return adjustForLocalZoom(rend->offsetLeft(), rend);
285     return 0;
286 }
287
288 int Element::offsetTop()
289 {
290     document()->updateLayoutIgnorePendingStylesheets();
291     if (RenderBoxModelObject* rend = renderBoxModelObject())
292         return adjustForLocalZoom(rend->offsetTop(), rend);
293     return 0;
294 }
295
296 int Element::offsetWidth()
297 {
298     document()->updateLayoutIgnorePendingStylesheets();
299     if (RenderBoxModelObject* rend = renderBoxModelObject())
300         return adjustForAbsoluteZoom(rend->offsetWidth(), rend);
301     return 0;
302 }
303
304 int Element::offsetHeight()
305 {
306     document()->updateLayoutIgnorePendingStylesheets();
307     if (RenderBoxModelObject* rend = renderBoxModelObject())
308         return adjustForAbsoluteZoom(rend->offsetHeight(), rend);
309     return 0;
310 }
311
312 Element* Element::offsetParent()
313 {
314     document()->updateLayoutIgnorePendingStylesheets();
315     if (RenderObject* rend = renderer())
316         if (RenderObject* offsetParent = rend->offsetParent())
317             return static_cast<Element*>(offsetParent->node());
318     return 0;
319 }
320
321 int Element::clientLeft()
322 {
323     document()->updateLayoutIgnorePendingStylesheets();
324
325     if (RenderBox* rend = renderBox())
326         return adjustForAbsoluteZoom(rend->clientLeft(), rend);
327     return 0;
328 }
329
330 int Element::clientTop()
331 {
332     document()->updateLayoutIgnorePendingStylesheets();
333
334     if (RenderBox* rend = renderBox())
335         return adjustForAbsoluteZoom(rend->clientTop(), rend);
336     return 0;
337 }
338
339 int Element::clientWidth()
340 {
341     document()->updateLayoutIgnorePendingStylesheets();
342
343     // When in strict mode, clientWidth for the document element should return the width of the containing frame.
344     // When in quirks mode, clientWidth for the body element should return the width of the containing frame.
345     bool inCompatMode = document()->inCompatMode();
346     if ((!inCompatMode && document()->documentElement() == this) ||
347         (inCompatMode && isHTMLElement() && document()->body() == this)) {
348         if (FrameView* view = document()->view())
349             return adjustForAbsoluteZoom(view->layoutWidth(), document()->renderer());
350     }
351     
352     if (RenderBox* rend = renderBox())
353         return adjustForAbsoluteZoom(rend->clientWidth(), rend);
354     return 0;
355 }
356
357 int Element::clientHeight()
358 {
359     document()->updateLayoutIgnorePendingStylesheets();
360
361     // When in strict mode, clientHeight for the document element should return the height of the containing frame.
362     // When in quirks mode, clientHeight for the body element should return the height of the containing frame.
363     bool inCompatMode = document()->inCompatMode();     
364
365     if ((!inCompatMode && document()->documentElement() == this) ||
366         (inCompatMode && isHTMLElement() && document()->body() == this)) {
367         if (FrameView* view = document()->view())
368             return adjustForAbsoluteZoom(view->layoutHeight(), document()->renderer());
369     }
370     
371     if (RenderBox* rend = renderBox())
372         return adjustForAbsoluteZoom(rend->clientHeight(), rend);
373     return 0;
374 }
375
376 int Element::scrollLeft()
377 {
378     document()->updateLayoutIgnorePendingStylesheets();
379     if (RenderBox* rend = renderBox())
380         return adjustForAbsoluteZoom(rend->scrollLeft(), rend);
381     return 0;
382 }
383
384 int Element::scrollTop()
385 {
386     document()->updateLayoutIgnorePendingStylesheets();
387     if (RenderBox* rend = renderBox())
388         return adjustForAbsoluteZoom(rend->scrollTop(), rend);
389     return 0;
390 }
391
392 void Element::setScrollLeft(int newLeft)
393 {
394     document()->updateLayoutIgnorePendingStylesheets();
395     if (RenderBox* rend = renderBox())
396         rend->setScrollLeft(static_cast<int>(newLeft * rend->style()->effectiveZoom()));
397 }
398
399 void Element::setScrollTop(int newTop)
400 {
401     document()->updateLayoutIgnorePendingStylesheets();
402     if (RenderBox* rend = renderBox())
403         rend->setScrollTop(static_cast<int>(newTop * rend->style()->effectiveZoom()));
404 }
405
406 int Element::scrollWidth()
407 {
408     document()->updateLayoutIgnorePendingStylesheets();
409     if (RenderBox* rend = renderBox())
410         return adjustForAbsoluteZoom(rend->scrollWidth(), rend);
411     return 0;
412 }
413
414 int Element::scrollHeight()
415 {
416     document()->updateLayoutIgnorePendingStylesheets();
417     if (RenderBox* rend = renderBox())
418         return adjustForAbsoluteZoom(rend->scrollHeight(), rend);
419     return 0;
420 }
421
422 PassRefPtr<ClientRectList> Element::getClientRects() const
423 {
424     document()->updateLayoutIgnorePendingStylesheets();
425
426     RenderBoxModelObject* renderBoxModelObject = this->renderBoxModelObject();
427     if (!renderBoxModelObject)
428         return ClientRectList::create();
429
430     // FIXME: Handle SVG elements.
431     // FIXME: Handle table/inline-table with a caption.
432
433     Vector<FloatQuad> quads;
434     renderBoxModelObject->absoluteQuads(quads);
435
436     if (FrameView* view = document()->view()) {
437         IntRect visibleContentRect = view->visibleContentRect();
438         for (size_t i = 0; i < quads.size(); ++i)
439             quads[i].move(-visibleContentRect.x(), -visibleContentRect.y());
440     }
441
442     return ClientRectList::create(quads);
443 }
444
445 PassRefPtr<ClientRect> Element::getBoundingClientRect() const
446 {
447     document()->updateLayoutIgnorePendingStylesheets();
448     RenderBoxModelObject* renderBoxModelObject = this->renderBoxModelObject();
449     if (!renderBoxModelObject)
450         return ClientRect::create();
451
452     Vector<FloatQuad> quads;
453     renderBoxModelObject->absoluteQuads(quads);
454
455     if (quads.isEmpty())
456         return ClientRect::create();
457
458     IntRect result = quads[0].enclosingBoundingBox();
459     for (size_t i = 1; i < quads.size(); ++i)
460         result.unite(quads[i].enclosingBoundingBox());
461
462     if (FrameView* view = document()->view()) {
463         IntRect visibleContentRect = view->visibleContentRect();
464         result.move(-visibleContentRect.x(), -visibleContentRect.y());
465     }
466
467     return ClientRect::create(result);
468 }
469
470 static inline bool shouldIgnoreAttributeCase(const Element* e)
471 {
472     return e && e->document()->isHTMLDocument() && e->isHTMLElement();
473 }
474
475 const AtomicString& Element::getAttribute(const String& name) const
476 {
477     String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
478     if (localName == styleAttr.localName() && !m_isStyleAttributeValid)
479         updateStyleAttribute();
480
481 #if ENABLE(SVG)
482     if (!m_areSVGAttributesValid)
483         updateAnimatedSVGAttribute(name);
484 #endif
485
486     if (namedAttrMap)
487         if (Attribute* a = namedAttrMap->getAttributeItem(name, shouldIgnoreAttributeCase(this)))
488             return a->value();
489     
490     return nullAtom;
491 }
492
493 const AtomicString& Element::getAttributeNS(const String& namespaceURI, const String& localName) const
494 {
495     return getAttribute(QualifiedName(nullAtom, localName, namespaceURI));
496 }
497
498 void Element::setAttribute(const AtomicString& name, const AtomicString& value, ExceptionCode& ec)
499 {
500     if (!Document::isValidName(name)) {
501         ec = INVALID_CHARACTER_ERR;
502         return;
503     }
504
505     const AtomicString& localName = (shouldIgnoreAttributeCase(this) && !name.string().impl()->isLower()) ? AtomicString(name.string().lower()) : name;
506
507     // allocate attributemap if necessary
508     Attribute* old = attributes(false)->getAttributeItem(localName, false);
509
510     document()->incDOMTreeVersion();
511
512     if (localName == idAttr.localName())
513         updateId(old ? old->value() : nullAtom, value);
514     
515     if (old && value.isNull())
516         namedAttrMap->removeAttribute(old->name());
517     else if (!old && !value.isNull())
518         namedAttrMap->addAttribute(createAttribute(QualifiedName(nullAtom, localName, nullAtom), value));
519     else if (old && !value.isNull()) {
520         old->setValue(value);
521         attributeChanged(old);
522     }
523 }
524
525 void Element::setAttribute(const QualifiedName& name, const AtomicString& value, ExceptionCode&)
526 {
527     document()->incDOMTreeVersion();
528
529     // allocate attributemap if necessary
530     Attribute* old = attributes(false)->getAttributeItem(name);
531
532     if (name == idAttr)
533         updateId(old ? old->value() : nullAtom, value);
534     
535     if (old && value.isNull())
536         namedAttrMap->removeAttribute(name);
537     else if (!old && !value.isNull())
538         namedAttrMap->addAttribute(createAttribute(name, value));
539     else if (old) {
540         old->setValue(value);
541         attributeChanged(old);
542     }
543 }
544
545 PassRefPtr<Attribute> Element::createAttribute(const QualifiedName& name, const AtomicString& value)
546 {
547     return Attribute::create(name, value);
548 }
549
550 void Element::attributeChanged(Attribute* attr, bool)
551 {
552     if (!document()->axObjectCache()->accessibilityEnabled())
553         return;
554
555     const QualifiedName& attrName = attr->name();
556     if (attrName == aria_activedescendantAttr) {
557         // any change to aria-activedescendant attribute triggers accessibility focus change, but document focus remains intact
558         document()->axObjectCache()->handleActiveDescendantChanged(renderer());
559     } else if (attrName == roleAttr) {
560         // the role attribute can change at any time, and the AccessibilityObject must pick up these changes
561         document()->axObjectCache()->handleAriaRoleChanged(renderer());
562     }
563 }
564
565 void Element::setAttributeMap(PassRefPtr<NamedAttrMap> list)
566 {
567     document()->incDOMTreeVersion();
568
569     // If setting the whole map changes the id attribute, we need to call updateId.
570
571     Attribute* oldId = namedAttrMap ? namedAttrMap->getAttributeItem(idAttr) : 0;
572     Attribute* newId = list ? list->getAttributeItem(idAttr) : 0;
573
574     if (oldId || newId)
575         updateId(oldId ? oldId->value() : nullAtom, newId ? newId->value() : nullAtom);
576
577     if (namedAttrMap)
578         namedAttrMap->m_element = 0;
579
580     namedAttrMap = list;
581
582     if (namedAttrMap) {
583         namedAttrMap->m_element = this;
584         unsigned len = namedAttrMap->length();
585         for (unsigned i = 0; i < len; i++)
586             attributeChanged(namedAttrMap->m_attributes[i].get());
587         // FIXME: What about attributes that were in the old map that are not in the new map?
588     }
589 }
590
591 bool Element::hasAttributes() const
592 {
593     if (!m_isStyleAttributeValid)
594         updateStyleAttribute();
595
596 #if ENABLE(SVG)
597     if (!m_areSVGAttributesValid)
598         updateAnimatedSVGAttribute(String());
599 #endif
600
601     return namedAttrMap && namedAttrMap->length() > 0;
602 }
603
604 String Element::nodeName() const
605 {
606     return m_tagName.toString();
607 }
608
609 String Element::nodeNamePreservingCase() const
610 {
611     return m_tagName.toString();
612 }
613
614 void Element::setPrefix(const AtomicString &_prefix, ExceptionCode& ec)
615 {
616     ec = 0;
617     checkSetPrefix(_prefix, ec);
618     if (ec)
619         return;
620
621     m_tagName.setPrefix(_prefix);
622 }
623
624 KURL Element::baseURI() const
625 {
626     KURL base(getAttribute(baseAttr));
627     if (!base.protocol().isEmpty())
628         return base;
629
630     Node* parent = parentNode();
631     if (!parent)
632         return base;
633
634     const KURL& parentBase = parent->baseURI();
635     if (parentBase.isNull())
636         return base;
637
638     return KURL(parentBase, base.string());
639 }
640
641 void Element::createAttributeMap() const
642 {
643     namedAttrMap = NamedAttrMap::create(const_cast<Element*>(this));
644 }
645
646 bool Element::isURLAttribute(Attribute*) const
647 {
648     return false;
649 }
650
651 const QualifiedName& Element::imageSourceAttributeName() const
652 {
653     return srcAttr;
654 }
655
656 RenderObject* Element::createRenderer(RenderArena* arena, RenderStyle* style)
657 {
658     if (document()->documentElement() == this && style->display() == NONE) {
659         // Ignore display: none on root elements.  Force a display of block in that case.
660         RenderBlock* result = new (arena) RenderBlock(this);
661         if (result)
662             result->setAnimatableStyle(style);
663         return result;
664     }
665     return RenderObject::createObject(this, style);
666 }
667
668
669 void Element::insertedIntoDocument()
670 {
671     // need to do superclass processing first so inDocument() is true
672     // by the time we reach updateId
673     ContainerNode::insertedIntoDocument();
674
675     if (hasID()) {
676         if (NamedAttrMap* attrs = namedAttrMap.get()) {
677             Attribute* idItem = attrs->getAttributeItem(idAttr);
678             if (idItem && !idItem->isNull())
679                 updateId(nullAtom, idItem->value());
680         }
681     }
682 }
683
684 void Element::removedFromDocument()
685 {
686     if (hasID()) {
687         if (NamedAttrMap* attrs = namedAttrMap.get()) {
688             Attribute* idItem = attrs->getAttributeItem(idAttr);
689             if (idItem && !idItem->isNull())
690                 updateId(idItem->value(), nullAtom);
691         }
692     }
693
694     ContainerNode::removedFromDocument();
695 }
696
697 void Element::attach()
698 {
699     createRendererIfNeeded();
700     ContainerNode::attach();
701     if (hasRareData()) {   
702         ElementRareData* data = rareData();
703         if (data->needsFocusAppearanceUpdateSoonAfterAttach()) {
704             if (isFocusable() && document()->focusedNode() == this)
705                 document()->updateFocusAppearanceSoon();
706             data->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
707         }
708     }
709 }
710
711 void Element::detach()
712 {
713     cancelFocusAppearanceUpdate();
714     if (hasRareData())
715         rareData()->resetComputedStyle();
716     ContainerNode::detach();
717 }
718
719 void Element::recalcStyle(StyleChange change)
720 {
721     RenderStyle* currentStyle = renderStyle();
722     bool hasParentStyle = parentNode() ? parentNode()->renderStyle() : false;
723     bool hasPositionalRules = changed() && currentStyle && currentStyle->childrenAffectedByPositionalRules();
724     bool hasDirectAdjacentRules = currentStyle && currentStyle->childrenAffectedByDirectAdjacentRules();
725
726 #if ENABLE(SVG)
727     if (!hasParentStyle && isShadowNode() && isSVGElement())
728         hasParentStyle = true;
729 #endif
730
731     if ((change > NoChange || changed())) {
732         if (hasRareData())
733             rareData()->resetComputedStyle();
734     }
735     if (hasParentStyle && (change >= Inherit || changed())) {
736         RefPtr<RenderStyle> newStyle = document()->styleSelector()->styleForElement(this);
737         StyleChange ch = diff(currentStyle, newStyle.get());
738         if (ch == Detach || !currentStyle) {
739             if (attached())
740                 detach();
741             attach(); // FIXME: The style gets computed twice by calling attach. We could do better if we passed the style along.
742             // attach recalulates the style for all children. No need to do it twice.
743             setChanged(NoStyleChange);
744             setHasChangedChild(false);
745             return;
746         }
747
748         if (currentStyle) {
749             // Preserve "affected by" bits that were propagated to us from descendants in the case where we didn't do a full
750             // style change (e.g., only inline style changed).
751             if (currentStyle->affectedByHoverRules())
752                 newStyle->setAffectedByHoverRules(true);
753             if (currentStyle->affectedByActiveRules())
754                 newStyle->setAffectedByActiveRules(true);
755             if (currentStyle->affectedByDragRules())
756                 newStyle->setAffectedByDragRules(true);
757             if (currentStyle->childrenAffectedByForwardPositionalRules())
758                 newStyle->setChildrenAffectedByForwardPositionalRules();
759             if (currentStyle->childrenAffectedByBackwardPositionalRules())
760                 newStyle->setChildrenAffectedByBackwardPositionalRules();
761             if (currentStyle->childrenAffectedByFirstChildRules())
762                 newStyle->setChildrenAffectedByFirstChildRules();
763             if (currentStyle->childrenAffectedByLastChildRules())
764                 newStyle->setChildrenAffectedByLastChildRules();
765             if (currentStyle->childrenAffectedByDirectAdjacentRules())
766                 newStyle->setChildrenAffectedByDirectAdjacentRules();
767         }
768
769         if (ch != NoChange) {
770             setRenderStyle(newStyle);
771         } else if (changed() && (styleChangeType() != AnimationStyleChange) && (document()->usesSiblingRules() || document()->usesDescendantRules())) {
772             // Although no change occurred, we use the new style so that the cousin style sharing code won't get
773             // fooled into believing this style is the same.  This is only necessary if the document actually uses
774             // sibling/descendant rules, since otherwise it isn't possible for ancestor styles to affect sharing of
775             // descendants.
776             if (renderer())
777                 renderer()->setStyleInternal(newStyle.get());
778             else
779                 setRenderStyle(newStyle);
780         } else if (styleChangeType() == AnimationStyleChange)
781              setRenderStyle(newStyle);
782
783         if (change != Force) {
784             if ((document()->usesDescendantRules() || hasPositionalRules) && styleChangeType() >= FullStyleChange)
785                 change = Force;
786             else
787                 change = ch;
788         }
789     }
790
791     // FIXME: This check is good enough for :hover + foo, but it is not good enough for :hover + foo + bar.
792     // For now we will just worry about the common case, since it's a lot trickier to get the second case right
793     // without doing way too much re-resolution.
794     bool forceCheckOfNextElementSibling = false;
795     for (Node *n = firstChild(); n; n = n->nextSibling()) {
796         bool childRulesChanged = n->changed() && n->styleChangeType() == FullStyleChange;
797         if (forceCheckOfNextElementSibling && n->isElementNode())
798             n->setChanged();
799         if (change >= Inherit || n->isTextNode() || n->hasChangedChild() || n->changed())
800             n->recalcStyle(change);
801         if (n->isElementNode())
802             forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentRules;
803     }
804
805     setChanged(NoStyleChange);
806     setHasChangedChild(false);
807 }
808
809 bool Element::childTypeAllowed(NodeType type)
810 {
811     switch (type) {
812         case ELEMENT_NODE:
813         case TEXT_NODE:
814         case COMMENT_NODE:
815         case PROCESSING_INSTRUCTION_NODE:
816         case CDATA_SECTION_NODE:
817         case ENTITY_REFERENCE_NODE:
818             return true;
819             break;
820         default:
821             return false;
822     }
823 }
824
825 static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool finishedParsingCallback,
826                                         Node* beforeChange, Node* afterChange, int childCountDelta)
827 {
828     if (!style || (e->changed() && style->childrenAffectedByPositionalRules()))
829         return;
830
831     // :first-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
832     // In the DOM case, we only need to do something if |afterChange| is not 0.
833     // |afterChange| is 0 in the parser case, so it works out that we'll skip this block.
834     if (style->childrenAffectedByFirstChildRules() && afterChange) {
835         // Find our new first child.
836         Node* newFirstChild = 0;
837         for (newFirstChild = e->firstChild(); newFirstChild && !newFirstChild->isElementNode(); newFirstChild = newFirstChild->nextSibling()) {};
838         
839         // Find the first element node following |afterChange|
840         Node* firstElementAfterInsertion = 0;
841         for (firstElementAfterInsertion = afterChange;
842              firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode();
843              firstElementAfterInsertion = firstElementAfterInsertion->nextSibling()) {};
844         
845         // This is the insert/append case.
846         if (newFirstChild != firstElementAfterInsertion && firstElementAfterInsertion && firstElementAfterInsertion->attached() &&
847             firstElementAfterInsertion->renderStyle() && firstElementAfterInsertion->renderStyle()->firstChildState())
848             firstElementAfterInsertion->setChanged();
849             
850         // We also have to handle node removal.
851         if (childCountDelta < 0 && newFirstChild == firstElementAfterInsertion && newFirstChild && newFirstChild->renderStyle() && !newFirstChild->renderStyle()->firstChildState())
852             newFirstChild->setChanged();
853     }
854
855     // :last-child.  In the parser callback case, we don't have to check anything, since we were right the first time.
856     // In the DOM case, we only need to do something if |afterChange| is not 0.
857     if (style->childrenAffectedByLastChildRules() && beforeChange) {
858         // Find our new last child.
859         Node* newLastChild = 0;
860         for (newLastChild = e->lastChild(); newLastChild && !newLastChild->isElementNode(); newLastChild = newLastChild->previousSibling()) {};
861         
862         // Find the last element node going backwards from |beforeChange|
863         Node* lastElementBeforeInsertion = 0;
864         for (lastElementBeforeInsertion = beforeChange;
865              lastElementBeforeInsertion && !lastElementBeforeInsertion->isElementNode();
866              lastElementBeforeInsertion = lastElementBeforeInsertion->previousSibling()) {};
867         
868         if (newLastChild != lastElementBeforeInsertion && lastElementBeforeInsertion && lastElementBeforeInsertion->attached() &&
869             lastElementBeforeInsertion->renderStyle() && lastElementBeforeInsertion->renderStyle()->lastChildState())
870             lastElementBeforeInsertion->setChanged();
871             
872         // 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
873         // to match now.
874         if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild == lastElementBeforeInsertion && newLastChild && newLastChild->renderStyle() && !newLastChild->renderStyle()->lastChildState())
875             newLastChild->setChanged();
876     }
877
878     // The + selector.  We need to invalidate the first element following the insertion point.  It is the only possible element
879     // that could be affected by this DOM change.
880     if (style->childrenAffectedByDirectAdjacentRules() && afterChange) {
881         Node* firstElementAfterInsertion = 0;
882         for (firstElementAfterInsertion = afterChange;
883              firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode();
884              firstElementAfterInsertion = firstElementAfterInsertion->nextSibling()) {};
885         if (firstElementAfterInsertion && firstElementAfterInsertion->attached())
886             firstElementAfterInsertion->setChanged();
887     }
888
889     // Forward positional selectors include the ~ selector, nth-child, nth-of-type, first-of-type and only-of-type.
890     // Backward positional selectors include nth-last-child, nth-last-of-type, last-of-type and only-of-type.
891     // We have to invalidate everything following the insertion point in the forward case, and everything before the insertion point in the
892     // backward case.
893     // |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.
894     // 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
895     // here.  recalcStyle will then force a walk of the children when it sees that this has happened.
896     if ((style->childrenAffectedByForwardPositionalRules() && afterChange) ||
897         (style->childrenAffectedByBackwardPositionalRules() && beforeChange))
898         e->setChanged();
899     
900     // :empty selector.
901     if (style->affectedByEmpty() && (!style->emptyState() || e->hasChildNodes()))
902         e->setChanged();
903 }
904
905 void Element::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
906 {
907     ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
908     if (!changedByParser)
909         checkForSiblingStyleChanges(this, renderStyle(), false, beforeChange, afterChange, childCountDelta);
910 }
911
912 void Element::finishParsingChildren()
913 {
914     ContainerNode::finishParsingChildren();
915     m_parsingChildrenFinished = true;
916     checkForSiblingStyleChanges(this, renderStyle(), true, lastChild(), 0, 0);
917 }
918
919 void Element::dispatchAttrRemovalEvent(Attribute*)
920 {
921     ASSERT(!eventDispatchForbidden());
922 #if 0
923     if (!document()->hasListenerType(Document::DOMATTRMODIFIED_LISTENER))
924         return;
925     ExceptionCode ec = 0;
926     dispatchEvent(new MutationEvent(DOMAttrModifiedEvent, true, false, attr, attr->value(),
927         attr->value(), document()->attrName(attr->id()), MutationEvent::REMOVAL), ec);
928 #endif
929 }
930
931 void Element::dispatchAttrAdditionEvent(Attribute*)
932 {
933     ASSERT(!eventDispatchForbidden());
934 #if 0
935     if (!document()->hasListenerType(Document::DOMATTRMODIFIED_LISTENER))
936         return;
937     ExceptionCode ec = 0;
938     dispatchEvent(new MutationEvent(DOMAttrModifiedEvent, true, false, attr, attr->value(),
939         attr->value(),document()->attrName(attr->id()), MutationEvent::ADDITION), ec);
940 #endif
941 }
942
943 String Element::openTagStartToString() const
944 {
945     String result = "<" + nodeName();
946
947     NamedAttrMap *attrMap = attributes(true);
948
949     if (attrMap) {
950         unsigned numAttrs = attrMap->length();
951         for (unsigned i = 0; i < numAttrs; i++) {
952             result += " ";
953
954             Attribute *attribute = attrMap->attributeItem(i);
955             result += attribute->name().toString();
956             if (!attribute->value().isNull()) {
957                 result += "=\"";
958                 // FIXME: substitute entities for any instances of " or '
959                 result += attribute->value();
960                 result += "\"";
961             }
962         }
963     }
964
965     return result;
966 }
967
968 void Element::updateId(const AtomicString& oldId, const AtomicString& newId)
969 {
970     if (!inDocument())
971         return;
972
973     if (oldId == newId)
974         return;
975
976     Document* doc = document();
977     if (!oldId.isEmpty())
978         doc->removeElementById(oldId, this);
979     if (!newId.isEmpty())
980         doc->addElementById(newId, this);
981 }
982
983 #ifndef NDEBUG
984 void Element::formatForDebugger(char* buffer, unsigned length) const
985 {
986     String result;
987     String s;
988     
989     s = nodeName();
990     if (s.length() > 0) {
991         result += s;
992     }
993           
994     s = getAttribute(idAttr);
995     if (s.length() > 0) {
996         if (result.length() > 0)
997             result += "; ";
998         result += "id=";
999         result += s;
1000     }
1001           
1002     s = getAttribute(classAttr);
1003     if (s.length() > 0) {
1004         if (result.length() > 0)
1005             result += "; ";
1006         result += "class=";
1007         result += s;
1008     }
1009           
1010     strncpy(buffer, result.utf8().data(), length - 1);
1011 }
1012 #endif
1013
1014 PassRefPtr<Attr> Element::setAttributeNode(Attr* attr, ExceptionCode& ec)
1015 {
1016     if (!attr) {
1017         ec = TYPE_MISMATCH_ERR;
1018         return 0;
1019     }
1020     return static_pointer_cast<Attr>(attributes(false)->setNamedItem(attr, ec));
1021 }
1022
1023 PassRefPtr<Attr> Element::setAttributeNodeNS(Attr* attr, ExceptionCode& ec)
1024 {
1025     if (!attr) {
1026         ec = TYPE_MISMATCH_ERR;
1027         return 0;
1028     }
1029     return static_pointer_cast<Attr>(attributes(false)->setNamedItem(attr, ec));
1030 }
1031
1032 PassRefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionCode& ec)
1033 {
1034     if (!attr) {
1035         ec = TYPE_MISMATCH_ERR;
1036         return 0;
1037     }
1038     if (attr->ownerElement() != this) {
1039         ec = NOT_FOUND_ERR;
1040         return 0;
1041     }
1042     if (document() != attr->document()) {
1043         ec = WRONG_DOCUMENT_ERR;
1044         return 0;
1045     }
1046
1047     NamedAttrMap *attrs = attributes(true);
1048     if (!attrs)
1049         return 0;
1050
1051     return static_pointer_cast<Attr>(attrs->removeNamedItem(attr->qualifiedName(), ec));
1052 }
1053
1054 void Element::setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode& ec)
1055 {
1056     String prefix, localName;
1057     if (!Document::parseQualifiedName(qualifiedName, prefix, localName, ec))
1058         return;
1059
1060     QualifiedName qName(prefix, localName, namespaceURI);
1061     setAttribute(qName, value, ec);
1062 }
1063
1064 void Element::removeAttribute(const String& name, ExceptionCode& ec)
1065 {
1066     String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
1067
1068     if (namedAttrMap) {
1069         namedAttrMap->removeNamedItem(localName, ec);
1070         if (ec == NOT_FOUND_ERR)
1071             ec = 0;
1072     }
1073 }
1074
1075 void Element::removeAttributeNS(const String& namespaceURI, const String& localName, ExceptionCode& ec)
1076 {
1077     removeAttribute(QualifiedName(nullAtom, localName, namespaceURI), ec);
1078 }
1079
1080 PassRefPtr<Attr> Element::getAttributeNode(const String& name)
1081 {
1082     NamedAttrMap* attrs = attributes(true);
1083     if (!attrs)
1084         return 0;
1085     String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
1086     return static_pointer_cast<Attr>(attrs->getNamedItem(localName));
1087 }
1088
1089 PassRefPtr<Attr> Element::getAttributeNodeNS(const String& namespaceURI, const String& localName)
1090 {
1091     NamedAttrMap* attrs = attributes(true);
1092     if (!attrs)
1093         return 0;
1094     return static_pointer_cast<Attr>(attrs->getNamedItem(QualifiedName(nullAtom, localName, namespaceURI)));
1095 }
1096
1097 bool Element::hasAttribute(const String& name) const
1098 {
1099     NamedAttrMap* attrs = attributes(true);
1100     if (!attrs)
1101         return false;
1102
1103     // This call to String::lower() seems to be required but
1104     // there may be a way to remove it.
1105     String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
1106     return attrs->getAttributeItem(localName, false);
1107 }
1108
1109 bool Element::hasAttributeNS(const String& namespaceURI, const String& localName) const
1110 {
1111     NamedAttrMap* attrs = attributes(true);
1112     if (!attrs)
1113         return false;
1114     return attrs->getAttributeItem(QualifiedName(nullAtom, localName, namespaceURI));
1115 }
1116
1117 CSSStyleDeclaration *Element::style()
1118 {
1119     return 0;
1120 }
1121
1122 void Element::focus(bool restorePreviousSelection)
1123 {
1124     Document* doc = document();
1125     if (doc->focusedNode() == this)
1126         return;
1127
1128     doc->updateLayoutIgnorePendingStylesheets();
1129     
1130     if (!supportsFocus())
1131         return;
1132     
1133     if (Page* page = doc->page())
1134         page->focusController()->setFocusedNode(this, doc->frame());
1135
1136     if (!isFocusable()) {
1137         ensureRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(true);
1138         return;
1139     }
1140         
1141     cancelFocusAppearanceUpdate();
1142     updateFocusAppearance(restorePreviousSelection);
1143 }
1144
1145 void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
1146 {
1147     if (this == rootEditableElement()) { 
1148         Frame* frame = document()->frame();
1149         if (!frame)
1150             return;
1151
1152         // FIXME: We should restore the previous selection if there is one.
1153         VisibleSelection newSelection = hasTagName(htmlTag) || hasTagName(bodyTag) ? VisibleSelection(Position(this, 0), DOWNSTREAM) : VisibleSelection::selectionFromContentsOfNode(this);
1154         
1155         if (frame->shouldChangeSelection(newSelection)) {
1156             frame->selection()->setSelection(newSelection);
1157             frame->revealSelection();
1158         }
1159     }
1160     // FIXME: I'm not sure all devices will want this off, but this is
1161     // currently turned off for Andriod.
1162 #if !ENABLE(DIRECTIONAL_PAD_NAVIGATION)
1163     else if (renderer() && !renderer()->isWidget())
1164         renderer()->enclosingLayer()->scrollRectToVisible(getRect());
1165 #endif
1166 }
1167
1168 void Element::blur()
1169 {
1170     cancelFocusAppearanceUpdate();
1171     Document* doc = document();
1172     if (doc->focusedNode() == this) {
1173         if (doc->frame())
1174             doc->frame()->page()->focusController()->setFocusedNode(0, doc->frame());
1175         else
1176             doc->setFocusedNode(0);
1177     }
1178 }
1179
1180 String Element::innerText() const
1181 {
1182     // We need to update layout, since plainText uses line boxes in the render tree.
1183     document()->updateLayoutIgnorePendingStylesheets();
1184
1185     if (!renderer())
1186         return textContent(true);
1187
1188     return plainText(rangeOfContents(const_cast<Element*>(this)).get());
1189 }
1190
1191 String Element::outerText() const
1192 {
1193     // Getting outerText is the same as getting innerText, only
1194     // setting is different. You would think this should get the plain
1195     // text for the outer range, but this is wrong, <br> for instance
1196     // would return different values for inner and outer text by such
1197     // a rule, but it doesn't in WinIE, and we want to match that.
1198     return innerText();
1199 }
1200
1201 String Element::title() const
1202 {
1203     return String();
1204 }
1205
1206 IntSize Element::minimumSizeForResizing() const
1207 {
1208     return hasRareData() ? rareData()->m_minimumSizeForResizing : defaultMinimumSizeForResizing();
1209 }
1210
1211 void Element::setMinimumSizeForResizing(const IntSize& size)
1212 {
1213     if (size == defaultMinimumSizeForResizing() && !hasRareData())
1214         return;
1215     ensureRareData()->m_minimumSizeForResizing = size;
1216 }
1217
1218 RenderStyle* Element::computedStyle()
1219 {
1220     if (RenderStyle* usedStyle = renderStyle())
1221         return usedStyle;
1222
1223     if (!attached())
1224         // FIXME: Try to do better than this. Ensure that styleForElement() works for elements that are not in the
1225         // document tree and figure out when to destroy the computed style for such elements.
1226         return 0;
1227
1228     ElementRareData* data = ensureRareData();
1229     if (!data->m_computedStyle)
1230         data->m_computedStyle = document()->styleSelector()->styleForElement(this, parent() ? parent()->computedStyle() : 0);
1231     return data->m_computedStyle.get();
1232 }
1233
1234 void Element::cancelFocusAppearanceUpdate()
1235 {
1236     if (hasRareData())
1237         rareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
1238     if (document()->focusedNode() == this)
1239         document()->cancelFocusAppearanceUpdate();
1240 }
1241
1242 void Element::normalizeAttributes()
1243 {
1244     // Normalize attributes.
1245     NamedAttrMap* attrs = attributes(true);
1246     if (!attrs)
1247         return;
1248     unsigned numAttrs = attrs->length();
1249     for (unsigned i = 0; i < numAttrs; i++) {
1250         if (Attr* attr = attrs->attributeItem(i)->attr())
1251             attr->normalize();
1252     }
1253 }
1254
1255 // ElementTraversal API
1256 Element* Element::firstElementChild() const
1257 {
1258     Node* n = firstChild();
1259     while (n && !n->isElementNode())
1260         n = n->nextSibling();
1261     return static_cast<Element*>(n);
1262 }
1263
1264 Element* Element::lastElementChild() const
1265 {
1266     Node* n = lastChild();
1267     while (n && !n->isElementNode())
1268         n = n->previousSibling();
1269     return static_cast<Element*>(n);
1270 }
1271
1272 Element* Element::previousElementSibling() const
1273 {
1274     Node* n = previousSibling();
1275     while (n && !n->isElementNode())
1276         n = n->previousSibling();
1277     return static_cast<Element*>(n);
1278 }
1279
1280 Element* Element::nextElementSibling() const
1281 {
1282     Node* n = nextSibling();
1283     while (n && !n->isElementNode())
1284         n = n->nextSibling();
1285     return static_cast<Element*>(n);
1286 }
1287
1288 unsigned Element::childElementCount() const
1289 {
1290     unsigned count = 0;
1291     Node* n = firstChild();
1292     while (n) {
1293         count += n->isElementNode();
1294         n = n->nextSibling();
1295     }
1296     return count;
1297 }
1298
1299 }