hyperclayjs 1.1.2 → 1.3.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.
Files changed (40) hide show
  1. package/README.md +44 -59
  2. package/communication/behaviorCollector.js +8 -1
  3. package/communication/sendMessage.js +8 -2
  4. package/communication/uploadFile.js +8 -2
  5. package/core/adminSystem.js +3 -0
  6. package/core/autosave.js +95 -0
  7. package/core/editmodeSystem.js +10 -8
  8. package/core/enablePersistentFormInputValues.js +8 -1
  9. package/core/optionVisibilityRuleGenerator.js +9 -1
  10. package/core/savePage.js +28 -71
  11. package/core/savePageCore.js +7 -14
  12. package/custom-attributes/ajaxElements.js +4 -0
  13. package/custom-attributes/domHelpers.js +9 -0
  14. package/custom-attributes/events.js +3 -0
  15. package/custom-attributes/inputHelpers.js +3 -0
  16. package/custom-attributes/sortable.js +9 -1
  17. package/dom-utilities/All.js +4 -7
  18. package/dom-utilities/getDataFromForm.js +9 -2
  19. package/dom-utilities/insertStyleTag.js +9 -2
  20. package/dom-utilities/onDomReady.js +8 -2
  21. package/dom-utilities/onLoad.js +8 -2
  22. package/hyperclay.js +109 -673
  23. package/module-dependency-graph.json +193 -137
  24. package/package.json +3 -3
  25. package/string-utilities/copy-to-clipboard.js +3 -7
  26. package/string-utilities/emmet-html.js +8 -2
  27. package/string-utilities/query.js +8 -1
  28. package/string-utilities/slugify.js +4 -7
  29. package/ui/info.js +9 -1
  30. package/ui/prompts.js +19 -12
  31. package/ui/theModal.js +4 -4
  32. package/ui/toast-hyperclay.js +21 -0
  33. package/ui/toast.js +4 -7
  34. package/utilities/cookie.js +4 -7
  35. package/utilities/debounce.js +10 -4
  36. package/utilities/mutation.js +5 -0
  37. package/utilities/nearest.js +6 -1
  38. package/utilities/throttle.js +8 -2
  39. package/vendor/idiomorph.min.js +9 -1
  40. package/README.template.md +0 -276
package/README.md CHANGED
@@ -52,89 +52,87 @@ import 'hyperclayjs/presets/standard.js';
52
52
 
53
53
  | Module | Size | Description |
54
54
  |--------|------|-------------|
55
- | Admin Features | 5.3KB | Hides admin inputs, scripts, contenteditable, onclick for regular viewers |
56
- | Edit Mode | 1.4KB | Toggle edit mode on/off |
57
- | Form Persistence | 2.2KB | Persist form values to the DOM with [persist] attribute |
58
- | Option Visibility | 4.4KB | Dynamic show/hide based on page state with option:attribute="value" |
59
- | Save Core | 5.9KB | Basic save function only - hyperclay.savePage() |
60
- | Save System | 4.9KB | Full save: save button, keyboard shortcut, auto-save, change tracking |
55
+ | admin | 5.4KB | Hides admin inputs, scripts, contenteditable, onclick for regular viewers |
56
+ | autosave | 2.4KB | Auto-save on DOM changes, unsaved changes warning |
57
+ | edit-mode | 1.7KB | Toggle edit mode on/off |
58
+ | option-visibility | 4.7KB | Dynamic show/hide based on ancestor state with option:attribute="value" |
59
+ | persist | 2.4KB | Persist form values to the DOM with [persist] attribute |
60
+ | save-core | 5.8KB | Basic save function only - hyperclay.savePage() |
61
+ | save-system | 4.1KB | Manual save: keyboard shortcut (CMD+S), save button, change tracking |
61
62
 
62
63
  ### Custom Attributes (HTML enhancements)
63
64
 
64
65
  | Module | Size | Description |
65
66
  |--------|------|-------------|
