@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.
Files changed (62) hide show
  1. package/README.md +25 -34
  2. package/dist/fore-dev.js +43 -0
  3. package/dist/fore-dev.js.map +1 -0
  4. package/dist/fore.js +36 -1
  5. package/dist/fore.js.map +1 -0
  6. package/index.js +3 -0
  7. package/package.json +34 -38
  8. package/resources/fore.css +35 -50
  9. package/src/DependencyNotifyingDomFacade.js +10 -16
  10. package/src/ForeElementMixin.js +25 -18
  11. package/src/actions/abstract-action.js +17 -9
  12. package/src/actions/fx-action.js +6 -4
  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 +10 -6
  18. package/src/actions/fx-insert.js +49 -39
  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 +15 -10
  27. package/src/actions/fx-update.js +3 -1
  28. package/src/dep_graph.js +4 -2
  29. package/src/drawdown.js +67 -82
  30. package/src/fore.js +158 -11
  31. package/src/functions/fx-function.js +11 -3
  32. package/src/fx-bind.js +42 -202
  33. package/src/fx-fore.js +105 -70
  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 +37 -11
  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 +7 -1
  46. package/src/ui/fx-control.js +283 -33
  47. package/src/ui/fx-dialog.js +54 -40
  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 +8 -8
  52. package/src/ui/fx-output.js +14 -5
  53. package/src/ui/fx-repeat.js +33 -41
  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 +121 -131
  58. package/src/xpath-util.js +14 -7
  59. package/dist/fore-all.js +0 -140
  60. package/src/.DS_Store +0 -0
  61. package/src/actions/.DS_Store +0 -0
  62. package/src/ui/.DS_Store +0 -0
@@ -1,7 +1,6 @@
1
1
  import { AbstractAction } from './abstract-action.js';
2
2
  import getInScopeContext from '../getInScopeContext.js';
