@pie-players/pie-assessment-toolkit 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 +469 -318
- package/dist/attempt/AssessmentSession.d.ts +1 -5
- package/dist/attempt/AssessmentSession.js +0 -29
- package/dist/attempt/TestSession.d.ts +1 -20
- package/dist/attempt/TestSession.js +8 -99
- package/dist/components/ItemScope.custom-element.d.ts +1 -0
- package/dist/components/ItemScope.custom-element.js +1 -0
- package/dist/components/ItemToolBar.custom-element.d.ts +1 -0
- package/dist/components/ItemToolBar.custom-element.js +1 -1
- package/dist/components/PieAssessmentToolkit.custom-element.d.ts +1 -0
- package/dist/components/PieAssessmentToolkit.custom-element.js +13 -13
- package/dist/components/SectionToolBar.custom-element.d.ts +1 -0
- package/dist/components/SectionToolBar.custom-element.js +1 -1
- package/dist/components/chunks/ItemToolBar-7tt7v2xp.js +4 -0
- package/dist/components/chunks/ItemToolBar-97hx60z4.js +2 -0
- package/dist/components/chunks/ItemToolBar-bxwyhr5p.js +2 -0
- package/dist/components/chunks/ItemToolBar-jx38w99s.js +2 -0
- package/dist/components/chunks/ItemToolBar-rd2bb4p6.js +40 -0
- package/dist/components/chunks/ItemToolBar-vdkyn9f3.js +2 -0
- package/dist/components/chunks/sre-engine-jd8cc08x.js +1 -0
- package/dist/components/item-scope-element.d.ts +2 -0
- package/dist/components/item-scope-element.js +2 -0
- package/dist/context/assessment-toolkit-context.d.ts +32 -6
- package/dist/index.d.ts +23 -48
- package/dist/index.js +12 -37
- package/dist/policy/core/PolicySource.d.ts +1 -1
- package/dist/policy/core/ToolPolicyEngine.d.ts +85 -34
- package/dist/policy/core/ToolPolicyEngine.js +148 -46
- package/dist/policy/core/compose-decision.d.ts +28 -7
- package/dist/policy/core/compose-decision.js +75 -54
- package/dist/policy/core/decision-types.d.ts +65 -34
- package/dist/policy/core/feature-decision.d.ts +16 -9
- package/dist/policy/core/feature-decision.js +14 -8
- package/dist/policy/core/pnp-policy-inputs.d.ts +24 -33
- package/dist/policy/core/pnp-policy-inputs.js +28 -56
- package/dist/policy/core/provenance.d.ts +9 -4
- package/dist/policy/core/provenance.js +1 -1
- package/dist/policy/engine.d.ts +7 -23
- package/dist/policy/engine.js +5 -20
- package/dist/policy/sources/PnpPolicySource.d.ts +44 -61
- package/dist/policy/sources/PnpPolicySource.js +117 -118
- package/dist/runtime/SectionControllerBinding.d.ts +279 -0
- package/dist/runtime/SectionControllerBinding.js +450 -0
- package/dist/runtime/SectionRuntimeEngine.d.ts +26 -289
- package/dist/runtime/SectionRuntimeEngine.js +30 -372
- package/dist/runtime/adapter/SectionEngineAdapter.d.ts +19 -80
- package/dist/runtime/adapter/SectionEngineAdapter.js +19 -92
- package/dist/runtime/adapter/dom-event-bridge.d.ts +15 -30
- package/dist/runtime/adapter/dom-event-bridge.js +17 -44
- package/dist/runtime/adapter/subscriber-fanout.d.ts +1 -2
- package/dist/runtime/adapter/subscriber-fanout.js +1 -2
- package/dist/runtime/catalog-context.d.ts +19 -0
- package/dist/runtime/catalog-context.js +28 -0
- package/dist/runtime/composition-emit-scheduler.d.ts +9 -15
- package/dist/runtime/composition-emit-scheduler.js +9 -15
- package/dist/runtime/content-language.d.ts +32 -0
- package/dist/runtime/content-language.js +46 -0
- package/dist/runtime/content-region.d.ts +17 -0
- package/dist/runtime/content-region.js +29 -0
- package/dist/runtime/content-registration.d.ts +13 -0
- package/dist/runtime/content-registration.js +25 -0
- package/dist/runtime/core/SectionEngineCore.d.ts +2 -2
- package/dist/runtime/core/SectionEngineCore.js +2 -2
- package/dist/runtime/core/cohort.d.ts +1 -1
- package/dist/runtime/core/cohort.js +1 -1
- package/dist/runtime/core/engine-input.d.ts +18 -30
- package/dist/runtime/core/engine-input.js +11 -12
- package/dist/runtime/core/engine-output.d.ts +16 -40
- package/dist/runtime/core/engine-output.js +9 -21
- package/dist/runtime/core/engine-readiness.d.ts +5 -37
- package/dist/runtime/core/engine-readiness.js +8 -41
- package/dist/runtime/core/engine-resolver.d.ts +46 -74
- package/dist/runtime/core/engine-resolver.js +18 -43
- package/dist/runtime/core/engine-state.d.ts +28 -36
- package/dist/runtime/core/engine-state.js +18 -21
- package/dist/runtime/core/engine-transition.d.ts +14 -19
- package/dist/runtime/core/engine-transition.js +71 -51
- package/dist/runtime/engine.d.ts +16 -19
- package/dist/runtime/engine.js +12 -19
- package/dist/runtime/page-warnings.d.ts +13 -0
- package/dist/runtime/page-warnings.js +22 -0
- package/dist/runtime/policy-input-forwarding.d.ts +25 -0
- package/dist/runtime/policy-input-forwarding.js +25 -0
- package/dist/runtime/registration-events.d.ts +14 -0
- package/dist/runtime/runtime-event-claim.d.ts +8 -0
- package/dist/runtime/runtime-event-claim.js +15 -0
- package/dist/runtime/shell-event-bridge.d.ts +45 -0
- package/dist/runtime/shell-event-bridge.js +127 -0
- package/dist/runtime/shell-registration.d.ts +73 -0
- package/dist/runtime/shell-registration.js +95 -0
- package/dist/runtime/shell-scope.d.ts +68 -0
- package/dist/runtime/shell-scope.js +188 -0
- package/dist/runtime/tool-host-contract.d.ts +28 -10
- package/dist/runtime/tool-host-contract.js +31 -10
- package/dist/runtime/unclaimed-registration-watch.d.ts +7 -0
- package/dist/runtime/unclaimed-registration-watch.js +23 -0
- package/dist/services/ElementToolStateStore.d.ts +14 -10
- package/dist/services/ElementToolStateStore.js +37 -13
- package/dist/services/HighlightCoordinator.d.ts +22 -28
- package/dist/services/HighlightCoordinator.js +431 -327
- package/dist/services/RangeSerializer.d.ts +10 -1
- package/dist/services/RangeSerializer.js +87 -14
- package/dist/services/TTSService.d.ts +130 -69
- package/dist/services/TTSService.js +713 -570
- package/dist/services/ToolCoordinator.d.ts +43 -66
- package/dist/services/ToolCoordinator.js +164 -208
- package/dist/services/ToolRegistry.d.ts +78 -54
- package/dist/services/ToolRegistry.js +107 -105
- package/dist/services/ToolkitCoordinator.d.ts +261 -175
- package/dist/services/ToolkitCoordinator.js +667 -433
- package/dist/services/audio-handoff.d.ts +6 -7
- package/dist/services/audio-handoff.js +20 -14
- package/dist/services/catalog-owner.d.ts +11 -1
- package/dist/services/catalog-owner.js +25 -0
- package/dist/services/create-tools-config.d.ts +2 -2
- package/dist/services/framework-error-bus.d.ts +3 -6
- package/dist/services/framework-error-bus.js +3 -6
- package/dist/services/framework-error.d.ts +30 -8
- package/dist/services/framework-error.js +9 -7
- package/dist/services/interfaces.d.ts +158 -129
- package/dist/services/section-controller-types.d.ts +15 -0
- package/dist/services/section-session-assignment.d.ts +21 -0
- package/dist/services/section-session-assignment.js +82 -0
- package/dist/services/spoken-audio-cards.d.ts +0 -2
- package/dist/services/spoken-audio-cards.js +1 -3
- package/dist/services/tool-config-defaults.d.ts +3 -3
- package/dist/services/tool-config-defaults.js +3 -3
- package/dist/services/tool-config-validation.d.ts +14 -4
- package/dist/services/tool-config-validation.js +63 -71
- package/dist/services/tool-context.d.ts +0 -8
- package/dist/services/tool-context.js +29 -25
- package/dist/services/tool-icons.d.ts +4 -3
- package/dist/services/tool-icons.js +4 -3
- package/dist/services/tool-instance-id.d.ts +0 -1
- package/dist/services/tool-instance-id.js +0 -6
- package/dist/services/tool-providers/TTSToolProvider.d.ts +41 -80
- package/dist/services/tool-providers/TTSToolProvider.js +81 -40
- package/dist/services/tool-providers/ToolProviderApi.d.ts +10 -4
- package/dist/services/tool-providers/ToolProviderRegistry.d.ts +32 -28
- package/dist/services/tool-providers/ToolProviderRegistry.js +121 -107
- package/dist/services/tool-providers/index.d.ts +0 -9
- package/dist/services/tool-providers/index.js +2 -4
- package/dist/services/tool-request.d.ts +27 -12
- package/dist/services/tool-request.js +24 -14
- package/dist/services/toolbar-decided-tools.d.ts +15 -0
- package/dist/services/toolbar-decided-tools.js +28 -0
- package/dist/services/tools-config-normalizer.d.ts +37 -23
- package/dist/services/tools-config-normalizer.js +2 -10
- package/dist/services/tts/browser-provider.d.ts +38 -2
- package/dist/services/tts/browser-provider.js +276 -140
- package/dist/services/tts/catalog-span-alignment.d.ts +2 -17
- package/dist/services/tts/catalog-span-alignment.js +17 -142
- package/dist/services/tts/flat-tree.d.ts +71 -0
- package/dist/services/tts/flat-tree.js +269 -0
- package/dist/services/tts/generated-speech/assemble-plan.d.ts +3 -1
- package/dist/services/tts/generated-speech/assemble-plan.js +3 -1
- package/dist/services/tts/generated-speech/dom/build-dom-plan.d.ts +2 -0
- package/dist/services/tts/generated-speech/dom/build-dom-plan.js +1 -1
- package/dist/services/tts/generated-speech/math-speech-cache.d.ts +3 -1
- package/dist/services/tts/generated-speech/math-speech-cache.js +5 -1
- package/dist/services/tts/generated-speech/types.d.ts +0 -12
- package/dist/services/tts/highlight-pipeline/boundary-normalizer.js +12 -62
- package/dist/services/tts/highlight-pipeline/create-highlight-plan.js +38 -5
- package/dist/services/tts/highlight-pipeline/normalize-speech-chunks.js +3 -6
- package/dist/services/tts/highlight-pipeline/prose-boundary-resolver.js +6 -4
- package/dist/services/tts/highlight-pipeline/readable-region.js +3 -2
- package/dist/services/tts/highlight-pipeline/types.d.ts +5 -0
- package/dist/services/tts/highlight-pipeline/visible-map-range.d.ts +12 -0
- package/dist/services/tts/highlight-pipeline/visible-map-range.js +73 -7
- package/dist/services/tts/math-alignment/index.d.ts +0 -5
- package/dist/services/tts/math-alignment/index.js +5 -25
- package/dist/services/tts/math-alignment/speech-tokenizer.d.ts +9 -1
- package/dist/services/tts/math-alignment/speech-tokenizer.js +38 -36
- package/dist/services/tts/math-alignment/types.d.ts +4 -2
- package/dist/services/tts/math-aware-text-processing.d.ts +5 -1
- package/dist/services/tts/math-aware-text-processing.js +74 -18
- package/dist/services/tts/math-control-names.d.ts +21 -0
- package/dist/services/tts/math-control-names.js +142 -0
- package/dist/services/tts/math-speech.d.ts +16 -1
- package/dist/services/tts/math-speech.js +55 -19
- package/dist/services/tts/provider-options.d.ts +41 -0
- package/dist/services/tts/provider-options.js +1 -0
- package/dist/services/tts/sre-engine.d.ts +7 -0
- package/dist/services/tts/sre-engine.js +11 -0
- package/dist/services/tts/sre-locales.d.ts +14 -0
- package/dist/services/tts/sre-locales.js +57 -0
- package/dist/services/tts/ssml/spoken-text.d.ts +2 -26
- package/dist/services/tts/ssml/spoken-text.js +29 -0
- package/dist/services/tts/start-failure.d.ts +11 -0
- package/dist/services/tts/start-failure.js +19 -0
- package/dist/services/tts/text-processing.d.ts +9 -1
- package/dist/services/tts/text-processing.js +46 -34
- package/dist/services/tts/text-segmentation.d.ts +7 -0
- package/dist/services/tts/text-segmentation.js +47 -0
- package/dist/services/tts-runtime-config.d.ts +44 -18
- package/dist/services/tts-runtime-config.js +22 -93
- package/dist/tools/content-capability-resolution.d.ts +7 -9
- package/dist/tools/content-capability-resolution.js +8 -45
- package/dist/tools/registration.d.ts +58 -0
- package/dist/tools/registration.js +54 -0
- package/dist/tools/registrations/toolbar-registration-helpers.js +2 -2
- package/dist/tools/tool-surface-host.d.ts +6 -10
- package/dist/tools/tool-surface-host.js +44 -42
- package/dist/tools/tool-tag-map.d.ts +5 -15
- package/dist/tools/tool-tag-map.js +6 -20
- package/dist/utils/structural-equality.d.ts +11 -0
- package/dist/utils/structural-equality.js +47 -0
- package/package.json +24 -59
- package/dist/attempt/adapters/activity-to-test-attempt-session.d.ts +0 -49
- package/dist/attempt/adapters/activity-to-test-attempt-session.js +0 -138
- package/dist/components/chunks/ItemToolBar-byq80z42.js +0 -40
- package/dist/components/chunks/ItemToolBar-d36g3aw4.js +0 -49
- package/dist/context/runtime-context-consumer.d.ts +0 -13
- package/dist/context/runtime-context-consumer.js +0 -51
- package/dist/item-loader.d.ts +0 -44
- package/dist/item-loader.js +0 -61
- package/dist/policy/core/engine-context.d.ts +0 -29
- package/dist/policy/core/engine-context.js +0 -27
- package/dist/policy/core/policy-source-tag.d.ts +0 -31
- package/dist/policy/core/policy-source-tag.js +0 -28
- package/dist/policy/internal.d.ts +0 -25
- package/dist/policy/internal.js +0 -25
- package/dist/runtime/adapter/coordinator-bridge.d.ts +0 -92
- package/dist/runtime/adapter/coordinator-bridge.js +0 -126
- package/dist/runtime/adapter/framework-error-bridge.d.ts +0 -36
- package/dist/runtime/adapter/framework-error-bridge.js +0 -46
- package/dist/runtime/adapter/instrumentation-bridge.d.ts +0 -31
- package/dist/runtime/adapter/instrumentation-bridge.js +0 -38
- package/dist/runtime/core/engine-stage-derivation.d.ts +0 -18
- package/dist/runtime/core/engine-stage-derivation.js +0 -29
- package/dist/runtime/engine-context.d.ts +0 -39
- package/dist/runtime/engine-context.js +0 -31
- package/dist/runtime/internal.d.ts +0 -43
- package/dist/runtime/internal.js +0 -45
- package/dist/runtime/section-runtime-engine-host-context.d.ts +0 -80
- package/dist/runtime/section-runtime-engine-host-context.js +0 -95
- package/dist/runtime/stage-emit-gate.d.ts +0 -92
- package/dist/runtime/stage-emit-gate.js +0 -82
- package/dist/services/I18nService.d.ts +0 -47
- package/dist/services/I18nService.js +0 -84
- package/dist/services/ThemeProvider.d.ts +0 -95
- package/dist/services/ThemeProvider.js +0 -334
- package/dist/services/ToolConfigResolver.d.ts +0 -161
- package/dist/services/ToolConfigResolver.js +0 -229
- package/dist/services/catalog-media.d.ts +0 -56
- package/dist/services/catalog-media.js +0 -190
- package/dist/services/createDefaultToolRegistry.d.ts +0 -53
- package/dist/services/createDefaultToolRegistry.js +0 -45
- package/dist/services/defaultPersonalNeedsProfile.d.ts +0 -21
- package/dist/services/defaultPersonalNeedsProfile.js +0 -26
- package/dist/services/pnp-standard-features.d.ts +0 -238
- package/dist/services/pnp-standard-features.js +0 -338
- package/dist/services/tool-providers/CortexToolProvider.d.ts +0 -13
- package/dist/services/tool-providers/CortexToolProvider.js +0 -32
- package/dist/services/tool-providers/DesmosToolProvider.d.ts +0 -14
- package/dist/services/tool-providers/DesmosToolProvider.js +0 -32
- package/dist/services/tool-providers/GeoGebraToolProvider.d.ts +0 -16
- package/dist/services/tool-providers/GeoGebraToolProvider.js +0 -32
- package/dist/services/tool-providers/LazyCalculatorToolProvider.d.ts +0 -35
- package/dist/services/tool-providers/LazyCalculatorToolProvider.js +0 -95
- package/dist/services/tts/visual-line-ranges.d.ts +0 -18
- package/dist/services/tts/visual-line-ranges.js +0 -226
- package/dist/tools/client.d.ts +0 -12
- package/dist/tools/client.js +0 -14
- package/dist/tools/index.d.ts +0 -8
- package/dist/tools/index.js +0 -10
- package/dist/tools/internal.d.ts +0 -43
- package/dist/tools/internal.js +0 -41
- package/dist/tools/response-discovery.d.ts +0 -61
- package/dist/tools/response-discovery.js +0 -113
- package/dist/tools/types.d.ts +0 -337
- package/dist/tools/types.js +0 -12
- package/dist/tools/variant-resolver.d.ts +0 -41
- package/dist/tools/variant-resolver.js +0 -207
|
@@ -1,61 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Section runtime engine adapter
|
|
2
|
+
* Section runtime engine adapter.
|
|
3
3
|
*
|
|
4
4
|
* The adapter is the single I/O seam between the pure FSM core
|
|
5
|
-
* (`SectionEngineCore`) and the rest of the world (DOM
|
|
6
|
-
*
|
|
7
|
-
* exactly two jobs:
|
|
5
|
+
* (`SectionEngineCore`) and the rest of the world (the DOM and host
|
|
6
|
+
* subscribers). It does exactly two jobs:
|
|
8
7
|
*
|
|
9
|
-
* 1.
|
|
10
|
-
*
|
|
11
|
-
* them to the core via `core.dispatch(input)`.
|
|
8
|
+
* 1. Forward host-constructed `SectionEngineInput`s to the core via
|
|
9
|
+
* `core.dispatch(input)`.
|
|
12
10
|
*
|
|
13
|
-
* 2. Subscribe to the core's output stream and
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* byte-identical detail shapes.
|
|
11
|
+
* 2. Subscribe to the core's output stream and route each batch, in
|
|
12
|
+
* order, to the DOM-event bridge (`pie-stage-change`,
|
|
13
|
+
* `pie-loading-complete`) and then to the subscriber fan-out (one
|
|
14
|
+
* batch per `core.dispatch`).
|
|
18
15
|
*
|
|
19
|
-
* Output routing is a single exhaustive `switch
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* what to do with it.
|
|
16
|
+
* Output routing is a single exhaustive `switch`, so a new
|
|
17
|
+
* `SectionEngineOutput` kind is a compile error here until the adapter
|
|
18
|
+
* routes it.
|
|
23
19
|
*
|
|
24
|
-
* **
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* - framework-error bus (single fan-out for in-process subscribers)
|
|
28
|
-
* - instrumentation hook
|
|
29
|
-
* - public subscriber fan-out (batched, runs once per
|
|
30
|
-
* `core.dispatch`)
|
|
31
|
-
*
|
|
32
|
-
* The `readiness-change` / `interaction-ready` / `ready`
|
|
33
|
-
* DOM events and their event bridge were removed in the
|
|
34
|
-
* broad architecture review compat sweep; the corresponding output
|
|
35
|
-
* kinds are gone from `engine-output.ts`.
|
|
36
|
-
*
|
|
37
|
-
* **Layering constraint.** The adapter is plain TS. It must not
|
|
38
|
-
* import `svelte` — the M7 implementation plan and
|
|
39
|
-
* `scripts/check-engine-core-purity.mjs` enforce the core's purity;
|
|
40
|
-
* the adapter follows the same constraint by convention so it stays
|
|
41
|
-
* usable from non-Svelte hosts (Node tests, Storybook, or future
|
|
42
|
-
* non-Svelte consumers). `bun run check:custom-elements` already
|
|
43
|
-
* blocks `.svelte` imports in published `dist`; adding a Svelte
|
|
44
|
-
* dependency here would also leak through that gate.
|
|
20
|
+
* **Layering constraint.** The adapter is plain TS and must not import
|
|
21
|
+
* `svelte`; `scripts/check-engine-core-purity.mjs` enforces it, so the
|
|
22
|
+
* adapter stays usable from non-Svelte hosts and Node tests.
|
|
45
23
|
*/
|
|
46
24
|
import { SectionEngineCore } from "../core/SectionEngineCore.js";
|
|
47
|
-
import { createCoordinatorBridge, } from "./coordinator-bridge.js";
|
|
48
25
|
import { createDomEventBridge, } from "./dom-event-bridge.js";
|
|
49
|
-
import { createFrameworkErrorBridge, } from "./framework-error-bridge.js";
|
|
50
|
-
import { createInstrumentationBridge, } from "./instrumentation-bridge.js";
|
|
51
26
|
import { createSubscriberFanout, } from "./subscriber-fanout.js";
|
|
52
27
|
export class SectionEngineAdapter {
|
|
53
28
|
core;
|
|
54
29
|
domEventBridge;
|
|
55
|
-
frameworkErrorBridge;
|
|
56
|
-
instrumentationBridge;
|
|
57
30
|
subscriberFanout;
|
|
58
|
-
coordinatorBridge;
|
|
59
31
|
unsubscribeCore;
|
|
60
32
|
disposed = false;
|
|
61
33
|
constructor(options) {
|
|
@@ -66,19 +38,7 @@ export class SectionEngineAdapter {
|
|
|
66
38
|
sourceCe: options.sourceCe,
|
|
67
39
|
now: options.now,
|
|
68
40
|
});
|
|
69
|
-
this.frameworkErrorBridge = createFrameworkErrorBridge({
|
|
70
|
-
bus: options.frameworkErrorBus,
|
|
71
|
-
});
|
|
72
|
-
this.instrumentationBridge = createInstrumentationBridge({
|
|
73
|
-
hook: options.instrumentationHook,
|
|
74
|
-
});
|
|
75
41
|
this.subscriberFanout = createSubscriberFanout();
|
|
76
|
-
this.coordinatorBridge = options.coordinator
|
|
77
|
-
? createCoordinatorBridge({
|
|
78
|
-
coordinator: options.coordinator,
|
|
79
|
-
dispatchCoreInput: (input) => this.dispatchInput(input),
|
|
80
|
-
})
|
|
81
|
-
: null;
|
|
82
42
|
this.unsubscribeCore = this.core.subscribe((outputs) => {
|
|
83
43
|
this.routeOutputs(outputs);
|
|
84
44
|
});
|
|
@@ -114,35 +74,11 @@ export class SectionEngineAdapter {
|
|
|
114
74
|
this.domEventBridge.setHost(host);
|
|
115
75
|
}
|
|
116
76
|
/**
|
|
117
|
-
*
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
this.instrumentationBridge.setHook(hook);
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Resolve a section controller through the configured coordinator.
|
|
124
|
-
*
|
|
125
|
-
* Throws if the adapter was constructed without a coordinator.
|
|
126
|
-
* Standalone callers should manually feed
|
|
127
|
-
* `{ kind: "section-controller-resolved" }` after their own
|
|
128
|
-
* controller resolution path completes.
|
|
77
|
+
* Tear the adapter down. Safe to call more than once. Emits `disposed`
|
|
78
|
+
* for the active cohort, then detaches the core subscription and
|
|
79
|
+
* clears subscribers.
|
|
129
80
|
*/
|
|
130
|
-
|
|
131
|
-
if (!this.coordinatorBridge) {
|
|
132
|
-
throw new Error("[SectionEngineAdapter] resolveSectionController called without a coordinator.");
|
|
133
|
-
}
|
|
134
|
-
return this.coordinatorBridge.resolveSectionController(args);
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Tear the adapter down. Safe to call more than once. Disposes the
|
|
138
|
-
* coordinator bridge (which in turn disposes the section
|
|
139
|
-
* controller for the current cohort), detaches the core
|
|
140
|
-
* subscription, and clears subscribers.
|
|
141
|
-
*
|
|
142
|
-
* Does **not** dispose the framework-error bus — its lifetime is
|
|
143
|
-
* owned by the toolkit CE / host.
|
|
144
|
-
*/
|
|
145
|
-
async dispose() {
|
|
81
|
+
dispose() {
|
|
146
82
|
if (this.disposed)
|
|
147
83
|
return;
|
|
148
84
|
this.disposed = true;
|
|
@@ -151,9 +87,6 @@ export class SectionEngineAdapter {
|
|
|
151
87
|
this.core.dispatch({ kind: "dispose" });
|
|
152
88
|
this.unsubscribeCore();
|
|
153
89
|
this.subscriberFanout.dispose();
|
|
154
|
-
if (this.coordinatorBridge) {
|
|
155
|
-
await this.coordinatorBridge.dispose();
|
|
156
|
-
}
|
|
157
90
|
}
|
|
158
91
|
routeOutputs(outputs) {
|
|
159
92
|
for (const output of outputs) {
|
|
@@ -167,16 +100,10 @@ export class SectionEngineAdapter {
|
|
|
167
100
|
case "loading-complete":
|
|
168
101
|
this.domEventBridge.dispatch(output);
|
|
169
102
|
break;
|
|
170
|
-
case "framework-error":
|
|
171
|
-
this.domEventBridge.dispatch(output);
|
|
172
|
-
this.frameworkErrorBridge.dispatch(output);
|
|
173
|
-
break;
|
|
174
103
|
default: {
|
|
175
104
|
const exhaustive = output;
|
|
176
105
|
void exhaustive;
|
|
177
|
-
return;
|
|
178
106
|
}
|
|
179
107
|
}
|
|
180
|
-
this.instrumentationBridge.dispatch(output);
|
|
181
108
|
}
|
|
182
109
|
}
|
|
@@ -1,36 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* DOM event bridge for the section runtime engine adapter
|
|
3
|
-
* C, layered).
|
|
2
|
+
* DOM event bridge for the section runtime engine adapter.
|
|
4
3
|
*
|
|
5
|
-
* Translates
|
|
6
|
-
* `
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* canonical event surface stays stable while the kernel migrates onto
|
|
11
|
-
* the engine in PR 5.
|
|
4
|
+
* Translates engine outputs (`stage-change`, `loading-complete`) into
|
|
5
|
+
* `pie-stage-change` and `pie-loading-complete` on the host element. Both are
|
|
6
|
+
* dispatched with `CROSS_BOUNDARY_EVENT_INIT` (bubbling, composed), the init
|
|
7
|
+
* every other runtime event uses, so a listener above the layout element hears
|
|
8
|
+
* them as it hears `toolkit-ready` or `framework-error`.
|
|
12
9
|
*
|
|
13
|
-
* **Detail-shape contract.** The
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* `
|
|
17
|
-
*
|
|
18
|
-
* `
|
|
19
|
-
* `LoadingCompleteDetail` shapes verbatim. `runtimeId` and `sourceCe`
|
|
20
|
-
* are supplied at adapter construction time (one per engine instance);
|
|
21
|
-
* `timestamp` is captured per-emit via the injected `now()` clock so
|
|
22
|
-
* tests can pin a deterministic value.
|
|
10
|
+
* **Detail-shape contract.** The core emits structurally minimal outputs
|
|
11
|
+
* (`{ stage, status, cohort }`, `{ cohort, itemCount }`). The bridge enriches
|
|
12
|
+
* them with `runtimeId`, `sourceCe` and `timestamp` so the dispatched detail
|
|
13
|
+
* matches `StageChangeDetail` and `LoadingCompleteDetail` in
|
|
14
|
+
* `packages/players-shared/src/pie/stages.ts`. `runtimeId` and `sourceCe` are
|
|
15
|
+
* fixed per engine; `timestamp` comes from the injected `now()` clock.
|
|
23
16
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* function. The bridge is purely an output-to-DOM translator — it does
|
|
27
|
-
* not gate emissions, does not re-order, does not de-duplicate. That
|
|
28
|
-
* keeps the responsibility clean and matches the "outputs are already
|
|
29
|
-
* ordered correctly by the core" contract from
|
|
30
|
-
* `engine-transition.ts`.
|
|
31
|
-
*
|
|
32
|
-
* The bridge **must not** import `svelte`; per the M7 layering
|
|
33
|
-
* constraint the adapter is plain TS.
|
|
17
|
+
* The bridge only translates: ordering and once-per-cohort gating belong to
|
|
18
|
+
* the transition function. It must not import `svelte`.
|
|
34
19
|
*/
|
|
35
20
|
import type { SectionEngineOutput } from "../core/engine-output.js";
|
|
36
21
|
export interface DomEventBridgeOptions {
|
|
@@ -41,7 +26,7 @@ export interface DomEventBridgeOptions {
|
|
|
41
26
|
/**
|
|
42
27
|
* Tag name of the host CE without the `--version-<encoded>` suffix.
|
|
43
28
|
* Each layout CE that mounts the kernel passes its own canonical tag
|
|
44
|
-
* name
|
|
29
|
+
* name.
|
|
45
30
|
*/
|
|
46
31
|
sourceCe: string;
|
|
47
32
|
/**
|
|
@@ -1,37 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* DOM event bridge for the section runtime engine adapter
|
|
3
|
-
* C, layered).
|
|
2
|
+
* DOM event bridge for the section runtime engine adapter.
|
|
4
3
|
*
|
|
5
|
-
* Translates
|
|
6
|
-
* `
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* canonical event surface stays stable while the kernel migrates onto
|
|
11
|
-
* the engine in PR 5.
|
|
4
|
+
* Translates engine outputs (`stage-change`, `loading-complete`) into
|
|
5
|
+
* `pie-stage-change` and `pie-loading-complete` on the host element. Both are
|
|
6
|
+
* dispatched with `CROSS_BOUNDARY_EVENT_INIT` (bubbling, composed), the init
|
|
7
|
+
* every other runtime event uses, so a listener above the layout element hears
|
|
8
|
+
* them as it hears `toolkit-ready` or `framework-error`.
|
|
12
9
|
*
|
|
13
|
-
* **Detail-shape contract.** The
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* `
|
|
17
|
-
*
|
|
18
|
-
* `
|
|
19
|
-
* `LoadingCompleteDetail` shapes verbatim. `runtimeId` and `sourceCe`
|
|
20
|
-
* are supplied at adapter construction time (one per engine instance);
|
|
21
|
-
* `timestamp` is captured per-emit via the injected `now()` clock so
|
|
22
|
-
* tests can pin a deterministic value.
|
|
10
|
+
* **Detail-shape contract.** The core emits structurally minimal outputs
|
|
11
|
+
* (`{ stage, status, cohort }`, `{ cohort, itemCount }`). The bridge enriches
|
|
12
|
+
* them with `runtimeId`, `sourceCe` and `timestamp` so the dispatched detail
|
|
13
|
+
* matches `StageChangeDetail` and `LoadingCompleteDetail` in
|
|
14
|
+
* `packages/players-shared/src/pie/stages.ts`. `runtimeId` and `sourceCe` are
|
|
15
|
+
* fixed per engine; `timestamp` comes from the injected `now()` clock.
|
|
23
16
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* function. The bridge is purely an output-to-DOM translator — it does
|
|
27
|
-
* not gate emissions, does not re-order, does not de-duplicate. That
|
|
28
|
-
* keeps the responsibility clean and matches the "outputs are already
|
|
29
|
-
* ordered correctly by the core" contract from
|
|
30
|
-
* `engine-transition.ts`.
|
|
31
|
-
*
|
|
32
|
-
* The bridge **must not** import `svelte`; per the M7 layering
|
|
33
|
-
* constraint the adapter is plain TS.
|
|
17
|
+
* The bridge only translates: ordering and once-per-cohort gating belong to
|
|
18
|
+
* the transition function. It must not import `svelte`.
|
|
34
19
|
*/
|
|
20
|
+
import { dispatchCrossBoundaryEvent } from "../tool-host-contract.js";
|
|
35
21
|
export function createDomEventBridge(options) {
|
|
36
22
|
const { runtimeId, sourceCe } = options;
|
|
37
23
|
let host = options.host;
|
|
@@ -46,7 +32,7 @@ export function createDomEventBridge(options) {
|
|
|
46
32
|
timestamp: now(),
|
|
47
33
|
sourceCe,
|
|
48
34
|
};
|
|
49
|
-
host
|
|
35
|
+
dispatchCrossBoundaryEvent(host, "pie-stage-change", detail);
|
|
50
36
|
}
|
|
51
37
|
function dispatchLoadingComplete(output) {
|
|
52
38
|
const detail = {
|
|
@@ -54,20 +40,10 @@ export function createDomEventBridge(options) {
|
|
|
54
40
|
sectionId: output.cohort.sectionId,
|
|
55
41
|
attemptId: output.cohort.attemptId ? output.cohort.attemptId : undefined,
|
|
56
42
|
itemCount: output.itemCount,
|
|
57
|
-
loadedCount: output.loadedCount,
|
|
58
43
|
timestamp: now(),
|
|
59
44
|
sourceCe,
|
|
60
45
|
};
|
|
61
|
-
host
|
|
62
|
-
detail,
|
|
63
|
-
}));
|
|
64
|
-
}
|
|
65
|
-
function dispatchFrameworkError(output) {
|
|
66
|
-
// Mirror the kernel's existing surface — the `framework-error`
|
|
67
|
-
// DOM event detail is the framework-error model. The
|
|
68
|
-
// `framework-error-bridge` separately reports the same model
|
|
69
|
-
// into the bus so subscribers see one fan-out per error.
|
|
70
|
-
host.dispatchEvent(new CustomEvent("framework-error", { detail: output.error }));
|
|
46
|
+
dispatchCrossBoundaryEvent(host, "pie-loading-complete", detail);
|
|
71
47
|
}
|
|
72
48
|
function dispatch(output) {
|
|
73
49
|
switch (output.kind) {
|
|
@@ -77,9 +53,6 @@ export function createDomEventBridge(options) {
|
|
|
77
53
|
case "loading-complete":
|
|
78
54
|
dispatchLoadingComplete(output);
|
|
79
55
|
return;
|
|
80
|
-
case "framework-error":
|
|
81
|
-
dispatchFrameworkError(output);
|
|
82
|
-
return;
|
|
83
56
|
default: {
|
|
84
57
|
const exhaustive = output;
|
|
85
58
|
void exhaustive;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Subscriber fan-out for the section runtime engine adapter
|
|
3
|
-
* C, layered).
|
|
2
|
+
* Subscriber fan-out for the section runtime engine adapter.
|
|
4
3
|
*
|
|
5
4
|
* The adapter exposes a single `subscribe(listener)` channel for hosts
|
|
6
5
|
* that want a synchronous stream of `SectionEngineOutput[]` batches —
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Subscriber fan-out for the section runtime engine adapter
|
|
3
|
-
* C, layered).
|
|
2
|
+
* Subscriber fan-out for the section runtime engine adapter.
|
|
4
3
|
*
|
|
5
4
|
* The adapter exposes a single `subscribe(listener)` channel for hosts
|
|
6
5
|
* that want a synchronous stream of `SectionEngineOutput[]` batches —
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type AssessmentToolkitShellContext } from "../context/assessment-toolkit-context.js";
|
|
2
|
+
import type { CatalogLookupContext } from "../services/AccessibilityCatalogResolver.js";
|
|
3
|
+
/** Where a shell's owner registered its catalogs, from the toolkit runtime context. */
|
|
4
|
+
export interface CatalogRuntimeScope {
|
|
5
|
+
assessmentId?: string;
|
|
6
|
+
sectionId?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The catalog lookup context for content in `shell`: the cards its owner
|
|
10
|
+
* registered, then the assessment's.
|
|
11
|
+
*/
|
|
12
|
+
export declare const catalogContextForShell: (shell: AssessmentToolkitShellContext, runtime?: CatalogRuntimeScope | null) => CatalogLookupContext;
|
|
13
|
+
/**
|
|
14
|
+
* The catalog lookup context for the shell scope holding `node`, asked of that
|
|
15
|
+
* shell's context provider at the time of the call, or undefined outside every
|
|
16
|
+
* shell scope. For a tool that serves several shells and so has no shell
|
|
17
|
+
* context of its own, such as the section-wide annotation toolbar.
|
|
18
|
+
*/
|
|
19
|
+
export declare const catalogContextHolding: (node: Node, runtime?: CatalogRuntimeScope | null) => CatalogLookupContext | undefined;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { requestContext } from "@pie-players/pie-context";
|
|
2
|
+
import { assessmentToolkitShellContext, } from "../context/assessment-toolkit-context.js";
|
|
3
|
+
import { catalogOwnerContextFor } from "../services/catalog-owner.js";
|
|
4
|
+
import { composedParentElement } from "../services/tts/flat-tree.js";
|
|
5
|
+
/**
|
|
6
|
+
* The catalog lookup context for content in `shell`: the cards its owner
|
|
7
|
+
* registered, then the assessment's.
|
|
8
|
+
*/
|
|
9
|
+
export const catalogContextForShell = (shell, runtime) => catalogOwnerContextFor({
|
|
10
|
+
kind: shell.kind,
|
|
11
|
+
assessmentId: runtime?.assessmentId,
|
|
12
|
+
sectionId: runtime?.sectionId,
|
|
13
|
+
itemId: shell.itemId,
|
|
14
|
+
canonicalItemId: shell.canonicalItemId || shell.itemId,
|
|
15
|
+
});
|
|
16
|
+
/**
|
|
17
|
+
* The catalog lookup context for the shell scope holding `node`, asked of that
|
|
18
|
+
* shell's context provider at the time of the call, or undefined outside every
|
|
19
|
+
* shell scope. For a tool that serves several shells and so has no shell
|
|
20
|
+
* context of its own, such as the section-wide annotation toolbar.
|
|
21
|
+
*/
|
|
22
|
+
export const catalogContextHolding = (node, runtime) => {
|
|
23
|
+
const element = node.nodeType === 1 ? node : composedParentElement(node);
|
|
24
|
+
const shell = element
|
|
25
|
+
? requestContext(element, assessmentToolkitShellContext)
|
|
26
|
+
: undefined;
|
|
27
|
+
return shell ? catalogContextForShell(shell, runtime) : undefined;
|
|
28
|
+
};
|
|
@@ -1,23 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Composition emit scheduler
|
|
2
|
+
* Composition emit scheduler.
|
|
3
3
|
*
|
|
4
4
|
* `PieAssessmentToolkit.svelte` publishes the section composition to the
|
|
5
5
|
* players through exactly one path — the `composition-changed` event — and
|
|
6
6
|
* coalesces bursts of updates behind a one-shot latch so several changes
|
|
7
7
|
* within one frame produce a single emit.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* failure was in contexts with no compositor — headless browsers, hidden or
|
|
17
|
-
* offscreen tabs, agent and CI automation harnesses. A background tab only
|
|
18
|
-
* rendered late, because its pending frame becomes due on refocus.
|
|
19
|
-
*
|
|
20
|
-
* So the frame is raced against a deadline timer instead of trusted. Whichever
|
|
9
|
+
* The latch is released by a `requestAnimationFrame` callback raced against a
|
|
10
|
+
* deadline timer, because the existence of `window.requestAnimationFrame` does
|
|
11
|
+
* not mean it fires: in a document with no compositor (headless browsers,
|
|
12
|
+
* hidden or offscreen tabs, CI and agent harnesses) the callback never runs, so
|
|
13
|
+
* a frame-only latch would never clear and the player would keep its initial
|
|
14
|
+
* empty composition while the section controller held a correct view model. A
|
|
15
|
+
* background tab's pending frame only becomes due on refocus. Whichever
|
|
21
16
|
* arrives first releases the latch and flushes, and a non-painting document
|
|
22
17
|
* degrades to a slower render rather than a permanent blank. Svelte's own
|
|
23
18
|
* `tick()` races the same two primitives for the same reason.
|
|
@@ -34,8 +29,7 @@
|
|
|
34
29
|
*
|
|
35
30
|
* NOT a public surface: internal to the toolkit and not exported from
|
|
36
31
|
* `runtime/engine.ts`. It exists as its own module so the race can be pinned in
|
|
37
|
-
* a unit test without mounting the toolkit CE
|
|
38
|
-
* `runtime/stage-emit-gate.ts`.
|
|
32
|
+
* a unit test without mounting the toolkit CE.
|
|
39
33
|
*/
|
|
40
34
|
/**
|
|
41
35
|
* How long to wait for a frame before the timer takes over.
|
|
@@ -1,23 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Composition emit scheduler
|
|
2
|
+
* Composition emit scheduler.
|
|
3
3
|
*
|
|
4
4
|
* `PieAssessmentToolkit.svelte` publishes the section composition to the
|
|
5
5
|
* players through exactly one path — the `composition-changed` event — and
|
|
6
6
|
* coalesces bursts of updates behind a one-shot latch so several changes
|
|
7
7
|
* within one frame produce a single emit.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* failure was in contexts with no compositor — headless browsers, hidden or
|
|
17
|
-
* offscreen tabs, agent and CI automation harnesses. A background tab only
|
|
18
|
-
* rendered late, because its pending frame becomes due on refocus.
|
|
19
|
-
*
|
|
20
|
-
* So the frame is raced against a deadline timer instead of trusted. Whichever
|
|
9
|
+
* The latch is released by a `requestAnimationFrame` callback raced against a
|
|
10
|
+
* deadline timer, because the existence of `window.requestAnimationFrame` does
|
|
11
|
+
* not mean it fires: in a document with no compositor (headless browsers,
|
|
12
|
+
* hidden or offscreen tabs, CI and agent harnesses) the callback never runs, so
|
|
13
|
+
* a frame-only latch would never clear and the player would keep its initial
|
|
14
|
+
* empty composition while the section controller held a correct view model. A
|
|
15
|
+
* background tab's pending frame only becomes due on refocus. Whichever
|
|
21
16
|
* arrives first releases the latch and flushes, and a non-painting document
|
|
22
17
|
* degrades to a slower render rather than a permanent blank. Svelte's own
|
|
23
18
|
* `tick()` races the same two primitives for the same reason.
|
|
@@ -34,8 +29,7 @@
|
|
|
34
29
|
*
|
|
35
30
|
* NOT a public surface: internal to the toolkit and not exported from
|
|
36
31
|
* `runtime/engine.ts`. It exists as its own module so the race can be pinned in
|
|
37
|
-
* a unit test without mounting the toolkit CE
|
|
38
|
-
* `runtime/stage-emit-gate.ts`.
|
|
32
|
+
* a unit test without mounting the toolkit CE.
|
|
39
33
|
*/
|
|
40
34
|
/**
|
|
41
35
|
* How long to wait for a frame before the timer takes over.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** The content language when neither the markup nor the host names one. */
|
|
2
|
+
export declare const DEFAULT_CONTENT_LANGUAGE = "en-US";
|
|
3
|
+
/**
|
|
4
|
+
* The nearest non-empty `lang` attribute at or above `node`, climbing through
|
|
5
|
+
* shadow hosts, and ending after `boundary` when one is given.
|
|
6
|
+
*/
|
|
7
|
+
export declare const findLangAttribute: (node: Node | null | undefined, boundary?: Element | null) => string | undefined;
|
|
8
|
+
export interface ContentLanguageOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Where the `lang` climb ends, inclusive. Defaults to the nearest shell scope
|
|
11
|
+
* host above the target; with neither, markup names no language.
|
|
12
|
+
*/
|
|
13
|
+
boundary?: Element | null;
|
|
14
|
+
/** The host's `content-language` input. */
|
|
15
|
+
contentLanguage?: string | null;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The language the content at `target` is named as being in: the nearest `lang`
|
|
19
|
+
* between it and its shell scope host, else the host's `content-language` input.
|
|
20
|
+
* Undefined when neither names one.
|
|
21
|
+
*
|
|
22
|
+
* The climb stops at the shell because the page's own `lang` above it is the
|
|
23
|
+
* interface language, which the toolkit's `locale` carries; content language is
|
|
24
|
+
* the content's. Resolved at speak time, since a reading target's markup can
|
|
25
|
+
* change between reads.
|
|
26
|
+
*/
|
|
27
|
+
export declare const findContentLanguage: (target: Node | null | undefined, options?: ContentLanguageOptions) => string | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* {@link findContentLanguage}, else `en-US`: the language text processing and
|
|
30
|
+
* catalog lookup read.
|
|
31
|
+
*/
|
|
32
|
+
export declare const resolveContentLanguage: (target: Node | null | undefined, options?: ContentLanguageOptions) => string;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { composedParentElement } from "../services/tts/flat-tree.js";
|
|
2
|
+
import { findShellScopeHost } from "./content-region.js";
|
|
3
|
+
/** The content language when neither the markup nor the host names one. */
|
|
4
|
+
export const DEFAULT_CONTENT_LANGUAGE = "en-US";
|
|
5
|
+
/**
|
|
6
|
+
* The nearest non-empty `lang` attribute at or above `node`, climbing through
|
|
7
|
+
* shadow hosts, and ending after `boundary` when one is given.
|
|
8
|
+
*/
|
|
9
|
+
export const findLangAttribute = (node, boundary) => {
|
|
10
|
+
let current = !node
|
|
11
|
+
? null
|
|
12
|
+
: node.nodeType === 1
|
|
13
|
+
? node
|
|
14
|
+
: composedParentElement(node);
|
|
15
|
+
while (current) {
|
|
16
|
+
const lang = current.getAttribute("lang")?.trim();
|
|
17
|
+
if (lang)
|
|
18
|
+
return lang;
|
|
19
|
+
if (boundary && current === boundary)
|
|
20
|
+
return undefined;
|
|
21
|
+
current = composedParentElement(current);
|
|
22
|
+
}
|
|
23
|
+
return undefined;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* The language the content at `target` is named as being in: the nearest `lang`
|
|
27
|
+
* between it and its shell scope host, else the host's `content-language` input.
|
|
28
|
+
* Undefined when neither names one.
|
|
29
|
+
*
|
|
30
|
+
* The climb stops at the shell because the page's own `lang` above it is the
|
|
31
|
+
* interface language, which the toolkit's `locale` carries; content language is
|
|
32
|
+
* the content's. Resolved at speak time, since a reading target's markup can
|
|
33
|
+
* change between reads.
|
|
34
|
+
*/
|
|
35
|
+
export const findContentLanguage = (target, options = {}) => {
|
|
36
|
+
const boundary = options.boundary !== undefined
|
|
37
|
+
? options.boundary
|
|
38
|
+
: findShellScopeHost(target);
|
|
39
|
+
const fromMarkup = boundary ? findLangAttribute(target, boundary) : undefined;
|
|
40
|
+
return fromMarkup || options.contentLanguage?.trim() || undefined;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* {@link findContentLanguage}, else `en-US`: the language text processing and
|
|
44
|
+
* catalog lookup read.
|
|
45
|
+
*/
|
|
46
|
+
export const resolveContentLanguage = (target, options = {}) => findContentLanguage(target, options) ?? DEFAULT_CONTENT_LANGUAGE;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Marks the part of a shell scope that holds the content tools read and annotate. */
|
|
2
|
+
export declare const CONTENT_REGION_SELECTOR = "[data-region='content']";
|
|
3
|
+
/** Marks the host of a shell scope (`<pie-item-scope>`, `<pie-passage-shell>`). */
|
|
4
|
+
export declare const SHELL_SCOPE_HOST_SELECTOR = "[data-pie-shell-root]";
|
|
5
|
+
/**
|
|
6
|
+
* The content region of `scope` that tools read and annotate.
|
|
7
|
+
*
|
|
8
|
+
* With `target`, the region holding it: the nearest `data-region="content"`
|
|
9
|
+
* element from `target` up to `scope`, climbing through shadow hosts. Otherwise,
|
|
10
|
+
* or when `target` lies in none, `scope` itself when it is a content region,
|
|
11
|
+
* else its first content region, else `scope`, so a scope that marks no region
|
|
12
|
+
* is read whole. Resolved at each use, because a card renders its regions after
|
|
13
|
+
* its tools connect.
|
|
14
|
+
*/
|
|
15
|
+
export declare const resolveContentRegion: (scope: Element, target?: Node | null) => Element;
|
|
16
|
+
/** The nearest shell scope host at or above `node`, climbing through shadow hosts. */
|
|
17
|
+
export declare const findShellScopeHost: (node: Node | null | undefined) => Element | null;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { composedClosest, flatQuerySelector, } from "../services/tts/flat-tree.js";
|
|
2
|
+
/** Marks the part of a shell scope that holds the content tools read and annotate. */
|
|
3
|
+
export const CONTENT_REGION_SELECTOR = "[data-region='content']";
|
|
4
|
+
/** Marks the host of a shell scope (`<pie-item-scope>`, `<pie-passage-shell>`). */
|
|
5
|
+
export const SHELL_SCOPE_HOST_SELECTOR = "[data-pie-shell-root]";
|
|
6
|
+
/**
|
|
7
|
+
* The content region of `scope` that tools read and annotate.
|
|
8
|
+
*
|
|
9
|
+
* With `target`, the region holding it: the nearest `data-region="content"`
|
|
10
|
+
* element from `target` up to `scope`, climbing through shadow hosts. Otherwise,
|
|
11
|
+
* or when `target` lies in none, `scope` itself when it is a content region,
|
|
12
|
+
* else its first content region, else `scope`, so a scope that marks no region
|
|
13
|
+
* is read whole. Resolved at each use, because a card renders its regions after
|
|
14
|
+
* its tools connect.
|
|
15
|
+
*/
|
|
16
|
+
export const resolveContentRegion = (scope, target) => {
|
|
17
|
+
if (target) {
|
|
18
|
+
const holding = composedClosest(target, CONTENT_REGION_SELECTOR, scope);
|
|
19
|
+
if (holding)
|
|
20
|
+
return holding;
|
|
21
|
+
}
|
|
22
|
+
if (scope.matches?.(CONTENT_REGION_SELECTOR))
|
|
23
|
+
return scope;
|
|
24
|
+
return (scope.querySelector?.(CONTENT_REGION_SELECTOR) ??
|
|
25
|
+
flatQuerySelector(scope, CONTENT_REGION_SELECTOR) ??
|
|
26
|
+
scope);
|
|
27
|
+
};
|
|
28
|
+
/** The nearest shell scope host at or above `node`, climbing through shadow hosts. */
|
|
29
|
+
export const findShellScopeHost = (node) => node ? composedClosest(node, SHELL_SCOPE_HOST_SELECTOR) : null;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ToolkitCoordinatorApi } from "../services/interfaces.js";
|
|
2
|
+
import type { RuntimeRegistrationDetail } from "./registration-events.js";
|
|
3
|
+
/**
|
|
4
|
+
* What a content registration files with the coordinator: the content's
|
|
5
|
+
* accessibility catalogs, and an item's policy settings under its canonical
|
|
6
|
+
* id, the id its item-level toolbar scopes decisions by. Returns the cleanups
|
|
7
|
+
* that withdraw them, for the toolkit to run when the content unregisters or
|
|
8
|
+
* the coordinator changes.
|
|
9
|
+
*/
|
|
10
|
+
export declare function registerContentWithCoordinator(coordinator: Pick<ToolkitCoordinatorApi, "catalogResolver" | "registerItemSettings">, detail: RuntimeRegistrationDetail, owner: {
|
|
11
|
+
assessmentId: string;
|
|
12
|
+
sectionId: string;
|
|
13
|
+
}): Array<() => void>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a content registration files with the coordinator: the content's
|
|
3
|
+
* accessibility catalogs, and an item's policy settings under its canonical
|
|
4
|
+
* id, the id its item-level toolbar scopes decisions by. Returns the cleanups
|
|
5
|
+
* that withdraw them, for the toolkit to run when the content unregisters or
|
|
6
|
+
* the coordinator changes.
|
|
7
|
+
*/
|
|
8
|
+
export function registerContentWithCoordinator(coordinator, detail, owner) {
|
|
9
|
+
const cleanups = [
|
|
10
|
+
coordinator.catalogResolver.registerOwner({
|
|
11
|
+
owner: {
|
|
12
|
+
kind: detail.kind,
|
|
13
|
+
itemId: detail.itemId,
|
|
14
|
+
canonicalItemId: detail.canonicalItemId,
|
|
15
|
+
assessmentId: owner.assessmentId,
|
|
16
|
+
sectionId: owner.sectionId,
|
|
17
|
+
},
|
|
18
|
+
entity: detail.item,
|
|
19
|
+
}),
|
|
20
|
+
];
|
|
21
|
+
if (detail.kind === "item" && detail.settings) {
|
|
22
|
+
cleanups.push(coordinator.registerItemSettings(detail.canonicalItemId || detail.itemId, detail.settings));
|
|
23
|
+
}
|
|
24
|
+
return cleanups;
|
|
25
|
+
}
|