pro-editor-schema 1.4.1 → 1.5.5-8

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/index.js CHANGED
@@ -50,6 +50,13 @@ __export(index_exports, {
50
50
  LAYOUT_USER_ATTRIBUTE: () => LAYOUT_USER_ATTRIBUTE,
51
51
  LEFT_INDENT_ATTRIBUTE: () => LEFT_INDENT_ATTRIBUTE,
52
52
  LINKEND_ATTRIBUTE: () => LINKEND_ATTRIBUTE,
53
+ LINK_BLOCKER_ROLES: () => LINK_BLOCKER_ROLES,
54
+ LINK_TO_CROSS_CHECK: () => LINK_TO_CROSS_CHECK,
55
+ POSSIBLE_WEBLINK_CLASS: () => POSSIBLE_WEBLINK_CLASS,
56
+ POSSIBLE_WEBLINK_EXCLUDE_SELECTORS: () => POSSIBLE_WEBLINK_EXCLUDE_SELECTORS,
57
+ REFERENCE_FIELD_SCHEMAS: () => REFERENCE_FIELD_SCHEMAS,
58
+ REFERENCE_PART_SELECTOR: () => REFERENCE_PART_SELECTOR,
59
+ REFERENCE_TYPE_SCHEMAS: () => REFERENCE_TYPE_SCHEMAS,
53
60
  RIGHT_INDENT_ATTRIBUTE: () => RIGHT_INDENT_ATTRIBUTE,
54
61
  SCHEMAS: () => SCHEMAS,
55
62
  SPACE_ABOVE_ATTRIBUTE: () => SPACE_ABOVE_ATTRIBUTE,
@@ -62,24 +69,49 @@ __export(index_exports, {
62
69
  TRACK_CHANGES_ATTR_DATA_TIME: () => TRACK_CHANGES_ATTR_DATA_TIME,
63
70
  TRACK_CHANGES_ATTR_DATA_USERID: () => TRACK_CHANGES_ATTR_DATA_USERID,
64
71
  TRACK_CHANGES_ATTR_DATA_USERNAME: () => TRACK_CHANGES_ATTR_DATA_USERNAME,
72
+ VALIDATION_IGNORED_ATTRIBUTE: () => VALIDATION_IGNORED_ATTRIBUTE,
65
73
  XMLID_ATTRIBUTE: () => XMLID_ATTRIBUTE,
74
+ clearWeblinkMatches: () => clearWeblinkMatches,
66
75
  closestElementBySchema: () => closestElementBySchema,
67
76
  createElement: () => createElement,
77
+ extractFootnoteNumber: () => extractFootnoteNumber,
68
78
  findAttributeDefinitionByName: () => findAttributeDefinitionByName,
79
+ findElementLinkedTo: () => findElementLinkedTo,
80
+ findReferenceFieldByElement: () => findReferenceFieldByElement,
81
+ findReferenceTypeSchemaByElement: () => findReferenceTypeSchemaByElement,
69
82
  findSchemaByCode: () => findSchemaByCode,
70
83
  findSchemaByElement: () => findSchemaByElement,
71
84
  getAdjacentElement: () => getAdjacentElement,
72
85
  getAttributeName: () => getAttributeName,
86
+ getEffectiveChildElements: () => getEffectiveChildElements,
73
87
  getElementLinks: () => getElementLinks,
88
+ getPossibleWeblinks: () => getPossibleWeblinks,
89
+ getReferenceFieldElements: () => getReferenceFieldElements,
90
+ getReferenceParts: () => getReferenceParts,
91
+ getReferenceStructureIssueElements: () => getReferenceStructureIssueElements,
74
92
  getStore: () => getStore,
75
93
  isAttributeRestricted: () => isAttributeRestricted,
76
94
  isDeletedElement: () => isDeletedElement,
77
95
  isIgnoredAttribute: () => isIgnoredAttribute,
78
96
  isIgnoredElement: () => isIgnoredElement,
79
97
  isTrackChangesSchema: () => isTrackChangesSchema,
98
+ markPossibleWeblinks: () => markPossibleWeblinks,
80
99
  queryAllElementsBySchema: () => queryAllElementsBySchema,
81
100
  queryElementBySchema: () => queryElementBySchema,
82
- validateXml: () => validateXml
101
+ validateAttributes: () => validateAttributes,
102
+ validateConsecutiveFootnoteCues: () => validateConsecutiveFootnoteCues,
103
+ validateConsecutiveFootnotes: () => validateConsecutiveFootnotes,
104
+ validateElementAgainstSchema: () => validateElementAgainstSchema,
105
+ validateElementToLinkTo: () => validateElementToLinkTo,
106
+ validateFootnoteNumber: () => validateFootnoteNumber,
107
+ validateHierarchy: () => validateHierarchy,
108
+ validateLinkend: () => validateLinkend,
109
+ validateOlink: () => validateOlink,
110
+ validatePossibleWeblinks: () => validatePossibleWeblinks,
111
+ validatePossibleWeblinksSteps: () => validatePossibleWeblinksSteps,
112
+ validateReferenceStructure: () => validateReferenceStructure,
113
+ validateXml: () => validateXml,
114
+ validateXmlAsync: () => validateXmlAsync
83
115
  });
84
116
  module.exports = __toCommonJS(index_exports);
85
117
 
@@ -102,6 +134,7 @@ var FIGURE_PLACEMENT_ATTRIBUTE = "data-figure-placement";
102
134
  var LAYOUT_CELL_WIDTH_ATTRIBUTE = "data-cell-width";
103
135
  var LAYOUT_TABLE_ORIENTATION_ATTRIBUTE = "data-table-orientation";
104
136
  var LAYOUT_TABLE_PLACEMENT_ATTRIBUTE = "data-table-placement";
137
+ var VALIDATION_IGNORED_ATTRIBUTE = "data-validation-ignored";
105
138
  var LAYOUT_ATTRIBUTES = [
106
139
  ALIGNMENT_ATTRIBUTE,
107
140
  LEFT_INDENT_ATTRIBUTE,
@@ -231,7 +264,7 @@ var EMPHASIS_SCHEMA = createSchema({
231
264
  ...TRACK_CHANGES_ATTRS,
232
265
  {
233
266
  name: "role",
234
- values: ["lowercase", "uppercase", "initialcaps"],
267
+ values: ["lowercase", "uppercase", "initialcaps", "Non breaking space"],
235
268
  defaultValue: "lowercase"
236
269
  }
237
270
  ],
@@ -731,6 +764,27 @@ var POEM_TAG = "POEM";
731
764
  var BIBLIOMIXED_TAG = "BIBLIOMIXED";
732
765
  var REFERENCE_BIBLIOGRAPHY_TAG = "BIBLIOGRAPHY";
733
766
  var BIBLIODIV_TAG = "BIBLIODIV";
767
+ var BIBLIOMSET_TAG = "BIBLIOMSET";
768
+ var EDITOR_TAG = "EDITOR";
769
+ var OTHERCREDIT_TAG = "OTHERCREDIT";
770
+ var TRANSLATOR_TAG = "TRANSLATOR";
771
+ var COLLAB_TAG = "COLLAB";
772
+ var PUBDATE_TAG = "PUBDATE";
773
+ var DATE_TAG = "DATE";
774
+ var PUBLISHERNAME_TAG = "PUBLISHERNAME";
775
+ var ADDRESS_TAG = "ADDRESS";
776
+ var CITY_TAG = "CITY";
777
+ var VOLUMENUM_TAG = "VOLUMENUM";
778
+ var ISSUENUM_TAG = "ISSUENUM";
779
+ var PAGENUMS_TAG = "PAGENUMS";
780
+ var PAGENUM_TAG = "PAGENUM";
781
+ var EDITION_TAG = "EDITION";
782
+ var PUB_ID_TAG = "PUB-ID";
783
+ var BIBLIOID_TAG = "BIBLIOID";
784
+ var BIBLIOMISC_TAG = "BIBLIOMISC";
785
+ var CONFGROUP_TAG = "CONFGROUP";
786
+ var CONFTITLE_TAG = "CONFTITLE";
787
+ var CONFDATES_TAG = "CONFDATES";
734
788
  var MATHPHRASE_TAG = "MATHPHRASE";
735
789
  var MATH_TAG = "MATH";
736
790
  var MERROR_TAG = "MERROR";
@@ -951,7 +1005,8 @@ var EQUATION_SCHEMA = createSchema({
951
1005
  ],
952
1006
  allowedChildrenCodes: [
953
1007
  { code: "mathphrase", required: true },
954
- { code: "caption1", required: false }
1008
+ { code: "caption1", required: false },
1009
+ { code: "tag", required: false }
955
1010
  ]
956
1011
  });
957
1012
 
@@ -1876,6 +1931,82 @@ var TABLE_SCHEMA = createSchema({
1876
1931
  ]
1877
1932
  });
1878
1933
 
1934
+ // src/schema/elementSchemas/elements/heading.ts
1935
+ var HEADING_LEVEL = ["H0", "H1", "H2", "H3", "H4", "H5", "H6"];
1936
+ var HEADING_ROLES = [...HEADING_LEVEL, "vignette_group"];
1937
+ var HEADING_SCHEMA = createSchema({
1938
+ code: "heading",
1939
+ kind: "element",
1940
+ tag: SECTION_TAG,
1941
+ matchesElement: (element) => {
1942
+ const role = element.getAttribute("role");
1943
+ if (!role) return false;
1944
+ return HEADING_ROLES.includes(role);
1945
+ },
1946
+ requiredAttributes: [
1947
+ ...ID_ATTRS,
1948
+ "xmlid",
1949
+ {
1950
+ name: "role",
1951
+ values: HEADING_ROLES,
1952
+ defaultValue: "H1"
1953
+ }
1954
+ ],
1955
+ optionalAttributes: [...TRACK_CHANGES_ATTRS],
1956
+ defaultChildCode: "para",
1957
+ allowedChildrenCodes: [
1958
+ { code: "title1", required: false },
1959
+ { code: "label1", required: false },
1960
+ { code: "para", required: false },
1961
+ { code: "subtitle1", required: false },
1962
+ { code: "sidebar", required: false },
1963
+ { code: "epigraph", required: false },
1964
+ { code: "blockquote", required: false },
1965
+ { code: "ul", required: false },
1966
+ { code: "ol", required: false },
1967
+ { code: "poem", required: false },
1968
+ { code: "dialogue", required: false },
1969
+ { code: "appendix", required: false },
1970
+ { code: "table1", required: false },
1971
+ { code: "figure1", required: false },
1972
+ { code: "heading", required: false },
1973
+ { code: "footnoteSection", required: false },
1974
+ { code: "info1", required: false },
1975
+ { code: "equation", required: false }
1976
+ ]
1977
+ });
1978
+
1979
+ // src/schema/elementSchemas/elements/box.ts
1980
+ var BOX_LEVEL = ["box1", "box2", "box3", "box4", "box5"];
1981
+ var BOX_SCHEMA = createSchema({
1982
+ code: "sidebar",
1983
+ kind: "element",
1984
+ tag: SIDEBAR_TAG,
1985
+ requiredAttributes: [
1986
+ ...ID_ATTRS,
1987
+ {
1988
+ name: "status",
1989
+ values: BOX_LEVEL,
1990
+ defaultValue: "box1"
1991
+ }
1992
+ ],
1993
+ optionalAttributes: [
1994
+ ...TRACK_CHANGES_ATTRS,
1995
+ "xmlid",
1996
+ {
1997
+ name: "role",
1998
+ values: ["add-element", "change-para-box"],
1999
+ defaultValue: "add-element"
2000
+ }
2001
+ ],
2002
+ defaultChildCode: "para",
2003
+ allowedChildrenCodes: [
2004
+ { code: "para", required: false },
2005
+ { code: "title1", required: false },
2006
+ { code: "sidebar", required: false }
2007
+ ]
2008
+ });
2009
+
1879
2010
  // src/schema/elementSchemas/elements/title.ts
1880
2011
  var TITLE_SCHEMA = createSchema({
1881
2012
  code: "title1",
@@ -1893,7 +2024,7 @@ var TITLE_SCHEMA = createSchema({
1893
2024
  },
1894
2025
  {
1895
2026
  name: "title",
1896
- values: ["H1", "H2", "H3", "H4", "H5", "H6", "foot_note"],
2027
+ values: [...HEADING_LEVEL, ...BOX_LEVEL, "foot_note"],
1897
2028
  defaultValue: "H1"
1898
2029
  }
1899
2030
  ],
@@ -1971,36 +2102,8 @@ var BLOCKQUOTE_SCHEMA = createSchema({
1971
2102
  { code: "ul", required: false },
1972
2103
  { code: "ol", required: false },
1973
2104
  { code: "sidebar", required: false },
1974
- { code: "source1", required: false }
1975
- ]
1976
- });
1977
-
1978
- // src/schema/elementSchemas/elements/box.ts
1979
- var BOX_SCHEMA = createSchema({
1980
- code: "sidebar",
1981
- kind: "element",
1982
- tag: SIDEBAR_TAG,
1983
- requiredAttributes: [
1984
- ...ID_ATTRS,
1985
- {
1986
- name: "status",
1987
- values: ["box1", "box2", "box3", "box4", "box5"],
1988
- defaultValue: "box1"
1989
- }
1990
- ],
1991
- optionalAttributes: [
1992
- ...TRACK_CHANGES_ATTRS,
1993
- "xmlid",
1994
- {
1995
- name: "role",
1996
- values: ["add-element", "change-para-box"],
1997
- defaultValue: "add-element"
1998
- }
1999
- ],
2000
- defaultChildCode: "para",
2001
- allowedChildrenCodes: [
2002
- { code: "para", required: false },
2003
- { code: "title1", required: false }
2105
+ { code: "source1", required: false },
2106
+ { code: "tag", required: false }
2004
2107
  ]
2005
2108
  });
2006
2109
 
@@ -2057,7 +2160,10 @@ var EPIGRAPH_SCHEMA = createSchema({
2057
2160
  }
2058
2161
  ],
2059
2162
  defaultChildCode: "para",
2060
- allowedChildrenCodes: [{ code: "para", required: false }]
2163
+ allowedChildrenCodes: [
2164
+ { code: "para", required: false },
2165
+ { code: "tag", required: false }
2166
+ ]
2061
2167
  });
2062
2168
 
2063
2169
  // src/schema/elementSchemas/elements/footnoteSection.ts
@@ -2087,51 +2193,6 @@ var FOOTNOTE_SECTION_SCHEMA = createSchema({
2087
2193
  ]
2088
2194
  });
