@jinntec/fore 2.6.0 → 2.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.
Files changed (53) hide show
  1. package/dist/fore-dev.js +4470 -2643
  2. package/dist/fore.js +4415 -2620
  3. package/index.js +2 -0
  4. package/package.json +10 -4
  5. package/resources/fore.css +2 -6
  6. package/src/DependencyNotifyingDomFacade.js +27 -21
  7. package/src/ForeElementMixin.js +282 -277
  8. package/src/actions/abstract-action.js +7 -12
  9. package/src/actions/fx-append.js +23 -2
  10. package/src/actions/fx-call.js +2 -2
  11. package/src/actions/fx-delete.js +54 -29
  12. package/src/actions/fx-insert.js +23 -15
  13. package/src/actions/fx-refresh.js +15 -5
  14. package/src/actions/fx-replace.js +18 -3
  15. package/src/actions/fx-reset.js +6 -0
  16. package/src/actions/fx-send.js +10 -7
  17. package/src/actions/fx-setattribute.js +12 -0
  18. package/src/actions/fx-setfocus.js +11 -8
  19. package/src/actions/fx-setvalue.js +93 -93
  20. package/src/actions/fx-toggle.js +1 -1
  21. package/src/extract-predicate-deps.js +57 -0
  22. package/src/extractPredicateDependencies.js +36 -0
  23. package/src/fore.js +41 -16
  24. package/src/fx-bind.js +128 -23
  25. package/src/fx-connection.js +24 -7
  26. package/src/fx-fore.js +506 -259
  27. package/src/fx-instance.js +9 -11
  28. package/src/fx-model.js +154 -65
  29. package/src/fx-submission.js +19 -30
  30. package/src/fx-var.js +5 -0
  31. package/src/getInScopeContext.js +7 -8
  32. package/src/modelitem.js +247 -112
  33. package/src/tools/fx-action-log.js +21 -19
  34. package/src/tools/fx-log-settings.js +4 -2
  35. package/src/ui/TemplateExpression.js +12 -0
  36. package/src/ui/UIElement.js +125 -10
  37. package/src/ui/abstract-control.js +5 -0
  38. package/src/ui/fx-case.js +15 -3
  39. package/src/ui/fx-container.js +5 -0
  40. package/src/ui/fx-control-menu.js +23 -14
  41. package/src/ui/fx-control.js +55 -15
  42. package/src/ui/fx-items.js +10 -4
  43. package/src/ui/fx-repeat-attributes.js +111 -35
  44. package/src/ui/fx-repeat.js +332 -85
  45. package/src/ui/fx-repeat.updated.js +821 -0
  46. package/src/ui/fx-repeatitem.js +23 -20
  47. package/src/ui/fx-switch.js +5 -3
  48. package/src/ui/fx-upload.js +36 -40
  49. package/src/ui/repeat-base.js +532 -0
  50. package/src/withDraggability.js +8 -4
  51. package/src/xpath-evaluation.js +26 -8
  52. package/src/xpath-path.js +79 -0
  53. package/src/xpath-util.js +357 -289
@@ -1,12 +1,11 @@
1
1
  import { AbstractAction } from './abstract-action.js';
2
2
  import { Fore } from '../fore.js';
3
3
  import { resolveId } from '../xpath-evaluation.js';
4
+ import { XPathUtil } from '../xpath-util.js';
4
5
 
5
6
  /**
6
7
  * `fx-append` appends an entry to a repeat.
7
8
  *
8
- *
9
- *
10
9
  * @deprecated - will be replaced with `fx-insert`
11
10
  * @fires index-changed - fired after new item is appended
12
11
  * @customElement
@@ -76,6 +75,8 @@ class FxAppend extends AbstractAction {
76
75
 
77
76
  actionPerformed() {
78
77
  super.actionPerformed();
78
+ const mi = this.getModelItem();
79
+ mi.notify();
79
80
  // const repeat = document.getElementById(this.repeat);
80
81
  // repeat.setIndex(repeat.nodeset.length);
81
82
  this._dispatch();
@@ -103,6 +104,9 @@ class FxAppend extends AbstractAction {
103
104
 
104
105
  // const rootNode = document.createElement(repeat.ref);
105
106
  // const rootNode = inscope.ownerDocument.createElement(repeat.ref);
107
+ /**
108
+ * @type {Element}
109
+ */
106
110
  const rootNode = inscope.ownerDocument.createElement(repeat.ref);
