@jinntec/fore 1.0.0-0 → 1.0.0-3

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.
@@ -9,7 +9,7 @@ import { getBucketsForNode } from 'fontoxpath';
9
9
  */
10
10
  export class DependencyNotifyingDomFacade {
11
11
  /**
12
- * @param {function(touchedNode: Node): void)} onNodeTouched A function what will be executed whenever a node is 'touched' by the XPath
12
+ * @param onNodeTouched - onNodeTouched A function what will be executed whenever a node is 'touched' by the XPath
13
13
  */
14
14
  constructor(onNodeTouched) {
15
15
  this._onNodeTouched = onNodeTouched;
@@ -45,13 +45,21 @@ export class DependencyNotifyingDomFacade {
45
45
  * @param bucket - The bucket that matches the attribute that will be used.
46
46
  */
47
47
  // eslint-disable-next-line class-methods-use-this
48
+ /*
48
49
  getChildNodes(node, bucket) {
49
50
  const matchingNodes = Array.from(node.childNodes).filter(
50
51
  childNode => !bucket || getBucketsForNode(childNode).includes(bucket),
51
52
  );
52
53
  return matchingNodes;
53
54
  }
55
+ */
54
56
 
57
+ getChildNodes(node, bucket) {
58
+ const matchingNodes = Array.from(node.childNodes).filter(
59
+ childNode => !bucket || getBucketsForNode(childNode).includes(bucket));
60
+ matchingNodes.forEach(matchingNode => this._onNodeTouched(matchingNode));
61
+ return matchingNodes;
62
+ }
55
63
  /**
56
64
  * Get the data of this node.
57
65
  *
@@ -23,12 +23,6 @@ export const foreElementMixin = superclass =>
23
23
  model: {
24
24
  type: Object,
25
25
  },
26
- /**
27
- * XPath binding expression pointing to bound node
28
- */
29
- ref: {
30
- type: String,
31
- },
32
26
  /**
33
27
  * The modelitem object associated to the bound node holding the evaluated state.
34
28
  */
@@ -41,6 +35,15 @@ export const foreElementMixin = superclass =>
41
35
  nodeset: {
42
36
  type: Object,
43
37
  },
38
+ /**
39
+ * XPath binding expression pointing to bound node
40
+ */
41
+ ref: {
42
+ type: String,
43
+ },
44
+ inScopeVariables: {
45
+ type: Map,
46
+ },
44
47
  };
45
48
  }
46
49
 
@@ -50,6 +53,7 @@ export const foreElementMixin = superclass =>
50
53
  this.model = null;
51
54
  this.modelItem = {};
52
55
  this.ref = this.hasAttribute('ref') ? this.getAttribute('ref') : '';
56
+ this.inScopeVariables = null;
53
57
  }
54
58
 
