Commit 05bbbfd8 authored by Rakina Zata Amni's avatar Rakina Zata Amni Committed by Commit Bot

Update |active_tree_scopes| etc when shadow root with adoptedStyleSheets is inserted

When a shadow root with non-empty |adoptedStyleSheets| is inserted, we
should make sure that the |active_tree_scopes_| list is updated and the
tree scope is marked dirty so that style invalidation & recalc will
work.

Bug: 934340
Change-Id: I365936e4bcc0132c938fe4e200e208abac91d3d9
Reviewed-on: https://chromium-review.googlesource.com/c/1482437
Commit-Queue: Rakina Zata Amni <rakina@chromium.org>
Reviewed-by: default avatarKent Tamura <tkent@chromium.org>
Reviewed-by: default avatarAnders Hartvoll Ruud <andruud@chromium.org>
Cr-Commit-Position: refs/heads/master@{#634624}
parent 40ab0983
......@@ -511,6 +511,15 @@ const ActiveStyleSheetVector StyleEngine::ActiveStyleSheetsForInspector() {
return active_style_sheets;
}
void StyleEngine::ShadowRootInsertedToDocument(ShadowRoot& shadow_root) {
DCHECK(shadow_root.isConnected());
if (GetDocument().IsDetached() || !shadow_root.HasAdoptedStyleSheets())
return;
EnsureStyleSheetCollectionFor(shadow_root);
SetNeedsActiveStyleUpdate(shadow_root);
active_tree_scopes_.insert(&shadow_root);
}
void StyleEngine::ShadowRootRemovedFromDocument(ShadowRoot* shadow_root) {
style_sheet_collection_map_.erase(shadow_root);
active_tree_scopes_.erase(shadow_root);
......@@ -671,9 +680,9 @@ void StyleEngine::MarkTreeScopeDirty(TreeScope& scope) {
return;
}
TreeScopeStyleSheetCollection& collection =
EnsureStyleSheetCollectionFor(scope);
collection.MarkSheetListDirty();
TreeScopeStyleSheetCollection* collection = StyleSheetCollectionFor(scope);
DCHECK(collection);
collection->MarkSheetListDirty();
dirty_tree_scopes_.insert(&scope);
GetDocument().ScheduleLayoutTreeUpdateIfNeeded();
}
......
......@@ -217,6 +217,7 @@ class CORE_EXPORT StyleEngine final
void ResetCSSFeatureFlags(const RuleFeatureSet&);
void ShadowRootInsertedToDocument(ShadowRoot&);
void ShadowRootRemovedFromDocument(ShadowRoot*);
void AddTreeBoundaryCrossingScope(const TreeScope&);
const TreeOrderedList& TreeBoundaryCrossingScopes() const {
......
......@@ -167,8 +167,7 @@ Node::InsertionNotificationRequest ShadowRoot::InsertedInto(
if (!insertion_point.isConnected())
return kInsertionDone;
if (HasAdoptedStyleSheets())
GetDocument().GetStyleEngine().SetNeedsActiveStyleUpdate(*this);
GetDocument().GetStyleEngine().ShadowRootInsertedToDocument(*this);
GetDocument().GetSlotAssignmentEngine().Connected(*this);
......
......@@ -228,6 +228,41 @@ promise_test(() => {
});
}, 'Re-attaching shadow host with adopted stylesheets work');
test(() => {
const sheet = new CSSStyleSheet();
sheet.replaceSync(":host { color: red; }");
const host = document.createElement("div");
let sr = host.attachShadow({mode: "open"});
sr.adoptedStyleSheets = [sheet];
document.body.appendChild(host);
assert_equals(getComputedStyle(host).color, "rgb(255, 0, 0)", "Style applies when connected");
sheet.replaceSync(":host { color: blue; }");
assert_equals(getComputedStyle(host).color, "rgb(0, 0, 255)", "Style update applies when connected");
}, 'Attaching a shadow root that already has adopted stylesheets work');
test(() => {
const sheet = new CSSStyleSheet();
sheet.replaceSync(":host([red]) { color: red; } :host(.blue) { color: blue; }");
const host = document.createElement("div");
host.toggleAttribute("red");
document.body.appendChild(host);
assert_equals(getComputedStyle(host).color, "rgb(0, 0, 0)", "No style applies yet");
let sr = host.attachShadow({mode: "open"});
sr.adoptedStyleSheets = [sheet];
assert_equals(getComputedStyle(host).color, "rgb(255, 0, 0)", "Style applies after adding style");
document.body.removeChild(host);
document.body.appendChild(host);
assert_equals(getComputedStyle(host).color, "rgb(255, 0, 0)", "Style applies after reattachment");
host.toggleAttribute("red");
assert_equals(getComputedStyle(host).color, "rgb(0, 0, 0)", "Attribute updates to the element after reattachment apply");
host.classList.toggle("blue");
assert_equals(getComputedStyle(host).color, "rgb(0, 0, 255)", "Class updates to the element after reattachment apply");
}, "Re-attaching shadow host and updating attributes work");
promise_test(() => {
const plainSheet = new CSSStyleSheet();
const redStyleSheetPromise = plainSheet.replace(redStyleTexts[0]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment