@jinntec/fore 1.0.0-5 → 1.2.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.
- package/README.md +7 -28
- package/dist/fore-dev.js +43 -0
- package/dist/fore-dev.js.map +1 -0
- package/dist/fore.js +37 -0
- package/dist/fore.js.map +1 -0
- package/index.js +3 -1
- package/package.json +39 -41
- package/resources/fore.css +27 -54
- package/src/DependencyNotifyingDomFacade.js +5 -13
- package/src/ForeElementMixin.js +15 -22
- package/src/actions/abstract-action.js +34 -10
- package/src/actions/fx-action.js +7 -5
- package/src/actions/fx-append.js +8 -17
- package/src/actions/fx-confirm.js +5 -3
- package/src/actions/fx-delete.js +6 -3
- package/src/actions/fx-dispatch.js +9 -8
- package/src/actions/fx-hide.js +9 -6
- package/src/actions/fx-insert.js +27 -14
- package/src/actions/fx-message.js +3 -1
- package/src/actions/fx-refresh.js +24 -1
- package/src/actions/fx-replace.js +74 -0
- package/src/actions/fx-return.js +42 -0
- package/src/actions/fx-send.js +3 -1
- package/src/actions/fx-setfocus.js +37 -0
- package/src/actions/fx-setvalue.js +58 -51
- package/src/actions/fx-show.js +12 -4
- package/src/actions/fx-toggle.js +13 -9
- package/src/actions/fx-update.js +3 -1
- package/src/dep_graph.js +1 -1
- package/src/drawdown.js +67 -82
- package/src/fore.js +143 -26
- package/src/functions/fx-function.js +17 -3
- package/src/fx-bind.js +40 -200
- package/src/fx-fore.js +598 -568
- package/src/fx-header.js +3 -1
- package/src/fx-instance.js +9 -1
- package/src/fx-model.js +60 -27
- package/src/fx-submission.js +108 -51
- package/src/fx-var.js +7 -4
- package/src/getInScopeContext.js +23 -16
- package/src/modelitem.js +4 -4
- package/src/relevance.js +64 -0
- package/src/ui/abstract-control.js +65 -37
- package/src/ui/fx-alert.js +7 -1
- package/src/ui/fx-case.js +4 -3
- package/src/ui/fx-container.js +4 -2
- package/src/ui/fx-control.js +315 -34
- package/src/ui/fx-dialog.js +50 -45
- package/src/ui/fx-group.js +3 -1
- package/src/ui/fx-hint.js +4 -1
- package/src/ui/fx-inspector.js +118 -17
- package/src/ui/fx-items.js +7 -5
- package/src/ui/fx-output.js +19 -6
- package/src/ui/fx-repeat.js +13 -26
- package/src/ui/fx-repeatitem.js +10 -4
- package/src/ui/fx-switch.js +5 -3
- package/src/ui/fx-trigger.js +3 -1
- package/src/xpath-evaluation.js +622 -553
- package/src/xpath-util.js +2 -6
- package/dist/fore-all.js +0 -140
- package/dist/fore-debug.js +0 -140
- package/src/.DS_Store +0 -0
- package/src/actions/.DS_Store +0 -0
- package/src/ui/.DS_Store +0 -0
package/src/drawdown.js
CHANGED
|
@@ -4,72 +4,67 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
function markdown(src) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
7
|
+
const rx_lt = /</g;
|
|
8
|
+
const rx_gt = />/g;
|
|
9
|
+
const rx_space = /\t|\r|\uf8ff/g;
|
|
10
|
+
const rx_escape = /\\([\\\|`*_{}\[\]()#+\-~])/g;
|
|
11
|
+
const rx_hr = /^([*\-=_] *){3,}$/gm;
|
|
12
|
+
const rx_blockquote = /\n *> *([^]*?)(?=(\n|$){2})/g;
|
|
13
|
+
const rx_list = /\n( *)(?:[*\-+]|((\d+)|([a-z])|[A-Z])[.)]) +([^]*?)(?=(\n|$){2})/g;
|
|
14
|
+
const rx_listjoin = /<\/(ol|ul)>\n\n<\1>/g;
|
|
15
|
+
const rx_highlight = /(^|[^A-Za-z\d\\])(([*_])|(~)|(\^)|(--)|(\+\+)|`)(\2?)([^<]*?)\2\8(?!\2)(?=\W|_|$)/g;
|
|
16
|
+
const rx_code = /\n((```|~~~).*\n?([^]*?)\n?\2|(( {4}.*?\n)+))/g;
|
|
17
|
+
const rx_link = /((!?)\[(.*?)\]\((.*?)( ".*")?\)|\\([\\`*_{}\[\]()#+\-.!~]))/g;
|
|
18
|
+
const rx_table = /\n(( *\|.*?\| *\n)+)/g;
|
|
19
|
+
const rx_thead = /^.*\n( *\|( *\:?-+\:?-+\:? *\|)* *\n|)/;
|
|
20
|
+
const rx_row = /.*\n/g;
|
|
21
|
+
const rx_cell = /\||(.*?[^\\])\|/g;
|
|
22
|
+
const rx_heading = /(?=^|>|\n)([>\s]*?)(#{1,6}) (.*?)( #*)? *(?=\n|$)/g;
|
|
23
|
+
const rx_para = /(?=^|>|\n)\s*\n+([^<]+?)\n+\s*(?=\n|<|$)/g;
|
|
24
|
+
const rx_stash = /-\d+\uf8ff/g;
|
|
25
25
|
|
|
26
26
|
function replace(rex, fn) {
|
|
27
27
|
src = src.replace(rex, fn);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
function element(tag, content) {
|
|
31
|
-
return
|
|
31
|
+
return `<${tag}>${content}</${tag}>`;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
function blockquote(src) {
|
|
35
|
-
return src.replace(rx_blockquote,
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
return src.replace(rx_blockquote, (all, content) =>
|
|
36
|
+
element('blockquote', blockquote(highlight(content.replace(/^ *> */gm, '')))),
|
|
37
|
+
);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
function list(src) {
|
|
41
|
-
return src.replace(rx_list,
|
|
42
|
-
|
|
41
|
+
return src.replace(rx_list, (all, ind, ol, num, low, content) => {
|
|
42
|
+
const entry = element(
|
|
43
43
|
'li',
|
|
44
44
|
highlight(
|
|
45
45
|
content
|
|
46
|
-
.split(RegExp(
|
|
46
|
+
.split(RegExp(`\n ?${ind}(?:(?:\\d+|[a-zA-Z])[.)]|[*\\-+]) +`, 'g'))
|
|
47
47
|
.map(list)
|
|
48
48
|
.join('</li><li>'),
|
|
49
49
|
),
|
|
50
50
|
);
|
|
51
51
|
|
|
52
|
-
return
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
(low ? 'low' : 'upp') +
|
|
62
|
-
'er-alpha">') +
|
|
63
|
-
entry +
|
|
64
|
-
'</ol>'
|
|
65
|
-
: element('ul', entry))
|
|
66
|
-
);
|
|
52
|
+
return `\n${
|
|
53
|
+
ol
|
|
54
|
+
? `<ol start="${
|
|
55
|
+
num
|
|
56
|
+
? `${ol}">`
|
|
57
|
+
: `${parseInt(ol, 36) - 9}" style="list-style-type:${low ? 'low' : 'upp'}er-alpha">`
|
|
58
|
+
}${entry}</ol>`
|
|
59
|
+
: element('ul', entry)
|
|
60
|
+
}`;
|
|
67
61
|
});
|
|
68
62
|
}
|
|
69
63
|
|
|
70
64
|
function highlight(src) {
|
|
71
|
-
return src.replace(
|
|
72
|
-
|
|
65
|
+
return src.replace(
|
|
66
|
+
rx_highlight,
|
|
67
|
+
(all, _, p1, emp, sub, sup, small, big, p2, content) =>
|
|
73
68
|
_ +
|
|
74
69
|
element(
|
|
75
70
|
emp
|
|
@@ -88,19 +83,18 @@ function markdown(src) {
|
|
|
88
83
|
? 'big'
|
|
89
84
|
: 'code',
|
|
90
85
|
highlight(content),
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
});
|
|
86
|
+
),
|
|
87
|
+
);
|
|
94
88
|
}
|
|
95
89
|
|
|
96
90
|
function unesc(str) {
|
|
97
91
|
return str.replace(rx_escape, '$1');
|
|
98
92
|
}
|
|
99
93
|
|
|
100
|
-
|
|
101
|
-
|
|
94
|
+
const stash = [];
|
|
95
|
+
let si = 0;
|
|
102
96
|
|
|
103
|
-
src =
|
|
97
|
+
src = `\n${src}\n`;
|
|
104
98
|
|
|
105
99
|
replace(rx_lt, '<');
|
|
106
100
|
replace(rx_gt, '>');
|
|
@@ -117,56 +111,47 @@ function markdown(src) {
|
|
|
117
111
|
replace(rx_listjoin, '');
|
|
118
112
|
|
|
119
113
|
// code
|
|
120
|
-
replace(rx_code,
|
|
121
|
-
stash[--si] = element('pre', element('code', p3 || p4.replace(/^
|
|
122
|
-
return si
|
|
114
|
+
replace(rx_code, (all, p1, p2, p3, p4) => {
|
|
115
|
+
stash[--si] = element('pre', element('code', p3 || p4.replace(/^ {4}/gm, '')));
|
|
116
|
+
return `${si}\uf8ff`;
|
|
123
117
|
});
|
|
124
118
|
|
|
125
119
|
// link or image
|
|
126
|
-
replace(rx_link,
|
|
120
|
+
replace(rx_link, (all, p1, p2, p3, p4, p5, p6) => {
|
|
127
121
|
stash[--si] = p4
|
|
128
122
|
? p2
|
|
129
|
-
?
|
|
130
|
-
:
|
|
123
|
+
? `<img src="${p4}" alt="${p3}"/>`
|
|
124
|
+
: `<a href="${p4}">${unesc(highlight(p3))}</a>`
|
|
131
125
|
: p6;
|
|
132
|
-
return si
|
|
126
|
+
return `${si}\uf8ff`;
|
|
133
127
|
});
|
|
134
128
|
|
|
135
129
|
// table
|
|
136
|
-
replace(rx_table,
|
|
137
|
-
|
|
138
|
-
return (
|
|
139
|
-
'
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
'
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}),
|
|
152
|
-
)
|
|
153
|
-
);
|
|
130
|
+
replace(rx_table, (all, table) => {
|
|
131
|
+
const sep = table.match(rx_thead)[1];
|
|
132
|
+
return `\n${element(
|
|
133
|
+
'table',
|
|
134
|
+
table.replace(rx_row, (row, ri) =>
|
|
135
|
+
row == sep
|
|
136
|
+
? ''
|
|
137
|
+
: element(
|
|
138
|
+
'tr',
|
|
139
|
+
row.replace(rx_cell, (all, cell, ci) =>
|
|
140
|
+
ci ? element(sep && !ri ? 'th' : 'td', unesc(highlight(cell || ''))) : '',
|
|
141
|
+
),
|
|
142
|
+
),
|
|
143
|
+
),
|
|
144
|
+
)}`;
|
|
154
145
|
});
|
|
155
146
|
|
|
156
147
|
// heading
|
|
157
|
-
replace(rx_heading,
|
|
158
|
-
return _ + element('h' + p1.length, unesc(highlight(p2)));
|
|
159
|
-
});
|
|
148
|
+
replace(rx_heading, (all, _, p1, p2) => _ + element(`h${p1.length}`, unesc(highlight(p2))));
|
|
160
149
|
|
|
161
150
|
// paragraph
|
|
162
|
-
replace(rx_para,
|
|
163
|
-
return element('p', unesc(highlight(content)));
|
|
164
|
-
});
|
|
151
|
+
replace(rx_para, (all, content) => element('p', unesc(highlight(content))));
|
|
165
152
|
|
|
166
153
|
// stash
|
|
167
|
-
replace(rx_stash,
|
|
168
|
-
return stash[parseInt(all)];
|
|
169
|
-
});
|
|
154
|
+
replace(rx_stash, all => stash[parseInt(all)]);
|
|
170
155
|
|
|
171
156
|
return src.trim();
|
|
172
157
|
}
|
package/src/fore.js
CHANGED
|
@@ -127,7 +127,12 @@ export class Fore {
|
|
|
127
127
|
const { children } = startElement;
|
|
128
128
|
if (children) {
|
|
129
129
|
Array.from(children).forEach(element => {
|
|
130
|
+
if (element.nodeName.toUpperCase() === 'FX-FORE') {
|
|
131
|
+
resolve('done');
|
|
132
|
+
}
|
|
130
133
|
if (Fore.isUiElement(element.nodeName) && typeof element.refresh === 'function') {
|
|
134
|
+
// console.log('refreshing', element, element?.ref);
|
|
135
|
+
// console.log('refreshing ',element);
|
|
131
136
|
element.refresh();
|
|
132
137
|
} else if (element.nodeName.toUpperCase() !== 'FX-MODEL') {
|
|
133
138
|
Fore.refreshChildren(element, force);
|
|
@@ -140,14 +145,21 @@ export class Fore {
|
|
|
140
145
|
return refreshed;
|
|
141
146
|
}
|
|
142
147
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
148
|
+
/**
|
|
149
|
+
* Alternative to `closest` that respects subcontrol boundaries
|
|
150
|
+
*/
|
|
151
|
+
static getClosest(querySelector, start) {
|
|
152
|
+
while (!start.matches(querySelector)) {
|
|
153
|
+
if (start.matches('fx-fore')) {
|
|
154
|
+
// Subform reached. Bail out
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
start = start.parentNode;
|
|
158
|
+
if (!start) {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return start;
|
|
151
163
|
}
|
|
152
164
|
|
|
153
165
|
/**
|
|
@@ -193,13 +205,11 @@ export class Fore {
|
|
|
193
205
|
static fadeOutElement(element, duration) {
|
|
194
206
|
// const duration = duration;
|
|
195
207
|
let fadeOut = () => {
|
|
196
|
-
|
|
197
208
|
// Stop all current animations
|
|
198
209
|
if (element.getAnimations) {
|
|
199
210
|
element.getAnimations().map(anim => anim.finish());
|
|
200
211
|
}
|
|
201
212
|
|
|
202
|
-
|
|
203
213
|
// Play the animation with the newly specified duration
|
|
204
214
|
fadeOut = element.animate(
|
|
205
215
|
{
|
|
@@ -214,33 +224,36 @@ export class Fore {
|
|
|
214
224
|
|
|
215
225
|
static dispatch(target, eventName, detail) {
|
|
216
226
|
const event = new CustomEvent(eventName, {
|
|
217
|
-
composed:
|
|
227
|
+
composed: false,
|
|
218
228
|
bubbles: true,
|
|
219
229
|
detail,
|
|
220
230
|
});
|
|
221
|
-
console.log('
|
|
231
|
+
console.log('dispatching', event);
|
|
222
232
|
target.dispatchEvent(event);
|
|
223
233
|
}
|
|
224
234
|
|
|
225
235
|
static prettifyXml(source) {
|
|
226
236
|
const xmlDoc = new DOMParser().parseFromString(source, 'application/xml');
|
|
227
237
|
const xsltDoc = new DOMParser().parseFromString(
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
'
|
|
238
|
+
[
|
|
239
|
+
// describes how we want to modify the XML - indent everything
|
|
240
|
+
'<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">',
|
|
241
|
+
' <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>',
|
|
242
|
+
' <xsl:strip-space elements="*"/>',
|
|
243
|
+
' <xsl:template match="text()">', // change to just text() to strip space in text nodes
|
|
244
|
+
' <xsl:value-of select="normalize-space(.)"/>',
|
|
245
|
+
' </xsl:template>',
|
|
246
|
+
' <xsl:template match="node()|@*">',
|
|
247
|
+
' <xsl:copy>',
|
|
248
|
+
' <xsl:apply-templates select="node()|@*"/>',
|
|
249
|
+
' </xsl:copy>',
|
|
250
|
+
' </xsl:template>',
|
|
251
|
+
'</xsl:stylesheet>',
|
|
252
|
+
].join('\n'),
|
|
253
|
+
'application/xml',
|
|
242
254
|
);
|
|
243
255
|
|
|
256
|
+
|
|
244
257
|
const xsltProcessor = new XSLTProcessor();
|
|
245
258
|
xsltProcessor.importStylesheet(xsltDoc);
|
|
246
259
|
const resultDoc = xsltProcessor.transformToDocument(xmlDoc);
|
|
@@ -248,6 +261,110 @@ export class Fore {
|
|
|
248
261
|
return resultXml;
|
|
249
262
|
}
|
|
250
263
|
|
|
264
|
+
static formatXml (xml) {
|
|
265
|
+
var reg = /(>)(<)(\/*)/g;
|
|
266
|
+
var wsexp = / *(.*) +\n/g;
|
|
267
|
+
var contexp = /(<.+>)(.+\n)/g;
|
|
268
|
+
xml = xml.replace(reg, '$1\n$2$3').replace(wsexp, '$1\n').replace(contexp, '$1\n$2');
|
|
269
|
+
var pad = 0;
|
|
270
|
+
var formatted = '';
|
|
271
|
+
var lines = xml.split('\n');
|
|
272
|
+
var indent = 0;
|
|
273
|
+
var lastType = 'other';
|
|
274
|
+
// 4 types of tags - single, closing, opening, other (text, doctype, comment) - 4*4 = 16 transitions
|
|
275
|
+
var transitions = {
|
|
276
|
+
'single->single': 0,
|
|
277
|
+
'single->closing': -1,
|
|
278
|
+
'single->opening': 0,
|
|
279
|
+
'single->other': 0,
|
|
280
|
+
'closing->single': 0,
|
|
281
|
+
'closing->closing': -1,
|
|
282
|
+
'closing->opening': 0,
|
|
283
|
+
'closing->other': 0,
|
|
284
|
+
'opening->single': 1,
|
|
285
|
+
'opening->closing': 0,
|
|
286
|
+
'opening->opening': 1,
|
|
287
|
+
'opening->other': 1,
|
|
288
|
+
'other->single': 0,
|
|
289
|
+
'other->closing': -1,
|
|
290
|
+
'other->opening': 0,
|
|
291
|
+
'other->other': 0
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
for (var i = 0; i < lines.length; i++) {
|
|
295
|
+
var ln = lines[i];
|
|
296
|
+
var single = Boolean(ln.match(/<.+\/>/)); // is this line a single tag? ex. <br />
|
|
297
|
+
var closing = Boolean(ln.match(/<\/.+>/)); // is this a closing tag? ex. </a>
|
|
298
|
+
var opening = Boolean(ln.match(/<[^!].*>/)); // is this even a tag (that's not <!something>)
|
|
299
|
+
var type = single ? 'single' : closing ? 'closing' : opening ? 'opening' : 'other';
|
|
300
|
+
var fromTo = lastType + '->' + type;
|
|
301
|
+
lastType = type;
|
|
302
|
+
var padding = '';
|
|
303
|
+
|
|
304
|
+
indent += transitions[fromTo];
|
|
305
|
+
for (var j = 0; j < indent; j++) {
|
|
306
|
+
padding += ' ';
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
formatted += padding + ln + '\n';
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
static async loadForeFromUrl(hostElement, url) {
|
|
314
|
+
console.log('########## loading Fore from ', this.src, '##########');
|
|
315
|
+
await fetch(url, {
|
|
316
|
+
method: 'GET',
|
|
317
|
+
mode: 'cors',
|
|
318
|
+
credentials: 'include',
|
|
319
|
+
headers: {
|
|
320
|
+
'Content-Type': 'text/html',
|
|
321
|
+
},
|
|
322
|
+
})
|
|
323
|
+
.then(response => {
|
|
324
|
+
const responseContentType = response.headers.get('content-type').toLowerCase();
|
|
325
|
+
console.log('********** responseContentType *********', responseContentType);
|
|
326
|
+
if (responseContentType.startsWith('text/html')) {
|
|
327
|
+
return response.text().then(result =>
|
|
328
|
+
// console.log('xml ********', result);
|
|
329
|
+
new DOMParser().parseFromString(result, 'text/html'),
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
return 'done';
|
|
333
|
+
})
|
|
334
|
+
.then(data => {
|
|
335
|
+
// const theFore = fxEvaluateXPathToFirstNode('//fx-fore', data.firstElementChild);
|
|
336
|
+
const theFore = data.querySelector('fx-fore');
|
|
337
|
+
// console.log('thefore', theFore)
|
|
338
|
+
if (!theFore) {
|
|
339
|
+
hostElement.dispatchEvent(
|
|
340
|
+
new CustomEvent('error', {
|
|
341
|
+
composed: false,
|
|
342
|
+
bubbles: true,
|
|
343
|
+
detail: {
|
|
344
|
+
message: 'cyclic graph',
|
|
345
|
+
},
|
|
346
|
+
}),
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
hostElement.appendChild(theFore);
|
|
350
|
+
theFore.classList.add('widget');
|
|
351
|
+
// return theFore;
|
|
352
|
+
// theFore.setAttribute('from-src', this.src);
|
|
353
|
+
// this.replaceWith(theFore);
|
|
354
|
+
})
|
|
355
|
+
.catch(error => {
|
|
356
|
+
hostElement.dispatchEvent(
|
|
357
|
+
new CustomEvent('error', {
|
|
358
|
+
composed: false,
|
|
359
|
+
bubbles: true,
|
|
360
|
+
detail: {
|
|
361
|
+
error: error,
|
|
362
|
+
message: `'${url}' not found or does not contain Fore element.`,
|
|
363
|
+
},
|
|
364
|
+
}),
|
|
365
|
+
);
|
|
366
|
+
});
|
|
367
|
+
}
|
|
251
368
|
|
|
252
369
|
/**
|
|
253
370
|
* clear all text nodes and attribute values to get a 'clean' template.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { registerCustomXPathFunction } from 'fontoxpath';
|
|
2
2
|
import { foreElementMixin } from '../ForeElementMixin.js';
|
|
3
|
-
import { evaluateXPath } from '../xpath-evaluation.js';
|
|
3
|
+
import { evaluateXPath, globallyDeclaredFunctionLocalNames } from '../xpath-evaluation.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Allows to extend a form with local custom functions.
|
|
@@ -41,10 +41,16 @@ export class FxFunction extends foreElementMixin(HTMLElement) {
|
|
|
41
41
|
|
|
42
42
|
// TODO: lookup prefix
|
|
43
43
|
const functionIdentifier =
|
|
44
|
-
prefix === 'local'
|
|
44
|
+
prefix === 'local' || !prefix
|
|
45
45
|
? { namespaceURI: 'http://www.w3.org/2005/xquery-local-functions', localName }
|
|
46
46
|
: `${prefix}:${localName}`;
|
|
47
47
|
|
|
48
|
+
// Make the function available globally w/o a prefix. See the functionNameResolver for for how
|
|
49
|
+
// this is picked up
|
|
50
|
+
if (!prefix) {
|
|
51
|
+
globallyDeclaredFunctionLocalNames.push(localName);
|
|
52
|
+
}
|
|
53
|
+
|
|
48
54
|
const paramParts = params
|
|
49
55
|
? params.split(',').map(param => {
|
|
50
56
|
const match = param.match(/(?<variableName>\$[^\s]+)(?:\sas\s(?<varType>.+))/);
|
|
@@ -77,7 +83,12 @@ export class FxFunction extends foreElementMixin(HTMLElement) {
|
|
|
77
83
|
break;
|
|
78
84
|
}
|
|
79
85
|
|
|
86
|
+
case 'text/xquf':
|
|
87
|
+
case 'text/xquery':
|
|
80
88
|
case 'text/xpath': {
|
|
89
|
+
const language = type === 'text/xpath' ?
|
|
90
|
+
'XPath3.1' : type === 'text/xquery' ?
|
|
91
|
+
'XQuery3.1' : 'XQueryUpdate3.1';
|
|
81
92
|
const fun = (domFacade, ...args) =>
|
|
82
93
|
evaluateXPath(
|
|
83
94
|
this.functionBody,
|
|
@@ -87,6 +98,7 @@ export class FxFunction extends foreElementMixin(HTMLElement) {
|
|
|
87
98
|
variablesByName[paramPart.variableName.replace('$', '')] = args[i];
|
|
88
99
|
return variablesByName;
|
|
89
100
|
}, {}),
|
|
101
|
+
{language}
|
|
90
102
|
);
|
|
91
103
|
registerCustomXPathFunction(
|
|
92
104
|
functionIdentifier,
|
|
@@ -102,4 +114,6 @@ export class FxFunction extends foreElementMixin(HTMLElement) {
|
|
|
102
114
|
}
|
|
103
115
|
}
|
|
104
116
|
}
|
|
105
|
-
customElements.
|
|
117
|
+
if (!customElements.get('fx-function')) {
|
|
118
|
+
customElements.define('fx-function', FxFunction);
|
|
119
|
+
}
|