@pie-players/pie-tool-annotation-toolbar 0.3.74 → 0.3.75
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 +32 -31
- package/dist/tool-annotation-toolbar.js +1478 -1424
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -39,16 +39,14 @@ A text selection toolbar for highlighting and annotating text in PIE assessment
|
|
|
39
39
|
|
|
40
40
|
## Props
|
|
41
41
|
|
|
42
|
-
The strip shows itself when text is selected and hides when the selection is cleared or Escape is pressed.
|
|
42
|
+
The strip shows itself when text is selected and hides when the selection is cleared or Escape is pressed. It records annotations through the toolkit runtime context's `highlightCoordinator` and offers read-aloud when that context carries a `ttsService`; without a highlight coordinator the highlight controls no-op.
|
|
43
43
|
|
|
44
|
-
| Name
|
|
45
|
-
|
|
|
46
|
-
| `enabled`
|
|
47
|
-
| `
|
|
48
|
-
| `ttsService` | — | object | Read-aloud is offered only when present. |
|
|
49
|
-
| `selectionActions` | — | `ToolSelectionAction[]` | Host-supplied actions on the current selection. See below. |
|
|
44
|
+
| Name | Attribute | Type | Notes |
|
|
45
|
+
| ------------------ | --------- | ----------------------- | ------------------------------------------------------------ |
|
|
46
|
+
| `enabled` | `enabled` | boolean | Defaults to `true`; `false` stops it reacting to selections. |
|
|
47
|
+
| `selectionActions` | — | `ToolSelectionAction[]` | Host-supplied actions on the current selection. See below. |
|
|
50
48
|
|
|
51
|
-
Under `<pie-assessment-toolkit>`
|
|
49
|
+
Under `<pie-assessment-toolkit>` both are supplied by the capability's registration, so a host mounting the strip through the toolkit passes nothing.
|
|
52
50
|
|
|
53
51
|
### Selection actions
|
|
54
52
|
|
|
@@ -74,7 +72,7 @@ The toolbar takes its surface and text from the canonical `--pie-background` and
|
|
|
74
72
|
| `--pie-annotation-underline` | `#4221d5` | Underline mark on a light page |
|
|
75
73
|
| `--pie-annotation-underline-dark` | `#9c89ec` | Underline mark on a dark page |
|
|
76
74
|
|
|
77
|
-
The underline tokens are applied by `HighlightCoordinator` in `@pie-players/pie-assessment-toolkit`, which owns the `::highlight()` rules. They exist as a pair because one value cannot serve both surfaces — `#4221d5` is 2.41:1 on black and `#9c89ec` is 2.85:1 on white — and as two separate tokens so overriding one never silently moves the other.
|
|
75
|
+
The underline tokens are applied by `HighlightCoordinator` in `@pie-players/pie-assessment-toolkit`, which owns the `::highlight()` rules. They exist as a pair because one value cannot serve both surfaces — `#4221d5` is 2.41:1 on black and `#9c89ec` is 2.85:1 on white — and as two separate tokens so overriding one never silently moves the other. Under `data-theme="light"` and `data-theme="dark"` the underline reads only its own token, because a theme accent is chosen against one background and is illegible on the other. Under any other `data-theme` value, such as a host or DaisyUI palette, it reads `--pie-annotation-underline` and falls back to that palette's `--pie-primary`.
|
|
78
76
|
|
|
79
77
|
Which of the pair applies is decided by `[data-theme]`, which reports what the **page** declares — not which color scheme is active. A host that declares itself light while running a dark scheme would otherwise pin the light value over a dark background, so the accessibility palettes hand both states their own accent (below).
|
|
80
78
|
|
|
@@ -92,7 +90,7 @@ Hosts may override any of the three, but must keep 3:1 against both the toolbar
|
|
|
92
90
|
|
|
93
91
|
The annotation toolbar integrates with PIE's shared highlight infrastructure:
|
|
94
92
|
|
|
95
|
-
- **HighlightCoordinator**:
|
|
93
|
+
- **HighlightCoordinator**: One per `ToolkitCoordinator`, shared by TTS and annotation highlights
|
|
96
94
|
- **RangeSerializer**: Serializes/deserializes DOM ranges for persistence
|
|
97
95
|
- **CSS Custom Highlight API**: Modern browser API for non-invasive highlighting
|
|
98
96
|
|
|
@@ -108,27 +106,31 @@ For unsupported browsers, the component gracefully degrades (no highlights shown
|
|
|
108
106
|
|
|
109
107
|
## Annotation Persistence
|
|
110
108
|
|
|
111
|
-
Annotations are
|
|
109
|
+
Annotations are saved to `sessionStorage` after each change and restored two seconds after the toolbar mounts. The key is `pie-annotations:<id>`, where `<id>` is the enclosing item's canonical item id, else its item id, else `global`, so each item keeps its own annotations across navigation within the browser session.
|
|
112
110
|
|
|
113
|
-
Storage format:
|
|
111
|
+
Storage format, an array with one record per annotation:
|
|
114
112
|
|
|
115
113
|
```typescript
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
114
|
+
[
|
|
115
|
+
{
|
|
116
|
+
id: "annotation-0",
|
|
117
|
+
color: "yellow",
|
|
118
|
+
timestamp: 1234567890,
|
|
119
|
+
startContainer: "div:nth-of-type(2) > p",
|
|
119
120
|
startOffset: 10,
|
|
120
|
-
endContainer:
|
|
121
|
+
endContainer: "div:nth-of-type(2) > p",
|
|
121
122
|
endOffset: 20,
|
|
122
123
|
text: "highlighted text"
|
|
123
124
|
}
|
|
124
|
-
|
|
125
|
+
]
|
|
125
126
|
```
|
|
126
127
|
|
|
127
|
-
|
|
128
|
+
`startContainer` and `endContainer` are selector paths relative to the scope root, with ` >>> ` marking a step into a shadow root.
|
|
129
|
+
|
|
130
|
+
Stored annotations are removed when:
|
|
128
131
|
|
|
129
|
-
-
|
|
130
|
-
-
|
|
131
|
-
- sessionStorage is cleared
|
|
132
|
+
- The user presses "Clear all", which removes that item's key
|
|
133
|
+
- `sessionStorage` is cleared, for example when the tab closes
|
|
132
134
|
|
|
133
135
|
## Text-to-Speech Integration
|
|
134
136
|
|
|
@@ -144,26 +146,25 @@ The annotation toolbar includes a "Read" button that uses the TTS service to rea
|
|
|
144
146
|
|
|
145
147
|
### Technical Implementation
|
|
146
148
|
|
|
147
|
-
The toolbar
|
|
149
|
+
The toolbar passes the selected range to `ttsService.speak()`, which highlights
|
|
150
|
+
from the selection's offset within its content root:
|
|
148
151
|
|
|
149
152
|
```typescript
|
|
150
153
|
ttsSpeaking = true;
|
|
151
154
|
try {
|
|
152
|
-
// speakRange() calculates text offset for accurate highlighting.
|
|
153
155
|
// contentRoot: the item or passage scope element, else the document element.
|
|
154
|
-
|
|
156
|
+
// language: the toolkit's `content-language`; `speak` lets a `lang` in
|
|
157
|
+
// the content win over it.
|
|
158
|
+
// catalogContext: from the shell holding the selection.
|
|
159
|
+
await ttsService.speak(selectedRange, { contentRoot, language, catalogContext });
|
|
155
160
|
} finally {
|
|
156
161
|
ttsSpeaking = false;
|
|
157
162
|
}
|
|
158
163
|
```
|
|
159
164
|
|
|
160
|
-
`
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
- User selects text in the middle of a paragraph
|
|
165
|
-
- `speak(text)` would highlight from the beginning of the container (wrong)
|
|
166
|
-
- `speakRange(range)` highlights the exact selected text (correct)
|
|
165
|
+
`speak` resolves when reading ends and rejects on a playback error. A
|
|
166
|
+
`data-catalog-idref` node the selection holds whole reads its spoken card, as
|
|
167
|
+
under tts-inline; part of one reads as the selected text.
|
|
167
168
|
|
|
168
169
|
### UX Details
|
|
169
170
|
|