@pie-players/pie-players-shared 0.3.73 → 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 +30 -2
- package/dist/components/vendor/nds/README.md +7 -5
- package/dist/config/profile.d.ts +0 -2
- package/dist/config/profile.js +2 -8
- package/dist/i18n/index.d.ts +2 -3
- package/dist/i18n/index.js +2 -3
- package/dist/i18n/messages/en-US.d.ts +11 -24
- package/dist/i18n/messages/en-US.js +13 -26
- package/dist/i18n/messages/nl-NL.d.ts +7 -24
- package/dist/i18n/messages/nl-NL.js +9 -26
- package/dist/i18n/provider.d.ts +4 -5
- package/dist/i18n/provider.js +4 -5
- package/dist/i18n/types.d.ts +4 -5
- package/dist/index.d.ts +4 -2
- package/dist/index.js +3 -1
- package/dist/instrumentation/index.d.ts +5 -4
- package/dist/instrumentation/index.js +5 -4
- package/dist/instrumentation/new-relic-agent.d.ts +20 -0
- package/dist/instrumentation/new-relic-agent.js +24 -0
- package/dist/instrumentation/providers/BaseInstrumentationProvider.d.ts +5 -4
- package/dist/instrumentation/providers/NewRelicInstrumentationProvider.d.ts +7 -7
- package/dist/instrumentation/providers/NewRelicInstrumentationProvider.js +21 -32
- package/dist/instrumentation/types.d.ts +7 -3
- package/dist/loader-config.d.ts +16 -6
- package/dist/loaders/controller-loading.d.ts +14 -0
- package/dist/loaders/controller-loading.js +12 -0
- package/dist/loaders/defaults.d.ts +10 -0
- package/dist/loaders/defaults.js +10 -0
- package/dist/loaders/element-loader.d.ts +20 -8
- package/dist/loaders/element-loader.js +102 -36
- package/dist/loaders/element-package-policy.d.ts +2 -0
- package/dist/loaders/element-package-policy.js +2 -1
- package/dist/loaders/esm-adapter.d.ts +29 -0
- package/dist/loaders/esm-adapter.js +635 -102
- package/dist/loaders/iife-adapter.d.ts +0 -5
- package/dist/loaders/iife-adapter.js +3 -9
- package/dist/loaders/index.d.ts +12 -3
- package/dist/loaders/index.js +9 -3
- package/dist/loaders/mathjax-events.d.ts +22 -0
- package/dist/loaders/mathjax-events.js +65 -0
- package/dist/loaders/module-shim.d.ts +12 -0
- package/dist/loaders/module-shim.js +12 -0
- package/dist/loaders/preloaded-alignment.d.ts +24 -0
- package/dist/loaders/preloaded-alignment.js +57 -0
- package/dist/loaders/preloaded-authored-tags.d.ts +26 -0
- package/dist/loaders/preloaded-authored-tags.js +69 -0
- package/dist/loaders/preloaded-registration.d.ts +72 -0
- package/dist/loaders/preloaded-registration.js +141 -0
- package/dist/media/index.d.ts +69 -0
- package/dist/media/index.js +194 -0
- package/dist/pie/authoring.d.ts +1 -1
- package/dist/pie/authoring.js +25 -18
- package/dist/pie/element-announcements.d.ts +39 -0
- package/dist/pie/element-announcements.js +67 -0
- package/dist/pie/element-observer.d.ts +3 -1
- package/dist/pie/element-observer.js +1 -0
- package/dist/pie/elements-rendered.d.ts +25 -0
- package/dist/pie/elements-rendered.js +96 -0
- package/dist/pie/index.d.ts +8 -10
- package/dist/pie/index.js +9 -10
- package/dist/pie/initialization.js +13 -22
- package/dist/pie/initialize-element.d.ts +3 -0
- package/dist/pie/initialize-element.js +3 -4
- package/dist/pie/instrumentation-event-bridge.js +23 -1
- package/dist/pie/instrumentation-event-map.js +11 -25
- package/dist/pie/instrumentation-provider-resolution.d.ts +2 -1
- package/dist/pie/instrumentation-provider-resolution.js +0 -1
- package/dist/pie/item-controller.js +4 -0
- package/dist/pie/item-session-contract.d.ts +8 -0
- package/dist/pie/item-session-contract.js +30 -9
- package/dist/pie/logger.d.ts +6 -0
- package/dist/pie/logger.js +10 -0
- package/dist/pie/markup-math.d.ts +20 -0
- package/dist/pie/markup-math.js +118 -0
- package/dist/pie/math-assets.d.ts +48 -0
- package/dist/pie/math-assets.js +81 -0
- package/dist/pie/math-rendering.d.ts +10 -21
- package/dist/pie/math-rendering.js +50 -35
- package/dist/pie/registry.d.ts +13 -1
- package/dist/pie/registry.js +39 -1
- package/dist/pie/resource-monitor.d.ts +6 -33
- package/dist/pie/resource-monitor.js +14 -213
- package/dist/pie/scoring.d.ts +12 -8
- package/dist/pie/scoring.js +21 -24
- package/dist/pie/session-commit.d.ts +16 -0
- package/dist/pie/session-commit.js +34 -6
- package/dist/pie/session-snapshot.d.ts +80 -0
- package/dist/pie/session-snapshot.js +166 -0
- package/dist/pie/stages.d.ts +10 -47
- package/dist/pie/stages.js +10 -47
- package/dist/pie/tag-names.d.ts +1 -0
- package/dist/pie/tag-names.js +1 -0
- package/dist/pie/types.d.ts +4 -5
- package/dist/pie/types.js +1 -0
- package/dist/pie/updates.d.ts +2 -2
- package/dist/pie/updates.js +33 -15
- package/dist/pie/versioned-tag.d.ts +4 -0
- package/dist/pie/versioned-tag.js +4 -0
- package/dist/security/index.d.ts +2 -3
- package/dist/security/index.js +2 -3
- package/dist/security/sanitize-item-markup.d.ts +4 -2
- package/dist/security/sanitize-item-markup.js +48 -6
- package/dist/security/sanitize-svg-icon.d.ts +0 -2
- package/dist/security/sanitize-svg-icon.js +0 -5
- package/dist/security/wrap-overwide-images.js +19 -0
- package/dist/security/wrap-overwide.d.ts +13 -0
- package/dist/security/wrap-overwide.js +63 -3
- package/dist/timed-media/policy.js +5 -16
- package/dist/types/index.d.ts +67 -423
- package/dist/types/index.js +0 -68
- package/dist/ui/attribute-coercion.d.ts +12 -0
- package/dist/ui/attribute-coercion.js +33 -0
- package/dist/ui/content-styles.d.ts +18 -16
- package/dist/ui/content-styles.js +67 -36
- package/dist/ui/overlay-containment.d.ts +31 -0
- package/dist/ui/overlay-containment.js +63 -0
- package/dist/ui/overlay-placement.d.ts +110 -0
- package/dist/ui/overlay-placement.js +222 -0
- package/dist/ui/pointer-gesture.d.ts +32 -0
- package/dist/ui/pointer-gesture.js +56 -0
- package/dist/ui/pointer-rotate.d.ts +29 -0
- package/dist/ui/pointer-rotate.js +39 -0
- package/package.json +23 -18
- package/dist/pie/component-context.d.ts +0 -21
- package/dist/pie/component-context.js +0 -29
- package/dist/pie/player-initializer.d.ts +0 -54
- package/dist/pie/player-initializer.js +0 -122
- package/dist/pie/stage-tracker.d.ts +0 -50
- package/dist/pie/stage-tracker.js +0 -105
- package/dist/security/wrap-model-rich-content.d.ts +0 -1
- package/dist/security/wrap-model-rich-content.js +0 -40
- package/dist/server/npm-auth-env.d.ts +0 -13
- package/dist/server/npm-auth-env.js +0 -64
- package/dist/server/npm-registry.d.ts +0 -7
- package/dist/server/npm-registry.js +0 -59
- package/dist/ui/debug-panel-persistence.d.ts +0 -17
- package/dist/ui/debug-panel-persistence.js +0 -37
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Placement of a tool overlay the learner moves and turns: the ruler and the
|
|
3
|
+
* protractor. One controller holds where the tool sits and is the only writer of
|
|
4
|
+
* its `style.transform`, so a drag, an arrow key and a tap control always agree
|
|
5
|
+
* about where the tool is.
|
|
6
|
+
*/
|
|
7
|
+
import { clampOffsetOverlappingBlock, resolveContainingBlockRect, rotatedExtent, rotationCentreShift, uprightDockCentre, } from "./overlay-containment.js";
|
|
8
|
+
import { createPointerDragController } from "./pointer-drag.js";
|
|
9
|
+
import { createPointerGesture } from "./pointer-gesture.js";
|
|
10
|
+
import { createPointerRotateController } from "./pointer-rotate.js";
|
|
11
|
+
/** Pixels an arrow key or move button shifts the tool. */
|
|
12
|
+
export const OVERLAY_PLACEMENT_MOVE_STEP = 10;
|
|
13
|
+
/** Degrees Shift+arrow turns the tool. */
|
|
14
|
+
export const OVERLAY_PLACEMENT_ROTATE_STEP = 5;
|
|
15
|
+
/** Degrees Page Up/Down turns the tool. */
|
|
16
|
+
export const OVERLAY_PLACEMENT_FINE_ROTATE_STEP = 1;
|
|
17
|
+
/** Each move, with its tap control's glyph and label and its announcement. */
|
|
18
|
+
export const OVERLAY_PLACEMENT_NUDGES = {
|
|
19
|
+
left: {
|
|
20
|
+
dx: -1,
|
|
21
|
+
dy: 0,
|
|
22
|
+
glyph: "←",
|
|
23
|
+
labelKey: "toolkit.window.moveLeftA11y",
|
|
24
|
+
announceKey: "toolkit.announce.movedLeft",
|
|
25
|
+
},
|
|
26
|
+
up: {
|
|
27
|
+
dx: 0,
|
|
28
|
+
dy: -1,
|
|
29
|
+
glyph: "↑",
|
|
30
|
+
labelKey: "toolkit.window.moveUpA11y",
|
|
31
|
+
announceKey: "toolkit.announce.movedUp",
|
|
32
|
+
},
|
|
33
|
+
down: {
|
|
34
|
+
dx: 0,
|
|
35
|
+
dy: 1,
|
|
36
|
+
glyph: "↓",
|
|
37
|
+
labelKey: "toolkit.window.moveDownA11y",
|
|
38
|
+
announceKey: "toolkit.announce.movedDown",
|
|
39
|
+
},
|
|
40
|
+
right: {
|
|
41
|
+
dx: 1,
|
|
42
|
+
dy: 0,
|
|
43
|
+
glyph: "→",
|
|
44
|
+
labelKey: "toolkit.window.moveRightA11y",
|
|
45
|
+
announceKey: "toolkit.announce.movedRight",
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
/** The tap controls' rotations, the keyboard's two steps each way. */
|
|
49
|
+
export const OVERLAY_PLACEMENT_ROTATIONS = [
|
|
50
|
+
-OVERLAY_PLACEMENT_ROTATE_STEP,
|
|
51
|
+
-OVERLAY_PLACEMENT_FINE_ROTATE_STEP,
|
|
52
|
+
OVERLAY_PLACEMENT_FINE_ROTATE_STEP,
|
|
53
|
+
OVERLAY_PLACEMENT_ROTATE_STEP,
|
|
54
|
+
];
|
|
55
|
+
const ARROW_KEYS = {
|
|
56
|
+
ArrowLeft: "left",
|
|
57
|
+
ArrowUp: "up",
|
|
58
|
+
ArrowDown: "down",
|
|
59
|
+
ArrowRight: "right",
|
|
60
|
+
};
|
|
61
|
+
/** Pixels of the tool kept inside its containing block on each axis. */
|
|
62
|
+
const MIN_VISIBLE = 100;
|
|
63
|
+
/** Space between the tool's bottom edge and its tap controls. */
|
|
64
|
+
const CONTROLS_GAP = 8;
|
|
65
|
+
export function createOverlayPlacement(options) {
|
|
66
|
+
let placement = { x: 0, y: 0, rotation: 0 };
|
|
67
|
+
const sizeOf = (element) => ({
|
|
68
|
+
width: element.offsetWidth,
|
|
69
|
+
height: element.offsetHeight,
|
|
70
|
+
});
|
|
71
|
+
function dockControls(element) {
|
|
72
|
+
const controls = options.getControls();
|
|
73
|
+
if (!controls)
|
|
74
|
+
return;
|
|
75
|
+
// Counter-rotated, so each arrow points the way its button moves the tool.
|
|
76
|
+
const centre = uprightDockCentre(sizeOf(element), sizeOf(controls), placement.rotation, CONTROLS_GAP);
|
|
77
|
+
controls.style.transform = `translate(${centre.x}px, ${centre.y}px) translate(-50%, -50%) rotate(${-placement.rotation}deg)`;
|
|
78
|
+
}
|
|
79
|
+
function apply(next) {
|
|
80
|
+
const element = options.getElement();
|
|
81
|
+
if (!element)
|
|
82
|
+
return;
|
|
83
|
+
const block = resolveContainingBlockRect(element);
|
|
84
|
+
const size = sizeOf(element);
|
|
85
|
+
// A tool turning off its centre has its turned extent centred off its
|
|
86
|
+
// translate offset by this shift; the clamp bounds that centre.
|
|
87
|
+
const shift = options.pivot
|
|
88
|
+
? rotationCentreShift(size, options.pivot(size), next.rotation)
|
|
89
|
+
: { x: 0, y: 0 };
|
|
90
|
+
const centre = { x: next.x + shift.x, y: next.y + shift.y };
|
|
91
|
+
const bounded = block
|
|
92
|
+
? clampOffsetOverlappingBlock(centre, rotatedExtent(size, next.rotation), block, MIN_VISIBLE)
|
|
93
|
+
: centre;
|
|
94
|
+
placement = {
|
|
95
|
+
x: bounded.x - shift.x,
|
|
96
|
+
y: bounded.y - shift.y,
|
|
97
|
+
rotation: next.rotation,
|
|
98
|
+
};
|
|
99
|
+
element.style.transform = `translate(-50%, -50%) translate(${placement.x}px, ${placement.y}px) rotate(${placement.rotation}deg)`;
|
|
100
|
+
dockControls(element);
|
|
101
|
+
}
|
|
102
|
+
const dragController = createPointerDragController({
|
|
103
|
+
getPosition: () => ({ x: placement.x, y: placement.y }),
|
|
104
|
+
setPosition: (next) => apply({ ...placement, ...next }),
|
|
105
|
+
});
|
|
106
|
+
const rotateController = createPointerRotateController({
|
|
107
|
+
getRotation: () => placement.rotation,
|
|
108
|
+
setRotation: (rotation) => apply({ ...placement, rotation }),
|
|
109
|
+
});
|
|
110
|
+
const gesture = createPointerGesture({
|
|
111
|
+
onMove: (event) => {
|
|
112
|
+
dragController.handlePointerMove(event);
|
|
113
|
+
rotateController.handlePointerMove(event);
|
|
114
|
+
},
|
|
115
|
+
onEnd: () => {
|
|
116
|
+
dragController.endDragging();
|
|
117
|
+
rotateController.endRotating();
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
/**
|
|
121
|
+
* Claims a press for a drag or turn. The claim's `preventDefault` suppresses
|
|
122
|
+
* the press's default focus, so focus the tool here: the arrow-key
|
|
123
|
+
* alternatives act on it.
|
|
124
|
+
*/
|
|
125
|
+
function claim(event, element, target) {
|
|
126
|
+
if (!gesture.begin(event, target))
|
|
127
|
+
return false;
|
|
128
|
+
element.focus({ preventScroll: true });
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
const screenPivot = () => {
|
|
132
|
+
if (options.getScreenPivot)
|
|
133
|
+
return options.getScreenPivot();
|
|
134
|
+
const rect = options.getElement()?.getBoundingClientRect();
|
|
135
|
+
return (rect && { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 });
|
|
136
|
+
};
|
|
137
|
+
function nudge(direction) {
|
|
138
|
+
const { dx, dy, announceKey } = OVERLAY_PLACEMENT_NUDGES[direction];
|
|
139
|
+
apply({
|
|
140
|
+
x: placement.x + dx * OVERLAY_PLACEMENT_MOVE_STEP,
|
|
141
|
+
y: placement.y + dy * OVERLAY_PLACEMENT_MOVE_STEP,
|
|
142
|
+
rotation: placement.rotation,
|
|
143
|
+
});
|
|
144
|
+
options.announce(announceKey, {
|
|
145
|
+
position: Math.round(dx ? placement.x : placement.y),
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
function rotateBy(degrees) {
|
|
149
|
+
const rotation = (((Math.round(placement.rotation) + degrees) % 360) + 360) % 360;
|
|
150
|
+
apply({ ...placement, rotation });
|
|
151
|
+
options.announce("toolkit.announce.rotatedTo", { degrees: rotation });
|
|
152
|
+
}
|
|
153
|
+
const reapply = () => apply(placement);
|
|
154
|
+
return {
|
|
155
|
+
get placement() {
|
|
156
|
+
return placement;
|
|
157
|
+
},
|
|
158
|
+
apply,
|
|
159
|
+
show() {
|
|
160
|
+
const element = options.getElement();
|
|
161
|
+
if (!element)
|
|
162
|
+
return;
|
|
163
|
+
options.bringToFront?.(element);
|
|
164
|
+
reapply();
|
|
165
|
+
},
|
|
166
|
+
reset() {
|
|
167
|
+
gesture.release();
|
|
168
|
+
placement = { x: 0, y: 0, rotation: 0 };
|
|
169
|
+
},
|
|
170
|
+
startDrag(event) {
|
|
171
|
+
const element = options.getElement();
|
|
172
|
+
if (!element)
|
|
173
|
+
return;
|
|
174
|
+
options.bringToFront?.(element);
|
|
175
|
+
if (!claim(event, element, element))
|
|
176
|
+
return;
|
|
177
|
+
dragController.startDragging(event, element);
|
|
178
|
+
},
|
|
179
|
+
startRotate(event, handle) {
|
|
180
|
+
event.stopPropagation();
|
|
181
|
+
const element = options.getElement();
|
|
182
|
+
const pivot = screenPivot();
|
|
183
|
+
if (!element || !pivot)
|
|
184
|
+
return;
|
|
185
|
+
options.bringToFront?.(element);
|
|
186
|
+
if (!claim(event, element, handle))
|
|
187
|
+
return;
|
|
188
|
+
rotateController.startRotating(event, handle, pivot);
|
|
189
|
+
},
|
|
190
|
+
nudge,
|
|
191
|
+
rotateBy,
|
|
192
|
+
handleKeyDown(event) {
|
|
193
|
+
const direction = ARROW_KEYS[event.key];
|
|
194
|
+
if (direction && event.shiftKey) {
|
|
195
|
+
rotateBy(direction === "up" || direction === "left"
|
|
196
|
+
? -OVERLAY_PLACEMENT_ROTATE_STEP
|
|
197
|
+
: OVERLAY_PLACEMENT_ROTATE_STEP);
|
|
198
|
+
}
|
|
199
|
+
else if (direction) {
|
|
200
|
+
nudge(direction);
|
|
201
|
+
}
|
|
202
|
+
else if (event.key === "PageUp") {
|
|
203
|
+
rotateBy(-OVERLAY_PLACEMENT_FINE_ROTATE_STEP);
|
|
204
|
+
}
|
|
205
|
+
else if (event.key === "PageDown") {
|
|
206
|
+
rotateBy(OVERLAY_PLACEMENT_FINE_ROTATE_STEP);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
event.preventDefault();
|
|
212
|
+
return true;
|
|
213
|
+
},
|
|
214
|
+
connect() {
|
|
215
|
+
window.addEventListener("resize", reapply);
|
|
216
|
+
return () => {
|
|
217
|
+
gesture.release();
|
|
218
|
+
window.removeEventListener("resize", reapply);
|
|
219
|
+
};
|
|
220
|
+
},
|
|
221
|
+
};
|
|
222
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface PointerGestureArgs {
|
|
2
|
+
/** Receives every move of the pointer that began the gesture. */
|
|
3
|
+
onMove: (event: PointerEvent) => void;
|
|
4
|
+
/** Called once when the gesture ends, however it ends. */
|
|
5
|
+
onEnd: () => void;
|
|
6
|
+
}
|
|
7
|
+
export interface PointerGesture {
|
|
8
|
+
isActive: () => boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Claims a pointerdown for a gesture on `target`, returning whether it did.
|
|
11
|
+
* Declines a non-primary button, and any pointer while another gesture is
|
|
12
|
+
* active, so a second finger landing mid-drag neither moves nor pinches.
|
|
13
|
+
* The caller starts its drag or rotate controller after a claim, which
|
|
14
|
+
* takes the pointer capture this listens on.
|
|
15
|
+
*/
|
|
16
|
+
begin: (event: PointerEvent, target: HTMLElement) => boolean;
|
|
17
|
+
/** Ends the active gesture, if any, and releases its pointer capture. */
|
|
18
|
+
release: () => void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The lifecycle of one pointer gesture on a tool overlay: which pointer drives
|
|
22
|
+
* it, the listeners on the element that captured it, and every way it can end.
|
|
23
|
+
* `pointercancel` and `lostpointercapture` end it as well as `pointerup`,
|
|
24
|
+
* because iPadOS cancels a touch it takes over for a system gesture, and a
|
|
25
|
+
* gesture that waited for `pointerup` would stay stuck to the next touch.
|
|
26
|
+
*
|
|
27
|
+
* The claim calls `preventDefault`, which keeps a touch from scrolling or
|
|
28
|
+
* zooming the page and a mouse press from selecting text, and also suppresses
|
|
29
|
+
* the press's default focus: a caller whose keyboard alternatives act on a
|
|
30
|
+
* focused element focuses it itself.
|
|
31
|
+
*/
|
|
32
|
+
export declare function createPointerGesture(args: PointerGestureArgs): PointerGesture;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The lifecycle of one pointer gesture on a tool overlay: which pointer drives
|
|
3
|
+
* it, the listeners on the element that captured it, and every way it can end.
|
|
4
|
+
* `pointercancel` and `lostpointercapture` end it as well as `pointerup`,
|
|
5
|
+
* because iPadOS cancels a touch it takes over for a system gesture, and a
|
|
6
|
+
* gesture that waited for `pointerup` would stay stuck to the next touch.
|
|
7
|
+
*
|
|
8
|
+
* The claim calls `preventDefault`, which keeps a touch from scrolling or
|
|
9
|
+
* zooming the page and a mouse press from selecting text, and also suppresses
|
|
10
|
+
* the press's default focus: a caller whose keyboard alternatives act on a
|
|
11
|
+
* focused element focuses it itself.
|
|
12
|
+
*/
|
|
13
|
+
export function createPointerGesture(args) {
|
|
14
|
+
let pointerId = null;
|
|
15
|
+
let target = null;
|
|
16
|
+
const handleMove = (event) => {
|
|
17
|
+
if (event.pointerId === pointerId)
|
|
18
|
+
args.onMove(event);
|
|
19
|
+
};
|
|
20
|
+
const handleEnd = (event) => {
|
|
21
|
+
if (event.pointerId === pointerId)
|
|
22
|
+
release();
|
|
23
|
+
};
|
|
24
|
+
function release() {
|
|
25
|
+
const releasedTarget = target;
|
|
26
|
+
const releasedPointerId = pointerId;
|
|
27
|
+
pointerId = null;
|
|
28
|
+
target = null;
|
|
29
|
+
if (!releasedTarget || releasedPointerId === null)
|
|
30
|
+
return;
|
|
31
|
+
releasedTarget.removeEventListener("pointermove", handleMove);
|
|
32
|
+
releasedTarget.removeEventListener("pointerup", handleEnd);
|
|
33
|
+
releasedTarget.removeEventListener("pointercancel", handleEnd);
|
|
34
|
+
releasedTarget.removeEventListener("lostpointercapture", handleEnd);
|
|
35
|
+
if (releasedTarget.hasPointerCapture(releasedPointerId)) {
|
|
36
|
+
releasedTarget.releasePointerCapture(releasedPointerId);
|
|
37
|
+
}
|
|
38
|
+
args.onEnd();
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
isActive: () => pointerId !== null,
|
|
42
|
+
begin(event, nextTarget) {
|
|
43
|
+
if (event.button !== 0 || pointerId !== null)
|
|
44
|
+
return false;
|
|
45
|
+
pointerId = event.pointerId;
|
|
46
|
+
target = nextTarget;
|
|
47
|
+
nextTarget.addEventListener("pointermove", handleMove);
|
|
48
|
+
nextTarget.addEventListener("pointerup", handleEnd);
|
|
49
|
+
nextTarget.addEventListener("pointercancel", handleEnd);
|
|
50
|
+
nextTarget.addEventListener("lostpointercapture", handleEnd);
|
|
51
|
+
event.preventDefault();
|
|
52
|
+
return true;
|
|
53
|
+
},
|
|
54
|
+
release,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { PointerDragPosition } from "./pointer-drag.js";
|
|
2
|
+
export interface PointerRotateControllerArgs {
|
|
3
|
+
/** Current rotation in degrees. */
|
|
4
|
+
getRotation: () => number;
|
|
5
|
+
/** Receives the next rotation in degrees, normalised to `[0, 360)`. */
|
|
6
|
+
setRotation: (degrees: number) => void;
|
|
7
|
+
}
|
|
8
|
+
export interface PointerRotateController {
|
|
9
|
+
isRotating: () => boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Begin tracking a rotation from a pointerdown on a rotation handle. `pivot`
|
|
12
|
+
* is the point the element turns about, in client coordinates. As with
|
|
13
|
+
* `createPointerDragController`, callers own pointer-capture release and
|
|
14
|
+
* listener attach/detach.
|
|
15
|
+
*/
|
|
16
|
+
startRotating: (event: PointerEvent, container: Element, pivot: PointerDragPosition) => void;
|
|
17
|
+
/** No-ops when a rotation isn't in progress. */
|
|
18
|
+
handlePointerMove: (event: PointerEvent) => void;
|
|
19
|
+
endRotating: () => void;
|
|
20
|
+
}
|
|
21
|
+
/** Normalises an angle in degrees to `[0, 360)`. */
|
|
22
|
+
export declare function normalizeDegrees(degrees: number): number;
|
|
23
|
+
/**
|
|
24
|
+
* Tracks a pointer-capture-based rotation about a fixed pivot: the element
|
|
25
|
+
* turns by the angle the pointer sweeps around the pivot since the press, so
|
|
26
|
+
* grabbing the handle anywhere on its hit area causes no initial jump. The
|
|
27
|
+
* rotation counterpart of `createPointerDragController`.
|
|
28
|
+
*/
|
|
29
|
+
export declare function createPointerRotateController(args: PointerRotateControllerArgs): PointerRotateController;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** Normalises an angle in degrees to `[0, 360)`. */
|
|
2
|
+
export function normalizeDegrees(degrees) {
|
|
3
|
+
const turned = degrees % 360;
|
|
4
|
+
return turned < 0 ? turned + 360 : turned;
|
|
5
|
+
}
|
|
6
|
+
function angleDegrees(pivot, x, y) {
|
|
7
|
+
return (Math.atan2(y - pivot.y, x - pivot.x) * 180) / Math.PI;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Tracks a pointer-capture-based rotation about a fixed pivot: the element
|
|
11
|
+
* turns by the angle the pointer sweeps around the pivot since the press, so
|
|
12
|
+
* grabbing the handle anywhere on its hit area causes no initial jump. The
|
|
13
|
+
* rotation counterpart of `createPointerDragController`.
|
|
14
|
+
*/
|
|
15
|
+
export function createPointerRotateController(args) {
|
|
16
|
+
let rotating = false;
|
|
17
|
+
let pivot = { x: 0, y: 0 };
|
|
18
|
+
let startAngle = 0;
|
|
19
|
+
let startRotation = 0;
|
|
20
|
+
return {
|
|
21
|
+
isRotating: () => rotating,
|
|
22
|
+
startRotating(event, container, nextPivot) {
|
|
23
|
+
container.setPointerCapture(event.pointerId);
|
|
24
|
+
rotating = true;
|
|
25
|
+
pivot = nextPivot;
|
|
26
|
+
startAngle = angleDegrees(pivot, event.clientX, event.clientY);
|
|
27
|
+
startRotation = args.getRotation();
|
|
28
|
+
},
|
|
29
|
+
handlePointerMove(event) {
|
|
30
|
+
if (!rotating)
|
|
31
|
+
return;
|
|
32
|
+
const swept = angleDegrees(pivot, event.clientX, event.clientY) - startAngle;
|
|
33
|
+
args.setRotation(normalizeDegrees(startRotation + swept));
|
|
34
|
+
},
|
|
35
|
+
endRotating() {
|
|
36
|
+
rotating = false;
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pie-players/pie-players-shared",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.75",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Shared runtime + UI utilities for PIE players",
|
|
6
6
|
"license": "MIT",
|
|
@@ -45,6 +45,10 @@
|
|
|
45
45
|
"types": "./dist/timed-media/index.d.ts",
|
|
46
46
|
"import": "./dist/timed-media/index.js"
|
|
47
47
|
},
|
|
48
|
+
"./media": {
|
|
49
|
+
"types": "./dist/media/index.d.ts",
|
|
50
|
+
"import": "./dist/media/index.js"
|
|
51
|
+
},
|
|
48
52
|
"./pie": {
|
|
49
53
|
"types": "./dist/pie/index.d.ts",
|
|
50
54
|
"import": "./dist/pie/index.js"
|
|
@@ -57,14 +61,6 @@
|
|
|
57
61
|
"types": "./dist/loaders/index.d.ts",
|
|
58
62
|
"import": "./dist/loaders/index.js"
|
|
59
63
|
},
|
|
60
|
-
"./server/npm-registry": {
|
|
61
|
-
"types": "./dist/server/npm-registry.d.ts",
|
|
62
|
-
"import": "./dist/server/npm-registry.js"
|
|
63
|
-
},
|
|
64
|
-
"./server/npm-auth-env": {
|
|
65
|
-
"types": "./dist/server/npm-auth-env.d.ts",
|
|
66
|
-
"import": "./dist/server/npm-auth-env.js"
|
|
67
|
-
},
|
|
68
64
|
"./i18n": {
|
|
69
65
|
"types": "./dist/i18n/index.d.ts",
|
|
70
66
|
"import": "./dist/i18n/index.js"
|
|
@@ -89,6 +85,10 @@
|
|
|
89
85
|
"types": "./dist/components/vendor/nds/nds-icon-button.d.ts",
|
|
90
86
|
"import": "./dist/components/vendor/nds/nds-icon-button.js"
|
|
91
87
|
},
|
|
88
|
+
"./ui/attribute-coercion": {
|
|
89
|
+
"types": "./dist/ui/attribute-coercion.d.ts",
|
|
90
|
+
"import": "./dist/ui/attribute-coercion.js"
|
|
91
|
+
},
|
|
92
92
|
"./ui/content-styles": {
|
|
93
93
|
"types": "./dist/ui/content-styles.d.ts",
|
|
94
94
|
"import": "./dist/ui/content-styles.js"
|
|
@@ -102,28 +102,31 @@
|
|
|
102
102
|
"dist"
|
|
103
103
|
],
|
|
104
104
|
"dependencies": {
|
|
105
|
+
"@pie-element/shared-utils": "0.1.3",
|
|
105
106
|
"@pie-lib/math-rendering-module": "6.0.0",
|
|
106
|
-
"dompurify": "^3.4.
|
|
107
|
+
"dompurify": "^3.4.16",
|
|
107
108
|
"semver": "^7.8.5"
|
|
108
109
|
},
|
|
109
110
|
"scripts": {
|
|
110
|
-
"build": "rm -rf dist tsconfig.tsbuildinfo && tsc -p tsconfig.json && mkdir -p dist/components && cp -R src/components/vendor dist/components/vendor",
|
|
111
|
+
"build": "rm -rf dist tsconfig.tsbuildinfo && tsc -p tsconfig.json && node scripts/bundle-vendored-modules.mjs && mkdir -p dist/components && cp -R src/components/vendor dist/components/vendor",
|
|
111
112
|
"dev": "tsc -p tsconfig.json --watch",
|
|
112
|
-
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
113
|
-
"lint": "biome
|
|
113
|
+
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.tests.json",
|
|
114
|
+
"lint": "biome lint .",
|
|
114
115
|
"check": "tsc -p tsconfig.json --noEmit",
|
|
115
116
|
"test": "bun test",
|
|
116
117
|
"check-i18n": "bun run src/i18n/scripts/check-coverage.ts",
|
|
117
118
|
"scan-hardcoded": "bun run src/i18n/scripts/scan-hardcoded.ts"
|
|
118
119
|
},
|
|
119
120
|
"devDependencies": {
|
|
120
|
-
"@biomejs/biome": "^2.5.
|
|
121
|
-
"@happy-dom/global-registrator": "^20.
|
|
122
|
-
"@
|
|
121
|
+
"@biomejs/biome": "^2.5.15",
|
|
122
|
+
"@happy-dom/global-registrator": "^20.14.5",
|
|
123
|
+
"@pie-element/shared-math-rendering-mathjax": "0.1.4",
|
|
124
|
+
"@playwright/test": "^1.63.0",
|
|
123
125
|
"@types/semver": "^7.8.0",
|
|
126
|
+
"es-module-shims": "^2.8.4",
|
|
124
127
|
"esbuild": "^0.28.2",
|
|
125
128
|
"glob": "^13.0.0",
|
|
126
|
-
"svelte": "^5.57.
|
|
129
|
+
"svelte": "^5.57.1",
|
|
127
130
|
"typescript": "^5.9.3"
|
|
128
131
|
},
|
|
129
132
|
"homepage": "https://github.com/pie-framework/pie-players/tree/master/packages/players-shared#readme",
|
|
@@ -133,5 +136,7 @@
|
|
|
133
136
|
"engines": {
|
|
134
137
|
"node": ">=20.0.0"
|
|
135
138
|
},
|
|
136
|
-
"sideEffects":
|
|
139
|
+
"sideEffects": [
|
|
140
|
+
"./dist/components/vendor/nds/*.js"
|
|
141
|
+
]
|
|
137
142
|
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Component context stack for PIE mini-players.
|
|
3
|
-
*
|
|
4
|
-
* Used to attribute resource load failures (fonts/images/etc.) to the currently
|
|
5
|
-
* active mini-player component.
|
|
6
|
-
*/
|
|
7
|
-
export type ComponentContext = {
|
|
8
|
-
componentName: string;
|
|
9
|
-
elementType?: string;
|
|
10
|
-
itemId?: string;
|
|
11
|
-
timestamp: number;
|
|
12
|
-
};
|
|
13
|
-
/**
|
|
14
|
-
* Register a component as active (call when component mounts).
|
|
15
|
-
* Returns a cleanup function to call when the component unmounts.
|
|
16
|
-
*/
|
|
17
|
-
export declare function registerActiveComponent(context: ComponentContext): () => void;
|
|
18
|
-
/**
|
|
19
|
-
* Get the current active component context (top of the stack).
|
|
20
|
-
*/
|
|
21
|
-
export declare function getCurrentComponentContext(): ComponentContext | null;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Component context stack for PIE mini-players.
|
|
3
|
-
*
|
|
4
|
-
* Used to attribute resource load failures (fonts/images/etc.) to the currently
|
|
5
|
-
* active mini-player component.
|
|
6
|
-
*/
|
|
7
|
-
// Track active components (stack-based for nested components)
|
|
8
|
-
const activeComponents = [];
|
|
9
|
-
/**
|
|
10
|
-
* Register a component as active (call when component mounts).
|
|
11
|
-
* Returns a cleanup function to call when the component unmounts.
|
|
12
|
-
*/
|
|
13
|
-
export function registerActiveComponent(context) {
|
|
14
|
-
activeComponents.push(context);
|
|
15
|
-
return () => {
|
|
16
|
-
const index = activeComponents.indexOf(context);
|
|
17
|
-
if (index > -1) {
|
|
18
|
-
activeComponents.splice(index, 1);
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Get the current active component context (top of the stack).
|
|
24
|
-
*/
|
|
25
|
-
export function getCurrentComponentContext() {
|
|
26
|
-
return activeComponents.length > 0
|
|
27
|
-
? activeComponents[activeComponents.length - 1]
|
|
28
|
-
: null;
|
|
29
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared PIE player initialization logic
|
|
3
|
-
* Used by preloaded static player runtimes
|
|
4
|
-
*/
|
|
5
|
-
export interface PiePlayerConfig {
|
|
6
|
-
env: any;
|
|
7
|
-
addCorrectResponse: boolean;
|
|
8
|
-
session: any[];
|
|
9
|
-
externalStyleUrls?: string;
|
|
10
|
-
customClassName?: string;
|
|
11
|
-
containerClass?: string;
|
|
12
|
-
passageContainerClass?: string;
|
|
13
|
-
}
|
|
14
|
-
export interface ItemData {
|
|
15
|
-
item: {
|
|
16
|
-
config: any;
|
|
17
|
-
};
|
|
18
|
-
passage?: {
|
|
19
|
-
config: {
|
|
20
|
-
markup?: string;
|
|
21
|
-
};
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
export interface PiePlayerElements {
|
|
25
|
-
playerEl: HTMLElement;
|
|
26
|
-
passageMarkup: string | null;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Initialize PIE player with item data
|
|
30
|
-
* Shared initialization for preloaded/static player entrypoints.
|
|
31
|
-
*/
|
|
32
|
-
export declare function initializePiePlayer(itemData: ItemData, config: PiePlayerConfig, elements: PiePlayerElements): Promise<void>;
|
|
33
|
-
/**
|
|
34
|
-
* Extract passage markup from item data
|
|
35
|
-
*/
|
|
36
|
-
export declare function extractPassageMarkup(itemData: ItemData): string | null;
|
|
37
|
-
/**
|
|
38
|
-
* Ensure pie-player web component is loaded
|
|
39
|
-
*/
|
|
40
|
-
export declare function ensurePiePlayerLoaded(): Promise<void>;
|
|
41
|
-
/**
|
|
42
|
-
* Build event listeners map for PIE elements
|
|
43
|
-
*/
|
|
44
|
-
export declare function buildEventListenersMap(config: any, onSessionChanged: (detail: any) => void): Record<string, Record<string, (e: CustomEvent) => void>> | undefined;
|
|
45
|
-
/**
|
|
46
|
-
* Build URL parameters for API request
|
|
47
|
-
* Shared by preloaded/static player entrypoints.
|
|
48
|
-
*/
|
|
49
|
-
export declare function buildApiParams(env: any, addCorrectResponse: boolean): URLSearchParams;
|
|
50
|
-
/**
|
|
51
|
-
* Fetch item data from API
|
|
52
|
-
* Shared by preloaded/static player entrypoints.
|
|
53
|
-
*/
|
|
54
|
-
export declare function fetchItemData(apiBaseUrl: string, itemId: string, token: string, endpoint: "packaged" | "data-only", env: any, addCorrectResponse: boolean, signal?: AbortSignal): Promise<any>;
|