@jinntec/fore 1.0.0-2 → 1.0.0-5

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
@@ -5,6 +5,7 @@ import './src/fx-instance.js';
5
5
  import './src/fx-model.js';
6
6
  import './src/fx-submission.js';
7
7
  import './src/fx-header.js';
8
+ import './src/fx-var.js';
8
9
 
9
10
  // ui classes
10
11
  import './src/ui/fx-alert.js';
@@ -18,9 +19,11 @@ import './src/ui/fx-switch.js';
18
19
  import './src/ui/fx-trigger.js';
19
20
  import './src/ui/fx-case.js';
20
21
  import './src/ui/fx-inspector.js';
21
- // import './src/ui/fx-checkbox-group.js';
22
+ import './src/ui/fx-dialog.js';
22
23
  import './src/ui/fx-items.js';
23
24
 
25
+ // import './src/ui/fx-checkbox-group.js';
26
+
24
27
  // action classes
25
28
  import './src/actions/fx-append.js';
26
29
  import './src/actions/fx-delete.js';
@@ -33,5 +36,9 @@ import './src/actions/fx-dispatch.js';
33
36
  import './src/actions/fx-update.js';
34
37
  import './src/actions/fx-refresh.js';
35
38
  import './src/actions/fx-confirm.js';
39
+ import './src/actions/fx-show.js';
40
+ import './src/actions/fx-hide.js';
36
41
 
37
42
  import './src/functions/fx-function.js';
43
+
44
+ // import '@teipublisher/pb-components/src/pb-components-bundle.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jinntec/fore",
3
- "version": "1.0.0-2",
3
+ "version": "1.0.0-5",
4
4
  "description": "Fore - Forms for the Web",
5
5
  "module": "./index.js",
6
6
  "publishConfig": {
@@ -23,11 +23,11 @@
23
23
  "resources/vars.css",
24
24
  "resources/toastify.css",
25
25
  "src/**/*",
26
- "dist/fore.js",
27
- "dist/fore-all.js"
26
+ "dist/fore-all.js",
27
+ "dist/fore-debug.js"
28
28
  ],
