hyperclayjs 1.3.1 → 1.4.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/LICENSE +21 -0
- package/README.md +77 -45
- package/communication/behaviorCollector.js +7 -4
- package/communication/sendMessage.js +7 -4
- package/communication/uploadFile.js +8 -5
- package/core/autosave.js +5 -47
- package/core/editmodeSystem.js +8 -5
- package/core/enablePersistentFormInputValues.js +7 -4
- package/core/exportToWindow.js +14 -0
- package/core/optionVisibilityRuleGenerator.js +8 -5
- package/core/savePage.js +47 -14
- package/core/savePageCore.js +10 -7
- package/custom-attributes/domHelpers.js +7 -4
- package/custom-attributes/sortable.js +23 -16
- package/dom-utilities/All.js +9 -6
- package/dom-utilities/getDataFromForm.js +8 -5
- package/dom-utilities/insertStyleTag.js +8 -5
- package/dom-utilities/onDomReady.js +7 -4
- package/dom-utilities/onLoad.js +7 -4
- package/hyperclay.js +90 -31
- package/module-dependency-graph.json +103 -135
- package/package.json +1 -1
- package/string-utilities/copy-to-clipboard.js +7 -4
- package/string-utilities/query.js +8 -5
- package/string-utilities/slugify.js +8 -5
- package/ui/prompts.js +49 -31
- package/ui/theModal.js +50 -6
- package/ui/toast-hyperclay.js +27 -11
- package/ui/toast.js +82 -92
- package/utilities/cookie.js +8 -5
- package/utilities/debounce.js +7 -4
- package/utilities/loadVendorScript.js +57 -0
- package/utilities/mutation.js +9 -6
- package/utilities/nearest.js +7 -4
- package/utilities/throttle.js +7 -4
- package/vendor/Sortable.vendor.js +2 -0
- package/vendor/idiomorph.min.js +8 -5
- package/vendor/tailwind-play.js +16 -162
- package/vendor/tailwind-play.vendor.js +169 -0
- package/string-utilities/emmet-html.js +0 -60
- package/ui/info.js +0 -47
- package/vendor/Sortable.js +0 -3351
package/LICENSE
CHANGED
|
@@ -19,3 +19,24 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
19
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Third-Party Licenses
|
|
26
|
+
|
|
27
|
+
This project includes the following third-party libraries:
|
|
28
|
+
|
|
29
|
+
### Idiomorph
|
|
30
|
+
- Copyright (c) Big Sky Software
|
|
31
|
+
- License: 0BSD (Zero-Clause BSD)
|
|
32
|
+
- https://github.com/bigskysoftware/idiomorph
|
|
33
|
+
|
|
34
|
+
### Tailwind CSS
|
|
35
|
+
- Copyright (c) Tailwind Labs, Inc.
|
|
36
|
+
- License: MIT
|
|
37
|
+
- https://github.com/tailwindlabs/tailwindcss
|
|
38
|
+
|
|
39
|
+
### Sortable.js
|
|
40
|
+
- Copyright (c) All contributors to Sortable
|
|
41
|
+
- License: MIT
|
|
42
|
+
- https://github.com/SortableJS/Sortable
|
package/README.md
CHANGED
|
@@ -15,22 +15,27 @@ A modular JavaScript library for building interactive HTML applications with Hyp
|
|
|
15
15
|
|
|
16
16
|
### Using CDN (Self-detecting Loader)
|
|
17
17
|
|
|
18
|
-
The self-detecting loader reads URL parameters and automatically loads the requested features with all dependencies
|
|
18
|
+
The self-detecting loader reads URL parameters and automatically loads the requested features with all dependencies.
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
<!-- Minimal setup -->
|
|
22
|
-
<script src="https://hyperclay.com/js/hyperclay.js?preset=minimal" type="module"></script>
|
|
20
|
+
Destructure directly from the import:
|
|
23
21
|
|
|
24
|
-
|
|
25
|
-
<script
|
|
22
|
+
```html
|
|
23
|
+
<script type="module">
|
|
24
|
+
const { toast, savePage } = await import('https://cdn.jsdelivr.net/npm/hyperclayjs@1/hyperclay.js?preset=standard');
|
|
25
|
+
toast('Hello!');
|
|
26
|
+
</script>
|
|
27
|
+
```
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
<script src="https://hyperclay.com/js/hyperclay.js?features=save,admin,toast,ajax" type="module"></script>
|
|
29
|
+
Or with custom features:
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
<script
|
|
31
|
+
```html
|
|
32
|
+
<script type="module">
|
|
33
|
+
const { toast, ask } = await import('https://cdn.jsdelivr.net/npm/hyperclayjs@1/hyperclay.js?features=toast,dialogs');
|
|
34
|
+
</script>
|
|
32
35
|
```
|
|
33
36
|
|
|
37
|
+
**Note:** Presets include `export-to-window` by default, which also exports to `window.hyperclay`. Omit it from custom features if you only want ES module exports.
|
|
38
|
+
|
|
34
39
|
### Using NPM
|
|
35
40
|
|
|
36
41
|
```bash
|
|
@@ -52,91 +57,110 @@ import 'hyperclayjs/presets/standard.js';
|
|
|
52
57
|
|
|
53
58
|
| Module | Size | Description |
|
|
54
59
|
|--------|------|-------------|
|
|
55
|
-
|
|
|
56
|
-
|
|
|
57
|
-
| edit-mode |
|
|
60
|
+
| autosave | 1.2KB | Auto-save on DOM changes, unsaved changes warning |
|
|
61
|
+
| edit-mode | 1.8KB | Toggle edit mode on hyperclay on/off |
|
|
62
|
+
| edit-mode-helpers | 5.4KB | Admin-only functionality: [edit-mode-input], [edit-mode-resource], [edit-mode-onclick] |
|
|
58
63
|
| option-visibility | 4.7KB | Dynamic show/hide based on ancestor state with option:attribute="value" |
|
|
59
|
-
| persist | 2.
|
|
60
|
-
| save-core | 5.
|
|
61
|
-
| save-system | 4.
|
|
64
|
+
| persist | 2.5KB | Persist input/select/textarea values to the DOM with [persist] attribute |
|
|
65
|
+
| save-core | 5.9KB | Basic save function only - hyperclay.savePage() |
|
|
66
|
+
| save-system | 4.9KB | Manual save: keyboard shortcut (CMD+S), save button, change tracking |
|
|
62
67
|
|
|
63
68
|
### Custom Attributes (HTML enhancements)
|
|
64
69
|
|
|
65
70
|
| Module | Size | Description |
|
|
66
71
|
|--------|------|-------------|
|
|
67
72
|
| ajax-elements | 2.8KB | [ajax-form], [ajax-button] for async form submissions |
|
|
68
|
-
| dom-helpers | 5.
|
|
73
|
+
| dom-helpers | 5.7KB | el.nearest, el.val, el.text, el.exec, el.cycle |
|
|
69
74
|
| event-attrs | 3.6KB | [onclickaway], [onclone], [onpagemutation], [onrender] |
|
|
70
75
|
| input-helpers | 1.2KB | [prevent-enter], [autosize] for textareas |
|
|
71
|
-
| sortable |
|
|
76
|
+
| sortable | 2.8KB | Drag-drop sorting with [sortable], lazy-loads ~118KB Sortable.js in edit mode |
|
|
72
77
|
|
|
73
78
|
### UI Components (User interface elements)
|
|
74
79
|
|
|
75
80
|
| Module | Size | Description |
|
|
76
81
|
|--------|------|-------------|
|
|
77
|
-
| dialogs |
|
|
78
|
-
|
|
|
79
|
-
|
|
|
80
|
-
| toast | 7.
|
|
82
|
+
| dialogs | 8.4KB | ask(), consent(), tell(), snippet() dialog functions |
|
|
83
|
+
| tailwind-play | 0.7KB | Live Tailwind CSS editing, lazy-loads ~370KB script in edit mode only |
|
|
84
|
+
| the-modal | 19.8KB | Full modal window creation system - window.theModal |
|
|
85
|
+
| toast | 7.7KB | Success/error message notifications, toast(msg, msgType) |
|
|
81
86
|
|
|
82
87
|
### Utilities (Core utilities (often auto-included))
|
|
83
88
|
|
|
84
89
|
| Module | Size | Description |
|
|
85
90
|
|--------|------|-------------|
|
|
86
|
-
| cookie | 1.
|
|
91
|
+
| cookie | 1.4KB | Cookie management (often auto-included) |
|
|
87
92
|
| debounce | 0.4KB | Function debouncing |
|
|
88
|
-
| mutation |
|
|
89
|
-
| nearest | 3.
|
|
90
|
-
| throttle | 0.
|
|
93
|
+
| mutation | 13KB | DOM mutation observation (often auto-included) |
|
|
94
|
+
| nearest | 3.4KB | Find nearest elements (often auto-included) |
|
|
95
|
+
| throttle | 0.8KB | Function throttling |
|
|
91
96
|
|
|
92
97
|
### DOM Utilities (DOM manipulation helpers)
|
|
93
98
|
|
|
94
99
|
| Module | Size | Description |
|
|
95
100
|
|--------|------|-------------|
|
|
96
|
-
| all-js |
|
|
97
|
-
| dom-ready | 0.
|
|
98
|
-
| form-data |
|
|
99
|
-
| style-injection | 1KB | Dynamic stylesheet injection |
|
|
101
|
+
| all-js | 14KB | Full DOM manipulation library |
|
|
102
|
+
| dom-ready | 0.4KB | DOM ready callback |
|
|
103
|
+
| form-data | 2KB | Extract form data as an object |
|
|
104
|
+
| style-injection | 1.1KB | Dynamic stylesheet injection |
|
|
100
105
|
|
|
101
106
|
### String Utilities (String manipulation helpers)
|
|
102
107
|
|
|
103
108
|
| Module | Size | Description |
|
|
104
109
|
|--------|------|-------------|
|
|
105
|
-
| clipboard | 0.
|
|
106
|
-
|
|
|
107
|
-
|
|
|
108
|
-
| slugify | 0.6KB | URL-friendly slug generator |
|
|
110
|
+
| copy-to-clipboard | 0.9KB | Clipboard utility |
|
|
111
|
+
| query-params | 0.3KB | Parse URL search params |
|
|
112
|
+
| slugify | 0.7KB | URL-friendly slug generator |
|
|
109
113
|
|
|
110
114
|
### Communication & Files (File handling and messaging)
|
|
111
115
|
|
|
112
116
|
| Module | Size | Description |
|
|
113
117
|
|--------|------|-------------|
|
|
114
|
-
| file-upload | 10.
|
|
115
|
-
| send-message | 1.
|
|
118
|
+
| file-upload | 10.7KB | File upload with progress |
|
|
119
|
+
| send-message | 1.4KB | Message sending utility |
|
|
116
120
|
|
|
117
121
|
### Vendor Libraries (Third-party libraries)
|
|
118
122
|
|
|
119
123
|
| Module | Size | Description |
|
|
120
124
|
|--------|------|-------------|
|
|
121
|
-
| idiomorph | 8.
|
|
125
|
+
| idiomorph | 8.2KB | Efficient DOM morphing library |
|
|
122
126
|
|
|
123
127
|
## Presets
|
|
124
128
|
|
|
125
|
-
### Minimal (~
|
|
129
|
+
### Minimal (~24.3KB)
|
|
126
130
|
Essential features for basic editing
|
|
127
131
|
|
|
128
|
-
**Modules:** `save-core`, `save-system`, `
|
|
132
|
+
**Modules:** `save-core`, `save-system`, `edit-mode-helpers`, `toast`, `export-to-window`
|
|
129
133
|
|
|
130
|
-
### Standard (~
|
|
134
|
+
### Standard (~40.8KB)
|
|
131
135
|
Standard feature set for most use cases
|
|
132
136
|
|
|
133
|
-
**Modules:** `save-core`, `save-system`, `
|
|
137
|
+
**Modules:** `save-core`, `save-system`, `edit-mode-helpers`, `persist`, `option-visibility`, `event-attrs`, `dom-helpers`, `toast`, `export-to-window`
|
|
134
138
|
|
|
135
|
-
### Everything (~
|
|
139
|
+
### Everything (~145.1KB)
|
|
136
140
|
All available features
|
|
137
141
|
|
|
138
142
|
Includes all available modules across all categories.
|
|
139
143
|
|
|
144
|
+
## Lazy-Loaded Modules
|
|
145
|
+
|
|
146
|
+
Some modules with large vendor dependencies are **lazy-loaded** to optimize page performance:
|
|
147
|
+
|
|
148
|
+
| Module | Wrapper Size | Vendor Size | Loaded When |
|
|
149
|
+
|--------|-------------|-------------|-------------|
|
|
150
|
+
| `sortable` | ~3KB | ~118KB | Edit mode only |
|
|
151
|
+
| `tailwind-play` | ~1KB | ~370KB | Edit mode only |
|
|
152
|
+
|
|
153
|
+
**How it works:**
|
|
154
|
+
- The wrapper module checks if the page is in edit mode (`isEditMode`)
|
|
155
|
+
- If true, it injects a `<script save-ignore>` tag that loads the vendor script
|
|
156
|
+
- If false, nothing is loaded - viewers don't download the heavy scripts
|
|
157
|
+
- The `save-ignore` attribute strips the script tag when the page is saved
|
|
158
|
+
|
|
159
|
+
This means:
|
|
160
|
+
- **Editors** get full functionality when needed
|
|
161
|
+
- **Viewers** never download ~500KB of vendor scripts
|
|
162
|
+
- **Saved pages** stay clean with no leftover script tags
|
|
163
|
+
|
|
140
164
|
## Visual Configurator
|
|
141
165
|
|
|
142
166
|
Explore features and build your custom bundle with our interactive configurator:
|
|
@@ -217,7 +241,7 @@ The configurator dynamically loads this file to always show accurate information
|
|
|
217
241
|
- Safari 15.4+
|
|
218
242
|
- Edge 89+
|
|
219
243
|
|
|
220
|
-
The loader uses top-level await
|
|
244
|
+
The loader uses ES modules with top-level await. Use `await import()` to ensure modules finish loading before your code runs.
|
|
221
245
|
|
|
222
246
|
## API Examples
|
|
223
247
|
|
|
@@ -278,7 +302,7 @@ tell("Welcome to Hyperclay!");
|
|
|
278
302
|
Click outside this div
|
|
279
303
|
</div>
|
|
280
304
|
|
|
281
|
-
<!-- Persist
|
|
305
|
+
<!-- Persist input/select/textarea values -->
|
|
282
306
|
<input type="text" name="username" persist>
|
|
283
307
|
```
|
|
284
308
|
|
|
@@ -320,7 +344,7 @@ myFeature();
|
|
|
320
344
|
<script src="/js/hyperclay.js?preset=standard" type="module"></script>
|
|
321
345
|
|
|
322
346
|
<!-- Or specific features -->
|
|
323
|
-
<script src="/js/hyperclay.js?features=save,
|
|
347
|
+
<script src="/js/hyperclay.js?features=save,edit-mode-helpers,toast" type="module"></script>
|
|
324
348
|
```
|
|
325
349
|
|
|
326
350
|
## Contributing
|
|
@@ -338,6 +362,14 @@ myFeature();
|
|
|
338
362
|
|
|
339
363
|
MIT © Hyperclay
|
|
340
364
|
|
|
365
|
+
### Third-Party Credits
|
|
366
|
+
|
|
367
|
+
This project includes the following open-source libraries:
|
|
368
|
+
|
|
369
|
+
- **[Idiomorph](https://github.com/bigskysoftware/idiomorph)** - DOM morphing library by Big Sky Software (0BSD)
|
|
370
|
+
- **[Tailwind CSS](https://github.com/tailwindlabs/tailwindcss)** - Utility-first CSS framework by Tailwind Labs (MIT)
|
|
371
|
+
- **[Sortable.js](https://github.com/SortableJS/Sortable)** - Drag-and-drop library (MIT)
|
|
372
|
+
|
|
341
373
|
## Links
|
|
342
374
|
|
|
343
375
|
- [Documentation](https://hyperclay.com/docs)
|
|
@@ -222,9 +222,12 @@ const behaviorCollector = (() => {
|
|
|
222
222
|
};
|
|
223
223
|
})();
|
|
224
224
|
|
|
225
|
-
//
|
|
226
|
-
|
|
227
|
-
window.hyperclay
|
|
225
|
+
// Auto-export to window unless suppressed by loader
|
|
226
|
+
if (!window.__hyperclayNoAutoExport) {
|
|
227
|
+
window.hyperclay = window.hyperclay || {};
|
|
228
|
+
window.hyperclay.behaviorCollector = behaviorCollector;
|
|
229
|
+
window.h = window.hyperclay;
|
|
230
|
+
}
|
|
228
231
|
|
|
229
232
|
export default behaviorCollector;
|
|
230
233
|
|
|
@@ -234,4 +237,4 @@ export function init() {
|
|
|
234
237
|
}
|
|
235
238
|
|
|
236
239
|
// Auto-init when module is imported
|
|
237
|
-
init();
|
|
240
|
+
init();
|
|
@@ -47,8 +47,11 @@ function sendMessage(eventOrObj, successMessage = "Successfully sent", callback)
|
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
//
|
|
51
|
-
|
|
52
|
-
window.hyperclay
|
|
50
|
+
// Auto-export to window unless suppressed by loader
|
|
51
|
+
if (!window.__hyperclayNoAutoExport) {
|
|
52
|
+
window.hyperclay = window.hyperclay || {};
|
|
53
|
+
window.hyperclay.sendMessage = sendMessage;
|
|
54
|
+
window.h = window.hyperclay;
|
|
55
|
+
}
|
|
53
56
|
|
|
54
|
-
export default sendMessage;
|
|
57
|
+
export default sendMessage;
|
|
@@ -347,8 +347,11 @@ function detectContentType(content) {
|
|
|
347
347
|
return { type: "txt", mime: "text/plain", extension: ".txt" };
|
|
348
348
|
}
|
|
349
349
|
|
|
350
|
-
//
|
|
351
|
-
|
|
352
|
-
window.hyperclay
|
|
353
|
-
window.hyperclay.
|
|
354
|
-
window.hyperclay.
|
|
350
|
+
// Auto-export to window unless suppressed by loader
|
|
351
|
+
if (!window.__hyperclayNoAutoExport) {
|
|
352
|
+
window.hyperclay = window.hyperclay || {};
|
|
353
|
+
window.hyperclay.uploadFile = uploadFile;
|
|
354
|
+
window.hyperclay.createFile = createFile;
|
|
355
|
+
window.hyperclay.uploadFileBasic = uploadFileBasic;
|
|
356
|
+
window.h = window.hyperclay;
|
|
357
|
+
}
|
package/core/autosave.js
CHANGED
|
@@ -4,60 +4,22 @@
|
|
|
4
4
|
* Automatically saves page on DOM changes with throttling.
|
|
5
5
|
* Warns before leaving page with unsaved changes.
|
|
6
6
|
*
|
|
7
|
-
* Requires the 'save' module to be loaded first.
|
|
7
|
+
* Requires the 'save-system' module to be loaded first.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import toast from "../ui/toast.js";
|
|
11
|
-
import throttle from "../utilities/throttle.js";
|
|
12
11
|
import Mutation from "../utilities/mutation.js";
|
|
13
12
|
import { isEditMode, isOwner } from "./isAdminOfCurrentResource.js";
|
|
14
|
-
import { getPageContents } from "./savePageCore.js";
|
|
15
13
|
import {
|
|
16
|
-
|
|
17
|
-
getUnsavedChanges
|
|
18
|
-
setUnsavedChanges,
|
|
19
|
-
getLastSavedContents
|
|
14
|
+
savePageThrottled,
|
|
15
|
+
getUnsavedChanges
|
|
20
16
|
} from "./savePage.js";
|
|
21
17
|
|
|
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
18
|
/**
|
|
57
19
|
* Initialize auto-save on DOM changes
|
|
58
20
|
* Uses debounced mutation observer
|
|
59
21
|
*/
|
|
60
|
-
|
|
22
|
+
function initSavePageOnChange() {
|
|
61
23
|
Mutation.onAnyChange({
|
|
62
24
|
debounce: 3333,
|
|
63
25
|
omitChangeDetails: true
|
|
@@ -83,13 +45,9 @@ function init() {
|
|
|
83
45
|
initSavePageOnChange();
|
|
84
46
|
}
|
|
85
47
|
|
|
86
|
-
//
|
|
87
|
-
window.hyperclay = window.hyperclay || {};
|
|
88
|
-
window.hyperclay.savePageThrottled = savePageThrottled;
|
|
89
|
-
window.hyperclay.initSavePageOnChange = initSavePageOnChange;
|
|
48
|
+
// No window exports - savePageThrottled is exported from save-system
|
|
90
49
|
|
|
91
50
|
// Auto-init when module is imported
|
|
92
51
|
init();
|
|
93
52
|
|
|
94
|
-
export { init, savePageThrottled, initSavePageOnChange };
|
|
95
53
|
export default init;
|
package/core/editmodeSystem.js
CHANGED
|
@@ -7,11 +7,14 @@ function init() {
|
|
|
7
7
|
initPageType();
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
//
|
|
11
|
-
|
|
12
|
-
window.hyperclay
|
|
13
|
-
window.hyperclay.
|
|
14
|
-
window.hyperclay.
|
|
10
|
+
// Auto-export to window unless suppressed by loader
|
|
11
|
+
if (!window.__hyperclayNoAutoExport) {
|
|
12
|
+
window.hyperclay = window.hyperclay || {};
|
|
13
|
+
window.hyperclay.toggleEditMode = toggleEditMode;
|
|
14
|
+
window.hyperclay.isEditMode = isEditMode;
|
|
15
|
+
window.hyperclay.isOwner = isOwner;
|
|
16
|
+
window.h = window.hyperclay;
|
|
17
|
+
}
|
|
15
18
|
|
|
16
19
|
// Auto-init when module is imported
|
|
17
20
|
init();
|
|
@@ -61,9 +61,12 @@ export function init() {
|
|
|
61
61
|
enablePersistentFormInputValues("[persist]");
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
//
|
|
65
|
-
|
|
66
|
-
window.hyperclay
|
|
64
|
+
// Auto-export to window unless suppressed by loader
|
|
65
|
+
if (!window.__hyperclayNoAutoExport) {
|
|
66
|
+
window.hyperclay = window.hyperclay || {};
|
|
67
|
+
window.hyperclay.enablePersistentFormInputValues = enablePersistentFormInputValues;
|
|
68
|
+
window.h = window.hyperclay;
|
|
69
|
+
}
|
|
67
70
|
|
|
68
71
|
// Auto-init when module is imported
|
|
69
|
-
init();
|
|
72
|
+
init();
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Export to Window Module
|
|
3
|
+
*
|
|
4
|
+
* When loaded FIRST by the loader, this flips the __hyperclayNoAutoExport flag
|
|
5
|
+
* to false, allowing subsequent modules to self-export to window.hyperclay.
|
|
6
|
+
*
|
|
7
|
+
* This module is included in all presets by default.
|
|
8
|
+
* Exclude it if you prefer ES module-only imports (no window pollution).
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// Flip the flag so modules will auto-export
|
|
12
|
+
window.__hyperclayNoAutoExport = false;
|
|
13
|
+
|
|
14
|
+
export default true;
|
|
@@ -152,10 +152,13 @@ const optionVisibilityRuleGenerator = {
|
|
|
152
152
|
},
|
|
153
153
|
};
|
|
154
154
|
|
|
155
|
-
//
|
|
156
|
-
window.
|
|
157
|
-
window.
|
|
158
|
-
window.hyperclay
|
|
155
|
+
// Auto-export to window unless suppressed by loader
|
|
156
|
+
if (!window.__hyperclayNoAutoExport) {
|
|
157
|
+
window.optionVisibilityRuleGenerator = optionVisibilityRuleGenerator;
|
|
158
|
+
window.hyperclay = window.hyperclay || {};
|
|
159
|
+
window.hyperclay.optionVisibilityRuleGenerator = optionVisibilityRuleGenerator;
|
|
160
|
+
window.h = window.hyperclay;
|
|
161
|
+
}
|
|
159
162
|
|
|
160
163
|
export default optionVisibilityRuleGenerator;
|
|
161
164
|
|
|
@@ -165,4 +168,4 @@ export function init() {
|
|
|
165
168
|
}
|
|
166
169
|
|
|
167
170
|
// Auto-init when module is imported
|
|
168
|
-
init();
|
|
171
|
+
init();
|
package/core/savePage.js
CHANGED
|
@@ -10,18 +10,17 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import toast from "../ui/toast.js";
|
|
13
|
+
import throttle from "../utilities/throttle.js";
|
|
13
14
|
import { isEditMode, isOwner } from "./isAdminOfCurrentResource.js";
|
|
14
15
|
import {
|
|
15
16
|
savePage as savePageCore,
|
|
16
17
|
getPageContents,
|
|
17
|
-
replacePageWith as replacePageWithCore
|
|
18
|
+
replacePageWith as replacePageWithCore,
|
|
19
|
+
beforeSave
|
|
18
20
|
} from "./savePageCore.js";
|
|
19
21
|
|
|
20
|
-
// Re-export
|
|
21
|
-
export { beforeSave }
|
|
22
|
-
|
|
23
|
-
// Re-export getPageContents for autosave module
|
|
24
|
-
export { getPageContents } from "./savePageCore.js";
|
|
22
|
+
// Re-export from core for backward compatibility
|
|
23
|
+
export { beforeSave, getPageContents };
|
|
25
24
|
|
|
26
25
|
let unsavedChanges = false;
|
|
27
26
|
let lastSavedContents = '';
|
|
@@ -97,6 +96,39 @@ export function replacePageWith(url) {
|
|
|
97
96
|
});
|
|
98
97
|
}
|
|
99
98
|
|
|
99
|
+
// Throttled version of savePage for auto-save
|
|
100
|
+
const throttledSave = throttle(savePage, 1200);
|
|
101
|
+
|
|
102
|
+
// Baseline for autosave comparison
|
|
103
|
+
let baselineContents = '';
|
|
104
|
+
|
|
105
|
+
// Capture baseline after setup mutations settle
|
|
106
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
107
|
+
if (isEditMode) {
|
|
108
|
+
setTimeout(() => {
|
|
109
|
+
baselineContents = getPageContents();
|
|
110
|
+
}, 1500);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Save the page with throttling, for use with auto-save
|
|
116
|
+
* Checks both baseline and last saved content to prevent saves from initial setup
|
|
117
|
+
*
|
|
118
|
+
* @param {Function} callback - Optional callback
|
|
119
|
+
*/
|
|
120
|
+
export function savePageThrottled(callback = () => {}) {
|
|
121
|
+
if (!isEditMode) return;
|
|
122
|
+
|
|
123
|
+
const currentContents = getPageContents();
|
|
124
|
+
// For autosave: check both that content changed from baseline AND from last save
|
|
125
|
+
// This prevents saves from initial setup mutations
|
|
126
|
+
if (currentContents !== baselineContents && currentContents !== lastSavedContents) {
|
|
127
|
+
unsavedChanges = true;
|
|
128
|
+
throttledSave(callback);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
100
132
|
/**
|
|
101
133
|
* Initialize keyboard shortcut for save (CMD/CTRL+S)
|
|
102
134
|
*/
|
|
@@ -138,16 +170,17 @@ export function init() {
|
|
|
138
170
|
initHyperclaySaveButton();
|
|
139
171
|
}
|
|
140
172
|
|
|
141
|
-
//
|
|
142
|
-
|
|
143
|
-
window.hyperclay
|
|
144
|
-
window.hyperclay.
|
|
145
|
-
window.hyperclay.
|
|
146
|
-
window.hyperclay.
|
|
147
|
-
window.hyperclay.
|
|
173
|
+
// Auto-export to window unless suppressed by loader
|
|
174
|
+
if (!window.__hyperclayNoAutoExport) {
|
|
175
|
+
window.hyperclay = window.hyperclay || {};
|
|
176
|
+
window.hyperclay.savePage = savePage;
|
|
177
|
+
window.hyperclay.savePageThrottled = savePageThrottled;
|
|
178
|
+
window.hyperclay.beforeSave = beforeSave;
|
|
179
|
+
window.hyperclay.replacePageWith = replacePageWith;
|
|
180
|
+
window.h = window.hyperclay;
|
|
181
|
+
}
|
|
148
182
|
|
|
149
183
|
// Auto-init when module is imported
|
|
150
184
|
init();
|
|
151
185
|
|
|
152
|
-
export { savePage, replacePageWith, initSaveKeyboardShortcut, initHyperclaySaveButton, init };
|
|
153
186
|
export default savePage;
|
package/core/savePageCore.js
CHANGED
|
@@ -220,10 +220,13 @@ export function replacePageWith(url, callback = () => {}) {
|
|
|
220
220
|
});
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
-
//
|
|
224
|
-
|
|
225
|
-
window.hyperclay
|
|
226
|
-
window.hyperclay.
|
|
227
|
-
window.hyperclay.
|
|
228
|
-
window.hyperclay.
|
|
229
|
-
window.hyperclay.
|
|
223
|
+
// Auto-export to window unless suppressed by loader
|
|
224
|
+
if (!window.__hyperclayNoAutoExport) {
|
|
225
|
+
window.hyperclay = window.hyperclay || {};
|
|
226
|
+
window.hyperclay.savePage = savePage;
|
|
227
|
+
window.hyperclay.saveHtml = saveHtml;
|
|
228
|
+
window.hyperclay.replacePageWith = replacePageWith;
|
|
229
|
+
window.hyperclay.beforeSave = beforeSave;
|
|
230
|
+
window.hyperclay.getPageContents = getPageContents;
|
|
231
|
+
window.h = window.hyperclay;
|
|
232
|
+
}
|
|
@@ -172,10 +172,13 @@ function init () {
|
|
|
172
172
|
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
-
//
|
|
176
|
-
window.
|
|
177
|
-
window.
|
|
178
|
-
window.hyperclay
|
|
175
|
+
// Auto-export to window unless suppressed by loader
|
|
176
|
+
if (!window.__hyperclayNoAutoExport) {
|
|
177
|
+
window.initCustomAttributes = init;
|
|
178
|
+
window.hyperclay = window.hyperclay || {};
|
|
179
|
+
window.hyperclay.initCustomAttributes = init;
|
|
180
|
+
window.h = window.hyperclay;
|
|
181
|
+
}
|
|
179
182
|
|
|
180
183
|
// Auto-init when module is imported
|
|
181
184
|
init();
|
|
@@ -8,12 +8,16 @@
|
|
|
8
8
|
- add `onsorted` attribute to execute code when items are sorted
|
|
9
9
|
- e.g. <ul sortable onsorted="console.log('Items reordered!')"></ul>
|
|
10
10
|
|
|
11
|
+
This wrapper conditionally loads the full Sortable.js vendor script (~118KB)
|
|
12
|
+
only when in edit mode. The script is injected with save-ignore so it's
|
|
13
|
+
stripped from the page before saving.
|
|
14
|
+
|
|
11
15
|
*/
|
|
12
|
-
import { isEditMode
|
|
16
|
+
import { isEditMode } from "../core/isAdminOfCurrentResource.js";
|
|
13
17
|
import Mutation from "../utilities/mutation.js";
|
|
14
|
-
import
|
|
18
|
+
import { loadVendorScript, getVendorUrl } from "../utilities/loadVendorScript.js";
|
|
15
19
|
|
|
16
|
-
function makeSortable
|
|
20
|
+
function makeSortable(sortableElem, Sortable) {
|
|
17
21
|
let options = {};
|
|
18
22
|
|
|
19
23
|
// Check if Sortable instance already exists
|
|
@@ -51,11 +55,23 @@ function makeSortable (sortableElem) {
|
|
|
51
55
|
Sortable.create(sortableElem, options);
|
|
52
56
|
}
|
|
53
57
|
|
|
54
|
-
function init
|
|
58
|
+
async function init() {
|
|
55
59
|
if (!isEditMode) return;
|
|
56
60
|
|
|
61
|
+
// Load the vendor script
|
|
62
|
+
const vendorUrl = getVendorUrl(import.meta.url, '../vendor/Sortable.vendor.js');
|
|
63
|
+
const Sortable = await loadVendorScript(vendorUrl, 'Sortable');
|
|
64
|
+
|
|
65
|
+
// Auto-export to window unless suppressed by loader
|
|
66
|
+
if (!window.__hyperclayNoAutoExport) {
|
|
67
|
+
window.Sortable = Sortable;
|
|
68
|
+
window.hyperclay = window.hyperclay || {};
|
|
69
|
+
window.hyperclay.Sortable = Sortable;
|
|
70
|
+
window.h = window.hyperclay;
|
|
71
|
+
}
|
|
72
|
+
|
|
57
73
|
// Set up sortable on page load
|
|
58
|
-
document.querySelectorAll('[sortable]').forEach(makeSortable);
|
|
74
|
+
document.querySelectorAll('[sortable]').forEach(el => makeSortable(el, Sortable));
|
|
59
75
|
|
|
60
76
|
// Set up listener for dynamically added elements
|
|
61
77
|
Mutation.onAddElement({
|
|
@@ -63,22 +79,13 @@ function init () {
|
|
|
63
79
|
debounce: 200
|
|
64
80
|
}, (changes) => {
|
|
65
81
|
changes.forEach(({ element }) => {
|
|
66
|
-
makeSortable(element);
|
|
82
|
+
makeSortable(element, Sortable);
|
|
67
83
|
});
|
|
68
84
|
});
|
|
69
|
-
|
|
70
|
-
// ❗️re-initializing sortable on parent elements isn't necessary
|
|
71
|
-
// sortable.js handles this automatically
|
|
72
|
-
// ❌ onElementAdded(newElem => makeSortable(newElem.closest('[sortable]')))
|
|
73
85
|
}
|
|
74
86
|
|
|
75
|
-
// Self-export to window and hyperclay
|
|
76
|
-
window.Sortable = Sortable;
|
|
77
|
-
window.hyperclay = window.hyperclay || {};
|
|
78
|
-
window.hyperclay.Sortable = Sortable;
|
|
79
|
-
|
|
80
87
|
// Auto-init when module is imported
|
|
81
88
|
init();
|
|
82
89
|
|
|
83
|
-
export { init
|
|
90
|
+
export { init };
|
|
84
91
|
export default init;
|