@patch-adams/core 1.5.24 → 1.6.1

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.js CHANGED
@@ -6018,6 +6018,228 @@ function buildSkinJsOptions(config) {
6018
6018
  };
6019
6019
  }
6020
6020
 
6021
+ // src/templates/class-mappings.ts
6022
+ function hasClassMappings(mappings) {
6023
+ if (!mappings) return false;
6024
+ if (mappings.course?.trim()) return true;
6025
+ if (mappings.lessons && Object.values(mappings.lessons).some((v) => v?.trim())) return true;
6026
+ if (mappings.blocks && Object.values(mappings.blocks).some((v) => v?.trim())) return true;
6027
+ if (mappings.blockGroups && mappings.blockGroups.length > 0) return true;
6028
+ return false;
6029
+ }
6030
+ function generateClassMappingsScript(mappings) {
6031
+ if (!hasClassMappings(mappings)) return "";
6032
+ const courseClasses = (mappings.course || "").trim();
6033
+ const blockMap = {};
6034
+ const lessonMap = {};
6035
+ if (mappings.blocks) {
6036
+ for (const [id, classes] of Object.entries(mappings.blocks)) {
6037
+ const trimmed = classes?.trim();
6038
+ if (trimmed) blockMap[id] = trimmed;
6039
+ }
6040
+ }
6041
+ if (mappings.lessons) {
6042
+ for (const [id, classes] of Object.entries(mappings.lessons)) {
6043
+ const trimmed = classes?.trim();
6044
+ if (trimmed) lessonMap[id] = trimmed;
6045
+ }
6046
+ }
6047
+ const hasBlocks = Object.keys(blockMap).length > 0;
6048
+ const hasLessons = Object.keys(lessonMap).length > 0;
6049
+ const blockGroups = (mappings.blockGroups || []).filter(
6050
+ (g) => g.blockIds.length >= 2 && g.className.trim() && g.lessonId
6051
+ );
6052
+ const hasGroups = blockGroups.length > 0;
6053
+ const parts = [];
6054
+ parts.push(`// PA-Patcher: Custom Class Mappings`);
6055
+ parts.push(`(function() {`);
6056
+ parts.push(` 'use strict';`);
6057
+ parts.push(``);
6058
+ if (courseClasses) {
6059
+ parts.push(` // Course-level classes (applied to <html>)`);
6060
+ parts.push(` var courseClasses = ${JSON.stringify(courseClasses)};`);
6061
+ parts.push(` courseClasses.split(' ').forEach(function(cls) {`);
6062
+ parts.push(` if (cls) document.documentElement.classList.add(cls);`);
6063
+ parts.push(` });`);
6064
+ parts.push(``);
6065
+ }
6066
+ if (hasBlocks) {
6067
+ parts.push(` // Block-level classes (applied to [data-block-id] elements)`);
6068
+ parts.push(` var blockMap = ${JSON.stringify(blockMap)};`);
6069
+ parts.push(``);
6070
+ parts.push(` function applyBlockClasses() {`);
6071
+ parts.push(` var ids = Object.keys(blockMap);`);
6072
+ parts.push(` for (var i = 0; i < ids.length; i++) {`);
6073
+ parts.push(` var el = document.querySelector('[data-block-id="' + ids[i] + '"]');`);
6074
+ parts.push(` if (el) {`);
6075
+ parts.push(` var classes = blockMap[ids[i]].split(' ');`);
6076
+ parts.push(` for (var j = 0; j < classes.length; j++) {`);
6077
+ parts.push(` if (classes[j]) el.classList.add(classes[j]);`);
6078
+ parts.push(` }`);
6079
+ parts.push(` }`);
6080
+ parts.push(` }`);
6081
+ parts.push(` }`);
6082
+ parts.push(``);
6083
+ }
6084
+ if (hasLessons) {
6085
+ parts.push(` // Lesson-level classes (toggled on <html> via hash navigation)`);
6086
+ parts.push(` var lessonMap = ${JSON.stringify(lessonMap)};`);
6087
+ parts.push(` var allLessonClasses = [];`);
6088
+ parts.push(` Object.keys(lessonMap).forEach(function(id) {`);
6089
+ parts.push(` lessonMap[id].split(' ').forEach(function(cls) {`);
6090
+ parts.push(` if (cls && allLessonClasses.indexOf(cls) === -1) allLessonClasses.push(cls);`);
6091
+ parts.push(` });`);
6092
+ parts.push(` });`);
6093
+ parts.push(``);
6094
+ parts.push(` var currentLessonId = null;`);
6095
+ parts.push(``);
6096
+ parts.push(` function detectCurrentLesson() {`);
6097
+ parts.push(` var hash = window.location.hash || '';`);
6098
+ parts.push(` var match = hash.match(/#\\/lessons\\/([^/]+)/);`);
6099
+ parts.push(` return match ? match[1] : null;`);
6100
+ parts.push(` }`);
6101
+ parts.push(``);
6102
+ parts.push(` function applyLessonClasses() {`);
6103
+ parts.push(` var lessonId = detectCurrentLesson();`);
6104
+ parts.push(` if (lessonId === currentLessonId) return;`);
6105
+ parts.push(` currentLessonId = lessonId;`);
6106
+ parts.push(` for (var i = 0; i < allLessonClasses.length; i++) {`);
6107
+ parts.push(` document.documentElement.classList.remove(allLessonClasses[i]);`);
6108
+ parts.push(` }`);
6109
+ parts.push(` if (lessonId && lessonMap[lessonId]) {`);
6110
+ parts.push(` var classes = lessonMap[lessonId].split(' ');`);
6111
+ parts.push(` for (var j = 0; j < classes.length; j++) {`);
6112
+ parts.push(` if (classes[j]) document.documentElement.classList.add(classes[j]);`);
6113
+ parts.push(` }`);
6114
+ parts.push(` }`);
6115
+ parts.push(` }`);
6116
+ parts.push(``);
6117
+ }
6118
+ if (hasGroups) {
6119
+ const groupData = blockGroups.map((g) => ({
6120
+ id: g.id,
6121
+ lessonId: g.lessonId,
6122
+ blockIds: g.blockIds,
6123
+ className: g.className.trim()
6124
+ }));
6125
+ parts.push(` // Block groups (adjacent blocks wrapped in container divs)`);
6126
+ parts.push(` var groupMap = ${JSON.stringify(groupData)};`);
6127
+ parts.push(``);
6128
+ parts.push(` function applyBlockGroups() {`);
6129
+ parts.push(` var hash = window.location.hash || '';`);
6130
+ parts.push(` var match = hash.match(/#\\/lessons\\/([^/]+)/);`);
6131
+ parts.push(` var currentLesson = match ? match[1] : null;`);
6132
+ parts.push(` for (var g = 0; g < groupMap.length; g++) {`);
6133
+ parts.push(` var group = groupMap[g];`);
6134
+ parts.push(` if (group.lessonId !== currentLesson) continue;`);
6135
+ parts.push(` if (document.querySelector('[data-pa-group-id="' + group.id + '"]')) continue;`);
6136
+ parts.push(` var blocks = [];`);
6137
+ parts.push(` var allPresent = true;`);
6138
+ parts.push(` for (var b = 0; b < group.blockIds.length; b++) {`);
6139
+ parts.push(` var el = document.querySelector('[data-block-id="' + group.blockIds[b] + '"]');`);
6140
+ parts.push(` if (!el) { allPresent = false; break; }`);
6141
+ parts.push(` blocks.push(el);`);
6142
+ parts.push(` }`);
6143
+ parts.push(` if (!allPresent) continue;`);
6144
+ parts.push(` var parent = blocks[0].parentNode;`);
6145
+ parts.push(` var sameParent = true;`);
6146
+ parts.push(` for (var s = 1; s < blocks.length; s++) {`);
6147
+ parts.push(` if (blocks[s].parentNode !== parent) { sameParent = false; break; }`);
6148
+ parts.push(` }`);
6149
+ parts.push(` if (!sameParent) continue;`);
6150
+ parts.push(` var wrapper = document.createElement('div');`);
6151
+ parts.push(` wrapper.setAttribute('data-pa-group-id', group.id);`);
6152
+ parts.push(` var cls = group.className.split(' ');`);
6153
+ parts.push(` for (var c = 0; c < cls.length; c++) {`);
6154
+ parts.push(` if (cls[c]) wrapper.classList.add(cls[c]);`);
6155
+ parts.push(` }`);
6156
+ parts.push(` parent.insertBefore(wrapper, blocks[0]);`);
6157
+ parts.push(` for (var m = 0; m < blocks.length; m++) {`);
6158
+ parts.push(` wrapper.appendChild(blocks[m]);`);
6159
+ parts.push(` }`);
6160
+ parts.push(` }`);
6161
+ parts.push(` }`);
6162
+ parts.push(``);
6163
+ parts.push(` function teardownBlockGroups() {`);
6164
+ parts.push(` var wrappers = document.querySelectorAll('[data-pa-group-id]');`);
6165
+ parts.push(` for (var w = 0; w < wrappers.length; w++) {`);
6166
+ parts.push(` var wr = wrappers[w];`);
6167
+ parts.push(` var par = wr.parentNode;`);
6168
+ parts.push(` while (wr.firstChild) {`);
6169
+ parts.push(` par.insertBefore(wr.firstChild, wr);`);
6170
+ parts.push(` }`);
6171
+ parts.push(` par.removeChild(wr);`);
6172
+ parts.push(` }`);
6173
+ parts.push(` }`);
6174
+ parts.push(``);
6175
+ }
6176
+ parts.push(` // Initialization`);
6177
+ parts.push(` function init() {`);
6178
+ if (hasBlocks) {
6179
+ parts.push(` applyBlockClasses();`);
6180
+ }
6181
+ if (hasGroups) {
6182
+ parts.push(` applyBlockGroups();`);
6183
+ }
6184
+ if (hasLessons) {
6185
+ parts.push(` applyLessonClasses();`);
6186
+ }
6187
+ if (hasLessons || hasGroups) {
6188
+ parts.push(``);
6189
+ parts.push(` // Watch for Rise SPA navigation`);
6190
+ parts.push(` window.addEventListener('hashchange', function() {`);
6191
+ if (hasGroups) {
6192
+ parts.push(` teardownBlockGroups();`);
6193
+ }
6194
+ if (hasLessons) {
6195
+ parts.push(` applyLessonClasses();`);
6196
+ }
6197
+ if (hasBlocks) {
6198
+ parts.push(` setTimeout(applyBlockClasses, 200);`);
6199
+ }
6200
+ if (hasGroups) {
6201
+ parts.push(` setTimeout(applyBlockGroups, 300);`);
6202
+ }
6203
+ parts.push(` });`);
6204
+ }
6205
+ if (hasBlocks || hasGroups) {
6206
+ parts.push(``);
6207
+ parts.push(` // MutationObserver for lazily-rendered Rise blocks`);
6208
+ if (hasGroups) {
6209
+ parts.push(` var debounceTimer = null;`);
6210
+ parts.push(` var observer = new MutationObserver(function() {`);
6211
+ parts.push(` if (debounceTimer) clearTimeout(debounceTimer);`);
6212
+ parts.push(` debounceTimer = setTimeout(function() {`);
6213
+ if (hasBlocks) {
6214
+ parts.push(` applyBlockClasses();`);
6215
+ }
6216
+ parts.push(` applyBlockGroups();`);
6217
+ parts.push(` }, 100);`);
6218
+ parts.push(` });`);
6219
+ } else {
6220
+ parts.push(` var observer = new MutationObserver(function(mutations) {`);
6221
+ parts.push(` for (var i = 0; i < mutations.length; i++) {`);
6222
+ parts.push(` if (mutations[i].addedNodes.length > 0) {`);
6223
+ parts.push(` applyBlockClasses();`);
6224
+ parts.push(` return;`);
6225
+ parts.push(` }`);
6226
+ parts.push(` }`);
6227
+ parts.push(` });`);
6228
+ }
6229
+ parts.push(` var container = document.querySelector('#app') || document.body;`);
6230
+ parts.push(` observer.observe(container, { childList: true, subtree: true });`);
6231
+ }
6232
+ parts.push(` }`);
6233
+ parts.push(``);
6234
+ parts.push(` if (document.readyState === 'loading') {`);
6235
+ parts.push(` document.addEventListener('DOMContentLoaded', init);`);
6236
+ parts.push(` } else {`);
6237
+ parts.push(` init();`);
6238
+ parts.push(` }`);
6239
+ parts.push(`})();`);
6240
+ return parts.join("\n");
6241
+ }
6242
+
6021
6243
  // src/patcher/html-injector.ts
6022
6244
  var HtmlInjector = class {
6023
6245
  config;
@@ -7098,6 +7320,13 @@ var Patcher = class {
7098
7320
  console.log(`[Patcher] Fetched ${fetchedCount} remote files`);
7099
7321
  }
7100
7322
  const pluginAssets = this.generatePluginAssets();
7323
+ if (hasClassMappings(options.classMappings)) {
7324
+ const classMappingsJs = generateClassMappingsScript(options.classMappings);
7325
+ if (classMappingsJs) {
7326
+ pluginAssets.jsAfter = classMappingsJs + (pluginAssets.jsAfter ? "\n" + pluginAssets.jsAfter : "");
7327
+ console.log("[Patcher] Class mappings JS will be injected inline into HTML");
7328
+ }
7329
+ }
7101
7330
  const hasPluginAssets = pluginAssets.cssBefore || pluginAssets.cssAfter || pluginAssets.jsBefore || pluginAssets.jsAfter;
7102
7331
  if (hasPluginAssets) {
7103
7332
  htmlInjector.setPluginAssets(pluginAssets);