@pie-players/pie-players-shared 1.0.0-beta.7 → 1.0.0-beta.8
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 +3 -1
- package/dist/i18n/catalogs.d.ts +20 -13
- package/dist/i18n/catalogs.js +22 -23
- package/dist/i18n/language-tags.d.ts +23 -6
- package/dist/i18n/language-tags.js +74 -9
- package/dist/i18n/messages/en-US.d.ts +17 -0
- package/dist/i18n/messages/en-US.js +19 -0
- package/dist/i18n/types.d.ts +6 -1
- package/dist/security/private-hosts.d.ts +27 -0
- package/dist/security/private-hosts.js +85 -0
- package/dist/tools/term-lookup.d.ts +15 -0
- package/dist/tools/term-lookup.js +16 -0
- package/dist/types/index.d.ts +16 -2
- package/dist/types/interchange.d.ts +66 -4
- package/dist/ui/fontawesome.d.ts +51 -0
- package/dist/ui/fontawesome.js +122 -0
- package/package.json +12 -3
- package/dist/i18n/messages/nl-NL.d.ts +0 -639
- package/dist/i18n/messages/nl-NL.js +0 -639
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* Interchange types: backends and authoring tools exchange them, and no player
|
|
3
|
+
* reads them. Their tier is listed on the content-model page.
|
|
4
4
|
*
|
|
5
|
+
* Language variants (PIE-1393): no player reads `AdaptationLink` or
|
|
6
|
+
* `LanguagePolicy`.
|
|
5
7
|
* A language variant is its own item or passage version that declares
|
|
6
8
|
* `language` and, when it is a translation, `isAdaptationOf`. Its family is
|
|
7
9
|
* `isAdaptationOf.baseId ?? baseId`.
|
|
@@ -40,8 +42,13 @@ export interface LanguagePolicy {
|
|
|
40
42
|
*/
|
|
41
43
|
staleness: "serve" | "require-current";
|
|
42
44
|
}
|
|
43
|
-
/**
|
|
44
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Why the served content differs from what was requested: `"fallback"`, not
|
|
47
|
+
* in a requested language; `"variety"`, in another variety of a requested
|
|
48
|
+
* language, such as `es-ES` for `es-MX`; `"stale"`, a translation of an older
|
|
49
|
+
* source release.
|
|
50
|
+
*/
|
|
51
|
+
export type ContentSubstitution = "fallback" | "stale" | "variety";
|
|
45
52
|
/** The content version a backend served, and the language it served it in. */
|
|
46
53
|
export interface ServedContentIdentity {
|
|
47
54
|
baseId: string;
|
|
@@ -52,3 +59,58 @@ export interface ServedContentIdentity {
|
|
|
52
59
|
servedLanguage?: string;
|
|
53
60
|
substitution?: ContentSubstitution;
|
|
54
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* One curriculum standard, skill or competency the content is aligned to
|
|
64
|
+
* (PIE-1381). QTI 3 Curriculum Standards Metadata (CSM 1.1), one entry per
|
|
65
|
+
* `labelledGUID`. Content records direct links only; a framework provider
|
|
66
|
+
* resolves parents, crosswalks and successors on read.
|
|
67
|
+
*/
|
|
68
|
+
export interface CurriculumStandard {
|
|
69
|
+
/**
|
|
70
|
+
* CSM `curriculumStandardsMetadata@providerId`: who issued `guid`, from the
|
|
71
|
+
* provider-id registry on the content-model page, or a host value. Absent
|
|
72
|
+
* means `"AB"` (Academic Benchmarks).
|
|
73
|
+
*/
|
|
74
|
+
providerId?: string;
|
|
75
|
+
/**
|
|
76
|
+
* CSM `labelledGUID/GUID`, as the provider issued it. Stored with its case
|
|
77
|
+
* and compared case-insensitively.
|
|
78
|
+
*/
|
|
79
|
+
guid: string;
|
|
80
|
+
/** CSM `labelledGUID/caseItemURI`, for a CASE framework item. */
|
|
81
|
+
caseItemURI?: string;
|
|
82
|
+
/** CSM `labelledGUID/label`: a display code. Never a key. */
|
|
83
|
+
label?: string;
|
|
84
|
+
/** LOM classification purpose. Absent means `"educational objective"`. */
|
|
85
|
+
purpose?: "educational objective" | "prerequisite" | (string & {});
|
|
86
|
+
/** The record's main standard for this provider. At most one per `providerId`. */
|
|
87
|
+
primary?: boolean;
|
|
88
|
+
/** How the link was made. */
|
|
89
|
+
provenance?: "authored" | "derived" | "imported";
|
|
90
|
+
/**
|
|
91
|
+
* For a derived link: the link it was generated from. An absent
|
|
92
|
+
* `providerId` means `"AB"`.
|
|
93
|
+
*/
|
|
94
|
+
derivedFrom?: {
|
|
95
|
+
providerId?: string;
|
|
96
|
+
guid: string;
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* A cognitive-complexity classification of the content (PIE-1381). LOM
|
|
101
|
+
* classification purpose "skill level".
|
|
102
|
+
*/
|
|
103
|
+
export interface SkillLevel {
|
|
104
|
+
/**
|
|
105
|
+
* LOM `taxonPath/source`: `"webb-dok"`, `"blooms-revised"`,
|
|
106
|
+
* `"blooms-original"`, or a host taxonomy.
|
|
107
|
+
*/
|
|
108
|
+
source: string;
|
|
109
|
+
/**
|
|
110
|
+
* LOM `taxon/id`: `"1"` to `"4"` for `webb-dok`; `"remember"` to `"create"`
|
|
111
|
+
* for `blooms-revised`.
|
|
112
|
+
*/
|
|
113
|
+
id: string;
|
|
114
|
+
/** PIE extension: the author's justification. */
|
|
115
|
+
rationale?: string;
|
|
116
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FontAwesome for `<nds-icon-button>`, which renders its glyph as
|
|
3
|
+
* `<i class="fa-light fa-${name}">` and ships no font of its own.
|
|
4
|
+
*
|
|
5
|
+
* FontAwesome comes from the host page when it links any FA stylesheet.
|
|
6
|
+
* Otherwise `ensureFontAwesome` adds FA Free from the ESM CDN the item player's
|
|
7
|
+
* `loaderOptions` name, jsDelivr by default. Pro is never fetched from here:
|
|
8
|
+
* ui.renaissance.com serves its font files to Renaissance origins only, so a
|
|
9
|
+
* host that licenses it links it itself, as section-demos does through its dev
|
|
10
|
+
* proxy.
|
|
11
|
+
*
|
|
12
|
+
* `fa-light` is a weight only Pro carries. Free has no `.fa-light` rule and its
|
|
13
|
+
* Regular font lacks most toolbar glyphs, so without Pro `applyNdsGlyphVariant`
|
|
14
|
+
* renders every glyph in Solid, the one Free weight that has them all.
|
|
15
|
+
*
|
|
16
|
+
* Roboto comes from the vendored button: its connectedCallback links
|
|
17
|
+
* ui.renaissance.com's Roboto unless the page links a stylesheet whose URL
|
|
18
|
+
* contains `Roboto`.
|
|
19
|
+
*/
|
|
20
|
+
export type NdsGlyphVariant = "fa-light" | "fa-regular" | "fa-solid";
|
|
21
|
+
/**
|
|
22
|
+
* Adds FA Free to `<head>` unless the page already links a FontAwesome
|
|
23
|
+
* stylesheet. Appending Free after a host's Pro would override Pro's
|
|
24
|
+
* `.fa-regular` / `.fa-solid` font-family rules page-wide.
|
|
25
|
+
*
|
|
26
|
+
* A stylesheet that fails to load stays in `<head>` marked
|
|
27
|
+
* `data-pie-load-failed`: no later call requests it again, and no shadow root
|
|
28
|
+
* copies it.
|
|
29
|
+
*/
|
|
30
|
+
export declare function ensureFontAwesome(loaderOptions: {
|
|
31
|
+
esmCdnUrl?: unknown;
|
|
32
|
+
esmCdnProvider?: unknown;
|
|
33
|
+
} | null | undefined): void;
|
|
34
|
+
/**
|
|
35
|
+
* Copies the page's FontAwesome `<link>`s into the shadow root `node` renders
|
|
36
|
+
* in, since `<head>` stylesheets do not cross a shadow boundary. Does nothing
|
|
37
|
+
* when `node` is in the document tree, and runs once per shadow root.
|
|
38
|
+
*
|
|
39
|
+
* A stylesheet still loading is copied once it loads, so the copy comes from
|
|
40
|
+
* the cache; one that fails is not copied, since every copy would request it
|
|
41
|
+
* again. Chromium gives a link a `sheet` even when its load fails, so a failed
|
|
42
|
+
* one is known by its mark.
|
|
43
|
+
*/
|
|
44
|
+
export declare function installFontAwesomeInShadow(node: Node): void;
|
|
45
|
+
/**
|
|
46
|
+
* Renders the `fa-light` glyphs inside `button` in `preferred` when the page
|
|
47
|
+
* links Pro, and in Solid otherwise. Re-applies whenever Lit renders or
|
|
48
|
+
* rewrites the icon's class; the class edit removes `fa-light`, so the
|
|
49
|
+
* callback it triggers is a no-op. Returns the observer's disconnect.
|
|
50
|
+
*/
|
|
51
|
+
export declare function applyNdsGlyphVariant(button: HTMLElement, preferred: NdsGlyphVariant): () => void;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FontAwesome for `<nds-icon-button>`, which renders its glyph as
|
|
3
|
+
* `<i class="fa-light fa-${name}">` and ships no font of its own.
|
|
4
|
+
*
|
|
5
|
+
* FontAwesome comes from the host page when it links any FA stylesheet.
|
|
6
|
+
* Otherwise `ensureFontAwesome` adds FA Free from the ESM CDN the item player's
|
|
7
|
+
* `loaderOptions` name, jsDelivr by default. Pro is never fetched from here:
|
|
8
|
+
* ui.renaissance.com serves its font files to Renaissance origins only, so a
|
|
9
|
+
* host that licenses it links it itself, as section-demos does through its dev
|
|
10
|
+
* proxy.
|
|
11
|
+
*
|
|
12
|
+
* `fa-light` is a weight only Pro carries. Free has no `.fa-light` rule and its
|
|
13
|
+
* Regular font lacks most toolbar glyphs, so without Pro `applyNdsGlyphVariant`
|
|
14
|
+
* renders every glyph in Solid, the one Free weight that has them all.
|
|
15
|
+
*
|
|
16
|
+
* Roboto comes from the vendored button: its connectedCallback links
|
|
17
|
+
* ui.renaissance.com's Roboto unless the page links a stylesheet whose URL
|
|
18
|
+
* contains `Roboto`.
|
|
19
|
+
*/
|
|
20
|
+
import { resolveEsmPackageFileUrl } from "../loaders/esm-adapter.js";
|
|
21
|
+
/** The one FA Free build the players add; `<package>@<version>/<path>`. */
|
|
22
|
+
const FONTAWESOME_FREE_FILE = "@fortawesome/fontawesome-free@6.5.2/css/all.min.css";
|
|
23
|
+
// Matches any FA stylesheet the host page links: `fontawesome.min.css`,
|
|
24
|
+
// `font-awesome.css`, a `/_fa-pro/` proxy, `fontawesome-free@…`.
|
|
25
|
+
const FA_HREF_PATTERN = /font.?awesome|fa-?pro/i;
|
|
26
|
+
const FA_FREE_HREF_PATTERN = /fontawesome-free/i;
|
|
27
|
+
const documentStylesheetLinks = () => Array.from(document.querySelectorAll('link[rel="stylesheet"][href]'));
|
|
28
|
+
const documentFontAwesomeLinks = () => documentStylesheetLinks().filter((link) => FA_HREF_PATTERN.test(link.href));
|
|
29
|
+
/** Whether the page links a FontAwesome build other than Free. */
|
|
30
|
+
const pageLinksFontAwesomePro = () => documentFontAwesomeLinks().some((link) => !FA_FREE_HREF_PATTERN.test(link.href));
|
|
31
|
+
/**
|
|
32
|
+
* Adds FA Free to `<head>` unless the page already links a FontAwesome
|
|
33
|
+
* stylesheet. Appending Free after a host's Pro would override Pro's
|
|
34
|
+
* `.fa-regular` / `.fa-solid` font-family rules page-wide.
|
|
35
|
+
*
|
|
36
|
+
* A stylesheet that fails to load stays in `<head>` marked
|
|
37
|
+
* `data-pie-load-failed`: no later call requests it again, and no shadow root
|
|
38
|
+
* copies it.
|
|
39
|
+
*/
|
|
40
|
+
export function ensureFontAwesome(loaderOptions) {
|
|
41
|
+
if (typeof document === "undefined")
|
|
42
|
+
return;
|
|
43
|
+
if (documentFontAwesomeLinks().length > 0)
|
|
44
|
+
return;
|
|
45
|
+
const href = resolveEsmPackageFileUrl(loaderOptions, FONTAWESOME_FREE_FILE);
|
|
46
|
+
const link = document.createElement("link");
|
|
47
|
+
link.rel = "stylesheet";
|
|
48
|
+
link.href = href;
|
|
49
|
+
link.addEventListener("error", () => {
|
|
50
|
+
link.dataset.pieLoadFailed = "";
|
|
51
|
+
}, { once: true });
|
|
52
|
+
document.head.appendChild(link);
|
|
53
|
+
}
|
|
54
|
+
const mirroredShadowRoots = new WeakSet();
|
|
55
|
+
/**
|
|
56
|
+
* Copies the page's FontAwesome `<link>`s into the shadow root `node` renders
|
|
57
|
+
* in, since `<head>` stylesheets do not cross a shadow boundary. Does nothing
|
|
58
|
+
* when `node` is in the document tree, and runs once per shadow root.
|
|
59
|
+
*
|
|
60
|
+
* A stylesheet still loading is copied once it loads, so the copy comes from
|
|
61
|
+
* the cache; one that fails is not copied, since every copy would request it
|
|
62
|
+
* again. Chromium gives a link a `sheet` even when its load fails, so a failed
|
|
63
|
+
* one is known by its mark.
|
|
64
|
+
*/
|
|
65
|
+
export function installFontAwesomeInShadow(node) {
|
|
66
|
+
const shadow = node.getRootNode();
|
|
67
|
+
if (!(shadow instanceof ShadowRoot) || mirroredShadowRoots.has(shadow)) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
mirroredShadowRoots.add(shadow);
|
|
71
|
+
const appendLink = (href) => {
|
|
72
|
+
const present = Array.from(shadow.querySelectorAll('link[rel="stylesheet"]')).some((link) => link.href === href);
|
|
73
|
+
if (!href || present)
|
|
74
|
+
return;
|
|
75
|
+
const link = document.createElement("link");
|
|
76
|
+
link.rel = "stylesheet";
|
|
77
|
+
link.href = href;
|
|
78
|
+
shadow.appendChild(link);
|
|
79
|
+
};
|
|
80
|
+
for (const link of documentFontAwesomeLinks()) {
|
|
81
|
+
if ("pieLoadFailed" in link.dataset)
|
|
82
|
+
continue;
|
|
83
|
+
if (link.sheet) {
|
|
84
|
+
appendLink(link.href);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const settle = (event) => {
|
|
88
|
+
link.removeEventListener("load", settle);
|
|
89
|
+
link.removeEventListener("error", settle);
|
|
90
|
+
if (event.type === "load")
|
|
91
|
+
appendLink(link.href);
|
|
92
|
+
};
|
|
93
|
+
link.addEventListener("load", settle);
|
|
94
|
+
link.addEventListener("error", settle);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Renders the `fa-light` glyphs inside `button` in `preferred` when the page
|
|
99
|
+
* links Pro, and in Solid otherwise. Re-applies whenever Lit renders or
|
|
100
|
+
* rewrites the icon's class; the class edit removes `fa-light`, so the
|
|
101
|
+
* callback it triggers is a no-op. Returns the observer's disconnect.
|
|
102
|
+
*/
|
|
103
|
+
export function applyNdsGlyphVariant(button, preferred) {
|
|
104
|
+
const variant = pageLinksFontAwesomePro() ? preferred : "fa-solid";
|
|
105
|
+
if (variant === "fa-light")
|
|
106
|
+
return () => { };
|
|
107
|
+
const apply = () => {
|
|
108
|
+
for (const icon of button.querySelectorAll("i.fa-light")) {
|
|
109
|
+
icon.classList.remove("fa-light");
|
|
110
|
+
icon.classList.add(variant);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
apply();
|
|
114
|
+
const observer = new MutationObserver(apply);
|
|
115
|
+
observer.observe(button, {
|
|
116
|
+
childList: true,
|
|
117
|
+
subtree: true,
|
|
118
|
+
attributes: true,
|
|
119
|
+
attributeFilter: ["class"],
|
|
120
|
+
});
|
|
121
|
+
return () => observer.disconnect();
|
|
122
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pie-players/pie-players-shared",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.8",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Shared runtime + UI utilities for PIE players",
|
|
6
6
|
"license": "MIT",
|
|
@@ -29,6 +29,10 @@
|
|
|
29
29
|
"types": "./dist/security/index.d.ts",
|
|
30
30
|
"import": "./dist/security/index.js"
|
|
31
31
|
},
|
|
32
|
+
"./security/private-hosts": {
|
|
33
|
+
"types": "./dist/security/private-hosts.d.ts",
|
|
34
|
+
"import": "./dist/security/private-hosts.js"
|
|
35
|
+
},
|
|
32
36
|
"./object": {
|
|
33
37
|
"types": "./dist/object/index.d.ts",
|
|
34
38
|
"import": "./dist/object/index.js"
|
|
@@ -97,6 +101,10 @@
|
|
|
97
101
|
"types": "./dist/ui/content-styles.d.ts",
|
|
98
102
|
"import": "./dist/ui/content-styles.js"
|
|
99
103
|
},
|
|
104
|
+
"./ui/fontawesome": {
|
|
105
|
+
"types": "./dist/ui/fontawesome.d.ts",
|
|
106
|
+
"import": "./dist/ui/fontawesome.js"
|
|
107
|
+
},
|
|
100
108
|
"./tools/term-lookup": {
|
|
101
109
|
"types": "./dist/tools/term-lookup.d.ts",
|
|
102
110
|
"import": "./dist/tools/term-lookup.js"
|
|
@@ -109,6 +117,7 @@
|
|
|
109
117
|
"@pie-element/shared-utils": "0.1.6",
|
|
110
118
|
"@pie-lib/math-rendering-module": "6.0.0",
|
|
111
119
|
"dompurify": "^3.4.17",
|
|
120
|
+
"ipaddr.js": "^2.5.0",
|
|
112
121
|
"semver": "^7.8.5"
|
|
113
122
|
},
|
|
114
123
|
"scripts": {
|
|
@@ -122,7 +131,7 @@
|
|
|
122
131
|
"scan-hardcoded": "bun run src/i18n/scripts/scan-hardcoded.ts"
|
|
123
132
|
},
|
|
124
133
|
"devDependencies": {
|
|
125
|
-
"@biomejs/biome": "^2.6.
|
|
134
|
+
"@biomejs/biome": "^2.6.4",
|
|
126
135
|
"@happy-dom/global-registrator": "^21.0.4",
|
|
127
136
|
"@pie-element/shared-math-rendering-mathjax": "0.1.8",
|
|
128
137
|
"@playwright/test": "^1.64.1",
|
|
@@ -130,7 +139,7 @@
|
|
|
130
139
|
"es-module-shims": "^2.8.4",
|
|
131
140
|
"esbuild": "^0.28.2",
|
|
132
141
|
"glob": "^13.0.0",
|
|
133
|
-
"svelte": "^5.57.
|
|
142
|
+
"svelte": "^5.57.3",
|
|
134
143
|
"svelte-check": "^4.7.6",
|
|
135
144
|
"typescript": "^5.9.3"
|
|
136
145
|
},
|