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() { ...@@ -511,6 +511,15 @@ const ActiveStyleSheetVector StyleEngine::ActiveStyleSheetsForInspector() {
return active_style_sheets; 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) { void StyleEngine::ShadowRootRemovedFromDocument(ShadowRoot* shadow_root) {
style_sheet_collection_map_.erase(shadow_root); style_sheet_collection_map_.erase(shadow_root);
active_tree_scopes_.erase(shadow_root); active_tree_scopes_.erase(shadow_root);
...@@ -671,9 +680,9 @@ void StyleEngine::MarkTreeScopeDirty(TreeScope& scope) { ...@@ -671,9 +680,9 @@ void StyleEngine::MarkTreeScopeDirty(TreeScope& scope) {
return; return;
} }
TreeScopeStyleSheetCollection& collection = TreeScopeStyleSheetCollection* collection = StyleSheetCollectionFor(scope);
EnsureStyleSheetCollectionFor(scope); DCHECK(collection);
collection.MarkSheetListDirty(); collection->MarkSheetListDirty();
dirty_tree_scopes_.insert(&scope); dirty_tree_scopes_.insert(&scope);
GetDocument().ScheduleLayoutTreeUpdateIfNeeded(); GetDocument().ScheduleLayoutTreeUpdateIfNeeded();
} }
......
...@@ -217,6 +217,7 @@ class CORE_EXPORT StyleEngine final ...@@ -217,6 +217,7 @@ class CORE_EXPORT StyleEngine final
void ResetCSSFeatureFlags(const RuleFeatureSet&); void ResetCSSFeatureFlags(const RuleFeatureSet&);
void ShadowRootInsertedToDocument(ShadowRoot&);
void ShadowRootRemovedFromDocument(ShadowRoot*); void ShadowRootRemovedFromDocument(ShadowRoot*);
void AddTreeBoundaryCrossingScope(const TreeScope&); void AddTreeBoundaryCrossingScope(const TreeScope&);
const TreeOrderedList& TreeBoundaryCrossingScopes() const { const TreeOrderedList& TreeBoundaryCrossingScopes() const {
......
...@@ -167,8 +167,7 @@ Node::InsertionNotificationRequest ShadowRoot::InsertedInto( ...@@ -167,8 +167,7 @@ Node::InsertionNotificationRequest ShadowRoot::InsertedInto(
if (!insertion_point.isConnected()) if (!insertion_point.isConnected())
return kInsertionDone; return kInsertionDone;
if (HasAdoptedStyleSheets()) GetDocument().GetStyleEngine().ShadowRootInsertedToDocument(*this);
GetDocument().GetStyleEngine().SetNeedsActiveStyleUpdate(*this);
GetDocument().GetSlotAssignmentEngine().Connected(*this); GetDocument().GetSlotAssignmentEngine().Connected(*this);
......
...@@ -228,6 +228,41 @@ promise_test(() => { ...@@ -228,6 +228,41 @@ promise_test(() => {
}); });
}, 'Re-attaching shadow host with adopted stylesheets work'); }, '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(() => { promise_test(() => {
const plainSheet = new CSSStyleSheet(); const plainSheet = new CSSStyleSheet();
const redStyleSheetPromise = plainSheet.replace(redStyleTexts[0]); 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