@jinntec/fore 1.0.0-3 → 1.0.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/README.md +25 -34
- package/dist/fore-dev.js +43 -0
- package/dist/fore-dev.js.map +1 -0
- package/dist/fore.js +36 -1
- package/dist/fore.js.map +1 -0
- package/index.js +3 -0
- package/package.json +34 -38
- package/resources/fore.css +35 -50
- package/src/DependencyNotifyingDomFacade.js +10 -16
- package/src/ForeElementMixin.js +25 -18
- package/src/actions/abstract-action.js +17 -9
- package/src/actions/fx-action.js +6 -4
- package/src/actions/fx-append.js +8 -17
- package/src/actions/fx-confirm.js +3 -1
- package/src/actions/fx-delete.js +6 -3
- package/src/actions/fx-dispatch.js +9 -8
- package/src/actions/fx-hide.js +10 -6
- package/src/actions/fx-insert.js +49 -39
- package/src/actions/fx-message.js +3 -1
- package/src/actions/fx-refresh.js +11 -1
- package/src/actions/fx-replace.js +68 -0
- package/src/actions/fx-return.js +42 -0
- package/src/actions/fx-send.js +3 -1
- package/src/actions/fx-setvalue.js +58 -51
- package/src/actions/fx-show.js +8 -4
- package/src/actions/fx-toggle.js +15 -10
- package/src/actions/fx-update.js +3 -1
- package/src/dep_graph.js +4 -2
- package/src/drawdown.js +67 -82
- package/src/fore.js +158 -11
- package/src/functions/fx-function.js +11 -3
- package/src/fx-bind.js +42 -202
- package/src/fx-fore.js +105 -70
- package/src/fx-header.js +3 -1
- package/src/fx-instance.js +9 -1
- package/src/fx-model.js +31 -23
- package/src/fx-submission.js +73 -47
- package/src/fx-var.js +7 -4
- package/src/getInScopeContext.js +37 -11
- package/src/modelitem.js +4 -4
- package/src/relevance.js +65 -0
- package/src/ui/abstract-control.js +55 -35
- package/src/ui/fx-alert.js +7 -1
- package/src/ui/fx-case.js +3 -1
- package/src/ui/fx-container.js +7 -1
- package/src/ui/fx-control.js +283 -33
- package/src/ui/fx-dialog.js +54 -40
- package/src/ui/fx-group.js +3 -1
- package/src/ui/fx-hint.js +4 -1
- package/src/ui/fx-inspector.js +117 -17
- package/src/ui/fx-items.js +8 -8
- package/src/ui/fx-output.js +14 -5
- package/src/ui/fx-repeat.js +33 -41
- package/src/ui/fx-repeatitem.js +10 -4
- package/src/ui/fx-switch.js +3 -1
- package/src/ui/fx-trigger.js +3 -1
- package/src/xpath-evaluation.js +121 -131
- package/src/xpath-util.js +14 -7
- package/dist/fore-all.js +0 -140
- package/src/.DS_Store +0 -0
- package/src/actions/.DS_Store +0 -0
- package/src/ui/.DS_Store +0 -0
package/src/ui/fx-case.js
CHANGED
package/src/ui/fx-container.js
CHANGED
|
@@ -44,6 +44,10 @@ export class FxContainer extends foreElementMixin(HTMLElement) {
|
|
|
44
44
|
if (this.isBound()) {
|
|
45
45
|
this.evalInContext();
|
|
46
46
|
this.modelItem = this.getModelItem();
|
|
47
|
+
if (!this.modelItem.boundControls.includes(this)) {
|
|
48
|
+
this.modelItem.boundControls.push(this);
|
|
49
|
+
}
|
|
50
|
+
|
|
47
51
|
// this.value = this.modelItem.value;
|
|
48
52
|
}
|
|
49
53
|
|
|
@@ -107,4 +111,6 @@ export class FxContainer extends foreElementMixin(HTMLElement) {
|
|
|
107
111
|
}
|
|
108
112
|
}
|
|
109
113
|
|
|
110
|
-
|
|
114
|
+
if (!customElements.get('fx-container')) {
|
|
115
|
+
window.customElements.define('fx-container', FxContainer);
|
|
116
|
+
}
|
package/src/ui/fx-control.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import XfAbstractControl from './abstract-control.js';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
evaluateXPath,
|
|
4
|
+
evaluateXPathToString,
|
|
5
|
+
evaluateXPathToFirstNode,
|
|
6
|
+
} from '../xpath-evaluation.js';
|
|
3
7
|
import getInScopeContext from '../getInScopeContext.js';
|
|
4
8
|
import { Fore } from '../fore.js';
|
|
5
9
|
|
|
@@ -14,6 +18,16 @@ const WIDGETCLASS = 'widget';
|
|
|
14
18
|
* @customElement
|
|
15
19
|
* @demo demo/index.html
|
|
16
20
|
*/
|
|
21
|
+
|
|
22
|
+
function debounce(func, timeout = 300) {
|
|
23
|
+
let timer;
|
|
24
|
+
return (...args) => {
|
|
25
|
+
clearTimeout(timer);
|
|
26
|
+
timer = setTimeout(() => {
|
|
27
|
+
func.apply(this, args);
|
|
28
|
+
}, timeout);
|
|
29
|
+
};
|
|
30
|
+
}
|
|
17
31
|
export default class FxControl extends XfAbstractControl {
|
|
18
32
|
constructor() {
|
|
19
33
|
super();
|
|
@@ -22,6 +36,12 @@ export default class FxControl extends XfAbstractControl {
|
|
|
22
36
|
}
|
|
23
37
|
|
|
24
38
|
connectedCallback() {
|
|
39
|
+
this.initial = this.hasAttribute('initial') ? this.getAttribute('initial') : null;
|
|
40
|
+
this.url = this.hasAttribute('url') ? this.getAttribute('url') : null;
|
|
41
|
+
this.loaded = false;
|
|
42
|
+
this.initialNode = null;
|
|
43
|
+
this.debounceDelay = this.hasAttribute('debounce') ? this.getAttribute('debounce') : null;
|
|
44
|
+
|
|
25
45
|
this.updateEvent = this.hasAttribute('update-event')
|
|
26
46
|
? this.getAttribute('update-event')
|
|
27
47
|
: 'blur';
|
|
@@ -33,21 +53,6 @@ export default class FxControl extends XfAbstractControl {
|
|
|
33
53
|
}
|
|
34
54
|
`;
|
|
35
55
|
|
|
36
|
-
/*
|
|
37
|
-
const controlHtml = `
|
|
38
|
-
<slot></slot>
|
|
39
|
-
<fx-setvalue id="setvalue" ref="${this.ref}"></fx-setvalue>
|
|
40
|
-
`;
|
|
41
|
-
*/
|
|
42
|
-
|
|
43
|
-
/*
|
|
44
|
-
this.shadowRoot.innerHTML = `
|
|
45
|
-
<style>
|
|
46
|
-
${style}
|
|
47
|
-
</style>
|
|
48
|
-
${controlHtml}
|
|
49
|
-
`
|
|
50
|
-
*/
|
|
51
56
|
this.shadowRoot.innerHTML = `
|
|
52
57
|
<style>
|
|
53
58
|
${style}
|
|
@@ -69,32 +74,116 @@ export default class FxControl extends XfAbstractControl {
|
|
|
69
74
|
});
|
|
70
75
|
this.updateEvent = 'blur'; // needs to be registered too
|
|
71
76
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
77
|
+
if (this.debounceDelay) {
|
|
78
|
+
this.widget.addEventListener(
|
|
79
|
+
this.updateEvent,
|
|
80
|
+
debounce(() => {
|
|
81
|
+
console.log('eventlistener ', this.updateEvent);
|
|
82
|
+
this.setValue(this.widget[this.valueProp]);
|
|
83
|
+
}, this.debounceDelay),
|
|
84
|
+
);
|
|
85
|
+
} else {
|
|
86
|
+
this.widget.addEventListener(this.updateEvent, () => {
|
|
87
|
+
console.log('eventlistener ', this.updateEvent);
|
|
88
|
+
this.setValue(this.widget[this.valueProp]);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
this.addEventListener('return', e => {
|
|
93
|
+
console.log('catched return action on ', this);
|
|
94
|
+
console.log('return detail', e.detail);
|
|
95
|
+
|
|
96
|
+
console.log('return triggered on ', this);
|
|
97
|
+
console.log('this.ref', this.ref);
|
|
98
|
+
console.log('current outer instance', this.getInstance());
|
|
99
|
+
|
|
100
|
+
console.log(
|
|
101
|
+
'???? why ???? current nodeset should point to the node of the outer control',
|
|
102
|
+
e.currentTarget.nodeset,
|
|
103
|
+
);
|
|
104
|
+
console.log(
|
|
105
|
+
'???? why ???? current nodeset should point to the node of the outer control',
|
|
106
|
+
this.nodeset,
|
|
107
|
+
);
|
|
108
|
+
const newNodes = e.detail.nodeset;
|
|
109
|
+
console.log('new nodeset', newNodes);
|
|
110
|
+
console.log('currentTarget', e.currentTarget);
|
|
111
|
+
console.log('target', e.target);
|
|
112
|
+
|
|
113
|
+
e.stopPropagation();
|
|
114
|
+
|
|
115
|
+
this._replaceNode(newNodes);
|
|
75
116
|
});
|
|
76
117
|
|
|
77
|
-
const slot = this.shadowRoot.querySelector('slot');
|
|
78
118
|
this.template = this.querySelector('template');
|
|
79
119
|
// console.log('template',this.template);
|
|
80
120
|
}
|
|
81
121
|
|
|
122
|
+
_debounce(func, timeout = 300) {
|
|
123
|
+
let timer;
|
|
124
|
+
return (...args) => {
|
|
125
|
+
const context = this;
|
|
126
|
+
clearTimeout(timer);
|
|
127
|
+
timer = setTimeout(() => {
|
|
128
|
+
func.apply(context, args);
|
|
129
|
+
}, timeout);
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* updates the model with a new value by executing it's `<fx-setvalue>` action.
|
|
135
|
+
*
|
|
136
|
+
* In case the `as='node'` is given the bound node is replaced with the widgets' value with is
|
|
137
|
+
* expected to be a node again.
|
|
138
|
+
*
|
|
139
|
+
* @param val the new value to be set
|
|
140
|
+
*/
|
|
82
141
|
setValue(val) {
|
|
83
142
|
const modelitem = this.getModelItem();
|
|
143
|
+
|
|
144
|
+
if (modelitem?.readonly) return; // do nothing when modelItem is readonly
|
|
145
|
+
|
|
146
|
+
if (this.getAttribute('as') === 'node') {
|
|
147
|
+
const widgetValue = this.getWidget().value;
|
|
148
|
+
const replace = this.shadowRoot.getElementById('replace');
|
|
149
|
+
replace.replace(this.nodeset, this.getWidget().value);
|
|
150
|
+
if (widgetValue && widgetValue !== modelitem.value) {
|
|
151
|
+
modelitem.value = widgetValue;
|
|
152
|
+
replace.actionPerformed();
|
|
153
|
+
}
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
84
156
|
const setval = this.shadowRoot.getElementById('setvalue');
|
|
85
157
|
setval.setValue(modelitem, val);
|
|
86
158
|
setval.actionPerformed();
|
|
87
159
|
}
|
|
88
160
|
|
|
161
|
+
_replaceNode(node) {
|
|
162
|
+
// Note: clone the node while replacing to prevent the instances to leak through
|
|
163
|
+
this.modelItem.node.replaceWith(node.cloneNode(true));
|
|
164
|
+
this.getOwnerForm().refresh();
|
|
165
|
+
}
|
|
166
|
+
|
|
89
167
|
renderHTML(ref) {
|
|
90
168
|
return `
|
|
91
169
|
${this.label ? `${this.label}` : ''}
|
|
92
170
|
<slot></slot>
|
|
93
|
-
|
|
171
|
+
${
|
|
172
|
+
this.hasAttribute('as') && this.getAttribute('as') === 'node'
|
|
173
|
+
? `<fx-replace id="replace" ref=".">`
|
|
174
|
+
: `<fx-setvalue id="setvalue" ref="${ref}"></fx-setvalue>`
|
|
175
|
+
}
|
|
176
|
+
|
|
94
177
|
`;
|
|
95
178
|
}
|
|
96
179
|
|
|
97
180
|
/**
|
|
181
|
+
* The widget is the actual control being used in the UI e.g. a native input control or any
|
|
182
|
+
* other component that presents a control that can be interacted with.
|
|
183
|
+
*
|
|
184
|
+
* This function returns the widget by querying the children of this control for an element
|
|
185
|
+
* with `class="widget"`. If that cannot be found it searches for an native `input` of any type.
|
|
186
|
+
* If either cannot be found a `<input type="text">` is created.
|
|
98
187
|
*
|
|
99
188
|
* @returns {HTMLElement|*}
|
|
100
189
|
*/
|
|
@@ -114,24 +203,169 @@ export default class FxControl extends XfAbstractControl {
|
|
|
114
203
|
return widget;
|
|
115
204
|
}
|
|
116
205
|
|
|
117
|
-
|
|
206
|
+
/**
|
|
207
|
+
* updates the widget from the modelItem value. During refresh the a control
|
|
208
|
+
* evaluates it's binding expression to determine the bound node. The bound node corresponds
|
|
209
|
+
* to a modelItem which acts a the state object of a node. The modelItem determines the value
|
|
210
|
+
* and the state of the node and set the `value` property of this class.
|
|
211
|
+
*
|
|
212
|
+
* @returns {Promise<void>}
|
|
213
|
+
*/
|
|
118
214
|
async updateWidgetValue() {
|
|
119
215
|
// this.widget[this.valueProp] = this.value;
|
|
216
|
+
|
|
217
|
+
let { widget } = this;
|
|
218
|
+
if (!widget) {
|
|
219
|
+
widget = this;
|
|
220
|
+
}
|
|
221
|
+
// ### value is bound to checkbox
|
|
120
222
|
if (this.valueProp === 'checked') {
|
|
121
223
|
if (this.value === 'true') {
|
|
122
|
-
|
|
224
|
+
widget.checked = true;
|
|
123
225
|
} else {
|
|
124
|
-
|
|
226
|
+
widget.checked = false;
|
|
125
227
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (this.hasAttribute('as')) {
|
|
232
|
+
const as = this.getAttribute('as');
|
|
233
|
+
|
|
234
|
+
// ### when there's an `as=text` attribute serialize nodeset to prettified string
|
|
235
|
+
if (as === 'text') {
|
|
236
|
+
const serializer = new XMLSerializer();
|
|
237
|
+
const pretty = Fore.prettifyXml(serializer.serializeToString(this.nodeset));
|
|
238
|
+
widget.value = pretty;
|
|
239
|
+
}
|
|
240
|
+
if (as === 'node' && this.nodeset !== widget.value) {
|
|
241
|
+
const oldVal = this.nodeset.innerHTML;
|
|
242
|
+
if (widget.value) {
|
|
243
|
+
if (oldVal !== this.widget.value) {
|
|
244
|
+
console.log('changed');
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
widget.value = this.nodeset.cloneNode(true);
|
|
250
|
+
console.log('passed value to widget', widget.value);
|
|
130
251
|
}
|
|
252
|
+
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// ### when there's a url Fore is used as widget and will be loaded from external file
|
|
257
|
+
if (this.url && !this.loaded) {
|
|
258
|
+
// ### evaluate initial data if necessary
|
|
259
|
+
if (this.initial) {
|
|
260
|
+
this.initialNode = evaluateXPathToFirstNode(this.initial, this.nodeset, this);
|
|
261
|
+
console.log('initialNodes', this.initialNode);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// ### load the markup from Url
|
|
265
|
+
await this._loadForeFromUrl();
|
|
266
|
+
this.loaded = true;
|
|
267
|
+
|
|
268
|
+
// ### replace default instance of embedded Fore with initial nodes
|
|
269
|
+
// const innerInstance = this.querySelector('fx-instance');
|
|
270
|
+
// console.log('innerInstance',innerInstance);
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/*
|
|
275
|
+
if(this.url && !this.loaded){
|
|
276
|
+
this._loadForeFromUrl();
|
|
277
|
+
this.loaded=true;
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
*/
|
|
281
|
+
if (widget.value !== this.value) {
|
|
131
282
|
widget.value = this.value;
|
|
132
283
|
}
|
|
133
284
|
}
|
|
134
285
|
|
|
286
|
+
/**
|
|
287
|
+
* loads an external Fore from an HTML file given by `url` attribute.
|
|
288
|
+
*
|
|
289
|
+
* Will look for the `<fx-fore>` element within the returned HTML file and return that element.
|
|
290
|
+
*
|
|
291
|
+
* If that cannot be found an error is dispatched.
|
|
292
|
+
*
|
|
293
|
+
* todo: dispatch link error
|
|
294
|
+
* @private
|
|
295
|
+
*/
|
|
296
|
+
async _loadForeFromUrl() {
|
|
297
|
+
console.log('########## loading Fore from ', this.src, '##########');
|
|
298
|
+
try {
|
|
299
|
+
const response = await fetch(this.url, {
|
|
300
|
+
method: 'GET',
|
|
301
|
+
mode: 'cors',
|
|
302
|
+
credentials: 'include',
|
|
303
|
+
headers: {
|
|
304
|
+
'Content-Type': 'text/html',
|
|
305
|
+
},
|
|
306
|
+
});
|
|
307
|
+
const responseContentType = response.headers.get('content-type').toLowerCase();
|
|
308
|
+
console.log('********** responseContentType *********', responseContentType);
|
|
309
|
+
let data;
|
|
310
|
+
if (responseContentType.startsWith('text/html')) {
|
|
311
|
+
data = await response.text().then(result =>
|
|
312
|
+
// console.log('xml ********', result);
|
|
313
|
+
new DOMParser().parseFromString(result, 'text/html'),
|
|
314
|
+
);
|
|
315
|
+
} else {
|
|
316
|
+
data = 'done';
|
|
317
|
+
}
|
|
318
|
+
// const theFore = fxEvaluateXPathToFirstNode('//fx-fore', data.firstElementChild);
|
|
319
|
+
const theFore = data.querySelector('fx-fore');
|
|
320
|
+
// console.log('thefore', theFore)
|
|
321
|
+
theFore.classList.add('widget'); // is the new widget
|
|
322
|
+
const dummy = this.querySelector('input');
|
|
323
|
+
if (this.hasAttribute('shadow')) {
|
|
324
|
+
dummy.parentNode.removeChild(dummy);
|
|
325
|
+
this.shadowRoot.appendChild(theFore);
|
|
326
|
+
} else {
|
|
327
|
+
dummy.replaceWith(theFore);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
console.log(`########## loaded fore as component ##### ${this.url}`);
|
|
331
|
+
theFore.addEventListener(
|
|
332
|
+
'model-construct-done',
|
|
333
|
+
e => {
|
|
334
|
+
console.log('subcomponent ready', e.target);
|
|
335
|
+
const defaultInst = theFore.querySelector('fx-instance');
|
|
336
|
+
console.log('defaultInst', defaultInst);
|
|
337
|
+
const doc = new DOMParser().parseFromString('<data></data>', 'application/xml');
|
|
338
|
+
// Note: Clone the input to prevent the inner fore from editing the outer node
|
|
339
|
+
doc.firstElementChild.appendChild(this.initialNode.cloneNode(true));
|
|
340
|
+
// defaultinst.setInstanceData(this.initialNode);
|
|
341
|
+
defaultInst.setInstanceData(doc);
|
|
342
|
+
console.log('new data', defaultInst.getInstanceData());
|
|
343
|
+
// theFore.getModel().modelConstruct();
|
|
344
|
+
theFore.getModel().updateModel();
|
|
345
|
+
theFore.refresh();
|
|
346
|
+
},
|
|
347
|
+
{ once: true },
|
|
348
|
+
);
|
|
349
|
+
|
|
350
|
+
if (!theFore) {
|
|
351
|
+
this.dispatchEvent(
|
|
352
|
+
new CustomEvent('error', {
|
|
353
|
+
detail: {
|
|
354
|
+
message: `Fore element not found in '${this.src}'. Maybe wrapped within 'template' element?`,
|
|
355
|
+
},
|
|
356
|
+
}),
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
console.log('loaded');
|
|
360
|
+
this.dispatchEvent(new CustomEvent('loaded', { detail: { fore: theFore } }));
|
|
361
|
+
} catch (error) {
|
|
362
|
+
console.log('error', error);
|
|
363
|
+
this.getOwnerForm().dispatchEvent(
|
|
364
|
+
new CustomEvent('error', { detail: { message: `${this.url} not found` } }),
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
135
369
|
getTemplate() {
|
|
136
370
|
return this.querySelector('template');
|
|
137
371
|
}
|
|
@@ -144,7 +378,20 @@ export default class FxControl extends XfAbstractControl {
|
|
|
144
378
|
|
|
145
379
|
// ### if we find a ref on control we have a 'select' control of some kind
|
|
146
380
|
const widget = this.getWidget();
|
|
147
|
-
|
|
381
|
+
this._handleBoundWidget(widget);
|
|
382
|
+
Fore.refreshChildren(this, force);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* If the widget itself has a `ref` it binds to another nodeset to provide some
|
|
387
|
+
* dynamic items to be created from a template usually. Examples are dynamic select option lists
|
|
388
|
+
* or a set of checkboxes.
|
|
389
|
+
*
|
|
390
|
+
* @param widget the widget to handle
|
|
391
|
+
* @private
|
|
392
|
+
*/
|
|
393
|
+
_handleBoundWidget(widget) {
|
|
394
|
+
if (widget && widget.hasAttribute('ref')) {
|
|
148
395
|
// ### eval nodeset for list control
|
|
149
396
|
const ref = widget.getAttribute('ref');
|
|
150
397
|
/*
|
|
@@ -158,6 +405,9 @@ export default class FxControl extends XfAbstractControl {
|
|
|
158
405
|
// const nodeset = evaluateXPathToNodes(ref, inscope, this);
|
|
159
406
|
const nodeset = evaluateXPath(ref, inscope, this);
|
|
160
407
|
|
|
408
|
+
// ### bail out when nodeset is array and empty
|
|
409
|
+
if (Array.isArray(nodeset) && nodeset.length === 0) return;
|
|
410
|
+
|
|
161
411
|
// ### clear items
|
|
162
412
|
const { children } = widget;
|
|
163
413
|
Array.from(children).forEach(child => {
|
|
@@ -184,7 +434,6 @@ export default class FxControl extends XfAbstractControl {
|
|
|
184
434
|
}
|
|
185
435
|
}
|
|
186
436
|
}
|
|
187
|
-
Fore.refreshChildren(this, force);
|
|
188
437
|
}
|
|
189
438
|
|
|
190
439
|
updateEntry(newEntry, node) {
|
|
@@ -194,7 +443,7 @@ export default class FxControl extends XfAbstractControl {
|
|
|
194
443
|
const valueAttribute = this._getValueAttribute(newEntry);
|
|
195
444
|
const valueExpr = valueAttribute.value;
|
|
196
445
|
const cutted = valueExpr.substring(1, valueExpr.length - 1);
|
|
197
|
-
const evaluated =
|
|
446
|
+
const evaluated = evaluateXPathToString(cutted, node, newEntry);
|
|
198
447
|
valueAttribute.value = evaluated;
|
|
199
448
|
|
|
200
449
|
if (this.value === evaluated) {
|
|
@@ -230,5 +479,6 @@ export default class FxControl extends XfAbstractControl {
|
|
|
230
479
|
return result;
|
|
231
480
|
}
|
|
232
481
|
}
|
|
233
|
-
|
|
234
|
-
window.customElements.define('fx-control', FxControl);
|
|
482
|
+
if (!customElements.get('fx-control')) {
|
|
483
|
+
window.customElements.define('fx-control', FxControl);
|
|
484
|
+
}
|
package/src/ui/fx-dialog.js
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
|
+
import { Fore } from '../fore.js';
|
|
2
|
+
|
|
1
3
|
export class FxDialog extends HTMLElement {
|
|
4
|
+
static get properties() {
|
|
5
|
+
return {
|
|
6
|
+
id: String,
|
|
7
|
+
};
|
|
8
|
+
}
|
|
2
9
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
10
|
+
constructor() {
|
|
11
|
+
super();
|
|
12
|
+
this.attachShadow({ mode: 'open' });
|
|
13
|
+
}
|
|
8
14
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
this.attachShadow({mode: 'open'});
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
connectedCallback() {
|
|
15
|
-
const style = `
|
|
15
|
+
connectedCallback() {
|
|
16
|
+
const style = `
|
|
16
17
|
:host {
|
|
17
|
-
display:
|
|
18
|
+
display:none;
|
|
18
19
|
height: 100vh;
|
|
19
20
|
width:100vw;
|
|
20
21
|
position:fixed;
|
|
@@ -22,47 +23,60 @@ export class FxDialog extends HTMLElement {
|
|
|
22
23
|
top:0;
|
|
23
24
|
right:0;
|
|
24
25
|
bottom:0;
|
|
26
|
+
transition:opacity 0.4s linear;
|
|
25
27
|
}
|
|
26
|
-
`;
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
this.id = this.getAttribute('id');
|
|
29
|
+
`;
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
this.shadowRoot.innerHTML = this.render(style);
|
|
32
|
+
this.id = this.getAttribute('id');
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
if (closeBtn) {
|
|
35
|
-
closeBtn.addEventListener('click', (e) => {
|
|
36
|
-
document.getElementById(this.id).classList.remove('show');
|
|
37
|
-
});
|
|
38
|
-
}
|
|
34
|
+
// const dialog = document.getElementById(this.id);
|
|
39
35
|
|
|
40
|
-
|
|
36
|
+
const closeBtn = this.querySelector('.close-dialog');
|
|
37
|
+
if (closeBtn) {
|
|
38
|
+
closeBtn.addEventListener('click', () => {
|
|
39
|
+
this.classList.remove('show');
|
|
40
|
+
});
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
this.addEventListener('transitionend', () => {
|
|
44
|
+
console.log('transitionend');
|
|
45
|
+
// this.style.display = 'none';
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
this.focus();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
render(styles) {
|
|
52
|
+
return `
|
|
45
53
|
<style>
|
|
46
54
|
${styles}
|
|
47
55
|
</style>
|
|
48
56
|
<slot></slot>
|
|
49
57
|
`;
|
|
50
|
-
|
|
58
|
+
}
|
|
51
59
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
open() {
|
|
61
|
+
window.addEventListener(
|
|
62
|
+
'keyup',
|
|
63
|
+
e => {
|
|
64
|
+
if (e.key === 'Escape') {
|
|
65
|
+
this.hide();
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
{ once: true },
|
|
69
|
+
);
|
|
61
70
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
71
|
+
this.classList.add('show');
|
|
72
|
+
}
|
|
65
73
|
|
|
74
|
+
async hide() {
|
|
75
|
+
await Fore.fadeOutElement(this, 400);
|
|
76
|
+
this.classList.remove('show');
|
|
77
|
+
}
|
|
66
78
|
}
|
|
67
79
|
|
|
68
|
-
customElements.
|
|
80
|
+
if (!customElements.get('fx-dialog')) {
|
|
81
|
+
customElements.define('fx-dialog', FxDialog);
|
|
82
|
+
}
|
package/src/ui/fx-group.js
CHANGED