107
111
 
108
112
  // const data = this._dataFromRefs(rootNode, templ.content)
@@ -111,6 +115,23 @@ class FxAppend extends AbstractAction {
111
115
  inscope.appendChild(data);
112
116
  parentForm.signalChangeToElement(inscope.localName);
113
117
  parentForm.signalChangeToElement(data.localName);
118
+
119
+ const instanceId = XPathUtil.resolveInstance(this, this.ref);
120
+ const inst = this.getModel().getInstance(instanceId);
121
+
122
+ const fore = this.getOwnerForm();
123
+
124
+ Fore.dispatch(inst, 'insert', {
125
+ insertedNodes: data,
126
+ insertedParent: inscope,
127
+ ref: this.ref,
128
+ location: data.previousSibling,
129
+ position: 'after',
130
+ instanceId: inst.id,
131
+ foreId: fore.id,
132
+ index: Array.from(inscope.children).indexOf(data),
133
+ });
134
+
114
135
  // console.log('appended new item ', data);
115
136
  // return data;
116
137
  }
@@ -3,7 +3,7 @@ import { AbstractAction } from './abstract-action.js';
3
3
  import { evaluateXPath } from '../xpath-evaluation.js';
4
4
  import { Fore } from '../fore.js';
5
5
  import getInScopeContext from '../getInScopeContext.js';
6
- import { XPathUtil } from '../xpath-util.js';
6
+ import { getDocPath } from '../xpath-path.js';
7
7
 
8
8
  /**
9
9
  * `fx-call`
@@ -67,7 +67,7 @@ export default class FxCall extends AbstractAction {
67
67
  Fore.dispatch(this, 'error', {
68
68
  origin: this,
69
69
  message: `Action '${this.action}' not found`,
70
- expr: XPathUtil.getDocPath(this),
70
+ expr: getDocPath(this),
71
71
  level: 'Error',
72
72
  });
73
73
  }
@@ -1,7 +1,6 @@
1
- import * as fx from 'fontoxpath';
2
1
  import { AbstractAction } from './abstract-action.js';
3
2
  import { Fore } from '../fore.js';
4
- import { evaluateXPathToNodes, evaluateXPathToString } from '../xpath-evaluation.js';
3
+ import { evaluateXPathToNodes } from '../xpath-evaluation.js';
5
4
  import { XPathUtil } from '../xpath-util.js';
6
5
  import getInScopeContext from '../getInScopeContext.js';
7
6
 
@@ -55,49 +54,75 @@ class FxDelete extends AbstractAction {
55
54
  const fore = this.getOwnerForm();
56
55
 
57
56
  let parent;
57
+
58
+ const removedNodes = [];
58
59
  if (Array.isArray(nodesToDelete)) {
59
- if (nodesToDelete.length === 0) return;
60
+ if (nodesToDelete.length === 0) {
61
+ return;
62
+ }
60
63
  parent = nodesToDelete[0].parentNode;
61
- fore.signalChangeToElement(parent.localName);
64
+
62
65
  nodesToDelete.forEach(item => {
63
- this._deleteNode(parent, item);
64
- fore.signalChangeToElement(item.localName);
66
+ if (this._deleteNode(parent, item)) {
67
+ fore.signalChangeToElement(item.localName);
68
+ removedNodes.push(item);
69
+ }
65
70
  });
71
+ if (removedNodes.length) {
72
+ fore.signalChangeToElement(parent.localName);
73
+ }
66
74
  } else {
67
75
  parent = nodesToDelete.parentNode;
68
- fore.signalChangeToElement(parent.localName);
76
+ if (this._deleteNode(parent, nodesToDelete)) {
77
+ fore.signalChangeToElement(parent.localName);
69
78
 
70
- this._deleteNode(parent, nodesToDelete);
71
- fore.signalChangeToElement(nodesToDelete.localName);
79
+ fore.signalChangeToElement(nodesToDelete.localName);
80
+ removedNodes.push(nodesToDelete);
81
+ }
72
82
  }
73
83
 
74
- await Fore.dispatch(instance, 'deleted', {
75
- ref: path,
76
- deletedNodes: nodesToDelete,
77
- instanceId,
78
- foreId: fore.id,
79
- });
80
- this.needsUpdate = true;
84
+ if (removedNodes.length) {
85
+ await Fore.dispatch(instance, 'deleted', {
86
+ ref: path,
87
+ deletedNodes: removedNodes,
88
+ instanceId,
89
+ parent,
90
+ foreId: fore.id,
91
+ });
92
+ this.needsUpdate = true;
93
+ }
81
94
  }
82
95
 
96
+ /**
97
+ * Delete a node (if allowed). Does not hold for JSON
98
+ *
99
+ * @param {ParentNode} parent - The parent of the node to remove
100
+ * @param {ChildNode} node - The child to remove
101
+ *
102
+ * @returns {boolean} Whether the delete is allowed and succeeded
103
+ */
83
104
  _deleteNode(parent, node) {
84
- if (parent.nodeType === Node.DOCUMENT_NODE) return;
85
- if (node.nodeType === Node.DOCUMENT_NODE) return;
86
- if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) return;
87
- if (node.parentNode === null) return;
105
+ if (
106
+ parent.nodeType === Node.DOCUMENT_NODE ||
107
+ node.nodeType === Node.DOCUMENT_NODE ||
108
+ node.nodeType === Node.DOCUMENT_FRAGMENT_NODE ||
109
+ node.parentNode === null
110
+ ) {
111
+ return false;
112
+ }
88
113
 
