alchemy-widget 0.1.4 → 0.1.6

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.
@@ -83,6 +83,17 @@ AlchemyWidgets.setProperty(function value() {
83
83
  return result;
84
84
 
85
85
  }, function setValue(value) {
86
+ this.applyValue(value);
87
+ });
88
+
89
+ /**
90
+ * Apply the given value
91
+ *
92
+ * @author Jelle De Loecker <jelle@elevenways.be>
93
+ * @since 0.1.5
94
+ * @version 0.1.5
95
+ */
96
+ AlchemyWidgets.setMethod(function applyValue(value) {
86
97
 
87
98
  let widgets,
88
99
  config;
@@ -24,7 +24,7 @@ let AddArea = Function.inherits('Alchemy.Element.Widget.Base', function AlchemyW
24
24
  *
25
25
  * @author Jelle De Loecker <jelle@elevenways.be>
26
26
  * @since 0.1.0
27
- * @version 0.1.0
27
+ * @version 0.1.6
28
28
  */
29
29
  AddArea.setMethod(function showTypes(event) {
30
30
 
@@ -42,7 +42,7 @@ AddArea.setMethod(function showTypes(event) {
42
42
 
43
43
  for (let widget of widgets) {
44
44
 
45
- if (widget.type_name == 'container') {
45
+ if (!widget.canBeAdded(that.parentElement)) {
46
46
  continue;
47
47
  }
48
48
 
@@ -15,7 +15,7 @@ let Toolbar = Function.inherits('Alchemy.Element.Widget.Base', function AlchemyW
15
15
  *
16
16
  * @author Jelle De Loecker <jelle@elevenways.be>
17
17
  * @since 0.1.0
18
- * @version 0.1.0
18
+ * @version 0.1.6
19
19
  *
20
20
  * @param {HTMLElement} widget
21
21
  */
@@ -37,7 +37,24 @@ Toolbar.setMethod(function showWidgetActions(widget) {
37
37
  let button = this.createElement('button');
38
38
  button.classList.add('aw-toolbar-button');
39
39
 
40
- button.innerHTML = action.getButtonHTML();
40
+ let content = action.getButtonContent();
41
+
42
+ if (!content) {
43
+ content = action.title;
44
+ }
45
+
46
+ if (typeof content == 'string') {
47
+ button.innerText = content;
48
+ } else if (content) {
49
+ if (Array.isArray(content)) {
50
+ for (let entry of content) {
51
+ button.append(entry);
52
+ }
53
+ } else {
54
+ button.append(content);
55
+ }
56
+ }
57
+
41
58
  button.setAttribute('title', action.title);
42
59
 
43
60
  let is_selected = action.isAlreadySelected(widget);
@@ -141,30 +141,31 @@ Action.setMethod(function test(widget) {
141
141
  *
142
142
  * @author Jelle De Loecker <jelle@elevenways.be>
143
143
  * @since 0.1.0
144
- * @version 0.1.0
144
+ * @version 0.1.6
145
145
  *
146
- * @return {String}
146
+ * @return {HTMLElement|String}
147
147
  */
148
- Action.setMethod(function getButtonHTML() {
148
+ Action.setMethod(function getButtonContent() {
149
149
 
150
- let html;
150
+ let result;
151
151
 
152
152
  if (this.icon) {
153
153
 
154
154
  let icon = this.icon;
155
155
 
156
156
  if (typeof icon == 'string') {
157
- html = '<i class="' + icon + '"></i>';
157
+ result = Blast.Classes.Hawkejs.Hawkejs.createElement('al-ico');
158
+ result.setIcon(icon);
158
159
  } else if (icon.html) {
159
- html = icon.html;
160
+ result = Blast.Classes.Hawkejs.parseHTML(icon.html);
160
161
  }
161
162
  }
162
163
 
163
- if (!html) {
164
- html = this.name;
164
+ if (!result) {
165
+ result = this.name;
165
166
  }
166
167
 
167
- return html;
168
+ return result;
168
169
  });
169
170
 
170
171
  /**
@@ -77,14 +77,20 @@ Widget.setProperty(function element() {
77
77
  *
78
78
  * @author Jelle De Loecker <jelle@elevenways.be>
79
79
  * @since 0.1.0
80
- * @version 0.1.0
80
+ * @version 0.1.6
81
81
  *
82
82
  * @type {Hawkejs.Renderer}
83
83
  */
84
84
  Widget.enforceProperty(function hawkejs_renderer(new_value) {
85
85
 
86
- if (!new_value && Blast.isBrowser) {
87
- new_value = hawkejs.scene.general_renderer;
86
+ if (!new_value) {
87
+ if (this.parent_instance && this.parent_instance.hawkejs_renderer) {
88
+ new_value = this.parent_instance.hawkejs_renderer;
89
+ } else if (this.widget && this.widget.hawkejs_renderer) {
90
+ new_value = this.widget.hawkejs_renderer;
91
+ } else if (Blast.isBrowser) {
92
+ new_value = hawkejs.scene.general_renderer;
93
+ }
88
94
  }
89
95
 
90
96
  return new_value;
@@ -95,7 +101,7 @@ Widget.enforceProperty(function hawkejs_renderer(new_value) {
95
101
  *
96
102
  * @author Jelle De Loecker <jelle@elevenways.be>
97
103
  * @since 0.1.0
98
- * @version 0.1.0
104
+ * @version 0.1.6
99
105
  */
100
106
  Widget.constitute(function prepareSchema() {
101
107
 
@@ -120,6 +126,19 @@ Widget.constitute(function prepareSchema() {
120
126
  array: true,
121
127
  });
122
128
 
129
+ // Add the "save" action
130
+ let save = this.createAction('save', 'Save');
131
+
132
+ save.setHandler(function removeAction(widget_el, handle) {
133
+ return widget_el.save();
134
+ });
135
+
136
+ save.setTester(function saveAction(widget_el, handle) {
137
+ return widget_el.can_be_saved;
138
+ });
139
+
140
+ save.setIcon('floppy-disk');
141
+
123
142
  // Add the remove action
124
143
  let remove = this.createAction('remove', 'Remove');
125
144
 
@@ -130,16 +149,16 @@ Widget.constitute(function prepareSchema() {
130
149
  });
131
150
 
132
151
  remove.setTester(function removeTester(widget_el, handle) {
133
- // The root alchemy-widgets element should not be removed
134
- return widget_el.tagName !== 'ALCHEMY-WIDGETS';
152
+ return widget_el.can_be_removed;
135
153
  });
136
154
 
137
- remove.setIcon('gg-trash');
155
+ remove.setIcon('trash');
138
156
 
139
157
  // Add the config action
140
158
  let config = this.createAction('config', 'Config');
141
159
 
142
160
  config.close_toolbar = true;
161
+ config.setIcon('gears');
143
162
 
144
163
  config.setHandler(function configAction(widget_el, handle) {
145
164
  widget_el.instance.showConfig();
@@ -156,10 +175,15 @@ Widget.constitute(function prepareSchema() {
156
175
  });
157
176
 
158
177
  move_left.setTester(function moveLeftTest(widget_el, handle) {
178
+
179
+ if (!widget_el.can_be_moved) {
180
+ return false;
181
+ }
182
+
159
183
  return !!handle.previousElementSibling;
160
184
  });
161
185
 
162
- move_left.setIcon('gg-arrow-left');
186
+ move_left.setIcon('arrow-left');
163
187
 
164
188
  let move_right = this.createAction('move-right', 'Move right');
165
189
 
@@ -172,6 +196,10 @@ Widget.constitute(function prepareSchema() {
172
196
 
173
197
  move_right.setTester(function moveRightTest(widget_el, handle) {
174
198
 
199
+ if (!widget_el.can_be_moved) {
200
+ return false;
201
+ }
202
+
175
203
  let next = handle.nextElementSibling;
176
204
 
177
205
  if (!next || next.tagName == 'ALCHEMY-WIDGET-ADD-AREA') {
@@ -181,7 +209,7 @@ Widget.constitute(function prepareSchema() {
181
209
  return true;
182
210
  });
183
211
 
184
- move_right.setIcon('gg-arrow-right');
212
+ move_right.setIcon('arrow-right');
185
213
 
186
214
  // The move-in-left action
187
215
  let move_in_left = this.createAction('move-in-left', 'Move in left');
@@ -198,10 +226,15 @@ Widget.constitute(function prepareSchema() {
198
226
  });
199
227
 
200
228
  move_in_left.setTester(function moveLeftTest(widget_el, handle) {
229
+
230
+ if (!widget_el.can_be_moved) {
231
+ return false;
232
+ }
233
+
201
234
  return !!handle.previous_container;
202
235
  });
203
236
 
204
- move_in_left.setIcon('gg-arrow-left');
237
+ move_in_left.setIcon('arrow-left');
205
238
 
206
239
  // The move-in-right action
207
240
  let move_in_right = this.createAction('move-in-right', 'Move in right');
@@ -218,17 +251,23 @@ Widget.constitute(function prepareSchema() {
218
251
  });
219
252
 
220
253
  move_in_right.setTester(function moveRightTest(widget_el, handle) {
221
- console.log('Right test of:', handle)
254
+
255
+ if (!widget_el.can_be_moved) {
256
+ return false;
257
+ }
258
+
222
259
  return !!handle.next_container;
223
260
  });
224
261
 
225
- move_in_right.setIcon('gg-arrow-right');
262
+ move_in_right.setIcon('arrow-right');
226
263
 
227
264
  let css_class = this.createAction('css-class', 'CSS Class');
228
265
 
229
266
  css_class.setHandler(function setCssClass(widget_el, handle) {
230
267
  widget_el.instance.showConfig(['main_class_names']);
231
268
  });
269
+
270
+ css_class.setIcon('tags');
232
271
  });
233
272
 
234
273
  /**
@@ -268,6 +307,43 @@ Widget.setStatic(function createAction(name, title) {
268
307
  return action;
269
308
  });
270
309
 
310
+ /**
311
+ * Add a check to see if the widget can be added to the current location
312
+ *
313
+ * @author Jelle De Loecker <jelle@elevenways.be>
314
+ * @since 0.1.6
315
+ * @version 0.1.6
316
+ *
317
+ * @param {Boolean|Function} checker
318
+ */
319
+ Widget.setStatic(function setAddChecker(checker) {
320
+ this.add_checker = checker;
321
+ });
322
+
323
+ /**
324
+ * Actually perform the add-check
325
+ *
326
+ * @author Jelle De Loecker <jelle@elevenways.be>
327
+ * @since 0.1.6
328
+ * @version 0.1.6
329
+ *
330
+ * @param {Alchemy.Element.Widget.Base} widget_element
331
+ */
332
+ Widget.setStatic(function canBeAdded(widget_element) {
333
+
334
+ if (this.add_checker != null) {
335
+ const type = typeof this.add_checker;
336
+
337
+ if (type == 'function') {
338
+ return this.add_checker(widget_element);
339
+ } else if (type == 'boolean') {
340
+ return this.add_checker;
341
+ }
342
+ }
343
+
344
+ return true;
345
+ });
346
+
271
347
  /**
272
348
  * unDry an object
273
349
  *
@@ -449,11 +525,11 @@ Widget.setMethod(function _createPopulatedWidgetElement() {
449
525
  });
450
526
 
451
527
  /**
452
- * Dummy populate method
528
+ * Populate the contents of the widget
453
529
  *
454
530
  * @author Jelle De Loecker <jelle@elevenways.be>
455
531
  * @since 0.1.0
456
- * @version 0.1.2
532
+ * @version 0.1.6
457
533
  */
458
534
  Widget.setMethod(function populateWidget() {
459
535
 
@@ -469,6 +545,16 @@ Widget.setMethod(function populateWidget() {
469
545
  }
470
546
  }
471
547
 
548
+ let child_classes = this.widget.child_class;
549
+
550
+ if (child_classes) {
551
+ let children = this.widget.children,
552
+ i;
553
+
554
+ for (i = 0; i < children.length; i++) {
555
+ Hawkejs.addClasses(children[i], child_classes);
556
+ }
557
+ }
472
558
  });
473
559
 
474
560
  /**
@@ -476,16 +562,23 @@ Widget.setMethod(function populateWidget() {
476
562
  *
477
563
  * @author Jelle De Loecker <jelle@elevenways.be>
478
564
  * @since 0.1.0
479
- * @version 0.1.0
565
+ * @version 0.1.6
480
566
  */
481
- Widget.setMethod(function startEditor() {
567
+ Widget.setMethod(async function startEditor() {
482
568
 
483
569
  // Show this is being edited
484
570
  this.editing = true;
485
571
 
572
+ // Make sure the icon font is loaded
573
+ if (this.hawkejs_renderer?.helpers?.Media) {
574
+ this.hawkejs_renderer.helpers.Media.loadIconFont();
575
+ }
576
+
486
577
  // Add the appropriate class to the current widget wrapper
487
578
  this.widget.classList.add('aw-editing');
488
579
 
580
+ await this.widget.waitForTasks();
581
+
489
582
  if (typeof this._startEditor == 'function') {
490
583
  this._startEditor();
491
584
  }
@@ -518,13 +611,13 @@ Widget.setMethod(function stopEditor() {
518
611
  *
519
612
  * @author Jelle De Loecker <jelle@elevenways.be>
520
613
  * @since 0.1.0
521
- * @version 0.1.0
614
+ * @version 0.1.6
522
615
  */
523
- Widget.setMethod(function rerender() {
616
+ Widget.setMethod(async function rerender() {
524
617
 
525
618
  Hawkejs.removeChildren(this.widget);
526
619
 
527
- this.populateWidget();
620
+ await this.populateWidget();
528
621
 
529
622
  if (this.editing) {
530
623
  this.startEditor();
@@ -549,7 +642,7 @@ Widget.setMethod(function syncConfig() {
549
642
  *
550
643
  * @author Jelle De Loecker <jelle@elevenways.be>
551
644
  * @since 0.1.0
552
- * @version 0.1.0
645
+ * @version 0.1.12
553
646
  */
554
647
  Widget.setMethod(async function showConfig(fields) {
555
648
 
@@ -579,9 +672,11 @@ Widget.setMethod(async function showConfig(fields) {
579
672
  }
580
673
  }
581
674
 
675
+ let widget_settings = Object.assign({}, this.syncConfig());
676
+
582
677
  let variables = {
583
678
  schema : this.schema,
584
- widget_settings : this.syncConfig(),
679
+ widget_settings,
585
680
  fields : fields
586
681
  };
587
682
 
@@ -596,6 +691,9 @@ Widget.setMethod(async function showConfig(fields) {
596
691
  let dialog = dialog_contents.queryParents('he-dialog'),
597
692
  button = dialog_contents.querySelector('.btn-apply');
598
693
 
694
+ dialog_contents.classList.add('default-form-editor');
695
+ hawkejs.scene.enableStyle('chimera/chimera');
696
+
599
697
  button.addEventListener('click', e => {
600
698
  e.preventDefault();
601
699
 
@@ -11,6 +11,11 @@
11
11
  */
12
12
  const Container = Function.inherits('Alchemy.Widget', 'Container');
13
13
 
14
+ /**
15
+ * Make this an abstract class
16
+ */
17
+ Container.makeAbstractClass();
18
+
14
19
  /**
15
20
  * Prepare the schema
16
21
  *
@@ -33,7 +33,7 @@ Header.constitute(function prepareSchema() {
33
33
  *
34
34
  * @author Jelle De Loecker <jelle@elevenways.be>
35
35
  * @since 0.1.0
36
- * @version 0.1.0
36
+ * @version 0.1.6
37
37
  */
38
38
  Header.constitute(function addActions() {
39
39
 
@@ -43,7 +43,7 @@ Header.constitute(function addActions() {
43
43
  for (let level of levels) {
44
44
  let level_action = this.createAction('make-level-' + level, 'Level ' + level);
45
45
 
46
- level_action.setHandler(function setLevelAction(widget, toolbar) {
46
+ level_action.setHandler(function setLevelAction(widget, handle, toolbar) {
47
47
 
48
48
  let content = widget.querySelector(query);
49
49
 
@@ -0,0 +1,215 @@
1
+ /**
2
+ * The Partial Widget class
3
+ *
4
+ * @constructor
5
+ *
6
+ * @author Jelle De Loecker <jelle@elevenways.be>
7
+ * @since 0.1.6
8
+ * @version 0.1.6
9
+ *
10
+ * @param {Object} data
11
+ */
12
+ const Partial = Function.inherits('Alchemy.Widget', 'Partial');
13
+
14
+ /**
15
+ * Make this an abstract class
16
+ */
17
+ Partial.makeAbstractClass();
18
+
19
+ /**
20
+ * Get the type name
21
+ *
22
+ * @author Jelle De Loecker <jelle@elevenways.be>
23
+ * @since 0.1.6
24
+ * @version 0.1.6
25
+ */
26
+ Partial.setStatic(function createClassTypeName() {
27
+ return 'partial_' + this.name.underscore();
28
+ });
29
+
30
+ /**
31
+ * Set the template to use
32
+ *
33
+ * @author Jelle De Loecker <jelle@elevenways.be>
34
+ * @since 0.1.6
35
+ * @version 0.1.6
36
+ */
37
+ Partial.setStatic(function setTemplateFile(name) {
38
+ this.constitute(function _setTemplateFile() {
39
+ this.template_file = name;
40
+ });
41
+ });
42
+
43
+ /**
44
+ * Prepare the schema
45
+ *
46
+ * @author Jelle De Loecker <jelle@elevenways.be>
47
+ * @since 0.1.6
48
+ * @version 0.1.6
49
+ */
50
+ Partial.constitute(function prepareSchema() {
51
+
52
+ this.schema.addField('view', 'String', {
53
+ title : 'Partial View',
54
+ description : 'The actual HWK template to use for rendering this widget',
55
+ });
56
+
57
+ let contents = this.createSchema();
58
+
59
+ contents.addField('name', 'String');
60
+ contents.addField('content', 'Widgets');
61
+
62
+ this.schema.addField('contents', contents, {array: true});
63
+ });
64
+
65
+ /**
66
+ * Populate the widget
67
+ *
68
+ * @author Jelle De Loecker <jelle@elevenways.be>
69
+ * @since 0.1.6
70
+ * @version 0.1.6
71
+ *
72
+ * @param {HTMLElement} widget
73
+ */
74
+ Partial.setMethod(async function populateWidget() {
75
+
76
+ let view = this.constructor.template_file || this.config.view;
77
+
78
+ if (view) {
79
+
80
+ let options = {
81
+ print : false,
82
+ };
83
+
84
+ let variables = {};
85
+
86
+ await this.addVariablesForRender(variables);
87
+
88
+ if (this.config?.contents?.length) {
89
+ for (let entry of this.config.contents) {
90
+ variables[entry.name] = entry.contents;
91
+ }
92
+ }
93
+
94
+ variables.config = this.config;
95
+
96
+ let placeholder = this.hawkejs_renderer.addSubtemplate(view, options, variables);
97
+
98
+ // If the widget is already part of the DOM,
99
+ // it's being edited and we need to manually kickstart the renderer
100
+ if (Blast.isBrowser && document.body.contains(this.widget)) {
101
+ await placeholder.getContent();
102
+ }
103
+
104
+ Hawkejs.removeChildren(this.widget);
105
+
106
+ this.widget.append(placeholder);
107
+ }
108
+
109
+ populateWidget.super.call(this);
110
+ });
111
+
112
+ /**
113
+ * Allow adding variables for rendering the partial
114
+ *
115
+ * @author Jelle De Loecker <jelle@elevenways.be>
116
+ * @since 0.1.
117
+ * @version 0.1.
118
+ */
119
+ Partial.setMethod(function addVariablesForRender(variables) {
120
+ // To be optionally implemented by child widgets
121
+ });
122
+
123
+ /**
124
+ * Get all the sub widgets by their name
125
+ *
126
+ * @author Jelle De Loecker <jelle@elevenways.be>
127
+ * @since 0.1.6
128
+ * @version 0.1.6
129
+ *
130
+ * @return {Object}
131
+ */
132
+ Partial.setMethod(function getSubWidgets() {
133
+
134
+ let elements = this.widget.queryAllNotNested('[data-section-name]'),
135
+ result = {};
136
+
137
+ for (let element of elements) {
138
+ result[element.dataset.sectionName] = element;
139
+ }
140
+
141
+ return result;
142
+ });
143
+
144
+ /**
145
+ * Start the editor
146
+ *
147
+ * @author Jelle De Loecker <jelle@elevenways.be>
148
+ * @since 0.1.6
149
+ * @version 0.1.6
150
+ */
151
+ Partial.setMethod(function _startEditor() {
152
+
153
+ let sub_widgets = this.getSubWidgets();
154
+
155
+ for (let name in sub_widgets) {
156
+ let sub_widget = sub_widgets[name];
157
+ sub_widget.startEditor();
158
+ }
159
+ });
160
+
161
+ /**
162
+ * Stop the editor
163
+ *
164
+ * @author Jelle De Loecker <jelle@elevenways.be>
165
+ * @since 0.1.6
166
+ * @version 0.1.6
167
+ */
168
+ Partial.setMethod(function _stopEditor() {
169
+
170
+ let sub_widgets = this.getSubWidgets();
171
+
172
+ for (let name in sub_widgets) {
173
+ let sub_widget = sub_widgets[name];
174
+ sub_widget.stopEditor();
175
+ }
176
+
177
+ this.populateWidget();
178
+ });
179
+
180
+ /**
181
+ * Update the config values
182
+ *
183
+ * @author Jelle De Loecker <jelle@elevenways.be>
184
+ * @since 0.1.6
185
+ * @version 0.1.6
186
+ *
187
+ * @return {Object}
188
+ */
189
+ Partial.setMethod(function syncConfig() {
190
+
191
+ let sub_widgets = this.getSubWidgets(),
192
+ contents = this.config.contents;
193
+
194
+ if (!contents) {
195
+ contents = [];
196
+ this.config.contents = contents;
197
+ }
198
+
199
+ for (let name in sub_widgets) {
200
+ let sub_widget = sub_widgets[name];
201
+ let widget_config = contents.findByPath('name', name);
202
+
203
+ if (!widget_config) {
204
+ widget_config = {
205
+ name,
206
+ };
207
+
208
+ contents.push(widget_config);
209
+ }
210
+
211
+ widget_config.contents = sub_widget.value;
212
+ }
213
+
214
+ return this.config;
215
+ });
@@ -28,18 +28,28 @@ 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.0
31
+ * @version 0.1.6
32
32
  *
33
33
  * @param {HTMLElement} widget
34
34
  */
35
35
  Text.setMethod(function populateWidget() {
36
36
 
37
+ let tag_name;
38
+
37
39
  populateWidget.super.call(this);
38
40
 
39
- let paragraph = this.createElement('p');
40
- paragraph.textContent = this.config.content || '';
41
+ if (this.widget.dataset.textElementTag) {
42
+ tag_name = this.widget.dataset.textElementTag;
43
+ }
44
+
45
+ if (!tag_name) {
46
+ tag_name = 'p';
47
+ }
48
+
49
+ let text_element = this.createElement(tag_name);
50
+ text_element.textContent = this.config.content || '';
41
51
 
42
- this.widget.append(paragraph);
52
+ this.widget.append(text_element);
43
53
  });
44
54
 
45
55
  /**
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.1.4",
4
+ "version": "0.1.6",
5
5
  "author": "Jelle De Loecker <jelle@elevenways.be>",
6
6
  "keywords": [
7
7
  "alchemy",
@@ -15,6 +15,6 @@
15
15
  "repository": "11ways/alchemy-widget",
16
16
  "license": "MIT",
17
17
  "engines": {
18
- "node" : ">=12.0.0"
18
+ "node" : ">=14.0.0"
19
19
  }
20
20
  }