3
3
  import {
4
- evaluateXPath,
5
4
  evaluateXPathToNodes,
6
5
  evaluateXPathToFirstNode,
7
6
  evaluateXPathToNumber,
@@ -47,6 +46,12 @@ export class FxInsert extends AbstractAction {
47
46
  // ### if there's an origin attribute use it
48
47
  let originTarget;
49
48
  try {
49
+ /*
50
+ todo: discuss where to pass vars from event.detail into function context
51
+ */
52
+ // this.setInScopeVariables(this.detail);
53
+
54
+ // originTarget = evaluateXPathToFirstNode(this.origin, inscope, this);
50
55
  originTarget = evaluateXPathToFirstNode(this.origin, inscope, this.getOwnerForm());
51
56
  if (Array.isArray(originTarget) && originTarget.length === 0) {
52
57
  console.warn('invalid origin for this insert action - ignoring...', this);
@@ -85,32 +90,26 @@ export class FxInsert extends AbstractAction {
85
90
  console.log('this.nodeset', this.nodeset);
86
91
  */
87
92
 
88
- // ### obtaining targetSequence
89
- const inscope = getInScopeContext(this.getAttributeNode('ref'), this.ref);
90
-
91
- // @ts-ignore
92
- const targetSequence = evaluateXPathToNodes(this.ref, inscope, this.getOwnerForm());
93
- // console.log('insert nodeset ', targetSequence);
93
+ let inscope;
94
+ // ### 'context' attribute takes precedence over 'ref'
95
+ let targetSequence;
96
+ if (this.hasAttribute('context')) {
97
+ inscope = getInScopeContext(this.getAttributeNode('context'), this.getAttribute('context'));
98
+ targetSequence = evaluateXPathToNodes(
99
+ this.getAttribute('context'),
100
+ inscope,
101
+ this.getOwnerForm(),
102
+ );
103
+ }
94
104
 
95
- // ### obtaining originSequence
96
- /*
97
- let originSequence;
98
- if (this.origin) {
99
- // ### if there's an origin attribute use it
100
- const originTarget = evaluateXPathToFirstNode(this.origin, inscope, this.getOwnerForm());
101
- if(Array.isArray(originTarget) && originTarget.length === 0){
102
- console.warn('invalid origin for this insert action - ignoring...', this);
103
- return;
104
- }
105
- originSequence = originTarget.cloneNode(true);
106
- } else if (targetSequence) {
107
- // ### use last item of targetSequence
108
- originSequence = this._cloneTargetSequence(targetSequence);
109
- if(originSequence && !this.keepValues){
110
- this._clear(originSequence);
111
- }
112
- }
113
- */
105
+ if (this.hasAttribute('ref')) {
106
+ if (inscope) {
107
+ targetSequence = evaluateXPathToNodes(this.ref, inscope, this.getOwnerForm());
108
+ } else {
109
+ inscope = getInScopeContext(this.getAttributeNode('ref'), this.ref);
110
+ targetSequence = evaluateXPathToNodes(this.ref, inscope, this.getOwnerForm());
111
+ }
112
+ }
114
113
  const originSequenceClone = this._cloneOriginSequence(inscope, targetSequence);
115
114
  if (!originSequenceClone) return; // if no origin back out without effect
116
115
 
@@ -127,13 +126,9 @@ export class FxInsert extends AbstractAction {
127
126
  index = 1;
128
127
  console.log('appended', inscope);
129
128
  } else {
130
- // todo: eval 'at'
131
-
132
- /*
133
- insert at position given by 'at' or use the last item in the targetSequence
134
- */
135
- // if (this.at) {
129
+ /* ### insert at position given by 'at' or use the last item in the targetSequence ### */
136
130
  if (this.hasAttribute('at')) {
131
+ // todo: eval 'at'
137
132
  // index = this.at;
138
133
  // insertLocationNode = targetSequence[this.at - 1];
139
134
 
@@ -150,7 +145,11 @@ export class FxInsert extends AbstractAction {
150
145
  index = 1;
151
146
 
152
147
  insertLocationNode = targetSequence;
153
- const context = evaluateXPath('count(preceding::*)', targetSequence, this.getOwnerForm());
148
+ const context = evaluateXPathToNumber(
149
+ 'count(preceding::*)',
150
+ targetSequence,
151
+ this.getOwnerForm(),
152
+ );
154
153
  // console.log('context', context);
155
154
  index = context + 1;
156
155
  // index = targetSequence.findIndex(insertLocationNode);
@@ -165,7 +164,15 @@ export class FxInsert extends AbstractAction {
165
164
  // insertLocationNode.parentNode.append(originSequence);
166
165
  // const nextSibl = insertLocationNode.nextSibling;
167
166
  index += 1;
168
- insertLocationNode.insertAdjacentElement('afterend', originSequenceClone);
167
+ if (this.hasAttribute('context') && this.hasAttribute('ref')) {
168
+ // index=1;
169
+ inscope.append(originSequenceClone);
170
+ } else if (this.hasAttribute('context')) {
171
+ index = 1;
172
+ insertLocationNode.prepend(originSequenceClone);
173
+ } else {
174
+ insertLocationNode.insertAdjacentElement('afterend', originSequenceClone);
175
+ }
169
176
  }
170
177
  }
171
178
 
@@ -173,16 +180,17 @@ export class FxInsert extends AbstractAction {
173
180
  // console.log('parent ', insertLocationNode.parentNode);
174
181
  // console.log('instance ', this.getModel().getDefaultContext());
175
182
 
176
- // console.log('<<<<<<< at', this.at);
177
- // console.log('<<<<<<< index', index);
183
+ console.log('<<<<<<< at', this.at);
184
+ console.log('<<<<<<< index', index);
178
185
  // todo: this actually should dispatch to respective instance
179
186
  document.dispatchEvent(
180
- new CustomEvent('insert', {
187
+ // new CustomEvent('insert', {
188
+ new CustomEvent('index-changed', {
181
189
  composed: true,
182
190
  bubbles: true,
183
191
  detail: {
184
192
  insertedNodes: originSequenceClone,
185
- position: index,
193
+ index,
186
194
  },
187
195
  }),
188
196
  );
@@ -235,4 +243,6 @@ export class FxInsert extends AbstractAction {
235
243
  }
236
244
  }
237
245
 
238
- window.customElements.define('fx-insert', FxInsert);
246
+ if (!customElements.get('fx-insert')) {
247
+ window.customElements.define('fx-insert', FxInsert);
248
+ }
@@ -61,4 +61,6 @@ class FxMessage extends AbstractAction {
61
61
  }
62
62
  }
63
63
 
64
- window.customElements.define('fx-message', FxMessage);
64
+ if (!customElements.get('fx-message')) {
65
+ window.customElements.define('fx-message', FxMessage);
66
+ }
@@ -1,4 +1,5 @@
1
1
  import { AbstractAction } from './abstract-action.js';
2
+ import { Fore } from '../fore.js';
2
3
 
3
4
  /**
4
5
  * `fx-refresh`
@@ -8,8 +9,17 @@ import { AbstractAction } from './abstract-action.js';
8
9
  */
9
10
  class FxRefresh extends AbstractAction {
10
11
  perform() {
12
+ if (this.hasAttribute('self')) {
13
+ const control = Fore.getClosest('fx-control', this);
14
+ if (control) {
15
+ control.refresh();
16
+ return;
17
+ }
18
+ }
11
19
  this.getOwnerForm().refresh();
12
20
  }
13
21
  }
14
22
 
15
- window.customElements.define('fx-refresh', FxRefresh);
23
+ if (!customElements.get('fx-refresh')) {
24
+ window.customElements.define('fx-refresh', FxRefresh);
25
+ }
@@ -0,0 +1,68 @@
1
+ // import { FxAction } from './fx-action.js';
2
+ import '../fx-model.js';
3
+ import { AbstractAction } from './abstract-action.js';
4
+ import { evaluateXPathToFirstNode } from '../xpath-evaluation.js';
5
+
6
+ /**
7
+ * `fx-replace` - replaces the node referred to with 'ref' with node referred to with 'with' attribute.
8
+ *
9
+ * @customElement
10
+ */
11
+ export default class FxReplace extends AbstractAction {
12
+ static get properties() {
13
+ return {
14
+ ...super.properties,
15
+ with: {
16
+ type: String,
17
+ },
18
+ replaceNode: Object,
19
+ };
20
+ }
21
+
22
+ constructor() {
23
+ super();
24
+ this.with = '';
25
+ }
26
+
27
+ connectedCallback() {
28
+ if (super.connectedCallback) {
29
+ super.connectedCallback();
30
+ }
31
+ this.with = this.getAttribute('with');
32
+ }
33
+
34
+ perform() {
35
+ super.perform();
36
+ console.log('replace action');
37
+ if (!this.nodeset) {
38
+ return;
39
+ }
40
+ const target = evaluateXPathToFirstNode(this.with, this.nodeset, this);
41
+ if (!target) return;
42
+
43
+ this.replace(this.nodeset, target);
44
+ }
45
+
46
+ replace(toReplace, replaceWith) {
47
+ if (!toReplace || !replaceWith) return; // bail out silently
48
+ if (!toReplace.nodeName || !replaceWith.nodeName) {
49
+ console.warn('fx-replace: one argument is not a node');
50
+ return;
51
+ }
52
+
53
+ if (toReplace.nodeType === Node.ATTRIBUTE_NODE) {
54
+ const { ownerElement } = toReplace;
55
+ ownerElement.setAttribute(replaceWith.nodeName, replaceWith.textContent);
56
+ ownerElement.removeAttribute(toReplace.nodeName);
57
+ console.log('owner', ownerElement);
58
+ } else if (toReplace.nodeType === Node.ELEMENT_NODE) {
59
+ const cloned = replaceWith.cloneNode(true);
60
+ toReplace.replaceWith(cloned);
61
+ }
62
+ this.needsUpdate = true;
63
+ }
64
+ }
65
+
66
+ if (!customElements.get('fx-replace')) {
67
+ window.customElements.define('fx-replace', FxReplace);
68
+ }
@@ -0,0 +1,42 @@
1
+ import { AbstractAction } from './abstract-action.js';
2
+
3
+ /**
4
+ * `fx-return`
5
+ * returns data from a nested Fore to it's host Fore.
6
+ *
7
+ * behaves like a `<fx-submission @replace='instance' with `targetref` and respects relevance processing.
8
+ *
9
+ * `targetref` will be the `ref` of the host control.
10
+ *
11
+ * todo: deos not relevant selection yet
12
+ *
13
+ * @customElement
14
+ */
15
+ export class FxReturn extends AbstractAction {
16
+ connectedCallback() {
17
+ if (super.connectedCallback) {
18
+ super.connectedCallback();
19
+ }
20
+ // const nonrelevant = this.hasAttribute('nonrelevant') ? this.getAttribute('nonrelevant') : null;
21
+ }
22
+
23
+ perform() {
24
+ super.perform();
25
+ console.log('performing return with nodes', this.nodeset);
26
+
27
+ /*
28
+ ### note that this event does not use Fore.dispatch as the event uses 'composed:true' to let the event travel
29
+ up through the shadowRoot and being catched in outer form.
30
+ */
31
+ const event = new CustomEvent('return', {
32
+ composed: true,
33
+ bubbles: true,
34
+ detail: { nodeset: this.nodeset },
35
+ });
36
+ this.getOwnerForm().dispatchEvent(event);
37
+ }
38
+ }
39
+
40
+ if (!customElements.get('fx-return')) {
41
+ window.customElements.define('fx-return', FxReturn);
42
+ }
@@ -45,4 +45,6 @@ class FxSend extends AbstractAction {
45
45
  }
46
46
  }
47
47
 
48
- window.customElements.define('fx-send', FxSend);
48
+ if (!customElements.get('fx-send')) {
49
+ window.customElements.define('fx-send', FxSend);
50
+ }
@@ -1,7 +1,7 @@
1
1
  // import { FxAction } from './fx-action.js';
2
2
  import '../fx-model.js';
3
- import { AbstractAction } from './abstract-action.js';
4
- import { evaluateXPath } from '../xpath-evaluation.js';
3
+ import {AbstractAction} from './abstract-action.js';
4
+ import {evaluateXPath} from '../xpath-evaluation.js';
5
5
 
6
6
  /**
7
7
  * `fx-setvalue`
@@ -9,64 +9,71 @@ import { evaluateXPath } from '../xpath-evaluation.js';
9
9
  * @customElement
10
10
  */
11
11
  export default class FxSetvalue extends AbstractAction {
12
- static get properties() {
13
- return {
14
- ...super.properties,
15
- ref: {
16
- type: String,
17
- },
18
- valueAttr: {
19
- type: String,
20
- },
21
- };
22
- }
23
-
24
- constructor() {
25
- super();
26
- this.ref = '';
27
- this.valueAttr = '';
28
- }
12
+ static get properties() {
13
+ return {
14
+ ...super.properties,
15
+ ref: {
16
+ type: String,
17
+ },
18
+ valueAttr: {
19
+ type: String,
20
+ },
21
+ };
22
+ }
29
23
 
30
- connectedCallback() {
31
- if (super.connectedCallback) {
32
- super.connectedCallback();
24
+ constructor() {
25
+ super();
26
+ this.ref = '';
27
+ this.valueAttr = '';
33
28
  }
34
29
 
35
- if (this.hasAttribute('ref')) {
36
- this.ref = this.getAttribute('ref');
37
- } else {
38
- throw new Error('fx-setvalue must specify a "ref" attribute');
30
+ connectedCallback() {
31
+ if (super.connectedCallback) {
32
+ super.connectedCallback();
33
+ }
34
+
35
+ if (this.hasAttribute('ref')) {
36
+ this.ref = this.getAttribute('ref');
37
+ } else {
38
+ throw new Error('fx-setvalue must specify a "ref" attribute');
39
+ }
40
+ this.valueAttr = this.getAttribute('value');
39
41
  }
40
- this.valueAttr = this.getAttribute('value');
41
- }
42
42
 
43
- perform() {
44
- super.perform();
45
- let { value } = this;
46
- if (this.valueAttr !== null) {
47
- value = evaluateXPath(this.valueAttr, this.nodeset, this, this.detail);
48
- } else if (this.textContent !== '') {
49
- value = this.textContent;
50
- } else {
51
- value = '';
43
+ perform() {
44
+ super.perform();
45
+ let {value} = this;
46
+ if (this.valueAttr !== null) {
47
+ [value] = evaluateXPath(this.valueAttr, this.nodeset, this, this.detail);
48
+ } else if (this.textContent !== '') {
49
+ value = this.textContent;
50
+ } else {
51
+ value = '';
52
+ }
53
+ console.log('value', value);
54
+ if (value.nodeType === Node.ATTRIBUTE_NODE) {
55
+ console.log('value', value.nodeValue);
56
+ value = value.nodeValue;
57
+ }
58
+ const mi = this.getModelItem();
59
+ this.setValue(mi, value);
52
60
  }
53
- const mi = this.getModelItem();
54
- this.setValue(mi, value);
55
- }
56
61
 
57
- setValue(modelItem, newVal) {
58
- console.log('setvalue[1] ', modelItem, newVal);
62
+ setValue(modelItem, newVal) {
63
+ console.log('setvalue[1] ', modelItem, newVal);
59
64
 
60
- const item = modelItem;
61
- if (!item) return;
65
+ const item = modelItem;
66
+ if (!item) return;
62
67
 
63
- if (item.value !== newVal) {
64
- item.value = newVal;
65
- this.getModel().changed.push(modelItem);
66
- this.needsUpdate = true;
67
- console.log('setvalue[2] ', item, newVal);
68
+ if (item.value !== newVal) {
69
+ item.value = newVal;
70
+ this.getModel().changed.push(modelItem);
71
+ this.needsUpdate = true;
72
+ console.log('setvalue[2] ', item, newVal);
73
+ }
68
74
  }
69
- }
70
75
  }
71
76
 
72
- window.customElements.define('fx-setvalue', FxSetvalue);
77
+ if (!customElements.get('fx-setvalue')) {
78
+ window.customElements.define('fx-setvalue', FxSetvalue);
79
+ }
@@ -1,4 +1,6 @@
1
+ import { Fore } from '../fore.js';
1
2
  import { FxAction } from './fx-action.js';
3
+ import { resolveId } from '../xpath-evaluation.js';
2
4
 
3
5
  /**
4
6
  * `fx-confirm`
@@ -10,14 +12,16 @@ import { FxAction } from './fx-action.js';
10
12
  export class FxShow extends FxAction {
11
13
  connectedCallback() {
12
14
  this.dialog = this.getAttribute('dialog');
13
- if(!this.dialog){
14
- this.dispatch('error',{message:'dialog does not exist'})
15
+ if (!this.dialog) {
16
+ Fore.dispatch(this, 'error', { message: 'dialog does not exist' });
15
17
  }
16
18
  }
17
19
 
18
20
  perform() {
19
- document.getElementById(this.dialog).open();
21
+ resolveId(this.dialog, this).open();
20
22
  }
21
23
  }
22
24
 
23
- window.customElements.define('fx-show', FxShow);
25
+ if (!customElements.get('fx-show')) {
26
+ window.customElements.define('fx-show', FxShow);
27
+ }
@@ -1,23 +1,25 @@
1
- import { FxAction } from './fx-action.js';
1
+ import { AbstractAction } from './abstract-action.js';
2
2
 
3
3
  /**
4
4
  * `fx-toggle`
5
5
  *
6
6
  */
7
- class FxToggle extends FxAction {
7
+ class FxToggle extends AbstractAction {
8
+ /*
9
+ constructor() {
10
+ super();
11
+ this.attachShadow({ mode: 'open' });
12
+ }
13
+ */
8
14
  connectedCallback() {
15
+ super.connectedCallback();
9
16
  if (this.hasAttribute('case')) {
10
17
  this.case = this.getAttribute('case');
11
18
  }
12
19
  }
13
20
 
14
- /*
15
- disconnectedCallback() {
16
- super.disconnectedCallback();
17
- }
18
-
19
- */
20
- execute() {
21
+ perform() {
22
+ super.perform();
21
23
  console.log('### fx-toggle.execute ');
22
24
  if (this.case) {
23
25
  const ownerForm = this.getOwnerForm();
@@ -25,7 +27,10 @@ class FxToggle extends FxAction {
25
27
  const fxSwitch = caseElement.parentNode;
26
28
  fxSwitch.toggle(caseElement);
27
29
  }
30
+ // this.needsUpdate = true;
28
31
  }
29
32
  }
30
33
 
31
- window.customElements.define('fx-toggle', FxToggle);
34
+ if (!customElements.get('fx-toggle')) {
35
+ window.customElements.define('fx-toggle', FxToggle);
36
+ }
@@ -12,4 +12,6 @@ class FxUpdate extends AbstractAction {
12
12
  }
13
13
  }
14
14
 
15
- window.customElements.define('fx-update', FxUpdate);
15
+ if (!customElements.get('fx-update')) {
16
+ window.customElements.define('fx-update', FxUpdate);
17
+ }
package/src/dep_graph.js CHANGED
@@ -80,7 +80,7 @@ function createDFS(edges, leavesOnly, result, circular) {
80
80
  currentPath.push(node);
81
81
  window.dispatchEvent(
82
82
  new CustomEvent('compute-exception', {
83
- composed: true,
83
+ composed: false,
84
84
  bubbles: true,
85
85
  detail: {
86
86
  path: currentPath,
@@ -91,7 +91,9 @@ function createDFS(edges, leavesOnly, result, circular) {
91
91
  // return;
92
92
  // console.log('‘circular path: ' + currentPath);
93
93
  // throw new DepGraphCycleError(currentPath);
94
- // throw new Error(currentPath);
94
+
95
+ // Stop all processing. This form is broken and we should not break the browser
96
+ throw new Error(`Cyclic at ${currentPath}`);
95
97
  }
96
98
 
97
99
  inCurrentPath[node] = true;