89
- const mi = this.getModelItem();
90
- if (mi.readonly) return;
114
+ const mi = this.getModel().getModelItem(node);
115
+ // Note that the model item can be absent, For elements that had no controls on them.
116
+ // In that case, allow removals
117
+ if (mi?.readonly) {
118
+ return false;
119
+ }
91
120
 
92
121
  parent.removeChild(node);
93
- }
94
122
 
95
- /**
96
- * overwriting as we need to perform additional rebuild()
97
- */
98
- actionPerformed() {
99
- this.getModel().rebuild();
100
- super.actionPerformed();
123
+ this.getModel().removeModelItem(node);
124
+
125
+ return true;
101
126
  }
102
127
  }
103
128
 
@@ -7,6 +7,7 @@ import {
7
7
  } from '../xpath-evaluation.js';
8
8
  import { XPathUtil } from '../xpath-util';
9
9
  import { Fore } from '../fore.js';
10
+ import { getPath } from '../xpath-path.js';
10
11
 
11
12
  /**
12
13
  * `fx-insert`
@@ -60,7 +61,6 @@ export class FxInsert extends AbstractAction {
60
61
  this.keepValues = !!this.hasAttribute('keep-values');
61
62
  }
62
63
 
63
-
64
64
  _cloneOriginSequence(inscope, targetSequence) {
65
65
  let originSequenceClone;
66
66
  if (this.origin) {
@@ -76,13 +76,13 @@ export class FxInsert extends AbstractAction {
76
76
  if in 'create-nodes' mode and origin targets a repeat, the repeat
77
77
  we use the already during initData() created nodeset as a template for insertion
78
78
  */