66
- | AJAX Elements | 2.7KB | [ajax-form], [ajax-button] for async form submissions |
67
- | DOM Helpers | 5.4KB | el.nearest, el.val, el.text, el.exec, el.cycle |
68
- | Event Attributes | 3.5KB | [onclickaway], [onclone], [onpagemutation], [onrender] |
69
- | Input Helpers | 1.2KB | [prevent-enter], [autosize] for textareas |
70
- | Sortable | 117.9KB | Drag-drop sorting with [sortable] - includes Sortable.js vendor library |
67
+ | ajax-elements | 2.8KB | [ajax-form], [ajax-button] for async form submissions |
68
+ | dom-helpers | 5.6KB | el.nearest, el.val, el.text, el.exec, el.cycle |
69
+ | event-attrs | 3.6KB | [onclickaway], [onclone], [onpagemutation], [onrender] |
70
+ | input-helpers | 1.2KB | [prevent-enter], [autosize] for textareas |
71
+ | sortable | 118.1KB | Drag-drop sorting with [sortable] - includes Sortable.js vendor library |
71
72
 
72
73
  ### UI Components (User interface elements)
73
74
 
74
75
  | Module | Size | Description |
75
76
  |--------|------|-------------|
76
- | Dialog Functions | 7.7KB | ask(), consent(), tell(), snippet() functions |
77
- | Info Dialog | 3.2KB | Info dialog component |
78
- | Modal System | 18.4KB | Full modal window creation system - window.theModal |
79
- | Tailwind Play | 362.3KB | Live Tailwind CSS editing - updates styles based on classes in your HTML |
80
- | Toast Notifications | 7.3KB | Success/error message notifications - toast(msg, msgType) |
77
+ | dialogs | 11.2KB | ask(), consent(), tell(), info(), snippet() functions |
78
+ | modal | 18.5KB | Full modal window creation system - window.theModal |
79
+ | tailwind-play | 362.3KB | Live Tailwind CSS editing - no need for a build system |
80
+ | toast | 7.3KB | Success/error message notifications - toast(msg, msgType) |
81
81
 
82
82
  ### Utilities (Core utilities (often auto-included))
83
83
 
84
84
  | Module | Size | Description |
85
85
  |--------|------|-------------|
86
- | Cookie Helper | 1.3KB | Cookie management (often auto-included) |
87
- | Debounce | 0.2KB | Function debouncing |
88
- | Mutation Observer | 12.8KB | DOM mutation observation (often auto-included) |
89
- | Nearest Element | 3.2KB | Find nearest elements (often auto-included) |
90
- | Throttle | 0.6KB | Function throttling |
86
+ | cookie | 1.3KB | Cookie management (often auto-included) |
87
+ | debounce | 0.4KB | Function debouncing |
88
+ | mutation | 12.9KB | DOM mutation observation (often auto-included) |
89
+ | nearest | 3.3KB | Find nearest elements (often auto-included) |
90
+ | throttle | 0.7KB | Function throttling |
91
91
 
92
92
  ### DOM Utilities (DOM manipulation helpers)
93
93
 
94
94
  | Module | Size | Description |
95
95
  |--------|------|-------------|
96
- | All.js (jQuery-like) | 13.9KB | Full DOM manipulation library |
97
- | DOM Ready | 0.2KB | DOM ready callback |
98
- | Get Data From Form | 1.7KB | Extract form data as an object |
99
- | Style Injection | 0.8KB | Dynamic stylesheet injection |
100
- | Window Load | 0.2KB | Window load callback |
96
+ | all-js | 13.9KB | Full DOM manipulation library |
97
+ | dom-ready | 0.3KB | DOM ready callback |
98
+ | form-data | 1.9KB | Extract form data as an object |
99
+ | style-injection | 1KB | Dynamic stylesheet injection |
101
100
 
102
101
  ### String Utilities (String manipulation helpers)
103
102
 
104
103
  | Module | Size | Description |
105
104
  |--------|------|-------------|
106
- | Copy to Clipboard | 0.9KB | Clipboard utility |
107
- | Emmet HTML | 1.4KB | Emmet-like HTML generation |
108
- | Slugify | 0.7KB | URL-friendly slug generator |
109
- | URL Query Parser | 0.1KB | Parse URL search params |
105
+ | clipboard | 0.8KB | Clipboard utility |
106
+ | emmet | 1.5KB | Emmet-like HTML generation |
107
+ | query-params | 0.2KB | Parse URL search params |
108
+ | slugify | 0.6KB | URL-friendly slug generator |
110
109
 
