alchemy-widget 0.2.0 → 0.2.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/CHANGELOG.md +20 -0
- package/assets/stylesheets/alchemy_widgets.scss +13 -8
- package/bootstrap.js +97 -0
- package/controller/alchemy_widgets_controller.js +64 -0
- package/element/00-widget_base_element.js +13 -4
- package/element/05-widget_element.js +29 -8
- package/element/10-container_elements.js +12 -17
- package/element/table_of_contents_element.js +44 -7
- package/helper/widgets/00-widget.js +191 -10
- package/helper/widgets/01-container.js +22 -0
- package/helper/widgets/alchemy_tabs_widget.js +0 -2
- package/helper/widgets/hawkejs_template.js +60 -0
- package/helper/widgets/header.js +5 -7
- package/helper/widgets/html.js +52 -3
- package/helper/widgets/markdown.js +1 -3
- package/helper/widgets/partial.js +1 -3
- package/helper/widgets/sourcecode.js +1 -3
- package/helper/widgets/table_of_contents.js +1 -3
- package/helper/widgets/text.js +15 -15
- package/package.json +2 -2
- package/view/elements/table_of_contents.hwk +11 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
## 0.2.1 (2022-12-23)
|
|
2
|
+
|
|
3
|
+
* Add a `-first` modifier class to the first visible entry of a table-of-contents element
|
|
4
|
+
* Make HTML widget editable
|
|
5
|
+
* Also store and retrieve copied widget config from localStorage
|
|
6
|
+
* Move `Container` widget init logic from the custom-element to the main widget instance
|
|
7
|
+
* Disable most `backdrop-filter` properties, they caused too many FPS issues
|
|
8
|
+
* Add the ability to hide widgets from the public
|
|
9
|
+
* Allow overriding the language (`lang` attribute) of a widget
|
|
10
|
+
* Fix config of container widgets not being saved
|
|
11
|
+
* Only add minium dimensions when editing
|
|
12
|
+
* Add `child-role` attribute & use it to set the default role of child widgets
|
|
13
|
+
* Add the `toc-has-content` or `toc-is-empty` class to `al-toc` elements
|
|
14
|
+
* Fix issue where `Text` widget would break when edited with LanguageTool extension
|
|
15
|
+
* Do not truncate titles in table-of-contents automatically
|
|
16
|
+
* Fix nesting levels in `al-toc`
|
|
17
|
+
* Only allow text inside header widgets
|
|
18
|
+
* Move default `Widget#populateWidget()` code to `Widget#finalizePopulatedWidget()`
|
|
19
|
+
* Add `HawkejsTemplate` widget
|
|
20
|
+
|
|
1
21
|
## 0.2.0 (2022-11-02)
|
|
2
22
|
|
|
3
23
|
* Use `al-` prefix for all custom elements
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
al-widget-toolbar {
|
|
3
3
|
display: none;
|
|
4
4
|
}
|
|
5
|
+
|
|
6
|
+
[hidden] {
|
|
7
|
+
display: none !important;
|
|
8
|
+
}
|
|
5
9
|
}
|
|
6
10
|
|
|
7
11
|
html.logged-in {
|
|
@@ -110,6 +114,7 @@ al-widgets-column {
|
|
|
110
114
|
&.aw-editing {
|
|
111
115
|
position: relative;
|
|
112
116
|
min-height: 3rem;
|
|
117
|
+
min-width: 10rem;
|
|
113
118
|
}
|
|
114
119
|
|
|
115
120
|
> * {
|
|
@@ -127,7 +132,7 @@ al-widget {
|
|
|
127
132
|
background: white;
|
|
128
133
|
border: 2px dashed rgba(0, 0, 0, 0.4);
|
|
129
134
|
pointer-events: none;
|
|
130
|
-
backdrop-filter: invert(80%);
|
|
135
|
+
//backdrop-filter: invert(80%);
|
|
131
136
|
clip-path: polygon(0% 0%, 0% 100%, 2px 100%, 2px 2px, calc(100% - 2px) 2px, calc(100% - 2px) calc(100% - 2px), 0 calc(100% - 2px), 0 100%, 100% 100%, 100% 0)
|
|
132
137
|
}
|
|
133
138
|
}
|
|
@@ -159,11 +164,6 @@ al-widgets-column {
|
|
|
159
164
|
}
|
|
160
165
|
}
|
|
161
166
|
|
|
162
|
-
al-widgets {
|
|
163
|
-
min-width: 10rem;
|
|
164
|
-
min-height: 10rem;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
167
|
al-widgets-row {
|
|
168
168
|
flex-flow: row;
|
|
169
169
|
flex: 10 10 auto;
|
|
@@ -287,12 +287,13 @@ al-widget {
|
|
|
287
287
|
|
|
288
288
|
&.aw-editing {
|
|
289
289
|
min-height: 2rem;
|
|
290
|
+
min-width: 2rem;
|
|
290
291
|
|
|
291
292
|
&:hover {
|
|
292
293
|
background: rgba(60, 60, 120, 0.2);
|
|
293
294
|
|
|
294
|
-
// This actually causes some glitches on Firefox :/
|
|
295
|
-
backdrop-filter: blur(4px);
|
|
295
|
+
// This actually causes some glitches on Firefox and chrome too :/
|
|
296
|
+
//backdrop-filter: blur(4px);
|
|
296
297
|
}
|
|
297
298
|
}
|
|
298
299
|
|
|
@@ -423,4 +424,8 @@ al-toc {
|
|
|
423
424
|
display: block;
|
|
424
425
|
}
|
|
425
426
|
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
.aw-hidden {
|
|
430
|
+
opacity: 0.8;
|
|
426
431
|
}
|
package/bootstrap.js
CHANGED
|
@@ -4,9 +4,106 @@ if (!alchemy.plugins.form) {
|
|
|
4
4
|
throw new Error('The alchemy-form plugin has to be loaded BEFORE alchemy-widget');
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
+
/* Ckeditor 5 available toolbar buttons (from styleboost build)
|
|
8
|
+
[
|
|
9
|
+
"blockQuote",
|
|
10
|
+
"bold",
|
|
11
|
+
"code",
|
|
12
|
+
"codeBlock",
|
|
13
|
+
"selectAll",
|
|
14
|
+
"undo",
|
|
15
|
+
"redo",
|
|
16
|
+
"heading",
|
|
17
|
+
"horizontalLine",
|
|
18
|
+
"imageTextAlternative",
|
|
19
|
+
"toggleImageCaption",
|
|
20
|
+
"imageStyle:inline",
|
|
21
|
+
"imageStyle:alignLeft",
|
|
22
|
+
"imageStyle:alignRight",
|
|
23
|
+
"imageStyle:alignCenter",
|
|
24
|
+
"imageStyle:alignBlockLeft",
|
|
25
|
+
"imageStyle:alignBlockRight",
|
|
26
|
+
"imageStyle:block",
|
|
27
|
+
"imageStyle:side",
|
|
28
|
+
"imageStyle:wrapText",
|
|
29
|
+
"imageStyle:breakText",
|
|
30
|
+
"uploadImage",
|
|
31
|
+
"imageUpload",
|
|
32
|
+
"indent",
|
|
33
|
+
"outdent",
|
|
34
|
+
"italic",
|
|
35
|
+
"link",
|
|
36
|
+
"linkImage",
|
|
37
|
+
"numberedList",
|
|
38
|
+
"bulletedList",
|
|
39
|
+
"mediaEmbed",
|
|
40
|
+
"removeFormat",
|
|
41
|
+
"sourceEditing",
|
|
42
|
+
"strikethrough",
|
|
43
|
+
"insertTable",
|
|
44
|
+
"tableColumn",
|
|
45
|
+
"tableRow",
|
|
46
|
+
"mergeTableCells",
|
|
47
|
+
"toggleTableCaption",
|
|
48
|
+
"tableCellProperties",
|
|
49
|
+
"tableProperties",
|
|
50
|
+
"todoList"
|
|
51
|
+
]
|
|
52
|
+
*/
|
|
53
|
+
|
|
54
|
+
let options = {
|
|
55
|
+
ckeditor_path: null,
|
|
56
|
+
ckeditor_toolbar: [
|
|
57
|
+
'heading',
|
|
58
|
+
'|',
|
|
59
|
+
'bold', 'italic', 'link', 'bulletedList', 'numberedList',
|
|
60
|
+
'|',
|
|
61
|
+
'indent',
|
|
62
|
+
'outdent',
|
|
63
|
+
'horizontalLine',
|
|
64
|
+
'|',
|
|
65
|
+
'blockQuote',
|
|
66
|
+
'code',
|
|
67
|
+
'codeBlock',
|
|
68
|
+
'|',
|
|
69
|
+
'imageUpload',
|
|
70
|
+
'insertTable',
|
|
71
|
+
'|',
|
|
72
|
+
'undo', 'redo',
|
|
73
|
+
],
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// Inject the user-overridden options
|
|
77
|
+
alchemy.plugins.widget = Object.assign(options, alchemy.plugins.widget);
|
|
78
|
+
|
|
79
|
+
if (!options.ckeditor_path) {
|
|
80
|
+
if (alchemy.plugins.styleboost) {
|
|
81
|
+
options.ckeditor_path = '/public/ckeditor/5/ckeditor.js';
|
|
82
|
+
} else {
|
|
83
|
+
options.ckeditor_path = 'https://cdn.ckeditor.com/ckeditor5/35.3.2/inline/ckeditor.js';
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (options.ckeditor_path) {
|
|
88
|
+
alchemy.exposeStatic('ckeditor_path', options.ckeditor_path);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (options.ckeditor_toolbar) {
|
|
92
|
+
alchemy.exposeStatic('ckeditor_toolbar', options.ckeditor_toolbar);
|
|
93
|
+
}
|
|
94
|
+
|
|
7
95
|
Router.add({
|
|
8
96
|
name : 'AlchemyWidgets#save',
|
|
9
97
|
methods : 'post',
|
|
10
98
|
paths : '/api/alchemywidgets/save',
|
|
11
99
|
policy : 'logged_in',
|
|
100
|
+
permission : 'alchemy.widgets.save',
|
|
12
101
|
});
|
|
102
|
+
|
|
103
|
+
Router.add({
|
|
104
|
+
name : 'AlchemyWidgets#uploadImage',
|
|
105
|
+
methods : 'post',
|
|
106
|
+
paths : '/api/alchemywidgets/upload',
|
|
107
|
+
policy : 'logged_in',
|
|
108
|
+
permission : 'alchemy.widgets.image.upload',
|
|
109
|
+
});
|
|
@@ -184,4 +184,68 @@ AlchemyWidgets.setAction(async function save(conduit) {
|
|
|
184
184
|
};
|
|
185
185
|
|
|
186
186
|
conduit.end(result);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Handle an image upload from within CKeditor
|
|
191
|
+
*
|
|
192
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
193
|
+
* @since 0.2.1
|
|
194
|
+
* @version 0.2.1
|
|
195
|
+
*/
|
|
196
|
+
AlchemyWidgets.setAction(async function uploadImage(conduit) {
|
|
197
|
+
|
|
198
|
+
let file = conduit.files.upload;
|
|
199
|
+
|
|
200
|
+
const MediaFile = this.getModel('MediaFile');
|
|
201
|
+
|
|
202
|
+
let name = file.name.split('.');
|
|
203
|
+
|
|
204
|
+
// Remove the last piece if there are more than 1
|
|
205
|
+
if (name.length > 1) {
|
|
206
|
+
name.pop();
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Join them again
|
|
210
|
+
name = name.join('.');
|
|
211
|
+
|
|
212
|
+
const options = {
|
|
213
|
+
move : true,
|
|
214
|
+
filename : file.name,
|
|
215
|
+
name : name,
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
MediaFile.addFile(file.path, options, (err, result) => {
|
|
219
|
+
|
|
220
|
+
if (err) {
|
|
221
|
+
return conduit.error(err);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const params = {
|
|
225
|
+
id : result._id,
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
let default_path = alchemy.routeUrl('Media::image', params);
|
|
229
|
+
let url = RURL.parse(default_path);
|
|
230
|
+
|
|
231
|
+
let path_800 = url.clone();
|
|
232
|
+
path_800.param('width', '800');
|
|
233
|
+
|
|
234
|
+
let path_1024 = url.clone();
|
|
235
|
+
path_1024.param('height', '1024');
|
|
236
|
+
|
|
237
|
+
let path_1920 = url.clone();
|
|
238
|
+
path_1920.param('width', '1920');
|
|
239
|
+
|
|
240
|
+
let response = {
|
|
241
|
+
urls: {
|
|
242
|
+
default : default_path,
|
|
243
|
+
'800' : path_800+'',
|
|
244
|
+
'1024' : path_1024+'',
|
|
245
|
+
'1920' : path_1920+''
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
conduit.end(response);
|
|
250
|
+
});
|
|
187
251
|
});
|
|
@@ -364,7 +364,7 @@ Base.setMethod(async function save() {
|
|
|
364
364
|
*
|
|
365
365
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
366
366
|
* @since 0.2.0
|
|
367
|
-
* @version 0.2.
|
|
367
|
+
* @version 0.2.1
|
|
368
368
|
*/
|
|
369
369
|
Base.setMethod(async function copyConfigToClipboard() {
|
|
370
370
|
|
|
@@ -377,11 +377,15 @@ Base.setMethod(async function copyConfigToClipboard() {
|
|
|
377
377
|
value._altype = 'widget';
|
|
378
378
|
value.type = this.type;
|
|
379
379
|
|
|
380
|
+
let dried = JSON.dry(value, null, '\t');
|
|
381
|
+
|
|
380
382
|
try {
|
|
381
|
-
await navigator.clipboard.writeText(
|
|
383
|
+
await navigator.clipboard.writeText(dried);
|
|
382
384
|
} catch (err) {
|
|
383
385
|
console.error('Failed to copy:', err);
|
|
384
386
|
}
|
|
387
|
+
|
|
388
|
+
localStorage._copied_widget_config = dried;
|
|
385
389
|
});
|
|
386
390
|
|
|
387
391
|
/**
|
|
@@ -389,7 +393,7 @@ Base.setMethod(async function copyConfigToClipboard() {
|
|
|
389
393
|
*
|
|
390
394
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
391
395
|
* @since 0.2.0
|
|
392
|
-
* @version 0.2.
|
|
396
|
+
* @version 0.2.1
|
|
393
397
|
*/
|
|
394
398
|
Base.setMethod(async function getConfigFromClipboard() {
|
|
395
399
|
|
|
@@ -398,7 +402,12 @@ Base.setMethod(async function getConfigFromClipboard() {
|
|
|
398
402
|
try {
|
|
399
403
|
result = await navigator.clipboard.readText();
|
|
400
404
|
} catch (err) {
|
|
401
|
-
|
|
405
|
+
|
|
406
|
+
if (!localStorage._copied_widget_config) {
|
|
407
|
+
return false;
|
|
408
|
+
} else {
|
|
409
|
+
result = localStorage._copied_widget_config;
|
|
410
|
+
}
|
|
402
411
|
}
|
|
403
412
|
|
|
404
413
|
if (result) {
|
|
@@ -79,6 +79,15 @@ Widget.setAssignedProperty('filter_value');
|
|
|
79
79
|
*/
|
|
80
80
|
Widget.setAttribute('child-class');
|
|
81
81
|
|
|
82
|
+
/**
|
|
83
|
+
* A role to give to each child widgets
|
|
84
|
+
*
|
|
85
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
86
|
+
* @since 0.2.1
|
|
87
|
+
* @version 0.2.1
|
|
88
|
+
*/
|
|
89
|
+
Widget.setAttribute('child-role');
|
|
90
|
+
|
|
82
91
|
/**
|
|
83
92
|
* Is this widget being edited?
|
|
84
93
|
*
|
|
@@ -269,13 +278,11 @@ Widget.setMethod(function syncConfig() {
|
|
|
269
278
|
*
|
|
270
279
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
271
280
|
* @since 0.1.0
|
|
272
|
-
* @version 0.1
|
|
281
|
+
* @version 0.2.1
|
|
273
282
|
*/
|
|
274
283
|
Widget.setMethod(function startEditor() {
|
|
275
284
|
|
|
276
|
-
|
|
277
|
-
throw new Error('Unable to start the editor: this widget element has no accompanying instance');
|
|
278
|
-
}
|
|
285
|
+
this.assertWidgetInstance();
|
|
279
286
|
|
|
280
287
|
this.instance.startEditor();
|
|
281
288
|
this.addEditEventListeners();
|
|
@@ -286,19 +293,33 @@ Widget.setMethod(function startEditor() {
|
|
|
286
293
|
*
|
|
287
294
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
288
295
|
* @since 0.1.0
|
|
289
|
-
* @version 0.1
|
|
296
|
+
* @version 0.2.1
|
|
290
297
|
*/
|
|
291
298
|
Widget.setMethod(function stopEditor() {
|
|
292
299
|
|
|
293
|
-
|
|
294
|
-
throw new Error('Unable to stop the editor: this widget element has no accompanying instance');
|
|
295
|
-
}
|
|
300
|
+
this.assertWidgetInstance();
|
|
296
301
|
|
|
297
302
|
this.unselectWidget();
|
|
298
303
|
this.instance.stopEditor();
|
|
299
304
|
this.removeEditEventListeners();
|
|
300
305
|
});
|
|
301
306
|
|
|
307
|
+
/**
|
|
308
|
+
* Make sure there is an instance
|
|
309
|
+
*
|
|
310
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
311
|
+
* @since 0.2.1
|
|
312
|
+
* @version 0.2.1
|
|
313
|
+
*/
|
|
314
|
+
Widget.setMethod(function assertWidgetInstance() {
|
|
315
|
+
|
|
316
|
+
if (!this.instance) {
|
|
317
|
+
console.error('Problem with widget element:', this);
|
|
318
|
+
throw new Error('Unable to stop the editor: this ' + this.tagName + ' element has no accompanying instance');
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
});
|
|
322
|
+
|
|
302
323
|
/**
|
|
303
324
|
* Mouse click
|
|
304
325
|
*
|
|
@@ -62,21 +62,22 @@ AlchemyWidgets.setAssignedProperty('context_variables', function getContextData(
|
|
|
62
62
|
*
|
|
63
63
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
64
64
|
* @since 0.1.0
|
|
65
|
-
* @version 0.1
|
|
65
|
+
* @version 0.2.1
|
|
66
66
|
*/
|
|
67
67
|
AlchemyWidgets.setProperty(function value() {
|
|
68
68
|
|
|
69
|
-
let
|
|
69
|
+
let config = this.instance.config,
|
|
70
|
+
widgets = this.getWidgetsConfig(),
|
|
70
71
|
result;
|
|
72
|
+
|
|
73
|
+
config = Object.assign({}, config, {widgets});
|
|
71
74
|
|
|
72
75
|
if (this.nodeName == 'AL-WIDGETS') {
|
|
73
|
-
result =
|
|
76
|
+
result = config;
|
|
74
77
|
} else {
|
|
75
78
|
result = {
|
|
76
79
|
type : this.instance.constructor.type_name,
|
|
77
|
-
config :
|
|
78
|
-
widgets : widgets
|
|
79
|
-
}
|
|
80
|
+
config : config,
|
|
80
81
|
};
|
|
81
82
|
}
|
|
82
83
|
|
|
@@ -91,7 +92,7 @@ AlchemyWidgets.setProperty(function value() {
|
|
|
91
92
|
*
|
|
92
93
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
93
94
|
* @since 0.1.5
|
|
94
|
-
* @version 0.1
|
|
95
|
+
* @version 0.2.1
|
|
95
96
|
*/
|
|
96
97
|
AlchemyWidgets.setMethod(function applyValue(value) {
|
|
97
98
|
|
|
@@ -119,24 +120,18 @@ AlchemyWidgets.setMethod(function applyValue(value) {
|
|
|
119
120
|
if (config.class_names) {
|
|
120
121
|
Hawkejs.addClasses(this, config.class_names);
|
|
121
122
|
}
|
|
123
|
+
} else {
|
|
124
|
+
config = this.instance?.config || {};
|
|
122
125
|
}
|
|
123
126
|
|
|
124
127
|
if (!this.instance) {
|
|
125
128
|
return;
|
|
126
129
|
}
|
|
127
130
|
|
|
131
|
+
config.widgets = widgets;
|
|
132
|
+
|
|
128
133
|
this.instance.config = config;
|
|
129
134
|
this.instance.initContainer();
|
|
130
|
-
|
|
131
|
-
if (!widgets || !widgets.length) {
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
let widget;
|
|
136
|
-
|
|
137
|
-
for (widget of widgets) {
|
|
138
|
-
this.addWidget(widget.type, widget.config);
|
|
139
|
-
}
|
|
140
135
|
});
|
|
141
136
|
|
|
142
137
|
/**
|
|
@@ -88,12 +88,21 @@ TableOfContents.setAttribute('title-selector');
|
|
|
88
88
|
*/
|
|
89
89
|
TableOfContents.setAttribute('intersection-class');
|
|
90
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Should titles be truncated?
|
|
93
|
+
*
|
|
94
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
95
|
+
* @since 0.2.1
|
|
96
|
+
* @version 0.2.1
|
|
97
|
+
*/
|
|
98
|
+
TableOfContents.setAttribute('truncate-length', {type: 'number'});
|
|
99
|
+
|
|
91
100
|
/**
|
|
92
101
|
* Get the entries
|
|
93
102
|
*
|
|
94
103
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
95
104
|
* @since 0.1.2
|
|
96
|
-
* @version 0.2.
|
|
105
|
+
* @version 0.2.1
|
|
97
106
|
*/
|
|
98
107
|
TableOfContents.setProperty(function entries() {
|
|
99
108
|
|
|
@@ -138,7 +147,7 @@ TableOfContents.setProperty(function entries() {
|
|
|
138
147
|
|
|
139
148
|
let title_element,
|
|
140
149
|
starts_level,
|
|
141
|
-
|
|
150
|
+
ends_level;
|
|
142
151
|
|
|
143
152
|
if (this.title_selector) {
|
|
144
153
|
title_element = element.querySelector(this.title_selector);
|
|
@@ -155,7 +164,10 @@ TableOfContents.setProperty(function entries() {
|
|
|
155
164
|
current_level = heading_level;
|
|
156
165
|
} else if (heading_level > current_level) {
|
|
157
166
|
current_level++;
|
|
158
|
-
|
|
167
|
+
|
|
168
|
+
if (last_entry) {
|
|
169
|
+
last_entry.starts_level = true;
|
|
170
|
+
}
|
|
159
171
|
} else if (heading_level == current_level && last_entry) {
|
|
160
172
|
last_entry.starts_level = false;
|
|
161
173
|
} else if (heading_level < current_level) {
|
|
@@ -169,7 +181,9 @@ TableOfContents.setProperty(function entries() {
|
|
|
169
181
|
|
|
170
182
|
title = (title_element.toc_title || title_element.textContent || '').trim();
|
|
171
183
|
|
|
172
|
-
|
|
184
|
+
if (this.truncate_length) {
|
|
185
|
+
title = title.truncate(this.truncate_length);
|
|
186
|
+
}
|
|
173
187
|
|
|
174
188
|
// Don't add empty titles
|
|
175
189
|
if (!title) {
|
|
@@ -191,7 +205,7 @@ TableOfContents.setProperty(function entries() {
|
|
|
191
205
|
let ended_level = false,
|
|
192
206
|
entries = result,
|
|
193
207
|
current_branch,
|
|
194
|
-
|
|
208
|
+
current_nodes = [];
|
|
195
209
|
|
|
196
210
|
result = current_nodes;
|
|
197
211
|
last_entry = null;
|
|
@@ -255,7 +269,7 @@ TableOfContents.setProperty(function entries() {
|
|
|
255
269
|
*
|
|
256
270
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
257
271
|
* @since 0.1.2
|
|
258
|
-
* @version 0.1
|
|
272
|
+
* @version 0.2.1
|
|
259
273
|
*/
|
|
260
274
|
TableOfContents.setMethod(async function introduced() {
|
|
261
275
|
|
|
@@ -263,7 +277,8 @@ TableOfContents.setMethod(async function introduced() {
|
|
|
263
277
|
|
|
264
278
|
const observer = new IntersectionObserver(entries => {
|
|
265
279
|
|
|
266
|
-
let class_name = this.intersection_class || 'visible'
|
|
280
|
+
let class_name = this.intersection_class || 'visible',
|
|
281
|
+
first_name = class_name + '-first';
|
|
267
282
|
|
|
268
283
|
for (let entry of entries) {
|
|
269
284
|
const id = entry.target.getAttribute('id');
|
|
@@ -281,6 +296,28 @@ TableOfContents.setMethod(async function introduced() {
|
|
|
281
296
|
element.classList.remove(class_name);
|
|
282
297
|
}
|
|
283
298
|
};
|
|
299
|
+
|
|
300
|
+
let is_visible,
|
|
301
|
+
all_marked = this.querySelectorAll('.' + class_name + ', .' + first_name),
|
|
302
|
+
element,
|
|
303
|
+
seen = 0,
|
|
304
|
+
i;
|
|
305
|
+
|
|
306
|
+
for (i = 0; i < all_marked.length; i++) {
|
|
307
|
+
element = all_marked[i];
|
|
308
|
+
is_visible = element.classList.contains(class_name);
|
|
309
|
+
|
|
310
|
+
if (is_visible && seen == 0) {
|
|
311
|
+
element.classList.add(first_name);
|
|
312
|
+
} else {
|
|
313
|
+
element.classList.remove(first_name);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
if (is_visible) {
|
|
317
|
+
seen++;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
284
321
|
});
|
|
285
322
|
|
|
286
323
|
for (let entry of this.entries) {
|
|
@@ -5,14 +5,18 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
7
7
|
* @since 0.1.0
|
|
8
|
-
* @version 0.1
|
|
8
|
+
* @version 0.2.1
|
|
9
9
|
*
|
|
10
10
|
* @param {Object} config
|
|
11
11
|
*/
|
|
12
12
|
const Widget = Function.inherits('Alchemy.Base', 'Alchemy.Widget', function Widget(config) {
|
|
13
13
|
|
|
14
14
|
// The configuration of this widget
|
|
15
|
-
|
|
15
|
+
if (config) {
|
|
16
|
+
this.config = config;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
this.originalconfig = this.config;
|
|
16
20
|
|
|
17
21
|
// Are we currently editing?
|
|
18
22
|
this.editing = false;
|
|
@@ -72,6 +76,24 @@ Widget.setProperty(function element() {
|
|
|
72
76
|
return this.widget = element;
|
|
73
77
|
});
|
|
74
78
|
|
|
79
|
+
/**
|
|
80
|
+
* The config object
|
|
81
|
+
*
|
|
82
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
83
|
+
* @since 0.2.1
|
|
84
|
+
* @version 0.2.1
|
|
85
|
+
*
|
|
86
|
+
* @type {Object}
|
|
87
|
+
*/
|
|
88
|
+
Widget.enforceProperty(function config(new_value) {
|
|
89
|
+
|
|
90
|
+
if (!new_value) {
|
|
91
|
+
new_value = {};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return new_value;
|
|
95
|
+
});
|
|
96
|
+
|
|
75
97
|
/**
|
|
76
98
|
* A reference to the renderer
|
|
77
99
|
*
|
|
@@ -96,12 +118,37 @@ Widget.enforceProperty(function hawkejs_renderer(new_value) {
|
|
|
96
118
|
return new_value;
|
|
97
119
|
});
|
|
98
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Visibility of the widget
|
|
123
|
+
*
|
|
124
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
125
|
+
* @since 0.2.1
|
|
126
|
+
* @version 0.2.1
|
|
127
|
+
*
|
|
128
|
+
* @type {Boolean}
|
|
129
|
+
*/
|
|
130
|
+
Widget.enforceProperty(function is_hidden(new_value) {
|
|
131
|
+
|
|
132
|
+
if (new_value == null) {
|
|
133
|
+
new_value = this.config.hidden;
|
|
134
|
+
|
|
135
|
+
if (new_value == null) {
|
|
136
|
+
new_value = false;
|
|
137
|
+
}
|
|
138
|
+
} else {
|
|
139
|
+
this.config.hidden = new_value;
|
|
140
|
+
this.queueVisibilityUpdate();
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return new_value;
|
|
144
|
+
});
|
|
145
|
+
|
|
99
146
|
/**
|
|
100
147
|
* Prepare the schema & actions
|
|
101
148
|
*
|
|
102
149
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
103
150
|
* @since 0.1.0
|
|
104
|
-
* @version 0.2.
|
|
151
|
+
* @version 0.2.1
|
|
105
152
|
*/
|
|
106
153
|
Widget.constitute(function prepareSchema() {
|
|
107
154
|
|
|
@@ -126,6 +173,19 @@ Widget.constitute(function prepareSchema() {
|
|
|
126
173
|
array: true,
|
|
127
174
|
});
|
|
128
175
|
|
|
176
|
+
// Should this widget be hidden?
|
|
177
|
+
this.schema.addField('hidden', 'Boolean', {
|
|
178
|
+
title : 'Should this widget be hidden?',
|
|
179
|
+
description : 'Hidden widgets are only visible during editing',
|
|
180
|
+
default : false,
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
this.schema.addField('language', 'String', {
|
|
184
|
+
title : 'Language override',
|
|
185
|
+
description : 'If the content of this widget is in a different language, set it here',
|
|
186
|
+
widget_config_editable : true,
|
|
187
|
+
});
|
|
188
|
+
|
|
129
189
|
// Add the "copy to clipboard" action
|
|
130
190
|
let copy = this.createAction('copy', 'Copy to clipboard');
|
|
131
191
|
|
|
@@ -167,6 +227,36 @@ Widget.constitute(function prepareSchema() {
|
|
|
167
227
|
|
|
168
228
|
save.setIcon('floppy-disk');
|
|
169
229
|
|
|
230
|
+
// Add the hide action
|
|
231
|
+
let hide = this.createAction('hide', 'Hide');
|
|
232
|
+
|
|
233
|
+
hide.close_actionbar = true;
|
|
234
|
+
|
|
235
|
+
hide.setHandler(function hideAction(widget_el, handle) {
|
|
236
|
+
widget_el.instance.is_hidden = true;
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
hide.setTester(function hideTester(widget_el, handle) {
|
|
240
|
+
return !widget_el.instance.is_hidden;
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
hide.setIcon('eye-slash');
|
|
244
|
+
|
|
245
|
+
// Add the show action
|
|
246
|
+
let show = this.createAction('show', 'Show');
|
|
247
|
+
|
|
248
|
+
show.close_actionbar = true;
|
|
249
|
+
|
|
250
|
+
show.setHandler(function showAction(widget_el, handle) {
|
|
251
|
+
widget_el.instance.is_hidden = false;
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
show.setTester(function showTester(widget_el, handle) {
|
|
255
|
+
return widget_el.instance.is_hidden;
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
show.setIcon('eye');
|
|
259
|
+
|
|
170
260
|
// Add the remove action
|
|
171
261
|
let remove = this.createAction('remove', 'Remove');
|
|
172
262
|
|
|
@@ -559,20 +649,34 @@ Widget.setMethod(function _createPopulatedWidgetElement() {
|
|
|
559
649
|
return element;
|
|
560
650
|
});
|
|
561
651
|
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* Populate the actual widget
|
|
655
|
+
*
|
|
656
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
657
|
+
* @since 0.2.1
|
|
658
|
+
* @version 0.2.1
|
|
659
|
+
*/
|
|
660
|
+
Widget.setMethod(function populateWidget() {
|
|
661
|
+
// Does nothing on its own
|
|
662
|
+
});
|
|
663
|
+
|
|
562
664
|
/**
|
|
563
665
|
* Populate the contents of the widget
|
|
564
666
|
*
|
|
565
667
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
566
668
|
* @since 0.1.0
|
|
567
|
-
* @version 0.1
|
|
669
|
+
* @version 0.2.1
|
|
568
670
|
*/
|
|
569
|
-
Widget.setMethod(function
|
|
671
|
+
Widget.setMethod(function finalizePopulatedWidget() {
|
|
672
|
+
|
|
673
|
+
const config = this.config;
|
|
570
674
|
|
|
571
|
-
if (
|
|
675
|
+
if (config.wrapper_class_names) {
|
|
572
676
|
let name,
|
|
573
677
|
i;
|
|
574
678
|
|
|
575
|
-
let class_names = Array.cast(
|
|
679
|
+
let class_names = Array.cast(config.wrapper_class_names);
|
|
576
680
|
|
|
577
681
|
for (i = 0; i < class_names.length; i++) {
|
|
578
682
|
name = class_names[i];
|
|
@@ -580,6 +684,12 @@ Widget.setMethod(function populateWidget() {
|
|
|
580
684
|
}
|
|
581
685
|
}
|
|
582
686
|
|
|
687
|
+
if (config.language) {
|
|
688
|
+
this.widget.setAttribute('lang', config.language);
|
|
689
|
+
} else {
|
|
690
|
+
this.widget.removeAttribute('lang');
|
|
691
|
+
}
|
|
692
|
+
|
|
583
693
|
let child_classes = this.widget.child_class;
|
|
584
694
|
|
|
585
695
|
if (child_classes) {
|
|
@@ -590,6 +700,68 @@ Widget.setMethod(function populateWidget() {
|
|
|
590
700
|
Hawkejs.addClasses(children[i], child_classes);
|
|
591
701
|
}
|
|
592
702
|
}
|
|
703
|
+
|
|
704
|
+
let child_roles = this.widget.child_role;
|
|
705
|
+
|
|
706
|
+
if (child_roles) {
|
|
707
|
+
let children = this.widget.children,
|
|
708
|
+
child,
|
|
709
|
+
i;
|
|
710
|
+
|
|
711
|
+
for (i = 0; i < children.length; i++) {
|
|
712
|
+
child = children[i];
|
|
713
|
+
|
|
714
|
+
if (!child.hasAttribute('role')) {
|
|
715
|
+
child.setAttribute('role', child_roles);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
this.checkVisibility();
|
|
721
|
+
});
|
|
722
|
+
|
|
723
|
+
/**
|
|
724
|
+
* Queue a widget element visibility update
|
|
725
|
+
*
|
|
726
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
727
|
+
* @since 0.2.1
|
|
728
|
+
* @version 0.2.1
|
|
729
|
+
*/
|
|
730
|
+
Widget.setMethod(function queueVisibilityUpdate() {
|
|
731
|
+
|
|
732
|
+
if (this._visibility_update_queue) {
|
|
733
|
+
clearTimeout(this._visibility_update_queue);
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
this._visibility_update_queue = setTimeout(() => {
|
|
737
|
+
this.checkVisibility();
|
|
738
|
+
this._visibility_update_queue = null;
|
|
739
|
+
}, 50);
|
|
740
|
+
});
|
|
741
|
+
|
|
742
|
+
/**
|
|
743
|
+
* Check the widget element visibility
|
|
744
|
+
*
|
|
745
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
746
|
+
* @since 0.2.1
|
|
747
|
+
* @version 0.2.1
|
|
748
|
+
*/
|
|
749
|
+
Widget.setMethod(function checkVisibility() {
|
|
750
|
+
|
|
751
|
+
let should_be_hidden = this.is_hidden;
|
|
752
|
+
|
|
753
|
+
if (this.editing) {
|
|
754
|
+
this.widget.hidden = false;
|
|
755
|
+
} else {
|
|
756
|
+
this.widget.hidden = should_be_hidden;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
if (should_be_hidden) {
|
|
760
|
+
this.widget.classList.add('aw-hidden');
|
|
761
|
+
} else {
|
|
762
|
+
this.widget.classList.remove('aw-hidden');
|
|
763
|
+
}
|
|
764
|
+
|
|
593
765
|
});
|
|
594
766
|
|
|
595
767
|
/**
|
|
@@ -597,7 +769,7 @@ Widget.setMethod(function populateWidget() {
|
|
|
597
769
|
*
|
|
598
770
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
599
771
|
* @since 0.1.0
|
|
600
|
-
* @version 0.1
|
|
772
|
+
* @version 0.2.1
|
|
601
773
|
*/
|
|
602
774
|
Widget.setMethod(async function startEditor() {
|
|
603
775
|
|
|
@@ -617,6 +789,8 @@ Widget.setMethod(async function startEditor() {
|
|
|
617
789
|
if (typeof this._startEditor == 'function') {
|
|
618
790
|
this._startEditor();
|
|
619
791
|
}
|
|
792
|
+
|
|
793
|
+
this.checkVisibility();
|
|
620
794
|
});
|
|
621
795
|
|
|
622
796
|
/**
|
|
@@ -624,7 +798,7 @@ Widget.setMethod(async function startEditor() {
|
|
|
624
798
|
*
|
|
625
799
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
626
800
|
* @since 0.1.0
|
|
627
|
-
* @version 0.1
|
|
801
|
+
* @version 0.2.1
|
|
628
802
|
*/
|
|
629
803
|
Widget.setMethod(function stopEditor() {
|
|
630
804
|
|
|
@@ -638,7 +812,13 @@ Widget.setMethod(function stopEditor() {
|
|
|
638
812
|
|
|
639
813
|
if (typeof this._stopEditor == 'function') {
|
|
640
814
|
this._stopEditor();
|
|
815
|
+
|
|
816
|
+
// Remove the editing class again
|
|
817
|
+
// (some editors will try to restore the original classes)
|
|
818
|
+
this.widget.classList.remove('aw-editing');
|
|
641
819
|
}
|
|
820
|
+
|
|
821
|
+
this.checkVisibility();
|
|
642
822
|
});
|
|
643
823
|
|
|
644
824
|
/**
|
|
@@ -646,13 +826,14 @@ Widget.setMethod(function stopEditor() {
|
|
|
646
826
|
*
|
|
647
827
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
648
828
|
* @since 0.1.0
|
|
649
|
-
* @version 0.1
|
|
829
|
+
* @version 0.2.1
|
|
650
830
|
*/
|
|
651
831
|
Widget.setMethod(async function rerender() {
|
|
652
832
|
|
|
653
833
|
Hawkejs.removeChildren(this.widget);
|
|
654
834
|
|
|
655
835
|
await this.populateWidget();
|
|
836
|
+
await this.finalizePopulatedWidget();
|
|
656
837
|
|
|
657
838
|
if (this.editing) {
|
|
658
839
|
this.startEditor();
|
|
@@ -46,6 +46,28 @@ Container.setMethod(function initContainer() {
|
|
|
46
46
|
this.populateWidget();
|
|
47
47
|
});
|
|
48
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Populate the widget
|
|
51
|
+
*
|
|
52
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
53
|
+
* @since 0.2.1
|
|
54
|
+
* @version 0.2.1
|
|
55
|
+
*
|
|
56
|
+
* @return {HTMLElement}
|
|
57
|
+
*/
|
|
58
|
+
Container.setMethod(function populateWidget() {
|
|
59
|
+
|
|
60
|
+
const widgets = this.config.widgets;
|
|
61
|
+
|
|
62
|
+
if (widgets?.length) {
|
|
63
|
+
let widget;
|
|
64
|
+
|
|
65
|
+
for (widget of widgets) {
|
|
66
|
+
this.widget.addWidget(widget.type, widget.config);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
49
71
|
/**
|
|
50
72
|
* Create an instance of the HTML element representing this widget
|
|
51
73
|
*
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Widget Template class
|
|
3
|
+
*
|
|
4
|
+
* @constructor
|
|
5
|
+
*
|
|
6
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
7
|
+
* @since 0.2.1
|
|
8
|
+
* @version 0.2.1
|
|
9
|
+
*
|
|
10
|
+
* @param {Object} data
|
|
11
|
+
*/
|
|
12
|
+
const Template = Function.inherits('Alchemy.Widget.Sourcecode', 'HawkejsTemplate');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Populate the widget
|
|
16
|
+
*
|
|
17
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
18
|
+
* @since 0.2.1
|
|
19
|
+
* @version 0.2.1
|
|
20
|
+
*
|
|
21
|
+
* @param {HTMLElement} widget
|
|
22
|
+
*/
|
|
23
|
+
Template.setMethod(async function populateWidget() {
|
|
24
|
+
|
|
25
|
+
let input = this.config.sourcecode;
|
|
26
|
+
|
|
27
|
+
if (input) {
|
|
28
|
+
input = input.trim();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
Hawkejs.removeChildren(this.widget);
|
|
32
|
+
|
|
33
|
+
if (input) {
|
|
34
|
+
|
|
35
|
+
let hawkejs = this.hawkejs_renderer.hawkejs,
|
|
36
|
+
hash = Object.checksum(input),
|
|
37
|
+
name = 'interpret_' + hash,
|
|
38
|
+
fnc;
|
|
39
|
+
|
|
40
|
+
if (hawkejs.templates[name]) {
|
|
41
|
+
fnc = hawkejs.templates[name];
|
|
42
|
+
} else {
|
|
43
|
+
fnc = hawkejs.compile({
|
|
44
|
+
template_name : name,
|
|
45
|
+
template : input
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let variables = {};
|
|
50
|
+
let placeholder = this.hawkejs_renderer.addSubtemplate(fnc, {print: false}, variables);
|
|
51
|
+
|
|
52
|
+
// If the widget is already part of the DOM,
|
|
53
|
+
// it's being edited and we need to manually kickstart the renderer
|
|
54
|
+
if (Blast.isBrowser && document.body.contains(this.widget)) {
|
|
55
|
+
await placeholder.getContent();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
this.widget.append(placeholder);
|
|
59
|
+
}
|
|
60
|
+
});
|
package/helper/widgets/header.js
CHANGED
|
@@ -78,18 +78,18 @@ Header.constitute(function addActions() {
|
|
|
78
78
|
*
|
|
79
79
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
80
80
|
* @since 0.1.0
|
|
81
|
-
* @version 0.1
|
|
81
|
+
* @version 0.2.1
|
|
82
82
|
*
|
|
83
83
|
* @return {Object}
|
|
84
84
|
*/
|
|
85
85
|
Header.setMethod(function syncConfig() {
|
|
86
86
|
|
|
87
|
-
let header = this.widget.
|
|
87
|
+
let header = this.widget.querySelector('h1, h2, h3, h4, h5'),
|
|
88
88
|
content = '',
|
|
89
89
|
level = 1;
|
|
90
90
|
|
|
91
91
|
if (header) {
|
|
92
|
-
content = header.
|
|
92
|
+
content = header.textContent;
|
|
93
93
|
level = parseInt(header.tagName[1]);
|
|
94
94
|
}
|
|
95
95
|
|
|
@@ -104,7 +104,7 @@ Header.setMethod(function syncConfig() {
|
|
|
104
104
|
*
|
|
105
105
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
106
106
|
* @since 0.1.0
|
|
107
|
-
* @version 0.1
|
|
107
|
+
* @version 0.2.1
|
|
108
108
|
*
|
|
109
109
|
* @param {HTMLElement} widget
|
|
110
110
|
*/
|
|
@@ -113,11 +113,9 @@ Header.setMethod(function populateWidget() {
|
|
|
113
113
|
let level = this.config.level || 1;
|
|
114
114
|
|
|
115
115
|
let header = this.createElement('h' + level);
|
|
116
|
-
header.
|
|
116
|
+
header.textContent = this.config.content || 'header level ' + level;
|
|
117
117
|
|
|
118
118
|
this.widget.append(header);
|
|
119
|
-
|
|
120
|
-
populateWidget.super.call(this);
|
|
121
119
|
});
|
|
122
120
|
|
|
123
121
|
/**
|
package/helper/widgets/html.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
|
|
1
2
|
/**
|
|
2
3
|
* The Widget HTML class
|
|
3
4
|
*
|
|
@@ -23,19 +24,67 @@ Html.constitute(function prepareSchema() {
|
|
|
23
24
|
this.schema.addField('html', 'Html');
|
|
24
25
|
});
|
|
25
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Start the editor
|
|
29
|
+
*
|
|
30
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
31
|
+
* @since 0.2.1
|
|
32
|
+
* @version 0.2.1
|
|
33
|
+
*/
|
|
34
|
+
Html.setMethod(async function _startEditor() {
|
|
35
|
+
|
|
36
|
+
if (this.ckeditor) {
|
|
37
|
+
this.ckeditor.destroy();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let ckeditor_path = hawkejs.scene.exposed.ckeditor_path;
|
|
41
|
+
|
|
42
|
+
if (!ckeditor_path) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
await hawkejs.require(ckeditor_path);
|
|
47
|
+
|
|
48
|
+
const options = {
|
|
49
|
+
toolbar: hawkejs.scene.exposed.ckeditor_toolbar,
|
|
50
|
+
updateSourceElementOnDestroy: true,
|
|
51
|
+
removePlugins: ['Markdown'],
|
|
52
|
+
simpleUpload: {
|
|
53
|
+
uploadUrl: alchemy.routeUrl('AlchemyWidgets#uploadImage'),
|
|
54
|
+
withCredentials: true,
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
let editor = await InlineEditor.create(this.widget, options);
|
|
59
|
+
|
|
60
|
+
this.ckeditor = editor;
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Stop the editor
|
|
65
|
+
*
|
|
66
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
67
|
+
* @since 0.2.1
|
|
68
|
+
* @version 0.2.1
|
|
69
|
+
*/
|
|
70
|
+
Html.setMethod(function _stopEditor() {
|
|
71
|
+
if (this.ckeditor) {
|
|
72
|
+
this.ckeditor.destroy();
|
|
73
|
+
this.ckeditor = null;
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
|
|
26
77
|
/**
|
|
27
78
|
* Populate the widget
|
|
28
79
|
*
|
|
29
80
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
30
81
|
* @since 0.1.0
|
|
31
|
-
* @version 0.1
|
|
82
|
+
* @version 0.2.1
|
|
32
83
|
*
|
|
33
84
|
* @param {HTMLElement} widget
|
|
34
85
|
*/
|
|
35
86
|
Html.setMethod(function populateWidget() {
|
|
36
87
|
this.widget.innerHTML = this.config.html;
|
|
37
|
-
|
|
38
|
-
populateWidget.super.call(this);
|
|
39
88
|
});
|
|
40
89
|
|
|
41
90
|
/**
|
|
@@ -28,14 +28,12 @@ Markdown.constitute(function prepareSchema() {
|
|
|
28
28
|
*
|
|
29
29
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
30
30
|
* @since 0.1.0
|
|
31
|
-
* @version 0.1
|
|
31
|
+
* @version 0.2.1
|
|
32
32
|
*
|
|
33
33
|
* @param {HTMLElement} widget
|
|
34
34
|
*/
|
|
35
35
|
Markdown.setMethod(function populateWidget() {
|
|
36
36
|
|
|
37
|
-
populateWidget.super.call(this);
|
|
38
|
-
|
|
39
37
|
let source = this.config.markdown || '';
|
|
40
38
|
|
|
41
39
|
if (!source) {
|
|
@@ -67,7 +67,7 @@ Partial.constitute(function prepareSchema() {
|
|
|
67
67
|
*
|
|
68
68
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
69
69
|
* @since 0.1.6
|
|
70
|
-
* @version 0.1
|
|
70
|
+
* @version 0.2.1
|
|
71
71
|
*
|
|
72
72
|
* @param {HTMLElement} widget
|
|
73
73
|
*/
|
|
@@ -105,8 +105,6 @@ Partial.setMethod(async function populateWidget() {
|
|
|
105
105
|
|
|
106
106
|
this.widget.append(placeholder);
|
|
107
107
|
}
|
|
108
|
-
|
|
109
|
-
populateWidget.super.call(this);
|
|
110
108
|
});
|
|
111
109
|
|
|
112
110
|
/**
|
|
@@ -37,14 +37,12 @@ Sourcecode.setProperty('sourcecode_field', 'sourcecode');
|
|
|
37
37
|
*
|
|
38
38
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
39
39
|
* @since 0.1.0
|
|
40
|
-
* @version 0.1
|
|
40
|
+
* @version 0.2.1
|
|
41
41
|
*
|
|
42
42
|
* @param {HTMLElement} widget
|
|
43
43
|
*/
|
|
44
44
|
Sourcecode.setMethod(function populateWidget() {
|
|
45
45
|
|
|
46
|
-
populateWidget.super.call(this);
|
|
47
|
-
|
|
48
46
|
let source = this.config[this.sourcecode_field] || '';
|
|
49
47
|
|
|
50
48
|
if (!source) {
|
|
@@ -16,12 +16,10 @@ const Toc = Function.inherits('Alchemy.Widget', 'TableOfContents');
|
|
|
16
16
|
*
|
|
17
17
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
18
18
|
* @since 0.1.2
|
|
19
|
-
* @version 0.2.
|
|
19
|
+
* @version 0.2.1
|
|
20
20
|
*/
|
|
21
21
|
Toc.setMethod(function populateWidget() {
|
|
22
22
|
|
|
23
|
-
populateWidget.super.call(this);
|
|
24
|
-
|
|
25
23
|
let toc = this.createElement('al-toc');
|
|
26
24
|
|
|
27
25
|
if (this.config.parent_selector) {
|
package/helper/widgets/text.js
CHANGED
|
@@ -28,7 +28,7 @@ Text.constitute(function prepareSchema() {
|
|
|
28
28
|
*
|
|
29
29
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
30
30
|
* @since 0.1.0
|
|
31
|
-
* @version 0.1
|
|
31
|
+
* @version 0.2.1
|
|
32
32
|
*
|
|
33
33
|
* @param {HTMLElement} widget
|
|
34
34
|
*/
|
|
@@ -36,8 +36,6 @@ Text.setMethod(function populateWidget() {
|
|
|
36
36
|
|
|
37
37
|
let tag_name;
|
|
38
38
|
|
|
39
|
-
populateWidget.super.call(this);
|
|
40
|
-
|
|
41
39
|
if (this.widget.dataset.textElementTag) {
|
|
42
40
|
tag_name = this.widget.dataset.textElementTag;
|
|
43
41
|
}
|
|
@@ -57,13 +55,16 @@ Text.setMethod(function populateWidget() {
|
|
|
57
55
|
*
|
|
58
56
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
59
57
|
* @since 0.1.0
|
|
60
|
-
* @version 0.1
|
|
58
|
+
* @version 0.2.1
|
|
61
59
|
*/
|
|
62
60
|
Text.setMethod(function _startEditor() {
|
|
63
61
|
|
|
64
|
-
let child
|
|
62
|
+
let child,
|
|
63
|
+
i;
|
|
64
|
+
|
|
65
|
+
for (i = 0; i < this.widget.children.length; i++) {
|
|
66
|
+
child = this.widget.children[i];
|
|
65
67
|
|
|
66
|
-
if (child) {
|
|
67
68
|
child.setAttribute('contenteditable', true);
|
|
68
69
|
}
|
|
69
70
|
});
|
|
@@ -73,13 +74,16 @@ Text.setMethod(function _startEditor() {
|
|
|
73
74
|
*
|
|
74
75
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
75
76
|
* @since 0.1.0
|
|
76
|
-
* @version 0.1
|
|
77
|
+
* @version 0.2.1
|
|
77
78
|
*/
|
|
78
79
|
Text.setMethod(function _stopEditor() {
|
|
79
80
|
|
|
80
|
-
let child
|
|
81
|
+
let child,
|
|
82
|
+
i;
|
|
83
|
+
|
|
84
|
+
for (i = 0; i < this.widget.children.length; i++) {
|
|
85
|
+
child = this.widget.children[i];
|
|
81
86
|
|
|
82
|
-
if (child) {
|
|
83
87
|
child.removeAttribute('contenteditable');
|
|
84
88
|
}
|
|
85
89
|
});
|
|
@@ -89,17 +93,13 @@ Text.setMethod(function _stopEditor() {
|
|
|
89
93
|
*
|
|
90
94
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
91
95
|
* @since 0.1.0
|
|
92
|
-
* @version 0.1
|
|
96
|
+
* @version 0.2.1
|
|
93
97
|
*
|
|
94
98
|
* @return {Object}
|
|
95
99
|
*/
|
|
96
100
|
Text.setMethod(function syncConfig() {
|
|
97
101
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
if (child) {
|
|
101
|
-
this.config.content = child.textContent;
|
|
102
|
-
}
|
|
102
|
+
this.config.content = this.widget?.textContent;
|
|
103
103
|
|
|
104
104
|
return this.config;
|
|
105
105
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "alchemy-widget",
|
|
3
3
|
"description": "The widget plugin for the AlchemyMVC",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.1",
|
|
5
5
|
"author": "Jelle De Loecker <jelle@elevenways.be>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"alchemy",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
],
|
|
12
12
|
"peerDependencies": {
|
|
13
13
|
"alchemymvc" : ">=1.2.0",
|
|
14
|
-
"alchemy-form": "~0.2.
|
|
14
|
+
"alchemy-form": "~0.2.1"
|
|
15
15
|
},
|
|
16
16
|
"repository": "11ways/alchemy-widget",
|
|
17
17
|
"license": "MIT",
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
<% all_entries = self.entries %>
|
|
2
|
+
|
|
1
3
|
{% macro printEntries %}
|
|
2
4
|
<ol>
|
|
3
5
|
{% each entries as entry %}
|
|
@@ -20,4 +22,12 @@
|
|
|
20
22
|
</li>
|
|
21
23
|
{% /macro %}
|
|
22
24
|
|
|
23
|
-
{% run printEntries entries=
|
|
25
|
+
{% run printEntries entries=all_entries %}
|
|
26
|
+
|
|
27
|
+
{% if all_entries %}
|
|
28
|
+
<% self.classList.add('toc-has-content') %>
|
|
29
|
+
{% else %}
|
|
30
|
+
<% self.classList.add('toc-is-empty') %>
|
|
31
|
+
{% /if %}
|
|
32
|
+
|
|
33
|
+
<% all_entries = null %>
|