79
- if(this.origin.startsWith('#') && this.getOwnerForm().createNodes){
79
+ if (this.origin.startsWith('#') && this.getOwnerForm().createNodes) {
80
80
  const repeat = this.getOwnerForm().querySelector(this.origin);
81
81
  originSequenceClone = repeat.createdNodeset.cloneNode(true);
82
- if(!originSequenceClone){
82
+ if (!originSequenceClone) {
83
83
  console.error(`createdNodeset for repeat ${this.origin} does not exist`);
84
84
  }
85
- }else{
85
+ } else {
86
86
  // originTarget = evaluateXPathToFirstNode(this.origin, inscope, this);
87
87
  originTarget = evaluateXPathToFirstNode(this.origin, inscope, this);
88
88
  if (Array.isArray(originTarget) && originTarget.length === 0) {
@@ -128,7 +128,7 @@ export class FxInsert extends AbstractAction {
128
128
 
129
129
  // ### 'context' attribute takes precedence over 'ref'
130
130
  if (this.hasAttribute('context')) {
131
- [context] = evaluateXPathToNodes(this.getAttribute('context'), inscopeContext, fore);
131
+ [context] = evaluateXPathToNodes(this.getAttribute('context'), inscopeContext, this);
132
132
  inscope = inscopeContext;
133
133
  }
134
134
 
@@ -145,7 +145,13 @@ export class FxInsert extends AbstractAction {
145
145
  const originSequenceClone = this._cloneOriginSequence(inscope, targetSequence);
146
146
  if (!originSequenceClone) return; // if no origin back out without effect
147
147
 
148
+ /**
149
+ * @type {Node}
150
+ */
148
151
  let insertLocationNode;
152
+ /**
153
+ * @type {number}
154
+ */
149
155
  let index;
150
156
 
151
157
  // if the targetSequence is empty but we got an originSequence use inscope as context and ignore 'at' and 'position'
@@ -157,20 +163,18 @@ export class FxInsert extends AbstractAction {
157
163
  fore.signalChangeToElement(originSequenceClone.localName);
158
164
  index = 1;
159
165
  } else {
160
-
161
166
  // No context but creating nodes from UI
162
- if(!inscope && this.getOwnerForm().createNodes){
167
+ if (!inscope && this.getOwnerForm().createNodes) {
163
168
  const repeat = this.getOwnerForm().querySelector(this.origin);
164
169
  inscope = getInScopeContext(repeat, repeat.ref);
165
170
  insertLocationNode = inscope;
166
171
  inscope.appendChild(originSequenceClone);
167
172
  index = inscope.length - 1;
168
- }else{
173
+ } else {
169
174
  insertLocationNode = inscope;
170
175
  inscope.appendChild(originSequenceClone);
171
176
  index = 1;
172
177
  }
173
-
174
178
  }
175
179
  } else {
176
180
  /* ### insert at position given by 'at' or use the last item in the targetSequence ### */
@@ -216,6 +220,8 @@ export class FxInsert extends AbstractAction {
216
220
  if (this.hasAttribute('context') && this.hasAttribute('ref')) {
217
221
  // index=1;
218
222
  inscope.append(originSequenceClone);
223
+ fore.signalChangeToElement(insertLocationNode);
224
+ fore.signalChangeToElement(originSequenceClone.localName);
219
225
  } else if (this.hasAttribute('context')) {
220
226
  index = 1;
221
227
  insertLocationNode.prepend(originSequenceClone);
@@ -241,7 +247,7 @@ export class FxInsert extends AbstractAction {
241
247
  // console.log('<<<<<<< resolved instance', inst);
242
248
  // Note: the parent to insert under is always the parent of the inserted node. The 'context' is not always the parent if the sequence is empty, or the position is different
243
249
  // const xpath = XPathUtil.getPath(originSequenceClone.parentNode, instanceId);
244
- const xpath = XPathUtil.getPath(insertLocationNode.parentNode, instanceId);
250
+ const xpath = getPath(insertLocationNode, instanceId);
245
251
 
246
252
  const path = Fore.getDomNodeIndexString(originSequenceClone);
247
253
  this.dispatchEvent(
@@ -252,13 +258,16 @@ export class FxInsert extends AbstractAction {
252
258
  detail: { action: this, event: this.event, path },
253
259
  }),
254
260
  );
255
-
256
261
  Fore.dispatch(inst, 'insert', {
257
- 'inserted-nodes': originSequenceClone,
258
- 'insert-location-node': insertLocationNode,
262
+ insertedNodes: originSequenceClone,
263
+ insertedParent: insertLocationNode.parentNode,
264
+ ref: this.ref,
265
+ location: insertLocationNode,
259
266
  position: this.position,
260
267
  instanceId,
261
268
  foreId: fore.id,
269
+ index,
270
+ xpath,
262
271
  });
263
272
 
264
273
  // todo: this actually should dispatch to respective instance
@@ -275,7 +284,6 @@ export class FxInsert extends AbstractAction {
275
284
  );
276
285
 
277
286
  this.needsUpdate = true;
278
- console.log('Changed!', xpath);
279
287
  return [xpath];
280
288
  }
281
289
 
@@ -292,7 +300,7 @@ export class FxInsert extends AbstractAction {
292
300
 
293
301
  actionPerformed(changedPaths) {
294
302
  // ### make sure the necessary modelItems will get created
295
- this.getModel().rebuild();
303
+ // this.getModel().rebuild();
296
304
  super.actionPerformed();
297
305
  }
298
306
 
@@ -22,23 +22,33 @@ class FxRefresh extends AbstractAction {
22
22
 
23
23
  if (this.hasAttribute('self')) {
24
24
  console.log(`### <<<<< refresh() self ${this} >>>>>`);
25
- const control = XPathUtil.getClosest('fx-control', this);
25
+ const control = XPathUtil.getClosest('fx-control, fx-output, fx-upload', this);
26
26
  if (control) {
27
- control.refresh();
27
+ control.refresh(true);
28
28
  return;
29
29
  }
30
30
  }
31
31
  if (this.hasAttribute('force')) {
32
32
  console.log(`### <<<<< refresh() force ${this} >>>>>`);
33
- this.getOwnerForm().forceRefresh();
33
+ this.getOwnerForm().refresh(true);
34
+ return;
35
+ }
36
+ if(this.hasAttribute('selector')){
37
+ const target = document.querySelector(this.getAttribute('selector'));
38
+ if (target && Fore.isUiElement(target.nodeName) && typeof target.refresh === 'function') {
39
+ target.refresh(true);
40
+ }
34
41
  return;
35
42
  }
36
43
  if (this.hasAttribute('control')) {
37
44
  const targetId = this.getAttribute('control');
38
45
  console.log(`### <<<<< refresh() control '${targetId}' >>>>>`);
39
- const ctrl = resolveId(targetId, this);
46
+ let ctrl = resolveId(targetId, this);
47
+ if(!ctrl){
48
+ ctrl = document.querySelector(`#${targetId}`);
49
+ }
40
50
  if (ctrl && Fore.isUiElement(ctrl.nodeName) && typeof ctrl.refresh === 'function') {
41
- ctrl.refresh();
51
+ ctrl.refresh(true);
42
52
  }
43
53
  return;
44
54
  }
@@ -2,6 +2,7 @@
2
2
  import '../fx-model.js';
3
3
  import { AbstractAction } from './abstract-action.js';
4
4
  import { evaluateXPathToFirstNode } from '../xpath-evaluation.js';
5
+ import { FxBind } from '../fx-bind.js';
5
6
 
6
7
  /**
7
8
  * `fx-replace` - replaces the node referred to with 'ref' with node referred to with 'with' attribute.
@@ -44,8 +45,9 @@ export default class FxReplace extends AbstractAction {
44
45
  }
45
46
 
46
47
  actionPerformed() {
47
- this.getModel().rebuild();
48
- super.actionPerformed();
48
+ this.getModel().updateModel();
49
+ this.getOwnerForm().refresh(true); //todo: optimize and update only the affected subtree
50
+ this.dispatchActionPerformed();
49
51
  }
50
52
 
51
53
  replace(toReplace, replaceWith) {
@@ -63,7 +65,20 @@ export default class FxReplace extends AbstractAction {
63
65
  const cloned = replaceWith.cloneNode(true);
64
66
  toReplace.replaceWith(cloned);
65
67
  }
66
- // const modelitem = this.getModelItem();
68
+ // todo: add selective update and create and notify modelItem for toReplace and replaceWith
69
+ /*
70
+ let replaceWithModelItem = this.getModel().getModelItem(replaceWith);
71
+ if (!replaceWithModelItem) {
72
+ const replaceWithModelItem = FxBind.createModelItem(
73
+ this.getAttribute('with'),
74
+ replaceWith,
75
+ this,
76
+ null,
77
+ );
78
+ this.getModel().registerModelItem(replaceWithModelItem);
79
+ this.getOwnerForm().addToBatchedNotifications(replaceWithModelItem);
80
+ }
81
+ */
67
82
  // this.getModel().changed.push(modelitem);
68
83
  this.needsUpdate = true;
69
84
  }
@@ -41,6 +41,12 @@ export class FxReset extends AbstractAction {
41
41
  data.reset();
42
42
  this.needsUpdate = true;
43
43
  }
44
+
45
+ actionPerformed() {
46
+ this.getModel().updateModel();
47
+ this.getOwnerForm().refresh(true);
48
+ this.dispatchActionPerformed();
49
+ }
44
50
  }
45
51
 
46
52
  if (!customElements.get('fx-reset')) {
@@ -1,7 +1,7 @@
1
1
  import '../fx-model.js';
2
2
  import '../fx-submission.js';
3
3
  import { AbstractAction } from './abstract-action.js';
4
- import { XPathUtil } from '../xpath-util.js';
4
+ import { getDocPath } from '../xpath-path.js';
5
5
 
6
6
  /**
7
7
  * `fx-send` - finds and activates a `fx-submission` or a `fx-connection` element.
@@ -44,7 +44,7 @@ class FxSend extends AbstractAction {
44
44
  id: this.id,
45
45
  origin: this,
46
46
  message: `<fx-connection id="${this.connection}"> not found`,
47
- expr: XPathUtil.getDocPath(this),
47
+ expr: getDocPath(this),
48
48
  level: 'Error',
49
49
  },
50
50
  }),
@@ -66,7 +66,7 @@ class FxSend extends AbstractAction {
66
66
  id: this.id,
67
67
  origin: this,
68
68
  message: `<fx-submission id="${this.submission}"> not found`,
69
- expr: XPathUtil.getDocPath(this),
69
+ expr: getDocPath(this),
70
70
  level: 'Error',
71
71
  },
72
72
  }),
@@ -87,10 +87,13 @@ class FxSend extends AbstractAction {
87
87
  }
88
88
 
89
89
  await submission.submit();
90
- if(submission.replace === 'instance'){
91
- this.getModel().updateModel();
92
- this.getOwnerForm().refresh();
93
- }
90
+ if (submission.replace === 'instance') {
91
+ this.getModel().updateModel();
92
+ // todo: this bypasses observers...
93
+ this.getOwnerForm().refresh(true); //whole instance changes - full refresh necessary
94
+ // this.getOwnerForm().addToBatchedNotifications(this.getOwnerForm());
95
+ // this.needsUpdate = true;
96
+ }
94
97
  // if not of type fx-submission signal error
95
98
  }
96
99
 
@@ -4,6 +4,7 @@ import { AbstractAction } from './abstract-action.js';
4
4
  import { evaluateXPathToString } from '../xpath-evaluation.js';
5
5
  import { Fore } from '../fore.js';
6
6
  import getInScopeContext from '../getInScopeContext';
7
+ import { FxBind } from '../fx-bind';
7
8
 
8
9
  /**
9
10
  * `fx-setattribute` allows to create and set an attribute value in the data.
@@ -58,7 +59,18 @@ export default class FxSetattribute extends AbstractAction {
58
59
  return;
59
60
  }
60
61
  mi.node.setAttribute(this.attrName, this.attrValue);
62
+ const newModelItem = FxBind.createModelItem(
63
+ `${this.ref}/@${this.attrName}`,
64
+ mi.node.getAttributeNode(this.attrName),
65
+ this,
66
+ null,
67
+ );
68
+ this.getOwnerForm()
69
+ .getModel()
70
+ .registerModelItem(newModelItem);
71
+ this.getOwnerForm().addToBatchedNotifications(newModelItem);
61
72
  this.needsUpdate = true;
73
+ newModelItem.notify();
62
74
  }
63
75
  }
64
76
 
@@ -39,14 +39,6 @@ export class FxSetfocus extends AbstractAction {
39
39
  return;
40
40
  }
41
41
 
42
- // ### focus action is itself hosted within a repeat
43
- const parentIItem = targetElement.closest('fx-repeatitem');
44
- if (parentIItem) {
45
- targetElement = parentIItem.querySelector(selector);
46
- this._focus(targetElement);
47
- // return;
48
- }
49
-
50
42
  // ### the target element is hosted within a repeat
51
43
  const repeatitem = targetElement.closest('fx-repeatitem, .fx-repeatitem');
52
44
  if (repeatitem) {
@@ -54,7 +46,18 @@ export class FxSetfocus extends AbstractAction {
54
46
  // get the active repeatitem (only for fx-repeat for now - todo: support repeat attributes
55
47
  const repeat = repeatitem.parentNode;
56
48
  targetElement = repeat.querySelector(`[repeat-index] ${selector}`);
49
+ this._focus(targetElement);
50
+ }
51
+
52
+ // ### focus action is itself hosted within a repeat
53
+ /*
54
+ const parentIItem = targetElement.closest('fx-repeatitem');
55
+ if (parentIItem) {
56
+ targetElement = parentIItem.querySelector(selector);
57
+ this._focus(targetElement);
58
+ // return;
57
59
  }
60
+ */
58
61
 
59
62
  this._focus(targetElement);
60
63
  if (this.hasAttribute('select')) {