securemark 0.274.1 → 0.274.2
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/CHANGELOG.md +4 -0
- package/dist/index.js +58 -89
- package/package.json +1 -1
- package/src/parser/api/bind.test.ts +6 -6
- package/src/parser/api/parse.test.ts +3 -3
- package/src/parser/inline/media.ts +7 -19
- package/src/parser/processor/figure.ts +14 -53
- package/src/parser/processor/note.test.ts +23 -10
- package/src/parser/processor/note.ts +31 -33
- package/src/parser/util.ts +26 -0
package/CHANGELOG.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! securemark v0.274.
|
|
1
|
+
/*! securemark v0.274.2 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
|
|
2
2
|
(function webpackUniversalModuleDefinition(root, factory) {
|
|
3
3
|
if(typeof exports === 'object' && typeof module === 'object')
|
|
4
4
|
module.exports = factory(require("Prism"), require("DOMPurify"));
|
|
@@ -6645,6 +6645,7 @@ const link_1 = __webpack_require__(9628);
|
|
|
6645
6645
|
const html_1 = __webpack_require__(5994);
|
|
6646
6646
|
const htmlentity_1 = __webpack_require__(1562);
|
|
6647
6647
|
const source_1 = __webpack_require__(6743);
|
|
6648
|
+
const util_1 = __webpack_require__(9437);
|
|
6648
6649
|
const url_1 = __webpack_require__(2261);
|
|
6649
6650
|
const array_1 = __webpack_require__(8112);
|
|
6650
6651
|
const dom_1 = __webpack_require__(3252);
|
|
@@ -6692,32 +6693,19 @@ function sanitize(target, uri, alt) {
|
|
|
6692
6693
|
case 'http:':
|
|
6693
6694
|
case 'https:':
|
|
6694
6695
|
if (/\/\.\.?(?:\/|$)/.test('/' + uri.source.slice(0, uri.source.search(/[?#]|$/)))) {
|
|
6695
|
-
(0,
|
|
6696
|
-
class: void target.classList.add('invalid'),
|
|
6697
|
-
'data-invalid-syntax': 'media',
|
|
6698
|
-
'data-invalid-type': 'argument',
|
|
6699
|
-
'data-invalid-message': 'Dot-segments cannot be used in media paths; use subresource paths instead'
|
|
6700
|
-
});
|
|
6696
|
+
(0, util_1.markInvalid)(target, 'media', 'argument', 'Dot-segments cannot be used in media paths; use subresource paths instead');
|
|
6701
6697
|
return false;
|
|
6702
6698
|
}
|
|
6703
6699
|
break;
|
|
6704
6700
|
default:
|
|
6705
|
-
(0,
|
|
6706
|
-
class: void target.classList.add('invalid'),
|
|
6707
|
-
'data-invalid-syntax': 'media',
|
|
6708
|
-
'data-invalid-type': 'argument',
|
|
6709
|
-
'data-invalid-message': 'Invalid protocol'
|
|
6710
|
-
});
|
|
6701
|
+
(0, util_1.markInvalid)(target, 'media', 'argument', 'Invalid protocol');
|
|
6711
6702
|
return false;
|
|
6712
6703
|
}
|
|
6713
6704
|
if (alt.includes('\x1B')) {
|
|
6714
6705
|
(0, dom_1.define)(target, {
|
|
6715
|
-
class: void target.classList.add('invalid'),
|
|
6716
|
-
'data-invalid-syntax': 'media',
|
|
6717
|
-
'data-invalid-type': 'content',
|
|
6718
|
-
'data-invalid-message': `Cannot use invalid HTML entitiy "${alt.match(/&[0-9A-Za-z]+;/)[0]}"`,
|
|
6719
6706
|
alt: target.getAttribute('alt')?.replace(/\x1B/g, '')
|
|
6720
6707
|
});
|
|
6708
|
+
(0, util_1.markInvalid)(target, 'media', 'content', `Cannot use invalid HTML entitiy "${alt.match(/&[0-9A-Za-z]+;/)[0]}"`);
|
|
6721
6709
|
return false;
|
|
6722
6710
|
}
|
|
6723
6711
|
return true;
|
|
@@ -6924,6 +6912,7 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
6924
6912
|
}));
|
|
6925
6913
|
exports.figure = void 0;
|
|
6926
6914
|
const label_1 = __webpack_require__(466);
|
|
6915
|
+
const util_1 = __webpack_require__(9437);
|
|
6927
6916
|
const queue_1 = __webpack_require__(4934);
|
|
6928
6917
|
const array_1 = __webpack_require__(8112);
|
|
6929
6918
|
const dom_1 = __webpack_require__(3252);
|
|
@@ -6946,11 +6935,8 @@ function* figure(target, notes, opts = {}) {
|
|
|
6946
6935
|
const label = tagName === 'FIGURE' ? def.getAttribute('data-label') : `$-${increment(index, def)}`;
|
|
6947
6936
|
if (label.endsWith('-')) continue;
|
|
6948
6937
|
if (label.endsWith('-0')) {
|
|
6938
|
+
(0, util_1.markInvalid)(def, 'figure', 'argument', 'Invalid base index');
|
|
6949
6939
|
(0, dom_1.define)(def, {
|
|
6950
|
-
class: void def.classList.add('invalid'),
|
|
6951
|
-
'data-invalid-syntax': 'figure',
|
|
6952
|
-
'data-invalid-type': 'argument',
|
|
6953
|
-
'data-invalid-message': 'Invalid base index',
|
|
6954
6940
|
hidden: null
|
|
6955
6941
|
});
|
|
6956
6942
|
continue;
|
|
@@ -6958,32 +6944,23 @@ function* figure(target, notes, opts = {}) {
|
|
|
6958
6944
|
if (tagName === 'FIGURE' && label.endsWith('.0')) {
|
|
6959
6945
|
// $-x.x.0 is disabled.
|
|
6960
6946
|
if (label.lastIndexOf('.', label.length - 3) !== -1) {
|
|
6947
|
+
(0, util_1.markInvalid)(def, 'figure', 'argument', 'Base index must be $-x.0 format');
|
|
6961
6948
|
(0, dom_1.define)(def, {
|
|
6962
|
-
class: void def.classList.add('invalid'),
|
|
6963
|
-
'data-invalid-syntax': 'figure',
|
|
6964
|
-
'data-invalid-type': 'argument',
|
|
6965
|
-
'data-invalid-message': 'Base index must be $-x.0 format',
|
|
6966
6949
|
hidden: null
|
|
6967
6950
|
});
|
|
6968
6951
|
continue;
|
|
6969
6952
|
}
|
|
6970
6953
|
// $-x.0 after h1-h6.
|
|
6971
6954
|
if (!/^H[1-6]$/.test(def.previousElementSibling?.tagName ?? '')) {
|
|
6955
|
+
(0, util_1.markInvalid)(def, 'figure', 'position', messages.declaration);
|
|
6972
6956
|
(0, dom_1.define)(def, {
|
|
6973
|
-
class: void def.classList.add('invalid'),
|
|
6974
|
-
'data-invalid-syntax': 'figure',
|
|
6975
|
-
'data-invalid-type': 'position',
|
|
6976
|
-
'data-invalid-message': messages.declaration,
|
|
6977
6957
|
hidden: null
|
|
6978
6958
|
});
|
|
6979
6959
|
continue;
|
|
6980
6960
|
} else if (def.getAttribute('data-invalid-message') === messages.declaration) {
|
|
6961
|
+
(0, util_1.unmarkInvalid)(def);
|
|
6981
6962
|
(0, dom_1.define)(def, {
|
|
6982
|
-
|
|
6983
|
-
'data-invalid-syntax': null,
|
|
6984
|
-
'data-invalid-type': null,
|
|
6985
|
-
'data-invalid-message': null,
|
|
6986
|
-
hidden: ''
|
|
6963
|
+
hidden: null
|
|
6987
6964
|
});
|
|
6988
6965
|
}
|
|
6989
6966
|
}
|
|
@@ -7008,31 +6985,18 @@ function* figure(target, notes, opts = {}) {
|
|
|
7008
6985
|
if (labels.has(label)) {
|
|
7009
6986
|
if (def.classList.contains('invalid')) continue;
|
|
7010
6987
|
(0, dom_1.define)(def, {
|
|
7011
|
-
id: null
|
|
7012
|
-
class: void def.classList.add('invalid'),
|
|
7013
|
-
'data-invalid-syntax': 'figure',
|
|
7014
|
-
'data-invalid-type': 'argument',
|
|
7015
|
-
'data-invalid-message': messages.duplicate
|
|
6988
|
+
id: null
|
|
7016
6989
|
});
|
|
6990
|
+
(0, util_1.markInvalid)(def, 'figure', 'argument', messages.duplicate);
|
|
7017
6991
|
continue;
|
|
7018
6992
|
} else if (def.getAttribute('data-invalid-message') === messages.duplicate) {
|
|
7019
|
-
(0,
|
|
7020
|
-
class: void def.classList.remove('invalid'),
|
|
7021
|
-
'data-invalid-syntax': null,
|
|
7022
|
-
'data-invalid-type': null,
|
|
7023
|
-
'data-invalid-message': null
|
|
7024
|
-
});
|
|
6993
|
+
(0, util_1.unmarkInvalid)(def);
|
|
7025
6994
|
}
|
|
7026
6995
|
labels.add(label);
|
|
7027
6996
|
opts.id !== '' && def.setAttribute('id', `label:${opts.id ? `${opts.id}:` : ''}${label}`);
|
|
7028
6997
|
for (const ref of refs.take(label, Infinity)) {
|
|
7029
6998
|
if (ref.getAttribute('data-invalid-message') === messages.reference) {
|
|
7030
|
-
(0,
|
|
7031
|
-
class: void ref.classList.remove('invalid'),
|
|
7032
|
-
'data-invalid-syntax': null,
|
|
7033
|
-
'data-invalid-type': null,
|
|
7034
|
-
'data-invalid-message': null
|
|
7035
|
-
});
|
|
6999
|
+
(0, util_1.unmarkInvalid)(ref);
|
|
7036
7000
|
}
|
|
7037
7001
|
if (ref.hash.slice(1) === def.id && ref.innerText === figindex) continue;
|
|
7038
7002
|
yield (0, dom_1.define)(ref, opts.id !== '' ? {
|
|
@@ -7044,12 +7008,7 @@ function* figure(target, notes, opts = {}) {
|
|
|
7044
7008
|
}
|
|
7045
7009
|
for (const [, ref] of refs) {
|
|
7046
7010
|
if (opts.id !== '' && !ref.classList.contains('invalid')) {
|
|
7047
|
-
(0,
|
|
7048
|
-
class: void ref.classList.add('invalid'),
|
|
7049
|
-
'data-invalid-syntax': 'label',
|
|
7050
|
-
'data-invalid-type': 'reference',
|
|
7051
|
-
'data-invalid-message': messages.reference
|
|
7052
|
-
});
|
|
7011
|
+
(0, util_1.markInvalid)(ref, 'label', 'reference', messages.reference);
|
|
7053
7012
|
}
|
|
7054
7013
|
yield ref;
|
|
7055
7014
|
}
|
|
@@ -7091,6 +7050,7 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
7091
7050
|
}));
|
|
7092
7051
|
exports.reference = exports.annotation = exports.note = void 0;
|
|
7093
7052
|
const indexee_1 = __webpack_require__(1269);
|
|
7053
|
+
const util_1 = __webpack_require__(9437);
|
|
7094
7054
|
const dom_1 = __webpack_require__(3252);
|
|
7095
7055
|
function* note(target, notes, opts = {}, bottom = null) {
|
|
7096
7056
|
for (let es = target.querySelectorAll(`.annotations`), len = es.length, i = 0; i < len; ++i) {
|
|
@@ -7119,10 +7079,10 @@ function build(syntax, marker, splitter = '') {
|
|
|
7119
7079
|
const titles = new Map();
|
|
7120
7080
|
const defIndexes = new Map();
|
|
7121
7081
|
const refSubindexes = new Map();
|
|
7122
|
-
const defSubindexes = new Map();
|
|
7123
|
-
let refIndex = 0;
|
|
7082
|
+
const defSubindexes = splitter ? new Map() : undefined;
|
|
7124
7083
|
let total = 0;
|
|
7125
|
-
let
|
|
7084
|
+
let format;
|
|
7085
|
+
let refIndex = 0;
|
|
7126
7086
|
for (let len = refs.length, i = 0; i < len; ++i) {
|
|
7127
7087
|
const ref = refs[i];
|
|
7128
7088
|
if (ref.closest('[hidden]')) {
|
|
@@ -7146,41 +7106,31 @@ function build(syntax, marker, splitter = '') {
|
|
|
7146
7106
|
refSubindexes.set(identifier, refSubindex);
|
|
7147
7107
|
const refId = opts.id !== '' ? `${syntax}:${opts.id ?? ''}:ref:${identifier}:${refSubindex}` : undefined;
|
|
7148
7108
|
const initial = splitter ? !defs.has(identifier) : refSubindex === 1;
|
|
7149
|
-
const defSubindex = defSubindexes
|
|
7150
|
-
defSubindexes
|
|
7109
|
+
const defSubindex = defSubindexes?.get(identifier) + +initial || 1;
|
|
7110
|
+
initial && defSubindexes?.set(identifier, defSubindex);
|
|
7111
|
+
const defId = opts.id !== '' ? `${syntax}:${opts.id ?? ''}:def:${identifier}${splitter && `:${defSubindex}`}` : undefined;
|
|
7151
7112
|
const def = initial ? (0, dom_1.html)('li', {
|
|
7152
|
-
id:
|
|
7153
|
-
'data-marker':
|
|
7113
|
+
id: defId,
|
|
7114
|
+
'data-marker': note ? undefined : marker(total + defs.size + 1, abbr)
|
|
7154
7115
|
}, [(0, dom_1.define)(ref.firstElementChild.cloneNode(true), {
|
|
7155
7116
|
hidden: null
|
|
7156
7117
|
}), (0, dom_1.html)('sup')]) : defs.get(identifier);
|
|
7157
7118
|
initial && defs.set(identifier, def);
|
|
7158
7119
|
const defIndex = initial ? total + defs.size : defIndexes.get(def);
|
|
7159
7120
|
initial && defIndexes.set(def, defIndex);
|
|
7160
|
-
const defId = def.id || undefined;
|
|
7161
7121
|
const title = initial ? (0, indexee_1.text)(ref.firstElementChild) : titles.get(identifier);
|
|
7162
7122
|
initial && titles.set(identifier, title);
|
|
7163
|
-
|
|
7164
|
-
if (
|
|
7165
|
-
(
|
|
7166
|
-
|
|
7167
|
-
|
|
7168
|
-
|
|
7169
|
-
|
|
7170
|
-
|
|
7171
|
-
|
|
7172
|
-
(0, dom_1.define)(ref, {
|
|
7173
|
-
class: void ref.classList.remove('invalid'),
|
|
7174
|
-
'data-invalid-syntax': null,
|
|
7175
|
-
'data-invalid-type': null,
|
|
7176
|
-
'data-invalid-message': null
|
|
7177
|
-
});
|
|
7178
|
-
}
|
|
7179
|
-
if (!ref.firstElementChild.hasAttribute('hidden')) {
|
|
7180
|
-
ref.firstElementChild.setAttribute('hidden', '');
|
|
7181
|
-
} else {
|
|
7182
|
-
ref.lastChild?.remove();
|
|
7123
|
+
format ??= abbr ? 'abbr' : 'number';
|
|
7124
|
+
if (!ref.classList.contains('invalid')) {
|
|
7125
|
+
if (format === 'number' ? abbr : !abbr) {
|
|
7126
|
+
(0, util_1.markInvalid)(ref, syntax, 'format', 'Notation format must be consistent with numbers or abbreviations');
|
|
7127
|
+
}
|
|
7128
|
+
} else switch (ref.getAttribute('data-invalid-syntax')) {
|
|
7129
|
+
case 'format':
|
|
7130
|
+
case 'content':
|
|
7131
|
+
(0, util_1.unmarkInvalid)(ref);
|
|
7183
7132
|
}
|
|
7133
|
+
ref.firstElementChild.hasAttribute('hidden') ? ref.lastElementChild.remove() : ref.firstElementChild.setAttribute('hidden', '');
|
|
7184
7134
|
(0, dom_1.define)(ref, {
|
|
7185
7135
|
id: refId,
|
|
7186
7136
|
class: opts.id !== '' ? undefined : void ref.classList.add('disabled'),
|
|
@@ -7195,12 +7145,12 @@ function build(syntax, marker, splitter = '') {
|
|
|
7195
7145
|
yield ref.appendChild((0, dom_1.html)('a', {
|
|
7196
7146
|
href: refId && defId && `#${defId}`
|
|
7197
7147
|
}, marker(defIndex, abbr)));
|
|
7198
|
-
def.
|
|
7148
|
+
def.lastElementChild.appendChild((0, dom_1.html)('a', {
|
|
7199
7149
|
href: refId && `#${refId}`,
|
|
7200
7150
|
title: abbr && (0, indexee_1.text)((0, dom_1.frag)(ref.firstElementChild.cloneNode(true).childNodes)).trim() || undefined
|
|
7201
7151
|
}, `^${++refIndex}`));
|
|
7202
7152
|
}
|
|
7203
|
-
if (defs.size > 0
|
|
7153
|
+
if (note || defs.size > 0) {
|
|
7204
7154
|
yield* proc(defs, note ?? target.insertBefore((0, dom_1.html)('ol', {
|
|
7205
7155
|
class: `${syntax}s`
|
|
7206
7156
|
}), splitters[0] ?? bottom));
|
|
@@ -7586,7 +7536,7 @@ exports.unescsource = (0, combinator_1.creation)(1, false, ({
|
|
|
7586
7536
|
/***/ }),
|
|
7587
7537
|
|
|
7588
7538
|
/***/ 9437:
|
|
7589
|
-
/***/ ((__unused_webpack_module, exports) => {
|
|
7539
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
7590
7540
|
|
|
7591
7541
|
"use strict";
|
|
7592
7542
|
|
|
@@ -7594,7 +7544,26 @@ exports.unescsource = (0, combinator_1.creation)(1, false, ({
|
|
|
7594
7544
|
Object.defineProperty(exports, "__esModule", ({
|
|
7595
7545
|
value: true
|
|
7596
7546
|
}));
|
|
7597
|
-
exports.stringify = void 0;
|
|
7547
|
+
exports.stringify = exports.unmarkInvalid = exports.markInvalid = void 0;
|
|
7548
|
+
const dom_1 = __webpack_require__(3252);
|
|
7549
|
+
function markInvalid(el, syntax, type, message) {
|
|
7550
|
+
return (0, dom_1.define)(el, {
|
|
7551
|
+
class: void el.classList.add('invalid'),
|
|
7552
|
+
'data-invalid-syntax': syntax,
|
|
7553
|
+
'data-invalid-type': type,
|
|
7554
|
+
'data-invalid-message': message
|
|
7555
|
+
});
|
|
7556
|
+
}
|
|
7557
|
+
exports.markInvalid = markInvalid;
|
|
7558
|
+
function unmarkInvalid(el) {
|
|
7559
|
+
return (0, dom_1.define)(el, {
|
|
7560
|
+
class: void el.classList.remove('invalid'),
|
|
7561
|
+
'data-invalid-syntax': null,
|
|
7562
|
+
'data-invalid-type': null,
|
|
7563
|
+
'data-invalid-message': null
|
|
7564
|
+
});
|
|
7565
|
+
}
|
|
7566
|
+
exports.unmarkInvalid = unmarkInvalid;
|
|
7598
7567
|
function stringify(nodes) {
|
|
7599
7568
|
let acc = '';
|
|
7600
7569
|
for (let i = 0; i < nodes.length; ++i) {
|
package/package.json
CHANGED
|
@@ -194,34 +194,34 @@ describe('Unit: parser/api/bind', () => {
|
|
|
194
194
|
html('p', [
|
|
195
195
|
html('sup', { class: "reference", id: "reference::ref:1:1", title: "1" }, [
|
|
196
196
|
html('span', { hidden: '' }, '1'),
|
|
197
|
-
html('a', { href: "#reference::def:1
|
|
197
|
+
html('a', { href: "#reference::def:1" }, '[1]'),
|
|
198
198
|
]),
|
|
199
199
|
]).outerHTML,
|
|
200
200
|
html('p', [
|
|
201
201
|
html('sup', { class: "reference", id: "reference::ref:2:1", title: "2" }, [
|
|
202
202
|
html('span', { hidden: '' }, '2'),
|
|
203
|
-
html('a', { href: "#reference::def:2
|
|
203
|
+
html('a', { href: "#reference::def:2" }, '[2]'),
|
|
204
204
|
]),
|
|
205
205
|
]).outerHTML,
|
|
206
206
|
html('p', [
|
|
207
207
|
html('sup', { class: "reference", id: "reference::ref:3:1", title: "3" }, [
|
|
208
208
|
html('span', { hidden: '' }, '3'),
|
|
209
|
-
html('a', { href: "#reference::def:3
|
|
209
|
+
html('a', { href: "#reference::def:3" }, '[3]'),
|
|
210
210
|
]),
|
|
211
211
|
]).outerHTML,
|
|
212
212
|
]);
|
|
213
213
|
assert.deepStrictEqual(
|
|
214
214
|
cfgs.notes.references?.outerHTML,
|
|
215
215
|
html('ol', [
|
|
216
|
-
html('li', { id: 'reference::def:1
|
|
216
|
+
html('li', { id: 'reference::def:1' }, [
|
|
217
217
|
html('span', '1'),
|
|
218
218
|
html('sup', [html('a', { href: '#reference::ref:1:1' }, '^1')]),
|
|
219
219
|
]),
|
|
220
|
-
html('li', { id: 'reference::def:2
|
|
220
|
+
html('li', { id: 'reference::def:2' }, [
|
|
221
221
|
html('span', '2'),
|
|
222
222
|
html('sup', [html('a', { href: '#reference::ref:2:1' }, '^2')]),
|
|
223
223
|
]),
|
|
224
|
-
html('li', { id: 'reference::def:3
|
|
224
|
+
html('li', { id: 'reference::def:3' }, [
|
|
225
225
|
html('span', '3'),
|
|
226
226
|
html('sup', [html('a', { href: '#reference::ref:3:1' }, '^3')]),
|
|
227
227
|
]),
|
|
@@ -207,12 +207,12 @@ describe('Unit: parser/api/parse', () => {
|
|
|
207
207
|
[...parse('$-a\n$$\n$$\n\n(($-a[[^b]]))[[^b|$-a]]', { notes }).children].map(el => el.outerHTML),
|
|
208
208
|
[
|
|
209
209
|
'<figure data-type="math" data-label="$-a" data-group="$" data-number="1" id="label:$-a"><figcaption><span class="figindex">(1)</span><span class="figtext"></span></figcaption><div><div class="math" translate="no">$$\n$$</div></div></figure>',
|
|
210
|
-
'<p><sup class="annotation" id="annotation::ref:(1):1" title="(1)"><span hidden=""><a class="label" data-label="$-a" href="#label:$-a">(1)</a><sup class="reference" data-abbr="b"><span></span></sup></span><a href="#annotation::def:(1):1">*1</a></sup><sup class="reference" data-abbr="b" id="reference::ref:b:1" title="(1)"><span hidden=""><a class="label" data-label="$-a" href="#label:$-a">(1)</a></span><a href="#reference::def:b
|
|
211
|
-
'<ol class="annotations"><li id="annotation::def:(1):1" data-marker="*1"><span><a class="label" data-label="$-a" href="#label:$-a">(1)</a><sup class="reference" data-abbr="b" id="reference::ref:b:2" title="(1)"><span hidden=""></span><a href="#reference::def:b
|
|
210
|
+
'<p><sup class="annotation" id="annotation::ref:(1):1" title="(1)"><span hidden=""><a class="label" data-label="$-a" href="#label:$-a">(1)</a><sup class="reference" data-abbr="b"><span></span></sup></span><a href="#annotation::def:(1):1">*1</a></sup><sup class="reference" data-abbr="b" id="reference::ref:b:1" title="(1)"><span hidden=""><a class="label" data-label="$-a" href="#label:$-a">(1)</a></span><a href="#reference::def:b">[b]</a></sup></p>',
|
|
211
|
+
'<ol class="annotations"><li id="annotation::def:(1):1" data-marker="*1"><span><a class="label" data-label="$-a" href="#label:$-a">(1)</a><sup class="reference" data-abbr="b" id="reference::ref:b:2" title="(1)"><span hidden=""></span><a href="#reference::def:b">[b]</a></sup></span><sup><a href="#annotation::ref:(1):1">^1</a></sup></li></ol>',
|
|
212
212
|
]);
|
|
213
213
|
assert.deepStrictEqual(
|
|
214
214
|
notes.references.outerHTML,
|
|
215
|
-
'<ol><li id="reference::def:b
|
|
215
|
+
'<ol><li id="reference::def:b"><span><a class="label" data-label="$-a" href="#label:$-a">(1)</a></span><sup><a href="#reference::ref:b:1" title="(1)">^1</a><a href="#reference::ref:b:2">^2</a></sup></li></ol>');
|
|
216
216
|
});
|
|
217
217
|
|
|
218
218
|
it('normalize', () => {
|
|
@@ -5,6 +5,7 @@ import { attributes } from './html';
|
|
|
5
5
|
import { unsafehtmlentity } from './htmlentity';
|
|
6
6
|
import { txt, linebreak, str } from '../source';
|
|
7
7
|
import { Syntax, State } from '../context';
|
|
8
|
+
import { markInvalid } from '../util';
|
|
8
9
|
import { ReadonlyURL } from 'spica/url';
|
|
9
10
|
import { unshift, push } from 'spica/array';
|
|
10
11
|
import { html, define } from 'typed-dom/dom';
|
|
@@ -87,32 +88,19 @@ function sanitize(target: HTMLElement, uri: ReadonlyURL, alt: string): boolean {
|
|
|
87
88
|
case 'https:':
|
|
88
89
|
assert(uri.host);
|
|
89
90
|
if (/\/\.\.?(?:\/|$)/.test('/' + uri.source.slice(0, uri.source.search(/[?#]|$/)))) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
'data-invalid-syntax': 'media',
|
|
93
|
-
'data-invalid-type': 'argument',
|
|
94
|
-
'data-invalid-message': 'Dot-segments cannot be used in media paths; use subresource paths instead',
|
|
95
|
-
});
|
|
91
|
+
markInvalid(target, 'media', 'argument',
|
|
92
|
+
'Dot-segments cannot be used in media paths; use subresource paths instead');
|
|
96
93
|
return false;
|
|
97
94
|
}
|
|
98
95
|
break;
|
|
99
96
|
default:
|
|
100
|
-
|
|
101
|
-
class: void target.classList.add('invalid'),
|
|
102
|
-
'data-invalid-syntax': 'media',
|
|
103
|
-
'data-invalid-type': 'argument',
|
|
104
|
-
'data-invalid-message': 'Invalid protocol',
|
|
105
|
-
});
|
|
97
|
+
markInvalid(target, 'media', 'argument', 'Invalid protocol');
|
|
106
98
|
return false;
|
|
107
99
|
}
|
|
108
100
|
if (alt.includes('\x1B')) {
|
|
109
|
-
define(target, {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
'data-invalid-type': 'content',
|
|
113
|
-
'data-invalid-message': `Cannot use invalid HTML entitiy "${alt.match(/&[0-9A-Za-z]+;/)![0]}"`,
|
|
114
|
-
alt: target.getAttribute('alt')?.replace(/\x1B/g, ''),
|
|
115
|
-
});
|
|
101
|
+
define(target, { alt: target.getAttribute('alt')?.replace(/\x1B/g, '') });
|
|
102
|
+
markInvalid(target, 'media', 'content',
|
|
103
|
+
`Cannot use invalid HTML entitiy "${alt.match(/&[0-9A-Za-z]+;/)![0]}"`);
|
|
116
104
|
return false;
|
|
117
105
|
}
|
|
118
106
|
return true;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { number as calculate, isFixed } from '../inline/extension/label';
|
|
2
|
+
import { markInvalid, unmarkInvalid } from '../util';
|
|
2
3
|
import { MultiQueue } from 'spica/queue';
|
|
3
4
|
import { push } from 'spica/array';
|
|
4
5
|
import { define } from 'typed-dom/dom';
|
|
@@ -32,46 +33,26 @@ export function* figure(
|
|
|
32
33
|
: `$-${increment(index, def as HTMLHeadingElement)}`;
|
|
33
34
|
if (label.endsWith('-')) continue;
|
|
34
35
|
if (label.endsWith('-0')) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
'data-invalid-syntax': 'figure',
|
|
38
|
-
'data-invalid-type': 'argument',
|
|
39
|
-
'data-invalid-message': 'Invalid base index',
|
|
40
|
-
hidden: null,
|
|
41
|
-
});
|
|
36
|
+
markInvalid(def, 'figure', 'argument', 'Invalid base index');
|
|
37
|
+
define(def, { hidden: null });
|
|
42
38
|
continue;
|
|
43
39
|
}
|
|
44
40
|
if (tagName === 'FIGURE' && label.endsWith('.0')) {
|
|
45
41
|
// $-x.x.0 is disabled.
|
|
46
42
|
if (label.lastIndexOf('.', label.length - 3) !== -1) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
'data-invalid-syntax': 'figure',
|
|
50
|
-
'data-invalid-type': 'argument',
|
|
51
|
-
'data-invalid-message': 'Base index must be $-x.0 format',
|
|
52
|
-
hidden: null,
|
|
53
|
-
});
|
|
43
|
+
markInvalid(def, 'figure', 'argument', 'Base index must be $-x.0 format');
|
|
44
|
+
define(def, { hidden: null });
|
|
54
45
|
continue;
|
|
55
46
|
}
|
|
56
47
|
// $-x.0 after h1-h6.
|
|
57
48
|
if (!/^H[1-6]$/.test(def.previousElementSibling?.tagName ?? '')) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
'data-invalid-syntax': 'figure',
|
|
61
|
-
'data-invalid-type': 'position',
|
|
62
|
-
'data-invalid-message': messages.declaration,
|
|
63
|
-
hidden: null,
|
|
64
|
-
});
|
|
49
|
+
markInvalid(def, 'figure', 'position', messages.declaration);
|
|
50
|
+
define(def, { hidden: null });
|
|
65
51
|
continue;
|
|
66
52
|
}
|
|
67
53
|
else if (def.getAttribute('data-invalid-message') === messages.declaration) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
'data-invalid-syntax': null,
|
|
71
|
-
'data-invalid-type': null,
|
|
72
|
-
'data-invalid-message': null,
|
|
73
|
-
hidden: '',
|
|
74
|
-
});
|
|
54
|
+
unmarkInvalid(def);
|
|
55
|
+
define(def, { hidden: null });
|
|
75
56
|
}
|
|
76
57
|
}
|
|
77
58
|
const group = label.split('-', 1)[0];
|
|
@@ -120,33 +101,18 @@ export function* figure(
|
|
|
120
101
|
group === '$' ? figindex : `${figindex}. `);
|
|
121
102
|
if (labels.has(label)) {
|
|
122
103
|
if (def.classList.contains('invalid')) continue;
|
|
123
|
-
define(def, {
|
|
124
|
-
|
|
125
|
-
class: void def.classList.add('invalid'),
|
|
126
|
-
'data-invalid-syntax': 'figure',
|
|
127
|
-
'data-invalid-type': 'argument',
|
|
128
|
-
'data-invalid-message': messages.duplicate,
|
|
129
|
-
});
|
|
104
|
+
define(def, { id: null });
|
|
105
|
+
markInvalid(def, 'figure', 'argument', messages.duplicate);
|
|
130
106
|
continue;
|
|
131
107
|
}
|
|
132
108
|
else if (def.getAttribute('data-invalid-message') === messages.duplicate) {
|
|
133
|
-
|
|
134
|
-
class: void def.classList.remove('invalid'),
|
|
135
|
-
'data-invalid-syntax': null,
|
|
136
|
-
'data-invalid-type': null,
|
|
137
|
-
'data-invalid-message': null,
|
|
138
|
-
});
|
|
109
|
+
unmarkInvalid(def);
|
|
139
110
|
}
|
|
140
111
|
labels.add(label);
|
|
141
112
|
opts.id !== '' && def.setAttribute('id', `label:${opts.id ? `${opts.id}:` : ''}${label}`);
|
|
142
113
|
for (const ref of refs.take(label, Infinity)) {
|
|
143
114
|
if (ref.getAttribute('data-invalid-message') === messages.reference) {
|
|
144
|
-
|
|
145
|
-
class: void ref.classList.remove('invalid'),
|
|
146
|
-
'data-invalid-syntax': null,
|
|
147
|
-
'data-invalid-type': null,
|
|
148
|
-
'data-invalid-message': null,
|
|
149
|
-
});
|
|
115
|
+
unmarkInvalid(ref);
|
|
150
116
|
}
|
|
151
117
|
if (ref.hash.slice(1) === def.id && ref.innerText === figindex) continue;
|
|
152
118
|
yield define(ref,
|
|
@@ -156,12 +122,7 @@ export function* figure(
|
|
|
156
122
|
}
|
|
157
123
|
for (const [, ref] of refs) {
|
|
158
124
|
if (opts.id !== '' && !ref.classList.contains('invalid')) {
|
|
159
|
-
|
|
160
|
-
class: void ref.classList.add('invalid'),
|
|
161
|
-
'data-invalid-syntax': 'label',
|
|
162
|
-
'data-invalid-type': 'reference',
|
|
163
|
-
'data-invalid-message': messages.reference,
|
|
164
|
-
});
|
|
125
|
+
markInvalid(ref, 'label', 'reference', messages.reference);
|
|
165
126
|
}
|
|
166
127
|
yield ref;
|
|
167
128
|
}
|
|
@@ -162,7 +162,7 @@ describe('Unit: parser/processor/note', () => {
|
|
|
162
162
|
});
|
|
163
163
|
|
|
164
164
|
it('split', () => {
|
|
165
|
-
const target = parse('((1))\n\n## a\n\n((2))((1))((3))((2))');
|
|
165
|
+
const target = parse('((1))\n\n## a\n\n((2))((1))((3))((2))\n\n## b\n\n((2))');
|
|
166
166
|
for (let i = 0; i < 3; ++i) {
|
|
167
167
|
[...note(target)];
|
|
168
168
|
assert.deepStrictEqual(
|
|
@@ -216,6 +216,19 @@ describe('Unit: parser/processor/note', () => {
|
|
|
216
216
|
html('sup', [html('a', { href: '#annotation::ref:3:1' }, '^4')]),
|
|
217
217
|
]),
|
|
218
218
|
]).outerHTML,
|
|
219
|
+
html('h2', { id: 'index::b' }, 'b').outerHTML,
|
|
220
|
+
html('p', [
|
|
221
|
+
html('sup', { class: 'annotation', id: 'annotation::ref:2:3', title: '2' }, [
|
|
222
|
+
html('span', { hidden: '' }, '2'),
|
|
223
|
+
html('a', { href: '#annotation::def:2:2' }, '*5')
|
|
224
|
+
]),
|
|
225
|
+
]).outerHTML,
|
|
226
|
+
html('ol', { class: 'annotations' }, [
|
|
227
|
+
html('li', { id: 'annotation::def:2:2', 'data-marker': '*5' }, [
|
|
228
|
+
html('span', '2'),
|
|
229
|
+
html('sup', [html('a', { href: '#annotation::ref:2:3' }, '^6')]),
|
|
230
|
+
]),
|
|
231
|
+
]).outerHTML,
|
|
219
232
|
]);
|
|
220
233
|
}
|
|
221
234
|
});
|
|
@@ -260,14 +273,14 @@ describe('Unit: parser/processor/note', () => {
|
|
|
260
273
|
html('p', [
|
|
261
274
|
html('sup', { class: 'reference', id: 'reference::ref:a_b:1', title: 'a b' }, [
|
|
262
275
|
html('span', { hidden: '' }, 'a b'),
|
|
263
|
-
html('a', { href: '#reference::def:a_b
|
|
276
|
+
html('a', { href: '#reference::def:a_b' }, '[1]')
|
|
264
277
|
]),
|
|
265
278
|
]).outerHTML,
|
|
266
279
|
]);
|
|
267
280
|
assert.deepStrictEqual(
|
|
268
281
|
note.outerHTML,
|
|
269
282
|
html('ol', [
|
|
270
|
-
html('li', { id: 'reference::def:a_b
|
|
283
|
+
html('li', { id: 'reference::def:a_b' }, [
|
|
271
284
|
html('span', 'a b'),
|
|
272
285
|
html('sup', [html('a', { href: '#reference::ref:a_b:1' }, '^1')]),
|
|
273
286
|
]),
|
|
@@ -286,22 +299,22 @@ describe('Unit: parser/processor/note', () => {
|
|
|
286
299
|
html('p', [
|
|
287
300
|
html('sup', { class: 'reference', 'data-abbr': 'a', id: 'reference::ref:a:1', title: 'b' }, [
|
|
288
301
|
html('span', { hidden: '' }, 'b'),
|
|
289
|
-
html('a', { href: '#reference::def:a
|
|
302
|
+
html('a', { href: '#reference::def:a' }, '[a]')
|
|
290
303
|
]),
|
|
291
304
|
html('sup', { class: 'reference', 'data-abbr': 'a', id: 'reference::ref:a:2', title: 'b' }, [
|
|
292
305
|
html('span', { hidden: '' }),
|
|
293
|
-
html('a', { href: '#reference::def:a
|
|
306
|
+
html('a', { href: '#reference::def:a' }, '[a]')
|
|
294
307
|
]),
|
|
295
308
|
html('sup', { class: 'reference', 'data-abbr': 'a', id: 'reference::ref:a:3', title: 'b' }, [
|
|
296
309
|
html('span', { hidden: '' }),
|
|
297
|
-
html('a', { href: '#reference::def:a
|
|
310
|
+
html('a', { href: '#reference::def:a' }, '[a]')
|
|
298
311
|
]),
|
|
299
312
|
]).outerHTML,
|
|
300
313
|
]);
|
|
301
314
|
assert.deepStrictEqual(
|
|
302
315
|
note.outerHTML,
|
|
303
316
|
html('ol', [
|
|
304
|
-
html('li', { id: 'reference::def:a
|
|
317
|
+
html('li', { id: 'reference::def:a' }, [
|
|
305
318
|
html('span', 'b'),
|
|
306
319
|
html('sup', [
|
|
307
320
|
html('a', { href: '#reference::ref:a:1', title: 'b' }, '^1'),
|
|
@@ -334,7 +347,7 @@ describe('Unit: parser/processor/note', () => {
|
|
|
334
347
|
]),
|
|
335
348
|
html('sup', { class: 'reference', 'data-abbr': 'b', id: 'reference::ref:b:1', title: 'c' }, [
|
|
336
349
|
html('span', { hidden: '' }, 'c'),
|
|
337
|
-
html('a', { href: '#reference::def:b
|
|
350
|
+
html('a', { href: '#reference::def:b' }, '[b]')
|
|
338
351
|
]),
|
|
339
352
|
]).outerHTML,
|
|
340
353
|
html('ol', { class: 'annotations' }, [
|
|
@@ -343,7 +356,7 @@ describe('Unit: parser/processor/note', () => {
|
|
|
343
356
|
'a',
|
|
344
357
|
html('sup', { class: 'reference', 'data-abbr': 'b', id: 'reference::ref:b:2', title: 'c' }, [
|
|
345
358
|
html('span', { hidden: '' }),
|
|
346
|
-
html('a', { href: '#reference::def:b
|
|
359
|
+
html('a', { href: '#reference::def:b' }, '[b]')
|
|
347
360
|
]),
|
|
348
361
|
]),
|
|
349
362
|
html('sup', [html('a', { href: '#annotation::ref:a:1' }, '^1')])
|
|
@@ -353,7 +366,7 @@ describe('Unit: parser/processor/note', () => {
|
|
|
353
366
|
assert.deepStrictEqual(
|
|
354
367
|
note.outerHTML,
|
|
355
368
|
html('ol', [
|
|
356
|
-
html('li', { id: 'reference::def:b
|
|
369
|
+
html('li', { id: 'reference::def:b' }, [
|
|
357
370
|
html('span', 'c'),
|
|
358
371
|
html('sup', [
|
|
359
372
|
html('a', { href: '#reference::ref:b:1', title: 'c' }, '^1'),
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { identity, text } from '../inline/extension/indexee';
|
|
2
|
+
import { markInvalid, unmarkInvalid } from '../util';
|
|
2
3
|
import { frag, html, define } from 'typed-dom/dom';
|
|
3
4
|
|
|
4
5
|
export function* note(
|
|
5
6
|
target: ParentNode & Node,
|
|
6
|
-
notes?: {
|
|
7
|
+
notes?: {
|
|
8
|
+
readonly annotations?: HTMLOListElement;
|
|
9
|
+
readonly references: HTMLOListElement;
|
|
10
|
+
},
|
|
7
11
|
opts: { readonly id?: string; } = {},
|
|
8
12
|
bottom: Node | null = null,
|
|
9
13
|
): Generator<HTMLAnchorElement | HTMLLIElement | undefined, undefined, undefined> {
|
|
@@ -46,10 +50,10 @@ function build(
|
|
|
46
50
|
const titles = new Map<string, string>();
|
|
47
51
|
const defIndexes = new Map<HTMLLIElement, number>();
|
|
48
52
|
const refSubindexes = new Map<string, number>();
|
|
49
|
-
const defSubindexes = new Map<string, number>();
|
|
50
|
-
let refIndex = 0;
|
|
53
|
+
const defSubindexes = splitter ? new Map<string, number>() : undefined;
|
|
51
54
|
let total = 0;
|
|
52
|
-
let
|
|
55
|
+
let format: 'number' | 'abbr';
|
|
56
|
+
let refIndex = 0;
|
|
53
57
|
for (let len = refs.length, i = 0; i < len; ++i) {
|
|
54
58
|
const ref = refs[i];
|
|
55
59
|
if (ref.closest('[hidden]')) {
|
|
@@ -61,6 +65,7 @@ function build(
|
|
|
61
65
|
if (defs.size > 0) {
|
|
62
66
|
total += defs.size;
|
|
63
67
|
yield* proc(defs, target.insertBefore(html('ol', { class: `${syntax}s` }), splitters[0]));
|
|
68
|
+
assert(defs.size === 0);
|
|
64
69
|
}
|
|
65
70
|
else if (splitters.length % 100 === 0) {
|
|
66
71
|
yield;
|
|
@@ -77,51 +82,44 @@ function build(
|
|
|
77
82
|
const initial = splitter
|
|
78
83
|
? !defs.has(identifier)
|
|
79
84
|
: refSubindex === 1;
|
|
80
|
-
const defSubindex = defSubindexes
|
|
81
|
-
defSubindexes
|
|
85
|
+
const defSubindex = defSubindexes?.get(identifier)! + +initial || 1;
|
|
86
|
+
initial && defSubindexes?.set(identifier, defSubindex);
|
|
87
|
+
const defId = opts.id !== ''
|
|
88
|
+
? `${syntax}:${opts.id ?? ''}:def:${identifier}${splitter && `:${defSubindex}`}`
|
|
89
|
+
: undefined;
|
|
82
90
|
const def = initial
|
|
83
91
|
? html('li',
|
|
84
92
|
{
|
|
85
|
-
id:
|
|
86
|
-
'data-marker':
|
|
93
|
+
id: defId,
|
|
94
|
+
'data-marker': note ? undefined : marker(total + defs.size + 1, abbr),
|
|
87
95
|
},
|
|
88
96
|
[define(ref.firstElementChild!.cloneNode(true), { hidden: null }), html('sup')])
|
|
89
97
|
: defs.get(identifier)!;
|
|
90
98
|
initial && defs.set(identifier, def);
|
|
91
|
-
assert(def.
|
|
99
|
+
assert(def.lastElementChild?.matches('sup'));
|
|
92
100
|
const defIndex = initial
|
|
93
101
|
? total + defs.size
|
|
94
102
|
: defIndexes.get(def)!;
|
|
95
103
|
initial && defIndexes.set(def, defIndex);
|
|
96
|
-
const defId = def.id || undefined;
|
|
97
104
|
const title = initial
|
|
98
105
|
? text(ref.firstElementChild!)
|
|
99
106
|
: titles.get(identifier)!;
|
|
100
107
|
initial && titles.set(identifier, title);
|
|
101
108
|
assert(syntax !== 'annotation' || title);
|
|
102
|
-
|
|
103
|
-
if (
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
'data-invalid-type': 'style',
|
|
108
|
-
'data-invalid-message': `${syntax[0].toUpperCase() + syntax.slice(1)} style must be consistent`,
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
else if (ref.getAttribute('data-invalid-type') === 'style') {
|
|
112
|
-
define(ref, {
|
|
113
|
-
class: void ref.classList.remove('invalid'),
|
|
114
|
-
'data-invalid-syntax': null,
|
|
115
|
-
'data-invalid-type': null,
|
|
116
|
-
'data-invalid-message': null,
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
if (!ref.firstElementChild!.hasAttribute('hidden')) {
|
|
120
|
-
ref.firstElementChild!.setAttribute('hidden', '');
|
|
109
|
+
format ??= abbr ? 'abbr' : 'number';
|
|
110
|
+
if (!ref.classList.contains('invalid')) {
|
|
111
|
+
if (format === 'number' ? abbr : !abbr) {
|
|
112
|
+
markInvalid(ref, syntax, 'format', 'Notation format must be consistent with numbers or abbreviations');
|
|
113
|
+
}
|
|
121
114
|
}
|
|
122
|
-
else {
|
|
123
|
-
|
|
115
|
+
else switch (ref.getAttribute('data-invalid-syntax')) {
|
|
116
|
+
case 'format':
|
|
117
|
+
case 'content':
|
|
118
|
+
unmarkInvalid(ref);
|
|
124
119
|
}
|
|
120
|
+
ref.firstElementChild!.hasAttribute('hidden')
|
|
121
|
+
? ref.lastElementChild!.remove()
|
|
122
|
+
: ref.firstElementChild!.setAttribute('hidden', '');
|
|
125
123
|
define(ref, {
|
|
126
124
|
id: refId,
|
|
127
125
|
class: opts.id !== '' ? undefined : void ref.classList.add('disabled'),
|
|
@@ -135,7 +133,7 @@ function build(
|
|
|
135
133
|
});
|
|
136
134
|
yield ref.appendChild(html('a', { href: refId && defId && `#${defId}` }, marker(defIndex, abbr)));
|
|
137
135
|
assert(ref.title || ref.matches('.invalid'));
|
|
138
|
-
def.
|
|
136
|
+
def.lastElementChild!.appendChild(
|
|
139
137
|
html('a',
|
|
140
138
|
{
|
|
141
139
|
href: refId && `#${refId}`,
|
|
@@ -143,7 +141,7 @@ function build(
|
|
|
143
141
|
},
|
|
144
142
|
`^${++refIndex}`));
|
|
145
143
|
}
|
|
146
|
-
if (defs.size > 0
|
|
144
|
+
if (note || defs.size > 0) {
|
|
147
145
|
yield* proc(defs, note ?? target.insertBefore(html('ol', { class: `${syntax}s` }), splitters[0] ?? bottom));
|
|
148
146
|
}
|
|
149
147
|
return;
|
package/src/parser/util.ts
CHANGED
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
import { define } from 'typed-dom/dom';
|
|
2
|
+
|
|
3
|
+
export function markInvalid<T extends Element>(
|
|
4
|
+
el: T,
|
|
5
|
+
syntax: string,
|
|
6
|
+
type: string,
|
|
7
|
+
message: string,
|
|
8
|
+
): T {
|
|
9
|
+
assert(!message.endsWith('.'));
|
|
10
|
+
return define(el, {
|
|
11
|
+
class: void el.classList.add('invalid'),
|
|
12
|
+
'data-invalid-syntax': syntax,
|
|
13
|
+
'data-invalid-type': type,
|
|
14
|
+
'data-invalid-message': message,
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function unmarkInvalid<T extends Element>(el: T): T {
|
|
19
|
+
return define(el, {
|
|
20
|
+
class: void el.classList.remove('invalid'),
|
|
21
|
+
'data-invalid-syntax': null,
|
|
22
|
+
'data-invalid-type': null,
|
|
23
|
+
'data-invalid-message': null,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
1
27
|
export function stringify(nodes: readonly (HTMLElement | string)[]): string {
|
|
2
28
|
let acc = '';
|
|
3
29
|
for (let i = 0; i < nodes.length; ++i) {
|