@patch-adams/core 1.5.23 → 1.6.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/dist/cli.cjs +140 -1
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +140 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +224 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +88 -1
- package/dist/index.d.ts +88 -1
- package/dist/index.js +222 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -564,6 +564,53 @@ interface CourseMetadata {
|
|
|
564
564
|
*/
|
|
565
565
|
declare function extractCourseMetadata(zip: AdmZip, format: string): CourseMetadata;
|
|
566
566
|
|
|
567
|
+
/**
|
|
568
|
+
* Parsed course structure types for Rise SCORM packages.
|
|
569
|
+
* Used by the parse-structure API and the frontend tree view.
|
|
570
|
+
*/
|
|
571
|
+
/** A single block within a Rise lesson */
|
|
572
|
+
interface CourseStructureBlock {
|
|
573
|
+
/** Rise block ID (e.g. "cmk2wzn2p007q3b7hsiobz031") */
|
|
574
|
+
id: string;
|
|
575
|
+
/** Block type: "text", "image", "interactive", "knowledgeCheck", etc. */
|
|
576
|
+
type: string;
|
|
577
|
+
/** Block family: "text", "media", "interactive", etc. */
|
|
578
|
+
family?: string;
|
|
579
|
+
/** Block variant: "paragraph", "accordion", "hero", etc. */
|
|
580
|
+
variant?: string;
|
|
581
|
+
/** Human-readable title derived from block content or type label */
|
|
582
|
+
title?: string;
|
|
583
|
+
}
|
|
584
|
+
/** A lesson (section) in a Rise course */
|
|
585
|
+
interface CourseStructureLesson {
|
|
586
|
+
/** Rise lesson ID */
|
|
587
|
+
id: string;
|
|
588
|
+
/** Lesson title */
|
|
589
|
+
title: string;
|
|
590
|
+
/** Lesson type (e.g. "blocks") */
|
|
591
|
+
type: string;
|
|
592
|
+
/** Blocks within this lesson */
|
|
593
|
+
blocks: CourseStructureBlock[];
|
|
594
|
+
}
|
|
595
|
+
/** Parsed course structure returned by extractCourseStructure() */
|
|
596
|
+
interface CourseStructure {
|
|
597
|
+
/** Course title */
|
|
598
|
+
courseTitle: string;
|
|
599
|
+
/** Course identifier from manifest */
|
|
600
|
+
courseId?: string;
|
|
601
|
+
/** Lessons in the course */
|
|
602
|
+
lessons: CourseStructureLesson[];
|
|
603
|
+
}
|
|
604
|
+
/** User-assigned class mappings at course, lesson, and block levels */
|
|
605
|
+
interface CourseClassMappings {
|
|
606
|
+
/** Space-separated class names for the <html> element (course level) */
|
|
607
|
+
course?: string;
|
|
608
|
+
/** Lesson ID -> space-separated class names */
|
|
609
|
+
lessons?: Record<string, string>;
|
|
610
|
+
/** Block ID -> space-separated class names */
|
|
611
|
+
blocks?: Record<string, string>;
|
|
612
|
+
}
|
|
613
|
+
|
|
567
614
|
/**
|
|
568
615
|
* Base configuration for any plugin
|
|
569
616
|
*/
|
|
@@ -880,6 +927,8 @@ interface PatchOptions {
|
|
|
880
927
|
skin?: string;
|
|
881
928
|
/** Original package filename — baked into LRS bridge for statement searchability */
|
|
882
929
|
packageName?: string;
|
|
930
|
+
/** Custom CSS class mappings for course, lesson, and block levels */
|
|
931
|
+
classMappings?: CourseClassMappings;
|
|
883
932
|
}
|
|
884
933
|
/**
|
|
885
934
|
* Main Patcher class for patching e-learning course packages
|
|
@@ -1113,6 +1162,31 @@ declare function generateJsAfterLoader(options: JsAfterOptions): string;
|
|
|
1113
1162
|
*/
|
|
1114
1163
|
declare function buildJsAfterOptions(config: PatchAdamsConfig): JsAfterOptions;
|
|
1115
1164
|
|
|
1165
|
+
/**
|
|
1166
|
+
* Class Mappings Template
|
|
1167
|
+
*
|
|
1168
|
+
* Generates an inline JavaScript snippet that applies user-defined CSS classes
|
|
1169
|
+
* to course, lesson, and block elements at runtime.
|
|
1170
|
+
*
|
|
1171
|
+
* Timing: This script is injected inline (via plugin assets) so it executes
|
|
1172
|
+
* synchronously BEFORE the pa-loading class is removed. The user never sees
|
|
1173
|
+
* an un-styled flash — classes are applied while content is still hidden.
|
|
1174
|
+
*
|
|
1175
|
+
* - Course classes: added to <html> element immediately
|
|
1176
|
+
* - Block classes: added to [data-block-id] elements via MutationObserver
|
|
1177
|
+
* - Lesson classes: toggled on <html> via hashchange (Rise SPA routing)
|
|
1178
|
+
*/
|
|
1179
|
+
|
|
1180
|
+
/**
|
|
1181
|
+
* Check if class mappings contain any actual assignments
|
|
1182
|
+
*/
|
|
1183
|
+
declare function hasClassMappings(mappings?: CourseClassMappings): boolean;
|
|
1184
|
+
/**
|
|
1185
|
+
* Generate an inline JavaScript snippet that applies class mappings at runtime.
|
|
1186
|
+
* Returns an empty string if there are no mappings to apply.
|
|
1187
|
+
*/
|
|
1188
|
+
declare function generateClassMappingsScript(mappings: CourseClassMappings): string;
|
|
1189
|
+
|
|
1116
1190
|
type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent';
|
|
1117
1191
|
/**
|
|
1118
1192
|
* Simple logger utility for Patch-Adams
|
|
@@ -1129,6 +1203,19 @@ declare class Logger {
|
|
|
1129
1203
|
setLevel(level: LogLevel): void;
|
|
1130
1204
|
}
|
|
1131
1205
|
|
|
1206
|
+
/**
|
|
1207
|
+
* Rise Course Structure Parser
|
|
1208
|
+
*
|
|
1209
|
+
* Extracts the hierarchical course structure (lessons + blocks) from a
|
|
1210
|
+
* Rise SCORM ZIP package by parsing the embedded base64-encoded course JSON.
|
|
1211
|
+
*/
|
|
1212
|
+
|
|
1213
|
+
/**
|
|
1214
|
+
* Extract course structure from a Rise SCORM ZIP buffer.
|
|
1215
|
+
* Returns null if the ZIP is not a Rise package or parsing fails.
|
|
1216
|
+
*/
|
|
1217
|
+
declare function extractCourseStructure(zipBuffer: Buffer): CourseStructure | null;
|
|
1218
|
+
|
|
1132
1219
|
/**
|
|
1133
1220
|
* Plugin Registry for Patch-Adams
|
|
1134
1221
|
*
|
|
@@ -1198,4 +1285,4 @@ declare class PluginRegistry {
|
|
|
1198
1285
|
*/
|
|
1199
1286
|
declare const pluginRegistry: PluginRegistry;
|
|
1200
1287
|
|
|
1201
|
-
export { type AsyncAssetConfig, AsyncAssetConfigSchema, type AuthoringTool, AuthoringToolDetector, type AuthoringToolInfo, type BlockingAssetConfig, BlockingAssetConfigSchema, type CourseFingerprint, type CourseMetadata, type CssAfterOptions, type CssBeforeOptions, DEFAULT_LRS_OPTIONS, FormatDetector, type GeneratedPluginAssets, HtmlInjector, type JsAfterOptions, type JsBeforeOptions, type LocalFoldersConfig, LocalFoldersConfigSchema, type LogLevel, Logger, type LrsBridgeConfig, LrsBridgeConfigSchema, type LrsBridgeOptions, type ManifestPaths, ManifestUpdater, type PackageFormat, type PatchAdamsConfig, PatchAdamsConfigSchema, type PatchAdamsPlugin, type PatchOptions, type PatchResult, Patcher, type PluginAssets, type PluginConfig, PluginRegistry, type PluginsConfig, StorylineHtmlInjector, buildCssAfterOptions, buildCssBeforeOptions, buildJsAfterOptions, buildJsBeforeOptions, defaultConfig, extractCourseFingerprint, extractCourseMetadata, generateConfigTemplate, generateCssAfterLoader, generateCssBeforeLoader, generateJsAfterLoader, generateJsBeforeLoader, generateLrsBridgeCode, loadConfig, mergeWithDefaults, pluginRegistry };
|
|
1288
|
+
export { type AsyncAssetConfig, AsyncAssetConfigSchema, type AuthoringTool, AuthoringToolDetector, type AuthoringToolInfo, type BlockingAssetConfig, BlockingAssetConfigSchema, type CourseClassMappings, type CourseFingerprint, type CourseMetadata, type CourseStructure, type CourseStructureBlock, type CourseStructureLesson, type CssAfterOptions, type CssBeforeOptions, DEFAULT_LRS_OPTIONS, FormatDetector, type GeneratedPluginAssets, HtmlInjector, type JsAfterOptions, type JsBeforeOptions, type LocalFoldersConfig, LocalFoldersConfigSchema, type LogLevel, Logger, type LrsBridgeConfig, LrsBridgeConfigSchema, type LrsBridgeOptions, type ManifestPaths, ManifestUpdater, type PackageFormat, type PatchAdamsConfig, PatchAdamsConfigSchema, type PatchAdamsPlugin, type PatchOptions, type PatchResult, Patcher, type PluginAssets, type PluginConfig, PluginRegistry, type PluginsConfig, StorylineHtmlInjector, buildCssAfterOptions, buildCssBeforeOptions, buildJsAfterOptions, buildJsBeforeOptions, defaultConfig, extractCourseFingerprint, extractCourseMetadata, extractCourseStructure, generateClassMappingsScript, generateConfigTemplate, generateCssAfterLoader, generateCssBeforeLoader, generateJsAfterLoader, generateJsBeforeLoader, generateLrsBridgeCode, hasClassMappings, loadConfig, mergeWithDefaults, pluginRegistry };
|
package/dist/index.d.ts
CHANGED
|
@@ -564,6 +564,53 @@ interface CourseMetadata {
|
|
|
564
564
|
*/
|
|
565
565
|
declare function extractCourseMetadata(zip: AdmZip, format: string): CourseMetadata;
|
|
566
566
|
|
|
567
|
+
/**
|
|
568
|
+
* Parsed course structure types for Rise SCORM packages.
|
|
569
|
+
* Used by the parse-structure API and the frontend tree view.
|
|
570
|
+
*/
|
|
571
|
+
/** A single block within a Rise lesson */
|
|
572
|
+
interface CourseStructureBlock {
|
|
573
|
+
/** Rise block ID (e.g. "cmk2wzn2p007q3b7hsiobz031") */
|
|
574
|
+
id: string;
|
|
575
|
+
/** Block type: "text", "image", "interactive", "knowledgeCheck", etc. */
|
|
576
|
+
type: string;
|
|
577
|
+
/** Block family: "text", "media", "interactive", etc. */
|
|
578
|
+
family?: string;
|
|
579
|
+
/** Block variant: "paragraph", "accordion", "hero", etc. */
|
|
580
|
+
variant?: string;
|
|
581
|
+
/** Human-readable title derived from block content or type label */
|
|
582
|
+
title?: string;
|
|
583
|
+
}
|
|
584
|
+
/** A lesson (section) in a Rise course */
|
|
585
|
+
interface CourseStructureLesson {
|
|
586
|
+
/** Rise lesson ID */
|
|
587
|
+
id: string;
|
|
588
|
+
/** Lesson title */
|
|
589
|
+
title: string;
|
|
590
|
+
/** Lesson type (e.g. "blocks") */
|
|
591
|
+
type: string;
|
|
592
|
+
/** Blocks within this lesson */
|
|
593
|
+
blocks: CourseStructureBlock[];
|
|
594
|
+
}
|
|
595
|
+
/** Parsed course structure returned by extractCourseStructure() */
|
|
596
|
+
interface CourseStructure {
|
|
597
|
+
/** Course title */
|
|
598
|
+
courseTitle: string;
|
|
599
|
+
/** Course identifier from manifest */
|
|
600
|
+
courseId?: string;
|
|
601
|
+
/** Lessons in the course */
|
|
602
|
+
lessons: CourseStructureLesson[];
|
|
603
|
+
}
|
|
604
|
+
/** User-assigned class mappings at course, lesson, and block levels */
|
|
605
|
+
interface CourseClassMappings {
|
|
606
|
+
/** Space-separated class names for the <html> element (course level) */
|
|
607
|
+
course?: string;
|
|
608
|
+
/** Lesson ID -> space-separated class names */
|
|
609
|
+
lessons?: Record<string, string>;
|
|
610
|
+
/** Block ID -> space-separated class names */
|
|
611
|
+
blocks?: Record<string, string>;
|
|
612
|
+
}
|
|
613
|
+
|
|
567
614
|
/**
|
|
568
615
|
* Base configuration for any plugin
|
|
569
616
|
*/
|
|
@@ -880,6 +927,8 @@ interface PatchOptions {
|
|
|
880
927
|
skin?: string;
|
|
881
928
|
/** Original package filename — baked into LRS bridge for statement searchability */
|
|
882
929
|
packageName?: string;
|
|
930
|
+
/** Custom CSS class mappings for course, lesson, and block levels */
|
|
931
|
+
classMappings?: CourseClassMappings;
|
|
883
932
|
}
|
|
884
933
|
/**
|
|
885
934
|
* Main Patcher class for patching e-learning course packages
|
|
@@ -1113,6 +1162,31 @@ declare function generateJsAfterLoader(options: JsAfterOptions): string;
|
|
|
1113
1162
|
*/
|
|
1114
1163
|
declare function buildJsAfterOptions(config: PatchAdamsConfig): JsAfterOptions;
|
|
1115
1164
|
|
|
1165
|
+
/**
|
|
1166
|
+
* Class Mappings Template
|
|
1167
|
+
*
|
|
1168
|
+
* Generates an inline JavaScript snippet that applies user-defined CSS classes
|
|
1169
|
+
* to course, lesson, and block elements at runtime.
|
|
1170
|
+
*
|
|
1171
|
+
* Timing: This script is injected inline (via plugin assets) so it executes
|
|
1172
|
+
* synchronously BEFORE the pa-loading class is removed. The user never sees
|
|
1173
|
+
* an un-styled flash — classes are applied while content is still hidden.
|
|
1174
|
+
*
|
|
1175
|
+
* - Course classes: added to <html> element immediately
|
|
1176
|
+
* - Block classes: added to [data-block-id] elements via MutationObserver
|
|
1177
|
+
* - Lesson classes: toggled on <html> via hashchange (Rise SPA routing)
|
|
1178
|
+
*/
|
|
1179
|
+
|
|
1180
|
+
/**
|
|
1181
|
+
* Check if class mappings contain any actual assignments
|
|
1182
|
+
*/
|
|
1183
|
+
declare function hasClassMappings(mappings?: CourseClassMappings): boolean;
|
|
1184
|
+
/**
|
|
1185
|
+
* Generate an inline JavaScript snippet that applies class mappings at runtime.
|
|
1186
|
+
* Returns an empty string if there are no mappings to apply.
|
|
1187
|
+
*/
|
|
1188
|
+
declare function generateClassMappingsScript(mappings: CourseClassMappings): string;
|
|
1189
|
+
|
|
1116
1190
|
type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent';
|
|
1117
1191
|
/**
|
|
1118
1192
|
* Simple logger utility for Patch-Adams
|
|
@@ -1129,6 +1203,19 @@ declare class Logger {
|
|
|
1129
1203
|
setLevel(level: LogLevel): void;
|
|
1130
1204
|
}
|
|
1131
1205
|
|
|
1206
|
+
/**
|
|
1207
|
+
* Rise Course Structure Parser
|
|
1208
|
+
*
|
|
1209
|
+
* Extracts the hierarchical course structure (lessons + blocks) from a
|
|
1210
|
+
* Rise SCORM ZIP package by parsing the embedded base64-encoded course JSON.
|
|
1211
|
+
*/
|
|
1212
|
+
|
|
1213
|
+
/**
|
|
1214
|
+
* Extract course structure from a Rise SCORM ZIP buffer.
|
|
1215
|
+
* Returns null if the ZIP is not a Rise package or parsing fails.
|
|
1216
|
+
*/
|
|
1217
|
+
declare function extractCourseStructure(zipBuffer: Buffer): CourseStructure | null;
|
|
1218
|
+
|
|
1132
1219
|
/**
|
|
1133
1220
|
* Plugin Registry for Patch-Adams
|
|
1134
1221
|
*
|
|
@@ -1198,4 +1285,4 @@ declare class PluginRegistry {
|
|
|
1198
1285
|
*/
|
|
1199
1286
|
declare const pluginRegistry: PluginRegistry;
|
|
1200
1287
|
|
|
1201
|
-
export { type AsyncAssetConfig, AsyncAssetConfigSchema, type AuthoringTool, AuthoringToolDetector, type AuthoringToolInfo, type BlockingAssetConfig, BlockingAssetConfigSchema, type CourseFingerprint, type CourseMetadata, type CssAfterOptions, type CssBeforeOptions, DEFAULT_LRS_OPTIONS, FormatDetector, type GeneratedPluginAssets, HtmlInjector, type JsAfterOptions, type JsBeforeOptions, type LocalFoldersConfig, LocalFoldersConfigSchema, type LogLevel, Logger, type LrsBridgeConfig, LrsBridgeConfigSchema, type LrsBridgeOptions, type ManifestPaths, ManifestUpdater, type PackageFormat, type PatchAdamsConfig, PatchAdamsConfigSchema, type PatchAdamsPlugin, type PatchOptions, type PatchResult, Patcher, type PluginAssets, type PluginConfig, PluginRegistry, type PluginsConfig, StorylineHtmlInjector, buildCssAfterOptions, buildCssBeforeOptions, buildJsAfterOptions, buildJsBeforeOptions, defaultConfig, extractCourseFingerprint, extractCourseMetadata, generateConfigTemplate, generateCssAfterLoader, generateCssBeforeLoader, generateJsAfterLoader, generateJsBeforeLoader, generateLrsBridgeCode, loadConfig, mergeWithDefaults, pluginRegistry };
|
|
1288
|
+
export { type AsyncAssetConfig, AsyncAssetConfigSchema, type AuthoringTool, AuthoringToolDetector, type AuthoringToolInfo, type BlockingAssetConfig, BlockingAssetConfigSchema, type CourseClassMappings, type CourseFingerprint, type CourseMetadata, type CourseStructure, type CourseStructureBlock, type CourseStructureLesson, type CssAfterOptions, type CssBeforeOptions, DEFAULT_LRS_OPTIONS, FormatDetector, type GeneratedPluginAssets, HtmlInjector, type JsAfterOptions, type JsBeforeOptions, type LocalFoldersConfig, LocalFoldersConfigSchema, type LogLevel, Logger, type LrsBridgeConfig, LrsBridgeConfigSchema, type LrsBridgeOptions, type ManifestPaths, ManifestUpdater, type PackageFormat, type PatchAdamsConfig, PatchAdamsConfigSchema, type PatchAdamsPlugin, type PatchOptions, type PatchResult, Patcher, type PluginAssets, type PluginConfig, PluginRegistry, type PluginsConfig, StorylineHtmlInjector, buildCssAfterOptions, buildCssBeforeOptions, buildJsAfterOptions, buildJsBeforeOptions, defaultConfig, extractCourseFingerprint, extractCourseMetadata, extractCourseStructure, generateClassMappingsScript, generateConfigTemplate, generateCssAfterLoader, generateCssBeforeLoader, generateJsAfterLoader, generateJsBeforeLoader, generateLrsBridgeCode, hasClassMappings, loadConfig, mergeWithDefaults, pluginRegistry };
|
package/dist/index.js
CHANGED
|
@@ -5306,7 +5306,6 @@ window.pa_patcher = window.pa_patcher || {
|
|
|
5306
5306
|
try {
|
|
5307
5307
|
var xhr = new XMLHttpRequest();
|
|
5308
5308
|
xhr.open('GET', ASSET_VERSION_URL, false);
|
|
5309
|
-
xhr.timeout = 2000;
|
|
5310
5309
|
xhr.send();
|
|
5311
5310
|
if (xhr.status === 200) {
|
|
5312
5311
|
window.__pa_v = JSON.parse(xhr.responseText).v || '1';
|
|
@@ -5688,6 +5687,139 @@ function buildSkinJsOptions(config) {
|
|
|
5688
5687
|
};
|
|
5689
5688
|
}
|
|
5690
5689
|
|
|
5690
|
+
// src/templates/class-mappings.ts
|
|
5691
|
+
function hasClassMappings(mappings) {
|
|
5692
|
+
if (!mappings) return false;
|
|
5693
|
+
if (mappings.course?.trim()) return true;
|
|
5694
|
+
if (mappings.lessons && Object.values(mappings.lessons).some((v) => v?.trim())) return true;
|
|
5695
|
+
if (mappings.blocks && Object.values(mappings.blocks).some((v) => v?.trim())) return true;
|
|
5696
|
+
return false;
|
|
5697
|
+
}
|
|
5698
|
+
function generateClassMappingsScript(mappings) {
|
|
5699
|
+
if (!hasClassMappings(mappings)) return "";
|
|
5700
|
+
const courseClasses = (mappings.course || "").trim();
|
|
5701
|
+
const blockMap = {};
|
|
5702
|
+
const lessonMap = {};
|
|
5703
|
+
if (mappings.blocks) {
|
|
5704
|
+
for (const [id, classes] of Object.entries(mappings.blocks)) {
|
|
5705
|
+
const trimmed = classes?.trim();
|
|
5706
|
+
if (trimmed) blockMap[id] = trimmed;
|
|
5707
|
+
}
|
|
5708
|
+
}
|
|
5709
|
+
if (mappings.lessons) {
|
|
5710
|
+
for (const [id, classes] of Object.entries(mappings.lessons)) {
|
|
5711
|
+
const trimmed = classes?.trim();
|
|
5712
|
+
if (trimmed) lessonMap[id] = trimmed;
|
|
5713
|
+
}
|
|
5714
|
+
}
|
|
5715
|
+
const hasBlocks = Object.keys(blockMap).length > 0;
|
|
5716
|
+
const hasLessons = Object.keys(lessonMap).length > 0;
|
|
5717
|
+
const parts = [];
|
|
5718
|
+
parts.push(`// PA-Patcher: Custom Class Mappings`);
|
|
5719
|
+
parts.push(`(function() {`);
|
|
5720
|
+
parts.push(` 'use strict';`);
|
|
5721
|
+
parts.push(``);
|
|
5722
|
+
if (courseClasses) {
|
|
5723
|
+
parts.push(` // Course-level classes (applied to <html>)`);
|
|
5724
|
+
parts.push(` var courseClasses = ${JSON.stringify(courseClasses)};`);
|
|
5725
|
+
parts.push(` courseClasses.split(' ').forEach(function(cls) {`);
|
|
5726
|
+
parts.push(` if (cls) document.documentElement.classList.add(cls);`);
|
|
5727
|
+
parts.push(` });`);
|
|
5728
|
+
parts.push(``);
|
|
5729
|
+
}
|
|
5730
|
+
if (hasBlocks) {
|
|
5731
|
+
parts.push(` // Block-level classes (applied to [data-block-id] elements)`);
|
|
5732
|
+
parts.push(` var blockMap = ${JSON.stringify(blockMap)};`);
|
|
5733
|
+
parts.push(``);
|
|
5734
|
+
parts.push(` function applyBlockClasses() {`);
|
|
5735
|
+
parts.push(` var ids = Object.keys(blockMap);`);
|
|
5736
|
+
parts.push(` for (var i = 0; i < ids.length; i++) {`);
|
|
5737
|
+
parts.push(` var el = document.querySelector('[data-block-id="' + ids[i] + '"]');`);
|
|
5738
|
+
parts.push(` if (el) {`);
|
|
5739
|
+
parts.push(` var classes = blockMap[ids[i]].split(' ');`);
|
|
5740
|
+
parts.push(` for (var j = 0; j < classes.length; j++) {`);
|
|
5741
|
+
parts.push(` if (classes[j]) el.classList.add(classes[j]);`);
|
|
5742
|
+
parts.push(` }`);
|
|
5743
|
+
parts.push(` }`);
|
|
5744
|
+
parts.push(` }`);
|
|
5745
|
+
parts.push(` }`);
|
|
5746
|
+
parts.push(``);
|
|
5747
|
+
}
|
|
5748
|
+
if (hasLessons) {
|
|
5749
|
+
parts.push(` // Lesson-level classes (toggled on <html> via hash navigation)`);
|
|
5750
|
+
parts.push(` var lessonMap = ${JSON.stringify(lessonMap)};`);
|
|
5751
|
+
parts.push(` var allLessonClasses = [];`);
|
|
5752
|
+
parts.push(` Object.keys(lessonMap).forEach(function(id) {`);
|
|
5753
|
+
parts.push(` lessonMap[id].split(' ').forEach(function(cls) {`);
|
|
5754
|
+
parts.push(` if (cls && allLessonClasses.indexOf(cls) === -1) allLessonClasses.push(cls);`);
|
|
5755
|
+
parts.push(` });`);
|
|
5756
|
+
parts.push(` });`);
|
|
5757
|
+
parts.push(``);
|
|
5758
|
+
parts.push(` var currentLessonId = null;`);
|
|
5759
|
+
parts.push(``);
|
|
5760
|
+
parts.push(` function detectCurrentLesson() {`);
|
|
5761
|
+
parts.push(` var hash = window.location.hash || '';`);
|
|
5762
|
+
parts.push(` var match = hash.match(/#\\/lessons\\/([^/]+)/);`);
|
|
5763
|
+
parts.push(` return match ? match[1] : null;`);
|
|
5764
|
+
parts.push(` }`);
|
|
5765
|
+
parts.push(``);
|
|
5766
|
+
parts.push(` function applyLessonClasses() {`);
|
|
5767
|
+
parts.push(` var lessonId = detectCurrentLesson();`);
|
|
5768
|
+
parts.push(` if (lessonId === currentLessonId) return;`);
|
|
5769
|
+
parts.push(` currentLessonId = lessonId;`);
|
|
5770
|
+
parts.push(` for (var i = 0; i < allLessonClasses.length; i++) {`);
|
|
5771
|
+
parts.push(` document.documentElement.classList.remove(allLessonClasses[i]);`);
|
|
5772
|
+
parts.push(` }`);
|
|
5773
|
+
parts.push(` if (lessonId && lessonMap[lessonId]) {`);
|
|
5774
|
+
parts.push(` var classes = lessonMap[lessonId].split(' ');`);
|
|
5775
|
+
parts.push(` for (var j = 0; j < classes.length; j++) {`);
|
|
5776
|
+
parts.push(` if (classes[j]) document.documentElement.classList.add(classes[j]);`);
|
|
5777
|
+
parts.push(` }`);
|
|
5778
|
+
parts.push(` }`);
|
|
5779
|
+
parts.push(` }`);
|
|
5780
|
+
parts.push(``);
|
|
5781
|
+
}
|
|
5782
|
+
parts.push(` // Initialization`);
|
|
5783
|
+
parts.push(` function init() {`);
|
|
5784
|
+
if (hasBlocks) {
|
|
5785
|
+
parts.push(` applyBlockClasses();`);
|
|
5786
|
+
}
|
|
5787
|
+
if (hasLessons) {
|
|
5788
|
+
parts.push(` applyLessonClasses();`);
|
|
5789
|
+
parts.push(``);
|
|
5790
|
+
parts.push(` // Watch for Rise SPA navigation`);
|
|
5791
|
+
parts.push(` window.addEventListener('hashchange', function() {`);
|
|
5792
|
+
parts.push(` applyLessonClasses();`);
|
|
5793
|
+
if (hasBlocks) {
|
|
5794
|
+
parts.push(` setTimeout(applyBlockClasses, 200);`);
|
|
5795
|
+
}
|
|
5796
|
+
parts.push(` });`);
|
|
5797
|
+
}
|
|
5798
|
+
if (hasBlocks) {
|
|
5799
|
+
parts.push(``);
|
|
5800
|
+
parts.push(` // MutationObserver for lazily-rendered Rise blocks`);
|
|
5801
|
+
parts.push(` var observer = new MutationObserver(function(mutations) {`);
|
|
5802
|
+
parts.push(` for (var i = 0; i < mutations.length; i++) {`);
|
|
5803
|
+
parts.push(` if (mutations[i].addedNodes.length > 0) {`);
|
|
5804
|
+
parts.push(` applyBlockClasses();`);
|
|
5805
|
+
parts.push(` return;`);
|
|
5806
|
+
parts.push(` }`);
|
|
5807
|
+
parts.push(` }`);
|
|
5808
|
+
parts.push(` });`);
|
|
5809
|
+
parts.push(` var container = document.querySelector('#app') || document.body;`);
|
|
5810
|
+
parts.push(` observer.observe(container, { childList: true, subtree: true });`);
|
|
5811
|
+
}
|
|
5812
|
+
parts.push(` }`);
|
|
5813
|
+
parts.push(``);
|
|
5814
|
+
parts.push(` if (document.readyState === 'loading') {`);
|
|
5815
|
+
parts.push(` document.addEventListener('DOMContentLoaded', init);`);
|
|
5816
|
+
parts.push(` } else {`);
|
|
5817
|
+
parts.push(` init();`);
|
|
5818
|
+
parts.push(` }`);
|
|
5819
|
+
parts.push(`})();`);
|
|
5820
|
+
return parts.join("\n");
|
|
5821
|
+
}
|
|
5822
|
+
|
|
5691
5823
|
// src/patcher/html-injector.ts
|
|
5692
5824
|
var HtmlInjector = class {
|
|
5693
5825
|
config;
|
|
@@ -7078,6 +7210,13 @@ var Patcher = class {
|
|
|
7078
7210
|
console.log(`[Patcher] Fetched ${fetchedCount} remote files`);
|
|
7079
7211
|
}
|
|
7080
7212
|
const pluginAssets = this.generatePluginAssets();
|
|
7213
|
+
if (hasClassMappings(options.classMappings)) {
|
|
7214
|
+
const classMappingsJs = generateClassMappingsScript(options.classMappings);
|
|
7215
|
+
if (classMappingsJs) {
|
|
7216
|
+
pluginAssets.jsAfter = classMappingsJs + (pluginAssets.jsAfter ? "\n" + pluginAssets.jsAfter : "");
|
|
7217
|
+
console.log("[Patcher] Class mappings JS will be injected inline into HTML");
|
|
7218
|
+
}
|
|
7219
|
+
}
|
|
7081
7220
|
const hasPluginAssets = pluginAssets.cssBefore || pluginAssets.cssAfter || pluginAssets.jsBefore || pluginAssets.jsAfter;
|
|
7082
7221
|
if (hasPluginAssets) {
|
|
7083
7222
|
htmlInjector.setPluginAssets(pluginAssets);
|
|
@@ -7437,7 +7576,88 @@ var Logger = class {
|
|
|
7437
7576
|
this.level = level;
|
|
7438
7577
|
}
|
|
7439
7578
|
};
|
|
7579
|
+
var DESERIALIZE_REGEX = /deserialize\s*\(\s*["']([A-Za-z0-9+/=]+)["']\s*\)/;
|
|
7580
|
+
var RISE_HTML_PATHS = [
|
|
7581
|
+
"scormcontent/index.html",
|
|
7582
|
+
"index.html"
|
|
7583
|
+
];
|
|
7584
|
+
function extractCourseStructure(zipBuffer) {
|
|
7585
|
+
try {
|
|
7586
|
+
const zip = new AdmZip(zipBuffer);
|
|
7587
|
+
let htmlContent = null;
|
|
7588
|
+
for (const path of RISE_HTML_PATHS) {
|
|
7589
|
+
const entry = zip.getEntry(path);
|
|
7590
|
+
if (entry) {
|
|
7591
|
+
htmlContent = entry.getData().toString("utf-8");
|
|
7592
|
+
if (DESERIALIZE_REGEX.test(htmlContent)) break;
|
|
7593
|
+
htmlContent = null;
|
|
7594
|
+
}
|
|
7595
|
+
}
|
|
7596
|
+
if (!htmlContent) {
|
|
7597
|
+
return null;
|
|
7598
|
+
}
|
|
7599
|
+
const match = htmlContent.match(DESERIALIZE_REGEX);
|
|
7600
|
+
if (!match || !match[1]) {
|
|
7601
|
+
return null;
|
|
7602
|
+
}
|
|
7603
|
+
const jsonStr = Buffer.from(match[1], "base64").toString("utf-8");
|
|
7604
|
+
const data = JSON.parse(jsonStr);
|
|
7605
|
+
const course = data.course;
|
|
7606
|
+
if (!course || !Array.isArray(course.lessons)) {
|
|
7607
|
+
return null;
|
|
7608
|
+
}
|
|
7609
|
+
const lessons = course.lessons.filter((lesson) => !lesson.deleted).sort((a, b) => (a.position ?? 0) - (b.position ?? 0)).map((lesson) => {
|
|
7610
|
+
const blocks = (lesson.items || []).map((block) => {
|
|
7611
|
+
const structBlock = {
|
|
7612
|
+
id: block.id,
|
|
7613
|
+
type: block.type || "unknown"
|
|
7614
|
+
};
|
|
7615
|
+
if (block.family) structBlock.family = block.family;
|
|
7616
|
+
if (block.variant) structBlock.variant = block.variant;
|
|
7617
|
+
const title = deriveBlockTitle(block);
|
|
7618
|
+
if (title) structBlock.title = title;
|
|
7619
|
+
return structBlock;
|
|
7620
|
+
});
|
|
7621
|
+
return {
|
|
7622
|
+
id: lesson.id,
|
|
7623
|
+
title: lesson.title || "Untitled Lesson",
|
|
7624
|
+
type: lesson.type || "blocks",
|
|
7625
|
+
blocks
|
|
7626
|
+
};
|
|
7627
|
+
});
|
|
7628
|
+
return {
|
|
7629
|
+
courseTitle: course.title || course.name || "Untitled Course",
|
|
7630
|
+
courseId: course.id || void 0,
|
|
7631
|
+
lessons
|
|
7632
|
+
};
|
|
7633
|
+
} catch {
|
|
7634
|
+
return null;
|
|
7635
|
+
}
|
|
7636
|
+
}
|
|
7637
|
+
function deriveBlockTitle(block) {
|
|
7638
|
+
if (block.title && typeof block.title === "string") {
|
|
7639
|
+
return stripHtml(block.title).substring(0, 80);
|
|
7640
|
+
}
|
|
7641
|
+
const items = block.items;
|
|
7642
|
+
if (!Array.isArray(items) || items.length === 0) return void 0;
|
|
7643
|
+
const firstItem = items[0];
|
|
7644
|
+
if (!firstItem) return void 0;
|
|
7645
|
+
if (firstItem.heading) {
|
|
7646
|
+
return stripHtml(firstItem.heading).substring(0, 80);
|
|
7647
|
+
}
|
|
7648
|
+
if (firstItem.title && typeof firstItem.title === "string") {
|
|
7649
|
+
return stripHtml(firstItem.title).substring(0, 80);
|
|
7650
|
+
}
|
|
7651
|
+
if (firstItem.paragraph) {
|
|
7652
|
+
const text = stripHtml(firstItem.paragraph).substring(0, 60);
|
|
7653
|
+
if (text) return text + (firstItem.paragraph.length > 60 ? "..." : "");
|
|
7654
|
+
}
|
|
7655
|
+
return void 0;
|
|
7656
|
+
}
|
|
7657
|
+
function stripHtml(html) {
|
|
7658
|
+
return html.replace(/<[^>]*>/g, "").trim();
|
|
7659
|
+
}
|
|
7440
7660
|
|
|
7441
|
-
export { AsyncAssetConfigSchema, AuthoringToolDetector, BlockingAssetConfigSchema, DEFAULT_LRS_OPTIONS, FormatDetector, HtmlInjector, LocalFoldersConfigSchema, Logger, LrsBridgeConfigSchema, ManifestUpdater, PatchAdamsConfigSchema, Patcher, PluginRegistry, StorylineHtmlInjector, buildCssAfterOptions, buildCssBeforeOptions, buildJsAfterOptions, buildJsBeforeOptions, defaultConfig, extractCourseFingerprint, extractCourseMetadata, generateConfigTemplate, generateCssAfterLoader, generateCssBeforeLoader, generateJsAfterLoader, generateJsBeforeLoader, generateLrsBridgeCode, loadConfig, mergeWithDefaults, pluginRegistry };
|
|
7661
|
+
export { AsyncAssetConfigSchema, AuthoringToolDetector, BlockingAssetConfigSchema, DEFAULT_LRS_OPTIONS, FormatDetector, HtmlInjector, LocalFoldersConfigSchema, Logger, LrsBridgeConfigSchema, ManifestUpdater, PatchAdamsConfigSchema, Patcher, PluginRegistry, StorylineHtmlInjector, buildCssAfterOptions, buildCssBeforeOptions, buildJsAfterOptions, buildJsBeforeOptions, defaultConfig, extractCourseFingerprint, extractCourseMetadata, extractCourseStructure, generateClassMappingsScript, generateConfigTemplate, generateCssAfterLoader, generateCssBeforeLoader, generateJsAfterLoader, generateJsBeforeLoader, generateLrsBridgeCode, hasClassMappings, loadConfig, mergeWithDefaults, pluginRegistry };
|
|
7442
7662
|
//# sourceMappingURL=index.js.map
|
|
7443
7663
|
//# sourceMappingURL=index.js.map
|