2089
2195
 
2090
- // src/schema/elementSchemas/elements/heading.ts
2091
- var HEADING_LEVEL = ["H0", "H1", "H2", "H3", "H4", "H5", "H6"];
2092
- var HEADING_ROLES = [...HEADING_LEVEL, "vignette_group"];
2093
- var HEADING_SCHEMA = createSchema({
2094
- code: "heading",
2095
- kind: "element",
2096
- tag: SECTION_TAG,
2097
- matchesElement: (element) => {
2098
- const role = element.getAttribute("role");
2099
- if (!role) return false;
2100
- return HEADING_ROLES.includes(role);
2101
- },
2102
- requiredAttributes: [
2103
- ...ID_ATTRS,
2104
- "xmlid",
2105
- {
2106
- name: "role",
2107
- values: HEADING_ROLES,
2108
- defaultValue: "H1"
2109
- }
2110
- ],
2111
- optionalAttributes: [...TRACK_CHANGES_ATTRS],
2112
- defaultChildCode: "para",
2113
- allowedChildrenCodes: [
2114
- { code: "title1", required: false },
2115
- { code: "label1", required: false },
2116
- { code: "para", required: false },
2117
- { code: "subtitle1", required: false },
2118
- { code: "sidebar", required: false },
2119
- { code: "epigraph", required: false },
2120
- { code: "blockquote", required: false },
2121
- { code: "ul", required: false },
2122
- { code: "ol", required: false },
2123
- { code: "poem", required: false },
2124
- { code: "dialogue", required: false },
2125
- { code: "appendix", required: false },
2126
- { code: "table1", required: false },
2127
- { code: "figure1", required: false },
2128
- { code: "heading", required: false },
2129
- { code: "footnoteSection", required: false },
2130
- { code: "info1", required: false },
2131
- { code: "equation", required: false }
2132
- ]
2133
- });
2134
-
2135
2196
  // src/schema/elementSchemas/elements/info.ts
