@readium/decorator 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -87,12 +87,22 @@ class DecorationController {
|
|
|
87
87
|
registerDecorationObserver(group: string, observer: DecorationObserver): void
|
|
88
88
|
unregisterDecorationObserver(observer: DecorationObserver): void
|
|
89
89
|
|
|
90
|
+
// Watches an additional element for resize, so decorations relay out when it resizes
|
|
91
|
+
// even if the document's own size doesn't change (e.g. a sidebar collapsing and the
|
|
92
|
+
// reading pane reflowing inside it). Selector is resolved against the Decorator's document.
|
|
93
|
+
addDecorationResizeTarget(selector: string): void
|
|
94
|
+
removeDecorationResizeTarget(selector: string): void
|
|
95
|
+
|
|
90
96
|
destroy(): void
|
|
91
97
|
}
|
|
92
98
|
|
|
93
99
|
interface DecorationControllerConfig {
|
|
94
100
|
// Named style templates. Register a template here and reference it by ID in decoration styles.
|
|
95
101
|
decorationTemplates?: Record<string, HTMLDecorationTemplate>;
|
|
102
|
+
|
|
103
|
+
// CSS selectors to watch for resize from construction, equivalent to calling
|
|
104
|
+
// addDecorationResizeTarget() for each one right after construction.
|
|
105
|
+
resizeWatchSelectors?: string[];
|
|
96
106
|
}
|
|
97
107
|
```
|
|
98
108
|
|
|
@@ -165,7 +175,7 @@ interface IComms {
|
|
|
165
175
|
| `BuiltinDecorationStyle` | `{ type?, tint?, layout?, width?, enforceContrast?, expand? }` |
|
|
166
176
|
| `HTMLDecorationTemplate` | `{ type: "template", layout, width, element, stylesheet? }` — `element` is a function `(decoration) => string`, resolved to HTML per decoration before rendering |
|
|
167
177
|
| `NamedDecorationStyle` | `{ type: string }` — reference to a style registered in `DecoratorConfig.decorationTemplates` |
|
|
168
|
-
| `DecoratorConfig` | `{ decorationTemplates? }` — same shape as `DecorationControllerConfig` (the latter is a type alias of this) |
|
|
178
|
+
| `DecoratorConfig` | `{ decorationTemplates?, resizeWatchSelectors? }` — same shape as `DecorationControllerConfig` (the latter is a type alias of this) |
|
|
169
179
|
| `DecorationStyleType` | `"highlight" \| "highlightUnderline" \| "underline" \| "strikethrough" \| "outline" \| "textColor" \| "mask" \| "template"` |
|
|
170
180
|
| `DecorationLayout` | `"boxes" \| "bounds"` |
|
|
171
181
|
| `DecorationWidth` | `"wrap" \| "viewport" \| "bounds" \| "page"` |
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{supportsDecorationStyle as v,decorationsEqual as _,resolveDecorationForWire as d}from"../styles.js";class p{constructor(o
|
|
1
|
+
import{supportsDecorationStyle as v,decorationsEqual as _,resolveDecorationForWire as d}from"../styles.js";class p{constructor(e,o={}){this.host=e,this._decorations=new Map,this._activationState=new Map,this._hoverState=new Map,this._observers=new Map,this._hoveredDecorations=new Map,this._config=o,o.resizeWatchSelectors?.forEach(a=>this.addDecorationResizeTarget(a)),e.on("decoration_activated",a=>{const t=a,r=this._decorations.get(t.group)?.find(i=>i.id===t.decorationId);r&&this._observers.get(t.group)?.forEach(i=>i.onDecorationActivated?.({group:t.group,decoration:r,rect:t.rect,point:t.point}))}),e.on("decoration_pointer_enter",a=>{const t=a,r=this._decorations.get(t.group)?.find(i=>i.id===t.decorationId);r&&(this._hoveredDecorations.set(t.group,r),this._observers.get(t.group)?.forEach(i=>i.onDecorationPointerEnter?.({group:t.group,decoration:r,rect:t.rect,point:t.point})))}),e.on("decoration_pointer_leave",a=>{const t=a,r=this._decorations.get(t.group)?.find(i=>i.id===t.decorationId)??this._hoveredDecorations.get(t.group);this._hoveredDecorations.delete(t.group),r&&this._observers.get(t.group)?.forEach(i=>i.onDecorationPointerLeave?.({group:t.group,decoration:r,rect:t.rect,point:t.point}))})}addDecorationResizeTarget(e){this.host.send("decoration_resize",{action:"watch",selector:e})}removeDecorationResizeTarget(e){this.host.send("decoration_resize",{action:"unwatch",selector:e})}supportsDecorationStyle(e){return v(e,this._config.decorationTemplates)}applyDecorations(e,o){const a=this._decorations.get(o)??[],t=new Map(a.map(s=>[s.id,s])),r=new Map(e.map(s=>[s.id,s]));for(const[s,n]of t){const c=r.get(s);c?_(n,c)||this.host.send("decorate",{group:o,action:"update",decoration:d(c,this._config.decorationTemplates)}):this.host.send("decorate",{group:o,action:"remove",decoration:{id:s}})}for(const[s,n]of r)t.has(s)||this.host.send("decorate",{group:o,action:"add",decoration:d(n,this._config.decorationTemplates)});this._decorations.set(o,e);const i=this._activationState.get(o);i!==void 0&&this.host.send("decoration_activatable",{group:o,activatable:i});const h=this._hoverState.get(o);h!==void 0&&this.host.send("decoration_hoverable",{group:o,hoverable:h})}registerDecorationObserver(e,o){this._observers.has(e)||this._observers.set(e,new Set),this._observers.get(e).add(o),o.onDecorationActivated&&(this._activationState.set(e,!0),this.host.send("decoration_activatable",{group:e,activatable:!0})),(o.onDecorationPointerEnter||o.onDecorationPointerLeave)&&(this._hoverState.set(e,!0),this.host.send("decoration_hoverable",{group:e,hoverable:!0}))}unregisterDecorationObserver(e){this._observers.forEach((o,a)=>{if(!o.has(e))return;o.delete(e);const t=[...o].some(i=>i.onDecorationActivated);this._activationState.has(a)&&!t&&(this._activationState.delete(a),this.host.send("decoration_activatable",{group:a,activatable:!1}));const r=[...o].some(i=>i.onDecorationPointerEnter||i.onDecorationPointerLeave);this._hoverState.has(a)&&!r&&(this._hoverState.delete(a),this.host.send("decoration_hoverable",{group:a,hoverable:!1}))})}destroy(){this._decorations.clear(),this._activationState.clear(),this._hoverState.clear(),this._observers.clear(),this._hoveredDecorations.clear()}}export{p as DecorationController};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@readium/decorator",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Standalone decoration controller and renderer for HTML content",
|
|
6
6
|
"author": "readium",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"node": ">=18"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@readium/navigator-html-injectables": "2.
|
|
35
|
+
"@readium/navigator-html-injectables": "2.8.0",
|
|
36
36
|
"@readium/shared": "2.5.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
@@ -16,6 +16,7 @@ export class DecorationController {
|
|
|
16
16
|
|
|
17
17
|
constructor(private readonly host: DirectCommsHost, config: DecorationControllerConfig = {}) {
|
|
18
18
|
this._config = config;
|
|
19
|
+
config.resizeWatchSelectors?.forEach(selector => this.addDecorationResizeTarget(selector));
|
|
19
20
|
host.on("decoration_activated", (raw) => {
|
|
20
21
|
const ev = raw as DecorationActivatedEvent;
|
|
21
22
|
const decoration = this._decorations.get(ev.group)?.find(d => d.id === ev.decorationId);
|
|
@@ -47,6 +48,14 @@ export class DecorationController {
|
|
|
47
48
|
});
|
|
48
49
|
}
|
|
49
50
|
|
|
51
|
+
addDecorationResizeTarget(selector: string): void {
|
|
52
|
+
this.host.send("decoration_resize", { action: "watch", selector });
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
removeDecorationResizeTarget(selector: string): void {
|
|
56
|
+
this.host.send("decoration_resize", { action: "unwatch", selector });
|
|
57
|
+
}
|
|
58
|
+
|
|
50
59
|
supportsDecorationStyle(styleTypeId: string): boolean {
|
|
51
60
|
return supportsDecorationStyle(styleTypeId, this._config.decorationTemplates);
|
|
52
61
|
}
|
package/src/styles.ts
CHANGED
|
@@ -36,6 +36,13 @@ export interface DecoratorConfig {
|
|
|
36
36
|
* Template-type decoration.
|
|
37
37
|
*/
|
|
38
38
|
decorationTemplates?: Record<string, HTMLDecorationTemplate>;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* CSS selectors of additional elements to watch for resize, so decoration overlays are
|
|
42
|
+
* relaid-out when they resize for reasons that don't affect the document's own size
|
|
43
|
+
* (e.g. a sidebar collapsing and the reading pane reflowing within a flex/grid layout).
|
|
44
|
+
*/
|
|
45
|
+
resizeWatchSelectors?: string[];
|
|
39
46
|
}
|
|
40
47
|
|
|
41
48
|
export const BUILTIN_DECORATION_TYPES = new Set<string>(Object.values(DecorationStyleType));
|
|
@@ -11,6 +11,8 @@ export declare class DecorationController {
|
|
|
11
11
|
private _hoveredDecorations;
|
|
12
12
|
private readonly _config;
|
|
13
13
|
constructor(host: DirectCommsHost, config?: DecorationControllerConfig);
|
|
14
|
+
addDecorationResizeTarget(selector: string): void;
|
|
15
|
+
removeDecorationResizeTarget(selector: string): void;
|
|
14
16
|
supportsDecorationStyle(styleTypeId: string): boolean;
|
|
15
17
|
applyDecorations(decorations: Decoration[], group: string): void;
|
|
16
18
|
registerDecorationObserver(group: string, observer: DecorationObserver): void;
|
package/types/src/styles.d.ts
CHANGED
|
@@ -25,6 +25,12 @@ export interface DecoratorConfig {
|
|
|
25
25
|
* Template-type decoration.
|
|
26
26
|
*/
|
|
27
27
|
decorationTemplates?: Record<string, HTMLDecorationTemplate>;
|
|
28
|
+
/**
|
|
29
|
+
* CSS selectors of additional elements to watch for resize, so decoration overlays are
|
|
30
|
+
* relaid-out when they resize for reasons that don't affect the document's own size
|
|
31
|
+
* (e.g. a sidebar collapsing and the reading pane reflowing within a flex/grid layout).
|
|
32
|
+
*/
|
|
33
|
+
resizeWatchSelectors?: string[];
|
|
28
34
|
}
|
|
29
35
|
export declare const BUILTIN_DECORATION_TYPES: Set<string>;
|
|
30
36
|
/**
|