@jinntec/fore 1.10.0 → 1.10.1
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/dist/fore-dev.js +2 -2
- package/dist/fore-dev.js.map +1 -1
- package/dist/fore.js +2 -2
- package/dist/fore.js.map +1 -1
- package/package.json +1 -1
- package/resources/fore.css +2 -41
- package/src/actions/abstract-action.js +51 -62
- package/src/actions/fx-call.js +9 -0
- package/src/actions/fx-delete.js +1 -1
- package/src/actions/fx-insert.js +8 -4
- package/src/actions/fx-load.js +5 -2
- package/src/actions/fx-reload.js +1 -1
- package/src/actions/fx-send.js +8 -3
- package/src/actions/fx-setfocus.js +6 -1
- package/src/fore.js +3 -0
- package/src/fx-bind.js +1 -1
- package/src/fx-fore.js +74 -68
- package/src/fx-model.js +19 -6
- package/src/fx-submission.js +5 -0
- package/src/tools/fx-action-log.js +1 -1
- package/src/ui/abstract-control.js +18 -39
- package/src/ui/fx-control.js +12 -12
- package/src/ui/fx-repeat-attributes.js +2 -2
- package/src/ui/fx-repeat.js +12 -1
- package/src/ui/fx-repeatitem.js +2 -8
- package/src/ui/fx-trigger.js +3 -13
- package/src/xpath-evaluation.js +223 -69
- package/src/xpath-util.js +138 -130
package/src/xpath-evaluation.js
CHANGED
|
@@ -418,6 +418,7 @@ function getVariablesInScope(formElement) {
|
|
|
418
418
|
* @param {Node} contextNode The start of the XPath
|
|
419
419
|
* @param {{parentNode}|ForeElementMixin} formElement The form element associated to the XPath
|
|
420
420
|
*/
|
|
421
|
+
/*
|
|
421
422
|
export function evaluateXPath(xpath, contextNode, formElement, variables = {}, options={}, domFacade = null) {
|
|
422
423
|
const namespaceResolver = createNamespaceResolverForNode(xpath, contextNode, formElement);
|
|
423
424
|
const variablesInScope = getVariablesInScope(formElement);
|
|
@@ -440,7 +441,59 @@ export function evaluateXPath(xpath, contextNode, formElement, variables = {}, o
|
|
|
440
441
|
},
|
|
441
442
|
);
|
|
442
443
|
}
|
|
444
|
+
*/
|
|
445
|
+
export function evaluateXPath(xpath, contextNode, formElement, variables = {}, options={}) {
|
|
446
|
+
try{
|
|
447
|
+
console.log('evaluateXPath',xpath);
|
|
448
|
+
const namespaceResolver = createNamespaceResolverForNode(xpath, contextNode, formElement);
|
|
449
|
+
const variablesInScope = getVariablesInScope(formElement);
|
|
450
|
+
|
|
451
|
+
return fxEvaluateXPath(
|
|
452
|
+
xpath,
|
|
453
|
+
contextNode,
|
|
454
|
+
null,
|
|
455
|
+
{...variablesInScope, ...variables},
|
|
456
|
+
fxEvaluateXPath.ALL_RESULTS_TYPE,
|
|
457
|
+
{
|
|
458
|
+
debug: true,
|
|
459
|
+
currentContext: {formElement, variables},
|
|
460
|
+
moduleImports: {
|
|
461
|
+
xf: XFORMS_NAMESPACE_URI,
|
|
462
|
+
},
|
|
463
|
+
functionNameResolver,
|
|
464
|
+
namespaceResolver,
|
|
465
|
+
language: options.language || evaluateXPath.XPATH_3_1
|
|
466
|
+
},
|
|
467
|
+
);
|
|
468
|
+
}catch (e){
|
|
469
|
+
formElement.dispatchEvent(new CustomEvent('error', {
|
|
470
|
+
composed: false,
|
|
471
|
+
bubbles: true,
|
|
472
|
+
detail: {
|
|
473
|
+
origin: formElement,
|
|
474
|
+
message: `Expression '${xpath}' failed`,
|
|
475
|
+
expr:xpath,
|
|
476
|
+
level:'Error'
|
|
477
|
+
},
|
|
478
|
+
}));
|
|
443
479
|
|
|
480
|
+
/*
|
|
481
|
+
formElement.dispatchEvent(
|
|
482
|
+
new CustomEvent('error', {
|
|
483
|
+
composed: false,
|
|
484
|
+
bubbles: true,
|
|
485
|
+
cancelable:true,
|
|
486
|
+
detail: {
|
|
487
|
+
origin: formElement,
|
|
488
|
+
message: `Expression '${xpath}' failed`,
|
|
489
|
+
expr:xpath,
|
|
490
|
+
level:'Error'},
|
|
491
|
+
}),
|
|
492
|
+
);
|
|
493
|
+
*/
|
|
494
|
+
return false;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
444
497
|
/**
|
|
445
498
|
* Evaluate an XPath to the first Node
|
|
446
499
|
*
|
|
@@ -450,17 +503,30 @@ export function evaluateXPath(xpath, contextNode, formElement, variables = {}, o
|
|
|
450
503
|
* @return {Node} The first node found by the XPath
|
|
451
504
|
*/
|
|
452
505
|
export function evaluateXPathToFirstNode(xpath, contextNode, formElement) {
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
506
|
+
try{
|
|
507
|
+
const namespaceResolver = createNamespaceResolverForNode(xpath, contextNode, formElement);
|
|
508
|
+
const variablesInScope = getVariablesInScope(formElement);
|
|
509
|
+
return fxEvaluateXPathToFirstNode(xpath, contextNode, null, variablesInScope, {
|
|
510
|
+
defaultFunctionNamespaceURI: XFORMS_NAMESPACE_URI,
|
|
511
|
+
moduleImports: {
|
|
512
|
+
xf: XFORMS_NAMESPACE_URI,
|
|
513
|
+
},
|
|
514
|
+
currentContext: {formElement},
|
|
515
|
+
functionNameResolver,
|
|
516
|
+
namespaceResolver,
|
|
517
|
+
});
|
|
518
|
+
} catch (e){
|
|
519
|
+
formElement.dispatchEvent(new CustomEvent('error', {
|
|
520
|
+
composed: false,
|
|
521
|
+
bubbles: true,
|
|
522
|
+
detail: {
|
|
523
|
+
origin: formElement,
|
|
524
|
+
message: `Expression '${xpath}' failed`,
|
|
525
|
+
expr:xpath,
|
|
526
|
+
level:'Error'
|
|
527
|
+
},
|
|
528
|
+
}));
|
|
529
|
+
}
|
|
464
530
|
}
|
|
465
531
|
|
|
466
532
|
/**
|
|
@@ -472,17 +538,30 @@ export function evaluateXPathToFirstNode(xpath, contextNode, formElement) {
|
|
|
472
538
|
* @return {Node[]} All nodes
|
|
473
539
|
*/
|
|
474
540
|
export function evaluateXPathToNodes(xpath, contextNode, formElement) {
|
|
475
|
-
|
|
476
|
-
|
|
541
|
+
try{
|
|
542
|
+
const namespaceResolver = createNamespaceResolverForNode(xpath, contextNode, formElement);
|
|
543
|
+
const variablesInScope = getVariablesInScope(formElement);
|
|
477
544
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
545
|
+
return fxEvaluateXPathToNodes(xpath, contextNode, null, variablesInScope, {
|
|
546
|
+
currentContext: {formElement},
|
|
547
|
+
functionNameResolver,
|
|
548
|
+
moduleImports: {
|
|
549
|
+
xf: XFORMS_NAMESPACE_URI,
|
|
550
|
+
},
|
|
551
|
+
namespaceResolver,
|
|
552
|
+
});
|
|
553
|
+
}catch (e){
|
|
554
|
+
formElement.dispatchEvent(new CustomEvent('error', {
|
|
555
|
+
composed: false,
|
|
556
|
+
bubbles: true,
|
|
557
|
+
detail: {
|
|
558
|
+
origin: formElement,
|
|
559
|
+
message: `Expression '${xpath}' failed`,
|
|
560
|
+
expr:xpath,
|
|
561
|
+
level:'Error'
|
|
562
|
+
},
|
|
563
|
+
}));
|
|
564
|
+
}
|
|
486
565
|
}
|
|
487
566
|
|
|
488
567
|
/**
|
|
@@ -494,17 +573,30 @@ export function evaluateXPathToNodes(xpath, contextNode, formElement) {
|
|
|
494
573
|
* @return {boolean}
|
|
495
574
|
*/
|
|
496
575
|
export function evaluateXPathToBoolean(xpath, contextNode, formElement) {
|
|
497
|
-
|
|
498
|
-
|
|
576
|
+
try{
|
|
577
|
+
const namespaceResolver = createNamespaceResolverForNode(xpath, contextNode, formElement);
|
|
578
|
+
const variablesInScope = getVariablesInScope(formElement);
|
|
499
579
|
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
580
|
+
return fxEvaluateXPathToBoolean(xpath, contextNode, null, variablesInScope, {
|
|
581
|
+
currentContext: {formElement},
|
|
582
|
+
functionNameResolver,
|
|
583
|
+
moduleImports: {
|
|
584
|
+
xf: XFORMS_NAMESPACE_URI,
|
|
585
|
+
},
|
|
586
|
+
namespaceResolver,
|
|
587
|
+
});
|
|
588
|
+
}catch (e){
|
|
589
|
+
formElement.dispatchEvent(new CustomEvent('error', {
|
|
590
|
+
composed: false,
|
|
591
|
+
bubbles: true,
|
|
592
|
+
detail: {
|
|
593
|
+
origin: formElement,
|
|
594
|
+
message: `Expression '${xpath}' failed`,
|
|
595
|
+
expr:xpath,
|
|
596
|
+
level:'Error'
|
|
597
|
+
},
|
|
598
|
+
}));
|
|
599
|
+
}
|
|
508
600
|
}
|
|
509
601
|
|
|
510
602
|
/**
|
|
@@ -525,17 +617,30 @@ export function evaluateXPathToString(
|
|
|
525
617
|
domFacade = null,
|
|
526
618
|
namespaceReferenceNode = formElement,
|
|
527
619
|
) {
|
|
528
|
-
|
|
529
|
-
|
|
620
|
+
try{
|
|
621
|
+
const namespaceResolver = createNamespaceResolverForNode(xpath, contextNode, formElement);
|
|
622
|
+
const variablesInScope = getVariablesInScope(formElement);
|
|
530
623
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
624
|
+
return fxEvaluateXPathToString(xpath, contextNode, domFacade, variablesInScope, {
|
|
625
|
+
currentContext: {formElement},
|
|
626
|
+
functionNameResolver,
|
|
627
|
+
moduleImports: {
|
|
628
|
+
xf: XFORMS_NAMESPACE_URI,
|
|
629
|
+
},
|
|
630
|
+
namespaceResolver,
|
|
631
|
+
});
|
|
632
|
+
}catch (e) {
|
|
633
|
+
formElement.dispatchEvent(new CustomEvent('error', {
|
|
634
|
+
composed: false,
|
|
635
|
+
bubbles: true,
|
|
636
|
+
detail: {
|
|
637
|
+
origin: formElement,
|
|
638
|
+
message: `Expression '${xpath}' failed`,
|
|
639
|
+
expr:xpath,
|
|
640
|
+
level:'Error'
|
|
641
|
+
},
|
|
642
|
+
}));
|
|
643
|
+
}
|
|
539
644
|
}
|
|
540
645
|
|
|
541
646
|
/**
|
|
@@ -556,22 +661,31 @@ export function evaluateXPathToStrings(
|
|
|
556
661
|
domFacade = null,
|
|
557
662
|
namespaceReferenceNode = formElement,
|
|
558
663
|
) {
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
xpath,
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
xf: XFORMS_NAMESPACE_URI,
|
|
664
|
+
try{
|
|
665
|
+
const namespaceResolver = createNamespaceResolverForNode(xpath, contextNode, formElement);
|
|
666
|
+
return fxEvaluateXPathToStrings( xpath, contextNode, domFacade,
|
|
667
|
+
{},
|
|
668
|
+
{
|
|
669
|
+
currentContext: {formElement},
|
|
670
|
+
functionNameResolver,
|
|
671
|
+
moduleImports: {
|
|
672
|
+
xf: XFORMS_NAMESPACE_URI,
|
|
673
|
+
},
|
|
674
|
+
namespaceResolver,
|
|
571
675
|
},
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
676
|
+
);
|
|
677
|
+
} catch (e){
|
|
678
|
+
formElement.dispatchEvent(new CustomEvent('error', {
|
|
679
|
+
composed: false,
|
|
680
|
+
bubbles: true,
|
|
681
|
+
detail: {
|
|
682
|
+
origin: formElement,
|
|
683
|
+
message: `Expression '${xpath}' failed`,
|
|
684
|
+
expr:xpath,
|
|
685
|
+
level:'Error'
|
|
686
|
+
},
|
|
687
|
+
}));
|
|
688
|
+
}
|
|
575
689
|
}
|
|
576
690
|
|
|
577
691
|
/**
|
|
@@ -592,17 +706,30 @@ export function evaluateXPathToNumber(
|
|
|
592
706
|
domFacade = null,
|
|
593
707
|
namespaceReferenceNode = formElement,
|
|
594
708
|
) {
|
|
595
|
-
|
|
596
|
-
|
|
709
|
+
try{
|
|
710
|
+
const namespaceResolver = createNamespaceResolverForNode(xpath, contextNode, formElement);
|
|
711
|
+
const variablesInScope = getVariablesInScope(formElement);
|
|
597
712
|
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
713
|
+
return fxEvaluateXPathToNumber(xpath, contextNode, domFacade, variablesInScope, {
|
|
714
|
+
currentContext: {formElement},
|
|
715
|
+
functionNameResolver,
|
|
716
|
+
moduleImports: {
|
|
717
|
+
xf: XFORMS_NAMESPACE_URI,
|
|
718
|
+
},
|
|
719
|
+
namespaceResolver,
|
|
720
|
+
});
|
|
721
|
+
}catch (e) {
|
|
722
|
+
formElement.dispatchEvent(new CustomEvent('error', {
|
|
723
|
+
composed: false,
|
|
724
|
+
bubbles: true,
|
|
725
|
+
detail: {
|
|
726
|
+
origin: formElement,
|
|
727
|
+
message: `Expression '${xpath}' failed`,
|
|
728
|
+
expr:xpath,
|
|
729
|
+
level:'Error'
|
|
730
|
+
},
|
|
731
|
+
}));
|
|
732
|
+
}
|
|
606
733
|
}
|
|
607
734
|
|
|
608
735
|
const contextFunction = (dynamicContext, string) => {
|
|
@@ -844,18 +971,44 @@ const instance = (dynamicContext, string) => {
|
|
|
844
971
|
{namespaceResolver: xhtmlNamespaceResolver},
|
|
845
972
|
);
|
|
846
973
|
|
|
974
|
+
let lookup = null;
|
|
975
|
+
if(string === null || string === 'default'){
|
|
976
|
+
lookup = formElement.getModel().getDefaultInstance();
|
|
977
|
+
}else{
|
|
978
|
+
lookup = formElement.getModel().getInstance(string);
|
|
979
|
+
if(!lookup){
|
|
980
|
+
document.querySelector('fx-fore').dispatchEvent(new CustomEvent('error', {
|
|
981
|
+
composed: true,
|
|
982
|
+
bubbles: true,
|
|
983
|
+
detail: {
|
|
984
|
+
origin: 'functions',
|
|
985
|
+
message: `Function not found '${localName}'`,
|
|
986
|
+
level:'Error'
|
|
987
|
+
},
|
|
988
|
+
}));
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
const context = lookup.getDefaultContext();
|
|
993
|
+
if (!context) {
|
|
994
|
+
debugger;
|
|
995
|
+
return null;
|
|
996
|
+
}
|
|
997
|
+
return context;
|
|
998
|
+
|
|
999
|
+
/*
|
|
847
1000
|
const inst = string
|
|
848
1001
|
? formElement.getModel().getInstance(string)
|
|
849
1002
|
: formElement.getModel().getDefaultInstance();
|
|
1003
|
+
*/
|
|
850
1004
|
|
|
851
1005
|
/*
|
|
852
1006
|
const inst = string
|
|
853
1007
|
? resolveId(string, formElement, 'fx-instance')
|
|
854
1008
|
: formElement.querySelector(`fx-instance`);
|
|
855
|
-
*/
|
|
856
1009
|
|
|
857
|
-
if (
|
|
858
|
-
const context =
|
|
1010
|
+
if (lookup) {
|
|
1011
|
+
const context = lookup.getDefaultContext();
|
|
859
1012
|
if (!context) {
|
|
860
1013
|
debugger;
|
|
861
1014
|
return null;
|
|
@@ -863,6 +1016,7 @@ const instance = (dynamicContext, string) => {
|
|
|
863
1016
|
return context;
|
|
864
1017
|
}
|
|
865
1018
|
return null;
|
|
1019
|
+
*/
|
|
866
1020
|
};
|
|
867
1021
|
|
|
868
1022
|
registerCustomXPathFunction(
|
package/src/xpath-util.js
CHANGED
|
@@ -2,151 +2,159 @@ import * as fx from 'fontoxpath';
|
|
|
2
2
|
|
|
3
3
|
export class XPathUtil {
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Alternative to `contains` that respects shadowroots
|
|
7
|
+
*/
|
|
8
|
+
static contains(ancestor, descendant) {
|
|
9
|
+
while (descendant) {
|
|
10
|
+
if (descendant === ancestor) {
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Alternative to `closest` that respects subcontrol boundaries
|
|
26
|
-
*/
|
|
27
|
-
static getClosest(querySelector, start) {
|
|
28
|
-
while (start && !start.matches || !start.matches(querySelector)) {
|
|
29
|
-
if (start.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
|
|
30
|
-
// We are passing a shadow root boundary
|
|
31
|
-
start = start.host;
|
|
32
|
-
continue;
|
|
33
|
-
}
|
|
34
|
-
if (start.nodeType === Node.ATTRIBUTE_NODE) {
|
|
35
|
-
// We are passing an attribute
|
|
36
|
-
start = start.ownerElement;
|
|
37
|
-
continue;
|
|
38
|
-
}
|
|
39
|
-
if (start.nodeType === Node.TEXT_NODE) {
|
|
40
|
-
start = start.parentNode;
|
|
41
|
-
}
|
|
42
|
-
if (start.matches('fx-fore')) {
|
|
43
|
-
// Subform reached. Bail out
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
start = start.parentNode;
|
|
47
|
-
if (!start) {
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
14
|
+
if (descendant.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
|
|
15
|
+
// We are passing a shadow root boundary
|
|
16
|
+
descendant = descendant.host;
|
|
17
|
+
} else {
|
|
18
|
+
descendant = descendant.parentNode;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return false;
|
|
50
22
|
}
|
|
51
|
-
return start;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* returns next bound element upwards in tree
|
|
56
|
-
* @param start where to start the search
|
|
57
|
-
* @returns {*|null}
|
|
58
|
-
*/
|
|
59
|
-
static getParentBindingElement(start) {
|
|
60
|
-
/* if (start.parentNode.host) {
|
|
61
|
-
const { host } = start.parentNode;
|
|
62
|
-
if (host.hasAttribute('ref')) {
|
|
63
|
-
return host;
|
|
64
|
-
}
|
|
65
|
-
} else */
|
|
66
|
-
if (start.parentNode &&
|
|
67
|
-
(start.parentNode.nodeType !== Node.DOCUMENT_NODE || start.parentNode.nodeType !== Node.DOCUMENT_FRAGMENT_NODE) ) {
|
|
68
|
-
/*
|
|
69
|
-
if (start.parentNode.hasAttribute('ref')) {
|
|
70
|
-
return start.parentNode;
|
|
71
|
-
}
|
|
72
|
-
return XPathUtil.getParentBindingElement(start.parentNode);
|
|
73
|
-
*/
|
|
74
23
|
|
|
75
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Alternative to `closest` that respects subcontrol boundaries
|
|
26
|
+
*/
|
|
27
|
+
static getClosest(querySelector, start) {
|
|
28
|
+
while (start && !start.matches || !start.matches(querySelector)) {
|
|
29
|
+
if (start.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
|
|
30
|
+
// We are passing a shadow root boundary
|
|
31
|
+
start = start.host;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (start.nodeType === Node.ATTRIBUTE_NODE) {
|
|
35
|
+
// We are passing an attribute
|
|
36
|
+
start = start.ownerElement;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (start.nodeType === Node.TEXT_NODE) {
|
|
40
|
+
start = start.parentNode;
|
|
41
|
+
}
|
|
42
|
+
if (start.matches('fx-fore')) {
|
|
43
|
+
// Subform reached. Bail out
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
start = start.parentNode;
|
|
47
|
+
if (!start) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return start;
|
|
76
52
|
}
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
53
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
54
|
+
/**
|
|
55
|
+
* returns next bound element upwards in tree
|
|
56
|
+
* @param start where to start the search
|
|
57
|
+
* @returns {*|null}
|
|
58
|
+
*/
|
|
59
|
+
static getParentBindingElement(start) {
|
|
60
|
+
/* if (start.parentNode.host) {
|
|
61
|
+
const { host } = start.parentNode;
|
|
62
|
+
if (host.hasAttribute('ref')) {
|
|
63
|
+
return host;
|
|
64
|
+
}
|
|
65
|
+
} else */
|
|
66
|
+
if (start.parentNode &&
|
|
67
|
+
(start.parentNode.nodeType !== Node.DOCUMENT_NODE || start.parentNode.nodeType !== Node.DOCUMENT_FRAGMENT_NODE)) {
|
|
68
|
+
/*
|
|
69
|
+
if (start.parentNode.hasAttribute('ref')) {
|
|
70
|
+
return start.parentNode;
|
|
71
|
+
}
|
|
72
|
+
return XPathUtil.getParentBindingElement(start.parentNode);
|
|
73
|
+
*/
|
|
90
74
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
75
|
+
return start.parentNode.closest('[ref]');
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
94
79
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
static getInstanceId(ref) {
|
|
105
|
-
if (!ref) {
|
|
106
|
-
return 'default';
|
|
80
|
+
/**
|
|
81
|
+
* Checks whether the specified path expression is an absolute path.
|
|
82
|
+
*
|
|
83
|
+
* @param path the path expression.
|
|
84
|
+
* @return <code>true</code> if specified path expression is an absolute
|
|
85
|
+
* path, otherwise <code>false</code>.
|
|
86
|
+
*/
|
|
87
|
+
static isAbsolutePath(path) {
|
|
88
|
+
return path != null && (path.startsWith('/') || path.startsWith('instance('));
|
|
107
89
|
}
|
|
108
|
-
|
|
109
|
-
|
|
90
|
+
|
|
91
|
+
static isSelfReference(ref) {
|
|
92
|
+
return ref === '.' || ref === './text()' || ref === 'text()' || ref === '' || ref === null;
|
|
110
93
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* returns the instance id from a complete XPath using `instance()` function.
|
|
97
|
+
*
|
|
98
|
+
* Will return 'default' in case no ref is given at all or the `instance()` function is called without arg.
|
|
99
|
+
*
|
|
100
|
+
* Otherwise instance id is extracted from function and returned. If all fails null is returned.
|
|
101
|
+
* @param ref
|
|
102
|
+
* @returns {string}
|
|
103
|
+
*/
|
|
104
|
+
static getInstanceId(ref) {
|
|
105
|
+
if (!ref) {
|
|
106
|
+
return 'default';
|
|
107
|
+
}
|
|
108
|
+
if (ref.startsWith('instance()')) {
|
|
109
|
+
return 'default';
|
|
110
|
+
}
|
|
111
|
+
if (ref.startsWith('instance(')) {
|
|
112
|
+
const result = ref.substring(ref.indexOf('(') + 1);
|
|
113
|
+
return result.substring(1, result.indexOf(')') - 1);
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
114
116
|
}
|
|
115
|
-
return null;
|
|
116
|
-
}
|
|
117
117
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
118
|
+
static resolveInstance(boundElement, path) {
|
|
119
|
+
let instanceId = XPathUtil.getInstanceId(path);
|
|
120
|
+
if (!instanceId) {
|
|
121
|
+
instanceId = XPathUtil.getInstanceId(boundElement.getAttribute('ref'));
|
|
122
|
+
}
|
|
123
|
+
if (instanceId !== null) {
|
|
124
|
+
return instanceId;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const parentBinding = XPathUtil.getParentBindingElement(boundElement);
|
|
128
|
+
if (parentBinding) {
|
|
129
|
+
return this.resolveInstance(parentBinding, path);
|
|
130
|
+
}
|
|
131
|
+
return 'default';
|
|
125
132
|
}
|
|
126
133
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
134
|
+
static getDocPath(node) {
|
|
135
|
+
const path = fx.evaluateXPathToString('path()', node);
|
|
136
|
+
// Path is like `$default/x[1]/y[1]`
|
|
137
|
+
const shortened = XPathUtil.shortenPath(path);
|
|
138
|
+
return shortened.startsWith('/') ? `${shortened}` : `/${shortened}`;
|
|
130
139
|
}
|
|
131
|
-
return 'default';
|
|
132
|
-
}
|
|
133
140
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
141
|
+
static getPath(node, instanceId) {
|
|
142
|
+
const path = fx.evaluateXPathToString('path()', node);
|
|
143
|
+
// Path is like `$default/x[1]/y[1]`
|
|
144
|
+
const shortened = XPathUtil.shortenPath(path);
|
|
145
|
+
return shortened.startsWith('/') ? `$${instanceId}${shortened}` : `$${instanceId}/${shortened}`;
|
|
146
|
+
}
|
|
139
147
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
148
|
+
static shortenPath(path) {
|
|
149
|
+
const tmp = path.replaceAll(/(Q{(.*?)\})/g, '');
|
|
150
|
+
// cut off leading slash
|
|
151
|
+
const tmp1 = tmp.substring(1, tmp.length);
|
|
152
|
+
// ### cut-off root node ref
|
|
153
|
+
return tmp1.substring(tmp1.indexOf('/'), tmp.length);
|
|
154
|
+
}
|
|
147
155
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
156
|
+
static getBasePath(dep) {
|
|
157
|
+
const split = dep.split(':');
|
|
158
|
+
return split[0];
|
|
159
|
+
}
|
|
152
160
|
}
|