[css-highlight-api] Specifying behavior for Highlights involving multiple documents (original) (raw)
The Highlight API spec doesn't really consider cases where Highlights exist in multiple documents. The use of same-domain iframes bring up some interesting cases.
Case 1: A Highlight
is registered in multiple registries.
let iframe = document.createElement("iframe"); document.body.appendChild(iframe); let r = new Range(); r.setStart(document.body, 0); r.setStart(document.body, 1); let h1 = new Highlight(r); CSS.highlights.set("foo", h1); iframe.contentWindow.CSS.highlights.set("foo", h1);
This case breaks some assumptions of the current Chromium implementation, where a Highlight only has a pointer back to a single HighlightRegistry instance. The language of the spec also seems to assume that a highlight registry only contains highlights from a single document, but there is nothing explicitly blocking the scenario in the code above.
https://drafts.csswg.org/css-highlight-api-1/#registration:
"The highlight registry
is accessed via the highlights
attribute of the CSS
namespace, and represents all the custom highlights registered for the current global object’s associated Document
."
It's not completely clear what should happen here. Should it be possible for a Highlight to be added to multiple registries? If so, should changes to its contents trigger repaints for the documents associated with both registries?
Case 2: A Highlight
has ranges from multiple documents
let iframe = document.createElement("iframe"); document.body.appendChild(iframe); let r1 = new Range(); r1.setStart(document.body, 0); r1.setStart(document.body, 1); let r2 = new Range(); r2.setStart(iframe.contentDocument.body, 0); r2.setStart(iframe.contentDocument.body, 1); let h1 = new Highlight(r1, r2); CSS.highlights.set("foo", h1);
The language in https://drafts.csswg.org/css-highlight-api-1/#range-invalidation says that the UA must ignore ranges not in a document tree, but doesn't consider the case where ranges are in a different document tree from the one associated with the given highlight registry.
Again it's not clear what should happen here. Should the UA ignore ranges that are in a document tree different from the one associated with the highlight registry containing the Highlight
?
Solutions
An incremental fix for these corner cases would be to specify the following:
- A Highlight can be added to multiple highlight registries. In Chromium, this would mean that Highlight would store a list of pointers back to highlight registries, instead of a single pointer.
- When computing how to render a document, if a range in the highlight registry associated with that document is not in that document tree, ignore that range.
A result of doing things this way is that if a Highlight has ranges that are in different document trees, both ranges will be painted if and only if the Highlight was added to the highlight registry for both ranges.
A more adventurous idea that simplifies this somewhat is to consider whether Highlight can be eliminated altogether, such that ranges are added directly to the highlight registry. After #6198, Highlight is no longer needed to store the name. That leaves only priority
. Could priority
be specified some other way? One idea is to have a method to do this directly on the registry, e.g. CSS.highlights.setPriority("name", 42)
. Or, maybe the priority could be provided in CSS:
::highlight(name) { background-color: orange; priority: 42; }
I don't immediately see a reason not to specify the priority through the cascade like this, so it might be worth considering as a way to eliminate Highlight and simplify the API, thus making it easier to handle the cases described above involving multiple document trees.