OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2001 Peter Kelly (pmk@post.com) | 4 * (C) 2001 Peter Kelly (pmk@post.com) |
5 * (C) 2001 Dirk Mueller (mueller@kde.org) | 5 * (C) 2001 Dirk Mueller (mueller@kde.org) |
6 * (C) 2007 David Smith (catfish.man@gmail.com) | 6 * (C) 2007 David Smith (catfish.man@gmail.com) |
7 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc.
All rights reserved. | 7 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc.
All rights reserved. |
8 * (C) 2007 Eric Seidel (eric@webkit.org) | 8 * (C) 2007 Eric Seidel (eric@webkit.org) |
9 * | 9 * |
10 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 #include "wtf/BitVector.h" | 98 #include "wtf/BitVector.h" |
99 #include "wtf/HashFunctions.h" | 99 #include "wtf/HashFunctions.h" |
100 #include "wtf/text/CString.h" | 100 #include "wtf/text/CString.h" |
101 #include "wtf/text/TextPosition.h" | 101 #include "wtf/text/TextPosition.h" |
102 | 102 |
103 namespace WebCore { | 103 namespace WebCore { |
104 | 104 |
105 using namespace HTMLNames; | 105 using namespace HTMLNames; |
106 using namespace XMLNames; | 106 using namespace XMLNames; |
107 | 107 |
108 static inline bool shouldIgnoreAttributeCase(const Element* e) | |
109 { | |
110 return e && e->document().isHTMLDocument() && e->isHTMLElement(); | |
111 } | |
112 | |
113 class StyleResolverParentPusher { | 108 class StyleResolverParentPusher { |
114 public: | 109 public: |
115 StyleResolverParentPusher(Element* parent) | 110 StyleResolverParentPusher(Element* parent) |
116 : m_parent(parent) | 111 : m_parent(parent) |
117 , m_pushedStyleResolver(0) | 112 , m_pushedStyleResolver(0) |
118 { | 113 { |
119 } | 114 } |
120 void push() | 115 void push() |
121 { | 116 { |
122 if (m_pushedStyleResolver) | 117 if (m_pushedStyleResolver) |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 toSVGElement(this)->synchronizeAnimatedSVGAttribute(name); | 447 toSVGElement(this)->synchronizeAnimatedSVGAttribute(name); |
453 } | 448 } |
454 } | 449 } |
455 | 450 |
456 inline void Element::synchronizeAttribute(const AtomicString& localName) const | 451 inline void Element::synchronizeAttribute(const AtomicString& localName) const |
457 { | 452 { |
458 // This version of synchronizeAttribute() is streamlined for the case where
you don't have a full QualifiedName, | 453 // This version of synchronizeAttribute() is streamlined for the case where
you don't have a full QualifiedName, |
459 // e.g when called from DOM API. | 454 // e.g when called from DOM API. |
460 if (!elementData()) | 455 if (!elementData()) |
461 return; | 456 return; |
462 if (elementData()->m_styleAttributeIsDirty && equalPossiblyIgnoringCase(loca
lName, styleAttr.localName(), shouldIgnoreAttributeCase(this))) { | 457 if (elementData()->m_styleAttributeIsDirty && equalPossiblyIgnoringCase(loca
lName, styleAttr.localName(), shouldIgnoreAttributeCase())) { |
463 ASSERT(isStyledElement()); | 458 ASSERT(isStyledElement()); |
464 synchronizeStyleAttributeInternal(); | 459 synchronizeStyleAttributeInternal(); |
465 return; | 460 return; |
466 } | 461 } |
467 if (elementData()->m_animatedSVGAttributesAreDirty) { | 462 if (elementData()->m_animatedSVGAttributesAreDirty) { |
468 // We're not passing a namespace argument on purpose. SVGNames::*Attr ar
e defined w/o namespaces as well. | 463 // We're not passing a namespace argument on purpose. SVGNames::*Attr ar
e defined w/o namespaces as well. |
469 ASSERT(isSVGElement()); | 464 ASSERT(isSVGElement()); |
470 static_cast<const SVGElement*>(this)->synchronizeAnimatedSVGAttribute(Qu
alifiedName(nullAtom, localName, nullAtom)); | 465 static_cast<const SVGElement*>(this)->synchronizeAnimatedSVGAttribute(Qu
alifiedName(nullAtom, localName, nullAtom)); |
471 } | 466 } |
472 } | 467 } |
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
877 return IntRect(); | 872 return IntRect(); |
878 // FIXME: this should probably respect transforms | 873 // FIXME: this should probably respect transforms |
879 return document().view()->contentsToScreen(renderer()->absoluteBoundingBoxRe
ctIgnoringTransforms()); | 874 return document().view()->contentsToScreen(renderer()->absoluteBoundingBoxRe
ctIgnoringTransforms()); |
880 } | 875 } |
881 | 876 |
882 const AtomicString& Element::getAttribute(const AtomicString& localName) const | 877 const AtomicString& Element::getAttribute(const AtomicString& localName) const |
883 { | 878 { |
884 if (!elementData()) | 879 if (!elementData()) |
885 return nullAtom; | 880 return nullAtom; |
886 synchronizeAttribute(localName); | 881 synchronizeAttribute(localName); |
887 if (const Attribute* attribute = elementData()->getAttributeItem(localName,
shouldIgnoreAttributeCase(this))) | 882 if (const Attribute* attribute = elementData()->getAttributeItem(localName,
shouldIgnoreAttributeCase())) |
888 return attribute->value(); | 883 return attribute->value(); |
889 return nullAtom; | 884 return nullAtom; |
890 } | 885 } |
891 | 886 |
892 const AtomicString& Element::getAttributeNS(const AtomicString& namespaceURI, co
nst AtomicString& localName) const | 887 const AtomicString& Element::getAttributeNS(const AtomicString& namespaceURI, co
nst AtomicString& localName) const |
893 { | 888 { |
894 return getAttribute(QualifiedName(nullAtom, localName, namespaceURI)); | 889 return getAttribute(QualifiedName(nullAtom, localName, namespaceURI)); |
895 } | 890 } |
896 | 891 |
897 void Element::setAttribute(const AtomicString& localName, const AtomicString& va
lue, ExceptionState& es) | 892 void Element::setAttribute(const AtomicString& localName, const AtomicString& va
lue, ExceptionState& es) |
898 { | 893 { |
899 if (!Document::isValidName(localName)) { | 894 if (!Document::isValidName(localName)) { |
900 es.throwUninformativeAndGenericDOMException(InvalidCharacterError); | 895 es.throwUninformativeAndGenericDOMException(InvalidCharacterError); |
901 return; | 896 return; |
902 } | 897 } |
903 | 898 |
904 synchronizeAttribute(localName); | 899 synchronizeAttribute(localName); |
905 const AtomicString& caseAdjustedLocalName = shouldIgnoreAttributeCase(this)
? localName.lower() : localName; | 900 const AtomicString& caseAdjustedLocalName = shouldIgnoreAttributeCase() ? lo
calName.lower() : localName; |
906 | 901 |
907 size_t index = elementData() ? elementData()->getAttributeItemIndex(caseAdju
stedLocalName, false) : kNotFound; | 902 size_t index = elementData() ? elementData()->getAttributeItemIndex(caseAdju
stedLocalName, false) : kNotFound; |
908 const QualifiedName& qName = index != kNotFound ? attributeItem(index)->name
() : QualifiedName(nullAtom, caseAdjustedLocalName, nullAtom); | 903 const QualifiedName& qName = index != kNotFound ? attributeItem(index)->name
() : QualifiedName(nullAtom, caseAdjustedLocalName, nullAtom); |
909 setAttributeInternal(index, qName, value, NotInSynchronizationOfLazyAttribut
e); | 904 setAttributeInternal(index, qName, value, NotInSynchronizationOfLazyAttribut
e); |
910 } | 905 } |
911 | 906 |
912 void Element::setAttribute(const QualifiedName& name, const AtomicString& value) | 907 void Element::setAttribute(const QualifiedName& name, const AtomicString& value) |
913 { | 908 { |
914 synchronizeAttribute(name); | 909 synchronizeAttribute(name); |
915 size_t index = elementData() ? elementData()->getAttributeItemIndex(name) :
kNotFound; | 910 size_t index = elementData() ? elementData()->getAttributeItemIndex(name) :
kNotFound; |
(...skipping 1004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1920 // InUseAttributeError: Raised if node is an Attr that is already an attribu
te of another Element object. | 1915 // InUseAttributeError: Raised if node is an Attr that is already an attribu
te of another Element object. |
1921 // The DOM user must explicitly clone Attr nodes to re-use them in other ele
ments. | 1916 // The DOM user must explicitly clone Attr nodes to re-use them in other ele
ments. |
1922 if (attrNode->ownerElement()) { | 1917 if (attrNode->ownerElement()) { |
1923 es.throwUninformativeAndGenericDOMException(InUseAttributeError); | 1918 es.throwUninformativeAndGenericDOMException(InUseAttributeError); |
1924 return 0; | 1919 return 0; |
1925 } | 1920 } |
1926 | 1921 |
1927 synchronizeAllAttributes(); | 1922 synchronizeAllAttributes(); |
1928 UniqueElementData* elementData = ensureUniqueElementData(); | 1923 UniqueElementData* elementData = ensureUniqueElementData(); |
1929 | 1924 |
1930 size_t index = elementData->getAttributeItemIndex(attrNode->qualifiedName(),
shouldIgnoreAttributeCase(this)); | 1925 size_t index = elementData->getAttributeItemIndex(attrNode->qualifiedName(),
shouldIgnoreAttributeCase()); |
1931 if (index != kNotFound) { | 1926 if (index != kNotFound) { |
1932 if (oldAttrNode) | 1927 if (oldAttrNode) |
1933 detachAttrNodeFromElementWithValue(oldAttrNode.get(), elementData->a
ttributeItem(index)->value()); | 1928 detachAttrNodeFromElementWithValue(oldAttrNode.get(), elementData->a
ttributeItem(index)->value()); |
1934 else | 1929 else |
1935 oldAttrNode = Attr::create(document(), attrNode->qualifiedName(), el
ementData->attributeItem(index)->value()); | 1930 oldAttrNode = Attr::create(document(), attrNode->qualifiedName(), el
ementData->attributeItem(index)->value()); |
1936 } | 1931 } |
1937 | 1932 |
1938 setAttributeInternal(index, attrNode->qualifiedName(), attrNode->value(), No
tInSynchronizationOfLazyAttribute); | 1933 setAttributeInternal(index, attrNode->qualifiedName(), attrNode->value(), No
tInSynchronizationOfLazyAttribute); |
1939 | 1934 |
1940 attrNode->attachToElement(this); | 1935 attrNode->attachToElement(this); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2031 ensureUniqueElementData()->addAttribute(name, value); | 2026 ensureUniqueElementData()->addAttribute(name, value); |
2032 if (!inSynchronizationOfLazyAttribute) | 2027 if (!inSynchronizationOfLazyAttribute) |
2033 didAddAttribute(name, value); | 2028 didAddAttribute(name, value); |
2034 } | 2029 } |
2035 | 2030 |
2036 void Element::removeAttribute(const AtomicString& name) | 2031 void Element::removeAttribute(const AtomicString& name) |
2037 { | 2032 { |
2038 if (!elementData()) | 2033 if (!elementData()) |
2039 return; | 2034 return; |
2040 | 2035 |
2041 AtomicString localName = shouldIgnoreAttributeCase(this) ? name.lower() : na
me; | 2036 AtomicString localName = shouldIgnoreAttributeCase() ? name.lower() : name; |
2042 size_t index = elementData()->getAttributeItemIndex(localName, false); | 2037 size_t index = elementData()->getAttributeItemIndex(localName, false); |
2043 if (index == kNotFound) { | 2038 if (index == kNotFound) { |
2044 if (UNLIKELY(localName == styleAttr) && elementData()->m_styleAttributeI
sDirty && isStyledElement()) | 2039 if (UNLIKELY(localName == styleAttr) && elementData()->m_styleAttributeI
sDirty && isStyledElement()) |
2045 removeAllInlineStyleProperties(); | 2040 removeAllInlineStyleProperties(); |
2046 return; | 2041 return; |
2047 } | 2042 } |
2048 | 2043 |
2049 removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute); | 2044 removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute); |
2050 } | 2045 } |
2051 | 2046 |
2052 void Element::removeAttributeNS(const AtomicString& namespaceURI, const AtomicSt
ring& localName) | 2047 void Element::removeAttributeNS(const AtomicString& namespaceURI, const AtomicSt
ring& localName) |
2053 { | 2048 { |
2054 removeAttribute(QualifiedName(nullAtom, localName, namespaceURI)); | 2049 removeAttribute(QualifiedName(nullAtom, localName, namespaceURI)); |
2055 } | 2050 } |
2056 | 2051 |
2057 PassRefPtr<Attr> Element::getAttributeNode(const AtomicString& localName) | 2052 PassRefPtr<Attr> Element::getAttributeNode(const AtomicString& localName) |
2058 { | 2053 { |
2059 if (!elementData()) | 2054 if (!elementData()) |
2060 return 0; | 2055 return 0; |
2061 synchronizeAttribute(localName); | 2056 synchronizeAttribute(localName); |
2062 const Attribute* attribute = elementData()->getAttributeItem(localName, shou
ldIgnoreAttributeCase(this)); | 2057 const Attribute* attribute = elementData()->getAttributeItem(localName, shou
ldIgnoreAttributeCase()); |
2063 if (!attribute) | 2058 if (!attribute) |
2064 return 0; | 2059 return 0; |
2065 return ensureAttr(attribute->name()); | 2060 return ensureAttr(attribute->name()); |
2066 } | 2061 } |
2067 | 2062 |
2068 PassRefPtr<Attr> Element::getAttributeNodeNS(const AtomicString& namespaceURI, c
onst AtomicString& localName) | 2063 PassRefPtr<Attr> Element::getAttributeNodeNS(const AtomicString& namespaceURI, c
onst AtomicString& localName) |
2069 { | 2064 { |
2070 if (!elementData()) | 2065 if (!elementData()) |
2071 return 0; | 2066 return 0; |
2072 QualifiedName qName(nullAtom, localName, namespaceURI); | 2067 QualifiedName qName(nullAtom, localName, namespaceURI); |
2073 synchronizeAttribute(qName); | 2068 synchronizeAttribute(qName); |
2074 const Attribute* attribute = elementData()->getAttributeItem(qName); | 2069 const Attribute* attribute = elementData()->getAttributeItem(qName); |
2075 if (!attribute) | 2070 if (!attribute) |
2076 return 0; | 2071 return 0; |
2077 return ensureAttr(attribute->name()); | 2072 return ensureAttr(attribute->name()); |
2078 } | 2073 } |
2079 | 2074 |
2080 bool Element::hasAttribute(const AtomicString& localName) const | 2075 bool Element::hasAttribute(const AtomicString& localName) const |
2081 { | 2076 { |
2082 if (!elementData()) | 2077 if (!elementData()) |
2083 return false; | 2078 return false; |
2084 synchronizeAttribute(localName); | 2079 synchronizeAttribute(localName); |
2085 return elementData()->getAttributeItem(shouldIgnoreAttributeCase(this) ? loc
alName.lower() : localName, false); | 2080 return elementData()->getAttributeItem(shouldIgnoreAttributeCase() ? localNa
me.lower() : localName, false); |
2086 } | 2081 } |
2087 | 2082 |
2088 bool Element::hasAttributeNS(const AtomicString& namespaceURI, const AtomicStrin
g& localName) const | 2083 bool Element::hasAttributeNS(const AtomicString& namespaceURI, const AtomicStrin
g& localName) const |
2089 { | 2084 { |
2090 if (!elementData()) | 2085 if (!elementData()) |
2091 return false; | 2086 return false; |
2092 QualifiedName qName(nullAtom, localName, namespaceURI); | 2087 QualifiedName qName(nullAtom, localName, namespaceURI); |
2093 synchronizeAttribute(qName); | 2088 synchronizeAttribute(qName); |
2094 return elementData()->getAttributeItem(qName); | 2089 return elementData()->getAttributeItem(qName); |
2095 } | 2090 } |
(...skipping 1647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3743 return 0; | 3738 return 0; |
3744 } | 3739 } |
3745 | 3740 |
3746 Attribute* UniqueElementData::attributeItem(unsigned index) | 3741 Attribute* UniqueElementData::attributeItem(unsigned index) |
3747 { | 3742 { |
3748 ASSERT_WITH_SECURITY_IMPLICATION(index < length()); | 3743 ASSERT_WITH_SECURITY_IMPLICATION(index < length()); |
3749 return &m_attributeVector.at(index); | 3744 return &m_attributeVector.at(index); |
3750 } | 3745 } |
3751 | 3746 |
3752 } // namespace WebCore | 3747 } // namespace WebCore |
OLD | NEW |