2136
2197
  var INFO_SCHEMA = createSchema({
2137
2198
  code: "info1",
@@ -2176,28 +2237,6 @@ var MATHPHRASE_SCHEMA = createSchema({
2176
2237
  allowedChildrenCodes: [{ code: MATH_SCHEMA.code, required: true }]
2177
2238
  });
2178
2239
 
2179
- // src/schema/elementSchemas/elements/reference/bibliodiv.ts
2180
- var BIBLIODIV_SCHEMA = createSchema({
2181
- code: "bibliodiv",
2182
- kind: "element",
2183
- tag: BIBLIODIV_TAG,
2184
- requiredAttributes: [
2185
- ...ID_ATTRS,
2186
- {
2187
- name: "role",
2188
- values: ["H1", "H2", "H3", "H4", "H5", "H6"],
2189
- defaultValue: "H1"
2190
- }
2191
- ],
2192
- optionalAttributes: [],
2193
- allowedChildrenCodes: [
2194
- { code: "bibliodiv", required: false },
2195
- { code: "referenceBibliomixed", required: false },
2196
- { code: "para", required: false },
2197
- { code: "title1", required: false }
2198
- ]
2199
- });
2200
-
2201
2240
  // src/schema/elementSchemas/elements/reference/bibliography.ts
2202
2241
  var REFERENCE_BIBLIOGRAPHY_SCHEMA = createSchema({
2203
2242
  code: "referenceBibliography",
@@ -2226,6 +2265,31 @@ var REFERENCE_BIBLIOGRAPHY_SCHEMA = createSchema({
2226
2265
  ]
2227
2266
  });
2228
2267
 
2268
+ // src/schema/shared/allowedReferenceChildren.ts
2269
+ var REFERENCE_PART_CODES_ALLOWED_CHILDREN = [
2270
+ { code: "author", required: false },
2271
+ { code: "editor", required: false },
2272
+ { code: "othercredit", required: false },
2273
+ { code: "translator", required: false },
2274
+ { code: "collab", required: false },
2275
+ { code: "title1", required: false },
2276
+ { code: "pubdate", required: false },
2277
+ { code: "date", required: false },
2278
+ { code: "publishername", required: false },
2279
+ { code: "orgname", required: false },
2280
+ { code: "address", required: false },
2281
+ { code: "volumenum", required: false },
2282
+ { code: "issuenum", required: false },
2283
+ { code: "pagenums", required: false },
2284
+ { code: "pagenum", required: false },
2285
+ { code: "edition", required: false },
2286
+ { code: "link", required: false },
2287
+ { code: "pubId", required: false },
2288
+ { code: "biblioid", required: false },
2289
+ { code: "bibliomisc", required: false },
2290
+ { code: "confgroup", required: false }
2291
+ ];
2292
+
2229
2293
  // src/schema/elementSchemas/elements/reference/bibliomixed.ts
2230
2294
  var BIBLIOMIXED_SCHEMA = createSchema({
2231
2295
  code: "referenceBibliomixed",
@@ -2237,82 +2301,390 @@ var BIBLIOMIXED_SCHEMA = createSchema({
2237
2301
  TRACK_CHANGES_ATTR_DATA_USERID,
2238
2302
  TRACK_CHANGES_ATTR_DATA_DATE
2239
2303
  ],
2240
- allowedChildrenCodes: []
2304
+ allowedChildrenCodes: [
2305
+ { code: "bibliomset", required: false },
2306
+ ...REFERENCE_PART_CODES_ALLOWED_CHILDREN,
2307
+ ...ATOM_CODES_ALLOWED_CHILDREN
2308
+ ]
2241
2309
  });
2242
2310
 
2243
- // src/schema/elementSchemas/elements/index.ts
2244
- var ELEMENT_SCHEMAS = {
2245
- bibliodiv: BIBLIODIV_SCHEMA,
2246
- referenceBibliography: REFERENCE_BIBLIOGRAPHY_SCHEMA,
2247
- referenceBibliomixed: BIBLIOMIXED_SCHEMA,
2248
- para: PARA_SCHEMA,
2249
- title1: TITLE_SCHEMA,
2250
- footnote: FOOTNOTE_SCHEMA,
2251
- footnoteno: FOOTNOTE_NUMBER_SCHEMA,
2252
- olink: OLINK_SCHEMA,
2253
- firstname: FIRSTNAME_SCHEMA,
2254
- surname: SURNAME_SCHEMA,
2255
- honorific: HONORIFIC_SCHEMA,
2256
- orgname: ORGNAME_SCHEMA,
2257
- email: EMAIL_SCHEMA,
2258
- org: ORG_SCHEMA,
2259
- degrees: DEGREES_SCHEMA,
2260
- dialogue: DIALOGUE_SCHEMA,
2261
- line: LINE_SCHEMA,
2262
- linegroup: LINE_GROUP_SCHEMA,
2263
- speaker: SPEAKER_SCHEMA,
2264
- equation: EQUATION_SCHEMA,
2265
- math: MATH_SCHEMA,
2266
- mathphrase: MATHPHRASE_SCHEMA,
2267
- merror: MERROR_SCHEMA,
2268
- mfrac: MFRAC_SCHEMA,
2269
- mi: MI_SCHEMA,
2270
- mmultiscripts: MMULTISCRIPTS_SCHEMA,
2271
- mn: MN_SCHEMA,
2272
- mo: MO_SCHEMA,
2273
- mover: MOVER_SCHEMA,
2274
- mpadded: MPADDED_SCHEMA,
2275
- mphantom: MPHANTOM_SCHEMA,
2276
- mprescripts: MPRESCRIPTS_SCHEMA,
2277
- mroot: MROOT_SCHEMA,
2278
- mrow: MROW_SCHEMA,
2279
- ms: MS_SCHEMA,
2280
- mspace: MSPACE_SCHEMA,
2281
- msqrt: MSQRT_SCHEMA,
2282
- mstyle: MSTYLE_SCHEMA,
2283
- msub: MSUB_SCHEMA,
2284
- msubsup: MSUBSUP_SCHEMA,
2285
- msup: MSUP_SCHEMA,
2286
- mtable: MTABLE_SCHEMA,
2287
- mtd: MTD_SCHEMA,
2288
- mtext: MTEXT_SCHEMA,
2289
- mtr: MTR_SCHEMA,
2290
- munder: MUNDER_SCHEMA,
2291
- munderover: MUNDEROVER_SCHEMA,
2292
- img: IMG_SCHEMA,
2293
- alttext: ALTTEXT_SCHEMA,
2294
- imageobject: IMAGEOBJECT_SCHEMA,
2295
- mediaobject: MEDIAOBJECT_SCHEMA,
2296
- caption1: CAPTION_SCHEMA,
2297
- figsource: FIGSOURCE_SCHEMA,
2298
- fignote: FIGNOTE_SCHEMA,
2299
- figure1: FIGURE_SCHEMA,
2300
- informalfigure: INFORMALFIGURE_SCHEMA,
2301
- keywordset: KEYWORDSET_SCHEMA,
2302
- keyword: KEYWORD_SCHEMA,
2303
- punc: PUNC_SCHEMA,
2304
- label1: LABEL_SCHEMA,
2305
- li: LI_SCHEMA,
2306
- ol: OL_SCHEMA,
2307
- ul: UL_SCHEMA,
2308
- token: TOKEN_SCHEMA,
2309
- tag: TAG_SCHEMA,
2310
- lrh: LRH_SCHEMA,
2311
- rrh: RRH_SCHEMA,
2312
- source1: SOURCE_SCHEMA,
2313
- subtitle1: SUBTITLE_SCHEMA,
2314
- table1: TABLE_SCHEMA,
2315
- tgroup: TGROUP_SCHEMA,
2311
+ // src/schema/elementSchemas/elements/reference/bibliodiv.ts
2312
+ var BIBLIODIV_SCHEMA = createSchema({
2313
+ code: "bibliodiv",
2314
+ kind: "element",
2315
+ tag: BIBLIODIV_TAG,
2316
+ requiredAttributes: [
2317
+ ...ID_ATTRS,
2318
+ "role"
2319
+ ],
2320
+ optionalAttributes: [],
2321
+ allowedChildrenCodes: [
2322
+ { code: "bibliodiv", required: false },
2323
+ { code: "referenceBibliomixed", required: false },
2324
+ { code: "para", required: false },
2325
+ { code: "title1", required: false }
2326
+ ]
2327
+ });
2328
+
2329
+ // src/schema/elementSchemas/elements/reference/bibliomset.ts
2330
+ var CONTAINER_BIBLIOMSET_RELATIONS = ["book", "journal"];
2331
+ var PART_BIBLIOMSET_RELATION = "part";
2332
+ var BIBLIOMSET_SCHEMA = createSchema({
2333
+ code: "bibliomset",
2334
+ kind: "element",
2335
+ tag: BIBLIOMSET_TAG,
2336
+ requiredAttributes: [
2337
+ {
2338
+ name: "relation",
2339
+ values: [
2340
+ PART_BIBLIOMSET_RELATION,
2341
+ "article",
2342
+ ...CONTAINER_BIBLIOMSET_RELATIONS
2343
+ ],
2344
+ defaultValue: PART_BIBLIOMSET_RELATION
2345
+ }
2346
+ ],
2347
+ optionalAttributes: [...ID_ATTRS],
2348
+ allowedChildrenCodes: [
2349
+ ...REFERENCE_PART_CODES_ALLOWED_CHILDREN,
2350
+ ...ATOM_CODES_ALLOWED_CHILDREN
2351
+ ]
2352
+ });
2353
+
2354
+ // src/schema/elementSchemas/elements/reference/editor.ts
2355
+ var EDITOR_SCHEMA = createSchema({
2356
+ code: "editor",
2357
+ kind: "element",
2358
+ tag: EDITOR_TAG,
2359
+ requiredAttributes: [],
2360
+ optionalAttributes: [...ID_ATTRS],
2361
+ allowedChildrenCodes: [
2362
+ { code: "personname", required: false },
2363
+ { code: "orgname", required: false },
2364
+ ...ATOM_CODES_ALLOWED_CHILDREN
2365
+ ]
2366
+ });
2367
+
2368
+ // src/schema/elementSchemas/elements/reference/othercredit.ts
2369
+ var OTHERCREDIT_SCHEMA = createSchema({
2370
+ code: "othercredit",
2371
+ kind: "element",
2372
+ tag: OTHERCREDIT_TAG,
2373
+ requiredAttributes: [],
2374
+ optionalAttributes: [...ID_ATTRS, "class", "otherclass"],
2375
+ allowedChildrenCodes: [
2376
+ { code: "personname", required: false },
2377
+ { code: "orgname", required: false },
2378
+ ...ATOM_CODES_ALLOWED_CHILDREN
2379
+ ]
2380
+ });
2381
+
2382
+ // src/schema/elementSchemas/elements/reference/translator.ts
2383
+ var TRANSLATOR_SCHEMA = createSchema({
2384
+ code: "translator",
2385
+ kind: "element",
2386
+ tag: TRANSLATOR_TAG,
2387
+ requiredAttributes: [],
2388
+ optionalAttributes: [...ID_ATTRS],
2389
+ allowedChildrenCodes: [
2390
+ { code: "personname", required: false },
2391
+ { code: "orgname", required: false },
2392
+ ...ATOM_CODES_ALLOWED_CHILDREN
2393
+ ]
2394
+ });
2395
+
2396
+ // src/schema/elementSchemas/elements/reference/collab.ts
2397
+ var COLLAB_SCHEMA = createSchema({
2398
+ code: "collab",
2399
+ kind: "element",
2400
+ tag: COLLAB_TAG,
2401
+ requiredAttributes: [],
2402
+ optionalAttributes: [...ID_ATTRS],
2403
+ allowedChildrenCodes: [
2404
+ { code: "orgname", required: false },
2405
+ { code: "personname", required: false },
2406
+ ...ATOM_CODES_ALLOWED_CHILDREN
2407
+ ]
2408
+ });
2409
+
2410
+ // src/schema/elementSchemas/elements/reference/pubdate.ts
2411
+ var PUBDATE_SCHEMA = createSchema({
2412
+ code: "pubdate",
2413
+ kind: "element",
2414
+ tag: PUBDATE_TAG,
2415
+ requiredAttributes: [],
2416
+ optionalAttributes: [...ID_ATTRS],
2417
+ allowedChildrenCodes: [
2418
+ ...ATOM_CODES_ALLOWED_CHILDREN
2419
+ ]
2420
+ });
2421
+
2422
+ // src/schema/elementSchemas/elements/reference/date.ts
2423
+ var ACCESSED_DATE_ROLE = "accessed";
2424
+ var DATE_SCHEMA = createSchema({
2425
+ code: "date",
2426
+ kind: "element",
2427
+ tag: DATE_TAG,
2428
+ requiredAttributes: [],
2429
+ optionalAttributes: [...ID_ATTRS, "role"],
2430
+ allowedChildrenCodes: [...ATOM_CODES_ALLOWED_CHILDREN]
2431
+ });
2432
+
2433
+ // src/schema/elementSchemas/elements/reference/publishername.ts
2434
+ var PUBLISHERNAME_SCHEMA = createSchema({
2435
+ code: "publishername",
2436
+ kind: "element",
2437
+ tag: PUBLISHERNAME_TAG,
2438
+ requiredAttributes: [],
2439
+ optionalAttributes: [...ID_ATTRS],
2440
+ allowedChildrenCodes: [
2441
+ ...ATOM_CODES_ALLOWED_CHILDREN
2442
+ ]
2443
+ });
2444
+
2445
+ // src/schema/elementSchemas/elements/reference/address.ts
2446
+ var ADDRESS_SCHEMA = createSchema({
2447
+ code: "address",
2448
+ kind: "element",
2449
+ tag: ADDRESS_TAG,
2450
+ requiredAttributes: [],
2451
+ optionalAttributes: [...ID_ATTRS],
2452
+ allowedChildrenCodes: [
2453
+ { code: "city", required: false },
2454
+ ...ATOM_CODES_ALLOWED_CHILDREN
2455
+ ]
2456
+ });
2457
+
2458
+ // src/schema/elementSchemas/elements/reference/city.ts
2459
+ var CITY_SCHEMA = createSchema({
2460
+ code: "city",
2461
+ kind: "element",
2462
+ tag: CITY_TAG,
2463
+ requiredAttributes: [],
2464
+ optionalAttributes: [...ID_ATTRS],
2465
+ allowedChildrenCodes: [
2466
+ ...ATOM_CODES_ALLOWED_CHILDREN
2467
+ ]
2468
+ });
2469
+
2470
+ // src/schema/elementSchemas/elements/reference/volumenum.ts
2471
+ var VOLUMENUM_SCHEMA = createSchema({
2472
+ code: "volumenum",
2473
+ kind: "element",
2474
+ tag: VOLUMENUM_TAG,
2475
+ requiredAttributes: [],
2476
+ optionalAttributes: [...ID_ATTRS],
2477
+ allowedChildrenCodes: [
2478
+ ...ATOM_CODES_ALLOWED_CHILDREN
2479
+ ]
2480
+ });
2481
+
2482
+ // src/schema/elementSchemas/elements/reference/issuenum.ts
2483
+ var ISSUENUM_SCHEMA = createSchema({
2484
+ code: "issuenum",
2485
+ kind: "element",
2486
+ tag: ISSUENUM_TAG,
2487
+ requiredAttributes: [],
2488
+ optionalAttributes: [...ID_ATTRS],
2489
+ allowedChildrenCodes: [
2490
+ ...ATOM_CODES_ALLOWED_CHILDREN
2491
+ ]
2492
+ });
2493
+
2494
+ // src/schema/elementSchemas/elements/reference/pagenums.ts
2495
+ var PAGENUMS_SCHEMA = createSchema({
2496
+ code: "pagenums",
2497
+ kind: "element",
2498
+ tag: PAGENUMS_TAG,
2499
+ requiredAttributes: [],
2500
+ optionalAttributes: [...ID_ATTRS],
2501
+ allowedChildrenCodes: [
2502
+ ...ATOM_CODES_ALLOWED_CHILDREN
2503
+ ]
2504
+ });
2505
+
2506
+ // src/schema/elementSchemas/elements/reference/pagenum.ts
2507
+ var PAGENUM_SCHEMA = createSchema({
2508
+ code: "pagenum",
2509
+ kind: "element",
2510
+ tag: PAGENUM_TAG,
2511
+ requiredAttributes: [],
2512
+ optionalAttributes: [...ID_ATTRS],
2513
+ allowedChildrenCodes: [
2514
+ ...ATOM_CODES_ALLOWED_CHILDREN
2515
+ ]
2516
+ });
2517
+
2518
+ // src/schema/elementSchemas/elements/reference/edition.ts
2519
+ var EDITION_SCHEMA = createSchema({
2520
+ code: "edition",
2521
+ kind: "element",
2522
+ tag: EDITION_TAG,
2523
+ requiredAttributes: [],
2524
+ optionalAttributes: [...ID_ATTRS],
2525
+ allowedChildrenCodes: [
2526
+ ...ATOM_CODES_ALLOWED_CHILDREN
2527
+ ]
2528
+ });
2529
+
2530
+ // src/schema/elementSchemas/elements/reference/pubId.ts
2531
+ var PUB_ID_SCHEMA = createSchema({
2532
+ code: "pubId",
2533
+ kind: "element",
2534
+ tag: PUB_ID_TAG,
2535
+ requiredAttributes: [],
2536
+ optionalAttributes: [...ID_ATTRS, "pub-id-type", "assigning-authority"],
2537
+ allowedChildrenCodes: [
2538
+ ...ATOM_CODES_ALLOWED_CHILDREN
2539
+ ]
2540
+ });
2541
+
2542
+ // src/schema/helpers/matchesSchemaTag.ts
2543
+ var matchesSchemaTag = (element, tag) => element.tagName.toUpperCase() === tag.toUpperCase();
2544
+
2545
+ // src/schema/elementSchemas/elements/reference/biblioid.ts
2546
+ var PUBMED_ID_BIBLIOID_CLASS = "other";
2547
+ var PUBMED_ID_BIBLIOID_OTHERCLASS = "pmid";
2548
+ var BIBLIOID_SCHEMA = createSchema({
2549
+ code: "biblioid",
2550
+ kind: "element",
2551
+ tag: BIBLIOID_TAG,
2552
+ requiredAttributes: [],
2553
+ optionalAttributes: [...ID_ATTRS, "class", "otherclass"],
2554
+ allowedChildrenCodes: [...ATOM_CODES_ALLOWED_CHILDREN]
2555
+ });
2556
+ var isPubMedIdBiblioid = (element) => matchesSchemaTag(element, BIBLIOID_TAG) && element.classList.contains(PUBMED_ID_BIBLIOID_CLASS) && element.getAttribute("otherclass") === PUBMED_ID_BIBLIOID_OTHERCLASS;
2557
+
2558
+ // src/schema/elementSchemas/elements/reference/bibliomisc.ts
2559
+ var LEGAL_REFERENCE_BIBLIOMISC_ROLE = "legalRef";
2560
+ var BIBLIOMISC_SCHEMA = createSchema({
2561
+ code: "bibliomisc",
2562
+ kind: "element",
2563
+ tag: BIBLIOMISC_TAG,
2564
+ requiredAttributes: [],
2565
+ optionalAttributes: [...ID_ATTRS, "role"],
2566
+ allowedChildrenCodes: [...ATOM_CODES_ALLOWED_CHILDREN]
2567
+ });
2568
+
2569
+ // src/schema/elementSchemas/elements/reference/confgroup.ts
2570
+ var CONFGROUP_SCHEMA = createSchema({
2571
+ code: "confgroup",
2572
+ kind: "element",
2573
+ tag: CONFGROUP_TAG,
2574
+ requiredAttributes: [],
2575
+ optionalAttributes: [...ID_ATTRS],
2576
+ allowedChildrenCodes: [
2577
+ { code: "conftitle", required: false },
2578
+ { code: "address", required: false },
2579
+ ...ATOM_CODES_ALLOWED_CHILDREN
2580
+ ]
2581
+ });
2582
+
2583
+ // src/schema/elementSchemas/elements/reference/conftitle.ts
2584
+ var CONFTITLE_SCHEMA = createSchema({
2585
+ code: "conftitle",
2586
+ kind: "element",
2587
+ tag: CONFTITLE_TAG,
2588
+ requiredAttributes: [],
2589
+ optionalAttributes: [...ID_ATTRS],
2590
+ allowedChildrenCodes: [
2591
+ ...ATOM_CODES_ALLOWED_CHILDREN
2592
+ ]
2593
+ });
2594
+
2595
+ // src/schema/elementSchemas/elements/index.ts
2596
+ var ELEMENT_SCHEMAS = {
2597
+ bibliodiv: BIBLIODIV_SCHEMA,
2598
+ referenceBibliography: REFERENCE_BIBLIOGRAPHY_SCHEMA,
2599
+ referenceBibliomixed: BIBLIOMIXED_SCHEMA,
2600
+ bibliomset: BIBLIOMSET_SCHEMA,
2601
+ editor: EDITOR_SCHEMA,
2602
+ othercredit: OTHERCREDIT_SCHEMA,
2603
+ translator: TRANSLATOR_SCHEMA,
2604
+ collab: COLLAB_SCHEMA,
2605
+ pubdate: PUBDATE_SCHEMA,
2606
+ date: DATE_SCHEMA,
2607
+ publishername: PUBLISHERNAME_SCHEMA,
2608
+ address: ADDRESS_SCHEMA,
2609
+ city: CITY_SCHEMA,
2610
+ volumenum: VOLUMENUM_SCHEMA,
2611
+ issuenum: ISSUENUM_SCHEMA,
2612
+ pagenums: PAGENUMS_SCHEMA,
2613
+ pagenum: PAGENUM_SCHEMA,
2614
+ edition: EDITION_SCHEMA,
2615
+ pubId: PUB_ID_SCHEMA,
2616
+ biblioid: BIBLIOID_SCHEMA,
2617
+ bibliomisc: BIBLIOMISC_SCHEMA,
2618
+ confgroup: CONFGROUP_SCHEMA,
2619
+ conftitle: CONFTITLE_SCHEMA,
2620
+ para: PARA_SCHEMA,
2621
+ title1: TITLE_SCHEMA,
2622
+ footnote: FOOTNOTE_SCHEMA,
2623
+ footnoteno: FOOTNOTE_NUMBER_SCHEMA,
2624
+ olink: OLINK_SCHEMA,
2625
+ firstname: FIRSTNAME_SCHEMA,
2626
+ surname: SURNAME_SCHEMA,
2627
+ honorific: HONORIFIC_SCHEMA,
2628
+ orgname: ORGNAME_SCHEMA,
2629
+ email: EMAIL_SCHEMA,
2630
+ org: ORG_SCHEMA,
2631
+ degrees: DEGREES_SCHEMA,
2632
+ dialogue: DIALOGUE_SCHEMA,
2633
+ line: LINE_SCHEMA,
2634
+ linegroup: LINE_GROUP_SCHEMA,
2635
+ speaker: SPEAKER_SCHEMA,
2636
+ equation: EQUATION_SCHEMA,
2637
+ math: MATH_SCHEMA,
2638
+ mathphrase: MATHPHRASE_SCHEMA,
2639
+ merror: MERROR_SCHEMA,
2640
+ mfrac: MFRAC_SCHEMA,
2641
+ mi: MI_SCHEMA,
2642
+ mmultiscripts: MMULTISCRIPTS_SCHEMA,
2643
+ mn: MN_SCHEMA,
2644
+ mo: MO_SCHEMA,
2645
+ mover: MOVER_SCHEMA,
2646
+ mpadded: MPADDED_SCHEMA,
2647
+ mphantom: MPHANTOM_SCHEMA,
2648
+ mprescripts: MPRESCRIPTS_SCHEMA,
2649
+ mroot: MROOT_SCHEMA,
2650
+ mrow: MROW_SCHEMA,
2651
+ ms: MS_SCHEMA,
2652
+ mspace: MSPACE_SCHEMA,
2653
+ msqrt: MSQRT_SCHEMA,
2654
+ mstyle: MSTYLE_SCHEMA,
2655
+ msub: MSUB_SCHEMA,
2656
+ msubsup: MSUBSUP_SCHEMA,
2657
+ msup: MSUP_SCHEMA,
2658
+ mtable: MTABLE_SCHEMA,
2659
+ mtd: MTD_SCHEMA,
2660
+ mtext: MTEXT_SCHEMA,
2661
+ mtr: MTR_SCHEMA,
2662
+ munder: MUNDER_SCHEMA,
2663
+ munderover: MUNDEROVER_SCHEMA,
2664
+ img: IMG_SCHEMA,
2665
+ alttext: ALTTEXT_SCHEMA,
2666
+ imageobject: IMAGEOBJECT_SCHEMA,
2667
+ mediaobject: MEDIAOBJECT_SCHEMA,
2668
+ caption1: CAPTION_SCHEMA,
2669
+ figsource: FIGSOURCE_SCHEMA,
2670
+ fignote: FIGNOTE_SCHEMA,
2671
+ figure1: FIGURE_SCHEMA,
2672
+ informalfigure: INFORMALFIGURE_SCHEMA,
2673
+ keywordset: KEYWORDSET_SCHEMA,
2674
+ keyword: KEYWORD_SCHEMA,
2675
+ punc: PUNC_SCHEMA,
2676
+ label1: LABEL_SCHEMA,
2677
+ li: LI_SCHEMA,
2678
+ ol: OL_SCHEMA,
2679
+ ul: UL_SCHEMA,
2680
+ token: TOKEN_SCHEMA,
2681
+ tag: TAG_SCHEMA,
2682
+ lrh: LRH_SCHEMA,
2683
+ rrh: RRH_SCHEMA,
2684
+ source1: SOURCE_SCHEMA,
2685
+ subtitle1: SUBTITLE_SCHEMA,
2686
+ table1: TABLE_SCHEMA,
2687
+ tgroup: TGROUP_SCHEMA,
2316
2688
  table: HTML_TABLE_SCHEMA,
2317
2689
  thead: THEAD_SCHEMA,
2318
2690
  tbody: TBODY_SCHEMA,
@@ -2384,7 +2756,10 @@ var INLINEEQUATION_SCHEMA = createSchema({
2384
2756
  defaultValue: "added"
2385
2757
  }
2386
2758
  ],
2387
- allowedChildrenCodes: [{ code: "mathphrase", required: true }]
2759
+ allowedChildrenCodes: [
2760
+ { code: "mathphrase", required: true },
2761
+ { code: "tag", required: false }
2762
+ ]
2388
2763
  });
2389
2764
 
2390
2765
  // src/schema/elementSchemas/inlineElements/link.ts
@@ -2471,16 +2846,20 @@ var findAttributeDefinitionByName = (definitions, name) => {
2471
2846
  // src/schema/helpers/findSchemaByCode.ts
2472
2847
  var findSchemaByCode = (code) => SCHEMAS[code];
2473
2848
 
2474
- // src/schema/helpers/matchesSchemaTag.ts
2475
- var matchesSchemaTag = (element, tag) => element.tagName.toUpperCase() === tag.toUpperCase();
2476
-
2477
2849
  // src/schema/helpers/findSchemaByElement.ts
2478
- var findSchemaByElement = (element) => {
2479
- const schema = Object.values(SCHEMAS).find(
2480
- (schema2) => matchesSchemaTag(element, schema2.tag) && (!schema2.matchesElement || schema2.matchesElement(element))
2481
- );
2482
- return schema;
2850
+ var schemasByTag;
2851
+ var getSchemasByTag = () => {
2852
+ if (schemasByTag) return schemasByTag;
2853
+ schemasByTag = /* @__PURE__ */ new Map();
2854
+ for (const schema of Object.values(SCHEMAS)) {
2855
+ const tag = schema.tag.toUpperCase();
2856
+ const schemas = schemasByTag.get(tag);
2857
+ if (schemas) schemas.push(schema);
2858
+ else schemasByTag.set(tag, [schema]);
2859
+ }
2860
+ return schemasByTag;
2483
2861
  };
2862
+ var findSchemaByElement = (element) => getSchemasByTag().get(element.tagName.toUpperCase())?.find((schema) => !schema.matchesElement || schema.matchesElement(element));
2484
2863
 
2485
2864
  // src/schema/helpers/isAttributeRestricted.ts
2486
2865
  var isAttributeRestricted = (attr) => typeof attr !== "string";
@@ -2488,12 +2867,402 @@ var isAttributeRestricted = (attr) => typeof attr !== "string";
2488
2867
  // src/schema/helpers/isTrackChangesSchema.ts
2489
2868
  var isTrackChangesSchema = (schema) => schema.code === "insertion" || schema.code === "deletion" || schema.code === "lineGroupRemoval";
2490
2869
 
2870
+ // src/schema/referenceSchemas/referenceTypeSchemas.ts
2871
+ var LINK_FIELDS = ["doi", "url"];
2872
+ var OTHER_MATERIAL_FIELDS = [
2873
+ "author",
2874
+ "editor",
2875
+ "title",
2876
+ "year",
2877
+ "containerTitle",
2878
+ "publisherPlace",
2879
+ "publisher",
2880
+ "volume",
2881
+ "issue",
2882
+ "pages",
2883
+ "accessDate",
2884
+ "genre",
2885
+ "eventTitle",
2886
+ "eventPlace",
2887
+ "documentNumber",
2888
+ "pubmedId",
2889
+ ...LINK_FIELDS
2890
+ ];
2891
+ var REFERENCE_TYPE_SCHEMAS = {
2892
+ monograph: {
2893
+ code: "monograph",
2894
+ label: "Book",
2895
+ legacyRoles: ["book"],
2896
+ allowedFields: [
2897
+ "author",
2898
+ "editor",
2899
+ "title",
2900
+ "year",
2901
+ "volume",
2902
+ "publisherPlace",
2903
+ "publisher",
2904
+ ...LINK_FIELDS
2905
+ ],
2906
+ requiredFields: ["title", "creators"],
2907
+ fieldLabels: { title: "Book title" }
2908
+ },
2909
+ serial: {
2910
+ code: "serial",
2911
+ label: "Journal issue",
2912
+ legacyRoles: [],
2913
+ allowedFields: ["title", "year", "volume", "issue", ...LINK_FIELDS],
2914
+ requiredFields: ["title"]
2915
+ },
2916
+ contribution: {
2917
+ code: "contribution",
2918
+ label: "Contributed book",
2919
+ legacyRoles: ["chapter"],
2920
+ allowedFields: [
2921
+ "author",
2922
+ "editor",
2923
+ "title",
2924
+ "year",
2925
+ "containerTitle",
2926
+ "publisherPlace",
2927
+ "publisher",
2928
+ "pages",
2929
+ ...LINK_FIELDS
2930
+ ],
2931
+ requiredFields: ["title", "containerTitle", "creators"],
2932
+ bibliomsetRelations: ["part", "book"],
2933
+ fieldLabels: { title: "Chapter title", containerTitle: "Book title" }
2934
+ },
2935
+ article: {
2936
+ code: "article",
2937
+ label: "Journal article",
2938
+ legacyRoles: ["journal", "article-journal"],
2939
+ allowedFields: [
2940
+ "author",
2941
+ "editor",
2942
+ "title",
2943
+ "year",
2944
+ "containerTitle",
2945
+ "volume",
2946
+ "issue",
2947
+ "pages",
2948
+ "genre",
2949
+ "publisher",
2950
+ "publisherPlace",
2951
+ "pubmedId",
2952
+ "accessDate",
2953
+ ...LINK_FIELDS
2954
+ ],
2955
+ requiredFields: ["title", "containerTitle"],
2956
+ bibliomsetRelations: ["article", "journal"],
2957
+ fieldLabels: { title: "Article title", containerTitle: "Journal title" }
2958
+ },
2959
+ message: {
2960
+ code: "message",
2961
+ label: "Email message",
2962
+ legacyRoles: [],
2963
+ allowedFields: ["author", "title", "year", ...LINK_FIELDS],
2964
+ requiredFields: ["title"]
2965
+ },
2966
+ website: {
2967
+ code: "website",
2968
+ label: "Website",
2969
+ legacyRoles: [],
2970
+ allowedFields: ["author", "title", "year", "accessDate", ...LINK_FIELDS],
2971
+ requiredFields: ["title"]
2972
+ },
2973
+ unpublished: {
2974
+ code: "unpublished",
2975
+ label: "Unpublished material",
2976
+ legacyRoles: [],
2977
+ allowedFields: [
2978
+ "author",
2979
+ "title",
2980
+ "year",
2981
+ "publisher",
2982
+ "genre",
2983
+ "eventTitle",
2984
+ "eventPlace",
2985
+ ...LINK_FIELDS
2986
+ ],
2987
+ requiredFields: ["title"],
2988
+ replacedElements: [
2989
+ { tag: "pubdate", replacement: "date" },
2990
+ { tag: "publishername", replacement: "orgname" }
2991
+ ]
2992
+ },
2993
+ case: {
2994
+ code: "case",
2995
+ label: "Case",
2996
+ legacyRoles: [],
2997
+ allowedFields: ["title", "year", "documentNumber", ...LINK_FIELDS],
2998
+ requiredFields: ["title"]
2999
+ },
3000
+ legislation: {
3001
+ code: "legislation",
3002
+ label: "Legislation",
3003
+ legacyRoles: [],
3004
+ allowedFields: [
3005
+ "title",
3006
+ "year",
3007
+ "documentNumber",
3008
+ "publisherPlace",
3009
+ ...LINK_FIELDS
3010
+ ],
3011
+ requiredFields: ["title"]
3012
+ },
3013
+ other: {
3014
+ code: "other",
3015
+ label: "Other material",
3016
+ legacyRoles: [],
3017
+ allowedFields: OTHER_MATERIAL_FIELDS,
3018
+ requiredFields: ["title"]
3019
+ },
3020
+ recording: {
3021
+ code: "recording",
3022
+ label: "Recording",
3023
+ legacyRoles: [],
3024
+ allowedFields: ["author", "title", "year", ...LINK_FIELDS],
3025
+ requiredFields: ["title", "year"],
3026
+ replacedElements: [{ tag: "author", replacement: "othercredit" }]
3027
+ },
3028
+ film: {
3029
+ code: "film",
3030
+ label: "Film",
3031
+ legacyRoles: [],
3032
+ allowedFields: ["title", "year", ...LINK_FIELDS],
3033
+ requiredFields: ["title"]
3034
+ }
3035
+ };
3036
+
3037
+ // src/schema/helpers/findReferenceTypeSchemaByElement.ts
3038
+ var findReferenceTypeSchemaByElement = (reference) => {
3039
+ const role = reference.getAttribute("role")?.trim().toLowerCase() ?? "";
3040
+ const schemas = Object.values(REFERENCE_TYPE_SCHEMAS);
3041
+ return schemas.find(
3042
+ (schema) => schema.code === role || schema.legacyRoles.includes(role)
3043
+ );
3044
+ };
3045
+
3046
+ // src/helpers/isDeletedElement.ts
3047
+ var isDeletedElement = (element) => {
3048
+ return !!closestElementBySchema({
3049
+ element,
3050
+ code: "deletion"
3051
+ });
3052
+ };
3053
+
3054
+ // src/helpers/closestElementBySchema.ts
3055
+ var closestElementBySchema = ({
3056
+ element,
3057
+ code,
3058
+ ignoreDeletedElements = false
3059
+ }) => {
3060
+ const schema = findSchemaByCode(code);
3061
+ if (!schema) return;
3062
+ const closestElement = element.closest(
3063
+ schema.tag.toLowerCase()
3064
+ );
3065
+ if (!closestElement) return;
3066
+ if (schema.matchesElement && !schema.matchesElement(closestElement)) {
3067
+ return;
3068
+ }
3069
+ if (ignoreDeletedElements && isDeletedElement(closestElement)) {
3070
+ return closestElementBySchema({
3071
+ element: closestElement,
3072
+ code,
3073
+ ignoreDeletedElements
3074
+ });
3075
+ }
3076
+ return closestElement;
3077
+ };
3078
+
3079
+ // src/helpers/isInTrackedDeletion.ts
3080
+ var isInTrackedDeletion = (element) => !!element.closest("span.del");
3081
+
3082
+ // src/helpers/hasLiveUri.ts
3083
+ var hasLiveUri = (link) => Array.from(link.querySelectorAll("uri")).some(
3084
+ (uri) => !isInTrackedDeletion(uri)
3085
+ );
3086
+
3087
+ // src/schema/helpers/findReferenceFieldByElement.ts
3088
+ var isContainerTitle = (title) => {
3089
+ const relation = closestElementBySchema({
3090
+ element: title,
3091
+ code: "bibliomset"
3092
+ })?.getAttribute("relation");
3093
+ return CONTAINER_BIBLIOMSET_RELATIONS.some(
3094
+ (containerRelation) => containerRelation === relation
3095
+ );
3096
+ };
3097
+ var isUnpublishedReference = (element) => {
3098
+ const reference = closestElementBySchema({
3099
+ element,
3100
+ code: "referenceBibliomixed"
3101
+ });
3102
+ return !!reference && findReferenceTypeSchemaByElement(reference)?.code === "unpublished";
3103
+ };
3104
+ var hasAcceptedChild = (element, tag) => Array.from(element.querySelectorAll(tag.toLowerCase())).some(
3105
+ (child) => !isInTrackedDeletion(child)
3106
+ );
3107
+ var isConferenceDates = (confgroup) => hasAcceptedChild(confgroup, CONFDATES_TAG) && !hasAcceptedChild(confgroup, CONFTITLE_TAG);
3108
+ var findReferenceFieldByElement = (element) => {
3109
+ switch (findSchemaByElement(element)?.code) {
3110
+ case "author":
3111
+ case "othercredit":
3112
+ return "author";
3113
+ case "editor":
3114
+ return "editor";
3115
+ case "title1":
3116
+ return isContainerTitle(element) ? "containerTitle" : "title";
3117
+ case "pubdate":
3118
+ return "year";
3119
+ case "date":
3120
+ return element.getAttribute("role") === ACCESSED_DATE_ROLE ? "accessDate" : "year";
3121
+ case "publishername":
3122
+ case "orgname":
3123
+ return "publisher";
3124
+ case "address":
3125
+ return isUnpublishedReference(element) ? "eventPlace" : "publisherPlace";
3126
+ case "volumenum":
3127
+ return "volume";
3128
+ case "issuenum":
3129
+ return "issue";
3130
+ case "pagenums":
3131
+ return "pages";
3132
+ case "link":
3133
+ if (element.hasAttribute(LINKEND_ATTRIBUTE)) return void 0;
3134
+ return hasLiveUri(element) ? "url" : "doi";
3135
+ case "bibliomisc":
3136
+ return element.getAttribute("role") === LEGAL_REFERENCE_BIBLIOMISC_ROLE ? "documentNumber" : "genre";
3137
+ case "confgroup":
3138
+ return isConferenceDates(element) ? "year" : "eventTitle";
3139
+ case "biblioid":
3140
+ return isPubMedIdBiblioid(element) ? "pubmedId" : void 0;
3141
+ default:
3142
+ return void 0;
3143
+ }
3144
+ };
3145
+
3146
+ // src/schema/referenceSchemas/referenceFieldSchemas.ts
3147
+ var REFERENCE_FIELD_SCHEMAS = {
3148
+ author: {
3149
+ code: "author",
3150
+ label: "Author",
3151
+ elementCodes: ["author", "othercredit"]
3152
+ },
3153
+ editor: {
3154
+ code: "editor",
3155
+ label: "Editor",
3156
+ elementCodes: ["editor"]
3157
+ },
3158
+ title: {
3159
+ code: "title",
3160
+ label: "Title",
3161
+ elementCodes: ["title1"]
3162
+ },
3163
+ year: {
3164
+ code: "year",
3165
+ label: "Date",
3166
+ elementCodes: ["pubdate", "date", "confgroup"]
3167
+ },
3168
+ containerTitle: {
3169
+ code: "containerTitle",
3170
+ label: "Container title",
3171
+ elementCodes: ["title1"]
3172
+ },
3173
+ publisherPlace: {
3174
+ code: "publisherPlace",
3175
+ label: "Publisher place",
3176
+ elementCodes: ["address"]
3177
+ },
3178
+ publisher: {
3179
+ code: "publisher",
3180
+ label: "Publisher or institution",
3181
+ elementCodes: ["publishername", "orgname"]
3182
+ },
3183
+ volume: {
3184
+ code: "volume",
3185
+ label: "Volume",
3186
+ elementCodes: ["volumenum"]
3187
+ },
3188
+ issue: {
3189
+ code: "issue",
3190
+ label: "Issue",
3191
+ elementCodes: ["issuenum"]
3192
+ },
3193
+ pages: {
3194
+ code: "pages",
3195
+ label: "Pages",
3196
+ elementCodes: ["pagenums"]
3197
+ },
3198
+ doi: {
3199
+ code: "doi",
3200
+ label: "DOI",
3201
+ elementCodes: ["link"]
3202
+ },
3203
+ url: {
3204
+ code: "url",
3205
+ label: "URL",
3206
+ elementCodes: ["link"]
3207
+ },
3208
+ accessDate: {
3209
+ code: "accessDate",
3210
+ label: "Access date",
3211
+ elementCodes: ["date"]
3212
+ },
3213
+ genre: {
3214
+ code: "genre",
3215
+ label: "Description",
3216
+ elementCodes: ["bibliomisc"]
3217
+ },
3218
+ eventTitle: {
3219
+ code: "eventTitle",
3220
+ label: "Conference title",
3221
+ elementCodes: ["confgroup"]
3222
+ },
3223
+ eventPlace: {
3224
+ code: "eventPlace",
3225
+ label: "Conference place",
3226
+ elementCodes: ["address"]
3227
+ },
3228
+ documentNumber: {
3229
+ code: "documentNumber",
3230
+ label: "Legal reference",
3231
+ elementCodes: ["bibliomisc"]
3232
+ },
3233
+ pubmedId: {
3234
+ code: "pubmedId",
3235
+ label: "PubMed ID",
3236
+ elementCodes: ["biblioid"]
3237
+ }
3238
+ };
3239
+
2491
3240
  // src/schema/shared/labelElements.ts
2492
3241
  var ElementLabel = {
2493
3242
  mark: "Mark",
2494
3243
  referenceBibliomixed: "Reference Bibliomixed",
2495
3244
  referenceBibliography: "Reference Bibliography",
2496
3245
  bibliodiv: "Bibliodiv",
3246
+ bibliomset: "Reference Block",
3247
+ editor: "Editor",
3248
+ othercredit: "Other Credit",
3249
+ translator: "Translator",
3250
+ collab: "Collaborator",
3251
+ pubdate: "Publication Date",
3252
+ date: "Date",
3253
+ publishername: "Publisher Name",
3254
+ address: "Address",
3255
+ city: "City",
3256
+ volumenum: "Volume Number",
3257
+ issuenum: "Issue Number",
3258
+ pagenums: "Page Numbers",
3259
+ pagenum: "Page Number",
3260
+ edition: "Edition",
3261
+ pubId: "Publication ID",
3262
+ biblioid: "Bibliographic ID",
3263
+ bibliomisc: "Reference Miscellany",
3264
+ confgroup: "Conference",
3265
+ conftitle: "Conference Title",
2497
3266
  indexterm: "Indexterm",
2498
3267
  primary: "Primary",
2499
3268
  secondary: "Secondary",
@@ -2634,46 +3403,15 @@ var IGNORED_ELEMENT_SELECTORS = [
2634
3403
  "span.ref-drag",
2635
3404
  "span#dummySpan"
2636
3405
  ];
2637
- var isIgnoredElement = (element) => IGNORED_ELEMENT_SELECTORS.some((selector) => element.matches(selector));
3406
+ var IGNORED_ELEMENT_SELECTOR = IGNORED_ELEMENT_SELECTORS.join(", ");
3407
+ var isIgnoredElement = (element) => element.tagName.toUpperCase() === "SPAN" && element.matches(IGNORED_ELEMENT_SELECTOR);
2638
3408
 
2639
3409
  // src/validation/helpers/isIgnoredValidation.ts
2640
3410
  var IGNORED_VALIDATION_ELEMENT_SELECTORS = [
2641
3411
  "referenceBibliomixed"
2642
3412
  ];
2643
3413
  var isIgnoredValidation = (code) => IGNORED_VALIDATION_ELEMENT_SELECTORS.includes(code);
2644
-
2645
- // src/helpers/closestElementBySchema.ts
2646
- var closestElementBySchema = ({
2647
- element,
2648
- code,
2649
- ignoreDeletedElements = false
2650
- }) => {
2651
- const schema = findSchemaByCode(code);
2652
- if (!schema) return;
2653
- const closestElement = element.closest(
2654
- schema.tag.toLowerCase()
2655
- );
2656
- if (!closestElement) return;
2657
- if (schema.matchesElement && !schema.matchesElement(closestElement)) {
2658
- return;
2659
- }
2660
- if (ignoreDeletedElements && isDeletedElement(closestElement)) {
2661
- return closestElementBySchema({
2662
- element: closestElement,
2663
- code,
2664
- ignoreDeletedElements
2665
- });
2666
- }
2667
- return closestElement;
2668
- };
2669
-
2670
- // src/helpers/isDeletedElement.ts
2671
- var isDeletedElement = (element) => {
2672
- return !!closestElementBySchema({
2673
- element,
2674
- code: "deletion"
2675
- });
2676
- };
3414
+ var isIgnoredValidationByAttribute = (element) => element.getAttribute(VALIDATION_IGNORED_ATTRIBUTE) === "true";
2677
3415
 
2678
3416
  // src/validation/utils/getElementsSelector.ts
2679
3417
  var getElementsSelector = ({
@@ -2711,12 +3449,14 @@ var generateValidationIssueId = () => {
2711
3449
  };
2712
3450
 
2713
3451
  // src/validation/helpers/addValidationIssue.ts
2714
- var createValidationIssue = (issue) => ({
3452
+ var createValidationIssue = (element, issue) => ({
3453
+ ...issue,
2715
3454
  id: generateValidationIssueId(),
2716
- ...issue
3455
+ store: element ? getStore(element) : issue.store,
3456
+ ignored: element ? isIgnoredValidationByAttribute(element) : false
2717
3457
  });
2718
- var addValidationIssue = (errors, issue) => {
2719
- errors.push(createValidationIssue(issue));
3458
+ var addValidationIssue = (errors, element, issue) => {
3459
+ errors.push(createValidationIssue(element, issue));
2720
3460
  };
2721
3461
 
2722
3462
  // src/validation/validateFootnotes.ts
@@ -2735,8 +3475,7 @@ var validateFootnoteNumber = (footnoteElement) => {
2735
3475
  FOOTNOTE_NUMBER_SCHEMA.tag
2736
3476
  );
2737
3477
  if (!footnoteNumber) {
2738
- addValidationIssue(errors, {
2739
- store: getStore(footnoteElement),
3478
+ addValidationIssue(errors, footnoteElement, {
2740
3479
  title: "Footnote number missing",
2741
3480
  kind: "missing",
2742
3481
  description: "The footnote number is missing. Please add it to the footnote.",
@@ -2767,8 +3506,7 @@ var validateConsecutiveFootnotes = (root) => {
2767
3506
  );
2768
3507
  if (!footnoteNumberElement) {
2769
3508
  errors.push(
2770
- createValidationIssue({
2771
- store: getStore(footnote),
3509
+ createValidationIssue(footnote, {
2772
3510
  title: "Footnote number missing",
2773
3511
  kind: "missing",
2774
3512
  description: "The footnote number is missing. Please add it to the footnote.",
@@ -2781,8 +3519,7 @@ var validateConsecutiveFootnotes = (root) => {
2781
3519
  continue;
2782
3520
  }
2783
3521
  errors.push(
2784
- createValidationIssue({
2785
- store: getStore(footnote),
3522
+ createValidationIssue(footnote, {
2786
3523
  title: "Non-consecutive footnote numbers",
2787
3524
  kind: "missing",
2788
3525
  description: `Footnote numbers must be consecutive, footnote number (${label}) expected to be (${expectedNumber}). Please reorder the footnotes.`,
@@ -2813,8 +3550,7 @@ var validateConsecutiveFootnoteCues = (root) => {
2813
3550
  continue;
2814
3551
  }
2815
3552
  errors.push(
2816
- createValidationIssue({
2817
- store: getStore(footnoteLink),
3553
+ createValidationIssue(footnoteLink, {
2818
3554
  title: "Non-consecutive footnote cues",
2819
3555
  kind: "missing",
2820
3556
  description: "Footnote cues must be consecutive. Please reorder the footnote cues.",
@@ -2827,10 +3563,11 @@ var validateConsecutiveFootnoteCues = (root) => {
2827
3563
  return errors;
2828
3564
  };
2829
3565
 
3566
+ // src/validation/helpers/hasLinkId.ts
3567
+ var hasLinkId = (ids, id) => "has" in ids ? ids.has(id) : ids.includes(id);
3568
+
2830
3569
  // src/validation/validateLinkend.ts
2831
- var findElementLinkedTo = (linkend, elementsToLink) => {
2832
- return elementsToLink.includes(linkend);
2833
- };
3570
+ var findElementLinkedTo = (linkend, elementsToLink) => hasLinkId(elementsToLink, linkend);
2834
3571
  var LINK_TO_CROSS_CHECK = [
2835
3572
  TABLE_LINK_ROLE,
2836
3573
  FIGURE_LINK_ROLE,
@@ -2858,8 +3595,7 @@ var validateLinkend = (linkElement, elementsToLink) => {
2858
3595
  );
2859
3596
  if (isLinkFootnoteCue) {
2860
3597
  return [
2861
- createValidationIssue({
2862
- store: getStore(linkElement),
3598
+ createValidationIssue(linkElement, {
2863
3599
  title: "Unlinked footnote cue",
2864
3600
  kind: "unlinked",
2865
3601
  description: "This footnote cue is not referenced to any footnote in this chapter. Please link it again manually.",
@@ -2880,8 +3616,7 @@ var validateLinkend = (linkElement, elementsToLink) => {
2880
3616
  }
2881
3617
  const isBlocker = LINK_BLOCKER_ROLES.includes(role.toLowerCase());
2882
3618
  return [
2883
- createValidationIssue({
2884
- store: getStore(linkElement),
3619
+ createValidationIssue(linkElement, {
2885
3620
  title: "Unlinked element",
2886
3621
  kind: "unlinked",
2887
3622
  description: "This link is not referenced to any element in the current chapter or any other chapter. Please link it again manually.",
@@ -2941,8 +3676,7 @@ var validateAttributes = (element, schema) => {
2941
3676
  continue;
2942
3677
  }
2943
3678
  if (!definition.values.includes(value)) {
2944
- addValidationIssue(errors, {
2945
- store: getStore(element),
3679
+ addValidationIssue(errors, element, {
2946
3680
  title: `Invalid attribute value "${value}" in element ${element.tagName}`,
2947
3681
  level: "warning",
2948
3682
  kind: "forbidden",
@@ -2957,8 +3691,7 @@ var validateAttributes = (element, schema) => {
2957
3691
  var validateElementAgainstSchema = (element, schema) => {
2958
3692
  const errors = [];
2959
3693
  if (!matchesSchemaTag(element, schema.tag)) {
2960
- addValidationIssue(errors, {
2961
- store: getStore(element),
3694
+ addValidationIssue(errors, element, {
2962
3695
  title: `Expected ${schema.tag}, got ${element.tagName}`,
2963
3696
  level: "warning",
2964
3697
  kind: "forbidden",
@@ -2988,8 +3721,7 @@ var validateRequiredChildren = (element, schema, childElements) => {
2988
3721
  `Please provide at least one ${elementLabel} in this ${parentLabel}.`,
2989
3722
  extraInstruction
2990
3723
  ].filter(Boolean).join(" ");
2991
- addValidationIssue(errors, {
2992
- store: getStore(element),
3724
+ addValidationIssue(errors, element, {
2993
3725
  title: `${elementLabel} missing`,
2994
3726
  level: "warning",
2995
3727
  kind: "missing",
@@ -3023,8 +3755,7 @@ var validateChildren = (element, schema) => {
3023
3755
  for (const child of childElements) {
3024
3756
  const childSchema = findSchemaByElement(child);
3025
3757
  if (!childSchema) {
3026
- addValidationIssue(errors, {
3027
- store: getStore(child),
3758
+ addValidationIssue(errors, child, {
3028
3759
  title: `No schema found for child element ${child.tagName}`,
3029
3760
  level: "warning",
3030
3761
  kind: "missing",
@@ -3036,8 +3767,7 @@ var validateChildren = (element, schema) => {
3036
3767
  (candidate) => candidate.code === childSchema.code
3037
3768
  );
3038
3769
  if (!allowedChild) {
3039
- addValidationIssue(errors, {
3040
- store: getStore(child),
3770
+ addValidationIssue(errors, child, {
3041
3771
  title: `Forbidden child element ${child.tagName}`,
3042
3772
  level: "warning",
3043
3773
  kind: "forbidden",
@@ -3058,9 +3788,7 @@ var getExtraInstruction = (schema, childSchema) => {
3058
3788
  };
3059
3789
 
3060
3790
  // src/validation/validateElementToLinkTo.ts
3061
- var findElementLinkedTo2 = (xmlid, linkElements) => {
3062
- return linkElements.includes(xmlid);
3063
- };
3791
+ var findElementLinkedTo2 = (xmlid, linkElements) => hasLinkId(linkElements, xmlid);
3064
3792
  var isFootnote = (element) => {
3065
3793
  return matchesSchemaTag(element, FOOTNOTE_SCHEMA.tag);
3066
3794
  };
@@ -3087,8 +3815,7 @@ var validateElementToLinkTo = (element, linkElements) => {
3087
3815
  if (isFootnote(element)) {
3088
3816
  const label = extractFootnoteNumber(element);
3089
3817
  return [
3090
- createValidationIssue({
3091
- store: getStore(element),
3818
+ createValidationIssue(element, {
3092
3819
  title: "Uncited footnote",
3093
3820
  kind: "uncited",
3094
3821
  description: `The footnote ${label} is not cited to any footnote cue in this chapter. Please reference it in the chapter.`,
@@ -3098,8 +3825,7 @@ var validateElementToLinkTo = (element, linkElements) => {
3098
3825
  }
3099
3826
  if (isReference(element)) {
3100
3827
  return [
3101
- createValidationIssue({
3102
- store: getStore(element),
3828
+ createValidationIssue(element, {
3103
3829
  title: "Uncited reference",
3104
3830
  kind: "uncited",
3105
3831
  description: "This reference is not cited in this chapter or any other chapter. Please add a link to this reference or delete it.",
@@ -3109,8 +3835,7 @@ var validateElementToLinkTo = (element, linkElements) => {
3109
3835
  }
3110
3836
  if (isTable(element)) {
3111
3837
  return [
3112
- createValidationIssue({
3113
- store: getStore(element),
3838
+ createValidationIssue(element, {
3114
3839
  title: "Uncited table",
3115
3840
  kind: "uncited",
3116
3841
  description: "This table is not cited in this chapter or any other chapter. Please add a link to this table or delete it.",
@@ -3120,8 +3845,7 @@ var validateElementToLinkTo = (element, linkElements) => {
3120
3845
  }
3121
3846
  if (isFigure(element)) {
3122
3847
  return [
3123
- createValidationIssue({
3124
- store: getStore(element),
3848
+ createValidationIssue(element, {
3125
3849
  title: "Uncited figure",
3126
3850
  kind: "uncited",
3127
3851
  description: "This figure is not cited in this chapter or any other chapter. Please add a link to this figure or delete it.",
@@ -3134,9 +3858,20 @@ var validateElementToLinkTo = (element, linkElements) => {
3134
3858
 
3135
3859
  // src/validation/validateWeblink.ts
3136
3860
  var import_mark2 = __toESM(require("mark.js"));
3861
+
3862
+ // src/validation/helpers/steps.ts
3863
+ var runSteps = (steps) => {
3864
+ for (; ; ) {
3865
+ const step = steps.next();
3866
+ if (step.done) return step.value;
3867
+ }
3868
+ };
3869
+
3870
+ // src/validation/validateWeblink.ts
3137
3871
  var EDGE_PUNCTUATION = `:;.,\\-\u2013\u2014\u2012_(){}[\\]!'"+=\xAB\xBB\u2039\u203A\u201C\u201D\u2018\u2019<>`;
3138
3872
  var WEB_URI_PATTERN = `(?:(?:https?):\\/\\/|www\\.)(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,}(?::\\d{1,5})?(?:\\/(?:[^\\s]*[^\\s${EDGE_PUNCTUATION}])?)?`;
3139
3873
  var WEB_URI_IN_TEXT_REGEX = new RegExp(WEB_URI_PATTERN, "gi");
3874
+ var POSSIBLE_WEBLINK_CLASS = "possible-weblink";
3140
3875
  var POSSIBLE_WEBLINK_EXCLUDE_SELECTORS = [
3141
3876
  "tag",
3142
3877
  "tag *",
@@ -3148,40 +3883,150 @@ var POSSIBLE_WEBLINK_EXCLUDE_SELECTORS = [
3148
3883
  "query *",
3149
3884
  "comment",
3150
3885
  "comment *",
3886
+ `.${POSSIBLE_WEBLINK_CLASS}`,
3887
+ `.${POSSIBLE_WEBLINK_CLASS} *`,
3151
3888
  ...IGNORED_ELEMENT_SELECTORS
3152
3889
  ];
3153
- var collectPossibleWebLinks = (content) => {
3154
- const clone = content.cloneNode(true);
3155
- const possibleWebLinks = /* @__PURE__ */ new Set();
3156
- const instance = new import_mark2.default(clone);
3890
+ var getPossibleWeblinks = (root) => {
3891
+ const possibleWeblinks = /* @__PURE__ */ new Map();
3892
+ const allWeblinkMatches = Array.from(
3893
+ root.getElementsByClassName(POSSIBLE_WEBLINK_CLASS)
3894
+ );
3895
+ for (const weblinkMatch of allWeblinkMatches) {
3896
+ const storeId = weblinkMatch.getAttribute(STORE_ATTRIBUTE);
3897
+ if (!storeId || possibleWeblinks.has(storeId)) continue;
3898
+ const elements = allWeblinkMatches.filter(
3899
+ (element) => element.getAttribute(STORE_ATTRIBUTE) === storeId
3900
+ );
3901
+ const weblink = elements.map((element) => element.textContent).join("");
3902
+ possibleWeblinks.set(storeId, {
3903
+ weblink,
3904
+ elements
3905
+ });
3906
+ }
3907
+ return possibleWeblinks;
3908
+ };
3909
+ var getWeblinkMatchId = (matchIndex) => `weblink-match-${matchIndex}`;
3910
+ var createWeblinkMatchTracker = () => {
3911
+ const matchedText = [];
3912
+ const matchedElements = [];
3913
+ const possibleWeblinks = /* @__PURE__ */ new Map();
3914
+ let matchIndex = 0;
3915
+ let currentMatchId = getWeblinkMatchId(matchIndex);
3916
+ const resetMatch = () => {
3917
+ matchIndex += 1;
3918
+ currentMatchId = getWeblinkMatchId(matchIndex);
3919
+ matchedText.length = 0;
3920
+ matchedElements.length = 0;
3921
+ };
3922
+ const composeWeblink = (element, url) => {
3923
+ element.setAttribute(STORE_ATTRIBUTE, currentMatchId);
3924
+ matchedText.push(element.textContent);
3925
+ matchedElements.push(element);
3926
+ if (matchedText.join("") !== url) return;
3927
+ possibleWeblinks.set(currentMatchId, {
3928
+ weblink: matchedText.join(""),
3929
+ elements: [...matchedElements]
3930
+ });
3931
+ resetMatch();
3932
+ };
3933
+ return { composeWeblink, possibleWeblinks };
3934
+ };
3935
+ var markPossibleWeblinks = (editor) => {
3936
+ const instance = new import_mark2.default(editor);
3937
+ const { composeWeblink, possibleWeblinks } = createWeblinkMatchTracker();
3938
+ let possibleWebLink = "";
3157
3939
  instance.markRegExp(WEB_URI_IN_TEXT_REGEX, {
3940
+ className: POSSIBLE_WEBLINK_CLASS,
3158
3941
  acrossElements: false,
3159
3942
  exclude: POSSIBLE_WEBLINK_EXCLUDE_SELECTORS,
3160
3943
  filter: (_textNode, term) => {
3161
- possibleWebLinks.add(term);
3944
+ possibleWebLink = term;
3162
3945
  return true;
3163
- }
3946
+ },
3947
+ each: (element) => composeWeblink(element, possibleWebLink)
3164
3948
  });
3165
- return possibleWebLinks;
3949
+ return possibleWeblinks;
3166
3950
  };
3167
- var validatePossibleWeblinks = (root) => {
3168
- const errors = [];
3169
- const possibleWebLinks = collectPossibleWebLinks(root);
3170
- for (const possibleWebLink of possibleWebLinks) {
3171
- errors.push(
3172
- createValidationIssue({
3173
- store: possibleWebLink,
3951
+ var TEXT_NODES_PER_STEP = 256;
3952
+ var MARK_EXCLUDED_PARENT_SELECTOR = [
3953
+ ...POSSIBLE_WEBLINK_EXCLUDE_SELECTORS,
3954
+ "script",
3955
+ "style",
3956
+ "title",
3957
+ "head",
3958
+ "html"
3959
+ ].join(", ");
3960
+ var createWeblinkMatchElement = (ownerDocument, text, storeId) => {
3961
+ const element = ownerDocument.createElement("mark");
3962
+ element.setAttribute("data-markjs", "true");
3963
+ element.setAttribute("class", POSSIBLE_WEBLINK_CLASS);
3964
+ element.setAttribute(STORE_ATTRIBUTE, storeId);
3965
+ element.textContent = text;
3966
+ return element;
3967
+ };
3968
+ function* findPossibleWeblinks(root) {
3969
+ const possibleWeblinks = /* @__PURE__ */ new Map();
3970
+ const ownerDocument = root.ownerDocument;
3971
+ const walker = ownerDocument.createTreeWalker(root, NodeFilter.SHOW_TEXT);
3972
+ const regex = new RegExp(WEB_URI_PATTERN, "gi");
3973
+ let nodesSinceStep = 0;
3974
+ for (let node = walker.nextNode(); node; node = walker.nextNode()) {
3975
+ if (++nodesSinceStep === TEXT_NODES_PER_STEP) {
3976
+ nodesSinceStep = 0;
3977
+ yield;
3978
+ }
3979
+ const text = node.textContent ?? "";
3980
+ if (!text) continue;
3981
+ const parent = node.parentNode;
3982
+ if (parent instanceof Element && parent.matches(MARK_EXCLUDED_PARENT_SELECTOR)) {
3983
+ continue;
3984
+ }
3985
+ regex.lastIndex = 0;
3986
+ for (let match = regex.exec(text); match; match = regex.exec(text)) {
3987
+ const storeId = getWeblinkMatchId(possibleWeblinks.size);
3988
+ possibleWeblinks.set(storeId, {
3989
+ weblink: match[0],
3990
+ elements: [createWeblinkMatchElement(ownerDocument, match[0], storeId)]
3991
+ });
3992
+ }
3993
+ }
3994
+ return possibleWeblinks;
3995
+ }
3996
+ var hasWeblinkMatches = (root) => root.getElementsByClassName(POSSIBLE_WEBLINK_CLASS).length > 0;
3997
+ function* validatePossibleWeblinksSteps(root) {
3998
+ const issues = [];
3999
+ let possibleWeblinks;
4000
+ if (hasWeblinkMatches(root)) {
4001
+ const cloneRoot = root.cloneNode(true);
4002
+ clearWeblinkMatches(cloneRoot);
4003
+ possibleWeblinks = markPossibleWeblinks(cloneRoot);
4004
+ } else {
4005
+ possibleWeblinks = yield* findPossibleWeblinks(root);
4006
+ }
4007
+ for (const [storeId, { elements }] of Array.from(possibleWeblinks)) {
4008
+ issues.push(
4009
+ createValidationIssue(null, {
4010
+ store: storeId,
3174
4011
  title: "Possible web link",
3175
4012
  kind: "possible-url",
3176
4013
  description: "This looks like a URL. Would you like to add weblink tags?",
3177
- level: "warning"
4014
+ level: "info",
4015
+ elements
3178
4016
  })
3179
4017
  );
3180
4018
  }
3181
- return errors;
4019
+ return issues;
4020
+ }
4021
+ var validatePossibleWeblinks = (root) => runSteps(validatePossibleWeblinksSteps(root));
4022
+ var clearWeblinkMatches = (editor) => {
4023
+ const instance = new import_mark2.default(editor);
4024
+ instance.unmark({
4025
+ className: POSSIBLE_WEBLINK_CLASS
4026
+ });
3182
4027
  };
3183
4028
 
3184
- // src/validation/validateHeadingHierarchy.ts
4029
+ // src/validation/validateHierarchy.ts
3185
4030
  var shouldSuppressWarning = (element) => {
3186
4031
  const closestBox = closestElementBySchema({
3187
4032
  element,
@@ -3190,46 +4035,66 @@ var shouldSuppressWarning = (element) => {
3190
4035
  });
3191
4036
  return !!closestBox;
3192
4037
  };
3193
- var getHierarchyLevel = (element) => {
3194
- const role = element.getAttribute("role");
4038
+ var isHeading = (elementHierarchy) => {
4039
+ return elementHierarchy === "heading";
4040
+ };
4041
+ var getValidLevels = (elementHierarchy) => {
4042
+ return isHeading(elementHierarchy) ? HEADING_LEVEL : BOX_LEVEL;
4043
+ };
4044
+ var getAttributeName2 = (elementHierarchy) => {
4045
+ return isHeading(elementHierarchy) ? "role" : "status";
4046
+ };
4047
+ var getElementSchemaCode = (elementHierarchy) => {
4048
+ return isHeading(elementHierarchy) ? HEADING_SCHEMA.code : BOX_SCHEMA.code;
4049
+ };
4050
+ var getHierarchyLevel = (element, elementHierarchy) => {
4051
+ const role = element.getAttribute(getAttributeName2(elementHierarchy));
3195
4052
  if (!role) return void 0;
3196
- const validHeadingLevel = HEADING_LEVEL.indexOf(role);
3197
- if (validHeadingLevel === -1) return void 0;
3198
- return validHeadingLevel;
4053
+ const index = getValidLevels(elementHierarchy).indexOf(role);
4054
+ if (index === -1) return void 0;
4055
+ return isHeading(elementHierarchy) ? index : index + 1;
3199
4056
  };
3200
- var validateHeadingHierarchy = (element) => {
4057
+ var validateHierarchy = (element, elementHierarchy) => {
3201
4058
  const errors = [];
3202
4059
  if (isDeletedElement(element)) {
3203
4060
  return errors;
3204
4061
  }
3205
- if (shouldSuppressWarning(element)) {
4062
+ if (shouldSuppressWarning(element) && isHeading(elementHierarchy)) {
3206
4063
  return errors;
3207
4064
  }
3208
- const level = getHierarchyLevel(element);
4065
+ const level = getHierarchyLevel(element, elementHierarchy);
3209
4066
  if (level === void 0) {
3210
4067
  return errors;
3211
4068
  }
3212
4069
  if (!element.parentElement) {
3213
4070
  return errors;
3214
4071
  }
3215
- const parentHeading = closestElementBySchema({
4072
+ const parentElement = closestElementBySchema({
3216
4073
  element: element.parentElement,
3217
- code: HEADING_SCHEMA.code,
4074
+ code: getElementSchemaCode(elementHierarchy),
3218
4075
  ignoreDeletedElements: true
3219
4076
  });
3220
- if (!parentHeading) {
4077
+ if (!parentElement) {
3221
4078
  if (level > 1) {
3222
- addValidationIssue(errors, {
3223
- store: getStore(element),
3224
- title: "Missing heading H1",
3225
- kind: "missing",
3226
- description: `H${level} is not under an H1. Please check the heading hierarchy.`,
3227
- level: "warning"
3228
- });
4079
+ if (isHeading(elementHierarchy)) {
4080
+ addValidationIssue(errors, element, {
4081
+ title: "Missing heading H1",
4082
+ kind: "missing",
4083
+ description: `H${level} is not under an H1. Please check the heading hierarchy.`,
4084
+ level: "warning"
4085
+ });
4086
+ } else {
4087
+ addValidationIssue(errors, element, {
4088
+ title: "Missing box level 1",
4089
+ kind: "missing",
4090
+ description: `Box level ${level} is not under a box level. Please check the box hierarchy.`,
4091
+ level: "warning"
4092
+ });
4093
+ }
3229
4094
  }
3230
4095
  return errors;
3231
4096
  }
3232
- const parentLevel = getHierarchyLevel(parentHeading);
4097
+ const parentLevel = getHierarchyLevel(parentElement, elementHierarchy);
3233
4098
  if (parentLevel === void 0) {
3234
4099
  return errors;
3235
4100
  }
@@ -3237,13 +4102,21 @@ var validateHeadingHierarchy = (element) => {
3237
4102
  if (level === expectedLevel) {
3238
4103
  return errors;
3239
4104
  }
3240
- addValidationIssue(errors, {
3241
- store: getStore(element),
3242
- title: "Invalid heading hierarchy",
3243
- kind: "forbidden",
3244
- description: `H${level} cannot follow H${parentLevel} directly. Please check the heading hierarchy.`,
3245
- level: "warning"
3246
- });
4105
+ if (isHeading(elementHierarchy)) {
4106
+ addValidationIssue(errors, element, {
4107
+ title: "Invalid heading hierarchy",
4108
+ kind: "forbidden",
4109
+ description: `H${level} cannot follow H${parentLevel} directly. Please check the heading hierarchy.`,
4110
+ level: "warning"
4111
+ });
4112
+ } else {
4113
+ addValidationIssue(errors, element, {
4114
+ title: "Invalid box hierarchy",
4115
+ kind: "forbidden",
4116
+ description: `Box level ${level} cannot follow box level ${parentLevel} directly. Please check the box hierarchy.`,
4117
+ level: "warning"
4118
+ });
4119
+ }
3247
4120
  return errors;
3248
4121
  };
3249
4122
 
@@ -3260,8 +4133,7 @@ var validateOlink = (element) => {
3260
4133
  if (isEmpty || isValidOrcid) {
3261
4134
  return errors;
3262
4135
  }
3263
- addValidationIssue(errors, {
3264
- store: getStore(element.parentElement ?? element),
4136
+ addValidationIssue(errors, element, {
3265
4137
  title: "Invalid ORCID",
3266
4138
  kind: "forbidden",
3267
4139
  description: "The ORCiD is not the correct format. Please check it and adjust.",
@@ -3270,62 +4142,439 @@ var validateOlink = (element) => {
3270
4142
  return errors;
3271
4143
  };
3272
4144
 
4145
+ // src/helpers/getReferenceFieldElements.ts
4146
+ var REFERENCE_PART_SELECTOR = REFERENCE_PART_CODES_ALLOWED_CHILDREN.map(
4147
+ ({ code }) => findSchemaByCode(code).tag.toLowerCase()
4148
+ ).join(", ");
4149
+ var REFERENCE_PART_OWNER_SELECTOR = `${REFERENCE_PART_SELECTOR}, ${URI_SCHEMA.tag.toLowerCase()}`;
4150
+ var getReferenceParts = (reference) => Array.from(
4151
+ reference.querySelectorAll(REFERENCE_PART_SELECTOR)
4152
+ ).filter((element) => {
4153
+ if (isInTrackedDeletion(element)) return false;
4154
+ const owner = element.parentElement?.closest(REFERENCE_PART_OWNER_SELECTOR);
4155
+ return !owner || !reference.contains(owner);
4156
+ });
4157
+ var getReferenceFieldElements = (reference) => getReferenceParts(reference).flatMap((element) => {
4158
+ const field = findReferenceFieldByElement(element);
4159
+ return field ? [{ field, element }] : [];
4160
+ });
4161
+
4162
+ // src/validation/validateReferenceMarkup.ts
4163
+ var PERSONNAME_ORDER_ROLES = ["first-last", "last-first"];
4164
+ var ARTIST_OTHERCLASS = "artist";
4165
+ var NOT_PERMITTED_ELEMENTS = [
4166
+ { tag: BIBLIOID_TAG.toLowerCase() },
4167
+ { tag: "publisher" },
4168
+ { tag: AUTHORGROUP_TAG.toLowerCase() }
4169
+ ];
4170
+ var BIBLIOMSET = BIBLIOMSET_TAG.toLowerCase();
4171
+ var PERSONNAME = PERSONNAME_TAG.toLowerCase();
4172
+ var CONFGROUP = CONFGROUP_TAG.toLowerCase();
4173
+ var LINK = LINK_TAG.toLowerCase();
4174
+ var URI = URI_SCHEMA.tag.toLowerCase();
4175
+ var NAME_PARTS = [SURNAME_TAG, FIRSTNAME_TAG, HONORIFIC_TAG].map((tag) => tag.toLowerCase()).join(", ");
4176
+ var CONFERENCE_FIELDS_AND_DELETIONS = [
4177
+ CONFTITLE_TAG,
4178
+ CONFDATES_TAG,
4179
+ ADDRESS_TAG
4180
+ ].map((tag) => tag.toLowerCase()).concat("span.del").join(", ");
4181
+ var LOOSE_MARKUP = [
4182
+ BIBLIOMSET,
4183
+ PERSONNAME,
4184
+ URI,
4185
+ NAME_PARTS,
4186
+ CONFDATES_TAG.toLowerCase()
4187
+ ].concat(NOT_PERMITTED_ELEMENTS.map(({ tag }) => tag)).join(", ");
4188
+ var hasValue = (element, attribute) => !!element.getAttribute(attribute)?.trim();
4189
+ var hasUntaggedConferenceText = (element) => Array.from(element.childNodes).some((child) => {
4190
+ if (child.nodeType === Node.TEXT_NODE) return !!child.textContent?.trim();
4191
+ return child instanceof Element && !child.matches(CONFERENCE_FIELDS_AND_DELETIONS) && hasUntaggedConferenceText(child);
4192
+ });
4193
+ var isExternalLink = (link) => !hasValue(link, LINKEND_ATTRIBUTE);
4194
+ var DOI_URL = /^https?:\/\/(?:dx\.)?doi\.org\//i;
4195
+ var pointsAtDoiOrg = (link) => DOI_URL.test(link.getAttribute(LINK_ATTRIBUTE)?.trim() ?? "");
4196
+ var hasNameOrder = (personname) => {
4197
+ const order = personname.getAttribute("role")?.replace(/\s+/g, "");
4198
+ return PERSONNAME_ORDER_ROLES.some((role) => role === order);
4199
+ };
4200
+ var hasLooseReferenceMarkup = (reference) => Array.from(reference.querySelectorAll(LOOSE_MARKUP)).some(
4201
+ (element) => !isInTrackedDeletion(element)
4202
+ );
4203
+ var validateReferenceMarkup = (reference, typeSchema) => {
4204
+ const select = (selector) => Array.from(reference.querySelectorAll(selector)).filter(
4205
+ (element) => !isInTrackedDeletion(element)
4206
+ );
4207
+ const relations = typeSchema.bibliomsetRelations ?? [];
4208
+ const sets = select(BIBLIOMSET);
4209
+ const misrelatedSets = sets.filter(
4210
+ (set) => !relations.some((relation) => relation === set.getAttribute("relation"))
4211
+ );
4212
+ const hasEverySet = relations.every(
4213
+ (relation) => sets.some((set) => set.getAttribute("relation") === relation)
4214
+ );
4215
+ const rules = {
4216
+ missing_id: hasValue(reference, XMLID_ATTRIBUTE) ? [] : [reference],
4217
+ bibliomset_relation: misrelatedSets,
4218
+ bibliomset_missing: hasEverySet || misrelatedSets.length > 0 ? [] : [reference],
4219
+ bibliomset_repeated: sets.filter(
4220
+ (set, index) => sets.slice(0, index).some(
4221
+ (earlier) => earlier.getAttribute("relation") === set.getAttribute("relation")
4222
+ )
4223
+ ),
4224
+ bibliomset_title: sets.filter(
4225
+ (set) => !Array.from(set.querySelectorAll(TITLE_TAG.toLowerCase())).some(
4226
+ (title) => !isInTrackedDeletion(title)
4227
+ )
4228
+ ),
4229
+ bibliomset_nested: sets.filter(
4230
+ (set) => !!set.parentElement?.closest(BIBLIOMSET)
4231
+ ),
4232
+ part_editor: select(EDITOR_TAG.toLowerCase()).filter(
4233
+ (editor) => editor.closest(BIBLIOMSET)?.getAttribute("relation") === PART_BIBLIOMSET_RELATION
4234
+ ),
4235
+ personname_role: select(PERSONNAME).filter(
4236
+ (personname) => !hasNameOrder(personname)
4237
+ ),
4238
+ name_outside_personname: select(NAME_PARTS).filter(
4239
+ (part) => !part.closest(PERSONNAME)
4240
+ ),
4241
+ othercredit_artist: typeSchema.code === "recording" ? select(OTHERCREDIT_TAG.toLowerCase()).filter(
4242
+ (credit) => credit.getAttribute("otherclass") !== ARTIST_OTHERCLASS
4243
+ ) : [],
4244
+ link_without_target: select(LINK).filter(
4245
+ (link) => isExternalLink(link) && !hasValue(link, LINK_ATTRIBUTE)
4246
+ ),
4247
+ doi_inside_uri: select(LINK).filter(
4248
+ (link) => isExternalLink(link) && hasLiveUri(link) && pointsAtDoiOrg(link)
4249
+ ),
4250
+ doi_outside_doi_org: select(LINK).filter(
4251
+ (link) => isExternalLink(link) && hasValue(link, LINK_ATTRIBUTE) && !hasLiveUri(link) && !pointsAtDoiOrg(link)
4252
+ ),
4253
+ uri_outside_link: select(URI).filter(
4254
+ (uri) => !uri.closest(LINK) && !uri.closest(REFERENCE_PART_SELECTOR)
4255
+ ),
4256
+ confgroup_text: select(CONFGROUP).filter(hasUntaggedConferenceText),
4257
+ confdates_outside_confgroup: select(CONFDATES_TAG.toLowerCase()).filter(
4258
+ (dates) => !dates.closest(CONFGROUP)
4259
+ )
4260
+ };
4261
+ const wrongElements = [
4262
+ ...typeSchema.replacedElements ?? [],
4263
+ ...NOT_PERMITTED_ELEMENTS
4264
+ ].map(
4265
+ ({ tag, replacement }) => ({
4266
+ code: "wrong_element",
4267
+ tag,
4268
+ replacement,
4269
+ elements: select(tag).filter((element) => !isPubMedIdBiblioid(element))
4270
+ })
4271
+ );
4272
+ const markup = Object.entries(rules).map(
4273
+ ([rule, elements]) => ({
4274
+ code: "markup",
4275
+ rule,
4276
+ elements
4277
+ })
4278
+ );
4279
+ return [...wrongElements, ...markup].filter(
4280
+ ({ elements }) => elements.length > 0
4281
+ );
4282
+ };
4283
+
4284
+ // src/validation/validateReferenceStructure.ts
4285
+ var validateReferenceStructure = (reference) => {
4286
+ const typeSchema = findReferenceTypeSchemaByElement(reference);
4287
+ if (!typeSchema) return [{ code: "unknown_type" }];
4288
+ const issues = [];
4289
+ const present = /* @__PURE__ */ new Set();
4290
+ for (const { field } of getReferenceFieldElements(reference)) {
4291
+ if (!present.has(field) && !typeSchema.allowedFields.includes(field)) {
4292
+ issues.push({ code: "not_allowed", field });
4293
+ }
4294
+ present.add(field);
4295
+ }
4296
+ for (const field of typeSchema.requiredFields) {
4297
+ const isSatisfied = field === "creators" ? present.has("author") || present.has("editor") : present.has(field);
4298
+ if (!isSatisfied) issues.push({ code: "missing", field });
4299
+ }
4300
+ return [...issues, ...validateReferenceMarkup(reference, typeSchema)];
4301
+ };
4302
+ var isSameMarkupIssue = (candidate, issue) => candidate.code === "markup" && issue.code === "markup" && candidate.rule === issue.rule || candidate.code === "wrong_element" && issue.code === "wrong_element" && candidate.tag === issue.tag;
4303
+ var getReferenceStructureIssueElements = (reference, issue) => {
4304
+ if (issue.code === "not_allowed") {
4305
+ return getReferenceFieldElements(reference).filter(({ field }) => field === issue.field).map(({ element }) => element);
4306
+ }
4307
+ if (issue.code !== "markup" && issue.code !== "wrong_element") return [];
4308
+ const found = validateReferenceStructure(reference).find(
4309
+ (candidate) => isSameMarkupIssue(candidate, issue)
4310
+ );
4311
+ return (found?.elements ?? []).filter((element) => element !== reference);
4312
+ };
4313
+
4314
+ // src/validation/validateReference.ts
4315
+ var getFieldLabel = (field, typeSchema) => {
4316
+ if (field === "creators") {
4317
+ return typeSchema.allowedFields.includes("editor") ? "Author or editor" : "Author";
4318
+ }
4319
+ return typeSchema.fieldLabels?.[field] ?? REFERENCE_FIELD_SCHEMAS[field].label;
4320
+ };
4321
+ var getBibliomsetRelationCopy = (typeSchema) => {
4322
+ const relations = typeSchema.bibliomsetRelations ?? [];
4323
+ return relations.length > 0 ? `${typeSchema.label} references use bibliomset with the relation ${relations.join(" and ")}. Please correct the relation.` : `${typeSchema.label} references do not use bibliomset. Please remove it and keep its contents.`;
4324
+ };
4325
+ var getMarkupCopy = (rule, typeSchema) => {
4326
+ switch (rule) {
4327
+ case "missing_id":
4328
+ return {
4329
+ title: "Reference ID missing",
4330
+ kind: "missing",
4331
+ description: "Every reference needs an xml:id. Please add one."
4332
+ };
4333
+ case "bibliomset_relation":
4334
+ return {
4335
+ title: "Wrong bibliomset for this reference type",
4336
+ kind: "forbidden",
4337
+ description: getBibliomsetRelationCopy(typeSchema)
4338
+ };
4339
+ case "bibliomset_missing":
4340
+ return {
4341
+ title: "Bibliomset missing",
4342
+ kind: "missing",
4343
+ description: `${typeSchema.label} references need one bibliomset with the relation ${(typeSchema.bibliomsetRelations ?? []).join(" and one with ")}. Please wrap the details in them.`
4344
+ };
4345
+ case "bibliomset_repeated":
4346
+ return {
4347
+ title: "Bibliomset repeated",
4348
+ kind: "forbidden",
4349
+ description: "A reference holds one bibliomset of each relation. Please move the details of the repeated bibliomset into the first one."
4350
+ };
4351
+ case "bibliomset_title":
4352
+ return {
4353
+ title: "Bibliomset without a title",
4354
+ kind: "missing",
4355
+ description: "Every bibliomset must contain a title. Please move its title into it or remove the bibliomset."
4356
+ };
4357
+ case "bibliomset_nested":
4358
+ return {
4359
+ title: "Bibliomset inside another bibliomset",
4360
+ kind: "forbidden",
4361
+ description: "A bibliomset cannot sit inside another bibliomset. Please move it out so the two sit side by side."
4362
+ };
4363
+ case "part_editor":
4364
+ return {
4365
+ title: "Editor tagged in the chapter part",
4366
+ kind: "forbidden",
4367
+ description: "The part bibliomset holds the chapter and its author. Please tag the name as an author or move the editor to the book bibliomset."
4368
+ };
4369
+ case "personname_role":
4370
+ return {
4371
+ title: "Name order not set",
4372
+ kind: "missing",
4373
+ description: `Every personname needs a role of ${PERSONNAME_ORDER_ROLES.join(" or ")}. Please set the name order.`
4374
+ };
4375
+ case "name_outside_personname":
4376
+ return {
4377
+ title: "Name not wrapped in personname",
4378
+ kind: "forbidden",
4379
+ description: "A surname, firstname or honorific must sit inside a personname. Please wrap the name parts."
4380
+ };
4381
+ case "othercredit_artist":
4382
+ return {
4383
+ title: "Artist credit not marked",
4384
+ kind: "missing",
4385
+ description: `The othercredit of a recording needs otherclass="${ARTIST_OTHERCLASS}". Please set it.`
4386
+ };
4387
+ case "link_without_target":
4388
+ return {
4389
+ title: "Link incomplete",
4390
+ kind: "missing",
4391
+ description: "A link needs an xlink:href. Please complete the link."
4392
+ };
4393
+ case "doi_outside_doi_org":
4394
+ return {
4395
+ title: "DOI not pointing at doi.org",
4396
+ kind: "forbidden",
4397
+ description: "A DOI link must point at a https://doi.org/ address. Please fix its xlink:href, or tag the address as a URL with a uri inside the link."
4398
+ };
4399
+ case "doi_inside_uri":
4400
+ return {
4401
+ title: "DOI tagged as a URL",
4402
+ kind: "forbidden",
4403
+ description: "A DOI link holds the DOI directly, without a uri inside it. Please remove the uri."
4404
+ };
4405
+ case "uri_outside_link":
4406
+ return {
4407
+ title: "URL not wrapped in a link",
4408
+ kind: "forbidden",
4409
+ description: "A uri must sit inside a link that carries the xlink:href. Please wrap it in a link."
4410
+ };
4411
+ case "confgroup_text":
4412
+ return {
4413
+ title: "Text directly inside confgroup",
4414
+ kind: "forbidden",
4415
+ description: "A confgroup cannot hold text directly. Please tag the text as conftitle or confdates."
4416
+ };
4417
+ case "confdates_outside_confgroup":
4418
+ return {
4419
+ title: "Conference dates outside confgroup",
4420
+ kind: "forbidden",
4421
+ description: "Conference dates must sit inside a confgroup. Please wrap them in one."
4422
+ };
4423
+ }
4424
+ };
4425
+ var getIssueCopy = (issue, typeSchema) => {
4426
+ if (issue.code === "unknown_type" || !typeSchema) {
4427
+ return {
4428
+ title: "Reference type not set",
4429
+ kind: "missing",
4430
+ description: "This reference has no recognised type, so its structure cannot be checked. Please set its reference type."
4431
+ };
4432
+ }
4433
+ const typeLabel = typeSchema.label.toLowerCase();
4434
+ if (issue.code === "markup") return getMarkupCopy(issue.rule, typeSchema);
4435
+ if (issue.code === "wrong_element") {
4436
+ return {
4437
+ title: `${issue.tag} not allowed`,
4438
+ kind: "forbidden",
4439
+ description: issue.replacement ? `${issue.tag} is not used by ${typeLabel} references. Please use ${issue.replacement} instead.` : `${issue.tag} is not used by ${typeLabel} references. Please remove it and keep its contents.`
4440
+ };
4441
+ }
4442
+ const fieldLabel = getFieldLabel(issue.field, typeSchema);
4443
+ switch (issue.code) {
4444
+ case "missing":
4445
+ return {
4446
+ title: `${fieldLabel} missing`,
4447
+ kind: "missing",
4448
+ description: `Please tag the ${fieldLabel.toLowerCase()} in this ${typeLabel} reference.`
4449
+ };
4450
+ case "not_allowed":
4451
+ return {
4452
+ title: `${fieldLabel} not allowed`,
4453
+ kind: "forbidden",
4454
+ description: `${fieldLabel} is not used by ${typeLabel} references. Please untag or delete it.`
4455
+ };
4456
+ }
4457
+ };
4458
+ var validateReference = (reference) => {
4459
+ if (isDeletedElement(reference)) return [];
4460
+ const isBibliographyEntry = !!closestElementBySchema({
4461
+ element: reference,
4462
+ code: "referenceBibliography"
4463
+ });
4464
+ if (!isBibliographyEntry) return [];
4465
+ const isTagged = getReferenceParts(reference).length > 0 || hasLooseReferenceMarkup(reference);
4466
+ if (!isTagged) return [];
4467
+ const typeSchema = findReferenceTypeSchemaByElement(reference);
4468
+ return validateReferenceStructure(reference).map(
4469
+ (issue) => createValidationIssue(reference, {
4470
+ level: "warning",
4471
+ elements: getReferenceStructureIssueElements(reference, issue),
4472
+ ...getIssueCopy(issue, typeSchema)
4473
+ })
4474
+ );
4475
+ };
4476
+
3273
4477
  // src/validation/validateXml.ts
3274
- var validateElement = (element, root, elementsToLink, linkElements, schemasToValidateAgainst) => {
4478
+ var ELEMENTS_PER_STEP = 64;
4479
+ var DEFAULT_TIME_BUDGET_MS = 8;
4480
+ var validateOwnElement = (element, {
4481
+ elementsToLink,
4482
+ linkElements,
4483
+ schemasToValidateAgainst,
4484
+ errors
4485
+ }) => {
3275
4486
  if (isIgnoredElement(element)) {
3276
- return [];
4487
+ return false;
3277
4488
  }
3278
- const errors = [];
3279
4489
  const schema = findSchemaByElement(element);
3280
- if (schema) {
3281
- if (schemasToValidateAgainst.includes(schema.code)) {
3282
- errors.push(...validateElementAgainstSchema(element, schema));
3283
- }
3284
- if (schema.tag === FOOTNOTE_SCHEMA.tag) {
3285
- errors.push(...validateFootnoteNumber(element));
3286
- }
3287
- if (schema.code === HEADING_SCHEMA.code) {
3288
- errors.push(...validateHeadingHierarchy(element));
3289
- }
3290
- if (schema.code === OLINK_SCHEMA.code) {
3291
- errors.push(...validateOlink(element));
3292
- }
3293
- errors.push(...validateLinkend(element, elementsToLink));
3294
- errors.push(...validateElementToLinkTo(element, linkElements));
3295
- if (isIgnoredValidation(schema.code)) {
3296
- return errors;
3297
- }
4490
+ if (!schema) {
4491
+ return true;
3298
4492
  }
3299
- for (const child of Array.from(element.children)) {
4493
+ if (schemasToValidateAgainst.includes(schema.code)) {
3300
4494
  errors.push(
3301
- ...validateElement(
3302
- child,
3303
- root,
3304
- elementsToLink,
3305
- linkElements,
3306
- schemasToValidateAgainst
3307
- )
4495
+ ...schema.code === BIBLIOMIXED_SCHEMA.code ? validateReference(element) : validateElementAgainstSchema(element, schema)
3308
4496
  );
3309
4497
  }
3310
- return errors;
4498
+ if (schema.tag === FOOTNOTE_SCHEMA.tag) {
4499
+ errors.push(...validateFootnoteNumber(element));
4500
+ }
4501
+ if (schema.code === HEADING_SCHEMA.code) {
4502
+ errors.push(...validateHierarchy(element, "heading"));
4503
+ }
4504
+ if (schema.code === BOX_SCHEMA.code) {
4505
+ errors.push(...validateHierarchy(element, "box"));
4506
+ }
4507
+ if (schema.code === OLINK_SCHEMA.code) {
4508
+ errors.push(...validateOlink(element));
4509
+ }
4510
+ errors.push(...validateLinkend(element, elementsToLink));
4511
+ errors.push(...validateElementToLinkTo(element, linkElements));
4512
+ return !isIgnoredValidation(schema.code);
3311
4513
  };
3312
- var validateXml = (xml, elementsToLink, linkElements, schemasToValidateAgainst) => {
4514
+ function* validateElements(xml, context) {
4515
+ const pending = Array.from(xml.children).reverse();
4516
+ let elementsSinceStep = 0;
4517
+ for (let element = pending.pop(); element; element = pending.pop()) {
4518
+ if (validateOwnElement(element, context)) {
4519
+ const { children } = element;
4520
+ for (let index = children.length - 1; index >= 0; index -= 1) {
4521
+ pending.push(children[index]);
4522
+ }
4523
+ }
4524
+ if (++elementsSinceStep === ELEMENTS_PER_STEP) {
4525
+ elementsSinceStep = 0;
4526
+ yield;
4527
+ }
4528
+ }
4529
+ }
4530
+ function* validateXmlSteps(xml, elementsToLink, linkElements, schemasToValidateAgainst) {
3313
4531
  const errors = [];
3314
4532
  errors.push(...validateConsecutiveFootnotes(xml));
3315
4533
  errors.push(...validateConsecutiveFootnoteCues(xml));
3316
- errors.push(...validatePossibleWeblinks(xml));
3317
- for (const child of Array.from(xml.children)) {
3318
- errors.push(
3319
- ...validateElement(
3320
- child,
3321
- xml,
3322
- elementsToLink,
3323
- linkElements,
3324
- schemasToValidateAgainst
3325
- )
3326
- );
3327
- }
4534
+ yield;
4535
+ errors.push(...yield* validatePossibleWeblinksSteps(xml));
4536
+ yield* validateElements(xml, {
4537
+ elementsToLink: new Set(elementsToLink),
4538
+ linkElements: new Set(linkElements),
4539
+ schemasToValidateAgainst,
4540
+ errors
4541
+ });
3328
4542
  return errors;
4543
+ }
4544
+ var validateXml = (xml, elementsToLink, linkElements, schemasToValidateAgainst) => runSteps(
4545
+ validateXmlSteps(
4546
+ xml,
4547
+ elementsToLink,
4548
+ linkElements,
4549
+ schemasToValidateAgainst
4550
+ )
4551
+ );
4552
+ var yieldToMainThread = () => {
4553
+ const scheduler = globalThis.scheduler;
4554
+ if (scheduler?.yield) return scheduler.yield();
4555
+ return new Promise((resolve) => setTimeout(resolve, 0));
4556
+ };
4557
+ var throwIfAborted = (signal) => {
4558
+ if (!signal?.aborted) return;
4559
+ throw signal.reason ?? new DOMException("Aborted", "AbortError");
4560
+ };
4561
+ var validateXmlAsync = async (xml, elementsToLink, linkElements, schemasToValidateAgainst, { signal, timeBudgetMs = DEFAULT_TIME_BUDGET_MS } = {}) => {
4562
+ const steps = validateXmlSteps(
4563
+ xml,
4564
+ elementsToLink,
4565
+ linkElements,
4566
+ schemasToValidateAgainst
4567
+ );
4568
+ let sliceStart = performance.now();
4569
+ for (; ; ) {
4570
+ throwIfAborted(signal);
4571
+ const step = steps.next();
4572
+ if (step.done) return step.value;
4573
+ if (performance.now() - sliceStart >= timeBudgetMs) {
4574
+ await yieldToMainThread();
4575
+ sliceStart = performance.now();
4576
+ }
4577
+ }
3329
4578
  };
3330
4579
 
3331
4580
  // src/helpers/getElementLinks.ts
@@ -3427,6 +4676,13 @@ var getAdjacentElement = ({
3427
4676
  LAYOUT_USER_ATTRIBUTE,
3428
4677
  LEFT_INDENT_ATTRIBUTE,
3429
4678
  LINKEND_ATTRIBUTE,
4679
+ LINK_BLOCKER_ROLES,
4680
+ LINK_TO_CROSS_CHECK,
4681
+ POSSIBLE_WEBLINK_CLASS,
4682
+ POSSIBLE_WEBLINK_EXCLUDE_SELECTORS,
4683
+ REFERENCE_FIELD_SCHEMAS,
4684
+ REFERENCE_PART_SELECTOR,
4685
+ REFERENCE_TYPE_SCHEMAS,
3430
4686
  RIGHT_INDENT_ATTRIBUTE,
3431
4687
  SCHEMAS,
3432
4688
  SPACE_ABOVE_ATTRIBUTE,
@@ -3439,22 +4695,47 @@ var getAdjacentElement = ({
3439
4695
  TRACK_CHANGES_ATTR_DATA_TIME,
3440
4696
  TRACK_CHANGES_ATTR_DATA_USERID,
3441
4697
  TRACK_CHANGES_ATTR_DATA_USERNAME,
4698
+ VALIDATION_IGNORED_ATTRIBUTE,
3442
4699
  XMLID_ATTRIBUTE,
4700
+ clearWeblinkMatches,
3443
4701
  closestElementBySchema,
3444
4702
  createElement,
4703
+ extractFootnoteNumber,
3445
4704
  findAttributeDefinitionByName,
4705
+ findElementLinkedTo,
4706
+ findReferenceFieldByElement,
4707
+ findReferenceTypeSchemaByElement,
3446
4708
  findSchemaByCode,
3447
4709
  findSchemaByElement,
3448
4710
  getAdjacentElement,
3449
4711
  getAttributeName,
4712
+ getEffectiveChildElements,
3450
4713
  getElementLinks,
4714
+ getPossibleWeblinks,
4715
+ getReferenceFieldElements,
4716
+ getReferenceParts,
4717
+ getReferenceStructureIssueElements,
3451
4718
  getStore,
3452
4719
  isAttributeRestricted,
3453
4720
  isDeletedElement,
3454
4721
  isIgnoredAttribute,
3455
4722
  isIgnoredElement,
3456
4723
  isTrackChangesSchema,
4724
+ markPossibleWeblinks,
3457
4725
  queryAllElementsBySchema,
3458
4726
  queryElementBySchema,
3459
- validateXml
4727
+ validateAttributes,
4728
+ validateConsecutiveFootnoteCues,
4729
+ validateConsecutiveFootnotes,
4730
+ validateElementAgainstSchema,
4731
+ validateElementToLinkTo,
4732
+ validateFootnoteNumber,
4733
+ validateHierarchy,
4734
+ validateLinkend,
4735
+ validateOlink,
4736
+ validatePossibleWeblinks,
4737
+ validatePossibleWeblinksSteps,
4738
+ validateReferenceStructure,
4739
+ validateXml,
4740
+ validateXmlAsync
3460
4741
  });