@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 CHANGED
@@ -5647,7 +5647,6 @@ window.pa_patcher = window.pa_patcher || {
5647
5647
  try {
5648
5648
  var xhr = new XMLHttpRequest();
5649
5649
  xhr.open('GET', ASSET_VERSION_URL, false);
5650
- xhr.timeout = 2000;
5651
5650
  xhr.send();
5652
5651
  if (xhr.status === 200) {
5653
5652
  window.__pa_v = JSON.parse(xhr.responseText).v || '1';
@@ -6029,6 +6028,139 @@ function buildSkinJsOptions(config) {
6029
6028
  };
6030
6029
  }
6031
6030
 
6031
+ // src/templates/class-mappings.ts
6032
+ function hasClassMappings(mappings) {
6033
+ if (!mappings) return false;
6034
+ if (mappings.course?.trim()) return true;
6035
+ if (mappings.lessons && Object.values(mappings.lessons).some((v) => v?.trim())) return true;
6036
+ if (mappings.blocks && Object.values(mappings.blocks).some((v) => v?.trim())) return true;
6037
+ return false;
6038
+ }
6039
+ function generateClassMappingsScript(mappings) {
6040
+ if (!hasClassMappings(mappings)) return "";
6041
+ const courseClasses = (mappings.course || "").trim();
6042
+ const blockMap = {};
6043
+ const lessonMap = {};
6044
+ if (mappings.blocks) {
6045
+ for (const [id, classes] of Object.entries(mappings.blocks)) {
6046
+ const trimmed = classes?.trim();
6047
+ if (trimmed) blockMap[id] = trimmed;
6048
+ }
6049
+ }
6050
+ if (mappings.lessons) {
6051
+ for (const [id, classes] of Object.entries(mappings.lessons)) {
6052
+ const trimmed = classes?.trim();
6053
+ if (trimmed) lessonMap[id] = trimmed;
6054
+ }
6055
+ }
6056
+ const hasBlocks = Object.keys(blockMap).length > 0;
6057
+ const hasLessons = Object.keys(lessonMap).length > 0;
6058
+ const parts = [];
6059
+ parts.push(`// PA-Patcher: Custom Class Mappings`);
6060
+ parts.push(`(function() {`);
6061
+ parts.push(` 'use strict';`);
6062
+ parts.push(``);
6063
+ if (courseClasses) {
6064
+ parts.push(` // Course-level classes (applied to <html>)`);
6065
+ parts.push(` var courseClasses = ${JSON.stringify(courseClasses)};`);
6066
+ parts.push(` courseClasses.split(' ').forEach(function(cls) {`);
6067
+ parts.push(` if (cls) document.documentElement.classList.add(cls);`);
6068
+ parts.push(` });`);
6069
+ parts.push(``);
6070
+ }
6071
+ if (hasBlocks) {
6072
+ parts.push(` // Block-level classes (applied to [data-block-id] elements)`);
6073
+ parts.push(` var blockMap = ${JSON.stringify(blockMap)};`);
6074
+ parts.push(``);
6075
+ parts.push(` function applyBlockClasses() {`);
6076
+ parts.push(` var ids = Object.keys(blockMap);`);
6077
+ parts.push(` for (var i = 0; i < ids.length; i++) {`);
6078
+ parts.push(` var el = document.querySelector('[data-block-id="' + ids[i] + '"]');`);
6079
+ parts.push(` if (el) {`);
6080
+ parts.push(` var classes = blockMap[ids[i]].split(' ');`);
6081
+ parts.push(` for (var j = 0; j < classes.length; j++) {`);
6082
+ parts.push(` if (classes[j]) el.classList.add(classes[j]);`);
6083
+ parts.push(` }`);
6084
+ parts.push(` }`);
6085
+ parts.push(` }`);
6086
+ parts.push(` }`);
6087
+ parts.push(``);
6088
+ }
6089
+ if (hasLessons) {
6090
+ parts.push(` // Lesson-level classes (toggled on <html> via hash navigation)`);
6091
+ parts.push(` var lessonMap = ${JSON.stringify(lessonMap)};`);
6092
+ parts.push(` var allLessonClasses = [];`);
6093
+ parts.push(` Object.keys(lessonMap).forEach(function(id) {`);
6094
+ parts.push(` lessonMap[id].split(' ').forEach(function(cls) {`);
6095
+ parts.push(` if (cls && allLessonClasses.indexOf(cls) === -1) allLessonClasses.push(cls);`);
6096
+ parts.push(` });`);
6097
+ parts.push(` });`);
6098
+ parts.push(``);
6099
+ parts.push(` var currentLessonId = null;`);
6100
+ parts.push(``);
6101
+ parts.push(` function detectCurrentLesson() {`);
6102
+ parts.push(` var hash = window.location.hash || '';`);
6103
+ parts.push(` var match = hash.match(/#\\/lessons\\/([^/]+)/);`);
6104
+ parts.push(` return match ? match[1] : null;`);
6105
+ parts.push(` }`);
6106
+ parts.push(``);
6107
+ parts.push(` function applyLessonClasses() {`);
6108
+ parts.push(` var lessonId = detectCurrentLesson();`);
6109
+ parts.push(` if (lessonId === currentLessonId) return;`);
6110
+ parts.push(` currentLessonId = lessonId;`);
6111
+ parts.push(` for (var i = 0; i < allLessonClasses.length; i++) {`);
6112
+ parts.push(` document.documentElement.classList.remove(allLessonClasses[i]);`);
6113
+ parts.push(` }`);
6114
+ parts.push(` if (lessonId && lessonMap[lessonId]) {`);
6115
+ parts.push(` var classes = lessonMap[lessonId].split(' ');`);
6116
+ parts.push(` for (var j = 0; j < classes.length; j++) {`);
6117
+ parts.push(` if (classes[j]) document.documentElement.classList.add(classes[j]);`);
6118
+ parts.push(` }`);
6119
+ parts.push(` }`);
6120
+ parts.push(` }`);
6121
+ parts.push(``);
6122
+ }
6123
+ parts.push(` // Initialization`);
6124
+ parts.push(` function init() {`);
6125
+ if (hasBlocks) {
6126
+ parts.push(` applyBlockClasses();`);
6127
+ }
6128
+ if (hasLessons) {
6129
+ parts.push(` applyLessonClasses();`);
6130
+ parts.push(``);
6131
+ parts.push(` // Watch for Rise SPA navigation`);
6132
+ parts.push(` window.addEventListener('hashchange', function() {`);
6133
+ parts.push(` applyLessonClasses();`);
6134
+ if (hasBlocks) {
6135
+ parts.push(` setTimeout(applyBlockClasses, 200);`);
6136
+ }
6137
+ parts.push(` });`);
6138
+ }
6139
+ if (hasBlocks) {
6140
+ parts.push(``);
6141
+ parts.push(` // MutationObserver for lazily-rendered Rise blocks`);
6142
+ parts.push(` var observer = new MutationObserver(function(mutations) {`);
6143
+ parts.push(` for (var i = 0; i < mutations.length; i++) {`);
6144
+ parts.push(` if (mutations[i].addedNodes.length > 0) {`);
6145
+ parts.push(` applyBlockClasses();`);
6146
+ parts.push(` return;`);
6147
+ parts.push(` }`);
6148
+ parts.push(` }`);
6149
+ parts.push(` });`);
6150
+ parts.push(` var container = document.querySelector('#app') || document.body;`);
6151
+ parts.push(` observer.observe(container, { childList: true, subtree: true });`);
6152
+ }
6153
+ parts.push(` }`);
6154
+ parts.push(``);
6155
+ parts.push(` if (document.readyState === 'loading') {`);
6156
+ parts.push(` document.addEventListener('DOMContentLoaded', init);`);
6157
+ parts.push(` } else {`);
6158
+ parts.push(` init();`);
6159
+ parts.push(` }`);
6160
+ parts.push(`})();`);
6161
+ return parts.join("\n");
6162
+ }
6163
+
6032
6164
  // src/patcher/html-injector.ts
6033
6165
  var HtmlInjector = class {
6034
6166
  config;
@@ -7109,6 +7241,13 @@ var Patcher = class {
7109
7241
  console.log(`[Patcher] Fetched ${fetchedCount} remote files`);
7110
7242
  }
7111
7243
  const pluginAssets = this.generatePluginAssets();
7244
+ if (hasClassMappings(options.classMappings)) {
7245
+ const classMappingsJs = generateClassMappingsScript(options.classMappings);
7246
+ if (classMappingsJs) {
7247
+ pluginAssets.jsAfter = classMappingsJs + (pluginAssets.jsAfter ? "\n" + pluginAssets.jsAfter : "");
7248
+ console.log("[Patcher] Class mappings JS will be injected inline into HTML");
7249
+ }
7250
+ }
7112
7251
  const hasPluginAssets = pluginAssets.cssBefore || pluginAssets.cssAfter || pluginAssets.jsBefore || pluginAssets.jsAfter;
7113
7252
  if (hasPluginAssets) {
7114
7253
  htmlInjector.setPluginAssets(pluginAssets);