55
59
  getModel() {
@@ -90,7 +94,7 @@ export const foreElementMixin = superclass =>
90
94
  */
91
95
  evalInContext() {
92
96
  // const inscopeContext = this.getInScopeContext();
93
- const inscopeContext = getInScopeContext(this, this.ref);
97
+ const inscopeContext = getInScopeContext(this.getAttributeNode('ref') || this, this.ref);
94
98
  if (!inscopeContext) {
95
99
  console.warn('no in scopeContext for ', this);
96
100
  return;
@@ -98,26 +102,26 @@ export const foreElementMixin = superclass =>
98
102
  if (this.ref === '') {
99
103
  this.nodeset = inscopeContext;
100
104
  } else if (Array.isArray(inscopeContext)) {
105
+ /*
101
106
  inscopeContext.forEach(n => {
102
107
  if (XPathUtil.isSelfReference(this.ref)) {
103
108
  this.nodeset = inscopeContext;
104
109
  } else {
105
- const localResult = evaluateXPathToFirstNode(this.ref, n, null);
110
+ const localResult = evaluateXPathToFirstNode(this.ref, n, this);
106
111
  // console.log('local result: ', localResult);
107
112
  this.nodeset.push(localResult);
108
113
  }
109
114
  });
115
+ */
116
+ this.nodeset = evaluateXPathToFirstNode(this.ref, inscopeContext[0], this);
110
117
  } else {
111
118
  // this.nodeset = fx.evaluateXPathToFirstNode(this.ref, inscopeContext, null, {namespaceResolver: this.namespaceResolver});
112
-
113
- // todo: code below fails - why?
114
- const formElement = this.getOwnerForm();
115
- if (inscopeContext.nodeType) {
116
- this.nodeset = evaluateXPathToFirstNode(this.ref, inscopeContext, formElement);
119
+ const { nodeType } = inscopeContext;
120
+ if (nodeType) {
121
+ this.nodeset = evaluateXPathToFirstNode(this.ref, inscopeContext, this);
117
122
  } else {
118
- this.nodeset = evaluateXPath(this.ref, inscopeContext, formElement);
123
+ this.nodeset = evaluateXPath(this.ref, inscopeContext, this);
119
124
  }
120
- // this.nodeset = evaluateXPath(this.ref,inscopeContext,formElement)
121
125
  }
122
126
  // console.log('UiElement evaluated to nodeset: ', this.nodeset);
123
127
  }
@@ -217,7 +221,11 @@ export const foreElementMixin = superclass =>
217
221
  }
218
222
 
219
223
  getInScopeContext() {
220
- return getInScopeContext(this, this.ref);
224
+ return getInScopeContext(this.getAttributeNode('ref') || this, this.ref);
225
+ }
226
+
227
+ setInScopeVariables(inScopeVariables) {
228
+ this.inScopeVariables = inScopeVariables;
221
229
  }
222
230
 
223
231
  dispatch(eventName, detail) {
@@ -226,7 +234,7 @@ export const foreElementMixin = superclass =>
226
234
  bubbles: true,
227
235
  detail,
228
236
  });
229
- console.log('firing', event);
237
+ // console.log('firing', event);
230
238
  this.dispatchEvent(event);
231
239
  }
232
240
  };
