@jinntec/fore 1.5.0 → 1.6.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/dist/fore-dev.js +2 -36
- package/dist/fore-dev.js.map +1 -1
- package/dist/fore.js +2 -30
- package/dist/fore.js.map +1 -1
- package/index.js +12 -0
- package/package.json +9 -5
- package/resources/fore.css +178 -92
- package/src/DependencyNotifyingDomFacade.js +1 -2
- package/src/ForeElementMixin.js +31 -5
- package/src/actions/abstract-action.js +379 -297
- package/src/actions/fx-action.js +0 -1
- package/src/actions/fx-append.js +1 -2
- package/src/actions/fx-confirm.js +12 -0
- package/src/actions/fx-copy.js +0 -1
- package/src/actions/fx-delete.js +31 -9
- package/src/actions/fx-dispatch.js +19 -5
- package/src/actions/fx-hide.js +19 -0
- package/src/actions/fx-insert.js +72 -8
- package/src/actions/fx-load.js +253 -0
- package/src/actions/fx-message.js +22 -7
- package/src/actions/fx-refresh.js +11 -1
- package/src/actions/fx-reload.js +12 -2
- package/src/actions/fx-replace.js +5 -4
- package/src/actions/fx-reset.js +48 -0
- package/src/actions/fx-return.js +0 -1
- package/src/actions/fx-send.js +40 -2
- package/src/actions/fx-setfocus.js +25 -7
- package/src/actions/fx-setvalue.js +32 -4
- package/src/actions/fx-show.js +14 -2
- package/src/actions/fx-toggle.js +0 -1
- package/src/actions/fx-update.js +9 -0
- package/src/events.js +0 -1
- package/src/fore.js +118 -63
- package/src/functions/common-function.js +28 -0
- package/src/fx-bind.js +7 -7
- package/src/fx-fore.js +152 -55
- package/src/fx-instance.js +55 -17
- package/src/fx-model.js +31 -33
- package/src/fx-submission.js +50 -47
- package/src/getInScopeContext.js +8 -10
- package/src/lab/fore-component.js +90 -0
- package/src/lab/instance-inspector.js +56 -0
- package/src/lab/template.html +16 -0
- package/src/relevance.js +27 -1
- package/src/tools/adi.js +1056 -0
- package/src/tools/fx-action-log.js +662 -0
- package/src/tools/fx-devtools.js +444 -0
- package/src/tools/fx-dom-inspector.js +609 -0
- package/src/tools/fx-json-instance.js +435 -0
- package/src/tools/fx-log-item.js +133 -0
- package/src/tools/fx-log-settings.js +474 -0
- package/src/tools/fx-minimap.js +194 -0
- package/src/tools/helpers.js +132 -0
- package/src/ui/abstract-control.js +41 -3
- package/src/ui/fx-action-log.js +358 -0
- package/src/ui/fx-alert.js +0 -1
- package/src/ui/fx-container.js +14 -3
- package/src/ui/fx-control.js +553 -474
- package/src/ui/fx-dialog.js +2 -0
- package/src/ui/fx-dom-inspector.js +1255 -0
- package/src/ui/fx-group.js +3 -4
- package/src/ui/fx-hint.js +2 -4
- package/src/ui/fx-inspector.js +5 -6
- package/src/ui/fx-items.js +55 -14
- package/src/ui/fx-output.js +36 -17
- package/src/ui/fx-repeat-attributes.js +10 -43
- package/src/ui/fx-repeat.js +5 -7
- package/src/ui/fx-switch.js +14 -3
- package/src/ui/fx-trigger.js +13 -1
- package/src/xpath-evaluation.js +109 -26
- package/src/xpath-util.js +55 -1
package/src/actions/fx-action.js
CHANGED
package/src/actions/fx-append.js
CHANGED
|
@@ -15,6 +15,7 @@ import { resolveId } from '../xpath-evaluation.js';
|
|
|
15
15
|
class FxAppend extends AbstractAction {
|
|
16
16
|
static get properties() {
|
|
17
17
|
return {
|
|
18
|
+
...AbstractAction.properties,
|
|
18
19
|
ref: {
|
|
19
20
|
type: String,
|
|
20
21
|
},
|
|
@@ -37,7 +38,6 @@ class FxAppend extends AbstractAction {
|
|
|
37
38
|
|
|
38
39
|
connectedCallback() {
|
|
39
40
|
super.connectedCallback();
|
|
40
|
-
console.log('connectedCallback ', this);
|
|
41
41
|
this.ref = this.getAttribute('ref');
|
|
42
42
|
this.repeat = this.getAttribute('repeat');
|
|
43
43
|
// this.repeated = this.closest('fx-repeatitem');
|
|
@@ -120,7 +120,6 @@ class FxAppend extends AbstractAction {
|
|
|
120
120
|
*/
|
|
121
121
|
_dispatch() {
|
|
122
122
|
const targetRepeat = resolveId(this.repeat, this);
|
|
123
|
-
console.log('dispatching index change ', targetRepeat.nodeset.length);
|
|
124
123
|
Fore.dispatch(targetRepeat, 'index-changed', { index: targetRepeat.nodeset.length });
|
|
125
124
|
}
|
|
126
125
|
|
|
@@ -8,7 +8,19 @@ import {FxAction} from "./fx-action.js";
|
|
|
8
8
|
* @demo demo/project.html
|
|
9
9
|
*/
|
|
10
10
|
export class FxConfirm extends FxAction {
|
|
11
|
+
static get properties () {
|
|
12
|
+
return {
|
|
13
|
+
...FxAction.properties,
|
|
14
|
+
message: {
|
|
15
|
+
type:String
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
11
20
|
connectedCallback() {
|
|
21
|
+
if(super.connectedCallback){
|
|
22
|
+
super.connectedCallback();
|
|
23
|
+
}
|
|
12
24
|
this.message = this.hasAttribute('message') ? this.getAttribute('message') : null;
|
|
13
25
|
}
|
|
14
26
|
|
package/src/actions/fx-copy.js
CHANGED
package/src/actions/fx-delete.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import * as fx from "fontoxpath";
|
|
1
2
|
import {AbstractAction} from './abstract-action.js';
|
|
2
3
|
import {Fore} from '../fore.js';
|
|
3
|
-
import {evaluateXPathToNodes} from "../xpath-evaluation.js";
|
|
4
|
-
import {XPathUtil} from "../xpath-util";
|
|
4
|
+
import {evaluateXPathToNodes, evaluateXPathToString} from "../xpath-evaluation.js";
|
|
5
|
+
import {XPathUtil} from "../xpath-util.js";
|
|
5
6
|
import getInScopeContext from '../getInScopeContext.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -13,8 +14,13 @@ import getInScopeContext from '../getInScopeContext.js';
|
|
|
13
14
|
* @demo demo/todo.html
|
|
14
15
|
*/
|
|
15
16
|
class FxDelete extends AbstractAction {
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
static get properties() {
|
|
18
|
+
return {
|
|
19
|
+
...super.properties,
|
|
20
|
+
ref: {
|
|
21
|
+
type: String,
|
|
22
|
+
},
|
|
23
|
+
};
|
|
18
24
|
}
|
|
19
25
|
|
|
20
26
|
/**
|
|
@@ -23,13 +29,30 @@ class FxDelete extends AbstractAction {
|
|
|
23
29
|
* Will NOT perform delete if nodeset is pointing to document node, document fragment, root node or being readonly.
|
|
24
30
|
*/
|
|
25
31
|
async perform() {
|
|
26
|
-
|
|
32
|
+
|
|
27
33
|
const inscopeContext = getInScopeContext(this.getAttributeNode('ref') || this, this.ref);
|
|
28
34
|
this.nodeset = evaluateXPathToNodes(this.ref, inscopeContext, this);
|
|
29
35
|
|
|
30
|
-
console.log('delete nodeset ', this.nodeset);
|
|
36
|
+
// console.log('delete nodeset ', this.nodeset);
|
|
37
|
+
|
|
38
|
+
const instanceId = XPathUtil.resolveInstance(this);
|
|
39
|
+
const instance = this.getModel().getInstance(instanceId);
|
|
40
|
+
|
|
41
|
+
// const path = instance && this.nodeset.length !== 0 ? evaluateXPathToString('path()', this.nodeset[0], instance) : '';
|
|
42
|
+
|
|
43
|
+
const path = Fore.getDomNodeIndexString(this.nodeset);
|
|
31
44
|
|
|
32
45
|
const nodesToDelete = this.nodeset;
|
|
46
|
+
|
|
47
|
+
this.dispatchEvent(
|
|
48
|
+
new CustomEvent('execute-action', {
|
|
49
|
+
composed: true,
|
|
50
|
+
bubbles: true,
|
|
51
|
+
cancelable:true,
|
|
52
|
+
detail: { action: this, event:this.event, path:path},
|
|
53
|
+
}),
|
|
54
|
+
);
|
|
55
|
+
|
|
33
56
|
let parent;
|
|
34
57
|
if (Array.isArray(nodesToDelete)) {
|
|
35
58
|
if(nodesToDelete.length === 0) return;
|
|
@@ -42,9 +65,8 @@ class FxDelete extends AbstractAction {
|
|
|
42
65
|
this._deleteNode(parent, nodesToDelete);
|
|
43
66
|
}
|
|
44
67
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
Fore.dispatch(instance, 'deleted', {deletedNodes:nodesToDelete});
|
|
68
|
+
|
|
69
|
+
await Fore.dispatch(instance, 'deleted', {ref:path,deletedNodes:nodesToDelete});
|
|
48
70
|
this.needsUpdate = true;
|
|
49
71
|
}
|
|
50
72
|
|
|
@@ -10,6 +10,21 @@ import { evaluateXPath, resolveId } from '../xpath-evaluation.js';
|
|
|
10
10
|
* can be accessed in usual JavaScript way.
|
|
11
11
|
*/
|
|
12
12
|
export class FxDispatch extends AbstractAction {
|
|
13
|
+
static get properties() {
|
|
14
|
+
return {
|
|
15
|
+
...super.properties,
|
|
16
|
+
name: {
|
|
17
|
+
type: String,
|
|
18
|
+
},
|
|
19
|
+
targetid: {
|
|
20
|
+
type: String,
|
|
21
|
+
},
|
|
22
|
+
details: {
|
|
23
|
+
type: String,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
13
28
|
constructor() {
|
|
14
29
|
super();
|
|
15
30
|
this.name = null;
|
|
@@ -53,12 +68,12 @@ export class FxDispatch extends AbstractAction {
|
|
|
53
68
|
*/
|
|
54
69
|
|
|
55
70
|
async perform() {
|
|
56
|
-
|
|
71
|
+
super.perform();
|
|
57
72
|
|
|
58
73
|
const properties = this.querySelectorAll('fx-property');
|
|
59
74
|
const details = {};
|
|
60
75
|
Array.from(properties).forEach(prop => {
|
|
61
|
-
console.log('prop ', prop);
|
|
76
|
+
// console.log('prop ', prop);
|
|
62
77
|
const name = prop.getAttribute('name');
|
|
63
78
|
const value = prop.getAttribute('value');
|
|
64
79
|
const expr = prop.getAttribute('expr');
|
|
@@ -67,7 +82,7 @@ export class FxDispatch extends AbstractAction {
|
|
|
67
82
|
if (value) {
|
|
68
83
|
throw new Error('if "expr" is given there must not be a "value" attribute');
|
|
69
84
|
}
|
|
70
|
-
const [result] = evaluateXPath(expr, this.getInScopeContext(), this
|
|
85
|
+
const [result] = evaluateXPath(expr, this.getInScopeContext(), this);
|
|
71
86
|
|
|
72
87
|
let serialized = null;
|
|
73
88
|
if (result.nodeName) {
|
|
@@ -86,7 +101,7 @@ export class FxDispatch extends AbstractAction {
|
|
|
86
101
|
}
|
|
87
102
|
});
|
|
88
103
|
|
|
89
|
-
console.log('details ', details);
|
|
104
|
+
// console.log('details ', details);
|
|
90
105
|
|
|
91
106
|
// ### when targetid is given dispatch to that if present (throw an error if not) - otherwise dispatch to document
|
|
92
107
|
if (this.targetid) {
|
|
@@ -96,7 +111,6 @@ export class FxDispatch extends AbstractAction {
|
|
|
96
111
|
// However, it may be that our target is elsewhere. Do a global search for that case
|
|
97
112
|
target = document.getElementById(this.targetid);
|
|
98
113
|
}
|
|
99
|
-
console.log('target', target);
|
|
100
114
|
if (!target) {
|
|
101
115
|
throw new Error(`targetid ${this.targetid} does not exist in document`);
|
|
102
116
|
}
|
package/src/actions/fx-hide.js
CHANGED
|
@@ -10,7 +10,17 @@ import { resolveId } from '../xpath-evaluation.js';
|
|
|
10
10
|
* @demo demo/project.html
|
|
11
11
|
*/
|
|
12
12
|
export class FxHide extends AbstractAction {
|
|
13
|
+
static get properties() {
|
|
14
|
+
return {
|
|
15
|
+
...super.properties,
|
|
16
|
+
dialog: {
|
|
17
|
+
type: String,
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
13
22
|
connectedCallback() {
|
|
23
|
+
super.connectedCallback();
|
|
14
24
|
this.dialog = this.getAttribute('dialog');
|
|
15
25
|
if (!this.dialog) {
|
|
16
26
|
Fore.dispatch(this, 'error', { message: 'dialog does not exist' });
|
|
@@ -18,6 +28,15 @@ export class FxHide extends AbstractAction {
|
|
|
18
28
|
}
|
|
19
29
|
|
|
20
30
|
async perform() {
|
|
31
|
+
this.dispatchEvent(
|
|
32
|
+
new CustomEvent('execute-action', {
|
|
33
|
+
composed: true,
|
|
34
|
+
bubbles: true,
|
|
35
|
+
cancelable:true,
|
|
36
|
+
detail: { action: this, event:this.event},
|
|
37
|
+
}),
|
|
38
|
+
);
|
|
39
|
+
|
|
21
40
|
const dialog = resolveId(this.dialog, this);
|
|
22
41
|
dialog.hide();
|
|
23
42
|
Fore.dispatch(dialog,'dialog-hidden',{})
|
package/src/actions/fx-insert.js
CHANGED
|
@@ -5,6 +5,8 @@ import {
|
|
|
5
5
|
evaluateXPathToFirstNode,
|
|
6
6
|
evaluateXPathToNumber,
|
|
7
7
|
} from '../xpath-evaluation.js';
|
|
8
|
+
import {XPathUtil} from "../xpath-util";
|
|
9
|
+
import {Fore} from '../fore.js';
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* `fx-insert`
|
|
@@ -13,6 +15,24 @@ import {
|
|
|
13
15
|
* @customElement
|
|
14
16
|
*/
|
|
15
17
|
export class FxInsert extends AbstractAction {
|
|
18
|
+
static get properties() {
|
|
19
|
+
return {
|
|
20
|
+
...super.properties,
|
|
21
|
+
at: {
|
|
22
|
+
type: Number,
|
|
23
|
+
},
|
|
24
|
+
position: {
|
|
25
|
+
type: Number,
|
|
26
|
+
},
|
|
27
|
+
origin: {
|
|
28
|
+
type: Object,
|
|
29
|
+
},
|
|
30
|
+
keepValues: {
|
|
31
|
+
type: Boolean,
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
16
36
|
constructor() {
|
|
17
37
|
super();
|
|
18
38
|
this.attachShadow({ mode: 'open' });
|
|
@@ -40,6 +60,31 @@ export class FxInsert extends AbstractAction {
|
|
|
40
60
|
this.keepValues = !!this.hasAttribute('keep-values');
|
|
41
61
|
}
|
|
42
62
|
|
|
63
|
+
_getOriginSequence(inscope, targetSequence){
|
|
64
|
+
let originSequence;
|
|
65
|
+
if (this.origin) {
|
|
66
|
+
// ### if there's an origin attribute use it
|
|
67
|
+
let originTarget;
|
|
68
|
+
try {
|
|
69
|
+
originTarget = evaluateXPathToFirstNode(this.origin, inscope, this);
|
|
70
|
+
if (Array.isArray(originTarget) && originTarget.length === 0) {
|
|
71
|
+
console.warn('invalid origin for this insert action - ignoring...', this);
|
|
72
|
+
originSequence = null;
|
|
73
|
+
}
|
|
74
|
+
originSequence = originTarget;
|
|
75
|
+
} catch (error) {
|
|
76
|
+
console.warn('invalid origin for this insert action - ignoring...', this);
|
|
77
|
+
}
|
|
78
|
+
} else if (targetSequence) {
|
|
79
|
+
// ### use last item of targetSequence
|
|
80
|
+
originSequence = targetSequence;
|
|
81
|
+
if (originSequence && !this.keepValues) {
|
|
82
|
+
this._clear(originSequence);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return originSequence;
|
|
86
|
+
}
|
|
87
|
+
|
|
43
88
|
_cloneOriginSequence(inscope, targetSequence) {
|
|
44
89
|
let originSequenceClone;
|
|
45
90
|
if (this.origin) {
|
|
@@ -52,7 +97,7 @@ export class FxInsert extends AbstractAction {
|
|
|
52
97
|
// this.setInScopeVariables(this.detail);
|
|
53
98
|
|
|
54
99
|
// originTarget = evaluateXPathToFirstNode(this.origin, inscope, this);
|
|
55
|
-
originTarget = evaluateXPathToFirstNode(this.origin, inscope, this
|
|
100
|
+
originTarget = evaluateXPathToFirstNode(this.origin, inscope, this);
|
|
56
101
|
if (Array.isArray(originTarget) && originTarget.length === 0) {
|
|
57
102
|
console.warn('invalid origin for this insert action - ignoring...', this);
|
|
58
103
|
originSequenceClone = null;
|
|
@@ -76,13 +121,15 @@ export class FxInsert extends AbstractAction {
|
|
|
76
121
|
return null;
|
|
77
122
|
}
|
|
78
123
|
if (this.hasAttribute('at')) {
|
|
79
|
-
return evaluateXPathToNumber(this.getAttribute('at'), inscope, this
|
|
124
|
+
return evaluateXPathToNumber(this.getAttribute('at'), inscope, this);
|
|
80
125
|
}
|
|
81
126
|
return targetSequence.length;
|
|
82
127
|
}
|
|
83
128
|
|
|
84
129
|
async perform() {
|
|
85
130
|
// super.perform();
|
|
131
|
+
// as we're overwriting the superclass we need to dispatch the execute-action ourselves
|
|
132
|
+
|
|
86
133
|
|
|
87
134
|
/*
|
|
88
135
|
todo: !!! calling super here does not correctly give the nodeset - it's likely still a bug in ForeElementMixin !!!
|
|
@@ -104,10 +151,10 @@ export class FxInsert extends AbstractAction {
|
|
|
104
151
|
|
|
105
152
|
if (this.hasAttribute('ref')) {
|
|
106
153
|
if (inscope) {
|
|
107
|
-
targetSequence = evaluateXPathToNodes(this.ref, inscope, this
|
|
154
|
+
targetSequence = evaluateXPathToNodes(this.ref, inscope, this);
|
|
108
155
|
} else {
|
|
109
156
|
inscope = getInScopeContext(this.getAttributeNode('ref'), this.ref);
|
|
110
|
-
targetSequence = evaluateXPathToNodes(this.ref, inscope, this
|
|
157
|
+
targetSequence = evaluateXPathToNodes(this.ref, inscope, this);
|
|
111
158
|
}
|
|
112
159
|
}
|
|
113
160
|
const originSequenceClone = this._cloneOriginSequence(inscope, targetSequence);
|
|
@@ -124,7 +171,6 @@ export class FxInsert extends AbstractAction {
|
|
|
124
171
|
insertLocationNode = inscope;
|
|
125
172
|
inscope.appendChild(originSequenceClone);
|
|
126
173
|
index = 1;
|
|
127
|
-
console.log('appended', inscope);
|
|
128
174
|
} else {
|
|
129
175
|
/* ### insert at position given by 'at' or use the last item in the targetSequence ### */
|
|
130
176
|
if (this.hasAttribute('at')) {
|
|
@@ -132,7 +178,7 @@ export class FxInsert extends AbstractAction {
|
|
|
132
178
|
// index = this.at;
|
|
133
179
|
// insertLocationNode = targetSequence[this.at - 1];
|
|
134
180
|
|
|
135
|
-
index = evaluateXPathToNumber(this.getAttribute('at'), inscope, this
|
|
181
|
+
index = evaluateXPathToNumber(this.getAttribute('at'), inscope, this);
|
|
136
182
|
insertLocationNode = targetSequence[index - 1];
|
|
137
183
|
} else {
|
|
138
184
|
// this.at = targetSequence.length;
|
|
@@ -179,9 +225,27 @@ export class FxInsert extends AbstractAction {
|
|
|
179
225
|
// console.log('insert context item ', insertLocationNode);
|
|
180
226
|
// console.log('parent ', insertLocationNode.parentNode);
|
|
181
227
|
// console.log('instance ', this.getModel().getDefaultContext());
|
|
228
|
+
// Fore.dispatch()
|
|
229
|
+
|
|
230
|
+
const inst = this.getModel().getInstance(XPathUtil.resolveInstance(this));
|
|
231
|
+
// console.log('<<<<<<< resolved instance', inst);
|
|
232
|
+
|
|
233
|
+
const path = Fore.getDomNodeIndexString(originSequenceClone);
|
|
234
|
+
this.dispatchEvent(
|
|
235
|
+
new CustomEvent('execute-action', {
|
|
236
|
+
composed: true,
|
|
237
|
+
bubbles: true,
|
|
238
|
+
cancelable:true,
|
|
239
|
+
detail: { action: this, event:this.event, path },
|
|
240
|
+
}),
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
Fore.dispatch(inst,'insert',{
|
|
244
|
+
'inserted-nodes': originSequenceClone,
|
|
245
|
+
'insert-location-node': insertLocationNode,
|
|
246
|
+
'position': this.position
|
|
247
|
+
});
|
|
182
248
|
|
|
183
|
-
console.log('<<<<<<< at', this.at);
|
|
184
|
-
console.log('<<<<<<< index', index);
|
|
185
249
|
// todo: this actually should dispatch to respective instance
|
|
186
250
|
document.dispatchEvent(
|
|
187
251
|
// new CustomEvent('insert', {
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import {AbstractAction} from './abstract-action.js';
|
|
2
|
+
import {evaluateXPathToString, resolveId} from "../xpath-evaluation.js";
|
|
3
|
+
import getInScopeContext from '../getInScopeContext.js';
|
|
4
|
+
import {XPathUtil} from "../xpath-util.js";
|
|
5
|
+
import {Fore} from "../fore.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* `fx-message`
|
|
9
|
+
*
|
|
10
|
+
* Action to display messages to the user.
|
|
11
|
+
*
|
|
12
|
+
*
|
|
13
|
+
*/
|
|
14
|
+
class FxLoad extends AbstractAction {
|
|
15
|
+
|
|
16
|
+
static get properties() {
|
|
17
|
+
return {
|
|
18
|
+
...super.properties,
|
|
19
|
+
attachTo: {
|
|
20
|
+
type: String
|
|
21
|
+
},
|
|
22
|
+
url: {
|
|
23
|
+
type: String
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
constructor() {
|
|
29
|
+
super();
|
|
30
|
+
this.attachShadow({mode: 'open'});
|
|
31
|
+
this.url='';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
connectedCallback() {
|
|
35
|
+
super.connectedCallback();
|
|
36
|
+
this.attachTo = this.hasAttribute('attach-to') ? this.getAttribute('attach-to') : '_self';
|
|
37
|
+
|
|
38
|
+
// Add a 'doneEvent' to block the action chain untill the event fired on the element we're
|
|
39
|
+
// loading something into.
|
|
40
|
+
this.awaitEvent = this.hasAttribute('await') ? this.getAttribute('await') : '';
|
|
41
|
+
this.url = this.hasAttribute('url') ? this.getAttribute('url') : '';
|
|
42
|
+
const style = `
|
|
43
|
+
:host{
|
|
44
|
+
display:none;
|
|
45
|
+
}
|
|
46
|
+
`;
|
|
47
|
+
this.shadowRoot.innerHTML = `
|
|
48
|
+
<style>
|
|
49
|
+
${style}
|
|
50
|
+
</style>
|
|
51
|
+
${this.renderHTML()}`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
disconnectedCallback() {
|
|
55
|
+
// super.disconnectedCallback();
|
|
56
|
+
this.targetElement.removeEventListener(this.event, e => this.execute(e));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// eslint-disable-next-line class-methods-use-this
|
|
60
|
+
renderHTML() {
|
|
61
|
+
return `
|
|
62
|
+
<slot></slot>
|
|
63
|
+
`;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async perform() {
|
|
67
|
+
await super.perform();
|
|
68
|
+
|
|
69
|
+
// this.getOwnerForm().evaluateTemplateExpression(this.urlContent, this);
|
|
70
|
+
|
|
71
|
+
const template = this.querySelector('template');
|
|
72
|
+
if(template){
|
|
73
|
+
const clone = template.content.cloneNode(true);
|
|
74
|
+
const content = document.importNode(clone, true);
|
|
75
|
+
// this._attachToElement(content);
|
|
76
|
+
if (this.attachTo.startsWith('#')) {
|
|
77
|
+
const targetId = this.attachTo.substring(1);
|
|
78
|
+
const resolved = resolveId(targetId, this);
|
|
79
|
+
// remove all children
|
|
80
|
+
while (resolved.firstChild) {
|
|
81
|
+
resolved.removeChild(resolved.firstChild);
|
|
82
|
+
}
|
|
83
|
+
if (this.awaitEvent) {
|
|
84
|
+
let resolveEvent;
|
|
85
|
+
const waitForEvent = new Promise((resolve) => {
|
|
86
|
+
resolveEvent = resolve;
|
|
87
|
+
});
|
|
88
|
+
const eventListener = () => {
|
|
89
|
+
resolveEvent();
|
|
90
|
+
resolved.removeEventListener(this.awaitEvent, eventListener);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
resolved.appendChild(content);
|
|
94
|
+
resolved.addEventListener(this.awaitEvent, eventListener);
|
|
95
|
+
|
|
96
|
+
await waitForEvent;
|
|
97
|
+
|
|
98
|
+
this.needsUpdate = true;
|
|
99
|
+
|
|
100
|
+
Fore.dispatch(this, 'loaded', {attachPoint:this.attachTo, content});
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
resolved.appendChild(content);
|
|
105
|
+
|
|
106
|
+
this.needsUpdate = true;
|
|
107
|
+
}
|
|
108
|
+
Fore.dispatch(this, 'loaded', {});
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if(!this.url){
|
|
113
|
+
// for authoring errors we log errors directly to DOM
|
|
114
|
+
|
|
115
|
+
this.dispatchEvent(
|
|
116
|
+
new CustomEvent('log', {
|
|
117
|
+
composed: false,
|
|
118
|
+
bubbles: true,
|
|
119
|
+
cancelable:true,
|
|
120
|
+
detail: { id:this.id, message: `neiter template element nor Url was specified.`, level:'Error'},
|
|
121
|
+
}),
|
|
122
|
+
);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
this.url = this.evaluateAttributeTemplateExpression(this.url,this);
|
|
126
|
+
if (this.attachTo === '_blank') {
|
|
127
|
+
window.open(this.url);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (this.attachTo === '_self') {
|
|
131
|
+
window.location.href = this.url;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
const response = await fetch(this.url, {
|
|
136
|
+
method: 'GET',
|
|
137
|
+
mode: 'cors',
|
|
138
|
+
credentials: 'same-origin',
|
|
139
|
+
headers: {
|
|
140
|
+
'Content-Type': "text/html",
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
const data = await response.text();
|
|
144
|
+
// console.log('data loaded: ', data);
|
|
145
|
+
|
|
146
|
+
// todo: if data contain '<template' element as first child instanciate and insert it
|
|
147
|
+
if (!this.attachTo) {
|
|
148
|
+
this.innerHtml = data;
|
|
149
|
+
}
|
|
150
|
+
/*
|
|
151
|
+
if (this.attachTo.startsWith('#')) {
|
|
152
|
+
const targetId = this.attachTo.substring(1);
|
|
153
|
+
const resolved = resolveId(targetId, this);
|
|
154
|
+
resolved.innerHTML = '';
|
|
155
|
+
resolved.innerHTML = data;
|
|
156
|
+
}
|
|
157
|
+
*/
|
|
158
|
+
this._attachToElement(data);
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
Fore.dispatch(this, 'loaded', {url: this.url})
|
|
162
|
+
|
|
163
|
+
} catch (error) {
|
|
164
|
+
throw new Error(`failed loading data ${error}`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
_attachToElement(content){
|
|
169
|
+
let effectiveContent;
|
|
170
|
+
if(content.nodeType){
|
|
171
|
+
effectiveContent = content
|
|
172
|
+
}else{
|
|
173
|
+
try{
|
|
174
|
+
effectiveContent = new DOMParser().parseFromString(content, 'text/html').firstElementChild;
|
|
175
|
+
}catch (e) {
|
|
176
|
+
Fore.dispatch(this,'error',{message:'parsing of content as HTML failed'})
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if(!(this.attachTo.startsWith('_')||this.attachTo.startsWith('#'))){
|
|
181
|
+
Fore.dispatch(this,'error',{message:'valid values for "attach-to" start with "_" or "#"'});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (this.attachTo.startsWith('#')) {
|
|
185
|
+
const targetId = this.attachTo.substring(1);
|
|
186
|
+
const resolved = resolveId(targetId, this);
|
|
187
|
+
resolved.innerHTML = '';
|
|
188
|
+
// resolved.innerHTML = effectiveContent;
|
|
189
|
+
if(effectiveContent.querySelector('fx-fore')){
|
|
190
|
+
resolved.append(effectiveContent.querySelector('fx-fore').cloneNode(true));
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
const body = effectiveContent.querySelector('body').cloneNode(true);
|
|
194
|
+
resolved.appendChild( body.firstElementChild);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
_evaluateUrlExpression() {
|
|
199
|
+
const url = this.getAttribute('url');
|
|
200
|
+
if (!url) {
|
|
201
|
+
throw new Error('url not specified');
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const replaced = url.replace(/{[^}]*}/g, match => {
|
|
205
|
+
if (match === '{}') return match;
|
|
206
|
+
const naked = match.substring(1, match.length - 1);
|
|
207
|
+
const inscope = getInScopeContext(this, naked);
|
|
208
|
+
if (!inscope) {
|
|
209
|
+
console.warn('no inscope context for ', this);
|
|
210
|
+
return match;
|
|
211
|
+
}
|
|
212
|
+
// Templates are special: they use the namespace configuration from the place where they are
|
|
213
|
+
// being defined
|
|
214
|
+
const instanceId = XPathUtil.getInstanceId(naked);
|
|
215
|
+
|
|
216
|
+
// If there is an instance referred
|
|
217
|
+
const inst = instanceId ? this.getModel().getInstance(instanceId) : this.getModel().getDefaultInstance();
|
|
218
|
+
try {
|
|
219
|
+
return evaluateXPathToString(naked, inscope, this, null, inst);
|
|
220
|
+
} catch (error) {
|
|
221
|
+
console.warn('ignoring unparseable url', error);
|
|
222
|
+
return match;
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
return replaced;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
/*
|
|
230
|
+
_getValue() {
|
|
231
|
+
if (this.hasAttribute('value')) {
|
|
232
|
+
const valAttr = this.getAttribute('value');
|
|
233
|
+
try {
|
|
234
|
+
const inscopeContext = getInScopeContext(this, valAttr);
|
|
235
|
+
return evaluateXPathToString(valAttr, inscopeContext, this);
|
|
236
|
+
} catch (error) {
|
|
237
|
+
console.error(error);
|
|
238
|
+
Fore.dispatch(this, 'error', {message: error});
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
if (this.textContent) {
|
|
242
|
+
return this.textContent;
|
|
243
|
+
}
|
|
244
|
+
return null;
|
|
245
|
+
}
|
|
246
|
+
*/
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (!customElements.get('fx-load')) {
|
|
252
|
+
window.customElements.define('fx-load', FxLoad);
|
|
253
|
+
}
|