@pie-players/pie-tool-magnifier 0.1.8 → 1.0.0-beta.2
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 +101 -124
- package/custom-elements.json +83 -0
- package/dist/index.d.ts +1 -8
- package/dist/tool-magnifier.js +3102 -2869
- package/package.json +34 -30
- package/Magnifier.svelte +0 -340
- package/dist/index.d.ts.map +0 -1
- package/dist/tool-magnifier.js.map +0 -1
- package/index.ts +0 -8
- package/tool-magnifier.svelte +0 -140
package/README.md
CHANGED
|
@@ -1,135 +1,112 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @pie-players/pie-tool-magnifier
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Magnifying lens tool for PIE assessment players.
|
|
4
4
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
- **Multiple Zoom Levels**: 1.5x, 2x, and 3x magnification
|
|
8
|
-
- **Draggable**: Can be moved anywhere on the screen using mouse or keyboard
|
|
9
|
-
- **Content Cloning**: Creates a live clone of page content with accurate scroll positions
|
|
10
|
-
- **Keyboard Accessible**: Full keyboard navigation support
|
|
11
|
-
- **Zero DOM Mutation**: Does not modify the original content
|
|
12
|
-
|
|
13
|
-
## Architecture
|
|
14
|
-
|
|
15
|
-
This tool follows PIE's custom element (Web Component) architecture:
|
|
16
|
-
|
|
17
|
-
- Built with Svelte 5
|
|
18
|
-
- Registered as a custom element `<pie-tool-magnifier>`
|
|
19
|
-
- Integrates with PIE's ToolCoordinator for z-index management
|
|
20
|
-
- Uses Moveable.js for drag functionality
|
|
21
|
-
|
|
22
|
-
## Comparison to Production Implementations
|
|
23
|
-
|
|
24
|
-
### Similarities
|
|
25
|
-
|
|
26
|
-
- **Visual Design**: Same zoom levels (1.5x, 2x, 3x), button layout, and frame dimensions
|
|
27
|
-
- **Core Functionality**: DOM cloning, scroll position preservation, mouse tracking
|
|
28
|
-
- **UX Patterns**: Frozen view on mouse leave, continuous update on drag
|
|
29
|
-
|
|
30
|
-
### Differences
|
|
5
|
+
## Overview
|
|
31
6
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
7
|
+
A movable, resizable lens that shows the content under it enlarged. The lens is a
|
|
8
|
+
window with a bar on top: zoom out, the current zoom, zoom in, and close. Its
|
|
9
|
+
viewport shows a scaled copy of the page around the point beneath the lens, so
|
|
10
|
+
moving the lens moves what it magnifies. The shown point travels the lens's block
|
|
11
|
+
in step with the lens, so at the block's edges the view reaches the edge content
|
|
12
|
+
the lens stops short of.
|
|
38
13
|
|
|
39
|
-
|
|
14
|
+
The tool serves the AfA PNP 3.0 `magnification` support. Its tool id is that term,
|
|
15
|
+
`magnification`.
|
|
40
16
|
|
|
41
|
-
|
|
42
|
-
2. **Modern Svelte 5**: Uses runes (`$state`, `$derived`, `$effect`) for reactive state
|
|
43
|
-
3. **Cleaner Separation**: Tool coordination is handled by external coordinator, not internal store
|
|
44
|
-
4. **Accessibility First**: ARIA labels, keyboard navigation, screen reader announcements
|
|
17
|
+
## Custom Element
|
|
45
18
|
|
|
46
|
-
|
|
19
|
+
Tag: `pie-tool-magnifier`
|
|
47
20
|
|
|
48
|
-
|
|
21
|
+
| Attribute | Type | Default | Description |
|
|
22
|
+
|---|---|---|---|
|
|
23
|
+
| `visible` | `boolean` | `false` | Controls visibility |
|
|
24
|
+
| `tool-id` | `string` | `'magnification'` | Identifier used by the ToolCoordinator |
|
|
25
|
+
| `zoom` | `number` | `2` | Starting magnification, 2 meaning twice the size. Clamped to 1.25–8; a value of 1 or less, or none, is the default |
|
|
49
26
|
|
|
50
|
-
|
|
51
|
-
<pie-tool-magnifier
|
|
52
|
-
visible="true"
|
|
53
|
-
tool-id="magnifier"
|
|
54
|
-
magnify-root-selector="body"
|
|
55
|
-
></pie-tool-magnifier>
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
### With Coordinator
|
|
59
|
-
|
|
60
|
-
```typescript
|
|
61
|
-
import { ToolMagnifier } from '@pie-api-aws/pieoneer-tool-magnifier';
|
|
62
|
-
import { ToolCoordinator } from '$lib/assessment-toolkit';
|
|
63
|
-
|
|
64
|
-
const coordinator = new ToolCoordinator();
|
|
27
|
+
## Features
|
|
65
28
|
|
|
66
|
-
|
|
29
|
+
- Zoom steps of 1.5×, 2×, 2.5×, 3×, 4×, 5×, 6× and 8× from the bar's buttons or
|
|
30
|
+
the keyboard
|
|
31
|
+
- Drag the bar or the viewport to move the lens; drag the corner grip to resize it
|
|
32
|
+
around its centre
|
|
33
|
+
- Full keyboard support:
|
|
34
|
+
- On the lens: arrow keys to move, `+`/`-` to zoom
|
|
35
|
+
- On the resize grip: arrow keys change the width and height
|
|
36
|
+
- Anywhere on the page: `Escape` closes the lens, unless something else there
|
|
37
|
+
handles the key. Pressed on the lens it also returns focus to where it was
|
|
38
|
+
before the lens opened
|
|
39
|
+
- Keyboard focus on the page beneath the lens shows as a ring in the magnified view
|
|
40
|
+
- Tap controls beside the focused lens move it and change its width and height
|
|
41
|
+
without a drag (WCAG 2.5.7), and every control meets the 24×24 minimum target
|
|
42
|
+
size (WCAG 2.5.8). On a narrow pane they wrap onto a second row
|
|
43
|
+
- Screen reader announcements for zoom, size and position changes
|
|
44
|
+
- Stays inside its containing block, and opens over the part of it on screen
|
|
45
|
+
- Connects to `AssessmentToolkitRuntimeContext` for ToolCoordinator integration
|
|
46
|
+
|
|
47
|
+
## Profile and policy
|
|
48
|
+
|
|
49
|
+
A personal needs profile grants the tool by listing `magnification` in `supports`.
|
|
50
|
+
The starting zoom is the `zoom` tool parameter, which the registration in
|
|
51
|
+
`@pie-players/pie-default-tool-loaders` reads through the toolbar and sets as the
|
|
52
|
+
`zoom` attribute. `createPersonalNeedsProfileFromAfa` maps an AfA record's
|
|
53
|
+
`magnification` `zoom-amount` to it, taking the `text` amount when the record sets
|
|
54
|
+
text and non-text apart:
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
createPersonalNeedsProfileFromAfa({ magnification: { "all-content": { "zoom-amount": 2.5 } } });
|
|
58
|
+
// { supports: ["magnification"], toolParameters: { magnification: { zoom: 2.5 } } }
|
|
67
59
|
```
|
|
68
60
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
-
|
|
105
|
-
|
|
106
|
-
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
The
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
- Chrome/Edge 90+
|
|
123
|
-
- Firefox 90+
|
|
124
|
-
- Safari 14+
|
|
125
|
-
|
|
126
|
-
Requires:
|
|
127
|
-
- Custom Elements (Web Components)
|
|
128
|
-
- CSS Transform
|
|
129
|
-
- RequestAnimationFrame
|
|
130
|
-
- DOMMatrix
|
|
131
|
-
|
|
132
|
-
## Related Documentation
|
|
133
|
-
|
|
134
|
-
- [PIE Tools Architecture](../../docs/tools-high-level-architecture.md)
|
|
135
|
-
- [ToolCoordinator](../../tools/tool-coordinator.ts)
|
|
61
|
+
The learner changes the zoom from there; a new host value replaces theirs.
|
|
62
|
+
|
|
63
|
+
The packaged registration places the tool at section level by default and supports
|
|
64
|
+
section, passage, rubric and item placement. Placement puts it on a toolbar; a
|
|
65
|
+
profile's `prohibitedSupports`, a district block or a test-administration override
|
|
66
|
+
withdraws it. It is not universal: magnification is a granted accommodation, so
|
|
67
|
+
`createUniversalPersonalNeedsProfile()` leaves it out.
|
|
68
|
+
|
|
69
|
+
## How the lens draws
|
|
70
|
+
|
|
71
|
+
CSS cannot paint one part of a document inside another, so the lens shows a copy.
|
|
72
|
+
The live document is serialized without scripts or event-handler attributes into a
|
|
73
|
+
sandboxed `srcdoc` iframe: open shadow roots become declarative shadow roots, every
|
|
74
|
+
style sheet is written out from its CSSOM, and form state, scroll offsets, canvas
|
|
75
|
+
pixels and video frames are copied across after the copy loads. The lens scales and
|
|
76
|
+
offsets the iframe with a transform, which follows its position, size, the zoom and
|
|
77
|
+
page scrolling every frame.
|
|
78
|
+
|
|
79
|
+
A mutation observer marks the copy stale, and it is re-rendered at most every
|
|
80
|
+
200 ms, or every four times the main-thread time the last render took when that is
|
|
81
|
+
longer, so copying a large page keeps to about a quarter of the main thread. Two
|
|
82
|
+
iframes alternate, so the new copy paints in the hidden one and swaps in when it has
|
|
83
|
+
loaded. Every lens is left out of the copy.
|
|
84
|
+
|
|
85
|
+
Highlights painted through the CSS Custom Highlight API, text-to-speech word and
|
|
86
|
+
sentence highlighting and annotation-toolbar highlights among them, are mapped onto
|
|
87
|
+
the copy's nodes and registered in its frame under the same names, where the copy's
|
|
88
|
+
own `::highlight()` rules paint them. They follow the page every frame, without
|
|
89
|
+
waiting for a re-render.
|
|
90
|
+
|
|
91
|
+
The copy is inert: it takes no input and runs no script, so the lens is a viewing
|
|
92
|
+
aid and the learner answers on the page beneath it.
|
|
93
|
+
|
|
94
|
+
## Limitations
|
|
95
|
+
|
|
96
|
+
- Closed shadow roots, cross-origin iframes and WebGL canvases without a preserved
|
|
97
|
+
drawing buffer appear empty.
|
|
98
|
+
- A highlight over markup the HTML parser restructures, such as a block element a
|
|
99
|
+
script placed inside a `<p>`, does not show.
|
|
100
|
+
- Top-layer content is not carried: a modal dialog shows as a non-modal one in
|
|
101
|
+
place, and an open popover does not show.
|
|
102
|
+
- A custom element that renders its content only from script, with no open shadow
|
|
103
|
+
root or light-DOM children, appears as it does before it upgrades.
|
|
104
|
+
- Changes to the page reach the lens a render or two late: well under a second on a
|
|
105
|
+
typical section, and up to about five seconds on a page of 40,000 elements, whose
|
|
106
|
+
copy takes over a second to render.
|
|
107
|
+
|
|
108
|
+
## Theming
|
|
109
|
+
|
|
110
|
+
The lens reads canonical theme tokens and defines none of its own: `--pie-primary`
|
|
111
|
+
for the border, `--pie-background` and `--pie-text` for the lens, and
|
|
112
|
+
`--pie-secondary-background` and `--pie-border` for the bar.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": "2.1.0",
|
|
3
|
+
"modules": [
|
|
4
|
+
{
|
|
5
|
+
"kind": "javascript-module",
|
|
6
|
+
"path": "dist/tool-magnifier.js",
|
|
7
|
+
"declarations": [
|
|
8
|
+
{
|
|
9
|
+
"kind": "class",
|
|
10
|
+
"description": "Magnifying lens: a movable, resizable window that shows the content under it enlarged, with controls on its bar to change the zoom and close. The host shows it with `visible` and sets the starting magnification with `zoom` (the AfA PNP `magnification` amount; 2 when absent). Inside a toolkit runtime context it registers `tool-id` with the tool coordinator on the tool layer, and the close control hides it there. Arrow keys move it, `+` and `-` change the zoom, and Escape closes it, wherever on the page it is pressed.",
|
|
11
|
+
"name": "ToolMagnifier",
|
|
12
|
+
"tagName": "pie-tool-magnifier",
|
|
13
|
+
"customElement": true,
|
|
14
|
+
"members": [
|
|
15
|
+
{
|
|
16
|
+
"kind": "field",
|
|
17
|
+
"name": "visible",
|
|
18
|
+
"type": {
|
|
19
|
+
"text": "boolean"
|
|
20
|
+
},
|
|
21
|
+
"default": "false",
|
|
22
|
+
"attribute": "visible"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"kind": "field",
|
|
26
|
+
"name": "toolId",
|
|
27
|
+
"type": {
|
|
28
|
+
"text": "string"
|
|
29
|
+
},
|
|
30
|
+
"default": "'magnification'",
|
|
31
|
+
"attribute": "tool-id"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"kind": "field",
|
|
35
|
+
"name": "zoom",
|
|
36
|
+
"type": {
|
|
37
|
+
"text": "number"
|
|
38
|
+
},
|
|
39
|
+
"attribute": "zoom"
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
"attributes": [
|
|
43
|
+
{
|
|
44
|
+
"name": "visible",
|
|
45
|
+
"type": {
|
|
46
|
+
"text": "boolean"
|
|
47
|
+
},
|
|
48
|
+
"default": "false",
|
|
49
|
+
"fieldName": "visible"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"name": "tool-id",
|
|
53
|
+
"type": {
|
|
54
|
+
"text": "string"
|
|
55
|
+
},
|
|
56
|
+
"default": "'magnification'",
|
|
57
|
+
"fieldName": "toolId"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"name": "zoom",
|
|
61
|
+
"type": {
|
|
62
|
+
"text": "number"
|
|
63
|
+
},
|
|
64
|
+
"fieldName": "zoom"
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
"x-pie": {
|
|
68
|
+
"shadow": "open"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
],
|
|
72
|
+
"exports": [
|
|
73
|
+
{
|
|
74
|
+
"kind": "custom-element-definition",
|
|
75
|
+
"name": "pie-tool-magnifier",
|
|
76
|
+
"declaration": {
|
|
77
|
+
"name": "ToolMagnifier"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* pie-tool-magnifier - PIE Assessment Tool
|
|
3
|
-
*
|
|
4
|
-
* This package exports a web component built from Svelte.
|
|
5
|
-
* Import the built version for CDN usage, or the .svelte source for Svelte projects.
|
|
6
|
-
*/
|
|
7
|
-
export {};
|
|
8
|
-
//# sourceMappingURL=index.d.ts.map
|
|
1
|
+
export {}
|