@@ -81,7 +81,9 @@ export class AbstractAction extends foreElementMixin(HTMLElement) {
81
81
 
82
82
  this.target = this.getAttribute('target');
83
83
  if (this.target) {
84
- if (this.target === '#document') {
84
+ if (this.target === '#window') {
85
+ window.addEventListener(this.event, e => this.execute(e));
86
+ } else if (this.target === '#document') {
85
87
  document.addEventListener(this.event, e => this.execute(e));
86
88
  } else {
87
89
  this.targetElement = document.getElementById(this.target);
@@ -122,7 +124,7 @@ export class AbstractAction extends foreElementMixin(HTMLElement) {
122
124
  }
123
125
 
124
126
  // First check if 'if' condition is true - otherwise exist right away
125
- if (this.ifExpr && !evaluateXPathToBoolean(this.ifExpr, this.nodeset, this.getOwnerForm())) {
127
+ if (this.ifExpr && !evaluateXPathToBoolean(this.ifExpr, this.nodeset, this)) {
126
128
  return;
127
129
  }
128
130
 
@@ -137,7 +139,7 @@ export class AbstractAction extends foreElementMixin(HTMLElement) {
137
139
  return;
138
140
  }
139
141
 
140
- if (!evaluateXPathToBoolean(this.whileExpr, this.nodeset, this.getOwnerForm())) {
142
+ if (!evaluateXPathToBoolean(this.whileExpr, this.nodeset, this)) {
141
143
  // Done with iterating
142
144
  return;
143
145
  }
@@ -190,15 +192,14 @@ export class AbstractAction extends foreElementMixin(HTMLElement) {
190
192
  const model = this.getModel();
191
193
  model.recalculate();
192
194
  model.revalidate();
193
- model.parentNode.refresh();
194
- this._dispatchActionPerformed();
195
+ model.parentNode.refresh(true);
196
+ this.dispatchActionPerformed();
195
197
  }
196
198
  }
197
199
 
198
200
  /**
199
- * @private
200
201
  */
201
- _dispatchActionPerformed() {
202
+ dispatchActionPerformed() {
202
203
  console.log('action-performed ', this);
203
204
  this.dispatchEvent(
204
205
  new CustomEvent('action-performed', { composed: true, bubbles: true, detail: {} }),
@@ -41,11 +41,16 @@ export class FxAction extends AbstractAction {
41
41
  script.src = this.src;
42
42
  this.appendChild(script);
43
43
  } else {
44
- Array.from(children).forEach(action => {
44
+ Array.from(children).forEach(actionOrVar => {
45
+ if (actionOrVar.localName === 'fx-var') {
46
+ return;
47
+ }
48
+ const action = actionOrVar;
45
49
  action.detail = this.detail;
46
50
  // action.perform();
47
51
  action.execute();
48
52
  });
53
+ this.dispatchActionPerformed();
49
54
  // this.needsUpdate = false;
50
55
  }
51
56
  }
@@ -1,5 +1,6 @@
1
1
  import { AbstractAction } from './abstract-action.js';
2
- import { evaluateXPath } from '../xpath-evaluation.js';
2
+ import { evaluateXPath, resolveId } from '../xpath-evaluation.js';
3
+ import { XPathUtil } from '../xpath-util.js';
3
4
 
4
5
  /**
5
6
  * `fx-dispatch`
@@ -89,7 +90,14 @@ export class FxDispatch extends AbstractAction {
89
90
 
90
91
  // ### when targetid is given dispatch to that if present (throw an error if not) - otherwise dispatch to document
91
92
  if (this.targetid) {
92
- const target = document.getElementById(this.targetid);
93
+ // const target = document.getElementById(this.targetid);
94
+ let target;
95
+ if (XPathUtil.isRepeated(this)) {
96
+ target = resolveId(this.targetid, this.parentNode, null);
97
+ } else {
98
+ target = document.getElementById(this.targetid);
99
+ }
100
+ console.log('target', target);
93
101
  if (!target) {
94
102
  throw new Error(`targetid ${this.targetid} does not exist in document`);
95
103
  }
@@ -0,0 +1,23 @@
1
+ import { FxAction } from './fx-action.js';
2
+
3
+ /**
4
+ * `fx-hide`
5
+ * hides a dialog
6
+ *
7
+ * @customElement
8
+ * @demo demo/project.html
9
+ */
10
+ export class FxHide extends FxAction {
11
+ connectedCallback() {
12
+ this.dialog = this.getAttribute('dialog');
13
+ if(!this.dialog){
14
+ this.dispatch('error',{message:'dialog does not exist'})
15
+ }
16
+ }
17
+
18
+ perform() {
19
+ document.getElementById(this.dialog).hide();
20
+ }
21
+ }
22
+
23
+ window.customElements.define('fx-hide', FxHide);
@@ -77,7 +77,7 @@ export class FxInsert extends AbstractAction {
77
77
  }
78
78
 
79
79
  perform() {
80
- super.perform();
80
+ // super.perform();
81
81
 
82
82
  /*
83
83
  todo: !!! calling super here does not correctly give the nodeset - it's likely still a bug in ForeElementMixin !!!
@@ -86,11 +86,11 @@ export class FxInsert extends AbstractAction {
86
86
  */
87
87
 
88
88
  // ### obtaining targetSequence
89
- const inscope = getInScopeContext(this, this.ref);
89
+ const inscope = getInScopeContext(this.getAttributeNode('ref'), this.ref);
90
90
 
91
91
  // @ts-ignore
92
92
  const targetSequence = evaluateXPathToNodes(this.ref, inscope, this.getOwnerForm());
93
- console.log('insert nodeset ', targetSequence);
93
+ // console.log('insert nodeset ', targetSequence);
94
94
 
95
95
  // ### obtaining originSequence
96
96
  /*
@@ -117,8 +117,8 @@ export class FxInsert extends AbstractAction {
117
117
  let insertLocationNode;
118
118
  let index;
119
119
 
120
- const idx = this._getInsertIndex(inscope, targetSequence);
121
- console.log('insert index', idx);
120
+ // const idx = this._getInsertIndex(inscope, targetSequence);
121
+ // console.log('insert index', idx);
122
122
 
123
123
  // if the targetSequence is empty but we got an originSequence use inscope as context and ignore 'at' and 'position'
124
124
  if (targetSequence.length === 0) {
@@ -151,7 +151,7 @@ export class FxInsert extends AbstractAction {
151
151
 
152
152
  insertLocationNode = targetSequence;
153
153
  const context = evaluateXPath('count(preceding::*)', targetSequence, this.getOwnerForm());
154
- console.log('context', context);
154
+ // console.log('context', context);
155
155
  index = context + 1;
156
156
  // index = targetSequence.findIndex(insertLocationNode);
157
157
  }
@@ -171,15 +171,19 @@ export class FxInsert extends AbstractAction {
171
171
 
172
172
  // console.log('insert context item ', insertLocationNode);
173
173
  // console.log('parent ', insertLocationNode.parentNode);
174
- console.log('instance ', this.getModel().getDefaultContext());
174
+ // console.log('instance ', this.getModel().getDefaultContext());
175
175
 
176
- console.log('<<<<<<< at', this.at);
177
- console.log('<<<<<<< index', index);
176
+ // console.log('<<<<<<< at', this.at);
177
+ // console.log('<<<<<<< index', index);
178
+ // todo: this actually should dispatch to respective instance
178
179
  document.dispatchEvent(
179
180
  new CustomEvent('insert', {
180
181
  composed: true,
181
182
  bubbles: true,
182
- detail: { insertedNodes: originSequenceClone, position: index },
183
+ detail: {
184
+ insertedNodes: originSequenceClone,
185
+ position: index,
186
+ },
183
187
  }),
184
188
  );
185
189
 
@@ -17,7 +17,7 @@ class FxSend extends AbstractAction {
17
17
  connectedCallback() {
18
18
  // eslint-disable-next-line wc/guard-super-call
19
19
  super.connectedCallback();
20
- console.log('connectedCallback ', this);
20
+ // console.log('connectedCallback ', this);
21
21
  this.submission = this.getAttribute('submission');
22
22
  }
23
23
 
@@ -44,7 +44,7 @@ export default class FxSetvalue extends AbstractAction {
44
44
  super.perform();
45
45
  let { value } = this;
46
46
  if (this.valueAttr !== null) {
47
- value = evaluateXPath(this.valueAttr, this.nodeset, this.getOwnerForm(), this.detail);
47
+ value = evaluateXPath(this.valueAttr, this.nodeset, this, this.detail);
48
48
  } else if (this.textContent !== '') {
49
49
  value = this.textContent;
50
50
  } else {
@@ -62,10 +62,8 @@ export default class FxSetvalue extends AbstractAction {
62
62
 
63
63
  if (item.value !== newVal) {
64
64
  item.value = newVal;
65
- item.changed = true;
66
-
65
+ this.getModel().changed.push(modelItem);
67
66
  this.needsUpdate = true;
68
-
69
67
  console.log('setvalue[2] ', item, newVal);
70
68
  }
71
69
  }
@@ -0,0 +1,23 @@
1
+ import { FxAction } from './fx-action.js';
2
+
3
+ /**
4
+ * `fx-confirm`
5
+ * Displays a simple confirmation before actually executing the nested actions.
6
+ *
7
+ * @customElement
8
+ * @demo demo/project.html
9
+ */
10
+ export class FxShow extends FxAction {
11
+ connectedCallback() {
12
+ this.dialog = this.getAttribute('dialog');
13
+ if(!this.dialog){
14
+ this.dispatch('error',{message:'dialog does not exist'})
15
+ }
16
+ }
17
+
18
+ perform() {
19
+ document.getElementById(this.dialog).open();
20
+ }
21
+ }
22
+
23
+ window.customElements.define('fx-show', FxShow);
package/src/dep_graph.js CHANGED
@@ -320,6 +320,15 @@ DepGraph.prototype = {
320
320
  }
321
321
  throw new Error(`Node does not exist: ${node}`);
322
322
  },
323
+
324
+ /**
325
+ * Get an array of nodes that have no dependants (i.e. nothing depends on them).
326
+ */
327
+ entryNodes() {
328
+ const self = this;
329
+ return Object.keys(this.nodes).filter(node => self.incomingEdges[node].length === 0);
330
+ },
331
+
323
332
  /**
324
333
  * Construct the overall processing order for the dependency graph.
325
334
  *
@@ -0,0 +1,172 @@
1
+ /**
2
+ * drawdown.js
3
+ * (c) Adam Leggett
4
+ */
5
+
6
+ function markdown(src) {
7
+ var rx_lt = /</g;
8
+ var rx_gt = />/g;
9
+ var rx_space = /\t|\r|\uf8ff/g;
10
+ var rx_escape = /\\([\\\|`*_{}\[\]()#+\-~])/g;
11
+ var rx_hr = /^([*\-=_] *){3,}$/gm;
12
+ var rx_blockquote = /\n *&gt; *([^]*?)(?=(\n|$){2})/g;
13
+ var rx_list = /\n( *)(?:[*\-+]|((\d+)|([a-z])|[A-Z])[.)]) +([^]*?)(?=(\n|$){2})/g;
14
+ var rx_listjoin = /<\/(ol|ul)>\n\n<\1>/g;
15
+ var rx_highlight = /(^|[^A-Za-z\d\\])(([*_])|(~)|(\^)|(--)|(\+\+)|`)(\2?)([^<]*?)\2\8(?!\2)(?=\W|_|$)/g;
16
+ var rx_code = /\n((```|~~~).*\n?([^]*?)\n?\2|(( .*?\n)+))/g;
17
+ var rx_link = /((!?)\[(.*?)\]\((.*?)( ".*")?\)|\\([\\`*_{}\[\]()#+\-.!~]))/g;
18
+ var rx_table = /\n(( *\|.*?\| *\n)+)/g;
19
+ var rx_thead = /^.*\n( *\|( *\:?-+\:?-+\:? *\|)* *\n|)/;
20
+ var rx_row = /.*\n/g;
21
+ var rx_cell = /\||(.*?[^\\])\|/g;
22
+ var rx_heading = /(?=^|>|\n)([>\s]*?)(#{1,6}) (.*?)( #*)? *(?=\n|$)/g;
23
+ var rx_para = /(?=^|>|\n)\s*\n+([^<]+?)\n+\s*(?=\n|<|$)/g;
24
+ var rx_stash = /-\d+\uf8ff/g;
25
+
26
+ function replace(rex, fn) {
27
+ src = src.replace(rex, fn);
28
+ }
29
+
30
+ function element(tag, content) {
31
+ return '<' + tag + '>' + content + '</' + tag + '>';
32
+ }
33
+
34
+ function blockquote(src) {
35
+ return src.replace(rx_blockquote, function(all, content) {
36
+ return element('blockquote', blockquote(highlight(content.replace(/^ *&gt; */gm, ''))));
37
+ });
38
+ }
39
+
40
+ function list(src) {
41
+ return src.replace(rx_list, function(all, ind, ol, num, low, content) {
42
+ var entry = element(
43
+ 'li',
44
+ highlight(
45
+ content
46
+ .split(RegExp('\n ?' + ind + '(?:(?:\\d+|[a-zA-Z])[.)]|[*\\-+]) +', 'g'))
47
+ .map(list)
48
+ .join('</li><li>'),
49
+ ),
50
+ );
51
+
52
+ return (
53
+ '\n' +
54
+ (ol
55
+ ? '<ol start="' +
56
+ (num
57
+ ? ol + '">'
58
+ : parseInt(ol, 36) -
59
+ 9 +
60
+ '" style="list-style-type:' +
61
+ (low ? 'low' : 'upp') +
62
+ 'er-alpha">') +
63
+ entry +
64
+ '</ol>'
65
+ : element('ul', entry))
66
+ );
67
+ });
68
+ }
69
+
70
+ function highlight(src) {
71
+ return src.replace(rx_highlight, function(all, _, p1, emp, sub, sup, small, big, p2, content) {
72
+ return (
73
+ _ +
74
+ element(
75
+ emp
76
+ ? p2
77
+ ? 'strong'
78
+ : 'em'
79
+ : sub
80
+ ? p2
81
+ ? 's'
82
+ : 'sub'
83
+ : sup
84
+ ? 'sup'
85
+ : small
86
+ ? 'small'
87
+ : big
88
+ ? 'big'
89
+ : 'code',
90
+ highlight(content),
91
+ )
92
+ );
93
+ });
94
+ }
95
+
96
+ function unesc(str) {
97
+ return str.replace(rx_escape, '$1');
98
+ }
99
+
100
+ var stash = [];
101
+ var si = 0;
102
+
103
+ src = '\n' + src + '\n';
104
+
105
+ replace(rx_lt, '&lt;');
106
+ replace(rx_gt, '&gt;');
107
+ replace(rx_space, ' ');
108
+
109
+ // blockquote
110
+ src = blockquote(src);
111
+
112
+ // horizontal rule
113
+ replace(rx_hr, '<hr/>');
114
+
115
+ // list
116
+ src = list(src);
117
+ replace(rx_listjoin, '');
118
+
119
+ // code
120
+ replace(rx_code, function(all, p1, p2, p3, p4) {
121
+ stash[--si] = element('pre', element('code', p3 || p4.replace(/^ /gm, '')));
122
+ return si + '\uf8ff';
123
+ });
124
+
125
+ // link or image
126
+ replace(rx_link, function(all, p1, p2, p3, p4, p5, p6) {
127
+ stash[--si] = p4
128
+ ? p2
129
+ ? '<img src="' + p4 + '" alt="' + p3 + '"/>'
130
+ : '<a href="' + p4 + '">' + unesc(highlight(p3)) + '</a>'
131
+ : p6;
132
+ return si + '\uf8ff';
133
+ });
134
+
135
+ // table
136
+ replace(rx_table, function(all, table) {
137
+ var sep = table.match(rx_thead)[1];
138
+ return (
139
+ '\n' +
140
+ element(
141
+ 'table',
142
+ table.replace(rx_row, function(row, ri) {
143
+ return row == sep
144
+ ? ''
145
+ : element(
146
+ 'tr',
147
+ row.replace(rx_cell, function(all, cell, ci) {
148
+ return ci ? element(sep && !ri ? 'th' : 'td', unesc(highlight(cell || ''))) : '';
149
+ }),
150
+ );
151
+ }),
152
+ )
153
+ );
154
+ });
155
+
156
+ // heading
157
+ replace(rx_heading, function(all, _, p1, p2) {
158
+ return _ + element('h' + p1.length, unesc(highlight(p2)));
159
+ });
160
+
161
+ // paragraph
162
+ replace(rx_para, function(all, content) {
163
+ return element('p', unesc(highlight(content)));
164
+ });
165
+
166
+ // stash
167
+ replace(rx_stash, function(all) {
168
+ return stash[parseInt(all)];
169
+ });
170
+
171
+ return src.trim();
172
+ }