29
29
  "dependencies": {
30
- "@jinntec/jinn-toast": "^1.0.2",
30
+ "@jinntec/jinn-toast": "^1.0.3",
31
31
  "@polymer/iron-component-page": "^4.0.1",
32
32
  "@polymer/iron-demo-helpers": "^3.1.0",
33
33
  "@polymer/paper-button": "^3.0.1",
@@ -14,6 +14,15 @@ html{
14
14
  pointer-events: none;
15
15
  cursor: default;
16
16
  }
17
+ fx-fore{
18
+ opacity: 0;
19
+ }
20
+ fx-fore.fx-ready{
21
+ opacity: 1;
22
+ }
23
+ fx-group, fx-switch, fx-repeat, fx-dialog{
24
+ display: block;
25
+ }
17
26
  fx-trigger a[disabled] {
18
27
  color:lightgrey;
19
28
  }
@@ -99,6 +108,52 @@ fx-inspector summary{
99
108
  padding: 0;
100
109
  }
101
110
 
111
+ /* ### FX-DIALOG STYLES ### */
112
+ /* ### FX-DIALOG STYLES ### */
113
+ /* ### FX-DIALOG STYLES ### */
114
+ fx-dialog{
115
+ display: none;
116
+ opacity: 0;
117
+ transition: opacity 1s linear;
118
+ }
119
+ fx-dialog.show{
120
+ display: block;
121
+ min-height: 200px;
122
+ border-radius: 0.5rem;
123
+ opacity: 1;
124
+ background:rgba(0,0,0,0.5);
125
+ z-index: 10;
126
+ transition: opacity 2s linear;
127
+ }
128
+
129
+ fx-dialog.show .dialog-content{
130
+ padding: 1rem;
131
+ width:fit-content;
132
+ height:fit-content;
133
+ border:thin solid;
134
+ border-radius: 0.3rem;
135
+ position: absolute;
136
+ left:50%;
137
+ top:50%;
138
+ transform:translateX(-50%) translateY(-50%);
139
+ background: white;
140
+
141
+ }
142
+ fx-dialog a.close-dialog{
143
+ position: absolute;
144
+ right: 0.4rem;
145
+ top:0.2rem;
146
+ color:var(--paper-grey-900);
147
+ text-decoration: none;
148
+ font-size:1.2rem;
149
+ }
150
+ fx-dialog .action{
151
+ width: 100%;
152
+ text-align: center;
153
+ display: block;
154
+ }
155
+
156
+
102
157
 
103
158
  /*
104
159
  .visible {
@@ -45,7 +45,7 @@ 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
49
  getChildNodes(node, bucket) {
50
50
  const matchingNodes = Array.from(node.childNodes).filter(
51
51
  childNode => !bucket || getBucketsForNode(childNode).includes(bucket),
@@ -56,10 +56,12 @@ export class DependencyNotifyingDomFacade {
56
56
 
57
57
  getChildNodes(node, bucket) {
58
58
  const matchingNodes = Array.from(node.childNodes).filter(
59
- childNode => !bucket || getBucketsForNode(childNode).includes(bucket));
59
+ childNode => !bucket || getBucketsForNode(childNode).includes(bucket),
60
+ );
60
61
  matchingNodes.forEach(matchingNode => this._onNodeTouched(matchingNode));
61
62
  return matchingNodes;
62
63
  }
64
+
63
65
  /**
64
66
  * Get the data of this node.
65
67
  *
@@ -83,11 +85,11 @@ export class DependencyNotifyingDomFacade {
83
85
  * @param bucket - The bucket that matches the attribute that will be used.
84
86
  */
85
87
  getFirstChild(node, bucket) {
86
- const matchingNode = Array.from(this.getChildNodes()).filter(
87
- childNode => !bucket || getBucketsForNode(childNode).includes(bucket),
88
- )[0];
89
- if (matchingNode) {
90
- return matchingNode;
88
+ for (const child of node.childNodes) {
89
+ if (!bucket || getBucketsForNode(child).includes(bucket)) {
90
+ this._onNodeTouched(node);
91
+ return child;
92
+ }
91
93
  }
92
94
  return null;
93
95
  }
@@ -7,6 +7,11 @@ import {
7
7
  } from './xpath-evaluation.js';
8
8
  import getInScopeContext from './getInScopeContext.js';
9
9
 
10
+ /**
11
+ * Mixin containing all general functions that are shared by all Fore element classes.
12
+ * @param superclass
13
+ * @returns {{readonly properties: {ref: {type: StringConstructor}, context: {type: ObjectConstructor}, nodeset: {type: ObjectConstructor}, model: {type: ObjectConstructor}, inScopeVariables: {type: MapConstructor}, modelItem: {type: ObjectConstructor}}, new(): ForeElementMixin, context: null, model: null, modelItem: {}, ref: *|string, inScopeVariables: null, nodeset: *, prototype: ForeElementMixin}}
14
+ */
10
15
  export const foreElementMixin = superclass =>
11
16
  class ForeElementMixin extends superclass {
12
17
  static get properties() {
@@ -41,6 +46,9 @@ export const foreElementMixin = superclass =>
41
46
  ref: {
42
47
  type: String,
43
48
  },
49
+ inScopeVariables: {
50
+ type: Map,
51
+ },
44
52
  };
45
53
  }
46
54
 
@@ -50,6 +58,7 @@ export const foreElementMixin = superclass =>
50
58
  this.model = null;
51
59
  this.modelItem = {};
52
60
  this.ref = this.hasAttribute('ref') ? this.getAttribute('ref') : '';
61
+ this.inScopeVariables = null;
53
62
  }
54
63
 
55
64
  getModel() {
@@ -90,10 +99,19 @@ export const foreElementMixin = superclass =>
90
99
  */
91
100
  evalInContext() {
92
101
  // const inscopeContext = this.getInScopeContext();
93
- const inscopeContext = getInScopeContext(this, this.ref);
102
+ let inscopeContext;
103
+ if(this.hasAttribute('context')){
104
+ inscopeContext = getInScopeContext(this.getAttributeNode('context') || this, this.context);
105
+ }
106
+ if(this.hasAttribute('ref')){
107
+ inscopeContext = getInScopeContext(this.getAttributeNode('ref') || this, this.ref);
108
+ }
94
109
  if (!inscopeContext) {
110
+ // ### always fall back to default context with there's neither a 'context' or 'ref' present
111
+ inscopeContext = this.getModel().getDefaultInstance().getDefaultContext();
95
112
  console.warn('no in scopeContext for ', this);
96
- return;
113
+ console.warn('using default context ', this);
114
+ // return;
97
115
  }
98
116
  if (this.ref === '') {
99
117
  this.nodeset = inscopeContext;
@@ -217,7 +235,11 @@ export const foreElementMixin = superclass =>
217
235
  }
218
236
 
219
237
  getInScopeContext() {
220
- return getInScopeContext(this, this.ref);
238
+ return getInScopeContext(this.getAttributeNode('ref') || this, this.ref);
239
+ }
240
+
241
+ setInScopeVariables(inScopeVariables) {
242
+ this.inScopeVariables = inScopeVariables;
221
243
  }
222
244
 
223
245
  dispatch(eventName, detail) {
@@ -124,7 +124,7 @@ export class AbstractAction extends foreElementMixin(HTMLElement) {
124
124
  }
125
125
 
126
126
  // First check if 'if' condition is true - otherwise exist right away
127
- if (this.ifExpr && !evaluateXPathToBoolean(this.ifExpr, this.nodeset, this.getOwnerForm())) {
127
+ if (this.ifExpr && !evaluateXPathToBoolean(this.ifExpr, this.nodeset, this)) {
128
128
  return;
129
129
  }
130
130
 
@@ -139,7 +139,7 @@ export class AbstractAction extends foreElementMixin(HTMLElement) {
139
139
  return;
140
140
  }
141
141
 
142
- if (!evaluateXPathToBoolean(this.whileExpr, this.nodeset, this.getOwnerForm())) {
142
+ if (!evaluateXPathToBoolean(this.whileExpr, this.nodeset, this)) {
143
143
  // Done with iterating
144
144
  return;
145
145
  }
@@ -198,6 +198,9 @@ export class AbstractAction extends foreElementMixin(HTMLElement) {
198
198
  }
199
199
 
200
200
  /**
201
+ * dispathes action-performed event
202
+ *
203
+ * @event action-performed - whenever an action has been run
201
204
  */
202
205
  dispatchActionPerformed() {
203
206
  console.log('action-performed ', this);
@@ -41,7 +41,11 @@ 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();
@@ -50,6 +54,7 @@ export class FxAction extends AbstractAction {
50
54
  // this.needsUpdate = false;
51
55
  }
52
56
  }
57
+
53
58
  }
54
59
 
55
60
  window.customElements.define('fx-action', FxAction);
@@ -0,0 +1,24 @@
1
+ import { FxAction } from './fx-action.js';
2
+ import {AbstractAction} from "./abstract-action";
3
+
4
+ /**
5
+ * `fx-hide`
6
+ * hides a dialog
7
+ *
8
+ * @customElement
9
+ * @demo demo/project.html
10
+ */
11
+ export class FxHide extends AbstractAction {
12
+ connectedCallback() {
13
+ this.dialog = this.getAttribute('dialog');
14
+ if(!this.dialog){
15
+ this.dispatch('error',{message:'dialog does not exist'})
16
+ }
17
+ }
18
+
19
+ perform() {
20
+ document.getElementById(this.dialog).hide();
21
+ }
22
+ }
23
+
24
+ window.customElements.define('fx-hide', FxHide);
@@ -85,32 +85,22 @@ export class FxInsert extends AbstractAction {
85
85
  console.log('this.nodeset', this.nodeset);
86
86
  */
87
87
 
88
- // ### obtaining targetSequence
89
- const inscope = getInScopeContext(this, this.ref);
90
-
91
- // @ts-ignore
92
- const targetSequence = evaluateXPathToNodes(this.ref, inscope, this.getOwnerForm());
93
- // console.log('insert nodeset ', targetSequence);
88
+ let inscope;
89
+ // ### 'context' attribute takes precedence over 'ref'
90
+ let targetSequence;
91
+ if(this.hasAttribute('context')){
92
+ inscope = getInScopeContext(this.getAttributeNode('context'), this.getAttribute('context'));
93
+ targetSequence = evaluateXPathToNodes(this.getAttribute('context'), inscope, this.getOwnerForm());
94
+ }
94
95
 
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
- */
96
+ if(this.hasAttribute('ref')){
97
+ if(inscope){
98
+ targetSequence = evaluateXPathToNodes(this.ref, inscope, this.getOwnerForm());
99
+ }else{
100
+ inscope = getInScopeContext(this.getAttributeNode('ref'), this.ref);
101
+ targetSequence = evaluateXPathToNodes(this.ref, inscope, this.getOwnerForm());
102
+ }
103
+ }
114
104
  const originSequenceClone = this._cloneOriginSequence(inscope, targetSequence);
115
105
  if (!originSequenceClone) return; // if no origin back out without effect
116
106
 
@@ -127,13 +117,10 @@ export class FxInsert extends AbstractAction {
127
117
  index = 1;
128
118
  console.log('appended', inscope);
129
119
  } else {
130
- // todo: eval 'at'
131
120
 
132
- /*
133
- insert at position given by 'at' or use the last item in the targetSequence
134
- */
135
- // if (this.at) {
121
+ /* ### insert at position given by 'at' or use the last item in the targetSequence ### */
136
122
  if (this.hasAttribute('at')) {
123
+ // todo: eval 'at'
137
124
  // index = this.at;
138
125
  // insertLocationNode = targetSequence[this.at - 1];
139
126
 
@@ -165,7 +152,16 @@ export class FxInsert extends AbstractAction {
165
152
  // insertLocationNode.parentNode.append(originSequence);
166
153
  // const nextSibl = insertLocationNode.nextSibling;
167
154
  index += 1;
168
- insertLocationNode.insertAdjacentElement('afterend', originSequenceClone);
155
+ if(this.hasAttribute('context') && this.hasAttribute('ref')){
156
+ // index=1;
157
+ inscope.append(originSequenceClone);
158
+ }else if(this.hasAttribute('context')){
159
+ const contextAttr = this.getAttribute('context');
160
+ index=1;
161
+ insertLocationNode.prepend(originSequenceClone);
162
+ }else{
163
+ insertLocationNode.insertAdjacentElement('afterend', originSequenceClone);
164
+ }
169
165
  }
170
166
  }
171
167
 
@@ -173,16 +169,17 @@ export class FxInsert extends AbstractAction {
173
169
  // console.log('parent ', insertLocationNode.parentNode);
174
170
  // console.log('instance ', this.getModel().getDefaultContext());
175
171
 
176
- // console.log('<<<<<<< at', this.at);
177
- // console.log('<<<<<<< index', index);
172
+ console.log('<<<<<<< at', this.at);
173
+ console.log('<<<<<<< index', index);
178
174
  // todo: this actually should dispatch to respective instance
179
175
  document.dispatchEvent(
180
- new CustomEvent('insert', {
176
+ // new CustomEvent('insert', {
177
+ new CustomEvent('index-changed', {
181
178
  composed: true,
182
179
  bubbles: true,
183
180
  detail: {
184
181
  insertedNodes: originSequenceClone,
185
- position: index,
182
+ index,
186
183
  },
187
184
  }),
188
185
  );
@@ -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 {
@@ -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);
@@ -17,7 +17,8 @@ class FxToggle extends FxAction {
17
17
  }
18
18
 
19
19
  */
20
- execute() {
20
+ perform() {
21
+ super.perform();
21
22
  console.log('### fx-toggle.execute ');
22
23
  if (this.case) {
23
24
  const ownerForm = this.getOwnerForm();
package/src/dep_graph.js CHANGED
@@ -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;
package/src/fore.js CHANGED
@@ -13,6 +13,7 @@ export class Fore {
13
13
  return [
14
14
  'FX-DELETE',
15
15
  'FX-DISPATCH',
16
+ 'FX-HIDE',
16
17
  'FX-INSERT',
17
18
  'FX-LOAD',
18
19
  'FX-MESSAGE',
@@ -29,6 +30,7 @@ export class Fore {
29
30
  'FX-SETFOCUS',
30
31
  'FX-SETINDEX',
31
32
  'FX-SETVALUE',
33
+ 'FX-SHOW',
32
34
  'FX-TOGGLE',
33
35
  'FX-UPDATE',
34
36
  ];
@@ -83,6 +85,7 @@ export class Fore {
83
85
  'FX-TEXTAREA',
84
86
  'FX-TRIGGER',
85
87
  'FX-UPLOAD',
88
+ 'FX-VAR',
86
89
  ];
87
90
  }
88
91
 
@@ -187,14 +190,16 @@ export class Fore {
187
190
  return fadeIn();
188
191
  }
189
192
 
190
- static fadeOutElement(element) {
191
- const duration = 2600;
193
+ static fadeOutElement(element, duration) {
194
+ // const duration = duration;
192
195
  let fadeOut = () => {
196
+
193
197
  // Stop all current animations
194
198
  if (element.getAnimations) {
195
199
  element.getAnimations().map(anim => anim.finish());
196
200
  }
197
201
 
202
+
198
203
  // Play the animation with the newly specified duration
199
204
  fadeOut = element.animate(
200
205
  {
@@ -217,6 +222,33 @@ export class Fore {
217
222
  target.dispatchEvent(event);
218
223
  }
219
224
 
225
+ static prettifyXml(source) {
226
+ const xmlDoc = new DOMParser().parseFromString(source, 'application/xml');
227
+ const xsltDoc = new DOMParser().parseFromString(
228
+ [
229
+ // describes how we want to modify the XML - indent everything
230
+ '<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">',
231
+ ' <xsl:strip-space elements="*"/>',
232
+ ' <xsl:template match="para[content-style][not(text())]">', // change to just text() to strip space in text nodes
233
+ ' <xsl:value-of select="normalize-space(.)"/>',
234
+ ' </xsl:template>',
235
+ ' <xsl:template match="node()|@*">',
236
+ ' <xsl:copy><xsl:apply-templates select="node()|@*"/></xsl:copy>',
237
+ ' </xsl:template>',
238
+ ' <xsl:output indent="yes"/>',
239
+ '</xsl:stylesheet>',
240
+ ].join('\n'),
241
+ 'application/xml',
242
+ );
243
+
244
+ const xsltProcessor = new XSLTProcessor();
245
+ xsltProcessor.importStylesheet(xsltDoc);
246
+ const resultDoc = xsltProcessor.transformToDocument(xmlDoc);
247
+ const resultXml = new XMLSerializer().serializeToString(resultDoc);
248
+ return resultXml;
249
+ }
250
+
251
+
220
252
  /**
221
253
  * clear all text nodes and attribute values to get a 'clean' template.
222
254
  * @param n
package/src/fx-bind.js CHANGED
@@ -7,6 +7,7 @@ import {
7
7
  evaluateXPathToString,
8
8
  } from './xpath-evaluation.js';
9
9
  import { XPathUtil } from './xpath-util.js';
10
+ import getInScopeContext from './getInScopeContext.js';
10
11
 
11
12
  /**
12
13
  * FxBind declaratively attaches constraints to nodes in the data (instances).
@@ -229,12 +230,6 @@ export class FxBind extends foreElementMixin(HTMLElement) {
229
230
  }
230
231
  }
231
232
 
232
- _addNode(path, node) {
233
- if (!this.model.mainGraph.hasNode(path)) {
234
- this.model.mainGraph.addNode(path, { node });
235
- }
236
- }
237
-
238
233
  /**
239
234
  * Add the dependencies of this bind
240
235
  *
@@ -245,6 +240,7 @@ export class FxBind extends foreElementMixin(HTMLElement) {
245
240
  * @param {string} property The property with this dependency
246
241
  */
247
242
  _addDependencies(refs, node, path, property) {
243
+ // console.log('_addDependencies',path);
248
244
  const nodeHash = `${path}:${property}`;
249
245
  if (refs.length !== 0) {
250
246
  if (!this.model.mainGraph.hasNode(nodeHash)) {
@@ -252,11 +248,15 @@ export class FxBind extends foreElementMixin(HTMLElement) {
252
248
  }
253
249
  refs.forEach(ref => {
254
250
  const otherPath = XPathUtil.getPath(ref);
251
+ // console.log('otherPath', otherPath)
255
252
 
256
- if (!this.model.mainGraph.hasNode(otherPath)) {
257
- this.model.mainGraph.addNode(otherPath, ref);
253
+ // todo: nasty hack to prevent duplicate pathes like 'a[1]' and 'a[1]/text()[1]' to end up as separate nodes in the graph
254
+ if (!otherPath.endsWith('text()[1]')) {
255
+ if (!this.model.mainGraph.hasNode(otherPath)) {
256
+ this.model.mainGraph.addNode(otherPath, ref);
257
+ }
258
+ this.model.mainGraph.addDependency(nodeHash, otherPath);
258
259
  }
259
- this.model.mainGraph.addDependency(nodeHash, otherPath);
260
260
  });
261
261
  } else {
262
262
  this.model.mainGraph.addNode(nodeHash, node);
@@ -321,7 +321,7 @@ export class FxBind extends foreElementMixin(HTMLElement) {
321
321
  * overwrites
322
322
  */
323
323
  _evalInContext() {
324
- const inscopeContext = this.getInScopeContext();
324
+ const inscopeContext = getInScopeContext(this.getAttributeNode('ref') || this, this.ref);
325
325
 
326
326
  // reset nodeset
327
327
  this.nodeset = [];
@@ -335,7 +335,7 @@ export class FxBind extends foreElementMixin(HTMLElement) {
335
335
  } else {
336
336
  // eslint-disable-next-line no-lonely-if
337
337
  if (this.ref) {
338
- const localResult = evaluateXPathToNodes(this.ref, n, this.getOwnerForm());
338
+ const localResult = evaluateXPathToNodes(this.ref, n, this);
339
339
  localResult.forEach(item => {
340
340
  this.nodeset.push(item);
341
341
  });
@@ -351,7 +351,7 @@ export class FxBind extends foreElementMixin(HTMLElement) {
351
351
  } else {
352
352
  const inst = this.getModel().getInstance(this.instanceId);
353
353
  if (inst.type === 'xml') {
354
- this.nodeset = evaluateXPathToNodes(this.ref, inscopeContext, this.getOwnerForm());
354
+ this.nodeset = evaluateXPathToNodes(this.ref, inscopeContext, this);
355
355
  } else {
356
356
  this.nodeset = this.ref;
357
357
  }
@@ -509,13 +509,15 @@ export class FxBind extends foreElementMixin(HTMLElement) {
509
509
  * @param {string} propertyExpr The XPath to get the referenced nodes from
510
510
  *
511
511
  * @return {Node[]} The nodes that are referenced by the XPath
512
+ *
513
+ * todo: DependencyNotifyingDomFacade reports back too much in some cases like 'a[1]' and 'a[1]/text[1]'
512
514
  */
513
515
  _getReferencesForProperty(propertyExpr) {
514
516
  if (propertyExpr) {
515
517
  const touchedNodes = new Set();
516
518
  const domFacade = new DependencyNotifyingDomFacade(otherNode => touchedNodes.add(otherNode));
517
519
  this.nodeset.forEach(node => {
518
- evaluateXPathToString(propertyExpr, node, this.getOwnerForm(), domFacade);
520
+ evaluateXPathToString(propertyExpr, node, this, domFacade);
519
521
  });
520
522
 
521
523
  return Array.from(touchedNodes.values());