@jinntec/fore 1.0.0-5 → 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.
Files changed (63) hide show
  1. package/README.md +6 -27
  2. package/dist/fore-dev.js +43 -0
  3. package/dist/fore-dev.js.map +1 -0
  4. package/dist/fore.js +37 -0
  5. package/dist/fore.js.map +1 -0
  6. package/index.js +2 -1
  7. package/package.json +35 -39
  8. package/resources/fore.css +22 -54
  9. package/src/DependencyNotifyingDomFacade.js +5 -13
  10. package/src/ForeElementMixin.js +13 -20
  11. package/src/actions/abstract-action.js +14 -9
  12. package/src/actions/fx-action.js +6 -5
  13. package/src/actions/fx-append.js +8 -17
  14. package/src/actions/fx-confirm.js +3 -1
  15. package/src/actions/fx-delete.js +6 -3
  16. package/src/actions/fx-dispatch.js +9 -8
  17. package/src/actions/fx-hide.js +9 -6
  18. package/src/actions/fx-insert.js +27 -14
  19. package/src/actions/fx-message.js +3 -1
  20. package/src/actions/fx-refresh.js +11 -1
  21. package/src/actions/fx-replace.js +68 -0
  22. package/src/actions/fx-return.js +42 -0
  23. package/src/actions/fx-send.js +3 -1
  24. package/src/actions/fx-setvalue.js +58 -51
  25. package/src/actions/fx-show.js +8 -4
  26. package/src/actions/fx-toggle.js +13 -9
  27. package/src/actions/fx-update.js +3 -1
  28. package/src/dep_graph.js +1 -1
  29. package/src/drawdown.js +67 -82
  30. package/src/fore.js +141 -25
  31. package/src/functions/fx-function.js +11 -3
  32. package/src/fx-bind.js +39 -199
  33. package/src/fx-fore.js +101 -68
  34. package/src/fx-header.js +3 -1
  35. package/src/fx-instance.js +9 -1
  36. package/src/fx-model.js +31 -23
  37. package/src/fx-submission.js +73 -47
  38. package/src/fx-var.js +7 -4
  39. package/src/getInScopeContext.js +23 -16
  40. package/src/modelitem.js +4 -4
  41. package/src/relevance.js +65 -0
  42. package/src/ui/abstract-control.js +55 -35
  43. package/src/ui/fx-alert.js +7 -1
  44. package/src/ui/fx-case.js +3 -1
  45. package/src/ui/fx-container.js +4 -2
  46. package/src/ui/fx-control.js +283 -33
  47. package/src/ui/fx-dialog.js +50 -45
  48. package/src/ui/fx-group.js +3 -1
  49. package/src/ui/fx-hint.js +4 -1
  50. package/src/ui/fx-inspector.js +117 -17
  51. package/src/ui/fx-items.js +7 -5
  52. package/src/ui/fx-output.js +14 -5
  53. package/src/ui/fx-repeat.js +13 -26
  54. package/src/ui/fx-repeatitem.js +10 -4
  55. package/src/ui/fx-switch.js +3 -1
  56. package/src/ui/fx-trigger.js +3 -1
  57. package/src/xpath-evaluation.js +114 -102
  58. package/src/xpath-util.js +1 -5
  59. package/dist/fore-all.js +0 -140
  60. package/dist/fore-debug.js +0 -140
  61. package/src/.DS_Store +0 -0
  62. package/src/actions/.DS_Store +0 -0
  63. package/src/ui/.DS_Store +0 -0
