WICG / construct-stylesheets

API for constructing CSS stylesheet objects
Other
138 stars 25 forks source link

Observing the changes #126

Open tophf opened 4 years ago

tophf commented 4 years ago

This is a revised proposal addressing the feedback by domenic in the earlier one, which got unexpectedly off-topic.

We can observe changes in document.styleSheets, although somewhat ineffectively, via MutationObserver on the entire document or shadow root and check which link and style elements were added or removed.

There seems to be no way to observe changes in document.adoptedStyleSheets without resorting to a periodic check via setInterval.

We could hook the global setter (or shadow root's one) like the web scripts did 20-30 years ago. That seems unfortunate for a modern API. And it won't help in one real world scenario where an extension makes the change to adoptedStyleSheets in its content script: the page won't be able to hook the setter because extensions run in an isolated execution context. AFAIK This is not something an extension team of any browser can solve because such an isolation of JavaScript code is an inherent part of running extensions alongside web pages securely.

What about adding some kind of notification e.g. an asynchronous event or an observer?

For example, a new event adoptedStyleSheetsChanged on the respective DocumentOrShadowRoot, that would coalesce all changes and notify only once per JS event loop task.

Another idea is AdoptedStyleSheetObserver that's similar to other Observer API. It's not even necessary to provide any info to the callback if it turns out to be complicated or slow because the interested parties most likely would only need to get notified that such a change happened at all, not the individual additions or removals, and if needed they can save a copy of the old list and compare it to the current one.


Such an event/observer would make this feature more DOM-y, would solve the above use case with web-extensions as it would be context-agnostic just like other DOM events/observers, and would be beneficial to any modular web technology where a third-party JS library might want to independently observe the changes in an encapsulated fashion as they do now successfully with the existing DOM events.

tophf commented 2 years ago

Now that document.adoptedStyleSheets is not frozen anymore, the JS authors will have to override every Array.prototype method in order to detect changes. Well, that's if we want to intercept with 100% reliability, but we can simply add the spoofed methods as own properties on adoptedStyleSheets, which should work in 99.9% of cases, arguably. Still a lot of unnecessary work, and it's super fragile.

givankin commented 2 years ago

That would be a life-saver for developers implementing co-browse solutions. An event or a MutationObserver-like capability would be great.