diff options
| author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-07-30 11:37:48 +0200 |
|---|---|---|
| committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-07-30 11:38:52 +0200 |
| commit | 89e2486a48b739f8d771d69ede5a6a1b244a10fc (patch) | |
| tree | 503b1a7812cf97d93704c32437eb5f62dc1a1ff9 /Source/WebCore/dom/Element.cpp | |
| parent | 625f028249cb37c55bbbd153f3902afd0b0756d9 (diff) | |
| download | qtwebkit-89e2486a48b739f8d771d69ede5a6a1b244a10fc.tar.gz | |
Imported WebKit commit 0282df8ca7c11d8c8a66ea18543695c69f545a27 (http://svn.webkit.org/repository/webkit/trunk@124002)
New snapshot with prospective Mountain Lion build fix
Diffstat (limited to 'Source/WebCore/dom/Element.cpp')
| -rw-r--r-- | Source/WebCore/dom/Element.cpp | 204 |
1 files changed, 140 insertions, 64 deletions
diff --git a/Source/WebCore/dom/Element.cpp b/Source/WebCore/dom/Element.cpp index 3499447ed..c323fa10d 100644 --- a/Source/WebCore/dom/Element.cpp +++ b/Source/WebCore/dom/Element.cpp @@ -201,7 +201,7 @@ PassRefPtr<Attr> Element::detachAttribute(size_t index) { ASSERT(attributeData()); - Attribute* attribute = attributeData()->attributeItem(index); + const Attribute* attribute = attributeData()->attributeItem(index); ASSERT(attribute); RefPtr<Attr> attr = attrIfExists(attribute->name()); @@ -210,7 +210,7 @@ PassRefPtr<Attr> Element::detachAttribute(size_t index) else attr = Attr::create(document(), attribute->name(), attribute->value()); - attributeData()->removeAttribute(index, this); + mutableAttributeData()->removeAttribute(index, this); return attr.release(); } @@ -222,7 +222,11 @@ void Element::removeAttribute(const QualifiedName& name) if (RefPtr<Attr> attr = attrIfExists(name)) attr->detachFromElementWithValue(attr->value()); - attributeData()->removeAttribute(name, this); + size_t index = attributeData()->getAttributeItemIndex(name); + if (index == notFound) + return; + + mutableAttributeData()->removeAttribute(index, this); } void Element::setBooleanAttribute(const QualifiedName& name, bool value) @@ -264,8 +268,8 @@ const AtomicString& Element::getAttribute(const QualifiedName& name) const updateAnimatedSVGAttribute(name); #endif - if (m_attributeData) { - if (Attribute* attribute = getAttributeItem(name)) + if (attributeData()) { + if (const Attribute* attribute = getAttributeItem(name)) return attribute->value(); } return nullAtom; @@ -412,8 +416,12 @@ int Element::clientLeft() { document()->updateLayoutIgnorePendingStylesheets(); - if (RenderBox* renderer = renderBox()) - return adjustForAbsoluteZoom(roundToInt(renderer->clientLeft()), renderer); + if (RenderBox* renderer = renderBox()) { + LayoutUnit clientLeft = renderer->clientLeft(); + if (renderer->style() && renderer->style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) + clientLeft += renderer->verticalScrollbarWidth(); + return adjustForAbsoluteZoom(roundToInt(clientLeft), renderer); + } return 0; } @@ -624,15 +632,15 @@ const AtomicString& Element::getAttribute(const AtomicString& name) const } #endif - if (m_attributeData) { - if (Attribute* attribute = m_attributeData->getAttributeItem(name, ignoreCase)) + if (attributeData()) { + if (const Attribute* attribute = attributeData()->getAttributeItem(name, ignoreCase)) return attribute->value(); } return nullAtom; } -const AtomicString& Element::getAttributeNS(const String& namespaceURI, const String& localName) const +const AtomicString& Element::getAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const { return getAttribute(QualifiedName(nullAtom, localName, namespaceURI)); } @@ -658,15 +666,17 @@ void Element::setAttribute(const QualifiedName& name, const AtomicString& value, inline void Element::setAttributeInternal(size_t index, const QualifiedName& name, const AtomicString& value, EInUpdateStyleAttribute inUpdateStyleAttribute) { - Attribute* old = index != notFound ? m_attributeData->attributeItem(index) : 0; + ElementAttributeData* attributeData = mutableAttributeData(); + + Attribute* old = index != notFound ? attributeData->attributeItem(index) : 0; if (value.isNull()) { if (old) - m_attributeData->removeAttribute(index, this, inUpdateStyleAttribute); + attributeData->removeAttribute(index, this, inUpdateStyleAttribute); return; } if (!old) { - m_attributeData->addAttribute(Attribute(name, value), this, inUpdateStyleAttribute); + attributeData->addAttribute(Attribute(name, value), this, inUpdateStyleAttribute); return; } @@ -760,44 +770,44 @@ void Element::parserSetAttributes(const Vector<Attribute>& attributeVector, Frag if (attributeVector.isEmpty()) return; - createAttributeData(); - m_attributeData->m_attributes = attributeVector; - m_attributeData->m_attributes.shrinkToFit(); + Vector<Attribute> filteredAttributes = attributeVector; // If the element is created as result of a paste or drag-n-drop operation // we want to remove all the script and event handlers. if (scriptingPermission == DisallowScriptingContent) { unsigned i = 0; - while (i < m_attributeData->length()) { - const QualifiedName& attributeName = m_attributeData->m_attributes[i].name(); - if (isEventHandlerAttribute(attributeName)) { - m_attributeData->m_attributes.remove(i); + while (i < filteredAttributes.size()) { + Attribute& attribute = filteredAttributes[i]; + if (isEventHandlerAttribute(attribute.name())) { + filteredAttributes.remove(i); continue; } - if (isAttributeToRemove(attributeName, m_attributeData->m_attributes[i].value())) - m_attributeData->m_attributes[i].setValue(nullAtom); + if (isAttributeToRemove(attribute.name(), attribute.value())) + attribute.setValue(emptyAtom); i++; } } - // Store the set of attributes that changed on the stack in case + m_attributeData = ElementAttributeData::createImmutable(filteredAttributes); + + // Iterate over the set of attributes we already have on the stack in case // attributeChanged mutates m_attributeData. - Vector<Attribute> clonedAttributes = m_attributeData->clonedAttributeVector(); - for (unsigned i = 0; i < clonedAttributes.size(); ++i) - attributeChanged(clonedAttributes[i]); + // FIXME: Find a way so we don't have to do this. + for (unsigned i = 0; i < filteredAttributes.size(); ++i) + attributeChanged(filteredAttributes[i]); } bool Element::hasAttributes() const { updateInvalidAttributes(); - return m_attributeData && m_attributeData->length(); + return attributeData() && attributeData()->length(); } bool Element::hasEquivalentAttributes(const Element* other) const { - ElementAttributeData* attributeData = updatedAttributeData(); - ElementAttributeData* otherAttributeData = other->updatedAttributeData(); + const ElementAttributeData* attributeData = updatedAttributeData(); + const ElementAttributeData* otherAttributeData = other->updatedAttributeData(); if (attributeData) return attributeData->isEquivalent(otherAttributeData); if (otherAttributeData) @@ -843,11 +853,6 @@ KURL Element::baseURI() const return KURL(parentBase, baseAttribute); } -void Element::createAttributeData() const -{ - m_attributeData = ElementAttributeData::create(); -} - const QualifiedName& Element::imageSourceAttributeName() const { return srcAttr; @@ -1394,8 +1399,6 @@ PassRefPtr<Attr> Element::setAttributeNode(Attr* attr, ExceptionCode& ec) return 0; } - ElementAttributeData* attributeData = ensureUpdatedAttributeData(); - RefPtr<Attr> oldAttr = attrIfExists(attr->qualifiedName()); if (oldAttr.get() == attr) return attr; // This Attr is already attached to the element. @@ -1407,6 +1410,9 @@ PassRefPtr<Attr> Element::setAttributeNode(Attr* attr, ExceptionCode& ec) return 0; } + updateInvalidAttributes(); + ElementAttributeData* attributeData = mutableAttributeData(); + size_t index = attributeData->getAttributeItemIndex(attr->qualifiedName()); Attribute* oldAttribute = index != notFound ? attributeData->attributeItem(index) : 0; @@ -1444,7 +1450,7 @@ PassRefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionCode& ec) ASSERT(document() == attr->document()); - ElementAttributeData* attributeData = updatedAttributeData(); + const ElementAttributeData* attributeData = updatedAttributeData(); ASSERT(attributeData); size_t index = attributeData->getAttributeItemIndex(attr->qualifiedName()); @@ -1456,44 +1462,50 @@ PassRefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionCode& ec) return detachAttribute(index); } -void Element::setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode& ec, FragmentScriptingPermission scriptingPermission) +bool Element::parseAttributeName(QualifiedName& out, const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionCode& ec) { String prefix, localName; if (!Document::parseQualifiedName(qualifiedName, prefix, localName, ec)) - return; + return false; + ASSERT(!ec); QualifiedName qName(prefix, localName, namespaceURI); if (!Document::hasValidNamespaceForAttributes(qName)) { ec = NAMESPACE_ERR; - return; + return false; } - if (scriptingPermission == DisallowScriptingContent && (isEventHandlerAttribute(qName) || isAttributeToRemove(qName, value))) - return; + out = qName; + return true; +} - setAttribute(qName, value); +void Element::setAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& value, ExceptionCode& ec) +{ + QualifiedName parsedName = anyName; + if (!parseAttributeName(parsedName, namespaceURI, qualifiedName, ec)) + return; + setAttribute(parsedName, value); } void Element::removeAttribute(size_t index) { ASSERT(attributeData()); ASSERT(index <= attributeCount()); - attributeData()->removeAttribute(index, this); + mutableAttributeData()->removeAttribute(index, this); } void Element::removeAttribute(const String& name) { - ElementAttributeData* attributeData = this->attributeData(); - if (!attributeData) + if (!attributeData()) return; String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name; - size_t index = attributeData->getAttributeItemIndex(localName, false); + size_t index = attributeData()->getAttributeItemIndex(localName, false); if (index == notFound) return; - attributeData->removeAttribute(index, this); + mutableAttributeData()->removeAttribute(index, this); } void Element::removeAttributeNS(const String& namespaceURI, const String& localName) @@ -1503,7 +1515,7 @@ void Element::removeAttributeNS(const String& namespaceURI, const String& localN PassRefPtr<Attr> Element::getAttributeNode(const String& name) { - ElementAttributeData* attributeData = updatedAttributeData(); + const ElementAttributeData* attributeData = updatedAttributeData(); if (!attributeData) return 0; return attributeData->getAttributeNode(name, shouldIgnoreAttributeCase(this), this); @@ -1511,7 +1523,7 @@ PassRefPtr<Attr> Element::getAttributeNode(const String& name) PassRefPtr<Attr> Element::getAttributeNodeNS(const String& namespaceURI, const String& localName) { - ElementAttributeData* attributeData = updatedAttributeData(); + const ElementAttributeData* attributeData = updatedAttributeData(); if (!attributeData) return 0; return attributeData->getAttributeNode(QualifiedName(nullAtom, localName, namespaceURI), this); @@ -1519,19 +1531,18 @@ PassRefPtr<Attr> Element::getAttributeNodeNS(const String& namespaceURI, const S bool Element::hasAttribute(const String& name) const { - ElementAttributeData* attributeData = updatedAttributeData(); - if (!attributeData) + if (!attributeData()) return false; // This call to String::lower() seems to be required but // there may be a way to remove it. String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name; - return attributeData->getAttributeItem(localName, false); + return updatedAttributeData()->getAttributeItem(localName, false); } bool Element::hasAttributeNS(const String& namespaceURI, const String& localName) const { - ElementAttributeData* attributeData = updatedAttributeData(); + const ElementAttributeData* attributeData = updatedAttributeData(); if (!attributeData) return false; return attributeData->getAttributeItem(QualifiedName(nullAtom, localName, namespaceURI)); @@ -1738,12 +1749,11 @@ void Element::normalizeAttributes() if (!hasAttrList()) return; - ElementAttributeData* attributeData = updatedAttributeData(); + const ElementAttributeData* attributeData = updatedAttributeData(); ASSERT(attributeData); - const Vector<Attribute>& attributes = attributeData->attributeVector(); - for (size_t i = 0; i < attributes.size(); ++i) { - if (RefPtr<Attr> attr = attrIfExists(attributes[i].name())) + for (size_t i = 0; i < attributeData->length(); ++i) { + if (RefPtr<Attr> attr = attrIfExists(attributeData->attributeItem(i)->name())) attr->normalize(); } } @@ -1812,8 +1822,8 @@ DOMStringMap* Element::dataset() KURL Element::getURLAttribute(const QualifiedName& name) const { #if !ASSERT_DISABLED - if (m_attributeData) { - if (Attribute* attribute = getAttributeItem(name)) + if (attributeData()) { + if (const Attribute* attribute = getAttributeItem(name)) ASSERT(isURLAttribute(*attribute)); } #endif @@ -1823,8 +1833,8 @@ KURL Element::getURLAttribute(const QualifiedName& name) const KURL Element::getNonEmptyURLAttribute(const QualifiedName& name) const { #if !ASSERT_DISABLED - if (m_attributeData) { - if (Attribute* attribute = getAttributeItem(name)) + if (attributeData()) { + if (const Attribute* attribute = getAttributeItem(name)) ASSERT(isURLAttribute(*attribute)); } #endif @@ -2168,8 +2178,8 @@ PassRefPtr<RenderStyle> Element::customStyleForRenderer() void Element::cloneAttributesFromElement(const Element& other) { - if (ElementAttributeData* attributeData = other.updatedAttributeData()) - ensureUpdatedAttributeData()->cloneDataFrom(*attributeData, other, *this); + if (const ElementAttributeData* attributeData = other.updatedAttributeData()) + mutableAttributeData()->cloneDataFrom(*attributeData, other, *this); else if (m_attributeData) { m_attributeData->clearAttributes(this); m_attributeData.clear(); @@ -2182,4 +2192,70 @@ void Element::cloneDataFromElement(const Element& other) copyNonAttributePropertiesFromElement(other); } +void Element::createMutableAttributeData() +{ + if (!m_attributeData) + m_attributeData = ElementAttributeData::create(); + else + m_attributeData = m_attributeData->makeMutable(); +} + +#if ENABLE(UNDO_MANAGER) +bool Element::undoScope() const +{ + return hasRareData() && elementRareData()->m_undoScope; +} + +void Element::setUndoScope(bool undoScope) +{ + ElementRareData* data = ensureElementRareData(); + data->m_undoScope = undoScope; + if (!undoScope) + disconnectUndoManager(); +} + +PassRefPtr<UndoManager> Element::undoManager() +{ + if (!undoScope() || (isContentEditable() && !isRootEditableElement())) { + disconnectUndoManager(); + return 0; + } + ElementRareData* data = ensureElementRareData(); + if (!data->m_undoManager) + data->m_undoManager = UndoManager::create(this); + return data->m_undoManager; +} + +void Element::disconnectUndoManager() +{ + if (!hasRareData()) + return; + ElementRareData* data = elementRareData(); + UndoManager* undoManager = data->m_undoManager.get(); + if (!undoManager) + return; + undoManager->clearUndoRedo(); + undoManager->disconnect(); + data->m_undoManager.clear(); +} + +void Element::disconnectUndoManagersInSubtree() +{ + Node* node = firstChild(); + while (node) { + if (node->isElementNode()) { + Element* element = toElement(node); + if (element->hasRareData() && element->elementRareData()->m_undoManager) { + if (!node->isContentEditable()) { + node = node->traverseNextSibling(this); + continue; + } + element->disconnectUndoManager(); + } + } + node = node->traverseNextNode(this); + } +} +#endif + } // namespace WebCore |
