@longform/longform 0.0.4 → 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/dist/longform.js CHANGED
@@ -1,423 +1,508 @@
1
- const sniffTestRe = /^(?:(?:(--).*)|(?: *(@|#).*)|(?: *[\w\-]+(?::[\w\-]+)?(?:[#.[][^\n]+)?(::).*)|(?: +([\["]).*)|(\ \ .*))$/gmi, element1 = /((?:\ \ )+)? ?([\w\-]+(?::[\w\-]+)?)([#\.\[][^\n]*)?::(?: ({{?|[^\n]+))?/gmi, directive1 = /((?:\ \ )+)? ?@([\w][\w\-]+)(?::: ?([^\n]+)?)?/gmi, attribute1 = /((?:\ \ )+)\[(\w[\w-]*(?::\w[\w-]*)?)(?:=([^\n]+))?\]/, preformattedClose = /[ \t]*}}?[ \t]*/, id1 = /((?:\ \ )+)?#(#)?([\w\-]+)(?: ([\["]))?/gmi, idnt1 = /^(\ \ )+/, text1 = /^((?:\ \ )+)([^ \n][^\n]*)$/i, paramsRe = /(?:(#|\.)([^#.\[\n]+)|(?:\[(\w[\w\-]*(?::\w[\w\-]*)?)(?:=([^\n\]]+))?\]))/g, refRe = /#\[([\w\-]+)\]/g, escapeRe = /([&<>"'#\[\]{}])/g, templateLinesRe = /^(\ \ )?([^\n]+)$/gmi, voids = /* @__PURE__ */ new Set(["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wrb"]);
1
+ const sniffTestRe = /^(?:(?:(--).*)|(?: *(@|#).*)|(?: *[\w\-]+(?::[\w\-]+)?(?:[#.[][^\n]+)?(::).*)|(?: +([\["]).*)|(\ \ .*))$/gmi, element1 = /((?:\ \ )+)? ?([\w\-]+(?::[\w\-]+)?)([#\.\[][^\n]*)?::(?: ({{?|[^\n]+))?/gmi, directive1 = /((?:\ \ )+)? ?@([\w][\w\-]+)(?::: ?([^\n]+)?)?/gmi, attribute1 = /((?:\ \ )+)\[(\w[\w-]*(?::\w[\w-]*)?)(?:=([^\n]+))?\]/, preformattedClose = /[ \t]*}}?[ \t]*/, id1 = /((?:\ \ )+)?#(#)?([\w\-]+)(?: ([\["]))?/gmi, idnt1 = /^(\ \ )+/, text1 = /^((?:\ \ )+)([^ \n][^\n]*)$/i, paramsRe = /(?:(#|\.)([^#.\[\n]+)|(?:\[(\w[\w\-]*(?::\w[\w\-]*)?)(?:=([^\n\]]+))?\]))/g, refRe = /#\[([\w\-]+)\]/g, escapeRe = /([&<>"'#\[\]{}])/g, templateLinesRe = /^(\ \ )?([^\n]+)$/gmi, voids = new Set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wrb']);
2
2
  let m1, m2, m3;
3
3
  const entities = {
4
- "&": "&amp;",
5
- "<": "&lt;",
6
- ">": "&gt;",
7
- '"': "&quot;",
8
- "'": "&apos;"
9
- // '#': '&num;',
10
- // '[': '&lbrak;',
11
- // ']': '&rbrak;',
12
- // '{': '&rbrace;',
13
- // '}': '&lbrace;',
4
+ '&': '&amp;',
5
+ '<': '&lt;',
6
+ '>': '&gt;',
7
+ '"': '&quot;',
8
+ "'": '&apos;',
9
+ // '#': '&num;',
10
+ // '[': '&lbrak;',
11
+ // ']': '&rbrak;',
12
+ // '{': '&rbrace;',
13
+ // '}': '&lbrace;',
14
14
  };
15
15
  function escape(value) {
16
- return value.replace(escapeRe, (match) => {
17
- var _a;
18
- return (_a = entities[match]) != null ? _a : match;
19
- });
16
+ return value.replace(escapeRe, (match) => {
17
+ return entities[match] ?? match;
18
+ });
20
19
  }
21
20
  function makeElement(indent = 0) {
22
- return {
23
- indent,
24
- html: "",
25
- attrs: {}
26
- };
21
+ return {
22
+ indent,
23
+ html: '',
24
+ attrs: {},
25
+ };
27
26
  }
28
- function makeFragment(type = "bare") {
29
- return {
30
- type,
31
- html: "",
32
- template: false,
33
- mountable: false,
34
- els: [],
35
- refs: [],
36
- mountPoints: []
37
- };
27
+ function makeFragment(type = 'bare') {
28
+ return {
29
+ type,
30
+ html: '',
31
+ template: false,
32
+ mountable: false,
33
+ els: [],
34
+ refs: [],
35
+ mountPoints: [],
36
+ };
38
37
  }
39
- export function longform(doc, debug = () => {
40
- }) {
41
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
42
- let skipping = false, textIndent = null, verbatimSerialize = true, verbatimIndent = null, verbatimFirst = false, element = makeElement(), fragment = makeFragment(), root = null;
43
- const claimed = /* @__PURE__ */ new Set(), parsed = /* @__PURE__ */ new Map(), output = /* @__PURE__ */ Object.create(null);
44
- output.fragments = /* @__PURE__ */ Object.create(null);
45
- output.templates = /* @__PURE__ */ Object.create(null);
46
- function applyIndent(targetIndent) {
47
- if (element.tag != null) {
48
- const root2 = fragment.type === "range" ? targetIndent < 2 : fragment.html === "";
49
- fragment.html += `<${element.tag}`;
50
- if (root2) {
51
- if (fragment.type === "root") {
52
- fragment.html += ` data-lf-root`;
53
- } else if (fragment.type === "bare" || fragment.type === "range") {
54
- fragment.html += ` data-lf="${fragment.id}"`;
55
- }
56
- }
57
- if (element.mount != null) {
58
- fragment.html += ` data-lf-mount="${element.mount}"`;
59
- }
60
- if (element.id != null) {
61
- fragment.html += ' id="' + element.id + '"';
62
- }
63
- if (element.class != null) {
64
- fragment.html += ' class="' + element.class + '"';
65
- }
66
- for (const attr of Object.entries(element.attrs)) {
67
- if (attr[1] == null) {
68
- fragment.html += " " + attr[0];
69
- } else {
70
- fragment.html += ` ${attr[0]}="${attr[1]}"`;
71
- }
72
- }
73
- fragment.html += ">";
74
- if (!voids.has(element.tag) && element.text != null) {
75
- fragment.html += element.text;
76
- }
77
- if (!voids.has(element.tag)) {
78
- fragment.els.push(element);
79
- }
80
- }
81
- if (targetIndent <= element.indent) {
82
- element = makeElement(targetIndent);
83
- while (fragment.els.length !== 0 && (targetIndent == null || fragment.els[fragment.els.length - 1].indent !== targetIndent - 1)) {
84
- const element2 = fragment.els.pop();
85
- fragment.html += `</${element2 == null ? void 0 : element2.tag}>`;
86
- }
87
- if (targetIndent === 0) {
88
- debug(0, "<", fragment.type, fragment.id);
89
- if (fragment.template) {
90
- output.templates[fragment.id] = fragment.html;
91
- } else if (fragment.type === "root") {
92
- root = fragment;
93
- } else {
94
- parsed.set(fragment.id, fragment);
95
- }
96
- fragment = makeFragment();
97
- }
98
- } else {
99
- element = makeElement(targetIndent);
100
- }
101
- }
102
- while (m1 = sniffTestRe.exec(doc)) {
103
- if (m1[1] === "--") {
104
- continue;
105
- } else if (fragment.template) {
106
- fragment.html += m1[0];
107
- }
108
- if (verbatimIndent != null) {
109
- idnt1.lastIndex = 0;
110
- m2 = idnt1.exec(m1[0]);
111
- const indent = m2 == null ? null : m2[0].length / 2;
112
- if (m2 == null || indent <= verbatimIndent) {
113
- fragment.html += "\n";
114
- debug(indent, "}", m2 == null ? void 0 : m2[0]);
115
- applyIndent(indent);
116
- verbatimIndent = null;
117
- verbatimFirst = false;
118
- textIndent = indent;
119
- if (preformattedClose.test(m1[0])) {
120
- continue;
121
- }
122
- } else {
123
- const line = m1[0].replace(" ".repeat(verbatimIndent + 1), "");
124
- debug(indent, "{", line);
38
+ /**
39
+ * Parses a longform document into a object containing the root and fragments
40
+ * in the output format.
41
+ *
42
+ * @param {string} doc - The longform document to parse.
43
+ * @returns {ParsedResult}
44
+ */
45
+ function longform(doc, debug = () => { }) {
46
+ let textIndent = null, verbatimSerialize = true, verbatimIndent = null, verbatimFirst = false, element = makeElement(), fragment = makeFragment()
47
+ // the root fragment
48
+ , root = null;
49
+ // ids of claimed fragments
50
+ const claimed = new Set()
51
+ // parsed fragments
52
+ , parsed = new Map(), output = Object.create(null);
53
+ output.fragments = Object.create(null);
54
+ output.templates = Object.create(null);
55
+ /**
56
+ * Closes any current in progress element definition
57
+ * and creates a new working element.
58
+ */
59
+ function applyIndent(targetIndent) {
125
60
  if (element.tag != null) {
126
- applyIndent(indent);
61
+ const root = fragment.type === 'range'
62
+ ? targetIndent < 2
63
+ : fragment.html === '';
64
+ fragment.html += `<${element.tag}`;
65
+ if (root) {
66
+ if (fragment.type === 'root') {
67
+ fragment.html += ` data-lf-root`;
68
+ }
69
+ else if (fragment.type === 'bare' || fragment.type === 'range') {
70
+ fragment.html += ` data-lf="${fragment.id}"`;
71
+ }
72
+ }
73
+ if (element.mount != null) {
74
+ fragment.html += ` data-lf-mount="${element.mount}"`;
75
+ }
76
+ if (element.id != null) {
77
+ fragment.html += ' id="' + element.id + '"';
78
+ }
79
+ if (element.class != null) {
80
+ fragment.html += ' class="' + element.class + '"';
81
+ }
82
+ for (const attr of Object.entries(element.attrs)) {
83
+ if (attr[1] == null) {
84
+ fragment.html += ' ' + attr[0];
85
+ }
86
+ else {
87
+ fragment.html += ` ${attr[0]}="${attr[1]}"`;
88
+ }
89
+ }
90
+ fragment.html += '>';
91
+ if (!voids.has(element.tag) && element.text != null) {
92
+ fragment.html += element.text;
93
+ }
94
+ if (!voids.has(element.tag)) {
95
+ fragment.els.push(element);
96
+ }
127
97
  }
128
- if (verbatimFirst) {
129
- verbatimFirst = false;
130
- } else {
131
- fragment.html += "\n";
98
+ if (targetIndent <= element.indent) {
99
+ element = makeElement(targetIndent);
100
+ while (fragment.els.length !== 0 && (targetIndent == null ||
101
+ fragment.els[fragment.els.length - 1].indent !== targetIndent - 1)) {
102
+ const element = fragment.els.pop();
103
+ fragment.html += `</${element?.tag}>`;
104
+ }
105
+ if (targetIndent === 0) {
106
+ debug(0, '<', fragment.type, fragment.id);
107
+ if (fragment.template) {
108
+ output.templates[fragment.id] = fragment.html;
109
+ }
110
+ else if (fragment.type === 'root') {
111
+ root = fragment;
112
+ }
113
+ else {
114
+ parsed.set(fragment.id, fragment);
115
+ }
116
+ fragment = makeFragment();
117
+ }
132
118
  }
133
- if (verbatimSerialize) {
134
- fragment.html += escape(line);
135
- } else {
136
- fragment.html += line;
119
+ else {
120
+ element = makeElement(targetIndent);
137
121
  }
138
- continue;
139
- }
140
122
  }
141
- if (m1[0].trim() === "") {
142
- continue;
143
- }
144
- switch ((_b = (_a = m1[2]) != null ? _a : m1[3]) != null ? _b : m1[4]) {
145
- // deno-lint-ignore no-fallthrough
146
- case "#": {
147
- id1.lastIndex = 0;
148
- m2 = id1.exec(m1[0]);
149
- if (m2 != null) {
150
- const indent = ((_d = (_c = m2[1]) == null ? void 0 : _c.length) != null ? _d : 0) / 2;
151
- if (element.tag != null || textIndent != null) {
152
- applyIndent(indent);
153
- textIndent = null;
154
- }
155
- debug(indent, "id", m2[2], m2[3], m2[4]);
156
- fragment.id = m2[3];
157
- if (indent === 0) {
158
- if (m2[4] == "[") {
159
- fragment.type = "range";
160
- } else if (m2[4] === '"') {
161
- fragment.type = "text";
162
- } else if (m2[2] != null) {
163
- fragment.type = "bare";
164
- } else {
165
- fragment.type = "embed";
166
- element.id = fragment.id;
167
- }
168
- }
169
- break;
123
+ while ((m1 = sniffTestRe.exec(doc))) {
124
+ if (m1[1] === '--') {
125
+ continue;
170
126
  }
171
- }
172
- case "@":
173
- case "[":
174
- // deno-lint-ignore no-fallthrough
175
- case "::": {
176
- element1.lastIndex = 0;
177
- m2 = ((_e = m1[2]) != null ? _e : m1[4] != null) ? null : element1.exec(m1[0]);
178
- if (m2 != null) {
179
- const indent = ((_g = (_f = m2[1]) == null ? void 0 : _f.length) != null ? _g : 0) / 2, tg = m2[2], ar = m2[3], pr = m2[4] === "{" || m2[4] === "{{";
180
- const tx = pr ? null : m2[4];
181
- debug(indent, "e", tg, pr, tx);
182
- if (element.tag != null || element.indent > indent) {
183
- applyIndent(indent);
184
- }
185
- element.indent = indent;
186
- element.tag = tg;
187
- textIndent = null;
188
- if (indent === 0 && fragment.id == null) {
189
- if (root != null) {
190
- skipping = true;
191
- } else {
192
- fragment.type = "root";
193
- root = fragment;
127
+ else if (fragment.template) {
128
+ fragment.html += m1[0];
129
+ }
130
+ // If this is a script tag or preformatted block
131
+ // we want to retain the intended formatting less
132
+ // the indent. Preformatting can apply to any element
133
+ // by ending the declaration with `:: {`.
134
+ if (verbatimIndent != null) {
135
+ // inside a script or preformatted block
136
+ idnt1.lastIndex = 0;
137
+ m2 = idnt1.exec(m1[0]);
138
+ const indent = m2 == null
139
+ ? null
140
+ : m2[0].length / 2;
141
+ if (m2 == null || indent <= verbatimIndent) {
142
+ fragment.html += '\n';
143
+ debug(indent, '}', m2?.[0]);
144
+ applyIndent(indent);
145
+ verbatimIndent = null;
146
+ verbatimFirst = false;
147
+ textIndent = indent;
148
+ if (preformattedClose.test(m1[0])) {
149
+ continue;
150
+ }
194
151
  }
195
- }
196
- if (ar != null) {
197
- debug(indent, "a", ar);
198
- while (m2 = paramsRe.exec(ar)) {
199
- if (m2[1] === "#") {
200
- element.id = m2[2];
201
- } else if (m2[1] === ".") {
202
- if (element.class == null) {
203
- element.class = m2[2];
204
- } else {
205
- element.class += " " + m2[2];
152
+ else {
153
+ const line = m1[0].replace(' '.repeat(verbatimIndent + 1), '');
154
+ debug(indent, '{', line);
155
+ if (element.tag != null) {
156
+ applyIndent(indent);
157
+ }
158
+ if (verbatimFirst) {
159
+ verbatimFirst = false;
160
+ }
161
+ else {
162
+ fragment.html += '\n';
206
163
  }
207
- } else {
208
- if (m2[3] === "id") {
209
- if (element.id == null) {
210
- element.id = m2[4];
211
- }
212
- } else if (m2[3] === "class") {
213
- if (element.class == null) {
214
- element.class = m2[4];
215
- } else {
216
- element.class += " " + m2[4];
217
- }
218
- } else {
219
- element.attrs[m2[3]] = m2[4];
164
+ if (verbatimSerialize) {
165
+ fragment.html += escape(line);
220
166
  }
221
- }
167
+ else {
168
+ fragment.html += line;
169
+ }
170
+ continue;
222
171
  }
223
- }
224
- if (element.mount != null) {
225
- const id = element.mount;
226
- applyIndent(indent + 1);
227
- fragment.mountPoints.push({
228
- id,
229
- part: fragment.html
230
- });
231
- fragment.html = "";
232
- applyIndent(indent);
233
- break;
234
- }
235
- if (!pr && tx != null) {
236
- element.text = tx;
237
- } else if (pr) {
238
- verbatimFirst = true;
239
- verbatimIndent = indent;
240
- verbatimSerialize = m2[4] === "{";
241
- }
242
- break;
243
172
  }
244
- attribute1.lastIndex = 0;
245
- m2 = m1[2] != null ? null : attribute1.exec(m1[0]);
246
- if (m2 != null && element.tag != null) {
247
- debug("a", m2[2], m2[3]);
248
- if (m2[2] === "id") {
249
- if (element.id == null) {
250
- element.id = m2[3].trim();
251
- }
252
- } else if (m2[2] === "class") {
253
- if (element.class != null) {
254
- element.class += " " + m2[3].trim();
255
- } else {
256
- element.class = m2[3].trim();
257
- }
258
- } else if (element.attrs[m2[2]] != null) {
259
- element.attrs[m2[2]] += m2[3];
260
- } else {
261
- element.attrs[m2[2]] = m2[3];
262
- }
263
- break;
173
+ if (m1[0].trim() === '') {
174
+ continue;
264
175
  }
265
- directive1.lastIndex = 0;
266
- m2 = m1[3] != null ? null : directive1.exec(m1[0]);
267
- if (m2 != null) {
268
- const indent = ((_i = (_h = m2[1]) == null ? void 0 : _h.length) != null ? _i : 0) / 2;
269
- if (element.tag != null || textIndent != null) {
270
- applyIndent(indent);
271
- }
272
- debug(indent, "d", m2[2], m2[3]);
273
- switch (m2[2]) {
274
- case "doctype": {
275
- fragment.html += `<!doctype ${(_j = m2[3]) != null ? _j : "html"}>`;
276
- break;
176
+ switch (m1[2] ?? m1[3] ?? m1[4]) {
177
+ // deno-lint-ignore no-fallthrough
178
+ case '#': {
179
+ id1.lastIndex = 0;
180
+ m2 = id1.exec(m1[0]);
181
+ if (m2 != null) {
182
+ const indent = (m2[1]?.length ?? 0) / 2;
183
+ if (element.tag != null || textIndent != null) {
184
+ applyIndent(indent);
185
+ textIndent = null;
186
+ }
187
+ debug(indent, 'id', m2[2], m2[3], m2[4]);
188
+ fragment.id = m2[3];
189
+ if (indent === 0) {
190
+ if (m2[4] == '[') {
191
+ fragment.type = 'range';
192
+ }
193
+ else if (m2[4] === '"') {
194
+ fragment.type = 'text';
195
+ }
196
+ else if (m2[2] != null) {
197
+ fragment.type = 'bare';
198
+ }
199
+ else {
200
+ fragment.type = 'embed';
201
+ element.id = fragment.id;
202
+ }
203
+ }
204
+ break;
205
+ }
277
206
  }
278
- case "xml": {
279
- fragment.html += `<?xml ${(_k = m2[3]) != null ? _k : 'version="1.0" encoding="UTF-8"'}?>`;
280
- break;
207
+ case '@':
208
+ case '[':
209
+ // deno-lint-ignore no-fallthrough
210
+ case '::': {
211
+ element1.lastIndex = 0;
212
+ // fall through if m1[3] is a # or @
213
+ m2 = m1[2] ?? m1[4] != null
214
+ ? null
215
+ : element1.exec(m1[0]);
216
+ // if null then invalid element selector
217
+ // allow the default text case to handle
218
+ if (m2 != null) {
219
+ const indent = (m2[1]?.length ?? 0) / 2, tg = m2[2], ar = m2[3], pr = m2[4] === '{' || m2[4] === '{{';
220
+ const tx = pr ? null : m2[4];
221
+ debug(indent, 'e', tg, pr, tx);
222
+ if (element.tag != null ||
223
+ element.indent > indent) {
224
+ applyIndent(indent);
225
+ }
226
+ element.indent = indent;
227
+ element.tag = tg;
228
+ textIndent = null;
229
+ if (indent === 0 && fragment.id == null) {
230
+ if (root != null) ;
231
+ else {
232
+ fragment.type = 'root';
233
+ root = fragment;
234
+ }
235
+ }
236
+ if (ar != null) {
237
+ debug(indent, 'a', ar);
238
+ while ((m2 = paramsRe.exec(ar))) {
239
+ if (m2[1] === '#') {
240
+ element.id = m2[2];
241
+ }
242
+ else if (m2[1] === '.') {
243
+ if (element.class == null) {
244
+ element.class = m2[2];
245
+ }
246
+ else {
247
+ element.class += ' ' + m2[2];
248
+ }
249
+ }
250
+ else {
251
+ if (m2[3] === 'id') {
252
+ if (element.id == null) {
253
+ element.id = m2[4];
254
+ }
255
+ }
256
+ else if (m2[3] === 'class') {
257
+ if (element.class == null) {
258
+ element.class = m2[4];
259
+ }
260
+ else {
261
+ element.class += ' ' + m2[4];
262
+ }
263
+ }
264
+ else {
265
+ element.attrs[m2[3]] = m2[4];
266
+ }
267
+ }
268
+ }
269
+ }
270
+ // this is a hack to get temp support of mounting
271
+ // working. In the future it will be moved to a
272
+ // server specific process.
273
+ if (element.mount != null) {
274
+ const id = element.mount;
275
+ applyIndent(indent + 1);
276
+ fragment.mountPoints.push({
277
+ id,
278
+ part: fragment.html,
279
+ });
280
+ fragment.html = '';
281
+ applyIndent(indent);
282
+ break;
283
+ }
284
+ if (!pr && tx != null) {
285
+ element.text = tx;
286
+ }
287
+ else if (pr) {
288
+ verbatimFirst = true;
289
+ verbatimIndent = indent;
290
+ verbatimSerialize = m2[4] === '{';
291
+ }
292
+ break;
293
+ }
294
+ attribute1.lastIndex = 0;
295
+ m2 = m1[2] != null
296
+ ? null
297
+ : attribute1.exec(m1[0]);
298
+ if (m2 != null && element.tag != null) {
299
+ debug('a', m2[2], m2[3]);
300
+ if (m2[2] === 'id') {
301
+ if (element.id == null) {
302
+ element.id = m2[3].trim();
303
+ }
304
+ }
305
+ else if (m2[2] === 'class') {
306
+ if (element.class != null) {
307
+ element.class += ' ' + m2[3].trim();
308
+ }
309
+ else {
310
+ element.class = m2[3].trim();
311
+ }
312
+ }
313
+ else if (element.attrs[m2[2]] != null) {
314
+ element.attrs[m2[2]] += m2[3];
315
+ }
316
+ else {
317
+ element.attrs[m2[2]] = m2[3];
318
+ }
319
+ break;
320
+ }
321
+ directive1.lastIndex = 0;
322
+ m2 = m1[3] != null
323
+ ? null
324
+ : directive1.exec(m1[0]);
325
+ if (m2 != null) {
326
+ const indent = (m2[1]?.length ?? 0) / 2;
327
+ if (element.tag != null || textIndent != null) {
328
+ applyIndent(indent);
329
+ }
330
+ debug(indent, 'd', m2[2], m2[3]);
331
+ switch (m2[2]) {
332
+ case 'doctype': {
333
+ fragment.html += `<!doctype ${m2[3] ?? 'html'}>`;
334
+ break;
335
+ }
336
+ case 'xml': {
337
+ fragment.html += `<?xml ${m2[3] ?? 'version="1.0" encoding="UTF-8"'}?>`;
338
+ break;
339
+ }
340
+ case 'template': {
341
+ let indented = false;
342
+ fragment.template = indent === 0;
343
+ templateLinesRe.lastIndex = sniffTestRe.lastIndex;
344
+ while ((m2 = templateLinesRe.exec(doc))) {
345
+ if (m2[1] == null && !indented && fragment.id == null) {
346
+ id1.lastIndex = 0;
347
+ m3 = id1.exec(m2[0]);
348
+ if (m3 != null)
349
+ fragment.id = m3[3];
350
+ fragment.html += m2[0];
351
+ }
352
+ else if (m2[1] == null && indented) {
353
+ sniffTestRe.lastIndex = templateLinesRe.lastIndex - m2[0].length;
354
+ break;
355
+ }
356
+ else {
357
+ fragment.html += '\n' + m2[0];
358
+ if (m2[1] != null)
359
+ indented = true;
360
+ }
361
+ }
362
+ applyIndent(0);
363
+ break;
364
+ }
365
+ case 'mount': {
366
+ if (m2[3] == null) {
367
+ throw new Error('Mount points must have a name');
368
+ }
369
+ else if (fragment.type !== 'root') {
370
+ throw new Error('Mounting is only allowed on a root element');
371
+ }
372
+ fragment.mountable = true;
373
+ element.mount = m2[3].trim();
374
+ break;
375
+ }
376
+ }
377
+ break;
378
+ }
281
379
  }
282
- case "template": {
283
- let indented = false;
284
- fragment.template = indent === 0;
285
- templateLinesRe.lastIndex = sniffTestRe.lastIndex;
286
- while (m2 = templateLinesRe.exec(doc)) {
287
- if (m2[1] == null && !indented && fragment.id == null) {
288
- id1.lastIndex = 0;
289
- m3 = id1.exec(m2[0]);
290
- if (m3 != null) fragment.id = m3[3];
291
- fragment.html += m2[0];
292
- } else if (m2[1] == null && indented) {
293
- sniffTestRe.lastIndex = templateLinesRe.lastIndex - m2[0].length;
294
- break;
295
- } else {
296
- fragment.html += "\n" + m2[0];
297
- if (m2[1] != null) indented = true;
380
+ default: {
381
+ m2 = text1.exec(m1[0]);
382
+ if (m2 == null) {
383
+ break;
298
384
  }
299
- }
300
- applyIndent(0);
301
- break;
385
+ const indent = m2[1].length / 2;
386
+ const tx = m2[2].trim();
387
+ debug(indent, 't', m2[2]);
388
+ if (element.tag != null) {
389
+ applyIndent(indent);
390
+ fragment.html += tx;
391
+ }
392
+ else if (fragment.type === 'text' && fragment.html === '') {
393
+ fragment.html += tx;
394
+ }
395
+ else {
396
+ fragment.html += ' ' + tx;
397
+ }
398
+ textIndent = indent;
399
+ while ((m2 = refRe.exec(tx))) {
400
+ const start = fragment.html.length + m2.index - tx.length;
401
+ fragment.refs.push({
402
+ id: m2[1],
403
+ start,
404
+ end: start + m2[0].length,
405
+ });
406
+ }
407
+ break;
302
408
  }
303
- case "mount": {
304
- if (m2[3] == null) {
305
- throw new Error("Mount points must have a name");
306
- } else if (fragment.type !== "root") {
307
- throw new Error("Mounting is only allowed on a root element");
308
- }
309
- fragment.mountable = true;
310
- element.mount = m2[3].trim();
311
- break;
409
+ }
410
+ }
411
+ applyIndent(0);
412
+ const arr = Array.from(parsed.values());
413
+ function flatten(fragment) {
414
+ // work backwards so we don't change the html string length
415
+ // for the later replacements
416
+ for (let j = fragment.refs.length - 1; j >= 0; j--) {
417
+ const ref = fragment.refs[j];
418
+ if (claimed.has(ref.id) || !parsed.has(ref.id)) {
419
+ fragment.html = fragment.html.slice(0, ref.start)
420
+ + fragment.html.slice(ref.end);
421
+ }
422
+ else {
423
+ const child = flatten(parsed.get(ref.id));
424
+ fragment.html = fragment.html.slice(0, ref.start)
425
+ + child.html
426
+ + fragment.html.slice(ref.end);
427
+ if (child.type === 'embed') {
428
+ claimed.add(child.id);
429
+ }
312
430
  }
313
- }
314
- break;
315
431
  }
316
- }
317
- default: {
318
- m2 = text1.exec(m1[0]);
319
- if (m2 == null) {
320
- break;
432
+ fragment.refs = [];
433
+ return fragment;
434
+ }
435
+ if (root?.mountable) {
436
+ output.mountable = true;
437
+ output.tail = root.html;
438
+ output.mountPoints = root.mountPoints;
439
+ return output;
440
+ }
441
+ for (let i = 0; i < parsed.size + 1; i++) {
442
+ let fragment;
443
+ if (i === 0 && root == null) {
444
+ continue;
321
445
  }
322
- const indent = m2[1].length / 2;
323
- const tx = m2[2].trim();
324
- debug(indent, "t", m2[2]);
325
- if (element.tag != null) {
326
- applyIndent(indent);
327
- fragment.html += tx;
328
- } else if (fragment.type === "text" && fragment.html === "") {
329
- fragment.html += tx;
330
- } else {
331
- fragment.html += " " + tx;
446
+ else if (i === 0) {
447
+ fragment = root;
332
448
  }
333
- textIndent = indent;
334
- while (m2 = refRe.exec(tx)) {
335
- const start = fragment.html.length + m2.index - tx.length;
336
- fragment.refs.push({
337
- id: m2[1],
338
- start,
339
- end: start + m2[0].length
340
- });
449
+ else {
450
+ fragment = arr[i - 1];
341
451
  }
342
- break;
343
- }
344
- }
345
- }
346
- applyIndent(0);
347
- const arr = Array.from(parsed.values());
348
- function flatten(fragment2) {
349
- for (let j = fragment2.refs.length - 1; j >= 0; j--) {
350
- const ref = fragment2.refs[j];
351
- if (claimed.has(ref.id) || !parsed.has(ref.id)) {
352
- fragment2.html = fragment2.html.slice(0, ref.start) + fragment2.html.slice(ref.end);
353
- } else {
354
- const child = flatten(parsed.get(ref.id));
355
- fragment2.html = fragment2.html.slice(0, ref.start) + child.html + fragment2.html.slice(ref.end);
356
- if (child.type === "embed") {
357
- claimed.add(child.id);
452
+ if (fragment.refs.length === 0) {
453
+ continue;
358
454
  }
359
- }
455
+ flatten(fragment);
360
456
  }
361
- fragment2.refs = [];
362
- return fragment2;
363
- }
364
- if (root == null ? void 0 : root.mountable) {
365
- output.mountable = true;
366
- output.tail = root.html;
367
- output.mountPoints = root.mountPoints;
368
- return output;
369
- }
370
- for (let i = 0; i < parsed.size + 1; i++) {
371
- let fragment2;
372
- if (i === 0 && root == null) {
373
- continue;
374
- } else if (i === 0) {
375
- fragment2 = root;
376
- } else {
377
- fragment2 = arr[i - 1];
378
- }
379
- if (fragment2.refs.length === 0) {
380
- continue;
457
+ if (root?.html != null) {
458
+ output.root = root.html;
459
+ output.selector = `[data-lf-root]`;
381
460
  }
382
- flatten(fragment2);
383
- }
384
- if ((root == null ? void 0 : root.html) != null) {
385
- output.root = root.html;
386
- output.selector = `[data-lf-root]`;
387
- }
388
- for (let i = 0; i < arr.length; i++) {
389
- let selector;
390
- const fragment2 = arr[i];
391
- if (fragment2 == null || claimed.has(fragment2.id)) {
392
- continue;
393
- }
394
- if (fragment2.type === "embed") {
395
- selector = `[id=${fragment2.id}]`;
396
- } else if (fragment2.type === "bare") {
397
- selector = `[data-lf=${fragment2.id}]`;
398
- } else if (fragment2.type === "range") {
399
- selector = `[data-lf=${fragment2.id}]`;
461
+ for (let i = 0; i < arr.length; i++) {
462
+ let selector;
463
+ const fragment = arr[i];
464
+ if (fragment == null || claimed.has(fragment.id)) {
465
+ continue;
466
+ }
467
+ if (fragment.type === 'embed') {
468
+ selector = `[id=${fragment.id}]`;
469
+ }
470
+ else if (fragment.type === 'bare') {
471
+ selector = `[data-lf=${fragment.id}]`;
472
+ }
473
+ else if (fragment.type === 'range') {
474
+ selector = `[data-lf=${fragment.id}]`;
475
+ }
476
+ output.fragments[fragment.id] = {
477
+ id: fragment.id,
478
+ selector,
479
+ type: fragment.type,
480
+ html: fragment.html,
481
+ };
400
482
  }
401
- output.fragments[fragment2.id] = {
402
- id: fragment2.id,
403
- selector,
404
- type: fragment2.type,
405
- html: fragment2.html
406
- };
407
- }
408
- return output;
483
+ return output;
409
484
  }
410
485
  const templateRe = /(?:#{([\w][\w\-_]*)})|(?:#\[([\w][\w\-_]+)\])/g;
411
- export function processTemplate(template, args, getFragment) {
412
- var _a, _b;
413
- const lf = template.replace(templateRe, (_match, param, ref) => {
414
- if (ref != null) {
415
- const fragment = getFragment(ref);
416
- if (fragment == null) return "";
417
- return fragment;
418
- }
419
- return args[param] != null ? escape(args[param].toString()) : "";
420
- });
421
- return (_b = (_a = Object.values(longform(lf).fragments)[0]) == null ? void 0 : _a.html) != null ? _b : null;
486
+ /**
487
+ * Processes a client side Longform template to HTML fragment string.
488
+ *
489
+ * @param fragment - The fragment identifier.
490
+ * @param args - A record of template arguments.
491
+ * @param getFragment - A function which returns an already processed fragment's HTML string.
492
+ * @returns The processed template.
493
+ */
494
+ function processTemplate(template, args, getFragment) {
495
+ const lf = template.replace(templateRe, (_match, param, ref) => {
496
+ if (ref != null) {
497
+ const fragment = getFragment(ref);
498
+ if (fragment == null)
499
+ return '';
500
+ return fragment;
501
+ }
502
+ return args[param] != null ? escape(args[param].toString()) : '';
503
+ });
504
+ return Object.values(longform(lf).fragments)[0]?.html ?? null;
422
505
  }
506
+
507
+ export { longform, processTemplate };
423
508
  //# sourceMappingURL=longform.js.map