111
110
  ### Communication & Files (File handling and messaging)
112
111
 
113
112
  | Module | Size | Description |
114
113
  |--------|------|-------------|
115
- | Behavior Collector | 5.2KB | Tracks user interactions (mouse, scroll, keyboard) |
116
- | File Upload to App Owner | 10.4KB | File upload with progress |
117
- | Send Message to App Owner | 1.2KB | Message sending utility |
114
+ | file-upload | 10.6KB | File upload with progress |
115
+ | send-message | 1.3KB | Message sending utility |
118
116
 
119
117
  ### Vendor Libraries (Third-party libraries)
120
118
 
121
119
  | Module | Size | Description |
122
120
  |--------|------|-------------|
123
- | DOM Morphing | 7.9KB | Efficient DOM updates |
121
+ | idiomorph | 8.1KB | Efficient DOM morphing library |
124
122
 
125
123
  ## Presets
126
124
 
127
- ### Minimal (~23.4KB)
125
+ ### Minimal (~22.6KB)
128
126
  Essential features for basic editing
129
127
 
130
- **Modules:** `save-core`, `save`, `admin`, `toast`
128
+ **Modules:** `save-core`, `save-system`, `admin`, `toast`
131
129
 
132
- ### Standard (~37.2KB)
130
+ ### Standard (~38.9KB)
133
131
  Standard feature set for most use cases
134
132
 
135
- **Modules:** `save-core`, `save`, `admin`, `persist`, `ajax`, `events`, `helpers`, `toast`
133
+ **Modules:** `save-core`, `save-system`, `admin`, `persist`, `option-visibility`, `event-attrs`, `dom-helpers`, `toast`
136
134
 
137
- ### Everything (~616.4KB)
135
+ ### Everything (~629.5KB)
138
136
  All available features
139
137
 
140
138
  Includes all available modules across all categories.
@@ -214,12 +212,12 @@ The configurator dynamically loads this file to always show accurate information
214
212
 
215
213
  ## Browser Support
216
214
 
217
- - Chrome 90+
218
- - Firefox 88+
219
- - Safari 14+
220
- - Edge 90+
215
+ - Chrome 89+
216
+ - Firefox 89+
217
+ - Safari 15.4+
218
+ - Edge 89+
221
219
 
222
- All features use modern JavaScript (ES2020+). For older browser support, use a transpiler.
220
+ The loader uses top-level await, which means any `<script type="module">` placed after it will automatically wait for HyperclayJS to finish loading. No ready events or promises needed.
223
221
 
224
222
  ## API Examples
225
223
 
@@ -229,9 +227,6 @@ All features use modern JavaScript (ES2020+). For older browser support, use a t
229
227
  // Manually save the page
230
228
  hyperclay.savePage();
231
229
 
232
- // Initialize auto-save
233
- hyperclay.initSavePageOnChange();
234
-
235
230
  // Add save button
236
231
  hyperclay.initHyperclaySaveButton(); // Looks for [trigger-save]
237
232
 
@@ -308,18 +303,8 @@ export default function myFeature() {
308
303
  // Feature implementation
309
304
  }
310
305
 
