@jinntec/fore 1.1.0 → 1.3.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 +8 -8
- package/dist/fore-dev.js.map +1 -1
- package/dist/fore.js +7 -7
- package/dist/fore.js.map +1 -1
- package/index.js +1 -0
- package/package.json +2 -2
- package/resources/fore.css +95 -72
- package/src/ForeElementMixin.js +1 -1
- package/src/actions/abstract-action.js +55 -7
- package/src/actions/fx-action.js +2 -2
- package/src/actions/fx-confirm.js +2 -2
- package/src/actions/fx-delete.js +53 -62
- package/src/actions/fx-hide.js +3 -1
- package/src/actions/fx-message.js +25 -1
- package/src/actions/fx-refresh.js +9 -0
- package/src/actions/fx-reload.js +30 -0
- package/src/actions/fx-replace.js +1 -0
- package/src/actions/fx-send.js +11 -1
- package/src/actions/fx-setfocus.js +32 -5
- package/src/actions/fx-setvalue.js +4 -4
- package/src/actions/fx-show.js +1 -0
- package/src/actions/fx-toggle.js +5 -0
- package/src/events.js +24 -0
- package/src/fore.js +71 -8
- package/src/fx-bind.js +2 -2
- package/src/fx-fore.js +71 -20
- package/src/fx-instance.js +33 -8
- package/src/fx-model.js +435 -444
- package/src/fx-submission.js +78 -65
- package/src/getInScopeContext.js +91 -83
- package/src/modelitem.js +2 -2
- package/src/relevance.js +1 -1
- package/src/ui/abstract-control.js +114 -27
- package/src/ui/fx-alert.js +0 -1
- package/src/ui/fx-container.js +23 -27
- package/src/ui/fx-control.js +90 -34
- package/src/ui/fx-group.js +5 -0
- package/src/ui/fx-inspector.js +5 -2
- package/src/ui/fx-output.js +17 -15
- package/src/ui/fx-repeat.js +2 -2
- package/src/ui/fx-repeatitem.js +5 -3
- package/src/ui/fx-switch.js +11 -7
- package/src/ui/fx-trigger.js +15 -9
- package/src/xpath-evaluation.js +31 -18
- package/src/xpath-util.js +13 -0
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jinntec/fore",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Fore - declarative user interfaces in plain HTML",
|
|
5
5
|
"module": "./index.js",
|
|
6
6
|
"publishConfig": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@jinntec/jinn-toast": "^1.0.4",
|
|
34
|
-
"fontoxpath": "^3.
|
|
34
|
+
"fontoxpath": "^3.27.1"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@babel/plugin-proposal-class-properties": "^7.17.12",
|
package/resources/fore.css
CHANGED
|
@@ -17,32 +17,34 @@ html{
|
|
|
17
17
|
pointer-events: none;
|
|
18
18
|
cursor: default;
|
|
19
19
|
}
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
[refresh-on-view]{
|
|
21
|
+
/*opacity: 0;*/
|
|
22
22
|
}
|
|
23
|
+
/*
|
|
24
|
+
defaults for relevance
|
|
23
25
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
/* opacity: 1; */
|
|
29
|
-
/* } */
|
|
30
|
-
fx-group, fx-switch, fx-repeat, fx-dialog{
|
|
31
|
-
display: block;
|
|
32
|
-
}
|
|
33
|
-
fx-trigger a[disabled] {
|
|
34
|
-
color:lightgrey;
|
|
26
|
+
You can overwrite these matchers to use transistions
|
|
27
|
+
*/
|
|
28
|
+
[nonrelevant]{
|
|
29
|
+
display: none;
|
|
35
30
|
}
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
[relevant]{
|
|
32
|
+
display: block;
|
|
38
33
|
}
|
|
39
34
|
|
|
40
|
-
|
|
41
|
-
|
|
35
|
+
[required]:after {
|
|
36
|
+
content: "*";
|
|
37
|
+
display: inline;
|
|
38
|
+
color: red;
|
|
42
39
|
}
|
|
40
|
+
|
|
43
41
|
fx-alert{
|
|
44
42
|
color:darkred;
|
|
45
43
|
font-size: 0.9rem;
|
|
44
|
+
display: none;
|
|
45
|
+
}
|
|
46
|
+
.visited[invalid] fx-alert{
|
|
47
|
+
display: block;
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
/* case not displayed by default - if you want e.g. apply transitions you have to overwrite this rule with display='inline' or similar */
|
|
@@ -50,44 +52,30 @@ fx-case{
|
|
|
50
52
|
display: none;
|
|
51
53
|
}
|
|
52
54
|
|
|
53
|
-
fx-
|
|
54
|
-
|
|
55
|
+
fx-output[readonly] img{
|
|
56
|
+
background: inherit;
|
|
55
57
|
}
|
|
56
58
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
/* position: relative; */
|
|
59
|
+
.error{
|
|
60
|
+
background: var(--paper-red-500);
|
|
60
61
|
}
|
|
61
|
-
|
|
62
|
+
|
|
63
|
+
fx-control, fx-trigger , .fx-checkbox{
|
|
62
64
|
white-space: nowrap;
|
|
63
|
-
|
|
64
|
-
fx-hint{
|
|
65
|
-
display: none;
|
|
66
|
-
}
|
|
67
|
-
fx-repeatitem{
|
|
68
|
-
position:relative;
|
|
69
|
-
/*
|
|
70
|
-
opacity:1;
|
|
71
|
-
-webkit-transition: opacity 3s;
|
|
72
|
-
-moz-transition: opacity 3s;
|
|
73
|
-
transition: opacity 3s;
|
|
74
|
-
*/
|
|
75
|
-
}
|
|
76
|
-
.hidden {
|
|
77
|
-
visibility: hidden;
|
|
78
|
-
opacity: 0;
|
|
79
|
-
transition: visibility 0s 2s, opacity 2s linear;
|
|
65
|
+
/* position: relative; */
|
|
80
66
|
}
|
|
81
67
|
|
|
82
|
-
/* fx-inspector styles */
|
|
83
|
-
|
|
84
68
|
/* ### FX-DIALOG STYLES ### */
|
|
85
69
|
/* ### FX-DIALOG STYLES ### */
|
|
86
70
|
/* ### FX-DIALOG STYLES ### */
|
|
87
71
|
fx-dialog{
|
|
88
72
|
display: none;
|
|
89
73
|
opacity: 0;
|
|
74
|
+
width:100vw;
|
|
75
|
+
height: 100vh;
|
|
90
76
|
transition: opacity 1s linear;
|
|
77
|
+
z-index: -1;
|
|
78
|
+
transition: none;
|
|
91
79
|
}
|
|
92
80
|
fx-dialog.show{
|
|
93
81
|
display: block;
|
|
@@ -96,7 +84,7 @@ fx-dialog.show{
|
|
|
96
84
|
opacity: 1;
|
|
97
85
|
background:rgba(0,0,0,0.5);
|
|
98
86
|
z-index: 10;
|
|
99
|
-
transition: opacity
|
|
87
|
+
transition: opacity 0.4s linear;
|
|
100
88
|
}
|
|
101
89
|
|
|
102
90
|
fx-dialog.show .dialog-content{
|
|
@@ -126,48 +114,54 @@ fx-dialog .action{
|
|
|
126
114
|
display: block;
|
|
127
115
|
}
|
|
128
116
|
|
|
117
|
+
/* fx-fore{ */
|
|
118
|
+
/* opacity: 0; */
|
|
119
|
+
/* } */
|
|
120
|
+
/* fx-fore.fx-ready{ */
|
|
121
|
+
/* opacity: 1; */
|
|
122
|
+
/* } */
|
|
129
123
|
|
|
130
124
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
visibility: visible;
|
|
134
|
-
opacity: 1;
|
|
135
|
-
transition: opacity 2s linear;
|
|
125
|
+
fx-group, fx-switch, fx-repeat, fx-dialog{
|
|
126
|
+
display: block;
|
|
136
127
|
}
|
|
137
|
-
*/
|
|
138
128
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
color: red;
|
|
142
|
-
padding-left: 4px;
|
|
143
|
-
right:3px;
|
|
144
|
-
top:3px;
|
|
145
|
-
z-index: 1;
|
|
129
|
+
fx-hint{
|
|
130
|
+
display: none;
|
|
146
131
|
}
|
|
147
132
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
display: inline;
|
|
151
|
-
color: red;
|
|
133
|
+
fx-model, fx-model *, fx-model ::slotted(fx-instance), fx-instance{
|
|
134
|
+
display:none;
|
|
152
135
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
136
|
+
|
|
137
|
+
fx-trigger a[disabled] {
|
|
138
|
+
color:lightgrey;
|
|
156
139
|
}
|
|
157
|
-
|
|
140
|
+
fx-trigger img[disabled]{
|
|
141
|
+
filter:blur(2px);
|
|
142
|
+
}
|
|
143
|
+
|
|
158
144
|
|
|
145
|
+
fx-repeatitem{
|
|
146
|
+
position:relative;
|
|
147
|
+
opacity:1;
|
|
148
|
+
/*
|
|
149
|
+
-webkit-transition: opacity 3s;
|
|
150
|
+
-moz-transition: opacity 3s;
|
|
151
|
+
transition: opacity 3s;
|
|
152
|
+
*/
|
|
159
153
|
}
|
|
160
|
-
|
|
154
|
+
|
|
155
|
+
.hidden {
|
|
156
|
+
visibility: hidden;
|
|
161
157
|
opacity: 0;
|
|
162
|
-
|
|
163
|
-
transition: opacity 1s;
|
|
164
|
-
}
|
|
165
|
-
.vertical label{
|
|
166
|
-
display: block;
|
|
158
|
+
transition: visibility 0s 2s, opacity 2s linear;
|
|
167
159
|
}
|
|
168
|
-
|
|
169
|
-
|
|
160
|
+
|
|
161
|
+
.isEmpty.visited .widget{
|
|
162
|
+
background: lightpink;
|
|
170
163
|
}
|
|
164
|
+
|
|
171
165
|
.loaded{
|
|
172
166
|
animation: fadein 0.3s forwards;
|
|
173
167
|
}
|
|
@@ -176,6 +170,35 @@ fx-dialog .action{
|
|
|
176
170
|
animation: none;
|
|
177
171
|
opacity: 1;
|
|
178
172
|
}
|
|
173
|
+
|
|
174
|
+
.logtree details{
|
|
175
|
+
padding:0.1rem 1rem;
|
|
176
|
+
margin:0;
|
|
177
|
+
}
|
|
178
|
+
.logtree details summary{
|
|
179
|
+
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/*
|
|
183
|
+
.nonrelevant{
|
|
184
|
+
opacity: 0;
|
|
185
|
+
height: 0;
|
|
186
|
+
display: block;
|
|
187
|
+
padding: 0;
|
|
188
|
+
margin: 0;
|
|
189
|
+
border: none;
|
|
190
|
+
transition: opacity 0.4s;
|
|
191
|
+
}
|
|
192
|
+
*/
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
.submit-validation-failed .isEmpty .widget{
|
|
196
|
+
background: lightpink;
|
|
197
|
+
}
|
|
198
|
+
.vertical label{
|
|
199
|
+
display: block;
|
|
200
|
+
}
|
|
201
|
+
|
|
179
202
|
/* @keyframes fadein { */
|
|
180
203
|
/* 0% { */
|
|
181
204
|
/* opacity:0; */
|
package/src/ForeElementMixin.js
CHANGED
|
@@ -16,6 +16,9 @@ async function wait(howLong) {
|
|
|
16
16
|
* @demo demo/index.html
|
|
17
17
|
*/
|
|
18
18
|
export class AbstractAction extends foreElementMixin(HTMLElement) {
|
|
19
|
+
static outermostHandler = null;
|
|
20
|
+
static dataChanged = false;
|
|
21
|
+
|
|
19
22
|
static get properties() {
|
|
20
23
|
return {
|
|
21
24
|
...super.properties,
|
|
@@ -115,12 +118,33 @@ export class AbstractAction extends foreElementMixin(HTMLElement) {
|
|
|
115
118
|
*/
|
|
116
119
|
async execute(e) {
|
|
117
120
|
// console.log('executing', this);
|
|
121
|
+
|
|
118
122
|
// console.log('executing e', e);
|
|
119
123
|
// console.log('executing e phase', e.eventPhase);
|
|
124
|
+
if(AbstractAction.outermostHandler === null){
|
|
125
|
+
console.info(
|
|
126
|
+
`%coutermost Action `,
|
|
127
|
+
"background:#e65100; color:white; padding:0.3rem; display:inline-block; white-space: nowrap; border-radius:0.3rem;",
|
|
128
|
+
this
|
|
129
|
+
);
|
|
130
|
+
// console.log('starting outermost handler',this);
|
|
131
|
+
AbstractAction.outermostHandler = this;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if(AbstractAction.outermostHandler !== this){
|
|
135
|
+
console.info(
|
|
136
|
+
`%cAction `,
|
|
137
|
+
"background:orange; color:white; padding:0.3rem; display:inline-block; white-space: nowrap; border-radius:0.3rem;",
|
|
138
|
+
this
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
// console.log('>>> outermostHandler', AbstractAction.outermostHandler);
|
|
142
|
+
|
|
120
143
|
if(e && e.code){
|
|
121
144
|
const vars = new Map();
|
|
122
|
-
vars.set('code',e.code);
|
|
123
|
-
this.setInScopeVariables(vars);
|
|
145
|
+
vars.set('code', e.code);
|
|
146
|
+
// this.setInScopeVariables(vars);
|
|
147
|
+
this.setInScopeVariables(new Map([ ...this.inScopeVariables, ...vars]));
|
|
124
148
|
}
|
|
125
149
|
|
|
126
150
|
if (e && e.detail) {
|
|
@@ -131,12 +155,18 @@ export class AbstractAction extends foreElementMixin(HTMLElement) {
|
|
|
131
155
|
// index: the ordinal position of the key within the object
|
|
132
156
|
vars.set(key,e.detail[key]);
|
|
133
157
|
});
|
|
134
|
-
|
|
135
|
-
|
|
158
|
+
if(vars.size !== 0){
|
|
159
|
+
console.log("event detail vars", vars);
|
|
160
|
+
}
|
|
161
|
+
this.setInScopeVariables(new Map([ ...this.inScopeVariables, ...vars]));
|
|
136
162
|
}
|
|
137
163
|
this.needsUpdate = false;
|
|
138
164
|
|
|
139
|
-
|
|
165
|
+
try{
|
|
166
|
+
this.evalInContext();
|
|
167
|
+
}catch (error){
|
|
168
|
+
console.warn('evaluation faild',error);
|
|
169
|
+
}
|
|
140
170
|
if (this.targetElement && this.targetElement.nodeset) {
|
|
141
171
|
this.nodeset = this.targetElement.nodeset;
|
|
142
172
|
}
|
|
@@ -172,6 +202,7 @@ export class AbstractAction extends foreElementMixin(HTMLElement) {
|
|
|
172
202
|
// After loop is done call actionPerformed to update the model and UI
|
|
173
203
|
await loop();
|
|
174
204
|
this.actionPerformed();
|
|
205
|
+
Fore.dispatch(this, 'while-performed', {});
|
|
175
206
|
return;
|
|
176
207
|
}
|
|
177
208
|
|
|
@@ -187,15 +218,31 @@ export class AbstractAction extends foreElementMixin(HTMLElement) {
|
|
|
187
218
|
|
|
188
219
|
this.perform();
|
|
189
220
|
this.actionPerformed();
|
|
221
|
+
if(AbstractAction.outermostHandler === this){
|
|
222
|
+
AbstractAction.outermostHandler = null;
|
|
223
|
+
console.info(
|
|
224
|
+
`%coutermost Action done`,
|
|
225
|
+
"background:#e65100; color:white; padding:0.3rem; display:inline-block; white-space: nowrap; border-radius:0.3rem;",
|
|
226
|
+
this
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
}
|
|
190
230
|
}
|
|
191
231
|
|
|
192
232
|
/**
|
|
193
233
|
* Template method to be implemented by each action that is called by execute() as part of
|
|
194
234
|
* the processing.
|
|
195
235
|
*
|
|
196
|
-
*
|
|
236
|
+
* This function should not called on any action directly - call execute() instead to ensure proper execution of 'if' and 'while'
|
|
197
237
|
*/
|
|
198
238
|
perform() {
|
|
239
|
+
console.info(
|
|
240
|
+
`%cperform `,
|
|
241
|
+
"background:orange; color:white; padding:0.3rem; display:inline-block; white-space: nowrap; border-radius:0.3rem;",
|
|
242
|
+
this
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
//todo: review - this evaluation seems redundant as we already evaluated in execute
|
|
199
246
|
if (this.isBound() || this.nodeName === 'FX-ACTION') {
|
|
200
247
|
this.evalInContext();
|
|
201
248
|
}
|
|
@@ -206,6 +253,7 @@ export class AbstractAction extends foreElementMixin(HTMLElement) {
|
|
|
206
253
|
*/
|
|
207
254
|
actionPerformed() {
|
|
208
255
|
// console.log('actionPerformed action parentNode ', this.parentNode);
|
|
256
|
+
// if (this.needsUpdate && AbstractAction.outermostHandler !== this) {
|
|
209
257
|
if (this.needsUpdate) {
|
|
210
258
|
const model = this.getModel();
|
|
211
259
|
model.recalculate();
|
|
@@ -221,7 +269,7 @@ export class AbstractAction extends foreElementMixin(HTMLElement) {
|
|
|
221
269
|
* @event action-performed - whenever an action has been run
|
|
222
270
|
*/
|
|
223
271
|
dispatchActionPerformed() {
|
|
224
|
-
console.log('action-performed ', this);
|
|
272
|
+
// console.log('action-performed ', this);
|
|
225
273
|
Fore.dispatch(this, 'action-performed', {});
|
|
226
274
|
}
|
|
227
275
|
}
|
package/src/actions/fx-action.js
CHANGED
|
@@ -32,6 +32,7 @@ export class FxAction extends AbstractAction {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
perform() {
|
|
35
|
+
super.perform();
|
|
35
36
|
const { children } = this;
|
|
36
37
|
|
|
37
38
|
if (this.src) {
|
|
@@ -47,8 +48,7 @@ export class FxAction extends AbstractAction {
|
|
|
47
48
|
}
|
|
48
49
|
const action = actionOrVar;
|
|
49
50
|
action.detail = this.detail;
|
|
50
|
-
action.
|
|
51
|
-
// action.execute();
|
|
51
|
+
action.execute();
|
|
52
52
|
});
|
|
53
53
|
this.dispatchActionPerformed();
|
|
54
54
|
this.needsUpdate = true;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {FxAction} from "./fx-action.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* `fx-confirm`
|
|
@@ -7,7 +7,7 @@ import {AbstractAction} from "./abstract-action";
|
|
|
7
7
|
* @customElement
|
|
8
8
|
* @demo demo/project.html
|
|
9
9
|
*/
|
|
10
|
-
export class FxConfirm extends
|
|
10
|
+
export class FxConfirm extends FxAction {
|
|
11
11
|
connectedCallback() {
|
|
12
12
|
this.message = this.hasAttribute('message') ? this.getAttribute('message') : null;
|
|
13
13
|
}
|
package/src/actions/fx-delete.js
CHANGED
|
@@ -1,83 +1,74 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import {AbstractAction} from './abstract-action.js';
|
|
2
|
+
import {Fore} from '../fore.js';
|
|
3
|
+
import {evaluateXPathToNodes} from "../xpath-evaluation.js";
|
|
4
|
+
import {XPathUtil} from "../xpath-util";
|
|
5
|
+
import getInScopeContext from '../getInScopeContext.js';
|
|
3
6
|
|
|
4
7
|
/**
|
|
5
8
|
* `fx-delete`
|
|
6
|
-
*
|
|
9
|
+
* deletes nodes from instance data.
|
|
7
10
|
*
|
|
11
|
+
* @fires deleted event
|
|
8
12
|
* @customElement
|
|
9
13
|
* @demo demo/todo.html
|
|
10
14
|
*/
|
|
11
15
|
class FxDelete extends AbstractAction {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* deletes a
|
|
19
|
-
*/
|
|
20
|
-
perform() {
|
|
21
|
-
super.perform();
|
|
22
|
-
console.log('##### fx-delete executing...');
|
|
23
|
-
|
|
24
|
-
// this.ref = this.getAttribute('ref');
|
|
25
|
-
// const inscope = this.getInScopeContext();
|
|
26
|
-
// this.nodeset = fx.evaluateXPathToNodes(this.ref, inscope, null, {});
|
|
27
|
-
|
|
28
|
-
console.log('delete nodeset ', this.nodeset);
|
|
29
|
-
|
|
30
|
-
// ### if there's no repeat the delete action is inside of a repeat template
|
|
31
|
-
if (this.repeatId === '') {
|
|
32
|
-
// find the index to delete
|
|
33
|
-
const rItem = Fore.getClosest('fx-repeatitem', this.parentNode);
|
|
34
|
-
const idx = Array.from(rItem.parentNode.children).indexOf(rItem) + 1;
|
|
35
|
-
// console.log('>>> idx to delete ', idx);
|
|
16
|
+
constructor() {
|
|
17
|
+
super();
|
|
18
|
+
}
|
|
36
19
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
20
|
+
/**
|
|
21
|
+
* deletes nodes from instance data.
|
|
22
|
+
*
|
|
23
|
+
* Will NOT perform delete if nodeset is pointing to document node, document fragment, root node or being readonly.
|
|
24
|
+
*/
|
|
25
|
+
perform() {
|
|
26
|
+
console.log('##### fx-delete executing...');
|
|
27
|
+
const inscopeContext = getInScopeContext(this.getAttributeNode('ref') || this, this.ref);
|
|
28
|
+
this.nodeset = evaluateXPathToNodes(this.ref, inscopeContext, this);
|
|
40
29
|
|
|
41
|
-
|
|
42
|
-
let nodeToDelete;
|
|
43
|
-
if (Array.isArray(this.nodeset)) {
|
|
44
|
-
nodeToDelete = this.nodeset[idx - 1];
|
|
45
|
-
} else {
|
|
46
|
-
nodeToDelete = this.nodeset;
|
|
47
|
-
}
|
|
48
|
-
const p = nodeToDelete.parentNode;
|
|
49
|
-
p.removeChild(nodeToDelete);
|
|
30
|
+
console.log('delete nodeset ', this.nodeset);
|
|
50
31
|
|
|
51
|
-
|
|
52
|
-
|
|
32
|
+
const nodesToDelete = this.nodeset;
|
|
33
|
+
let parent;
|
|
34
|
+
if (Array.isArray(nodesToDelete)) {
|
|
35
|
+
if(nodesToDelete.length === 0) return;
|
|
36
|
+
parent = nodesToDelete[0].parentNode;
|
|
37
|
+
nodesToDelete.forEach(item => {
|
|
38
|
+
this._deleteNode(parent, item);
|
|
39
|
+
});
|
|
40
|
+
} else {
|
|
41
|
+
parent = nodesToDelete.parentNode;
|
|
42
|
+
this._deleteNode(parent, nodesToDelete);
|
|
43
|
+
}
|
|
53
44
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
} else if (idx > repeatSize) {
|
|
59
|
-
repeat.setIndex(repeatSize);
|
|
60
|
-
} else {
|
|
61
|
-
repeat.setIndex(idx);
|
|
62
|
-
}
|
|
45
|
+
const instanceId = XPathUtil.resolveInstance(this);
|
|
46
|
+
const instance = this.getModel().getInstance(instanceId);
|
|
47
|
+
Fore.dispatch(instance, 'deleted', {deletedNodes:nodesToDelete});
|
|
48
|
+
this.needsUpdate = true;
|
|
63
49
|
}
|
|
64
50
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
51
|
+
_deleteNode(parent, node) {
|
|
52
|
+
if (parent.nodeType === Node.DOCUMENT_NODE) return;
|
|
53
|
+
if (node.nodeType === Node.DOCUMENT_NODE) return;
|
|
54
|
+
if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) return;
|
|
55
|
+
if (node.parentNode === null) return;
|
|
69
56
|
|
|
70
|
-
|
|
57
|
+
const mi = this.getModelItem();
|
|
58
|
+
if (mi.readonly) return;
|
|
71
59
|
|
|
72
|
-
|
|
73
|
-
|
|
60
|
+
parent.removeChild(node);
|
|
61
|
+
}
|
|
74
62
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
63
|
+
/**
|
|
64
|
+
* overwriting as we need to perform additional rebuild()
|
|
65
|
+
*/
|
|
66
|
+
actionPerformed() {
|
|
67
|
+
this.getModel().rebuild();
|
|
68
|
+
super.actionPerformed();
|
|
69
|
+
}
|
|
79
70
|
}
|
|
80
71
|
|
|
81
72
|
if (!customElements.get('fx-delete')) {
|
|
82
|
-
|
|
73
|
+
window.customElements.define('fx-delete', FxDelete);
|
|
83
74
|
}
|
package/src/actions/fx-hide.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { AbstractAction } from './abstract-action.js';
|
|
2
|
+
import {evaluateXPathToString} from "../xpath-evaluation";
|
|
3
|
+
import {Fore} from "../fore";
|
|
4
|
+
import getInScopeContext from '../getInScopeContext.js';
|
|
2
5
|
|
|
3
6
|
/**
|
|
4
7
|
* `fx-message`
|
|
@@ -17,6 +20,8 @@ class FxMessage extends AbstractAction {
|
|
|
17
20
|
super.connectedCallback();
|
|
18
21
|
this.event = this.hasAttribute('event') ? this.getAttribute('event') : '';
|
|
19
22
|
this.level = this.hasAttribute('level') ? this.getAttribute('level') : 'ephemeral';
|
|
23
|
+
|
|
24
|
+
this.messageTextContent = this.textContent;
|
|
20
25
|
const style = `
|
|
21
26
|
:host{
|
|
22
27
|
display:none;
|
|
@@ -46,8 +51,9 @@ class FxMessage extends AbstractAction {
|
|
|
46
51
|
super.perform();
|
|
47
52
|
let message;
|
|
48
53
|
if (this.hasAttribute('value')) {
|
|
49
|
-
message = this.
|
|
54
|
+
message = this._getValue();
|
|
50
55
|
} else {
|
|
56
|
+
this.getOwnerForm().evaluateTemplateExpression(this.messageTextContent, this.firstChild);
|
|
51
57
|
message = this.textContent;
|
|
52
58
|
}
|
|
53
59
|
|
|
@@ -59,6 +65,24 @@ class FxMessage extends AbstractAction {
|
|
|
59
65
|
}),
|
|
60
66
|
);
|
|
61
67
|
}
|
|
68
|
+
|
|
69
|
+
_getValue() {
|
|
70
|
+
if (this.hasAttribute('value')) {
|
|
71
|
+
const valAttr = this.getAttribute('value');
|
|
72
|
+
try {
|
|
73
|
+
const inscopeContext = getInScopeContext(this, valAttr);
|
|
74
|
+
return evaluateXPathToString(valAttr, inscopeContext, this);
|
|
75
|
+
} catch (error) {
|
|
76
|
+
console.error(error);
|
|
77
|
+
Fore.dispatch(this, 'error', { message: error });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (this.textContent) {
|
|
81
|
+
return this.textContent;
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
|
|
62
86
|
}
|
|
63
87
|
|
|
64
88
|
if (!customElements.get('fx-message')) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AbstractAction } from './abstract-action.js';
|
|
2
2
|
import { Fore } from '../fore.js';
|
|
3
|
+
import {resolveId} from "../xpath-evaluation.js";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* `fx-refresh`
|
|
@@ -20,6 +21,14 @@ class FxRefresh extends AbstractAction {
|
|
|
20
21
|
this.getOwnerForm().forceRefresh();
|
|
21
22
|
return;
|
|
22
23
|
}
|
|
24
|
+
if(this.hasAttribute('control')){
|
|
25
|
+
const targetId = this.getAttribute('control');
|
|
26
|
+
const ctrl = resolveId(targetId, this);
|
|
27
|
+
if (Fore.isUiElement(ctrl.nodeName) && typeof ctrl.refresh === 'function') {
|
|
28
|
+
ctrl.refresh();
|
|
29
|
+
}
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
23
32
|
this.getOwnerForm().refresh();
|
|
24
33
|
}
|
|
25
34
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Fore } from '../fore.js';
|
|
2
|
+
import { AbstractAction } from './abstract-action.js';
|
|
3
|
+
import { resolveId } from '../xpath-evaluation.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* `fx-reload`
|
|
7
|
+
* reloads browser window when receiving 'reload' event
|
|
8
|
+
*
|
|
9
|
+
* @event reload dispatched when action executes. Usually calls its own handler but might get cancelled by other handler.
|
|
10
|
+
* @customElement
|
|
11
|
+
* @demo demo/project.html
|
|
12
|
+
*/
|
|
13
|
+
export class FxReload extends AbstractAction {
|
|
14
|
+
|
|
15
|
+
connectedCallback() {
|
|
16
|
+
super.connectedCallback();
|
|
17
|
+
this.addEventListener('reload', event => {
|
|
18
|
+
window.location.reload();
|
|
19
|
+
},{once:true});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
perform() {
|
|
23
|
+
Fore.dispatch(this, 'reload', {});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (!customElements.get('fx-reload')) {
|
|
28
|
+
window.customElements.define('fx-reload', FxReload);
|
|
29
|
+
}
|
|
30
|
+
|