alchemy-widget 0.2.2 → 0.2.4
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/CHANGELOG.md +11 -0
- package/controller/alchemy_widgets_controller.js +1 -1
- package/element/05-widget_element.js +16 -0
- package/element/10-container_elements.js +5 -4
- package/element/table_of_contents_element.js +98 -109
- package/helper/widgets/05-list.js +12 -0
- package/helper/widgets/partial.js +39 -4
- package/helper_field/widget.js +23 -1
- package/helper_field/widgets.js +14 -0
- package/package.json +1 -1
- package/view/elements/table_of_contents.hwk +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
## 0.2.4 (2023-01-30)
|
|
2
|
+
|
|
3
|
+
* Fix the tree structure generation of the `al-toc` element
|
|
4
|
+
* Make `TableOfContents#entries` return a flat list and `TableOfContents#tree` a tree structure
|
|
5
|
+
* Also take siblings of heading elements into account for the `TableOfContents` scrollspy
|
|
6
|
+
|
|
7
|
+
## 0.2.3 (2023-01-23)
|
|
8
|
+
|
|
9
|
+
* Fix `List` widgets not having their content saved
|
|
10
|
+
* Fix more issues with saving to the database
|
|
11
|
+
|
|
1
12
|
## 0.2.2 (2022-12-23)
|
|
2
13
|
|
|
3
14
|
* Fix widgets not being populated properly
|
|
@@ -225,7 +225,7 @@ AlchemyWidgets.setAction(async function uploadImage(conduit) {
|
|
|
225
225
|
id : result._id,
|
|
226
226
|
};
|
|
227
227
|
|
|
228
|
-
let default_path = alchemy.routeUrl('
|
|
228
|
+
let default_path = alchemy.routeUrl('MediaFile#image', params);
|
|
229
229
|
let url = RURL.parse(default_path);
|
|
230
230
|
|
|
231
231
|
let path_800 = url.clone();
|
|
@@ -389,6 +389,22 @@ Widget.setMethod(function getContextButton() {
|
|
|
389
389
|
return button;
|
|
390
390
|
});
|
|
391
391
|
|
|
392
|
+
/**
|
|
393
|
+
* Get a list of elements that could be child widgets
|
|
394
|
+
*
|
|
395
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
396
|
+
* @since 0.2.3
|
|
397
|
+
* @version 0.2.3
|
|
398
|
+
*/
|
|
399
|
+
Widget.setMethod(function getPossibleWidgetChildren() {
|
|
400
|
+
|
|
401
|
+
if (this.instance && typeof this.instance.getPossibleWidgetChildren == 'function') {
|
|
402
|
+
return this.instance.getPossibleWidgetChildren();
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
return this.children;
|
|
406
|
+
});
|
|
407
|
+
|
|
392
408
|
/**
|
|
393
409
|
* Show the config button
|
|
394
410
|
*
|
|
@@ -139,19 +139,20 @@ AlchemyWidgets.setMethod(function applyValue(value) {
|
|
|
139
139
|
*
|
|
140
140
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
141
141
|
* @since 0.1.0
|
|
142
|
-
* @version 0.
|
|
142
|
+
* @version 0.2.3
|
|
143
143
|
*
|
|
144
144
|
* @return {Array}
|
|
145
145
|
*/
|
|
146
146
|
AlchemyWidgets.setMethod(function getWidgetsConfig() {
|
|
147
147
|
|
|
148
|
-
let
|
|
148
|
+
let children = this.getPossibleWidgetChildren(),
|
|
149
|
+
widgets = [],
|
|
149
150
|
child,
|
|
150
151
|
temp,
|
|
151
152
|
i;
|
|
152
153
|
|
|
153
|
-
for (i = 0; i <
|
|
154
|
-
child =
|
|
154
|
+
for (i = 0; i < children.length; i++) {
|
|
155
|
+
child = children[i];
|
|
155
156
|
|
|
156
157
|
if (child instanceof Classes.Alchemy.Element.Widget.Base) {
|
|
157
158
|
temp = child.value;
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
const RELATED_HEADING = Symbol('related_heading'),
|
|
2
|
+
RELATED_SIBLINGS = Symbol('related_siblings');
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* The table-of-contents element
|
|
3
6
|
*
|
|
@@ -102,7 +105,7 @@ TableOfContents.setAttribute('truncate-length', {type: 'number'});
|
|
|
102
105
|
*
|
|
103
106
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
104
107
|
* @since 0.1.2
|
|
105
|
-
* @version 0.2.
|
|
108
|
+
* @version 0.2.4
|
|
106
109
|
*/
|
|
107
110
|
TableOfContents.setProperty(function entries() {
|
|
108
111
|
|
|
@@ -124,59 +127,42 @@ TableOfContents.setProperty(function entries() {
|
|
|
124
127
|
|
|
125
128
|
if (wrapper) {
|
|
126
129
|
|
|
127
|
-
let
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
element,
|
|
131
|
-
title,
|
|
132
|
-
i;
|
|
130
|
+
let heading_level = 0,
|
|
131
|
+
heading,
|
|
132
|
+
i;
|
|
133
133
|
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
let headings = wrapper.querySelectorAll(this.elements_selector || 'h1, h2, h3, h4, h5, h6'),
|
|
135
|
+
nodes = [];
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
for (i = 0; i < headings.length; i++) {
|
|
138
|
+
heading = headings[i];
|
|
138
139
|
|
|
139
|
-
|
|
140
|
-
|
|
140
|
+
if (!heading.id) {
|
|
141
|
+
|
|
142
|
+
if (heading.hawkejs_id) {
|
|
143
|
+
heading.id = heading.hawkejs_id;
|
|
141
144
|
}
|
|
142
145
|
|
|
143
|
-
if (!
|
|
146
|
+
if (!heading.id) {
|
|
144
147
|
continue;
|
|
145
148
|
}
|
|
146
149
|
}
|
|
147
150
|
|
|
148
151
|
let title_element,
|
|
149
|
-
|
|
150
|
-
ends_level;
|
|
152
|
+
title;
|
|
151
153
|
|
|
152
154
|
if (this.title_selector) {
|
|
153
|
-
title_element =
|
|
155
|
+
title_element = heading.querySelector(this.title_selector);
|
|
154
156
|
}
|
|
155
157
|
|
|
156
158
|
if (!title_element) {
|
|
157
|
-
title_element =
|
|
159
|
+
title_element = heading;
|
|
158
160
|
}
|
|
159
161
|
|
|
160
|
-
if (
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
current_level = heading_level;
|
|
165
|
-
} else if (heading_level > current_level) {
|
|
166
|
-
current_level++;
|
|
167
|
-
|
|
168
|
-
if (last_entry) {
|
|
169
|
-
last_entry.starts_level = true;
|
|
170
|
-
}
|
|
171
|
-
} else if (heading_level == current_level && last_entry) {
|
|
172
|
-
last_entry.starts_level = false;
|
|
173
|
-
} else if (heading_level < current_level) {
|
|
174
|
-
current_level--;
|
|
175
|
-
|
|
176
|
-
if (last_entry) {
|
|
177
|
-
last_entry.ends_level = true;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
162
|
+
if (title_element.nodeName[0] == 'H' && isFinite(title_element.nodeName[1])) {
|
|
163
|
+
heading_level = +title_element.nodeName[1];
|
|
164
|
+
} else if (!heading_level) {
|
|
165
|
+
heading_level = 1;
|
|
180
166
|
}
|
|
181
167
|
|
|
182
168
|
title = (title_element.toc_title || title_element.textContent || '').trim();
|
|
@@ -190,86 +176,39 @@ TableOfContents.setProperty(function entries() {
|
|
|
190
176
|
continue;
|
|
191
177
|
}
|
|
192
178
|
|
|
193
|
-
|
|
194
|
-
id
|
|
195
|
-
level
|
|
196
|
-
title
|
|
197
|
-
element
|
|
198
|
-
starts_level : starts_level,
|
|
199
|
-
ends_level : ends_level,
|
|
179
|
+
let node = {
|
|
180
|
+
id : heading.id,
|
|
181
|
+
level : heading_level,
|
|
182
|
+
title : title,
|
|
183
|
+
element : heading,
|
|
200
184
|
};
|
|
201
185
|
|
|
202
|
-
|
|
186
|
+
nodes.push(node);
|
|
203
187
|
}
|
|
204
188
|
|
|
205
|
-
|
|
206
|
-
entries = result,
|
|
207
|
-
current_branch,
|
|
208
|
-
current_nodes = [];
|
|
209
|
-
|
|
210
|
-
result = current_nodes;
|
|
211
|
-
last_entry = null;
|
|
212
|
-
|
|
213
|
-
for (let entry of entries) {
|
|
214
|
-
|
|
215
|
-
if (ended_level) {
|
|
216
|
-
|
|
217
|
-
while (entry.level >= current_branch.level) {
|
|
218
|
-
current_branch = current_branch.parent;
|
|
219
|
-
current_nodes = current_branch?.children || result;
|
|
220
|
-
|
|
221
|
-
if (!current_branch) {
|
|
222
|
-
current_branch = result[result.length - 1];
|
|
223
|
-
break;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
ended_level = false;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
if (!current_branch) {
|
|
231
|
-
current_branch = entry;
|
|
232
|
-
} else {
|
|
233
|
-
entry.parent = current_branch;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
if (entry.starts_level) {
|
|
237
|
-
|
|
238
|
-
current_branch = last_entry;
|
|
239
|
-
|
|
240
|
-
if (!current_branch.children) {
|
|
241
|
-
current_branch.children = [];
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
current_nodes = current_branch.children;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
current_nodes.push(entry);
|
|
248
|
-
|
|
249
|
-
if (entry.ends_level) {
|
|
250
|
-
ended_level = true;
|
|
251
|
-
current_branch = entry.parent;
|
|
252
|
-
current_nodes = current_branch.children || result;
|
|
253
|
-
|
|
254
|
-
if (!current_branch) {
|
|
255
|
-
current_branch = result[result.length - 1];
|
|
256
|
-
break;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
last_entry = entry;
|
|
261
|
-
}
|
|
189
|
+
result = nodes;
|
|
262
190
|
}
|
|
263
191
|
|
|
264
192
|
return result;
|
|
265
193
|
});
|
|
266
194
|
|
|
195
|
+
/**
|
|
196
|
+
* Get the entries tree
|
|
197
|
+
*
|
|
198
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
199
|
+
* @since 0.2.4
|
|
200
|
+
* @version 0.2.4
|
|
201
|
+
*/
|
|
202
|
+
TableOfContents.setProperty(function tree() {
|
|
203
|
+
return Blast.listToTree(this.entries);
|
|
204
|
+
});
|
|
205
|
+
|
|
267
206
|
/**
|
|
268
207
|
* Added to the dom for the first time
|
|
269
208
|
*
|
|
270
209
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
271
210
|
* @since 0.1.2
|
|
272
|
-
* @version 0.2.
|
|
211
|
+
* @version 0.2.4
|
|
273
212
|
*/
|
|
274
213
|
TableOfContents.setMethod(async function introduced() {
|
|
275
214
|
|
|
@@ -280,22 +219,51 @@ TableOfContents.setMethod(async function introduced() {
|
|
|
280
219
|
let class_name = this.intersection_class || 'visible',
|
|
281
220
|
first_name = class_name + '-first';
|
|
282
221
|
|
|
222
|
+
let intersect_map = new Map();
|
|
223
|
+
|
|
283
224
|
for (let entry of entries) {
|
|
284
|
-
const
|
|
225
|
+
const heading = entry.target[RELATED_HEADING] || entry.target;
|
|
226
|
+
const id = heading.getAttribute('id');
|
|
227
|
+
|
|
228
|
+
if (!id) {
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
285
231
|
|
|
286
232
|
let query = `a[href="#${id}"]`,
|
|
287
233
|
element = this.querySelector(query);
|
|
288
|
-
|
|
234
|
+
|
|
289
235
|
if (!element) {
|
|
290
|
-
|
|
236
|
+
continue;
|
|
291
237
|
}
|
|
292
238
|
|
|
239
|
+
let value = intersect_map.get(element) || 0;
|
|
240
|
+
|
|
293
241
|
if (entry.intersectionRatio > 0) {
|
|
242
|
+
value++;
|
|
243
|
+
} else {
|
|
244
|
+
let siblings = heading[RELATED_SIBLINGS];
|
|
245
|
+
|
|
246
|
+
if (siblings?.length) {
|
|
247
|
+
for (let sibling of siblings) {
|
|
248
|
+
if (sibling.isVisible(-150)) {
|
|
249
|
+
value++;
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
intersect_map.set(element, value);
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
for (let [element, value] of intersect_map) {
|
|
260
|
+
|
|
261
|
+
if (value > 0) {
|
|
294
262
|
element.classList.add(class_name);
|
|
295
263
|
} else {
|
|
296
264
|
element.classList.remove(class_name);
|
|
297
265
|
}
|
|
298
|
-
}
|
|
266
|
+
}
|
|
299
267
|
|
|
300
268
|
let is_visible,
|
|
301
269
|
all_marked = this.querySelectorAll('.' + class_name + ', .' + first_name),
|
|
@@ -317,10 +285,31 @@ TableOfContents.setMethod(async function introduced() {
|
|
|
317
285
|
seen++;
|
|
318
286
|
}
|
|
319
287
|
}
|
|
320
|
-
|
|
321
288
|
});
|
|
322
289
|
|
|
323
|
-
|
|
290
|
+
let entries = this.entries,
|
|
291
|
+
elements = [];
|
|
292
|
+
|
|
293
|
+
for (let entry of entries) {
|
|
324
294
|
observer.observe(entry.element);
|
|
295
|
+
elements.push(entry.element);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
for (let element of elements) {
|
|
299
|
+
|
|
300
|
+
element[RELATED_SIBLINGS] = [];
|
|
301
|
+
let sibling = element.nextElementSibling;
|
|
302
|
+
|
|
303
|
+
while (sibling) {
|
|
304
|
+
|
|
305
|
+
if (elements.includes(sibling)) {
|
|
306
|
+
break;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
element[RELATED_SIBLINGS].push(sibling);
|
|
310
|
+
sibling[RELATED_HEADING] = element;
|
|
311
|
+
observer.observe(sibling);
|
|
312
|
+
sibling = sibling.nextElementSibling;
|
|
313
|
+
}
|
|
325
314
|
}
|
|
326
315
|
});
|
|
@@ -11,6 +11,18 @@
|
|
|
11
11
|
*/
|
|
12
12
|
const List = Function.inherits('Alchemy.Widget.Container', 'List');
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Get a list of elements that could be child widgets
|
|
16
|
+
*
|
|
17
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
18
|
+
* @since 0.2.3
|
|
19
|
+
* @version 0.2.3
|
|
20
|
+
*/
|
|
21
|
+
List.setMethod(function getPossibleWidgetChildren() {
|
|
22
|
+
let children = this.widget.querySelectorAll(':scope > ul > li > *');
|
|
23
|
+
return children;
|
|
24
|
+
});
|
|
25
|
+
|
|
14
26
|
/**
|
|
15
27
|
* Dummy populate method
|
|
16
28
|
*
|
|
@@ -57,7 +57,7 @@ Partial.constitute(function prepareSchema() {
|
|
|
57
57
|
let contents = this.createSchema();
|
|
58
58
|
|
|
59
59
|
contents.addField('name', 'String');
|
|
60
|
-
contents.addField('
|
|
60
|
+
contents.addField('contents', 'Widgets');
|
|
61
61
|
|
|
62
62
|
this.schema.addField('contents', contents, {array: true});
|
|
63
63
|
});
|
|
@@ -87,7 +87,26 @@ Partial.setMethod(async function populateWidget() {
|
|
|
87
87
|
|
|
88
88
|
if (this.config?.contents?.length) {
|
|
89
89
|
for (let entry of this.config.contents) {
|
|
90
|
-
|
|
90
|
+
|
|
91
|
+
let actual_contents;
|
|
92
|
+
|
|
93
|
+
if (entry.contents) {
|
|
94
|
+
if (entry.contents.config) {
|
|
95
|
+
actual_contents = entry.contents.config;
|
|
96
|
+
} else if (entry.contents.widgets) {
|
|
97
|
+
actual_contents = entry.contents.widgets;
|
|
98
|
+
|
|
99
|
+
let type = actual_contents?.[0]?.type;
|
|
100
|
+
|
|
101
|
+
if (type == 'container' || type == 'row') {
|
|
102
|
+
actual_contents = actual_contents[0].config?.widgets;
|
|
103
|
+
} else {
|
|
104
|
+
actual_contents = actual_contents[0];
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
variables[entry.name] = actual_contents;
|
|
91
110
|
}
|
|
92
111
|
}
|
|
93
112
|
|
|
@@ -180,7 +199,7 @@ Partial.setMethod(function _stopEditor() {
|
|
|
180
199
|
*
|
|
181
200
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
182
201
|
* @since 0.1.6
|
|
183
|
-
* @version 0.
|
|
202
|
+
* @version 0.2.3
|
|
184
203
|
*
|
|
185
204
|
* @return {Object}
|
|
186
205
|
*/
|
|
@@ -206,7 +225,23 @@ Partial.setMethod(function syncConfig() {
|
|
|
206
225
|
contents.push(widget_config);
|
|
207
226
|
}
|
|
208
227
|
|
|
209
|
-
|
|
228
|
+
let value = sub_widget.value,
|
|
229
|
+
widget_contents;
|
|
230
|
+
|
|
231
|
+
if (value?.widgets) {
|
|
232
|
+
widget_contents = {
|
|
233
|
+
widgets : [{
|
|
234
|
+
type : 'row',
|
|
235
|
+
config : value,
|
|
236
|
+
}]
|
|
237
|
+
};
|
|
238
|
+
} else {
|
|
239
|
+
widget_contents = {
|
|
240
|
+
widgets: Array.cast(value)
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
widget_config.contents = widget_contents;
|
|
210
245
|
}
|
|
211
246
|
|
|
212
247
|
return this.config;
|
package/helper_field/widget.js
CHANGED
|
@@ -52,4 +52,26 @@ WidgetField.setMethod(function cast(value, to_datasource) {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
return value;
|
|
55
|
-
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Convert to JSON
|
|
59
|
+
*
|
|
60
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
61
|
+
* @since 0.2.3
|
|
62
|
+
* @version 0.2.3
|
|
63
|
+
*
|
|
64
|
+
* @return {Object}
|
|
65
|
+
*/
|
|
66
|
+
WidgetField.setMethod(function toDry() {
|
|
67
|
+
|
|
68
|
+
let {schema, ...options} = this.options;
|
|
69
|
+
|
|
70
|
+
let value = {
|
|
71
|
+
schema : this.schema,
|
|
72
|
+
name : this.name,
|
|
73
|
+
options : options,
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
return {value};
|
|
77
|
+
});
|
package/helper_field/widgets.js
CHANGED
|
@@ -22,4 +22,18 @@ const WidgetsField = Function.inherits('Alchemy.Field.Schema', function Widgets(
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
Widgets.super.call(this, schema, name, options);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Get the client-side options
|
|
29
|
+
*
|
|
30
|
+
* @author Jelle De Loecker <jelle@develry.be>
|
|
31
|
+
* @since 0.2.3
|
|
32
|
+
* @version 0.2.3
|
|
33
|
+
*
|
|
34
|
+
* @return {Object}
|
|
35
|
+
*/
|
|
36
|
+
WidgetsField.setMethod(function getOptionsForDrying() {
|
|
37
|
+
let {schema, ...options} = this.options;
|
|
38
|
+
return options;
|
|
25
39
|
});
|
package/package.json
CHANGED