-
-
Notifications
You must be signed in to change notification settings - Fork 129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Shadow DOM support for widgets #434
Labels
Comments
krassowski
added
enhancement
New feature or request
status:Needs Triage
performance
Addresses performance
labels
Oct 9, 2022
One place where shadow DOM wrappers could be very useful (performance aside) are CellOutput widgets in JupyterLab; this would allow outputs to add any CSS stylesheet they want without breaking the JupyterLab styling (on the other hand it would prevent them from modifying the theme which is probably a good thing security-wise). |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Problem
Lumino can be used in situations where there are hundreds of thousands of nodes, and where stylesheets from different providers are attached at the same time. Limiting the stylesheet applicability to a specific subset of nodes is possible with two approaches:
Lumino currently does not support shadow DOM in the sense that individual widgets cannot be moved to shadow DOM and there are no methods exposed allowing to attach stylesheets to specific widgets/shadow DOM roots.
Proposed Solution
Note: If you have not worked with shadow DOM before please see the details below to understand why the solution (2) wraps the shadow root into another
<div>
.DOM nodes can be moved to the shadow DOM by attaching them to a transient shadow DOM root which is attached to another DOM node. There can ever be only one shadow DOM root in each DOM element:
This is allowed:
This is forbidden (multiple shadow roots were removed from the specification in 2015):
The solutions I considered are:
Widget.node
andWidget.attachmentNode
; by defaultWidget.attachmentNode
would be just an alias forWidget.node
but when a widget is instructed to wrap itself into shadow DOM, it would point to the ShadowRoot (but wrapped into a translucent div to avoid the issue of multiple-roots)widget.node
is no longer a direct descendant of its parent (lm-translucentWrapper
is).Proxy
to create Frankenstein-kind hybrid ofShadowRoot
andHTMLElement
and keepingnode
without changes: this does not work because native code ininsertBefore
and friends does not accept non-native nodes (strict class checks are performed at runtime so even if the proxy quacks like a perfect node, it will be rejected).Then we could either:
ShadowWidget
which would put its node into shadow DOM.Further we would need to be consider how to handle CSS stylesheets. Widgets could have a method like:
I am slightly leaning towards 2a as that would allow us to enable shadow DOM downstream by changing the options without a need to duplicate class definitions. The separation of
node
andattachmentNode
could be introduced in Lumino 2.0 whether we decide to proceed with the shadow DOM implementation or not.Additional context
I was able to set it up in JupyterLab and created a code snipped to copy all stylesheets for adoption in widgets, thus limiting the performance benefits to containing style changes to nodes within the shadow DOM but still using all styles; this is super preliminary and I will update if I get a chance to perform a proper benchmark:
MainAreaWidget
to shadow DOMDockLayout
to shadow DOMMy confidence in the results above is low. I expect that gains will differ depending on the browser.
The text was updated successfully, but these errors were encountered: