@pie-players/pie-players-shared 0.3.74 → 1.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -75
- package/dist/components/vendor/nds/README.md +4 -5
- package/dist/config/profile.d.ts +1 -1
- package/dist/config/profile.js +1 -1
- package/dist/i18n/index.d.ts +1 -1
- package/dist/i18n/index.js +1 -1
- package/dist/i18n/language-tags.d.ts +9 -1
- package/dist/i18n/language-tags.js +11 -1
- package/dist/i18n/messages/en-US.d.ts +33 -28
- package/dist/i18n/messages/en-US.js +34 -29
- package/dist/i18n/messages/nl-NL.d.ts +33 -28
- package/dist/i18n/messages/nl-NL.js +34 -29
- package/dist/i18n/provider.d.ts +14 -7
- package/dist/i18n/provider.js +26 -29
- package/dist/i18n/types.d.ts +4 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.js +0 -1
- package/dist/instrumentation/providers/BaseInstrumentationProvider.js +0 -14
- package/dist/loader-config.d.ts +0 -2
- package/dist/loader-config.js +0 -2
- package/dist/loaders/element-loader.js +13 -6
- package/dist/loaders/esm-adapter.d.ts +11 -0
- package/dist/loaders/esm-adapter.js +74 -45
- package/dist/loaders/iife-adapter.d.ts +3 -3
- package/dist/loaders/iife-adapter.js +36 -35
- package/dist/loaders/index.d.ts +4 -2
- package/dist/loaders/index.js +2 -1
- package/dist/loaders/mathjax-events.d.ts +22 -0
- package/dist/loaders/mathjax-events.js +65 -0
- package/dist/loaders/preloaded-registration.d.ts +18 -2
- package/dist/loaders/preloaded-registration.js +14 -2
- package/dist/media/index.d.ts +4 -6
- package/dist/media/index.js +6 -8
- package/dist/object/index.d.ts +8 -3
- package/dist/object/index.js +8 -6
- package/dist/pie/asset-handler.d.ts +0 -17
- package/dist/pie/asset-handler.js +1 -1
- package/dist/pie/authoring.js +5 -7
- package/dist/pie/elements-rendered.d.ts +23 -0
- package/dist/pie/elements-rendered.js +96 -0
- package/dist/pie/index.d.ts +4 -6
- package/dist/pie/index.js +4 -7
- package/dist/pie/initialization.d.ts +13 -14
- package/dist/pie/initialization.js +61 -75
- package/dist/pie/instrumentation-event-bridge.js +23 -1
- package/dist/pie/instrumentation-event-map.js +11 -18
- package/dist/pie/item-controller.js +4 -0
- package/dist/pie/item-session-contract.js +7 -9
- package/dist/pie/logger.d.ts +6 -0
- package/dist/pie/logger.js +10 -0
- package/dist/pie/math-assets.d.ts +48 -0
- package/dist/pie/math-assets.js +81 -0
- package/dist/pie/resource-monitor.d.ts +34 -32
- package/dist/pie/resource-monitor.js +152 -231
- package/dist/pie/scoring.d.ts +1 -6
- package/dist/pie/scoring.js +3 -8
- package/dist/pie/session-commit.js +1 -1
- package/dist/pie/stages.d.ts +11 -47
- package/dist/pie/stages.js +11 -47
- package/dist/pie/updates.js +5 -4
- package/dist/pie/utils.d.ts +0 -2
- package/dist/pie/utils.js +0 -2
- package/dist/security/sanitize-item-markup.d.ts +8 -4
- package/dist/security/sanitize-item-markup.js +52 -6
- package/dist/security/sanitize-svg-icon.js +2 -2
- package/dist/security/wrap-overwide-images.d.ts +1 -1
- package/dist/security/wrap-overwide-images.js +20 -1
- package/dist/security/wrap-overwide.d.ts +8 -0
- package/dist/security/wrap-overwide.js +47 -3
- package/dist/timed-media/media-element-source.js +1 -2
- package/dist/types/index.d.ts +88 -153
- package/dist/types/index.js +2 -2
- package/dist/ui/attribute-coercion.d.ts +5 -0
- package/dist/ui/attribute-coercion.js +6 -4
- package/dist/ui/content-styles.d.ts +6 -10
- package/dist/ui/content-styles.js +8 -13
- package/dist/ui/first-focusable.d.ts +0 -1
- package/dist/ui/first-focusable.js +0 -1
- package/dist/ui/focus-trap.js +2 -3
- package/dist/ui/scope-css.d.ts +23 -26
- package/dist/ui/scope-css.js +23 -26
- package/package.json +6 -4
- package/dist/loaders/mathjax-version-conflict.d.ts +0 -17
- package/dist/loaders/mathjax-version-conflict.js +0 -51
- package/dist/pie/stage-tracker.d.ts +0 -50
- package/dist/pie/stage-tracker.js +0 -105
package/dist/types/index.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* The PIE content and assessment model the players share: item, passage and
|
|
3
|
+
* section configs, the QTI-aligned assessment structure, session snapshots,
|
|
4
|
+
* accessibility catalogs and media references, `Env`, the element controller
|
|
5
|
+
* contract and authoring asset events.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* The `*Entity` shapes mirror content-store records and may be shallower than
|
|
8
|
+
* them. The module depends on nothing beyond this package's own type modules,
|
|
9
|
+
* so front-end and server code can both import it.
|
|
9
10
|
*/
|
|
10
11
|
import type { FormativeDeliveryPolicy, FormativeItemPolicy, FormativeSectionSlice } from "../formative/types.js";
|
|
11
12
|
import type { TimedMediaSectionData, TimedMediaSectionSessionSlice } from "../timed-media/types.js";
|
|
@@ -55,10 +56,12 @@ export interface ConfigEntity {
|
|
|
55
56
|
markup: string;
|
|
56
57
|
elements: ConfigElements;
|
|
57
58
|
models: PieModel[];
|
|
59
|
+
/** Configure settings for authoring mode. */
|
|
58
60
|
configuration?: Record<string, any>;
|
|
59
61
|
/**
|
|
60
62
|
* QTI 3.0: Extracted accessibility catalogs from embedded SSML.
|
|
61
|
-
*
|
|
63
|
+
* Written by SSMLExtractor when a host's preprocessing runs it over content
|
|
64
|
+
* holding <speak> tags; the players register what this carries.
|
|
62
65
|
*/
|
|
63
66
|
extractedCatalogs?: AccessibilityCatalog[];
|
|
64
67
|
[key: string]: any;
|
|
@@ -77,12 +80,9 @@ export interface PassageEntity extends VersionEntity, ConfigContainerEntity, Sea
|
|
|
77
80
|
export interface ItemEntity extends VersionEntity, ConfigContainerEntity, SearchMetaDataEntity {
|
|
78
81
|
name?: string;
|
|
79
82
|
/**
|
|
80
|
-
* `null` as well as absent, because importers write it
|
|
81
|
-
* `undefined`, so an item transformed from another format carries an
|
|
82
|
-
* `passage: null` for "no passage"
|
|
83
|
-
* null, so it expected it while the type denied it. Excluding null
|
|
84
|
-
* only meant a host feeding real importer output through a typed path had to
|
|
85
|
-
* cast it away.
|
|
83
|
+
* `null` as well as absent, because importers write it: JSON has no
|
|
84
|
+
* `undefined`, so an item transformed from another format carries an
|
|
85
|
+
* explicit `passage: null` for "no passage", and the runtime tests for it.
|
|
86
86
|
*/
|
|
87
87
|
passage?: string | PassageEntity | null;
|
|
88
88
|
/** QTI/APIP-style accessibility catalogs owned by the item root. */
|
|
@@ -92,6 +92,23 @@ export interface ItemEntity extends VersionEntity, ConfigContainerEntity, Search
|
|
|
92
92
|
configuration?: any;
|
|
93
93
|
highlights?: Record<string, string[]>;
|
|
94
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* `baseId` and `version` are optional on an entity a section references. They
|
|
97
|
+
* identify a stored version, which a host building a section from an item
|
|
98
|
+
* config does not have, and no player reads either.
|
|
99
|
+
*/
|
|
100
|
+
type WithOptionalVersion<T extends VersionEntity> = Omit<T, "baseId" | "version"> & Partial<Pick<VersionEntity, "baseId" | "version">>;
|
|
101
|
+
/**
|
|
102
|
+
* A passage as a section's item references it. `name` is optional on the same
|
|
103
|
+
* ground: the section player reads it only as a fallback for a missing `id`.
|
|
104
|
+
*/
|
|
105
|
+
export type ReferencedPassageEntity = Omit<WithOptionalVersion<PassageEntity>, "name"> & {
|
|
106
|
+
name?: string;
|
|
107
|
+
};
|
|
108
|
+
/** An item as `AssessmentItemRef.item` references it. */
|
|
109
|
+
export type ReferencedItemEntity = Omit<WithOptionalVersion<ItemEntity>, "passage"> & {
|
|
110
|
+
passage?: string | ReferencedPassageEntity | null;
|
|
111
|
+
};
|
|
95
112
|
/**
|
|
96
113
|
* Metadata specifically for interpretation by clients, typically containing
|
|
97
114
|
* options that are relevant for the user interface. This is not indexed for search.
|
|
@@ -146,7 +163,7 @@ export interface AssessmentItemRef extends SearchMetaDataEntity {
|
|
|
146
163
|
* Resolved item entity with PIE config.
|
|
147
164
|
* This is populated by the client before passing to the player.
|
|
148
165
|
*/
|
|
149
|
-
item?:
|
|
166
|
+
item?: ReferencedItemEntity;
|
|
150
167
|
/** Item-level settings for tool requirements and customization */
|
|
151
168
|
settings?: ItemSettings;
|
|
152
169
|
/**
|
|
@@ -182,14 +199,6 @@ export interface AssessmentSection extends SearchMetaDataEntity, SettingsMetaDat
|
|
|
182
199
|
*/
|
|
183
200
|
assessmentItemRefs?: AssessmentItemRef[];
|
|
184
201
|
rubricBlocks?: RubricBlock[];
|
|
185
|
-
/**
|
|
186
|
-
* QTI 3.0: Personal Needs Profile (PNP 3.0) for section-scoped delivery.
|
|
187
|
-
*
|
|
188
|
-
* Section players read this (falling back to `settings.personalNeedsProfile`,
|
|
189
|
-
* then to the computed default profile) to drive PNP policy when a section is
|
|
190
|
-
* delivered without an enclosing assessment.
|
|
191
|
-
*/
|
|
192
|
-
personalNeedsProfile?: PersonalNeedsProfile;
|
|
193
202
|
/**
|
|
194
203
|
* Formative delivery policy for this section: how many Tries a learner gets
|
|
195
204
|
* on each item, when feedback is revealed, and whether the behavior is on at
|
|
@@ -232,11 +241,9 @@ export interface TestPart {
|
|
|
232
241
|
* The host-facing persistence snapshot for one section, returned by
|
|
233
242
|
* `SectionControllerHandle.getSession()` and accepted by `applySession()`.
|
|
234
243
|
*
|
|
235
|
-
* Canonical here
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
* The delivery slices it carries are defined in this package too, which is what
|
|
239
|
-
* previously forced them to reference this shape in prose instead of types.
|
|
244
|
+
* Canonical here, beside `AssessmentSection`: both entry paths need it, and the
|
|
245
|
+
* toolkit complements a player and sits beneath both of them. The delivery
|
|
246
|
+
* slices it carries live in this package too, so they reference it as a type.
|
|
240
247
|
*/
|
|
241
248
|
export interface SectionControllerSessionState {
|
|
242
249
|
currentItemIndex?: number;
|
|
@@ -362,7 +369,7 @@ export interface MediaFragmentRange {
|
|
|
362
369
|
* inside `qti-card-entry` — multiple sources, MIME types, poster, and an
|
|
363
370
|
* optional time range.
|
|
364
371
|
*
|
|
365
|
-
*
|
|
372
|
+
* It carries no `kind` discriminant: the card's `catalog` field is QTI's
|
|
366
373
|
* `qti-card@support` and is the only discriminator. Restating it here would
|
|
367
374
|
* create a second source of truth that can disagree with the first.
|
|
368
375
|
*/
|
|
@@ -373,15 +380,12 @@ export interface SignLanguageCardPayload {
|
|
|
373
380
|
* signed alternate is LSM, not ASL, so this must never be inferred from the
|
|
374
381
|
* item or assessment content language.
|
|
375
382
|
*
|
|
376
|
-
* Optional
|
|
377
|
-
*
|
|
378
|
-
*
|
|
379
|
-
*
|
|
380
|
-
*
|
|
381
|
-
*
|
|
382
|
-
* where the two genuinely differ, which is a card tagged with the item's
|
|
383
|
-
* content language (`language: "en-US"`, `signLang: "ase"`) so that resolution
|
|
384
|
-
* reaches it by the default-language rung.
|
|
383
|
+
* Optional: when absent, the card's `language` stands in, so author it only
|
|
384
|
+
* where the two differ. The sign-language tool reads every signing card in
|
|
385
|
+
* the owner's scope and selects on this value: a card in the requested sign
|
|
386
|
+
* language wins, a card naming no language is the fallback, and a card in
|
|
387
|
+
* another sign language is never shown. It also names the language in the
|
|
388
|
+
* region's accessible label.
|
|
385
389
|
*/
|
|
386
390
|
signLang?: string;
|
|
387
391
|
media: MediaAssetRef;
|
|
@@ -392,8 +396,7 @@ export interface SignLanguageCardPayload {
|
|
|
392
396
|
*
|
|
393
397
|
* QTI 3 treats recorded audio and synthesized speech as the *same* support:
|
|
394
398
|
* both are `spoken`, and a card holds recorded audio through `qti-file-href`
|
|
395
|
-
* plus a MIME type.
|
|
396
|
-
* existing one can take.
|
|
399
|
+
* plus a MIME type. A recording is the other form that accommodation takes.
|
|
397
400
|
*
|
|
398
401
|
* A node commonly carries both this and a `content` card in the same language —
|
|
399
402
|
* APIP's pattern, which QTI's migration guidance keeps, because the script is
|
|
@@ -426,15 +429,13 @@ export type CatalogCardPayload = SignLanguageCardPayload | SpokenAudioCardPayloa
|
|
|
426
429
|
* one of `content` or `payload`.
|
|
427
430
|
*
|
|
428
431
|
* One generic `payload` slot, not a field per accommodation. This is the shape
|
|
429
|
-
* `pie-elements-ng`
|
|
430
|
-
*
|
|
431
|
-
*
|
|
432
|
-
*
|
|
433
|
-
*
|
|
434
|
-
*
|
|
435
|
-
*
|
|
436
|
-
* its signing video and simultaneously reported that the item had no signed
|
|
437
|
-
* alternate. Both producers now emit `payload` and the alias is gone.
|
|
432
|
+
* `pie-elements-ng` and the PIE API service's Learnosity importer restate
|
|
433
|
+
* structurally; all three read the same authored JSON and none of them takes a
|
|
434
|
+
* package dependency on the others, so keeping the declarations identical is
|
|
435
|
+
* the only thing holding interop together; a `signLanguage` input alias, folded
|
|
436
|
+
* in on the resolution path but not the enumeration path, once had an imported
|
|
437
|
+
* card render its signing video while reporting no signed alternate. Both
|
|
438
|
+
* producers now emit `payload`.
|
|
438
439
|
*/
|
|
439
440
|
export interface CatalogCard {
|
|
440
441
|
catalog: string;
|
|
@@ -466,15 +467,7 @@ export interface AccessibilityCatalog {
|
|
|
466
467
|
export interface PersonalNeedsProfile {
|
|
467
468
|
supports: string[];
|
|
468
469
|
prohibitedSupports?: string[];
|
|
469
|
-
activateAtInit?: string[];
|
|
470
470
|
}
|
|
471
|
-
/**
|
|
472
|
-
* QTI 3.0: Reference to a shared stimulus (passage).
|
|
473
|
-
* Maps to qti-assessment-stimulus-ref element.
|
|
474
|
-
*
|
|
475
|
-
* NOTE: Not currently used. We embed PassageEntity directly in RubricBlock instead.
|
|
476
|
-
* Kept for potential future use if we need to support external stimulus references.
|
|
477
|
-
*/
|
|
478
471
|
export interface AssessmentEntity extends BaseEntity, SearchMetaDataEntity {
|
|
479
472
|
name?: string;
|
|
480
473
|
title?: string;
|
|
@@ -494,117 +487,59 @@ export interface AssessmentEntity extends BaseEntity, SearchMetaDataEntity {
|
|
|
494
487
|
* QTI 3.0: testParts structure (authoritative for QTI format).
|
|
495
488
|
*/
|
|
496
489
|
testParts?: TestPart[];
|
|
497
|
-
/** QTI 3.0: Stimulus material references (Phase 3 - placeholder) */
|
|
498
|
-
stimulusRefs?: any[];
|
|
499
490
|
}
|
|
500
491
|
/**
|
|
501
|
-
*
|
|
502
|
-
*
|
|
503
|
-
* tool configurations, and theme settings while remaining extensible.
|
|
492
|
+
* Assessment settings the tool policy reads: district policy, test
|
|
493
|
+
* administration and per-tool parameters.
|
|
504
494
|
*/
|
|
505
495
|
export interface AssessmentSettings {
|
|
506
496
|
/** District/organization policies */
|
|
507
497
|
districtPolicy?: {
|
|
508
498
|
blockedTools?: string[];
|
|
509
499
|
requiredTools?: string[];
|
|
510
|
-
policies?: Record<string, any>;
|
|
511
500
|
};
|
|
512
501
|
/** Test administration configuration */
|
|
513
502
|
testAdministration?: {
|
|
514
|
-
mode?: "practice" | "test" | "benchmark";
|
|
515
|
-
toolOverrides?: Record<string, boolean>;
|
|
516
|
-
startDate?: string;
|
|
517
|
-
endDate?: string;
|
|
518
|
-
};
|
|
519
|
-
/** Tool-specific provider configurations */
|
|
520
|
-
toolConfigs?: {
|
|
521
|
-
calculator?: AssessmentCalculatorConfig;
|
|
522
503
|
/**
|
|
523
|
-
*
|
|
524
|
-
*
|
|
525
|
-
*
|
|
526
|
-
* and
|
|
527
|
-
*
|
|
528
|
-
* Provider-specific extensions should be placed in providerOptions.
|
|
529
|
-
*
|
|
530
|
-
* @see https://w3c.github.io/speech-api/
|
|
504
|
+
* Per-session override by tool id. `false` withdraws the tool and
|
|
505
|
+
* outranks every policy level except a district block. `true` grants it
|
|
506
|
+
* below a district block, an item's `restrictedTools` and the profile's
|
|
507
|
+
* `prohibitedSupports`, and above requirements and profile supports.
|
|
531
508
|
*/
|
|
532
|
-
|
|
533
|
-
/**
|
|
534
|
-
* TTS provider
|
|
535
|
-
*
|
|
536
|
-
* @standard "browser" uses W3C Web Speech API
|
|
537
|
-
* @extension "polly" and "custom" are provider-specific
|
|
538
|
-
*/
|
|
539
|
-
provider?: "browser" | "polly" | "custom";
|
|
540
|
-
/**
|
|
541
|
-
* Voice identifier (provider-specific names)
|
|
542
|
-
*
|
|
543
|
-
* @standard W3C Web Speech API (concept)
|
|
544
|
-
* @example "Joanna" (Polly), "en-US-Standard-A" (Google), browser voices
|
|
545
|
-
*/
|
|
546
|
-
voice?: string;
|
|
547
|
-
/**
|
|
548
|
-
* Speech rate (speed multiplier)
|
|
549
|
-
*
|
|
550
|
-
* @standard W3C Web Speech API
|
|
551
|
-
* @range 0.25 to 4.0
|
|
552
|
-
* @default 1.0
|
|
553
|
-
*/
|
|
554
|
-
rate?: number;
|
|
555
|
-
/**
|
|
556
|
-
* Pitch adjustment
|
|
557
|
-
*
|
|
558
|
-
* @standard W3C Web Speech API
|
|
559
|
-
* @range 0 to 2 (as multiplier)
|
|
560
|
-
* @default 1.0
|
|
561
|
-
*/
|
|
562
|
-
pitch?: number;
|
|
563
|
-
/**
|
|
564
|
-
* Speech Rule Engine options for generated MathML speech.
|
|
565
|
-
*
|
|
566
|
-
* `style` is passed to SRE directly; ClearSpeak combines multiple
|
|
567
|
-
* preferences with ":" (for example,
|
|
568
|
-
* "ImpliedTimes_MoreImpliedTimes:Paren_Silent").
|
|
569
|
-
*
|
|
570
|
-
* Mirrors assessment-toolkit's SREMathSpeechOptions without importing
|
|
571
|
-
* toolkit service types into the shared content contract package.
|
|
572
|
-
*/
|
|
573
|
-
mathSpeech?: {
|
|
574
|
-
domain?: string;
|
|
575
|
-
style?: string;
|
|
576
|
-
engineOptions?: Record<string, unknown>;
|
|
577
|
-
};
|
|
578
|
-
/**
|
|
579
|
-
* Provider-specific options (extensions)
|
|
580
|
-
*
|
|
581
|
-
* @extension Not portable across providers
|
|
582
|
-
* @example For AWS Polly: { engine: "neural", region: "us-east-1" }
|
|
583
|
-
* @example For Google Cloud: { audioEncoding: "MP3", effectsProfileId: ["headphone-class-device"] }
|
|
584
|
-
*/
|
|
585
|
-
providerOptions?: Record<string, any>;
|
|
586
|
-
};
|
|
587
|
-
[toolId: string]: any;
|
|
588
|
-
};
|
|
589
|
-
/** Theme configuration (not in PNP) */
|
|
590
|
-
themeConfig?: {
|
|
591
|
-
scheme?: "default" | "high-contrast" | "dark";
|
|
592
|
-
fontSize?: number;
|
|
593
|
-
fontFamily?: string;
|
|
594
|
-
lineHeight?: number;
|
|
595
|
-
reducedMotion?: boolean;
|
|
509
|
+
toolOverrides?: Record<string, boolean>;
|
|
596
510
|
};
|
|
597
|
-
/**
|
|
598
|
-
|
|
511
|
+
/**
|
|
512
|
+
* Parameters by tool id, handed to the tool wherever policy shows it; an
|
|
513
|
+
* item's `toolParameters` entry wins on that item's own toolbar. Provider
|
|
514
|
+
* configuration belongs in the toolkit's `tools.providers`.
|
|
515
|
+
*/
|
|
516
|
+
toolParameters?: ToolParameters;
|
|
599
517
|
}
|
|
600
518
|
/**
|
|
601
|
-
*
|
|
602
|
-
*
|
|
519
|
+
* Parameter shapes by tool id. A tool outside the stock set may add its own by
|
|
520
|
+
* declaration merging, with a type literal as the value.
|
|
521
|
+
*
|
|
522
|
+
* The values come from authored content, so a tool still checks what it reads.
|
|
603
523
|
*/
|
|
604
|
-
export interface
|
|
605
|
-
|
|
606
|
-
|
|
524
|
+
export interface ToolParameterMap {
|
|
525
|
+
calculator: {
|
|
526
|
+
type?: "basic" | "scientific" | "graphing";
|
|
527
|
+
};
|
|
528
|
+
answerEliminator: {
|
|
529
|
+
strategy?: "strikethrough" | "mask";
|
|
530
|
+
};
|
|
531
|
+
signLanguage: {
|
|
532
|
+
signLang?: string;
|
|
533
|
+
};
|
|
607
534
|
}
|
|
535
|
+
/** The parameter shape of tool `K`: its {@link ToolParameterMap} entry, else open. */
|
|
536
|
+
export type ToolParametersFor<K extends string> = K extends keyof ToolParameterMap ? ToolParameterMap[K] : Record<string, unknown>;
|
|
537
|
+
/** Parameters by tool id: typed for the ids {@link ToolParameterMap} names. */
|
|
538
|
+
export type ToolParameters = {
|
|
539
|
+
[K in keyof ToolParameterMap]?: ToolParameterMap[K];
|
|
540
|
+
} & {
|
|
541
|
+
[toolId: string]: Record<string, unknown> | undefined;
|
|
542
|
+
};
|
|
608
543
|
/**
|
|
609
544
|
* Item-level settings for tool requirements.
|
|
610
545
|
* Used in AssessmentItemRef.settings to specify item-specific tool needs.
|
|
@@ -612,8 +547,8 @@ export interface AssessmentCalculatorConfig {
|
|
|
612
547
|
export interface ItemSettings {
|
|
613
548
|
requiredTools?: string[];
|
|
614
549
|
restrictedTools?: string[];
|
|
615
|
-
toolParameters
|
|
616
|
-
|
|
550
|
+
/** Parameters by tool id; outranks the assessment's `toolParameters` entry. */
|
|
551
|
+
toolParameters?: ToolParameters;
|
|
617
552
|
}
|
|
618
553
|
export type PlayerMode = "gather" | "view" | "evaluate" | "author";
|
|
619
554
|
export type PlayerRole = "student" | "instructor";
|
|
@@ -711,8 +646,8 @@ export interface AdvancedItemConfig {
|
|
|
711
646
|
}
|
|
712
647
|
export type ItemConfig = PieContent | AdvancedItemConfig;
|
|
713
648
|
/**
|
|
714
|
-
*
|
|
715
|
-
*
|
|
649
|
+
* Appended to an element's tag name to register the bundle's editor component
|
|
650
|
+
* as a custom element of its own when PIE bundles load.
|
|
716
651
|
*/
|
|
717
652
|
export declare const editorPostFix = "-pie-editor--";
|
|
718
653
|
export type ModelUpdatedDetail = {
|
package/dist/types/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* Appended to an element's tag name to register the bundle's editor component
|
|
3
|
+
* as a custom element of its own when PIE bundles load.
|
|
4
4
|
*/
|
|
5
5
|
export const editorPostFix = "-pie-editor--";
|
|
6
6
|
export class ModelUpdatedEvent extends CustomEvent {
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads a boolean-like prop or attribute value. Nullish or blank reads as
|
|
3
|
+
* `defaultValue`; `false`, `0`, `off` and `no` (any case) read as false; any
|
|
4
|
+
* other value reads as true.
|
|
5
|
+
*/
|
|
1
6
|
export declare function coerceBooleanLike(value: boolean | string | null | undefined, defaultValue?: boolean): boolean;
|
|
2
7
|
/**
|
|
3
8
|
* Reads a boolean attribute value: present is true and absent is false, as in
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads a boolean-like prop or attribute value. Nullish or blank reads as
|
|
3
|
+
* `defaultValue`; `false`, `0`, `off` and `no` (any case) read as false; any
|
|
4
|
+
* other value reads as true.
|
|
5
|
+
*/
|
|
1
6
|
export function coerceBooleanLike(value, defaultValue = false) {
|
|
2
7
|
if (typeof value === "boolean") {
|
|
3
8
|
return value;
|
|
@@ -12,10 +17,7 @@ export function coerceBooleanLike(value, defaultValue = false) {
|
|
|
12
17
|
if (["false", "0", "off", "no"].includes(normalizedValue)) {
|
|
13
18
|
return false;
|
|
14
19
|
}
|
|
15
|
-
|
|
16
|
-
return true;
|
|
17
|
-
}
|
|
18
|
-
return Boolean(normalizedValue);
|
|
20
|
+
return true;
|
|
19
21
|
}
|
|
20
22
|
/**
|
|
21
23
|
* Reads a boolean attribute value: present is true and absent is false, as in
|
|
@@ -9,11 +9,9 @@
|
|
|
9
9
|
* light DOM, so those rules have to exist as a document-level stylesheet —
|
|
10
10
|
* there is no shadow root to scope them to.
|
|
11
11
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* hand days later. Players install the stylesheet themselves instead, which
|
|
16
|
-
* keeps the host contract at "import the player".
|
|
12
|
+
* Players install that stylesheet themselves, which keeps the host contract at
|
|
13
|
+
* "import the player"; a host-side import was unenforced and failed silently,
|
|
14
|
+
* as an unstyled passage.
|
|
17
15
|
*
|
|
18
16
|
* The CSS text is passed in rather than imported here: this package builds with
|
|
19
17
|
* plain `tsc`, so it cannot inline a stylesheet. Bundler-built player packages
|
|
@@ -58,11 +56,9 @@ export declare function contentStylesPresent(): boolean;
|
|
|
58
56
|
* hand — first in the entry, before app CSS — so an app rule and a content rule
|
|
59
57
|
* of equal specificity resolve in the host's favour, exactly as before.
|
|
60
58
|
*
|
|
61
|
-
* A cascade layer
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
* `.numbered-paragraph { margin-left: 36px }`. That trades a visible missing
|
|
65
|
-
* stylesheet for a subtler override bug, so ordinary specificity wins instead.
|
|
59
|
+
* A cascade layer would invert that: unlayered author declarations beat *all*
|
|
60
|
+
* layered ones regardless of specificity, so a host reset as broad as
|
|
61
|
+
* `p { margin: 0 }` would outrank `.numbered-paragraph { margin-left: 36px }`.
|
|
66
62
|
*
|
|
67
63
|
* @param cssText Contents of `@pie-players/pie-theme/components.css`.
|
|
68
64
|
* @param source Package installing the styles, for diagnostics.
|
|
@@ -9,11 +9,9 @@
|
|
|
9
9
|
* light DOM, so those rules have to exist as a document-level stylesheet —
|
|
10
10
|
* there is no shadow root to scope them to.
|
|
11
11
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* hand days later. Players install the stylesheet themselves instead, which
|
|
16
|
-
* keeps the host contract at "import the player".
|
|
12
|
+
* Players install that stylesheet themselves, which keeps the host contract at
|
|
13
|
+
* "import the player"; a host-side import was unenforced and failed silently,
|
|
14
|
+
* as an unstyled passage.
|
|
17
15
|
*
|
|
18
16
|
* The CSS text is passed in rather than imported here: this package builds with
|
|
19
17
|
* plain `tsc`, so it cannot inline a stylesheet. Bundler-built player packages
|
|
@@ -48,9 +46,8 @@ const declaresContentStylesSentinel = (rule) => {
|
|
|
48
46
|
// Grouping rules hold no declarations of their own, so the sentinel sits one
|
|
49
47
|
// or more levels down. A host that confines its copy — `@scope
|
|
50
48
|
// (.item-content) { … }`, `@layer pie-content { … }` — presents exactly one
|
|
51
|
-
// top-level rule with an empty `.style`,
|
|
52
|
-
// as "no copy here".
|
|
53
|
-
// configuration this module most needs to recognise.
|
|
49
|
+
// top-level rule with an empty `.style`, which a top-level-only scan reads
|
|
50
|
+
// as "no copy here".
|
|
54
51
|
const nested = rule.cssRules;
|
|
55
52
|
if (!nested)
|
|
56
53
|
return false;
|
|
@@ -115,11 +112,9 @@ export function contentStylesPresent() {
|
|
|
115
112
|
* hand — first in the entry, before app CSS — so an app rule and a content rule
|
|
116
113
|
* of equal specificity resolve in the host's favour, exactly as before.
|
|
117
114
|
*
|
|
118
|
-
* A cascade layer
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
* `.numbered-paragraph { margin-left: 36px }`. That trades a visible missing
|
|
122
|
-
* stylesheet for a subtler override bug, so ordinary specificity wins instead.
|
|
115
|
+
* A cascade layer would invert that: unlayered author declarations beat *all*
|
|
116
|
+
* layered ones regardless of specificity, so a host reset as broad as
|
|
117
|
+
* `p { margin: 0 }` would outrank `.numbered-paragraph { margin-left: 36px }`.
|
|
123
118
|
*
|
|
124
119
|
* @param cssText Contents of `@pie-players/pie-theme/components.css`.
|
|
125
120
|
* @param source Package installing the styles, for diagnostics.
|
package/dist/ui/focus-trap.js
CHANGED
|
@@ -57,9 +57,8 @@ export function createFocusTrap(container, options = {}) {
|
|
|
57
57
|
container.focus?.();
|
|
58
58
|
return;
|
|
59
59
|
}
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
: document);
|
|
60
|
+
const rootNode = container.getRootNode();
|
|
61
|
+
const current = getDeepActiveElement(rootNode instanceof ShadowRoot ? rootNode : document);
|
|
63
62
|
const currentIndex = focusable.indexOf(current || focusable[0]);
|
|
64
63
|
if (event.shiftKey) {
|
|
65
64
|
if (currentIndex <= 0) {
|
package/dist/ui/scope-css.d.ts
CHANGED
|
@@ -4,37 +4,34 @@
|
|
|
4
4
|
* external-style-urls="...">` or `itemConfig.resources.stylesheets[*].url`
|
|
5
5
|
* styles that player's subtree instead of the whole host document.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
7
|
+
* Walks the stylesheet brace-by-brace. Block at-rules that hold rules
|
|
8
|
+
* (`@media`, `@supports`, `@container`, `@layer`, `@scope`) keep their prelude
|
|
9
|
+
* and have their inner rules scoped, every other at-rule passes through, and a
|
|
10
|
+
* leading `:root`, `html` or `body` is replaced by the scope, since
|
|
11
|
+
* `.scope :root` can never match: `:root` is `<html>`, which is no descendant
|
|
12
|
+
* of the player. A regex prefixer fails on exactly these cases: it turned
|
|
13
|
+
* `@media screen { … }` into the invalid `.scope @media screen { … }`, which the
|
|
14
|
+
* browser drops with every rule inside, and corrupted `@font-face`,
|
|
15
|
+
* `@keyframes` and `:root` the same way.
|
|
15
16
|
*
|
|
16
|
-
* The QTI player's `scopeCssRules` (`pie-qti` -
|
|
17
|
-
* `packages/item-player/src/components/utils/stylesheetRender.ts`) is
|
|
18
|
-
* drop-in
|
|
19
|
-
*
|
|
20
|
-
* at
|
|
21
|
-
* rules are hoisted and applied unconditionally — a mobile-only rule then
|
|
22
|
-
* applies at every viewport width, which is a subtler failure than dropping it.
|
|
17
|
+
* The `:root` handling follows the QTI player's `scopeCssRules` (`pie-qti` -
|
|
18
|
+
* `packages/item-player/src/components/utils/stylesheetRender.ts`), which is no
|
|
19
|
+
* drop-in: it excludes `@` from its selector pattern without understanding
|
|
20
|
+
* at-rules, so `@media` and `@supports` lose their condition and their rules
|
|
21
|
+
* apply at every viewport width.
|
|
23
22
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* runs in the delivery path, and scoping needs to know about rule boundaries
|
|
28
|
-
* only — not about property grammar.
|
|
23
|
+
* No CSS parser: `@pie-players/pie-item-player` ships with two workspace
|
|
24
|
+
* dependencies, this runs in the delivery path, and scoping needs rule
|
|
25
|
+
* boundaries only.
|
|
29
26
|
*
|
|
30
|
-
* Known limits
|
|
27
|
+
* Known limits:
|
|
31
28
|
*
|
|
32
|
-
* - `@import` is passed through untouched
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
29
|
+
* - `@import` is passed through untouched. It pulls in an unscoped stylesheet,
|
|
30
|
+
* so it defeats scoping, but blocking it is a security policy decision and
|
|
31
|
+
* not this function's job. Callers gate stylesheet URLs with
|
|
32
|
+
* `validateExternalStyleUrl` before fetching.
|
|
36
33
|
* - Declaration blocks are emitted verbatim, so `url(...)` references are left
|
|
37
|
-
* as authored and resolve against the stylesheet's own URL
|
|
34
|
+
* as authored and resolve against the stylesheet's own URL.
|
|
38
35
|
* - A style rule's block is never rewritten, which is also what native CSS
|
|
39
36
|
* nesting needs: nested selectors are relative to a parent that has already
|
|
40
37
|
* been scoped.
|