Bug 1330051; Reparse style attribute when adopting across style backends; r=bz

MozReview-Commit-ID: LWN57KApiMu

--HG--
extra : rebase_source : 20cfb66a8d6d5f88aa3db9cc6876f986d71290b4
This commit is contained in:
Manish Goregaokar 2017-03-24 15:28:19 -07:00
parent 1f58a6ce81
commit b8c378e1a5
12 changed files with 62 additions and 10 deletions

View File

@ -1673,7 +1673,7 @@ Element::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
// XXXbz if we already have a style attr parsed, this won't do
// anything... need to fix that.
// If MayHaveStyle() is true, we must be an nsStyledElement
static_cast<nsStyledElement*>(this)->ReparseStyleAttribute(false);
static_cast<nsStyledElement*>(this)->ReparseStyleAttribute(false, false);
}
if (aDocument) {

View File

@ -1154,10 +1154,11 @@ public:
* node has been changed.
*
* The new document can be reached via OwnerDoc().
*
* If you override this method,
* please call up to the parent NodeInfoChanged.
*/
virtual void NodeInfoChanged(nsIDocument* aOldDoc)
{
}
virtual void NodeInfoChanged(nsIDocument* aOldDoc) {}
/**
* Parse a string into an nsAttrValue for a CORS attribute. This

View File

@ -101,7 +101,7 @@ nsStyledElement::Style()
if (!slots->mStyle) {
// Just in case...
ReparseStyleAttribute(true);
ReparseStyleAttribute(true, false);
slots->mStyle = new nsDOMCSSAttributeDeclaration(this, false);
SetMayHaveStyle();
@ -111,13 +111,13 @@ nsStyledElement::Style()
}
nsresult
nsStyledElement::ReparseStyleAttribute(bool aForceInDataDoc)
nsStyledElement::ReparseStyleAttribute(bool aForceInDataDoc, bool aForceIfAlreadyParsed)
{
if (!MayHaveStyle()) {
return NS_OK;
}
const nsAttrValue* oldVal = mAttrsAndChildren.GetAttr(nsGkAtoms::style);
if (oldVal && oldVal->Type() != nsAttrValue::eCSSDeclaration) {
if (oldVal && (aForceIfAlreadyParsed || oldVal->Type() != nsAttrValue::eCSSDeclaration)) {
nsAttrValue attrValue;
nsAutoString stringValue;
oldVal->ToString(stringValue);
@ -131,6 +131,15 @@ nsStyledElement::ReparseStyleAttribute(bool aForceInDataDoc)
return NS_OK;
}
void
nsStyledElement::NodeInfoChanged(nsIDocument* aOldDoc)
{
nsStyledElementBase::NodeInfoChanged(aOldDoc);
if (OwnerDoc()->GetStyleBackendType() != aOldDoc->GetStyleBackendType()) {
ReparseStyleAttribute(false, /* aForceIfAlreadyParsed */ true);
}
}
nsICSSDeclaration*
nsStyledElement::GetExistingStyle()
{

View File

@ -76,9 +76,12 @@ protected:
* Create the style struct from the style attr. Used when an element is
* first put into a document. Only has an effect if the old value is a
* string. If aForceInDataDoc is true, will reparse even if we're in a data
* document.
* document. If aForceIfAlreadyParsed is set, this will always reparse even
* if the value has already been parsed.
*/
nsresult ReparseStyleAttribute(bool aForceInDataDoc);
nsresult ReparseStyleAttribute(bool aForceInDataDoc, bool aForceIfAlreadyParsed);
virtual void NodeInfoChanged(nsIDocument* aOldDoc) override;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsStyledElement, NS_STYLED_ELEMENT_IID)

View File

@ -712,6 +712,7 @@ HTMLImageElement::IntrinsicState() const
void
HTMLImageElement::NodeInfoChanged(nsIDocument* aOldDoc)
{
nsGenericHTMLElement::NodeInfoChanged(aOldDoc);
// Resetting the last selected source if adoption steps are run.
mLastSelectedSource = nullptr;
}

View File

@ -2841,6 +2841,7 @@ nsGenericHTMLFormElementWithState::RestoreFormControlState()
void
nsGenericHTMLFormElementWithState::NodeInfoChanged(nsIDocument* aOldDoc)
{
nsGenericHTMLElement::NodeInfoChanged(aOldDoc);
mStateKey.SetIsVoid(true);
}

View File

@ -909,6 +909,7 @@ nsSVGElement::IsNodeOfType(uint32_t aFlags) const
void
nsSVGElement::NodeInfoChanged(nsIDocument* aOldDoc)
{
nsSVGElementBase::NodeInfoChanged(aOldDoc);
aOldDoc->UnscheduleSVGForPresAttrEvaluation(this);
mContentDeclarationBlock = nullptr;
OwnerDoc()->ScheduleSVGForPresAttrEvaluation(this);

View File

@ -118,7 +118,7 @@ public:
* We override the default to unschedule computation of Servo declaration blocks
* when adopted across documents.
*/
virtual void NodeInfoChanged(nsIDocument* aOldDoc) override;
virtual void NodeInfoChanged(nsIDocument* aOldDoc) final;
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) override;
void WalkAnimatedContentStyleRules(nsRuleWalker* aRuleWalker);

View File

@ -0,0 +1,17 @@
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" class="reftest-wait">
<foreignObject width="500" height="500">
<iframe xmlns="http://www.w3.org/1999/xhtml"
srcdoc="A test">
</iframe>
</foreignObject>
<script>
frames[0].onload = function() {
var doc = frames[0].document;
let el = doc.createElement('div');
el.innerHTML = "This should remain green";
el.style.color = "green";
doc.body.appendChild(el);
document.documentElement.removeAttribute("class");
}
</script>
</svg>

After

Width:  |  Height:  |  Size: 559 B

View File

@ -0,0 +1,17 @@
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" class="reftest-wait">
<foreignObject width="500" height="500">
<iframe xmlns="http://www.w3.org/1999/xhtml"
srcdoc="A test">
</iframe>
<div xmlns="http://www.w3.org/1999/xhtml"
style="color: green" id="myDiv">This should remain green</div>
</foreignObject>
<script>
let el = document.getElementById('myDiv');
frames[0].onload = function() {
var doc = frames[0].document;
doc.body.appendChild(el);
document.documentElement.removeAttribute("class");
}
</script>
</svg>

After

Width:  |  Height:  |  Size: 602 B

View File

@ -1988,5 +1988,6 @@ HTTP == 652991-1b.html 652991-1b.html
HTTP == 652991-2.html 652991-2.html
HTTP == 652991-3.html 652991-3.html
fails HTTP == 652991-4.html 652991-4.html
== 1330051.svg 1330051.svg

View File

@ -1989,3 +1989,4 @@ fuzzy(2,40000) == 1316719-1b.html 1316719-1-ref.html
fuzzy(2,40000) == 1316719-1c.html 1316719-1-ref.html
skip-if(Android) != 1318769-1.html 1318769-1-ref.html
== 1322512-1.html 1322512-1-ref.html
== 1330051.svg 1330051-ref.svg