зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1737455 - Don't clear adoptedStyleSheets when adopting from a template document to its owner or vice versa. r=edgar
See https://github.com/WICG/construct-stylesheets/issues/133, which is where this change was discussed (and then made to Chromium apparently). I filed https://github.com/w3c/csswg-drafts/issues/7229 to put some actual spec text here. Also, tweak the wpt which is supposed to test so that it fails without this change. Differential Revision: https://phabricator.services.mozilla.com/D144564
This commit is contained in:
Родитель
3bb799fbce
Коммит
0bc8695c2a
|
@ -2889,6 +2889,10 @@ class Document : public nsINode,
|
||||||
*/
|
*/
|
||||||
Document* GetTemplateContentsOwner();
|
Document* GetTemplateContentsOwner();
|
||||||
|
|
||||||
|
Document* GetTemplateContentsOwnerIfExists() const {
|
||||||
|
return mTemplateContentsOwner.get();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this document is a static clone of a normal document.
|
* Returns true if this document is a static clone of a normal document.
|
||||||
*
|
*
|
||||||
|
|
|
@ -620,11 +620,6 @@ int32_t DocumentOrShadowRoot::StyleOrderIndexOfSheet(
|
||||||
return mStyleSheets.IndexOf(&aSheet);
|
return mStyleSheets.IndexOf(&aSheet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentOrShadowRoot::GetAdoptedStyleSheets(
|
|
||||||
nsTArray<RefPtr<StyleSheet>>& aAdoptedStyleSheets) const {
|
|
||||||
aAdoptedStyleSheets = mAdoptedStyleSheets.Clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DocumentOrShadowRoot::TraverseSheetRefInStylesIfApplicable(
|
void DocumentOrShadowRoot::TraverseSheetRefInStylesIfApplicable(
|
||||||
StyleSheet& aSheet, nsCycleCollectionTraversalCallback& cb) {
|
StyleSheet& aSheet, nsCycleCollectionTraversalCallback& cb) {
|
||||||
if (!aSheet.IsApplicable()) {
|
if (!aSheet.IsApplicable()) {
|
||||||
|
|
|
@ -89,8 +89,6 @@ class DocumentOrShadowRoot : public RadioGroupManager {
|
||||||
|
|
||||||
StyleSheetList* StyleSheets();
|
StyleSheetList* StyleSheets();
|
||||||
|
|
||||||
void GetAdoptedStyleSheets(nsTArray<RefPtr<StyleSheet>>&) const;
|
|
||||||
|
|
||||||
void RemoveStyleSheet(StyleSheet&);
|
void RemoveStyleSheet(StyleSheet&);
|
||||||
|
|
||||||
Element* GetElementById(const nsAString& aElementId);
|
Element* GetElementById(const nsAString& aElementId);
|
||||||
|
|
|
@ -101,6 +101,17 @@ JSObject* ShadowRoot::WrapNode(JSContext* aCx,
|
||||||
return mozilla::dom::ShadowRoot_Binding::Wrap(aCx, this, aGivenProto);
|
return mozilla::dom::ShadowRoot_Binding::Wrap(aCx, this, aGivenProto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShadowRoot::NodeInfoChanged(Document* aOldDoc) {
|
||||||
|
DocumentFragment::NodeInfoChanged(aOldDoc);
|
||||||
|
Document* newDoc = OwnerDoc();
|
||||||
|
const bool fromOrToTemplate =
|
||||||
|
aOldDoc->GetTemplateContentsOwnerIfExists() == newDoc ||
|
||||||
|
newDoc->GetTemplateContentsOwnerIfExists() == aOldDoc;
|
||||||
|
if (!fromOrToTemplate) {
|
||||||
|
ClearAdoptedStyleSheets();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ShadowRoot::CloneInternalDataFrom(ShadowRoot* aOther) {
|
void ShadowRoot::CloneInternalDataFrom(ShadowRoot* aOther) {
|
||||||
if (aOther->IsUAWidget()) {
|
if (aOther->IsUAWidget()) {
|
||||||
SetIsUAWidget();
|
SetIsUAWidget();
|
||||||
|
|
|
@ -185,10 +185,7 @@ class ShadowRoot final : public DocumentFragment,
|
||||||
|
|
||||||
JSObject* WrapNode(JSContext*, JS::Handle<JSObject*> aGivenProto) final;
|
JSObject* WrapNode(JSContext*, JS::Handle<JSObject*> aGivenProto) final;
|
||||||
|
|
||||||
void NodeInfoChanged(Document* aOldDoc) override {
|
void NodeInfoChanged(Document* aOldDoc) override;
|
||||||
DocumentFragment::NodeInfoChanged(aOldDoc);
|
|
||||||
ClearAdoptedStyleSheets();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddToIdTable(Element* aElement, nsAtom* aId);
|
void AddToIdTable(Element* aElement, nsAtom* aId);
|
||||||
void RemoveFromIdTable(Element* aElement, nsAtom* aId);
|
void RemoveFromIdTable(Element* aElement, nsAtom* aId);
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
[CSSStyleSheet-template-adoption.html]
|
|
||||||
[adoptedStyleSheets won'te be cleared when adopting into/from <template>s]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -13,30 +13,41 @@
|
||||||
<script>
|
<script>
|
||||||
test(function() {
|
test(function() {
|
||||||
let sheet = new CSSStyleSheet();
|
let sheet = new CSSStyleSheet();
|
||||||
sheet.replaceSync("div { color: red }");
|
sheet.replaceSync("div { color: blue }");
|
||||||
|
|
||||||
let host = document.getElementById("host");
|
let host = document.getElementById("host");
|
||||||
let root = host.attachShadow({ mode: "open" });
|
let root = host.attachShadow({ mode: "open" });
|
||||||
|
root.innerHTML = `<div></div>`;
|
||||||
root.adoptedStyleSheets = [sheet];
|
root.adoptedStyleSheets = [sheet];
|
||||||
|
|
||||||
|
function assertAdoptedStyleSheet() {
|
||||||
|
assert_equals(host.ownerDocument, root.firstChild.ownerDocument, "Shadow root was not adopted?");
|
||||||
assert_equals(root.adoptedStyleSheets.length, 1);
|
assert_equals(root.adoptedStyleSheets.length, 1);
|
||||||
assert_equals(root.adoptedStyleSheets[0], sheet);
|
assert_equals(root.adoptedStyleSheets[0], sheet);
|
||||||
|
if (root.ownerDocument == document) {
|
||||||
|
assert_equals(getComputedStyle(root.firstChild).color, "rgb(0, 0, 255)", "Sheet should apply");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assertAdoptedStyleSheet();
|
||||||
|
|
||||||
// adoptedStyleSheets is not cleared when adopted into a <template>.
|
// adoptedStyleSheets is not cleared when adopted into a <template>.
|
||||||
const template = document.getElementById("template");
|
const template = document.getElementById("template");
|
||||||
template.content.appendChild(host);
|
template.content.appendChild(host);
|
||||||
assert_equals(root.adoptedStyleSheets.length, 1);
|
|
||||||
assert_equals(root.adoptedStyleSheets[0], sheet);
|
assert_not_equals(host.ownerDocument, document, "Should've been adopted");
|
||||||
|
assertAdoptedStyleSheet();
|
||||||
|
|
||||||
// adoptedStyleSheets is not cleared when adopted back in the main document.
|
// adoptedStyleSheets is not cleared when adopted back in the main document.
|
||||||
document.body.appendChild(host);
|
document.body.appendChild(host);
|
||||||
assert_equals(root.adoptedStyleSheets.length, 1);
|
assert_equals(host.ownerDocument, document, "Should've been re-adopted");
|
||||||
assert_equals(root.adoptedStyleSheets[0], sheet);
|
assertAdoptedStyleSheet();
|
||||||
|
|
||||||
// adoptedStyleSheets is not cleared when adopted into a nested <template>.
|
// adoptedStyleSheets is not cleared when adopted into a nested <template>.
|
||||||
const nested_template = template.content.firstElementChild;
|
const nested_template = template.content.firstElementChild;
|
||||||
nested_template.content.appendChild(host);
|
nested_template.content.appendChild(host);
|
||||||
assert_equals(root.adoptedStyleSheets.length, 1);
|
assert_not_equals(host.ownerDocument, document, "Should've been adopted");
|
||||||
assert_equals(root.adoptedStyleSheets[0], sheet);
|
assertAdoptedStyleSheet();
|
||||||
|
|
||||||
// adoptedStyleSheets is cleared when adopted into an <iframe>.
|
// adoptedStyleSheets is cleared when adopted into an <iframe>.
|
||||||
const iframe = document.createElement("iframe");
|
const iframe = document.createElement("iframe");
|
||||||
|
|
Загрузка…
Ссылка в новой задаче