311
- // Export initialization function
312
- export function init() {
313
- if (typeof window !== 'undefined') {
314
- // Auto-initialize on import
315
- myFeature();
316
- }
317
- }
318
-
319
- // Auto-run if needed
320
- if (typeof window !== 'undefined') {
321
- init();
322
- }
306
+ // Auto-init when module is imported
307
+ myFeature();
323
308
  ```
324
309
 
325
310
  ## Migration from Monolithic Script
@@ -222,9 +222,16 @@ const behaviorCollector = (() => {
222
222
  };
223
223
  })();
224
224
 
225
+ // Self-export to hyperclay only
226
+ window.hyperclay = window.hyperclay || {};
227
+ window.hyperclay.behaviorCollector = behaviorCollector;
228
+
225
229
  export default behaviorCollector;
226
230
 
227
231
  // Auto-initialize - start collecting behavior data
228
232
  export function init() {
229
233
  behaviorCollector.init();
230
- }
234
+ }
235
+
236
+ // Auto-init when module is imported
237
+ init();
@@ -2,7 +2,7 @@ import behaviorCollector from "./behaviorCollector.js";
2
2
  import getDataFromForm from "../dom-utilities/getDataFromForm.js";
3
3
  import toast from "../ui/toast.js";
4
4
 
5
- export default function sendMessage(eventOrObj, successMessage = "Successfully sent", callback) {
5
+ function sendMessage(eventOrObj, successMessage = "Successfully sent", callback) {
6
6
  let form;
7
7
  let data;
8
8
 
@@ -45,4 +45,10 @@ export default function sendMessage(eventOrObj, successMessage = "Successfully s
45
45
  toast(`Failed to send message: ${error}`);
46
46
  throw error;
47
47
  });
48
- }
48
+ }
49
+
50
+ // Self-export to hyperclay only
51
+ window.hyperclay = window.hyperclay || {};
52
+ window.hyperclay.sendMessage = sendMessage;
53
+
54
+ export default sendMessage;
@@ -322,7 +322,7 @@ function detectContentType(content) {
322
322
  // CSV pattern
323
323
  { type: "csv", mime: "text/csv", regex: /^[^,\n]+(,[^,\n]+)+/ },
324
324
  // Markdown pattern
325
- {
325
+ {
326
326
  type: "md",
327
327
  mime: "text/markdown",
328
328
  regex: /#\S+\s+\S+|```[\s\S]*```/
@@ -345,4 +345,10 @@ function detectContentType(content) {
345
345
 
346
346
  // Default to plain text
347
347
  return { type: "txt", mime: "text/plain", extension: ".txt" };
348
- }
348
+ }
349
+
350
+ // Self-export to hyperclay only
351
+ window.hyperclay = window.hyperclay || {};
352
+ window.hyperclay.uploadFile = uploadFile;
353
+ window.hyperclay.createFile = createFile;
354
+ window.hyperclay.uploadFileBasic = uploadFileBasic;
@@ -11,5 +11,8 @@ function init() {
11
11
  initResources();
12
12
  }
13
13
 
14
+ // Auto-init when module is imported
15
+ init();
16
+
14
17
  export { init };
15
18
  export default init;
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Auto-save system for Hyperclay
3
+ *
4
+ * Automatically saves page on DOM changes with throttling.
5
+ * Warns before leaving page with unsaved changes.
6
+ *
7
+ * Requires the 'save' module to be loaded first.
8
+ */
9
+
10
+ import toast from "../ui/toast.js";
11
+ import throttle from "../utilities/throttle.js";
12
+ import Mutation from "../utilities/mutation.js";
13
+ import { isEditMode, isOwner } from "./isAdminOfCurrentResource.js";
14
+ import { getPageContents } from "./savePageCore.js";
15
+ import {
16
+ savePage,
17
+ getUnsavedChanges,
18
+ setUnsavedChanges,
19
+ getLastSavedContents
20
+ } from "./savePage.js";
21
+
22
+ let baselineContents = '';
23
+
24
+ // Capture baseline after setup mutations settle
25
+ document.addEventListener('DOMContentLoaded', () => {
26
+ if (isEditMode) {
27
+ setTimeout(() => {
28
+ baselineContents = getPageContents();
29
+ }, 1500);
30
+ }
31
+ });
32
+
33
+ /**
34
+ * Throttled version of savePage for auto-save
35
+ */
36
+ const throttledSave = throttle(savePage, 1200);
37
+
38
+ /**
39
+ * Save the page with throttling, for use with auto-save
40
+ * Checks both baseline and last saved content to prevent saves from initial setup
41
+ *
42
+ * @param {Function} callback - Optional callback
43
+ */
44
+ export function savePageThrottled(callback = () => {}) {
45
+ if (!isEditMode) return;
46
+
47
+ const currentContents = getPageContents();
48
+ // For autosave: check both that content changed from baseline AND from last save
49
+ // This prevents saves from initial setup mutations
50
+ if (currentContents !== baselineContents && currentContents !== getLastSavedContents()) {
51
+ setUnsavedChanges(true);
52
+ throttledSave(callback);
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Initialize auto-save on DOM changes
58
+ * Uses debounced mutation observer
59
+ */
60
+ export function initSavePageOnChange() {
61
+ Mutation.onAnyChange({
62
+ debounce: 3333,
63
+ omitChangeDetails: true
64
+ }, () => {
65
+ savePageThrottled(({msg, msgType} = {}) => {
66
+ if (msg) toast(msg, msgType);
67
+ });
68
+ });
69
+ }
70
+
71
+ /**
72
+ * Warn before leaving page with unsaved changes
73
+ */
74
+ window.addEventListener('beforeunload', (event) => {
75
+ if (getUnsavedChanges() && isOwner) {
76
+ event.preventDefault();
77
+ event.returnValue = '';
78
+ }
79
+ });
80
+
81
+ function init() {
82
+ if (!isEditMode) return;
83
+ initSavePageOnChange();
84
+ }
85
+
86
+ // Self-export to hyperclay
87
+ window.hyperclay = window.hyperclay || {};
88
+ window.hyperclay.savePageThrottled = savePageThrottled;
89
+ window.hyperclay.initSavePageOnChange = initSavePageOnChange;
90
+
91
+ // Auto-init when module is imported
92
+ init();
93
+
94
+ export { init, savePageThrottled, initSavePageOnChange };
95
+ export default init;
@@ -1,18 +1,20 @@
1
1
  // Edit mode system - combines editmode toggle with page type setting
2
2
  import { toggleEditMode } from './editmode.js';
3
+ import { isEditMode, isOwner } from './isAdminOfCurrentResource.js';
3
4
  import { init as initPageType } from './setPageTypeOnDocumentElement.js';
4
5
 
5
6
  function init() {
6
7
  initPageType();
7
8
  }
8
9
 
9
- function exportToWindow() {
10
- if (!window.hyperclay) {
11
- window.hyperclay = {};
12
- }
10
+ // Self-export to hyperclay only
11
+ window.hyperclay = window.hyperclay || {};
12
+ window.hyperclay.toggleEditMode = toggleEditMode;
13
+ window.hyperclay.isEditMode = isEditMode;
14
+ window.hyperclay.isOwner = isOwner;
13
15
 
14
- window.hyperclay.toggleEditMode = toggleEditMode;
15
- }
16
+ // Auto-init when module is imported
17
+ init();
16
18
 
17
- export { init, exportToWindow };
18
- export default { init, exportToWindow };
19
+ export { init, toggleEditMode, isEditMode, isOwner };
20
+ export default { init, toggleEditMode, isEditMode, isOwner };
@@ -59,4 +59,11 @@ export default function enablePersistentFormInputValues(filterBySelector = "[per
59
59
  // Auto-initialize with default selector
60
60
  export function init() {
61
61
  enablePersistentFormInputValues("[persist]");
62
- }
62
+ }
63
+
64
+ // Self-export to hyperclay only
65
+ window.hyperclay = window.hyperclay || {};
66
+ window.hyperclay.enablePersistentFormInputValues = enablePersistentFormInputValues;
67
+
68
+ // Auto-init when module is imported
69
+ init();
@@ -152,9 +152,17 @@ const optionVisibilityRuleGenerator = {
152
152
  },
153
153
  };
154
154
 
155
+ // Self-export to window and hyperclay
156
+ window.optionVisibilityRuleGenerator = optionVisibilityRuleGenerator;
157
+ window.hyperclay = window.hyperclay || {};
158
+ window.hyperclay.optionVisibilityRuleGenerator = optionVisibilityRuleGenerator;
159
+
155
160
  export default optionVisibilityRuleGenerator;
156
161
 
157
162
  // Auto-initialize
158
163
  export function init() {
159
164
  optionVisibilityRuleGenerator.start();
160
- }
165
+ }
166
+
167
+ // Auto-init when module is imported
168
+ init();
package/core/savePage.js CHANGED
@@ -1,15 +1,15 @@
1
1
  /**
2
- * Full save system for Hyperclay
2
+ * Save system for Hyperclay
3
3
  *
4
- * This includes all the conveniences: change detection, toast notifications,
5
- * auto-save, keyboard shortcuts, and more.
4
+ * Manual save with change detection, toast notifications,
5
+ * keyboard shortcuts, and save button support.
6
+ *
7
+ * For auto-save on DOM changes, also load the 'autosave' module.
6
8
  *
7
9
  * Built on top of savePageCore.js
8
10
  */
9
11
 
10
12
  import toast from "../ui/toast.js";
11
- import throttle from "../utilities/throttle.js";
12
- import Mutation from "../utilities/mutation.js";
13
13
  import { isEditMode, isOwner } from "./isAdminOfCurrentResource.js";
14
14
  import {
15
15
  savePage as savePageCore,
@@ -20,9 +20,17 @@ import {
20
20
  // Re-export beforeSave from core for backward compatibility
21
21
  export { beforeSave } from "./savePageCore.js";
22
22
 
23
+ // Re-export getPageContents for autosave module
24
+ export { getPageContents } from "./savePageCore.js";
25
+
23
26
  let unsavedChanges = false;
24
27
  let lastSavedContents = '';
25
- let baselineContents = ''; // State after initial setup, used to prevent autosave from setup mutations
28
+
29
+ // State accessors for autosave module
30
+ export function getUnsavedChanges() { return unsavedChanges; }
31
+ export function setUnsavedChanges(val) { unsavedChanges = val; }
32
+ export function getLastSavedContents() { return lastSavedContents; }
33
+ export function setLastSavedContents(val) { lastSavedContents = val; }
26
34
 
27
35
  // Initialize lastSavedContents on page load to match what's on disk
28
36
  // This prevents unnecessary save attempts when content hasn't changed
@@ -30,11 +38,6 @@ document.addEventListener('DOMContentLoaded', () => {
30
38
  if (isEditMode) {
31
39
  // Capture initial state immediately for comparison
32
40
  lastSavedContents = getPageContents();
33
-
34
- // Also capture baseline after setup for autosave detection
35
- setTimeout(() => {
36
- baselineContents = getPageContents();
37
- }, 1500);
38
41
  }
39
42
  });
40
43
 
@@ -72,29 +75,6 @@ export function savePage(callback = () => {}) {
72
75
  });
73
76
  }
74
77
 
75
- /**
76
- * Throttled version of savePage for auto-save
77
- */
78
- const throttledSave = throttle(savePage, 1200);
79
-
80
- /**
81
- * Save the page with throttling, for use with auto-save
82
- * Checks both baseline and last saved content to prevent saves from initial setup
83
- *
84
- * @param {Function} callback - Optional callback
85
- */
86
- export function savePageThrottled(callback = () => {}) {
87
- if (!isEditMode) return;
88
-
89
- const currentContents = getPageContents();
90
- // For autosave: check both that content changed from baseline AND from last save
91
- // This prevents saves from initial setup mutations
92
- if (currentContents !== baselineContents && currentContents !== lastSavedContents) {
93
- unsavedChanges = true;
94
- throttledSave(callback);
95
- }
96
- }
97
-
98
78
  /**
99
79
  * Fetch HTML from a URL and save it, then reload
100
80
  * Shows toast notifications
@@ -148,49 +128,26 @@ export function initHyperclaySaveButton() {
148
128
  }
149
129
 
150
130
  /**
151
- * Initialize auto-save on DOM changes
152
- * Uses debounced mutation observer
153
- */
154
- export function initSavePageOnChange() {
155
- Mutation.onAnyChange({
156
- debounce: 3333,
157
- omitChangeDetails: true
158
- }, () => {
159
- savePageThrottled(({msg, msgType} = {}) => {
160
- if (msg) toast(msg, msgType);
161
- });
162
- });
163
- }
164
-
165
- /**
166
- * Warn before leaving page with unsaved changes
167
- */
168
- window.addEventListener('beforeunload', (event) => {
169
- if (unsavedChanges && isOwner) {
170
- event.preventDefault();
171
- event.returnValue = '';
172
- }
173
- });
174
-
175
- /**
176
- * Initialize the full save system
131
+ * Initialize the save system (keyboard shortcut and save button)
132
+ * For auto-save, also load the 'autosave' module
177
133
  */
178
134
  export function init() {
179
135
  if (!isEditMode) return;
180
136
 
181
137
  initSaveKeyboardShortcut();
182
138
  initHyperclaySaveButton();
183
- initSavePageOnChange();
184
139
  }
185
140
 
186
- /**
187
- * Export save functions to window.hyperclay
188
- */
189
- export function exportToWindow() {
190
- if (!window.hyperclay) {
191
- window.hyperclay = {};
192
- }
141
+ // Self-export to hyperclay only
142
+ window.hyperclay = window.hyperclay || {};
143
+ window.hyperclay.savePage = savePage;
144
+ window.hyperclay.beforeSave = beforeSave;
145
+ window.hyperclay.replacePageWith = replacePageWith;
146
+ window.hyperclay.initHyperclaySaveButton = initHyperclaySaveButton;
147
+ window.hyperclay.initSaveKeyboardShortcut = initSaveKeyboardShortcut;
193
148
 
194
- window.hyperclay.savePage = savePage;
195
- window.hyperclay.replacePageWith = replacePageWith;
196
- }
149
+ // Auto-init when module is imported
150
+ init();
151
+
152
+ export { savePage, replacePageWith, initSaveKeyboardShortcut, initHyperclaySaveButton, init };
153
+ export default savePage;
@@ -220,17 +220,10 @@ export function replacePageWith(url, callback = () => {}) {
220
220
  });
221
221
  }
222
222
 
223
- /**
224
- * Export save functions to window.hyperclay
225
- */
226
- export function exportToWindow() {
227
- if (!window.hyperclay) {
228
- window.hyperclay = {};
229
- }
230
-
231
- window.hyperclay.savePage = savePage;
232
- window.hyperclay.saveHtml = saveHtml;
233
- window.hyperclay.replacePageWith = replacePageWith;
234
- window.hyperclay.beforeSave = beforeSave;
235
- window.hyperclay.getPageContents = getPageContents;
236
- }
223
+ // Self-export to hyperclay only
224
+ window.hyperclay = window.hyperclay || {};
225
+ window.hyperclay.savePage = savePage;
226
+ window.hyperclay.saveHtml = saveHtml;
227
+ window.hyperclay.replacePageWith = replacePageWith;
228
+ window.hyperclay.beforeSave = beforeSave;
229
+ window.hyperclay.getPageContents = getPageContents;
@@ -90,5 +90,9 @@ function init () {
90
90
  document.addEventListener('submit', handleFormSubmit);
91
91
  document.addEventListener('click', handleButtonClick);
92
92
  }
93
+
94
+ // Auto-init when module is imported
95
+ init();
96
+
93
97
  export { init };
94
98
  export default init;
@@ -171,5 +171,14 @@ function init () {
171
171
  };
172
172
 
173
173
  }
174
+
175
+ // Self-export to window and hyperclay
176
+ window.initCustomAttributes = init;
177
+ window.hyperclay = window.hyperclay || {};
178
+ window.hyperclay.initCustomAttributes = init;
179
+
180
+ // Auto-init when module is imported
181
+ init();
182
+
174
183
  export { init };
175
184
  export default init;
@@ -11,5 +11,8 @@ function init() {
11
11
  initOnrender();
12
12
  }
13
13
 
14
+ // Auto-init when module is imported
15
+ init();
16
+
14
17
  export { init };
15
18
  export default init;
@@ -7,5 +7,8 @@ function init() {
7
7
  initAutosize();
8
8
  }
9
9
 
10
+ // Auto-init when module is imported
11
+ init();
12
+
10
13
  export { init };
11
14
  export default init;
@@ -72,5 +72,13 @@ function init () {
72
72
  // ❌ onElementAdded(newElem => makeSortable(newElem.closest('[sortable]')))
73
73
  }
74
74
 
75
- export { init };
75
+ // Self-export to window and hyperclay
76
+ window.Sortable = Sortable;
77
+ window.hyperclay = window.hyperclay || {};
78
+ window.hyperclay.Sortable = Sortable;
79
+
80
+ // Auto-init when module is imported
81
+ init();
82
+
83
+ export { init, Sortable };
76
84
  export default init;
@@ -403,12 +403,9 @@ const All = new Proxy(function (selectorOrElements, contextSelector) {
403
403
  // Install default plugins
404
404
  All.use(defaultPlugins);
405
405
 
406
- // Export to window for global access
407
- export function exportToWindow() {
408
- if (!window.hyperclay) {
409
- window.hyperclay = {};
410
- }
411
- window.hyperclay.All = All;
412
- }
406
+ // Self-export to window and hyperclay
407
+ window.All = All;
408
+ window.hyperclay = window.hyperclay || {};
409
+ window.hyperclay.All = All;
413
410
 
414
411
  export default All;