Merge from Chromium at DEPS revision 257591
This commit was generated by merge_to_master.py.
Change-Id: I834f3ca85c1ef7ec2c1061847a3d92aa461da043
diff --git a/Source/core/dom/Element.cpp b/Source/core/dom/Element.cpp
index 5f2ae80..1b88ddb 100644
--- a/Source/core/dom/Element.cpp
+++ b/Source/core/dom/Element.cpp
@@ -31,10 +31,12 @@
#include "SVGNames.h"
#include "XMLNames.h"
#include "bindings/v8/Dictionary.h"
+#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "core/accessibility/AXObjectCache.h"
#include "core/animation/DocumentTimeline.h"
#include "core/animation/css/CSSAnimations.h"
+#include "core/css/CSSImageValue.h"
#include "core/css/CSSStyleSheet.h"
#include "core/css/CSSValuePool.h"
#include "core/css/PropertySetCSSStyleDeclaration.h"
@@ -61,6 +63,7 @@
#include "core/dom/RenderTreeBuilder.h"
#include "core/dom/ScriptableDocumentParser.h"
#include "core/dom/SelectorQuery.h"
+#include "core/dom/SiblingRuleHelper.h"
#include "core/dom/Text.h"
#include "core/dom/custom/CustomElement.h"
#include "core/dom/custom/CustomElementRegistrationContext.h"
@@ -72,10 +75,10 @@
#include "core/editing/markup.h"
#include "core/events/EventDispatcher.h"
#include "core/events/FocusEvent.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/UseCounter.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/html/ClassList.h"
#include "core/html/HTMLCollection.h"
#include "core/html/HTMLDocument.h"
@@ -208,7 +211,7 @@
detachAllAttrNodesFromElement();
if (hasPendingResources()) {
- document().accessSVGExtensions()->removeElementFromPendingResources(this);
+ document().accessSVGExtensions().removeElementFromPendingResources(this);
ASSERT(!hasPendingResources());
}
}
@@ -306,12 +309,12 @@
PassRefPtr<Attr> Element::detachAttribute(size_t index)
{
ASSERT(elementData());
- const Attribute* attribute = elementData()->attributeItem(index);
- RefPtr<Attr> attrNode = attrIfExists(attribute->name());
+ const Attribute& attribute = elementData()->attributeItem(index);
+ RefPtr<Attr> attrNode = attrIfExists(attribute.name());
if (attrNode)
detachAttrNodeAtIndex(attrNode.get(), index);
else {
- attrNode = Attr::create(document(), attribute->name(), attribute->value());
+ attrNode = Attr::create(document(), attribute.name(), attribute.value());
removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
}
return attrNode.release();
@@ -322,10 +325,9 @@
ASSERT(attr);
ASSERT(elementData());
- const Attribute* attribute = elementData()->attributeItem(index);
- ASSERT(attribute);
- ASSERT(attribute->name() == attr->qualifiedName());
- detachAttrNodeFromElementWithValue(attr, attribute->value());
+ const Attribute& attribute = elementData()->attributeItem(index);
+ ASSERT(attribute.name() == attr->qualifiedName());
+ detachAttrNodeFromElementWithValue(attr, attribute.value());
removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
}
@@ -366,12 +368,12 @@
return 0;
}
-ActiveAnimations* Element::ensureActiveAnimations()
+ActiveAnimations& Element::ensureActiveAnimations()
{
ElementRareData& rareData = ensureElementRareData();
if (!rareData.activeAnimations())
rareData.setActiveAnimations(adoptPtr(new ActiveAnimations()));
- return rareData.activeAnimations();
+ return *rareData.activeAnimations();
}
bool Element::hasActiveAnimations() const
@@ -554,7 +556,7 @@
int Element::offsetLeft()
{
- document().partialUpdateLayoutIgnorePendingStylesheets(this);
+ document().updateLayoutIgnorePendingStylesheets();
if (RenderBoxModelObject* renderer = renderBoxModelObject())
return adjustForLocalZoom(renderer->pixelSnappedOffsetLeft(), *renderer);
return 0;
@@ -562,7 +564,7 @@
int Element::offsetTop()
{
- document().partialUpdateLayoutIgnorePendingStylesheets(this);
+ document().updateLayoutIgnorePendingStylesheets();
if (RenderBoxModelObject* renderer = renderBoxModelObject())
return adjustForLocalZoom(renderer->pixelSnappedOffsetTop(), *renderer);
return 0;
@@ -577,7 +579,7 @@
return adjustLayoutUnitForAbsoluteZoom(renderer->fixedOffsetWidth(), *renderer).round();
}
- document().partialUpdateLayoutIgnorePendingStylesheets(this);
+ document().updateLayoutIgnorePendingStylesheets();
if (RenderBoxModelObject* renderer = renderBoxModelObject())
return adjustLayoutUnitForAbsoluteZoom(renderer->pixelSnappedOffsetWidth(), *renderer).round();
return 0;
@@ -585,7 +587,7 @@
int Element::offsetHeight()
{
- document().partialUpdateLayoutIgnorePendingStylesheets(this);
+ document().updateLayoutIgnorePendingStylesheets();
if (RenderBoxModelObject* renderer = renderBoxModelObject())
return adjustLayoutUnitForAbsoluteZoom(renderer->pixelSnappedOffsetHeight(), *renderer).round();
return 0;
@@ -726,7 +728,7 @@
if (document().inQuirksMode())
return;
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame)
return;
FrameView* view = frame->view();
@@ -772,7 +774,7 @@
if (document().inQuirksMode())
return;
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame)
return;
FrameView* view = frame->view();
@@ -932,7 +934,7 @@
const AtomicString& caseAdjustedLocalName = shouldIgnoreAttributeCase() ? localName.lower() : localName;
size_t index = elementData() ? elementData()->getAttributeItemIndex(caseAdjustedLocalName, false) : kNotFound;
- const QualifiedName& qName = index != kNotFound ? attributeItem(index)->name() : QualifiedName(nullAtom, caseAdjustedLocalName, nullAtom);
+ const QualifiedName& qName = index != kNotFound ? attributeItem(index).name() : QualifiedName(nullAtom, caseAdjustedLocalName, nullAtom);
setAttributeInternal(index, qName, value, NotInSynchronizationOfLazyAttribute);
}
@@ -962,20 +964,20 @@
return;
}
- const Attribute* existingAttribute = attributeItem(index);
- QualifiedName existingAttributeName = existingAttribute->name();
+ const Attribute& existingAttribute = attributeItem(index);
+ QualifiedName existingAttributeName = existingAttribute.name();
if (!inSynchronizationOfLazyAttribute)
- willModifyAttribute(existingAttributeName, existingAttribute->value(), newValue);
+ willModifyAttribute(existingAttributeName, existingAttribute.value(), newValue);
- if (newValue != existingAttribute->value()) {
+ if (newValue != existingAttribute.value()) {
// If there is an Attr node hooked to this attribute, the Attr::setValue() call below
// will write into the ElementData.
// FIXME: Refactor this so it makes some sense.
- if (RefPtr<Attr> attrNode = inSynchronizationOfLazyAttribute ? 0 : attrIfExists(existingAttributeName))
+ if (RefPtr<Attr> attrNode = inSynchronizationOfLazyAttribute ? nullptr : attrIfExists(existingAttributeName))
attrNode->setValue(newValue);
else
- ensureUniqueElementData()->attributeItem(index)->setValue(newValue);
+ ensureUniqueElementData().attributeItem(index).setValue(newValue);
}
if (!inSynchronizationOfLazyAttribute)
@@ -1026,12 +1028,14 @@
AtomicString newId = makeIdForStyleResolution(newValue, document().inQuirksMode());
if (newId != oldId) {
elementData()->setIdForStyleResolution(newId);
- shouldInvalidateStyle = testShouldInvalidateStyle && checkNeedsStyleInvalidationForIdChange(oldId, newId, styleResolver->ensureRuleFeatureSet());
+ shouldInvalidateStyle = testShouldInvalidateStyle && checkNeedsStyleInvalidationForIdChange(oldId, newId, styleResolver->ensureUpdatedRuleFeatureSet());
}
} else if (name == classAttr) {
classAttributeChanged(newValue);
} else if (name == HTMLNames::nameAttr) {
setHasName(!newValue.isNull());
+ } else if (name == HTMLNames::pseudoAttr) {
+ shouldInvalidateStyle |= testShouldInvalidateStyle && isInShadowTree();
}
invalidateNodeListCachesInAncestors(&name, this);
@@ -1085,17 +1089,18 @@
StyleResolver* styleResolver = document().styleResolver();
bool testShouldInvalidateStyle = inActiveDocument() && styleResolver && styleChangeType() < SubtreeStyleChange;
+ ASSERT(elementData());
if (classStringHasClassName(newClassString)) {
const bool shouldFoldCase = document().inQuirksMode();
const SpaceSplitString oldClasses = elementData()->classNames();
elementData()->setClass(newClassString, shouldFoldCase);
const SpaceSplitString& newClasses = elementData()->classNames();
if (testShouldInvalidateStyle)
- styleResolver->ensureRuleFeatureSet().scheduleStyleInvalidationForClassChange(oldClasses, newClasses, this);
+ styleResolver->ensureUpdatedRuleFeatureSet().scheduleStyleInvalidationForClassChange(oldClasses, newClasses, this);
} else {
const SpaceSplitString& oldClasses = elementData()->classNames();
if (testShouldInvalidateStyle)
- styleResolver->ensureRuleFeatureSet().scheduleStyleInvalidationForClassChange(oldClasses, this);
+ styleResolver->ensureUpdatedRuleFeatureSet().scheduleStyleInvalidationForClassChange(oldClasses, this);
elementData()->clearClass();
}
@@ -1246,11 +1251,12 @@
return prefix();
if (hasAttributes()) {
- for (unsigned i = 0; i < attributeCount(); i++) {
- const Attribute* attr = attributeItem(i);
+ unsigned attributeCount = this->attributeCount();
+ for (unsigned i = 0; i < attributeCount; ++i) {
+ const Attribute& attr = attributeItem(i);
- if (attr->prefix() == xmlnsAtom && attr->value() == namespaceToLocate)
- return attr->localName();
+ if (attr.prefix() == xmlnsAtom && attr.value() == namespaceToLocate)
+ return attr.localName();
}
}
@@ -1325,7 +1331,7 @@
if (!nameValue.isNull())
updateName(nullAtom, nameValue);
- if (hasTagName(labelTag)) {
+ if (isHTMLLabelElement(*this)) {
if (scope.shouldCacheLabelsByForAttribute())
updateLabel(scope, nullAtom, fastGetAttribute(forAttr));
}
@@ -1359,7 +1365,7 @@
if (!nameValue.isNull())
updateName(nameValue, nullAtom);
- if (hasTagName(labelTag)) {
+ if (isHTMLLabelElement(*this)) {
TreeScope& treeScope = insertionPoint->treeScope();
if (treeScope.shouldCacheLabelsByForAttribute())
updateLabel(treeScope, fastGetAttribute(forAttr), nullAtom);
@@ -1369,7 +1375,7 @@
ContainerNode::removedFrom(insertionPoint);
if (wasInDocument) {
if (hasPendingResources())
- document().accessSVGExtensions()->removeElementFromPendingResources(this);
+ document().accessSVGExtensions().removeElementFromPendingResources(this);
if (isUpgradedCustomElement())
CustomElement::didLeaveDocument(this, insertionPoint->document());
@@ -1592,8 +1598,11 @@
if (localChange == Reattach) {
AttachContext reattachContext;
reattachContext.resolvedStyle = newStyle.get();
+ bool rendererWillChange = needsAttach() || renderer();
reattach(reattachContext);
- return Reattach;
+ if (rendererWillChange || renderer())
+ return Reattach;
+ return ReattachNoRenderer;
}
ASSERT(oldStyle);
@@ -1647,7 +1656,7 @@
updatePseudoElement(BEFORE, change);
if (change < Force && hasRareData() && childNeedsStyleRecalc())
- checkForChildrenAdjacentRuleChanges();
+ SiblingRuleHelper(this).checkForChildrenAdjacentRuleChanges();
if (change > UpdatePseudoElements || childNeedsStyleRecalc()) {
// This loop is deliberately backwards because we use insertBefore in the rendering tree, and want to avoid
@@ -1678,36 +1687,6 @@
updatePseudoElement(BACKDROP, change);
}
-void Element::checkForChildrenAdjacentRuleChanges()
-{
- bool hasDirectAdjacentRules = childrenAffectedByDirectAdjacentRules();
- bool hasIndirectAdjacentRules = childrenAffectedByForwardPositionalRules();
-
- if (!hasDirectAdjacentRules && !hasIndirectAdjacentRules)
- return;
-
- unsigned forceCheckOfNextElementCount = 0;
- bool forceCheckOfAnyElementSibling = false;
-
- for (Node* child = firstChild(); child; child = child->nextSibling()) {
- if (!child->isElementNode())
- continue;
- Element* element = toElement(child);
- bool childRulesChanged = element->needsStyleRecalc() && element->styleChangeType() >= SubtreeStyleChange;
-
- if (forceCheckOfNextElementCount || forceCheckOfAnyElementSibling)
- element->setNeedsStyleRecalc(SubtreeStyleChange);
-
- if (forceCheckOfNextElementCount)
- forceCheckOfNextElementCount--;
-
- if (childRulesChanged && hasDirectAdjacentRules)
- forceCheckOfNextElementCount = document().styleEngine()->maxDirectAdjacentSelectors();
-
- forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules);
- }
-}
-
void Element::updateCallbackSelectors(RenderStyle* oldStyle, RenderStyle* newStyle)
{
Vector<String> emptyVector;
@@ -1771,7 +1750,7 @@
// flag is provided for testing how author shadows interact on these elements.
if (!areAuthorShadowsAllowed() && !RuntimeEnabledFeatures::authorShadowDOMForAnyElementEnabled()) {
exceptionState.throwDOMException(HierarchyRequestError, "Author-created shadow roots are disabled for this element.");
- return 0;
+ return nullptr;
}
return PassRefPtr<ShadowRoot>(ensureShadow().addShadowRoot(*this, ShadowRoot::AuthorShadowRoot));
@@ -1833,7 +1812,7 @@
if (!style && !styleAffectedByEmpty())
return;
- if (!style || (styleAffectedByEmpty() && (!style->emptyState() || hasChildNodes())))
+ if (!style || (styleAffectedByEmpty() && (!style->emptyState() || hasChildren())))
setNeedsStyleRecalc(SubtreeStyleChange);
}
@@ -1973,8 +1952,8 @@
PassRefPtr<Attr> Element::setAttributeNode(Attr* attrNode, ExceptionState& exceptionState)
{
if (!attrNode) {
- exceptionState.throwDOMException(TypeMismatchError, "The node provided is invalid.");
- return 0;
+ exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "Attr"));
+ return nullptr;
}
RefPtr<Attr> oldAttrNode = attrIfExists(attrNode->qualifiedName());
@@ -1985,18 +1964,18 @@
// The DOM user must explicitly clone Attr nodes to re-use them in other elements.
if (attrNode->ownerElement()) {
exceptionState.throwDOMException(InUseAttributeError, "The node provided is an attribute node that is already an attribute of another Element; attribute nodes must be explicitly cloned.");
- return 0;
+ return nullptr;
}
synchronizeAllAttributes();
- UniqueElementData* elementData = ensureUniqueElementData();
+ UniqueElementData& elementData = ensureUniqueElementData();
- size_t index = elementData->getAttributeItemIndex(attrNode->qualifiedName(), shouldIgnoreAttributeCase());
+ size_t index = elementData.getAttributeItemIndex(attrNode->qualifiedName(), shouldIgnoreAttributeCase());
if (index != kNotFound) {
if (oldAttrNode)
- detachAttrNodeFromElementWithValue(oldAttrNode.get(), elementData->attributeItem(index)->value());
+ detachAttrNodeFromElementWithValue(oldAttrNode.get(), elementData.attributeItem(index).value());
else
- oldAttrNode = Attr::create(document(), attrNode->qualifiedName(), elementData->attributeItem(index)->value());
+ oldAttrNode = Attr::create(document(), attrNode->qualifiedName(), elementData.attributeItem(index).value());
}
setAttributeInternal(index, attrNode->qualifiedName(), attrNode->value(), NotInSynchronizationOfLazyAttribute);
@@ -2011,12 +1990,12 @@
PassRefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionState& exceptionState)
{
if (!attr) {
- exceptionState.throwDOMException(TypeMismatchError, "The node provided is invalid.");
- return 0;
+ exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "Attr"));
+ return nullptr;
}
if (attr->ownerElement() != this) {
exceptionState.throwDOMException(NotFoundError, "The node provided is owned by another element.");
- return 0;
+ return nullptr;
}
ASSERT(document() == attr->document());
@@ -2026,7 +2005,7 @@
size_t index = elementData()->getAttrIndex(attr);
if (index == kNotFound) {
exceptionState.throwDOMException(NotFoundError, "The attribute was not found on this element.");
- return 0;
+ return nullptr;
}
RefPtr<Attr> guard(attr);
@@ -2064,10 +2043,10 @@
{
ASSERT_WITH_SECURITY_IMPLICATION(index < attributeCount());
- UniqueElementData* elementData = ensureUniqueElementData();
+ UniqueElementData& elementData = ensureUniqueElementData();
- QualifiedName name = elementData->attributeItem(index)->name();
- AtomicString valueBeingRemoved = elementData->attributeItem(index)->value();
+ QualifiedName name = elementData.attributeItem(index).name();
+ AtomicString valueBeingRemoved = elementData.attributeItem(index).value();
if (!inSynchronizationOfLazyAttribute) {
if (!valueBeingRemoved.isNull())
@@ -2075,9 +2054,9 @@
}
if (RefPtr<Attr> attrNode = attrIfExists(name))
- detachAttrNodeFromElementWithValue(attrNode.get(), elementData->attributeItem(index)->value());
+ detachAttrNodeFromElementWithValue(attrNode.get(), elementData.attributeItem(index).value());
- elementData->removeAttribute(index);
+ elementData.removeAttribute(index);
if (!inSynchronizationOfLazyAttribute)
didRemoveAttribute(name);
@@ -2087,7 +2066,7 @@
{
if (!inSynchronizationOfLazyAttribute)
willModifyAttribute(name, nullAtom, value);
- ensureUniqueElementData()->addAttribute(name, value);
+ ensureUniqueElementData().addAttribute(name, value);
if (!inSynchronizationOfLazyAttribute)
didAddAttribute(name, value);
}
@@ -2116,23 +2095,23 @@
PassRefPtr<Attr> Element::getAttributeNode(const AtomicString& localName)
{
if (!elementData())
- return 0;
+ return nullptr;
synchronizeAttribute(localName);
const Attribute* attribute = elementData()->getAttributeItem(localName, shouldIgnoreAttributeCase());
if (!attribute)
- return 0;
+ return nullptr;
return ensureAttr(attribute->name());
}
PassRefPtr<Attr> Element::getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName)
{
if (!elementData())
- return 0;
+ return nullptr;
QualifiedName qName(nullAtom, localName, namespaceURI);
synchronizeAttribute(qName);
const Attribute* attribute = elementData()->getAttributeItem(qName);
if (!attribute)
- return 0;
+ return nullptr;
return ensureAttr(attribute->name());
}
@@ -2199,7 +2178,7 @@
void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
{
if (isRootEditableElement()) {
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame)
return;
@@ -2223,7 +2202,7 @@
if (doc.page())
doc.page()->focusController().setFocusedElement(0, doc.frame());
else
- doc.setFocusedElement(0);
+ doc.setFocusedElement(nullptr);
}
}
@@ -2282,7 +2261,7 @@
{
if (RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, this, AllowScriptingContent, "innerHTML", exceptionState)) {
ContainerNode* container = this;
- if (hasTagName(templateTag))
+ if (isHTMLTemplateElement(*this))
container = toHTMLTemplateElement(this)->content();
replaceChildrenWithFragment(container, fragment.release(), exceptionState);
}
@@ -2461,16 +2440,11 @@
const AtomicString& Element::shadowPseudoId() const
{
- if (ShadowRoot* root = containingShadowRoot()) {
- if (root->type() == ShadowRoot::UserAgentShadowRoot)
- return fastGetAttribute(pseudoAttr);
- }
- return nullAtom;
+ return getAttribute(pseudoAttr);
}
void Element::setShadowPseudoId(const AtomicString& id)
{
- ASSERT(CSSSelector::parsePseudoType(id) == CSSSelector::PseudoWebKitCustomElement || CSSSelector::parsePseudoType(id) == CSSSelector::PseudoUserAgentCustomElement);
setAttribute(pseudoAttr, id);
}
@@ -2719,8 +2693,10 @@
{
if (!hasAttributes())
return;
+ // attributeCount() cannot be cached before the loop because the attributes
+ // list is altered while iterating.
for (unsigned i = 0; i < attributeCount(); ++i) {
- if (RefPtr<Attr> attr = attrIfExists(attributeItem(i)->name()))
+ if (RefPtr<Attr> attr = attrIfExists(attributeItem(i).name()))
attr->normalize();
}
}
@@ -2746,7 +2722,7 @@
// when RenderObject::isChildAllowed on our parent returns false for the
// PseudoElement's renderer for each style recalc.
if (!renderer() || !pseudoElementRendererIsNeeded(renderer()->getCachedPseudoStyle(pseudoId)))
- elementRareData()->setPseudoElement(pseudoId, 0);
+ elementRareData()->setPseudoElement(pseudoId, nullptr);
} else if (change >= UpdatePseudoElements) {
createPseudoElementIfNeeded(pseudoId);
}
@@ -2791,20 +2767,20 @@
return selectorQuery->matches(*this);
}
-DOMTokenList* Element::classList()
+DOMTokenList& Element::classList()
{
ElementRareData& rareData = ensureElementRareData();
if (!rareData.classList())
rareData.setClassList(ClassList::create(this));
- return rareData.classList();
+ return *rareData.classList();
}
-DOMStringMap* Element::dataset()
+DOMStringMap& Element::dataset()
{
ElementRareData& rareData = ensureElementRareData();
if (!rareData.dataset())
rareData.setDataset(DatasetDOMStringMap::create(this));
- return rareData.dataset();
+ return *rareData.dataset();
}
KURL Element::getURLAttribute(const QualifiedName& name) const
@@ -2869,12 +2845,12 @@
void Element::webkitRequestFullscreen()
{
- FullscreenElementStack::from(&document())->requestFullScreenForElement(this, ALLOW_KEYBOARD_INPUT, FullscreenElementStack::EnforceIFrameAllowFullScreenRequirement);
+ FullscreenElementStack::from(document()).requestFullScreenForElement(this, ALLOW_KEYBOARD_INPUT, FullscreenElementStack::EnforceIFrameAllowFullScreenRequirement);
}
void Element::webkitRequestFullScreen(unsigned short flags)
{
- FullscreenElementStack::from(&document())->requestFullScreenForElement(this, (flags | LEGACY_MOZILLA_REQUEST), FullscreenElementStack::EnforceIFrameAllowFullScreenRequirement);
+ FullscreenElementStack::from(document()).requestFullScreenForElement(this, (flags | LEGACY_MOZILLA_REQUEST), FullscreenElementStack::EnforceIFrameAllowFullScreenRequirement);
}
bool Element::containsFullScreenElement() const
@@ -3011,7 +2987,7 @@
void Element::updateLabel(TreeScope& scope, const AtomicString& oldForAttributeValue, const AtomicString& newForAttributeValue)
{
- ASSERT(hasTagName(labelTag));
+ ASSERT(isHTMLLabelElement(this));
if (!inDocument())
return;
@@ -3027,16 +3003,16 @@
static bool hasSelectorForAttribute(Document* document, const AtomicString& localName)
{
- return document->ensureStyleResolver().ensureRuleFeatureSet().hasSelectorForAttribute(localName);
+ return document->ensureStyleResolver().ensureUpdatedRuleFeatureSet().hasSelectorForAttribute(localName);
}
void Element::willModifyAttribute(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue)
{
- if (isIdAttributeName(name))
+ if (isIdAttributeName(name)) {
updateId(oldValue, newValue);
- else if (name == HTMLNames::nameAttr)
+ } else if (name == HTMLNames::nameAttr) {
updateName(oldValue, newValue);
- else if (name == HTMLNames::forAttr && hasTagName(labelTag)) {
+ } else if (name == HTMLNames::forAttr && isHTMLLabelElement(*this)) {
TreeScope& scope = treeScope();
if (scope.shouldCacheLabelsByForAttribute())
updateLabel(scope, oldValue, newValue);
@@ -3077,6 +3053,33 @@
dispatchSubtreeModifiedEvent();
}
+static bool needsURLResolutionForInlineStyle(const Element& element, const Document& oldDocument, const Document& newDocument)
+{
+ if (oldDocument == newDocument)
+ return false;
+ if (oldDocument.baseURL() == newDocument.baseURL())
+ return false;
+ const StylePropertySet* style = element.inlineStyle();
+ if (!style)
+ return false;
+ for (unsigned i = 0; i < style->propertyCount(); ++i) {
+ // FIXME: Should handle all URL-based properties: CSSImageSetValue, CSSCursorImageValue, etc.
+ if (style->propertyAt(i).value()->isImageValue())
+ return true;
+ }
+ return false;
+}
+
+static void reResolveURLsInInlineStyle(const Document& document, MutableStylePropertySet& style)
+{
+ for (unsigned i = 0; i < style.propertyCount(); ++i) {
+ StylePropertySet::PropertyReference property = style.propertyAt(i);
+ // FIXME: Should handle all URL-based properties: CSSImageSetValue, CSSCursorImageValue, etc.
+ if (property.value()->isImageValue())
+ toCSSImageValue(property.value())->reResolveURL(document);
+ }
+}
+
void Element::didMoveToNewDocument(Document& oldDocument)
{
Node::didMoveToNewDocument(oldDocument);
@@ -3090,6 +3093,9 @@
if (hasClass())
setAttribute(HTMLNames::classAttr, getClassAttribute());
}
+
+ if (needsURLResolutionForInlineStyle(*this, oldDocument, document()))
+ reResolveURLsInInlineStyle(document(), ensureMutableInlineStyle());
}
void Element::updateNamedItemRegistration(const AtomicString& oldName, const AtomicString& newName)
@@ -3122,16 +3128,16 @@
return collection;
if (type == TableRows) {
- ASSERT(hasTagName(tableTag));
- return ensureRareData().ensureNodeLists().addCache<HTMLTableRowsCollection>(this, type);
+ ASSERT(isHTMLTableElement(this));
+ return ensureRareData().ensureNodeLists().addCache<HTMLTableRowsCollection>(*this, type);
} else if (type == SelectOptions) {
- ASSERT(hasTagName(selectTag));
- return ensureRareData().ensureNodeLists().addCache<HTMLOptionsCollection>(this, type);
+ ASSERT(isHTMLSelectElement(this));
+ return ensureRareData().ensureNodeLists().addCache<HTMLOptionsCollection>(*this, type);
} else if (type == FormControls) {
- ASSERT(hasTagName(formTag) || hasTagName(fieldsetTag));
- return ensureRareData().ensureNodeLists().addCache<HTMLFormControlsCollection>(this, type);
+ ASSERT(isHTMLFormElement(this) || isHTMLFieldSetElement(this));
+ return ensureRareData().ensureNodeLists().addCache<HTMLFormControlsCollection>(*this, type);
}
- return ensureRareData().ensureNodeLists().addCache<HTMLCollection>(this, type);
+ return ensureRareData().ensureNodeLists().addCache<HTMLCollection>(*this, type);
}
static void scheduleLayerUpdateCallback(Node* node)
@@ -3170,7 +3176,7 @@
{
if (AttrNodeList* attrNodeList = attrNodeListForElement(this))
return findAttrNodeInList(*attrNodeList, name);
- return 0;
+ return nullptr;
}
PassRefPtr<Attr> Element::ensureAttr(const QualifiedName& name)
@@ -3207,10 +3213,11 @@
AttrNodeList* attrNodeList = attrNodeListForElement(this);
ASSERT(attrNodeList);
- for (unsigned i = 0; i < attributeCount(); ++i) {
- const Attribute* attribute = attributeItem(i);
- if (RefPtr<Attr> attrNode = findAttrNodeInList(*attrNodeList, attribute->name()))
- attrNode->detachFromElementWithValue(attribute->value());
+ unsigned attributeCount = this->attributeCount();
+ for (unsigned i = 0; i < attributeCount; ++i) {
+ const Attribute& attribute = attributeItem(i);
+ if (RefPtr<Attr> attrNode = findAttrNodeInList(*attrNodeList, attribute.name()))
+ attrNode->detachFromElementWithValue(attribute.value());
}
removeAttrNodeListForElement(this);
@@ -3230,7 +3237,7 @@
PassRefPtr<RenderStyle> Element::customStyleForRenderer()
{
ASSERT(hasCustomStyleCallbacks());
- return 0;
+ return nullptr;
}
void Element::cloneAttributesFromElement(const Element& other)
@@ -3269,14 +3276,15 @@
&& !other.m_elementData->presentationAttributeStyle())
const_cast<Element&>(other).m_elementData = static_cast<const UniqueElementData*>(other.m_elementData.get())->makeShareableCopy();
- if (!other.m_elementData->isUnique() && !ownerDocumentsHaveDifferentCaseSensitivity)
+ if (!other.m_elementData->isUnique() && !ownerDocumentsHaveDifferentCaseSensitivity && !needsURLResolutionForInlineStyle(other, other.document(), document()))
m_elementData = other.m_elementData;
else
m_elementData = other.m_elementData->makeUniqueCopy();
- for (unsigned i = 0; i < m_elementData->length(); ++i) {
- const Attribute* attribute = const_cast<const ElementData*>(m_elementData.get())->attributeItem(i);
- attributeChangedFromParserOrByCloning(attribute->name(), attribute->value(), ModifiedByCloning);
+ unsigned length = m_elementData->length();
+ for (unsigned i = 0; i < length; ++i) {
+ const Attribute& attribute = m_elementData->attributeItem(i);
+ attributeChangedFromParserOrByCloning(attribute.name(), attribute.value(), ModifiedByCloning);
}
}
@@ -3296,7 +3304,7 @@
}
}
-InputMethodContext* Element::inputMethodContext()
+InputMethodContext& Element::inputMethodContext()
{
return ensureElementRareData().ensureInputMethodContext(toHTMLElement(this));
}
@@ -3336,26 +3344,26 @@
{
if (!isStyledElement())
return 0;
- return ensureElementRareData().ensureInlineCSSStyleDeclaration(this);
+ return &ensureElementRareData().ensureInlineCSSStyleDeclaration(this);
}
-MutableStylePropertySet* Element::ensureMutableInlineStyle()
+MutableStylePropertySet& Element::ensureMutableInlineStyle()
{
ASSERT(isStyledElement());
- RefPtr<StylePropertySet>& inlineStyle = ensureUniqueElementData()->m_inlineStyle;
+ RefPtr<StylePropertySet>& inlineStyle = ensureUniqueElementData().m_inlineStyle;
if (!inlineStyle) {
CSSParserMode mode = (!isHTMLElement() || document().inQuirksMode()) ? HTMLQuirksMode : HTMLStandardMode;
inlineStyle = MutableStylePropertySet::create(mode);
} else if (!inlineStyle->isMutable()) {
inlineStyle = inlineStyle->mutableCopy();
}
- return toMutableStylePropertySet(inlineStyle);
+ return *toMutableStylePropertySet(inlineStyle);
}
void Element::clearMutableInlineStyleIfEmpty()
{
- if (ensureMutableInlineStyle()->isEmpty()) {
- ensureUniqueElementData()->m_inlineStyle.clear();
+ if (ensureMutableInlineStyle().isEmpty()) {
+ ensureUniqueElementData().m_inlineStyle.clear();
}
}
@@ -3377,7 +3385,7 @@
inlineStyle = BisonCSSParser::parseInlineStyleDeclaration(newStyleString, this);
} else {
ASSERT(inlineStyle->isMutable());
- static_pointer_cast<MutableStylePropertySet>(inlineStyle)->parseDeclaration(newStyleString, document().elementSheet()->contents());
+ static_pointer_cast<MutableStylePropertySet>(inlineStyle)->parseDeclaration(newStyleString, document().elementSheet().contents());
}
}
@@ -3389,7 +3397,7 @@
startLineNumber = document().scriptableDocumentParser()->lineNumber();
if (newStyleString.isNull()) {
- ensureUniqueElementData()->m_inlineStyle.clear();
+ ensureUniqueElementData().m_inlineStyle.clear();
} else if (modificationReason == ModifiedByCloning || document().contentSecurityPolicy()->allowInlineStyle(document().url(), startLineNumber)) {
setInlineStyleFromString(newStyleString);
}
@@ -3412,7 +3420,7 @@
bool Element::setInlineStyleProperty(CSSPropertyID propertyID, CSSValueID identifier, bool important)
{
ASSERT(isStyledElement());
- ensureMutableInlineStyle()->setProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important);
+ ensureMutableInlineStyle().setProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important);
inlineStyleChanged();
return true;
}
@@ -3420,7 +3428,7 @@
bool Element::setInlineStyleProperty(CSSPropertyID propertyID, CSSPropertyID identifier, bool important)
{
ASSERT(isStyledElement());
- ensureMutableInlineStyle()->setProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important);
+ ensureMutableInlineStyle().setProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important);
inlineStyleChanged();
return true;
}
@@ -3428,7 +3436,7 @@
bool Element::setInlineStyleProperty(CSSPropertyID propertyID, double value, CSSPrimitiveValue::UnitTypes unit, bool important)
{
ASSERT(isStyledElement());
- ensureMutableInlineStyle()->setProperty(propertyID, cssValuePool().createValue(value, unit), important);
+ ensureMutableInlineStyle().setProperty(propertyID, cssValuePool().createValue(value, unit), important);
inlineStyleChanged();
return true;
}
@@ -3436,7 +3444,7 @@
bool Element::setInlineStyleProperty(CSSPropertyID propertyID, const String& value, bool important)
{
ASSERT(isStyledElement());
- bool changes = ensureMutableInlineStyle()->setProperty(propertyID, value, important, document().elementSheet()->contents());
+ bool changes = ensureMutableInlineStyle().setProperty(propertyID, value, important, document().elementSheet().contents());
if (changes)
inlineStyleChanged();
return changes;
@@ -3447,7 +3455,7 @@
ASSERT(isStyledElement());
if (!inlineStyle())
return false;
- bool changes = ensureMutableInlineStyle()->removeProperty(propertyID);
+ bool changes = ensureMutableInlineStyle().removeProperty(propertyID);
if (changes)
inlineStyleChanged();
return changes;
@@ -3458,16 +3466,16 @@
ASSERT(isStyledElement());
if (!inlineStyle())
return;
- ensureMutableInlineStyle()->clear();
+ ensureMutableInlineStyle().clear();
inlineStyleChanged();
}
void Element::updatePresentationAttributeStyle()
{
// ShareableElementData doesn't store presentation attribute style, so make sure we have a UniqueElementData.
- UniqueElementData* elementData = ensureUniqueElementData();
- elementData->m_presentationAttributeStyleIsDirty = false;
- elementData->m_presentationAttributeStyle = computePresentationAttributeStyle(*this);
+ UniqueElementData& elementData = ensureUniqueElementData();
+ elementData.m_presentationAttributeStyleIsDirty = false;
+ elementData.m_presentationAttributeStyle = computePresentationAttributeStyle(*this);
}
void Element::addPropertyToPresentationAttributeStyle(MutableStylePropertySet* style, CSSPropertyID propertyID, CSSValueID identifier)
@@ -3521,17 +3529,17 @@
// Turn off style sharing for elements that can gain layers for reasons outside of the style system.
// See comments in RenderObject::setStyle().
// FIXME: Why does gaining a layer from outside the style system require disabling sharing?
- if (hasTagName(iframeTag)
- || hasTagName(frameTag)
- || hasTagName(embedTag)
- || hasTagName(objectTag)
- || hasTagName(appletTag)
- || hasTagName(canvasTag))
+ if (isHTMLIFrameElement(*this)
+ || isHTMLFrameElement(*this)
+ || isHTMLEmbedElement(*this)
+ || isHTMLObjectElement(*this)
+ || isHTMLAppletElement(*this)
+ || isHTMLCanvasElement(*this))
return false;
// FIXME: We should share style for option and optgroup whenever possible.
// Before doing so, we need to resolve issues in HTMLSelectElement::recalcListItems
// and RenderMenuList::setText. See also https://bugs.webkit.org/show_bug.cgi?id=88405
- if (hasTagName(optionTag) || hasTagName(optgroupTag))
+ if (isHTMLOptionElement(*this) || isHTMLOptGroupElement(*this))
return false;
if (FullscreenElementStack::isActiveFullScreenElement(this))
return false;