@@ -1,19 +1,19 @@
1
- import {Fore} from '../fore.js';
2
- export class FxDialog extends HTMLElement {
1
+ import { Fore } from '../fore.js';
3
2
 
4
- static get properties() {
5
- return {
6
- id: String
7
- };
8
- }
3
+ export class FxDialog extends HTMLElement {
4
+ static get properties() {
5
+ return {
6
+ id: String,
7
+ };
8
+ }
9
9
 
10
- constructor() {
11
- super();
12
- this.attachShadow({mode: 'open'});
13
- }
10
+ constructor() {
11
+ super();
12
+ this.attachShadow({ mode: 'open' });
13
+ }
14
14
 
15
- connectedCallback() {
16
- const style = `
15
+ connectedCallback() {
16
+ const style = `
17
17
  :host {
18
18
  display:none;
19
19
  height: 100vh;
@@ -28,50 +28,55 @@ export class FxDialog extends HTMLElement {
28
28
 
29
29
  `;
30
30
 
31
- this.shadowRoot.innerHTML = this.render(style);
32
- this.id = this.getAttribute('id');
31
+ this.shadowRoot.innerHTML = this.render(style);
32
+ this.id = this.getAttribute('id');
33
33
 
34
- // const dialog = document.getElementById(this.id);
34
+ // const dialog = document.getElementById(this.id);
35
35
 
36
- const closeBtn = this.querySelector('.close-dialog');
37
- if (closeBtn) {
38
- closeBtn.addEventListener('click', (e) => {
39
- document.getElementById(this.id).classList.remove('show');
40
- });
41
- }
36
+ const closeBtn = this.querySelector('.close-dialog');
37
+ if (closeBtn) {
38
+ closeBtn.addEventListener('click', () => {
39
+ this.classList.remove('show');
40
+ });
41
+ }
42
42
 
43
- this.addEventListener('transitionend',()=>{
44
- console.log('transitionend');
45
- // this.style.display = 'none';
46
- });
43
+ this.addEventListener('transitionend', () => {
44
+ console.log('transitionend');
45
+ // this.style.display = 'none';
46
+ });
47
47
 
48
- this.focus();
49
- }
48
+ this.focus();
49
+ }
50
50
 
51
- render(styles) {
52
- return `
51
+ render(styles) {
52
+ return `
53
53
  <style>
54
54
  ${styles}
55
55
  </style>
56
56
  <slot></slot>
57
57
  `;
58
- }
58
+ }
59
59
 
60
- open(){
61
- window.addEventListener('keyup', (e) => {
62
- if (e.key === "Escape") {
63
- this.hide();
64
- }
65
- },{once:true});
60
+ open() {
61
+ window.addEventListener(
62
+ 'keyup',
63
+ e => {
64
+ if (e.key === 'Escape') {
65
+ this.hide();
66
+ }
67
+ },
68
+ { once: true },
69
+ );
66
70
 
67
- this.classList.add('show');
68
- }
69
-
70
- async hide(){
71
- await Fore.fadeOutElement(this,400);
72
- this.classList.remove('show');
73
- }
71
+ this.classList.add('show');
72
+ }
74
73
 
74
+ async hide() {
75
+ await Fore.fadeOutElement(this, 400);
76
+ this.classList.remove('show');
77
+ }
75
78
  }
76
79
 
77
- customElements.define('fx-dialog', FxDialog);
80
+ if (!customElements.get('fx-dialog')) {
81
+ customElements.define('fx-dialog', FxDialog);
82
+ }
@@ -86,4 +86,6 @@ class FxGroup extends FxContainer {
86
86
  }
87
87
  }
88
88
 
89
- window.customElements.define('fx-group', FxGroup);
89
+ if (!customElements.get('fx-group')) {
90
+ window.customElements.define('fx-group', FxGroup);
91
+ }
package/src/ui/fx-hint.js CHANGED
@@ -45,4 +45,7 @@ export class FxHint extends XfAbstractControl {
45
45
  }
46
46
  */
47
47
  }
48
- customElements.define('fx-hint', FxHint);
48
+
49
+ if (!customElements.get('fx-hint')) {
50
+ customElements.define('fx-hint', FxHint);
51
+ }
@@ -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:100%;
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 instances = Array.from(document.querySelectorAll('fx-instance'));
21
- this.innerHTML = `
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
- ${instances
27
- .map(
28
- (instance, index) => `
29
- <details ${index === 0 ? `open` : ''}>
30
- <summary>${instance.id}</summary>
31
- <pre>{log('${instance.id}')}</pre>
32
- </details>
33
- `,
34
- )
35
- .join('')}
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.addEventListener('slotchange', e => {
39
- console.log('slotchange ', e);
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.define('fx-inspector', FxInspector);
142
+ if (!customElements.get('fx-inspector')) {
143
+ customElements.define('fx-inspector', FxInspector);
144
+ }
@@ -1,4 +1,4 @@
1
- import { evaluateXPath, evaluateXPathToString, evaluateXPathToNodes } from '../xpath-evaluation.js';
1
+ import { evaluateXPathToString, resolveId } from '../xpath-evaluation.js';
2
2
  import FxControl from './fx-control.js';
3
3
  import { Fore } from '../fore.js';
4
4
 
@@ -33,7 +33,7 @@ export class FxItems extends FxControl {
33
33
 
34
34
  let target;
35
35
  if (e.target.nodeName === 'LABEL') {
36
- target = document.getElementById(e.target.getAttribute('for'));
36
+ target = resolveId(e.target.getAttribute('for'), this);
37
37
  target.checked = !target.checked;
38
38
  }
39
39
 
@@ -46,7 +46,7 @@ export class FxItems extends FxControl {
46
46
  this.setAttribute('value', val.trim());
47
47
 
48
48
  // ### check for parent control
49
- const parentBind = this.parentNode.closest('[ref]');
49
+ const parentBind = Fore.getClosest('[ref]', this.parentNode);
50
50
  if (!parentBind) return;
51
51
  const modelitem = parentBind.getModelItem();
52
52
  const setval = this.shadowRoot.getElementById('setvalue');
@@ -62,7 +62,7 @@ export class FxItems extends FxControl {
62
62
  async updateWidgetValue() {
63
63
  // console.log('setting items value');
64
64
 
65
- const parentBind = this.parentNode.closest('[ref]');
65
+ const parentBind = Fore.getClosest('[ref]', this.parentNode);
66
66
  if (parentBind) {
67
67
  this.value = parentBind.value;
68
68
  }
@@ -115,4 +115,6 @@ export class FxItems extends FxControl {
115
115
  }
116
116
  }
117
117
 
118
- customElements.define('fx-items', FxItems);
118
+ if (!customElements.get('fx-items')) {
119
+ customElements.define('fx-items', FxItems);
120
+ }
@@ -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
- this.dispatch('error', { message: error });
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
- this.readonly = true;
154
- return this.readonly;
161
+ return true;
155
162
  }
156
163
  }
157
164
 
158
- customElements.define('fx-output', FxOutput);
165
+ if (!customElements.get('fx-output')) {
166
+ customElements.define('fx-output', FxOutput);
167
+ }
@@ -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 '../xpath-util';
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() {
@@ -133,7 +135,7 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
133
135
  // const index = prev.index();
134
136
  // this.applyIndex(this.index -1);
135
137
 
136
- this.dispatch('path-mutated', { path, index: this.index });
138
+ Fore.dispatch(this, 'path-mutated', { path, index: this.index });
137
139
  }
138
140
  }
139
141
  });
@@ -197,31 +199,13 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
197
199
  });
198
200
  }
199
201
 
200
- const seq = evaluateXPath(this.ref, inscope, this);
201
- // const seq = evaluateXPathToNodes(this.ref, inscope, this.getOwnerForm());
202
- if (seq === null) {
203
- // Empty sequence
204
- 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];
205
206
  return;
206
207
  }
207
-
208
- if (typeof seq === 'object') {
209
- // Either a node or an array
210
- if ('nodeType' in seq) {
211
- // Node
212
- this.nodeset = [seq];
213
- return;
214
- }
215
-
216
- // if (Array.isArray(seq) && seq.every(item => typeof item === 'object')) {
217
- if (Array.isArray(seq)) {
218
- // multiple Nodes or maps
219
- this.nodeset = seq;
220
- return;
221
- }
222
- }
223
-
224
- throw new Error(`Unexpected result of repeat nodeset: ${seq}`);
208
+ this.nodeset = rawNodeset;
225
209
  }
226
210
 
227
211
  async refresh(force) {
@@ -269,6 +253,7 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
269
253
 
270
254
  newItem.nodeset = this.nodeset[position - 1];
271
255
  newItem.index = position;
256
+ this.getOwnerForm().someInstanceDataStructureChanged = true;
272
257
  }
273
258
  }
274
259
 
@@ -410,4 +395,6 @@ export class FxRepeat extends foreElementMixin(HTMLElement) {
410
395
  }
411
396
  }
412
397
 
413
- window.customElements.define('fx-repeat', FxRepeat);
398
+ if (!customElements.get('fx-repeat')) {
399
+ window.customElements.define('fx-repeat', FxRepeat);
400
+ }
@@ -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
- // console.log('refresh repeatitem: ',this.nodeset);
84
- // console.log('refresh repeatitem nodeset: ',this.nodeset);
85
- this.modelItem = this.getModel().getModelItem(this.nodeset);
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
- window.customElements.define('fx-repeatitem', FxRepeatitem);
112
+ if (!customElements.get('fx-repeatitem')) {
113
+ window.customElements.define('fx-repeatitem', FxRepeatitem);
114
+ }
@@ -74,4 +74,6 @@ class FxSwitch extends FxContainer {
74
74
  }
75
75
  }
76
76
 
77
- window.customElements.define('fx-switch', FxSwitch);
77
+ if (!customElements.get('fx-switch')) {
78
+ window.customElements.define('fx-switch', FxSwitch);
79
+ }
@@ -110,4 +110,6 @@ export class FxTrigger extends XfAbstractControl {
110
110
  */
111
111
  }
112
112
 
113
- customElements.define('fx-trigger', FxTrigger);
113
+ if (!customElements.get('fx-trigger')) {
114
+ customElements.define('fx-trigger', FxTrigger);
115
+ }