@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-inspector.js
CHANGED
|
@@ -1,44 +1,144 @@
|
|
|
1
|
+
import { Fore } from '../fore.js';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* lists out all live instances in html 'details' and 'summary' elements.
|
|
3
5
|
*/
|
|
4
6
|
export class FxInspector extends HTMLElement {
|
|
7
|
+
constructor() {
|
|
8
|
+
super();
|
|
9
|
+
this.attachShadow({ mode: 'open' });
|
|
10
|
+
}
|
|
11
|
+
|
|
5
12
|
connectedCallback() {
|
|
6
13
|
const style = `
|
|
7
14
|
:host {
|
|
15
|
+
position:absolute;
|
|
8
16
|
display: block;
|
|
9
|
-
width:
|
|
17
|
+
width:var(--inspector-handle-width);
|
|
10
18
|
background:var(--inspector-bg);
|
|
19
|
+
top:0;
|
|
20
|
+
right:0;
|
|
21
|
+
bottom:0;
|
|
22
|
+
height: 100%;
|
|
23
|
+
background: var(--inspector-bg);
|
|
24
|
+
color: white;
|
|
25
|
+
/*max-height: 33%;*/
|
|
26
|
+
overflow: scroll;
|
|
27
|
+
transition:width 0.3s ease;
|
|
28
|
+
}
|
|
29
|
+
:host([open]){
|
|
30
|
+
width: 30%;
|
|
31
|
+
}
|
|
32
|
+
details{
|
|
33
|
+
margin:1rem;
|
|
34
|
+
}
|
|
35
|
+
.main{
|
|
36
|
+
padding-left:var(--inspector-handle-width);
|
|
37
|
+
color:var(--inspector-color);
|
|
38
|
+
overflow:scroll;
|
|
11
39
|
}
|
|
12
40
|
pre{
|
|
13
41
|
background:var(--inspector-pre-bg);
|
|
14
42
|
color:var(--inspector-color);
|
|
15
|
-
max-height:var(--inspector-instance-height,300px);
|
|
16
43
|
overflow:scroll;
|
|
44
|
+
padding:0.2rem;
|
|
45
|
+
}
|
|
46
|
+
.handle{
|
|
47
|
+
display:block;
|
|
48
|
+
height:100vh;
|
|
49
|
+
width:var(--inspector-handle-width);
|
|
50
|
+
background:var(--inspector-handle-bg);
|
|
51
|
+
opacity:0.7;
|
|
52
|
+
position:absolute;
|
|
53
|
+
left:0;
|
|
54
|
+
color:white;
|
|
55
|
+
cursor:pointer;
|
|
56
|
+
}
|
|
57
|
+
.handle:hover{
|
|
58
|
+
opacity:1;
|
|
59
|
+
}
|
|
60
|
+
.handle::before{
|
|
61
|
+
content: 'Data Inspector';
|
|
62
|
+
white-space: nowrap;
|
|
63
|
+
transform: rotate(-90deg);
|
|
64
|
+
display: inline-block;
|
|
65
|
+
position: absolute;
|
|
66
|
+
left: -85px;
|
|
67
|
+
width: 200px;
|
|
68
|
+
top: 40px;
|
|
69
|
+
}
|
|
70
|
+
summary{
|
|
71
|
+
cursor:pointer;
|
|
17
72
|
}
|
|
18
73
|
`;
|
|
19
74
|
|
|
20
|
-
const
|
|
21
|
-
|
|
75
|
+
const fore = this.closest('fx-fore');
|
|
76
|
+
|
|
77
|
+
// fore.addEventListener('ready', (e) => {
|
|
78
|
+
this.render(style);
|
|
79
|
+
// });
|
|
80
|
+
fore.addEventListener('refresh-done', () => {
|
|
81
|
+
this.update();
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
update() {
|
|
86
|
+
console.log('update');
|
|
87
|
+
const pre = this.shadowRoot.querySelectorAll('pre');
|
|
88
|
+
console.log('pre', pre);
|
|
89
|
+
const fore = this.closest('fx-fore');
|
|
90
|
+
|
|
91
|
+
Array.from(pre).forEach(element => {
|
|
92
|
+
const inst = fore.getModel().getInstance(element.getAttribute('id'));
|
|
93
|
+
if (inst.type === 'xml') {
|
|
94
|
+
element.innerText = this.serializeDOM(inst.instanceData);
|
|
95
|
+
}
|
|
96
|
+
if (inst.type === 'json') {
|
|
97
|
+
element.innerText = JSON.stringify(inst.instanceData, undefined, 2);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
render(style) {
|
|
103
|
+
const fore = this.closest('fx-fore');
|
|
104
|
+
const instances = Array.from(fore.querySelectorAll('fx-instance'));
|
|
105
|
+
this.shadowRoot.innerHTML = `
|
|
22
106
|
<style>
|
|
23
107
|
${style}
|
|
24
108
|
</style>
|
|
109
|
+
<div class="main">
|
|
25
110
|
<slot></slot>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
111
|
+
<span class="handle"></span>
|
|
112
|
+
${instances.map(
|
|
113
|
+
(instance, index) => `
|
|
114
|
+
<details open>
|
|
115
|
+
<summary>${instance.id}</summary>
|
|
116
|
+
<pre id="${instance.id}"></pre>
|
|
117
|
+
</details>
|
|
118
|
+
`,
|
|
119
|
+
)}
|
|
120
|
+
</div>
|
|
36
121
|
`;
|
|
37
122
|
|
|
38
|
-
this.
|
|
39
|
-
|
|
123
|
+
const handle = this.shadowRoot.querySelector('.handle');
|
|
124
|
+
handle.addEventListener('click', e => {
|
|
125
|
+
console.log('toggling');
|
|
126
|
+
const { target } = e;
|
|
127
|
+
if (this.hasAttribute('open')) {
|
|
128
|
+
this.removeAttribute('open');
|
|
129
|
+
} else {
|
|
130
|
+
this.setAttribute('open', 'open');
|
|
131
|
+
}
|
|
40
132
|
});
|
|
41
133
|
}
|
|
134
|
+
|
|
135
|
+
serializeDOM(data) {
|
|
136
|
+
console.log('serializeDOM', data);
|
|
137
|
+
const ser = new XMLSerializer().serializeToString(data);
|
|
138
|
+
return Fore.prettifyXml(ser);
|
|
139
|
+
}
|
|
42
140
|
}
|
|
43
141
|
|
|
44
|
-
customElements.
|
|
142
|
+
if (!customElements.get('fx-inspector')) {
|
|
143
|
+
customElements.define('fx-inspector', FxInspector);
|
|
144
|
+
}
|
package/src/ui/fx-items.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { evaluateXPath, evaluateXPathToString, evaluateXPathToNodes } from '../xpath-evaluation.js';
|
|
3
|
-
import getInScopeContext from '../getInScopeContext.js';
|
|
1
|
+
import { evaluateXPathToString, resolveId } from '../xpath-evaluation.js';
|
|
4
2
|
import FxControl from './fx-control.js';
|
|
5
3
|
import { Fore } from '../fore.js';
|
|
6
4
|
|
|
@@ -35,7 +33,7 @@ export class FxItems extends FxControl {
|
|
|
35
33
|
|
|
36
34
|
let target;
|
|
37
35
|
if (e.target.nodeName === 'LABEL') {
|
|
38
|
-
target =
|
|
36
|
+
target = resolveId(e.target.getAttribute('for'), this);
|
|
39
37
|
target.checked = !target.checked;
|
|
40
38
|
}
|
|
41
39
|
|
|
@@ -48,7 +46,7 @@ export class FxItems extends FxControl {
|
|
|
48
46
|
this.setAttribute('value', val.trim());
|
|
49
47
|
|
|
50
48
|
// ### check for parent control
|
|
51
|
-
const parentBind =
|
|
49
|
+
const parentBind = Fore.getClosest('[ref]', this.parentNode);
|
|
52
50
|
if (!parentBind) return;
|
|
53
51
|
const modelitem = parentBind.getModelItem();
|
|
54
52
|
const setval = this.shadowRoot.getElementById('setvalue');
|
|
@@ -64,7 +62,7 @@ export class FxItems extends FxControl {
|
|
|
64
62
|
async updateWidgetValue() {
|
|
65
63
|
// console.log('setting items value');
|
|
66
64
|
|
|
67
|
-
const parentBind =
|
|
65
|
+
const parentBind = Fore.getClosest('[ref]', this.parentNode);
|
|
68
66
|
if (parentBind) {
|
|
69
67
|
this.value = parentBind.value;
|
|
70
68
|
}
|
|
@@ -103,7 +101,7 @@ export class FxItems extends FxControl {
|
|
|
103
101
|
// getting expr
|
|
104
102
|
const expr = input.value;
|
|
105
103
|
const cutted = expr.substring(1, expr.length - 1);
|
|
106
|
-
const evaluated =
|
|
104
|
+
const evaluated = evaluateXPathToString(cutted, node, newEntry);
|
|
107
105
|
|
|
108
106
|
// adding space around value to allow matching of 'words'
|
|
109
107
|
const spaced = ` ${evaluated} `;
|
|
@@ -117,4 +115,6 @@ export class FxItems extends FxControl {
|
|
|
117
115
|
}
|
|
118
116
|
}
|
|
119
117
|
|
|
120
|
-
customElements.
|
|
118
|
+
if (!customElements.get('fx-items')) {
|
|
119
|
+
customElements.define('fx-items', FxItems);
|
|
120
|
+
}
|
package/src/ui/fx-output.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Fore } from '../fore.js';
|
|
1
2
|
import XfAbstractControl from './abstract-control.js';
|
|
2
3
|
import { evaluateXPath, evaluateXPathToStrings } from '../xpath-evaluation.js';
|
|
3
4
|
import getInScopeContext from '../getInScopeContext.js';
|
|
@@ -20,6 +21,8 @@ export class FxOutput extends XfAbstractControl {
|
|
|
20
21
|
super();
|
|
21
22
|
this.attachShadow({ mode: 'open' });
|
|
22
23
|
this.valueAttr = this.hasAttribute('value') ? this.getAttribute('value') : null;
|
|
24
|
+
// Outputs are always readonly!
|
|
25
|
+
this.readonly = true;
|
|
23
26
|
}
|
|
24
27
|
|
|
25
28
|
connectedCallback() {
|
|
@@ -85,13 +88,13 @@ export class FxOutput extends XfAbstractControl {
|
|
|
85
88
|
try {
|
|
86
89
|
const inscopeContext = getInScopeContext(this, this.valueAttr);
|
|
87
90
|
if (this.hasAttribute('html')) {
|
|
88
|
-
return evaluateXPath(this.valueAttr, inscopeContext, this);
|
|
91
|
+
return evaluateXPath(this.valueAttr, inscopeContext, this)[0];
|
|
89
92
|
}
|
|
90
93
|
|
|
91
94
|
return evaluateXPathToStrings(this.valueAttr, inscopeContext, this)[0];
|
|
92
95
|
} catch (error) {
|
|
93
96
|
console.error(error);
|
|
94
|
-
|
|
97
|
+
Fore.dispatch(this, 'error', { message: error });
|
|
95
98
|
}
|
|
96
99
|
return null;
|
|
97
100
|
}
|
|
@@ -101,6 +104,11 @@ export class FxOutput extends XfAbstractControl {
|
|
|
101
104
|
return valueWrapper;
|
|
102
105
|
}
|
|
103
106
|
|
|
107
|
+
handleReadonly() {
|
|
108
|
+
// An output is always read-only
|
|
109
|
+
this.setAttribute('readonly', 'readonly');
|
|
110
|
+
}
|
|
111
|
+
|
|
104
112
|
async updateWidgetValue() {
|
|
105
113
|
console.log('updateWidgetValue');
|
|
106
114
|
const valueWrapper = this.shadowRoot.getElementById('value');
|
|
@@ -150,9 +158,10 @@ export class FxOutput extends XfAbstractControl {
|
|
|
150
158
|
}
|
|
151
159
|
|
|
152
160
|
isReadonly() {
|
|
153
|
-
|
|
154
|
-
return this.readonly;
|
|
161
|
+
return true;
|
|
155
162
|
}
|
|
156
163
|
}
|
|
157
164
|
|
|
158
|
-
customElements.
|
|
165
|
+
if (!customElements.get('fx-output')) {
|
|
166
|
+
customElements.define('fx-output', FxOutput);
|
|
167
|
+
}
|
package/src/ui/fx-repeat.js
CHANGED
|
@@ -4,7 +4,7 @@ import { Fore } from '../fore.js';
|
|
|
4
4
|
import { foreElementMixin } from '../ForeElementMixin.js';
|
|
5
5
|
import { evaluateXPath } from '../xpath-evaluation.js';
|
|
6
6
|
import getInScopeContext from '../getInScopeContext.js';
|
|
7
|
-
import {XPathUtil} from
|
|
7
|
+
import { XPathUtil } from '../xpath-util.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* `fx-repeat`
|
|
@@ -18,6 +18,8 @@ import {XPathUtil} from "../xpath-util";
|
|
|
18
18
|
*
|
|
19
19
|
* @customElement
|
|
20
20
|
* @demo demo/todo.html
|
|
21
|
+
*
|
|
22
|
+
* todo: it should be seriously be considered to extend FxContainer instead but needs refactoring first.
|
|
21
23
|
*/
|
|
22
24
|
export class FxRepeat extends foreElementMixin(HTMLElement) {
|
|
23
25
|
static get properties() {
|
|
@@ -100,41 +102,46 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
|
|
|
100
102
|
this.index = idx + 1;
|
|
101
103
|
});
|
|
102
104
|
// todo: review - this is just used by append action - event consolidation ?
|
|
103
|
-
|
|
105
|
+
document.addEventListener('index-changed', e => {
|
|
104
106
|
e.stopPropagation();
|
|
105
107
|
if (!e.target === this) return;
|
|
106
108
|
console.log('handle index event ', e);
|
|
107
109
|
// const { item } = e.detail;
|
|
108
110
|
// const idx = Array.from(this.children).indexOf(item);
|
|
109
111
|
const { index } = e.detail;
|
|
110
|
-
this.index = index;
|
|
112
|
+
this.index = Number(index);
|
|
111
113
|
this.applyIndex(this.children[index - 1]);
|
|
112
114
|
});
|
|
115
|
+
/*
|
|
113
116
|
document.addEventListener('insert', e => {
|
|
114
117
|
const nodes = e.detail.insertedNodes;
|
|
115
118
|
this.index = e.detail.position;
|
|
116
119
|
console.log('insert catched', nodes, this.index);
|
|
117
120
|
});
|
|
121
|
+
*/
|
|
118
122
|
|
|
119
123
|
// if (this.getOwnerForm().lazyRefresh) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
124
|
+
this.mutationObserver = new MutationObserver(mutations => {
|
|
125
|
+
console.log('mutations', mutations);
|
|
126
|
+
|
|
127
|
+
if (mutations[0].type === 'childList') {
|
|
128
|
+
const added = mutations[0].addedNodes[0];
|
|
129
|
+
if (added) {
|
|
130
|
+
const path = XPathUtil.getPath(added);
|
|
131
|
+
console.log('path mutated', path);
|
|
132
|
+
// this.dispatch('path-mutated',{'path':path,'nodeset':this.nodeset,'index': this.index});
|
|
133
|
+
// this.index = index;
|
|
134
|
+
// const prev = mutations[0].previousSibling.previousElementSibling;
|
|
135
|
+
// const index = prev.index();
|
|
136
|
+
// this.applyIndex(this.index -1);
|
|
137
|
+
|
|
138
|
+
Fore.dispatch(this, 'path-mutated', { path, index: this.index });
|
|
132
139
|
}
|
|
133
|
-
}
|
|
140
|
+
}
|
|
141
|
+
});
|
|
134
142
|
// }
|
|
135
143
|
this.getOwnerForm().registerLazyElement(this);
|
|
136
144
|
|
|
137
|
-
|
|
138
145
|
const style = `
|
|
139
146
|
:host{
|
|
140
147
|
}
|
|
@@ -192,31 +199,13 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
|
|
|
192
199
|
});
|
|
193
200
|
}
|
|
194
201
|
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
this.nodeset = [];
|
|
202
|
+
const rawNodeset = evaluateXPath(this.ref, inscope, this);
|
|
203
|
+
if (rawNodeset.length === 1 && Array.isArray(rawNodeset[0])) {
|
|
204
|
+
// This XPath likely returned an XPath array. Just collapse to that array
|
|
205
|
+
this.nodeset = rawNodeset[0];
|
|
200
206
|
return;
|
|
201
207
|
}
|
|
202
|
-
|
|
203
|
-
if (typeof seq === 'object') {
|
|
204
|
-
// Either a node or an array
|
|
205
|
-
if ('nodeType' in seq) {
|
|
206
|
-
// Node
|
|
207
|
-
this.nodeset = [seq];
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// if (Array.isArray(seq) && seq.every(item => typeof item === 'object')) {
|
|
212
|
-
if (Array.isArray(seq)) {
|
|
213
|
-
// multiple Nodes or maps
|
|
214
|
-
this.nodeset = seq;
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
throw new Error(`Unexpected result of repeat nodeset: ${seq}`);
|
|
208
|
+
this.nodeset = rawNodeset;
|
|
220
209
|
}
|
|
221
210
|
|
|
222
211
|
async refresh(force) {
|
|
@@ -264,6 +253,7 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
|
|
|
264
253
|
|
|
265
254
|
newItem.nodeset = this.nodeset[position - 1];
|
|
266
255
|
newItem.index = position;
|
|
256
|
+
this.getOwnerForm().someInstanceDataStructureChanged = true;
|
|
267
257
|
}
|
|
268
258
|
}
|
|
269
259
|
|
|
@@ -405,4 +395,6 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
|
|
|
405
395
|
}
|
|
406
396
|
}
|
|
407
397
|
|
|
408
|
-
|
|
398
|
+
if (!customElements.get('fx-repeat')) {
|
|
399
|
+
window.customElements.define('fx-repeat', FxRepeat);
|
|
400
|
+
}
|
package/src/ui/fx-repeatitem.js
CHANGED
|
@@ -73,16 +73,20 @@ export class FxRepeatitem extends foreElementMixin(HTMLElement) {
|
|
|
73
73
|
this.inited = true;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
/*
|
|
76
77
|
getModelItem() {
|
|
77
78
|
super.getModelItem();
|
|
78
79
|
// console.log('modelItem in repeatitem ', this.getModelItem()[this.index]);
|
|
79
80
|
return this.getModelItem()[this.index];
|
|
80
81
|
}
|
|
82
|
+
*/
|
|
81
83
|
|
|
82
84
|
refresh(force) {
|
|
83
|
-
|
|
84
|
-
//
|
|
85
|
-
this.modelItem
|
|
85
|
+
this.modelItem = this.getModelItem();
|
|
86
|
+
// ### register ourselves as boundControl
|
|
87
|
+
if (!this.modelItem.boundControls.includes(this)) {
|
|
88
|
+
this.modelItem.boundControls.push(this);
|
|
89
|
+
}
|
|
86
90
|
|
|
87
91
|
if (this.modelItem && !this.modelItem.relevant) {
|
|
88
92
|
// await Fore.fadeOutElement(this)
|
|
@@ -105,4 +109,6 @@ export class FxRepeatitem extends foreElementMixin(HTMLElement) {
|
|
|
105
109
|
}
|
|
106
110
|
}
|
|
107
111
|
|
|
108
|
-
|
|
112
|
+
if (!customElements.get('fx-repeatitem')) {
|
|
113
|
+
window.customElements.define('fx-repeatitem', FxRepeatitem);
|
|
114
|
+
}
|
package/src/ui/fx-switch.js
CHANGED