@jinntec/fore 1.6.0 → 1.7.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/index.js CHANGED
@@ -55,6 +55,7 @@ import './src/actions/fx-hide.js';
55
55
  import './src/actions/fx-reload.js';
56
56
  import './src/actions/fx-reset.js';
57
57
  import './src/actions/fx-load.js';
58
+ import './src/actions/fx-toggleboolean.js';
58
59
 
59
60
  import './src/functions/fx-function.js';
60
61
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jinntec/fore",
3
- "version": "1.6.0",
3
+ "version": "1.7.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.5",
34
- "fontoxpath": "^3.29.0"
34
+ "fontoxpath": "^3.30.0"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@babel/plugin-proposal-class-properties": "^7.17.12",
@@ -0,0 +1,58 @@
1
+ // import { FxAction } from './fx-action.js';
2
+ import '../fx-model.js';
3
+ import {AbstractAction} from './abstract-action.js';
4
+ import {evaluateXPath} from '../xpath-evaluation.js';
5
+ import {Fore} from '../fore.js';
6
+
7
+ /**
8
+ * `fx-setvalue`
9
+ *
10
+ * @customElement
11
+ */
12
+ export default class FxToggleboolean extends AbstractAction {
13
+ static get properties() {
14
+ return {
15
+ ...super.properties,
16
+ ref: {
17
+ type: String,
18
+ },
19
+ valueAttr: {
20
+ type: String,
21
+ },
22
+ value:{
23
+ type: Boolean
24
+ }
25
+ };
26
+ }
27
+
28
+ constructor() {
29
+ super();
30
+ this.ref = '';
31
+ this.valueAttr = '';
32
+ this.value = false;
33
+ }
34
+
35
+ connectedCallback() {
36
+ if (super.connectedCallback) {
37
+ super.connectedCallback();
38
+ }
39
+
40
+ if (this.hasAttribute('ref')) {
41
+ this.ref = this.getAttribute('ref');
42
+ } else {
43
+ throw new Error('fx-togglealue must specify a "ref" attribute');
44
+ }
45
+ }
46
+
47
+ async perform() {
48
+ super.perform();
49
+ const mi = this.getModelItem();
50
+ mi.value === 'true' ? mi.node.textContent='false' : mi.node.textContent='true';
51
+ this.needsUpdate = true;
52
+ }
53
+
54
+ }
55
+
56
+ if (!customElements.get('fx-toggleboolean')) {
57
+ window.customElements.define('fx-toggleboolean', FxToggleboolean);
58
+ }
package/src/fore.js CHANGED
@@ -28,7 +28,7 @@ export class Fore {
28
28
  if(target?.classList.contains("widget")) return true;
29
29
  let parent = target.parentNode;
30
30
  while(parent && parent.nodeName !== 'FX-CONTROL'){
31
- if(parent.classList.contains('widget')) return true;
31
+ if(parent?.classList?.contains('widget')) return true;
32
32
  parent = parent.parentNode;
33
33
  }
34
34
  return false;
package/src/fx-bind.js CHANGED
@@ -44,6 +44,7 @@ export class FxBind extends foreElementMixin(HTMLElement) {
44
44
  connectedCallback() {
45
45
  // console.log('connectedCallback ', this);
46
46
  // this.id = this.hasAttribute('id')?this.getAttribute('id'):;
47
+ this.constraint = this.getAttribute('constraint');
47
48
  this.ref = this.getAttribute('ref');
48
49
  this.readonly = this.getAttribute('readonly');
49
50
  this.required = this.getAttribute('required');
@@ -133,6 +134,7 @@ export class FxBind extends foreElementMixin(HTMLElement) {
133
134
  this._addDependencies(constraintRefs, node, path, 'constraint');
134
135
  } else if (this.constraint) {
135
136
  this.model.mainGraph.addNode(`${path}:constraint`, node);
137
+ this.model.mainGraph.addDependency(path, `${path}:constraint`);
136
138
  }
137
139
  });
138
140
  }
package/src/fx-fore.js CHANGED
@@ -676,6 +676,7 @@ export class FxFore extends HTMLElement {
676
676
  generatedInstance.instanceData = generated;
677
677
  model.instances.push(generatedInstance);
678
678
  // console.log('generatedInstance ', this.getModel().getDefaultInstanceData());
679
+ Fore.dispatch(this,'instance-loaded',{instance:this})
679
680
  }
680
681
  }
681
682
 
@@ -113,7 +113,7 @@ export class FxInstance extends HTMLElement {
113
113
 
114
114
  reset(){
115
115
  // this._useInlineData();
116
- this.instanceData = this.originalInstance;
116
+ this.instanceData = this.originalInstance.cloneNode(true);
117
117
  }
118
118
 
119
119
  evalXPath(xpath) {
package/src/fx-model.js CHANGED
@@ -178,8 +178,8 @@ export class FxModel extends HTMLElement {
178
178
  bind.init(this);
179
179
  });
180
180
 
181
- // console.log(`mainGraph`, this.mainGraph);
182
- // console.log(`rebuild mainGraph calc order`, this.mainGraph.overallOrder());
181
+ console.log(`mainGraph`, this.mainGraph);
182
+ console.log(`rebuild mainGraph calc order`, this.mainGraph.overallOrder());
183
183
 
184
184
  // this.dispatchEvent(new CustomEvent('rebuild-done', {detail: {maingraph: this.mainGraph}}));
185
185
  Fore.dispatch(this,'rebuild-done',{maingraph:this.mainGraph});
@@ -1,358 +0,0 @@
1
- import {XPathUtil} from "../xpath-util";
2
-
3
- export class FxActionLog extends HTMLElement {
4
- constructor() {
5
- super();
6
- this.attachShadow({ mode: 'open' });
7
- this.listenTo = [];
8
- this.listeners = [];
9
- }
10
-
11
- connectedCallback() {
12
- const style = `
13
- :host {
14
- display:block;
15
- margin-top:1rem;
16
- position:relative;
17
- max-width:40em;
18
- }
19
- .buttons button{
20
- margin-right:0.5rem;
21
- }
22
- .info{
23
- padding:0.25em;
24
- }
25
- ol{
26
- background: #efefef;
27
- padding: 0.5em 1.5em;
28
- }
29
- li .info{
30
- margin:0.25em 0;
31
- }
32
- .info{
33
- display:grid;
34
- grid-template-columns:repeat(2, 1fr);
35
- background:orange;
36
- }
37
- .action.info{
38
- background:lightblue;
39
- }
40
-
41
- .event-name{
42
- width:14rem;
43
- display:inline-block;
44
- }
45
- /*
46
- .event-name::before{
47
- content:'triggered by';
48
- font-size:0.8em;
49
- text-decoration:italic;
50
- }
51
- */
52
- #filter{
53
- padding:1rem;
54
- display:flex;
55
- }
56
- label{
57
- margin-right:0.5rem;
58
- white-space:nowrap;
59
- display:inline-block;
60
- }
61
- .log-row{
62
- margin:0.25em 0;
63
- padding:0.5em;
64
- position:relative;
65
- }
66
- .log-row.empty-row summary{
67
- position:relative;
68
- }
69
- .log-row.empty-row summary{
70
- list-style:none;
71
- padding-left:1rem;
72
- }
73
- .log-row.empty-row summary::-webkit-details-marker {
74
- display: none;
75
- }
76
- .outermost{
77
- background:lightsteelblue;
78
- }
79
- `;
80
-
81
- if(localStorage.getItem('fx-action-log-filters')){
82
- this.listenTo = JSON.parse(localStorage.getItem('fx-action-log-filters'));
83
- }else {
84
- this._defaultSettings();
85
- }
86
-
87
-
88
- const html = `
89
- <details open>
90
- <summary>Event Log <span class="buttons"><button id="del"">del</a></button></span></summary>
91
- <details id="filter">
92
- <summary>filter <button id="reset">reset filters</button></summary>
93
- <div class="boxes"></div>
94
- </details>
95
- <div id="log"></div>
96
- </details>
97
- `;
98
-
99
- this.shadowRoot.innerHTML = `
100
- <style>
101
- ${style}
102
- </style>
103
- ${html}
104
- `;
105
-
106
- const fore = window.document.querySelector('fx-fore');
107
- if(!fore){
108
- console.error('fx-fore element not found in this page.');
109
- }
110
- const log = this.shadowRoot.querySelector('#log');
111
- fore.classList.add('action-log');
112
-
113
- this.listenTo.forEach(eventName => {
114
- if(eventName.show){
115
- fore.addEventListener(eventName.name, e => {
116
- this._log(e,log);
117
- });
118
- }
119
- });
120
-
121
- const boxes = this.shadowRoot.querySelector('.boxes');
122
-
123
- this.listenTo.forEach(item =>{
124
- const lbl = document.createElement('label');
125
- lbl.setAttribute('title',item.description);
126
- lbl.innerText = item.name;
127
- const cbx = document.createElement('input');
128
- cbx.setAttribute('type', 'checkbox');
129
- cbx.setAttribute('name', item.name);
130
- if(item.show){
131
- cbx.setAttribute('checked','');
132
- }
133
- lbl.append(cbx);
134
- cbx.addEventListener('click', e =>{
135
- console.log('filter box ticked', e);
136
- if(!e.target.checked){
137
- //remove event listener
138
- const fore = document.querySelector('fx-fore');
139
- fore.removeEventListener(item.name,this._log);
140
- // e.preventDefault();
141
- // e.stopPropagation();
142
- }
143
- const t = this.listenTo.find(evt => evt.name === item.name);
144
- e.target.checked ? t.show=true:t.show=false;
145
- // console.log('filter', this.listenTo);
146
- localStorage.setItem('fx-action-log-filters', JSON.stringify(this.listenTo));
147
- })
148
- boxes.appendChild(lbl);
149
- });
150
-
151
- document.addEventListener('outermost-action-start', e => {
152
- this.outermost = true;
153
- },{capture:true});
154
- document.addEventListener('outermost-action-end', e => {
155
- this.outermost = false;
156
- this.outermostAppender = null;
157
- },{capture:true});
158
-
159
- //buttons
160
- const del = this.shadowRoot.querySelector('#del');
161
- del.addEventListener('click', e => {
162
- this.shadowRoot.querySelector('#log').innerHTML = '';
163
- });
164
- const reset = this.shadowRoot.querySelector('#reset');
165
- reset.addEventListener('click', e => {
166
- this._defaultSettings();
167
- localStorage.removeItem('fx-action-log-filters');
168
- window.location.reload();
169
- });
170
-
171
-
172
-
173
- }
174
-
175
- _defaultSettings(){
176
- this.listenTo=[
177
- {name:"action-performed",show:true,description:'fired after an action has been performed'},
178
- {name:"click",show:true,description:''},
179
- {name:"deleted",show:true,description:'fired after a delete action has been executed'},
180
- {name:"dialog-shown",show:true,description:'fired when a dialog has been shown'},
181
- {name:"dialog-hidden",show:true,description:''},
182
- {name:"error",show:true,description:''},
183
- {name: "execute-action", show: true, description: ''},
184
- {name:"init",show:false,description:''},
185
- {name:"invalid",show:true,description:''},
186
- {name:"index-changed",show:true,description:''},
187
- {name:"instance-loaded",show:true,description:''},
188
- {name:"item-created",show:false,description:''},
189
- {name:"loaded",show:true,description:''},
190
- {name:"model-construct",show:true,description:''},
191
- {name:"model-construct-done",show:true,description:''},
192
- {name:"nonrelevant",show:true,description:''},
193
- {name:"optional",show:false,description:''},
194
- {name:"path-mutated", show:true,description:''},
195
- {name:"refresh-done", show:true,description:''},
196
- {name:"readonly",show:true,description:''},
197
- {name:"readwrite",show:true,description:''},
198
- {name:"rebuild-done",show:true,description:''},
199
- {name:"required",show:true,description:''},
200
- {name:"ready",show:true,description:''},
201
- {name:"recalculate-done",show:true,description:''},
202
- {name:"relevant",show:false,description:''},
203
- {name:"reload",show:true,description:''},
204
- {name:"select",show:true,description:''},
205
- {name:"deselect",show:true,description:''},
206
- {name:"submit",show:true,description:''},
207
- {name:"submit-error",show:true,description:''},
208
- {name:"submit-done",show:true,description:''},
209
- {name:"valid",show:false,description:''},
210
- {name: "value-changed", show: true, description: ''},
211
- {name: "outermost-action-start", show: true, description: ''},
212
- {name: "outermost-action-end", show: true, description: ''}
213
- ];
214
- }
215
-
216
- _log(e, log) {
217
- if(e.target.nodeName === 'FX-ACTION-LOG') return;
218
- e.preventDefault();
219
- e.stopPropagation();
220
-
221
-
222
-
223
-
224
- const row = document.createElement('div');
225
- row.classList.add('log-row');
226
- const logRow = this._logDetails(e);
227
- if(e.detail &&
228
- Object.keys(e.detail).length === 0 &&
229
- Object.getPrototypeOf(e.detail) === Object.prototype){
230
- row.classList.add('empty-row');
231
- }
232
-
233
- row.innerHTML = logRow;
234
-
235
- if(this.outermost){
236
- /*
237
- outermost-action-start and outermost-action-end are use as marker events only to start/end a list.
238
- They don't have aditional information to log.
239
- */
240
- if(e.type === 'outermost-action-start') return; // we don't want this event to actualy log something
241
- if(!this.outermostAppender){
242
- this.outermostAppender = document.createElement('ol');
243
- log.append(this.outermostAppender);
244
- }
245
- const li = document.createElement('li');
246
- li.innerHTML = logRow;
247
- this.outermostAppender.append(li);
248
- }else{
249
- log.append(row);
250
- }
251
- const logRowTarget = row.querySelector('.event-target');
252
- if(!logRowTarget) return;
253
-
254
- const targetElement = e.target;
255
- logRowTarget.addEventListener('click', e => {
256
- const alreadyLogged = document.querySelectorAll('.fx-action-log-debug');
257
- alreadyLogged.forEach(logged => {
258
- logged.classList.remove('fx-action-log-debug')
259
- });
260
-
261
- targetElement.dispatchEvent(
262
- new CustomEvent('log-action', {
263
- composed: false,
264
- bubbles: true,
265
- cancelable:true,
266
- detail: { target:targetElement },
267
- }),
268
- );
269
-
270
-
271
- targetElement.classList.add('fx-action-log-debug');
272
- targetElement.setAttribute('data-name', targetElement.nodeName)
273
- this._highlight(targetElement);
274
-
275
- });
276
- // log.append(logElements);
277
- }
278
-
279
- _logDetails(e){
280
- const {type} = e;
281
- // console.log('>>>> event type', type)
282
- const path = XPathUtil.getPath(e.target);
283
- switch (type){
284
- case 'outermost-action-start':
285
- return `start`;
286
- break;
287
- case 'outermost-action-end':
288
- return ``;
289
- break;
290
- case 'execute-action':
291
- const stripped = e.detail.action.nodeName.split('-')[1];
292
-
293
- switch (e.detail.action.nodeName){
294
- case 'FX-SEND':
295
- return `
296
- <div class="info action"
297
- <label class="action-name">${stripped} ${e.detail.action.getAttribute('submission')}</label>
298
- <a href="#" class="event-name">${e.detail.event}</a>
299
- </div>
300
- `;
301
- break;
302
- default:
303
- return `
304
- <div class="info action">
305
- <label class="action-name">${stripped}</label>
306
- <a href="#" class="event-name">${e.detail.event}</a>
307
- </div>
308
- `;
309
- }
310
- break;
311
- default:
312
- return `
313
- <div class="info event"
314
- <label class="event-name">${e.type}</label>
315
- <a href="#" class="event-target" title="${path}">${e.target.nodeName.toLowerCase()}</a>
316
- ${this._listAttributes(e)}
317
- </div>
318
- `;
319
-
320
- }
321
-
322
- // }
323
- }
324
-
325
- _listAttributes(e){
326
- console.log('_listAttributes',e)
327
- return ``;
328
- // return `${e.detail.model.id}`;
329
- /*
330
- if(e.detail &&
331
- Object.keys(e.detail).length === 0 &&
332
- Object.getPrototypeOf(e.detail) === Object.prototype){
333
- return ``;
334
- }else{
335
- return `${e.detail.map((item) => `<span>${item}</span>`)}`;
336
- }
337
- */
338
- }
339
-
340
- _highlight(element) {
341
- const defaultBG = element.style.backgroundColor;
342
- const defaultTransition = element.style.transition;
343
-
344
- element.style.transition = "background 1s";
345
- element.style.backgroundColor = "#FDFF47";
346
-
347
- setTimeout(() => {
348
- element.style.backgroundColor = defaultBG;
349
- setTimeout(() => {
350
- element.style.transition = defaultTransition;
351
- }, 400);
352
- }, 400);
353
- }
354
-
355
- }
356
- if (!customElements.get('fx-action-log')) {
357
- customElements.define('fx-action-log', FxActionLog);
358
- }