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.mjs CHANGED
@@ -17,6 +17,7 @@ var FIGURE_PLACEMENT_ATTRIBUTE = "data-figure-placement";
17
17
  var LAYOUT_CELL_WIDTH_ATTRIBUTE = "data-cell-width";
18
18
  var LAYOUT_TABLE_ORIENTATION_ATTRIBUTE = "data-table-orientation";
19
19
  var LAYOUT_TABLE_PLACEMENT_ATTRIBUTE = "data-table-placement";
20
+ var VALIDATION_IGNORED_ATTRIBUTE = "data-validation-ignored";
20
21
  var LAYOUT_ATTRIBUTES = [
21
22
  ALIGNMENT_ATTRIBUTE,
22
23
  LEFT_INDENT_ATTRIBUTE,
@@ -146,7 +147,7 @@ var EMPHASIS_SCHEMA = createSchema({
146
147
  ...TRACK_CHANGES_ATTRS,
147
148
  {
148
149
  name: "role",
149
- values: ["lowercase", "uppercase", "initialcaps"],
150
+ values: ["lowercase", "uppercase", "initialcaps", "Non breaking space"],
150
151
  defaultValue: "lowercase"
151
152
  }
152
153
  ],
@@ -646,6 +647,27 @@ var POEM_TAG = "POEM";
646
647
  var BIBLIOMIXED_TAG = "BIBLIOMIXED";
647
648
  var REFERENCE_BIBLIOGRAPHY_TAG = "BIBLIOGRAPHY";
648
649
  var BIBLIODIV_TAG = "BIBLIODIV";
650
+ var BIBLIOMSET_TAG = "BIBLIOMSET";
651
+ var EDITOR_TAG = "EDITOR";
652
+ var OTHERCREDIT_TAG = "OTHERCREDIT";
653
+ var TRANSLATOR_TAG = "TRANSLATOR";
654
+ var COLLAB_TAG = "COLLAB";
655
+ var PUBDATE_TAG = "PUBDATE";
656
+ var DATE_TAG = "DATE";
657
+ var PUBLISHERNAME_TAG = "PUBLISHERNAME";
658
+ var ADDRESS_TAG = "ADDRESS";
659
+ var CITY_TAG = "CITY";
660
+ var VOLUMENUM_TAG = "VOLUMENUM";
661
+ var ISSUENUM_TAG = "ISSUENUM";
662
+ var PAGENUMS_TAG = "PAGENUMS";
663
+ var PAGENUM_TAG = "PAGENUM";
664
+ var EDITION_TAG = "EDITION";
665
+ var PUB_ID_TAG = "PUB-ID";
666
+ var BIBLIOID_TAG = "BIBLIOID";
667
+ var BIBLIOMISC_TAG = "BIBLIOMISC";
668
+ var CONFGROUP_TAG = "CONFGROUP";
669
+ var CONFTITLE_TAG = "CONFTITLE";
670
+ var CONFDATES_TAG = "CONFDATES";
649
671
  var MATHPHRASE_TAG = "MATHPHRASE";
650
672
  var MATH_TAG = "MATH";
651
673
  var MERROR_TAG = "MERROR";
@@ -866,7 +888,8 @@ var EQUATION_SCHEMA = createSchema({
866
888
  ],
867
889
  allowedChildrenCodes: [
868
890
  { code: "mathphrase", required: true },
869
- { code: "caption1", required: false }
891
+ { code: "caption1", required: false },
892
+ { code: "tag", required: false }
870
893
  ]
871
894
  });
872
895
 
@@ -1791,6 +1814,82 @@ var TABLE_SCHEMA = createSchema({
1791
1814
  ]
1792
1815
  });
1793
1816
 
1817
+ // src/schema/elementSchemas/elements/heading.ts
1818
+ var HEADING_LEVEL = ["H0", "H1", "H2", "H3", "H4", "H5", "H6"];
1819
+ var HEADING_ROLES = [...HEADING_LEVEL, "vignette_group"];
1820
+ var HEADING_SCHEMA = createSchema({
1821
+ code: "heading",
1822
+ kind: "element",
1823
+ tag: SECTION_TAG,
1824
+ matchesElement: (element) => {
1825
+ const role = element.getAttribute("role");
1826
+ if (!role) return false;
1827
+ return HEADING_ROLES.includes(role);
1828
+ },
1829
+ requiredAttributes: [
1830
+ ...ID_ATTRS,
1831
+ "xmlid",
1832
+ {
1833
+ name: "role",
1834
+ values: HEADING_ROLES,
1835
+ defaultValue: "H1"
1836
+ }
1837
+ ],
1838
+ optionalAttributes: [...TRACK_CHANGES_ATTRS],
1839
+ defaultChildCode: "para",
1840
+ allowedChildrenCodes: [
1841
+ { code: "title1", required: false },
1842
+ { code: "label1", required: false },
1843
+ { code: "para", required: false },
1844
+ { code: "subtitle1", required: false },
1845
+ { code: "sidebar", required: false },
1846
+ { code: "epigraph", required: false },
1847
+ { code: "blockquote", required: false },
1848
+ { code: "ul", required: false },
1849
+ { code: "ol", required: false },
1850
+ { code: "poem", required: false },
1851
+ { code: "dialogue", required: false },
1852
+ { code: "appendix", required: false },
1853
+ { code: "table1", required: false },
1854
+ { code: "figure1", required: false },
1855
+ { code: "heading", required: false },
1856
+ { code: "footnoteSection", required: false },
1857
+ { code: "info1", required: false },
1858
+ { code: "equation", required: false }
1859
+ ]
1860
+ });
1861
+
1862
+ // src/schema/elementSchemas/elements/box.ts
1863
+ var BOX_LEVEL = ["box1", "box2", "box3", "box4", "box5"];
1864
+ var BOX_SCHEMA = createSchema({
1865
+ code: "sidebar",
1866
+ kind: "element",
1867
+ tag: SIDEBAR_TAG,
1868
+ requiredAttributes: [
1869
+ ...ID_ATTRS,
1870
+ {
1871
+ name: "status",
1872
+ values: BOX_LEVEL,
1873
+ defaultValue: "box1"
1874
+ }
1875
+ ],
1876
+ optionalAttributes: [
1877
+ ...TRACK_CHANGES_ATTRS,
1878
+ "xmlid",
1879
+ {
1880
+ name: "role",
1881
+ values: ["add-element", "change-para-box"],
1882
+ defaultValue: "add-element"
1883
+ }
1884
+ ],
1885
+ defaultChildCode: "para",
1886
+ allowedChildrenCodes: [
1887
+ { code: "para", required: false },
1888
+ { code: "title1", required: false },
1889
+ { code: "sidebar", required: false }
1890
+ ]
1891
+ });
1892
+
1794
1893
  // src/schema/elementSchemas/elements/title.ts
1795
1894
  var TITLE_SCHEMA = createSchema({
1796
1895
  code: "title1",
@@ -1808,7 +1907,7 @@ var TITLE_SCHEMA = createSchema({
1808
1907
  },
1809
1908
  {
1810
1909
  name: "title",
1811
- values: ["H1", "H2", "H3", "H4", "H5", "H6", "foot_note"],
1910
+ values: [...HEADING_LEVEL, ...BOX_LEVEL, "foot_note"],
1812
1911
  defaultValue: "H1"
1813
1912
  }
1814
1913
  ],
@@ -1886,36 +1985,8 @@ var BLOCKQUOTE_SCHEMA = createSchema({
1886
1985
  { code: "ul", required: false },
1887
1986
  { code: "ol", required: false },
1888
1987
  { code: "sidebar", required: false },
1889
- { code: "source1", required: false }
1890
- ]
1891
- });
1892
-
1893
- // src/schema/elementSchemas/elements/box.ts
1894
- var BOX_SCHEMA = createSchema({
1895
- code: "sidebar",
1896
- kind: "element",
1897
- tag: SIDEBAR_TAG,
1898
- requiredAttributes: [
1899
- ...ID_ATTRS,
1900
- {
1901
- name: "status",
1902
- values: ["box1", "box2", "box3", "box4", "box5"],
1903
- defaultValue: "box1"
1904
- }
1905
- ],
1906
- optionalAttributes: [
1907
- ...TRACK_CHANGES_ATTRS,
1908
- "xmlid",
1909
- {
1910
- name: "role",
1911
- values: ["add-element", "change-para-box"],
1912
- defaultValue: "add-element"
1913
- }
1914
- ],
1915
- defaultChildCode: "para",
1916
- allowedChildrenCodes: [
1917
- { code: "para", required: false },
1918
- { code: "title1", required: false }
1988
+ { code: "source1", required: false },
1989
+ { code: "tag", required: false }
1919
1990
  ]
1920
1991
  });
1921
1992
 
@@ -1972,7 +2043,10 @@ var EPIGRAPH_SCHEMA = createSchema({
1972
2043
  }
1973
2044
  ],
1974
2045
  defaultChildCode: "para",
1975
- allowedChildrenCodes: [{ code: "para", required: false }]
2046
+ allowedChildrenCodes: [
2047
+ { code: "para", required: false },
2048
+ { code: "tag", required: false }
2049
+ ]
1976
2050
  });
1977
2051
 
1978
2052
  // src/schema/elementSchemas/elements/footnoteSection.ts
@@ -2002,51 +2076,6 @@ var FOOTNOTE_SECTION_SCHEMA = createSchema({
2002
2076
  ]
2003
2077
  });
2004
2078
 
2005
- // src/schema/elementSchemas/elements/heading.ts
2006
- var HEADING_LEVEL = ["H0", "H1", "H2", "H3", "H4", "H5", "H6"];
2007
- var HEADING_ROLES = [...HEADING_LEVEL, "vignette_group"];
2008
- var HEADING_SCHEMA = createSchema({
2009
- code: "heading",
2010
- kind: "element",
2011
- tag: SECTION_TAG,
2012
- matchesElement: (element) => {
2013
- const role = element.getAttribute("role");
2014
- if (!role) return false;
2015
- return HEADING_ROLES.includes(role);
2016
- },
2017
- requiredAttributes: [
2018
- ...ID_ATTRS,
2019
- "xmlid",
2020
- {
2021
- name: "role",
2022
- values: HEADING_ROLES,
2023
- defaultValue: "H1"
2024
- }
2025
- ],
2026
- optionalAttributes: [...TRACK_CHANGES_ATTRS],
2027
- defaultChildCode: "para",
2028
- allowedChildrenCodes: [
2029
- { code: "title1", required: false },
2030
- { code: "label1", required: false },
2031
- { code: "para", required: false },
2032
- { code: "subtitle1", required: false },
2033
- { code: "sidebar", required: false },
2034
- { code: "epigraph", required: false },
2035
- { code: "blockquote", required: false },
2036
- { code: "ul", required: false },
2037
- { code: "ol", required: false },
2038
- { code: "poem", required: false },
2039
- { code: "dialogue", required: false },
2040
- { code: "appendix", required: false },
2041
- { code: "table1", required: false },
2042
- { code: "figure1", required: false },
2043
- { code: "heading", required: false },
2044
- { code: "footnoteSection", required: false },
2045
- { code: "info1", required: false },
2046
- { code: "equation", required: false }
2047
- ]
2048
- });
2049
-
2050
2079
  // src/schema/elementSchemas/elements/info.ts
2051
2080
  var INFO_SCHEMA = createSchema({
2052
2081
  code: "info1",
@@ -2091,28 +2120,6 @@ var MATHPHRASE_SCHEMA = createSchema({
2091
2120
  allowedChildrenCodes: [{ code: MATH_SCHEMA.code, required: true }]
2092
2121
  });
2093
2122
 
2094
- // src/schema/elementSchemas/elements/reference/bibliodiv.ts
2095
- var BIBLIODIV_SCHEMA = createSchema({
2096
- code: "bibliodiv",
2097
- kind: "element",
2098
- tag: BIBLIODIV_TAG,
2099
- requiredAttributes: [
2100
- ...ID_ATTRS,
2101
- {
2102
- name: "role",
2103
- values: ["H1", "H2", "H3", "H4", "H5", "H6"],
2104
- defaultValue: "H1"
2105
- }
2106
- ],
2107
- optionalAttributes: [],
2108
- allowedChildrenCodes: [
2109
- { code: "bibliodiv", required: false },
2110
- { code: "referenceBibliomixed", required: false },
2111
- { code: "para", required: false },
2112
- { code: "title1", required: false }
2113
- ]
2114
- });
2115
-
2116
2123
  // src/schema/elementSchemas/elements/reference/bibliography.ts
2117
2124
  var REFERENCE_BIBLIOGRAPHY_SCHEMA = createSchema({
2118
2125
  code: "referenceBibliography",
@@ -2141,6 +2148,31 @@ var REFERENCE_BIBLIOGRAPHY_SCHEMA = createSchema({
2141
2148
  ]
2142
2149
  });
2143
2150
 
2151
+ // src/schema/shared/allowedReferenceChildren.ts
2152
+ var REFERENCE_PART_CODES_ALLOWED_CHILDREN = [
2153
+ { code: "author", required: false },
2154
+ { code: "editor", required: false },
2155
+ { code: "othercredit", required: false },
2156
+ { code: "translator", required: false },
2157
+ { code: "collab", required: false },
2158
+ { code: "title1", required: false },
2159
+ { code: "pubdate", required: false },
2160
+ { code: "date", required: false },
2161
+ { code: "publishername", required: false },
2162
+ { code: "orgname", required: false },
2163
+ { code: "address", required: false },
2164
+ { code: "volumenum", required: false },
2165
+ { code: "issuenum", required: false },
2166
+ { code: "pagenums", required: false },
2167
+ { code: "pagenum", required: false },
2168
+ { code: "edition", required: false },
2169
+ { code: "link", required: false },
2170
+ { code: "pubId", required: false },
2171
+ { code: "biblioid", required: false },
2172
+ { code: "bibliomisc", required: false },
2173
+ { code: "confgroup", required: false }
2174
+ ];
2175
+
2144
2176
  // src/schema/elementSchemas/elements/reference/bibliomixed.ts
2145
2177
  var BIBLIOMIXED_SCHEMA = createSchema({
2146
2178
  code: "referenceBibliomixed",
@@ -2152,82 +2184,390 @@ var BIBLIOMIXED_SCHEMA = createSchema({
2152
2184
  TRACK_CHANGES_ATTR_DATA_USERID,
2153
2185
  TRACK_CHANGES_ATTR_DATA_DATE
2154
2186
  ],
2155
- allowedChildrenCodes: []
2187
+ allowedChildrenCodes: [
2188
+ { code: "bibliomset", required: false },
2189
+ ...REFERENCE_PART_CODES_ALLOWED_CHILDREN,
2190
+ ...ATOM_CODES_ALLOWED_CHILDREN
2191
+ ]
2156
2192
  });
2157
2193
 
2158
- // src/schema/elementSchemas/elements/index.ts
2159
- var ELEMENT_SCHEMAS = {
2160
- bibliodiv: BIBLIODIV_SCHEMA,
2161
- referenceBibliography: REFERENCE_BIBLIOGRAPHY_SCHEMA,
2162
- referenceBibliomixed: BIBLIOMIXED_SCHEMA,
2163
- para: PARA_SCHEMA,
2164
- title1: TITLE_SCHEMA,
2165
- footnote: FOOTNOTE_SCHEMA,
2166
- footnoteno: FOOTNOTE_NUMBER_SCHEMA,
2167
- olink: OLINK_SCHEMA,
2168
- firstname: FIRSTNAME_SCHEMA,
2169
- surname: SURNAME_SCHEMA,
2170
- honorific: HONORIFIC_SCHEMA,
2171
- orgname: ORGNAME_SCHEMA,
2172
- email: EMAIL_SCHEMA,
2173
- org: ORG_SCHEMA,
2174
- degrees: DEGREES_SCHEMA,
2175
- dialogue: DIALOGUE_SCHEMA,
2176
- line: LINE_SCHEMA,
2177
- linegroup: LINE_GROUP_SCHEMA,
2178
- speaker: SPEAKER_SCHEMA,
2179
- equation: EQUATION_SCHEMA,
2180
- math: MATH_SCHEMA,
2181
- mathphrase: MATHPHRASE_SCHEMA,
2182
- merror: MERROR_SCHEMA,
2183
- mfrac: MFRAC_SCHEMA,
2184
- mi: MI_SCHEMA,
2185
- mmultiscripts: MMULTISCRIPTS_SCHEMA,
2186
- mn: MN_SCHEMA,
2187
- mo: MO_SCHEMA,
2188
- mover: MOVER_SCHEMA,
2189
- mpadded: MPADDED_SCHEMA,
2190
- mphantom: MPHANTOM_SCHEMA,
2191
- mprescripts: MPRESCRIPTS_SCHEMA,
2192
- mroot: MROOT_SCHEMA,
2193
- mrow: MROW_SCHEMA,
2194
- ms: MS_SCHEMA,
2195
- mspace: MSPACE_SCHEMA,
2196
- msqrt: MSQRT_SCHEMA,
2197
- mstyle: MSTYLE_SCHEMA,
2198
- msub: MSUB_SCHEMA,
2199
- msubsup: MSUBSUP_SCHEMA,
2200
- msup: MSUP_SCHEMA,
2201
- mtable: MTABLE_SCHEMA,
2202
- mtd: MTD_SCHEMA,
2203
- mtext: MTEXT_SCHEMA,
2204
- mtr: MTR_SCHEMA,
2205
- munder: MUNDER_SCHEMA,
2206
- munderover: MUNDEROVER_SCHEMA,
2207
- img: IMG_SCHEMA,
2208
- alttext: ALTTEXT_SCHEMA,
2209
- imageobject: IMAGEOBJECT_SCHEMA,
2210
- mediaobject: MEDIAOBJECT_SCHEMA,
2211
- caption1: CAPTION_SCHEMA,
2212
- figsource: FIGSOURCE_SCHEMA,
2213
- fignote: FIGNOTE_SCHEMA,
2214
- figure1: FIGURE_SCHEMA,
2215
- informalfigure: INFORMALFIGURE_SCHEMA,
2216
- keywordset: KEYWORDSET_SCHEMA,
2217
- keyword: KEYWORD_SCHEMA,
2218
- punc: PUNC_SCHEMA,
2219
- label1: LABEL_SCHEMA,
2220
- li: LI_SCHEMA,
2221
- ol: OL_SCHEMA,
2222
- ul: UL_SCHEMA,
2223
- token: TOKEN_SCHEMA,
2224
- tag: TAG_SCHEMA,
2225
- lrh: LRH_SCHEMA,
2226
- rrh: RRH_SCHEMA,
2227
- source1: SOURCE_SCHEMA,
2228
- subtitle1: SUBTITLE_SCHEMA,
2229
- table1: TABLE_SCHEMA,
2230
- tgroup: TGROUP_SCHEMA,
2194
+ // src/schema/elementSchemas/elements/reference/bibliodiv.ts
2195
+ var BIBLIODIV_SCHEMA = createSchema({
2196
+ code: "bibliodiv",
2197
+ kind: "element",
2198
+ tag: BIBLIODIV_TAG,
2199
+ requiredAttributes: [
2200
+ ...ID_ATTRS,
2201
+ "role"
2202
+ ],
2203
+ optionalAttributes: [],
2204
+ allowedChildrenCodes: [
2205
+ { code: "bibliodiv", required: false },
2206
+ { code: "referenceBibliomixed", required: false },
2207
+ { code: "para", required: false },
2208
+ { code: "title1", required: false }
2209
+ ]
2210
+ });
2211
+
2212
+ // src/schema/elementSchemas/elements/reference/bibliomset.ts
2213
+ var CONTAINER_BIBLIOMSET_RELATIONS = ["book", "journal"];
2214
+ var PART_BIBLIOMSET_RELATION = "part";
2215
+ var BIBLIOMSET_SCHEMA = createSchema({
2216
+ code: "bibliomset",
2217
+ kind: "element",
2218
+ tag: BIBLIOMSET_TAG,
2219
+ requiredAttributes: [
2220
+ {
2221
+ name: "relation",
2222
+ values: [
2223
+ PART_BIBLIOMSET_RELATION,
2224
+ "article",
2225
+ ...CONTAINER_BIBLIOMSET_RELATIONS
2226
+ ],
2227
+ defaultValue: PART_BIBLIOMSET_RELATION
2228
+ }
2229
+ ],
2230
+ optionalAttributes: [...ID_ATTRS],
2231
+ allowedChildrenCodes: [
2232
+ ...REFERENCE_PART_CODES_ALLOWED_CHILDREN,
2233
+ ...ATOM_CODES_ALLOWED_CHILDREN
2234
+ ]
2235
+ });
2236
+
2237
+ // src/schema/elementSchemas/elements/reference/editor.ts
2238
+ var EDITOR_SCHEMA = createSchema({
2239
+ code: "editor",
2240
+ kind: "element",
2241
+ tag: EDITOR_TAG,
2242
+ requiredAttributes: [],
2243
+ optionalAttributes: [...ID_ATTRS],
2244
+ allowedChildrenCodes: [
2245
+ { code: "personname", required: false },
2246
+ { code: "orgname", required: false },
2247
+ ...ATOM_CODES_ALLOWED_CHILDREN
2248
+ ]
2249
+ });
2250
+
2251
+ // src/schema/elementSchemas/elements/reference/othercredit.ts
2252
+ var OTHERCREDIT_SCHEMA = createSchema({
2253
+ code: "othercredit",
2254
+ kind: "element",
2255
+ tag: OTHERCREDIT_TAG,
2256
+ requiredAttributes: [],
2257
+ optionalAttributes: [...ID_ATTRS, "class", "otherclass"],
2258
+ allowedChildrenCodes: [
2259
+ { code: "personname", required: false },
2260
+ { code: "orgname", required: false },
2261
+ ...ATOM_CODES_ALLOWED_CHILDREN
2262
+ ]
2263
+ });
2264
+
2265
+ // src/schema/elementSchemas/elements/reference/translator.ts
2266
+ var TRANSLATOR_SCHEMA = createSchema({
2267
+ code: "translator",
2268
+ kind: "element",
2269
+ tag: TRANSLATOR_TAG,
2270
+ requiredAttributes: [],
2271
+ optionalAttributes: [...ID_ATTRS],
2272
+ allowedChildrenCodes: [
2273
+ { code: "personname", required: false },
2274
+ { code: "orgname", required: false },
2275
+ ...ATOM_CODES_ALLOWED_CHILDREN
2276
+ ]
2277
+ });
2278
+
2279
+ // src/schema/elementSchemas/elements/reference/collab.ts
2280
+ var COLLAB_SCHEMA = createSchema({
2281
+ code: "collab",
2282
+ kind: "element",
2283
+ tag: COLLAB_TAG,
2284
+ requiredAttributes: [],
2285
+ optionalAttributes: [...ID_ATTRS],
2286
+ allowedChildrenCodes: [
2287
+ { code: "orgname", required: false },
2288
+ { code: "personname", required: false },
2289
+ ...ATOM_CODES_ALLOWED_CHILDREN
2290
+ ]
2291
+ });
2292
+
2293
+ // src/schema/elementSchemas/elements/reference/pubdate.ts
2294
+ var PUBDATE_SCHEMA = createSchema({
2295
+ code: "pubdate",
2296
+ kind: "element",
2297
+ tag: PUBDATE_TAG,
2298
+ requiredAttributes: [],
2299
+ optionalAttributes: [...ID_ATTRS],
2300
+ allowedChildrenCodes: [
2301
+ ...ATOM_CODES_ALLOWED_CHILDREN
2302
+ ]
2303
+ });
2304
+
2305
+ // src/schema/elementSchemas/elements/reference/date.ts
2306
+ var ACCESSED_DATE_ROLE = "accessed";
2307
+ var DATE_SCHEMA = createSchema({
2308
+ code: "date",
2309
+ kind: "element",
2310
+ tag: DATE_TAG,
2311
+ requiredAttributes: [],
2312
+ optionalAttributes: [...ID_ATTRS, "role"],
2313
+ allowedChildrenCodes: [...ATOM_CODES_ALLOWED_CHILDREN]
2314
+ });
2315
+
2316
+ // src/schema/elementSchemas/elements/reference/publishername.ts
2317
+ var PUBLISHERNAME_SCHEMA = createSchema({
2318
+ code: "publishername",
2319
+ kind: "element",
2320
+ tag: PUBLISHERNAME_TAG,
2321
+ requiredAttributes: [],
2322
+ optionalAttributes: [...ID_ATTRS],
2323
+ allowedChildrenCodes: [
2324
+ ...ATOM_CODES_ALLOWED_CHILDREN
2325
+ ]
2326
+ });
2327
+
2328
+ // src/schema/elementSchemas/elements/reference/address.ts
2329
+ var ADDRESS_SCHEMA = createSchema({
2330
+ code: "address",
2331
+ kind: "element",
2332
+ tag: ADDRESS_TAG,
2333
+ requiredAttributes: [],
2334
+ optionalAttributes: [...ID_ATTRS],
2335
+ allowedChildrenCodes: [
2336
+ { code: "city", required: false },
2337
+ ...ATOM_CODES_ALLOWED_CHILDREN
2338
+ ]
2339
+ });
2340
+
2341
+ // src/schema/elementSchemas/elements/reference/city.ts
2342
+ var CITY_SCHEMA = createSchema({
2343
+ code: "city",
2344
+ kind: "element",
2345
+ tag: CITY_TAG,
2346
+ requiredAttributes: [],
2347
+ optionalAttributes: [...ID_ATTRS],
2348
+ allowedChildrenCodes: [
2349
+ ...ATOM_CODES_ALLOWED_CHILDREN
2350
+ ]
2351
+ });
2352
+
2353
+ // src/schema/elementSchemas/elements/reference/volumenum.ts
2354
+ var VOLUMENUM_SCHEMA = createSchema({
2355
+ code: "volumenum",
2356
+ kind: "element",
2357
+ tag: VOLUMENUM_TAG,
2358
+ requiredAttributes: [],
2359
+ optionalAttributes: [...ID_ATTRS],
2360
+ allowedChildrenCodes: [
2361
+ ...ATOM_CODES_ALLOWED_CHILDREN
2362
+ ]
2363
+ });
2364
+
2365
+ // src/schema/elementSchemas/elements/reference/issuenum.ts
2366
+ var ISSUENUM_SCHEMA = createSchema({
2367
+ code: "issuenum",
2368
+ kind: "element",
2369
+ tag: ISSUENUM_TAG,
2370
+ requiredAttributes: [],
2371
+ optionalAttributes: [...ID_ATTRS],
2372
+ allowedChildrenCodes: [
2373
+ ...ATOM_CODES_ALLOWED_CHILDREN
2374
+ ]
2375
+ });
2376
+
2377
+ // src/schema/elementSchemas/elements/reference/pagenums.ts
2378
+ var PAGENUMS_SCHEMA = createSchema({
2379
+ code: "pagenums",
2380
+ kind: "element",
2381
+ tag: PAGENUMS_TAG,
2382
+ requiredAttributes: [],
2383
+ optionalAttributes: [...ID_ATTRS],
2384
+ allowedChildrenCodes: [
2385
+ ...ATOM_CODES_ALLOWED_CHILDREN
2386
+ ]
2387
+ });
2388
+
2389
+ // src/schema/elementSchemas/elements/reference/pagenum.ts
2390
+ var PAGENUM_SCHEMA = createSchema({
2391
+ code: "pagenum",
2392
+ kind: "element",
2393
+ tag: PAGENUM_TAG,
2394
+ requiredAttributes: [],
2395
+ optionalAttributes: [...ID_ATTRS],
2396
+ allowedChildrenCodes: [
2397
+ ...ATOM_CODES_ALLOWED_CHILDREN
2398
+ ]
2399
+ });
2400
+
2401
+ // src/schema/elementSchemas/elements/reference/edition.ts
2402
+ var EDITION_SCHEMA = createSchema({
2403
+ code: "edition",
2404
+ kind: "element",
2405
+ tag: EDITION_TAG,
2406
+ requiredAttributes: [],
2407
+ optionalAttributes: [...ID_ATTRS],
2408
+ allowedChildrenCodes: [
2409
+ ...ATOM_CODES_ALLOWED_CHILDREN
2410
+ ]
2411
+ });
2412
+
2413
+ // src/schema/elementSchemas/elements/reference/pubId.ts
2414
+ var PUB_ID_SCHEMA = createSchema({
2415
+ code: "pubId",
2416
+ kind: "element",
2417
+ tag: PUB_ID_TAG,
2418
+ requiredAttributes: [],
2419
+ optionalAttributes: [...ID_ATTRS, "pub-id-type", "assigning-authority"],
2420
+ allowedChildrenCodes: [
2421
+ ...ATOM_CODES_ALLOWED_CHILDREN
2422
+ ]
2423
+ });
2424
+
2425
+ // src/schema/helpers/matchesSchemaTag.ts
2426
+ var matchesSchemaTag = (element, tag) => element.tagName.toUpperCase() === tag.toUpperCase();
2427
+
2428
+ // src/schema/elementSchemas/elements/reference/biblioid.ts
2429
+ var PUBMED_ID_BIBLIOID_CLASS = "other";
2430
+ var PUBMED_ID_BIBLIOID_OTHERCLASS = "pmid";
2431
+ var BIBLIOID_SCHEMA = createSchema({
2432
+ code: "biblioid",
2433
+ kind: "element",
2434
+ tag: BIBLIOID_TAG,
2435
+ requiredAttributes: [],
2436
+ optionalAttributes: [...ID_ATTRS, "class", "otherclass"],
2437
+ allowedChildrenCodes: [...ATOM_CODES_ALLOWED_CHILDREN]
2438
+ });
2439
+ var isPubMedIdBiblioid = (element) => matchesSchemaTag(element, BIBLIOID_TAG) && element.classList.contains(PUBMED_ID_BIBLIOID_CLASS) && element.getAttribute("otherclass") === PUBMED_ID_BIBLIOID_OTHERCLASS;
2440
+
2441
+ // src/schema/elementSchemas/elements/reference/bibliomisc.ts
2442
+ var LEGAL_REFERENCE_BIBLIOMISC_ROLE = "legalRef";
2443
+ var BIBLIOMISC_SCHEMA = createSchema({
2444
+ code: "bibliomisc",
2445
+ kind: "element",
2446
+ tag: BIBLIOMISC_TAG,
2447
+ requiredAttributes: [],
2448
+ optionalAttributes: [...ID_ATTRS, "role"],
2449
+ allowedChildrenCodes: [...ATOM_CODES_ALLOWED_CHILDREN]
2450
+ });
2451
+
2452
+ // src/schema/elementSchemas/elements/reference/confgroup.ts
2453
+ var CONFGROUP_SCHEMA = createSchema({
2454
+ code: "confgroup",
2455
+ kind: "element",
2456
+ tag: CONFGROUP_TAG,
2457
+ requiredAttributes: [],
2458
+ optionalAttributes: [...ID_ATTRS],
2459
+ allowedChildrenCodes: [
2460
+ { code: "conftitle", required: false },
2461
+ { code: "address", required: false },
2462
+ ...ATOM_CODES_ALLOWED_CHILDREN
2463
+ ]
2464
+ });
2465
+
2466
+ // src/schema/elementSchemas/elements/reference/conftitle.ts
2467
+ var CONFTITLE_SCHEMA = createSchema({
2468
+ code: "conftitle",
2469
+ kind: "element",
2470
+ tag: CONFTITLE_TAG,
2471
+ requiredAttributes: [],
2472
+ optionalAttributes: [...ID_ATTRS],
2473
+ allowedChildrenCodes: [
2474
+ ...ATOM_CODES_ALLOWED_CHILDREN
2475
+ ]
2476
+ });
2477
+
2478
+ // src/schema/elementSchemas/elements/index.ts
2479
+ var ELEMENT_SCHEMAS = {
2480
+ bibliodiv: BIBLIODIV_SCHEMA,
2481
+ referenceBibliography: REFERENCE_BIBLIOGRAPHY_SCHEMA,
2482
+ referenceBibliomixed: BIBLIOMIXED_SCHEMA,
2483
+ bibliomset: BIBLIOMSET_SCHEMA,
2484
+ editor: EDITOR_SCHEMA,
2485
+ othercredit: OTHERCREDIT_SCHEMA,
2486
+ translator: TRANSLATOR_SCHEMA,
2487
+ collab: COLLAB_SCHEMA,
2488
+ pubdate: PUBDATE_SCHEMA,
2489
+ date: DATE_SCHEMA,
2490
+ publishername: PUBLISHERNAME_SCHEMA,
2491
+ address: ADDRESS_SCHEMA,
2492
+ city: CITY_SCHEMA,
2493
+ volumenum: VOLUMENUM_SCHEMA,
2494
+ issuenum: ISSUENUM_SCHEMA,
2495
+ pagenums: PAGENUMS_SCHEMA,
2496
+ pagenum: PAGENUM_SCHEMA,
2497
+ edition: EDITION_SCHEMA,
2498
+ pubId: PUB_ID_SCHEMA,
2499
+ biblioid: BIBLIOID_SCHEMA,
2500
+ bibliomisc: BIBLIOMISC_SCHEMA,
2501
+ confgroup: CONFGROUP_SCHEMA,
2502
+ conftitle: CONFTITLE_SCHEMA,
2503
+ para: PARA_SCHEMA,
2504
+ title1: TITLE_SCHEMA,
2505
+ footnote: FOOTNOTE_SCHEMA,
2506
+ footnoteno: FOOTNOTE_NUMBER_SCHEMA,
2507
+ olink: OLINK_SCHEMA,
2508
+ firstname: FIRSTNAME_SCHEMA,
2509
+ surname: SURNAME_SCHEMA,
2510
+ honorific: HONORIFIC_SCHEMA,
2511
+ orgname: ORGNAME_SCHEMA,
2512
+ email: EMAIL_SCHEMA,
2513
+ org: ORG_SCHEMA,
2514
+ degrees: DEGREES_SCHEMA,
2515
+ dialogue: DIALOGUE_SCHEMA,
2516
+ line: LINE_SCHEMA,
2517
+ linegroup: LINE_GROUP_SCHEMA,
2518
+ speaker: SPEAKER_SCHEMA,
2519
+ equation: EQUATION_SCHEMA,
2520
+ math: MATH_SCHEMA,
2521
+ mathphrase: MATHPHRASE_SCHEMA,
2522
+ merror: MERROR_SCHEMA,
2523
+ mfrac: MFRAC_SCHEMA,
2524
+ mi: MI_SCHEMA,
2525
+ mmultiscripts: MMULTISCRIPTS_SCHEMA,
2526
+ mn: MN_SCHEMA,
2527
+ mo: MO_SCHEMA,
2528
+ mover: MOVER_SCHEMA,
2529
+ mpadded: MPADDED_SCHEMA,
2530
+ mphantom: MPHANTOM_SCHEMA,
2531
+ mprescripts: MPRESCRIPTS_SCHEMA,
2532
+ mroot: MROOT_SCHEMA,
2533
+ mrow: MROW_SCHEMA,
2534
+ ms: MS_SCHEMA,
2535
+ mspace: MSPACE_SCHEMA,
2536
+ msqrt: MSQRT_SCHEMA,
2537
+ mstyle: MSTYLE_SCHEMA,
2538
+ msub: MSUB_SCHEMA,
2539
+ msubsup: MSUBSUP_SCHEMA,
2540
+ msup: MSUP_SCHEMA,
2541
+ mtable: MTABLE_SCHEMA,
2542
+ mtd: MTD_SCHEMA,
2543
+ mtext: MTEXT_SCHEMA,
2544
+ mtr: MTR_SCHEMA,
2545
+ munder: MUNDER_SCHEMA,
2546
+ munderover: MUNDEROVER_SCHEMA,
2547
+ img: IMG_SCHEMA,
2548
+ alttext: ALTTEXT_SCHEMA,
2549
+ imageobject: IMAGEOBJECT_SCHEMA,
2550
+ mediaobject: MEDIAOBJECT_SCHEMA,
2551
+ caption1: CAPTION_SCHEMA,
2552
+ figsource: FIGSOURCE_SCHEMA,
2553
+ fignote: FIGNOTE_SCHEMA,
2554
+ figure1: FIGURE_SCHEMA,
2555
+ informalfigure: INFORMALFIGURE_SCHEMA,
2556
+ keywordset: KEYWORDSET_SCHEMA,
2557
+ keyword: KEYWORD_SCHEMA,
2558
+ punc: PUNC_SCHEMA,
2559
+ label1: LABEL_SCHEMA,
2560
+ li: LI_SCHEMA,
2561
+ ol: OL_SCHEMA,
2562
+ ul: UL_SCHEMA,
2563
+ token: TOKEN_SCHEMA,
2564
+ tag: TAG_SCHEMA,
2565
+ lrh: LRH_SCHEMA,
2566
+ rrh: RRH_SCHEMA,
2567
+ source1: SOURCE_SCHEMA,
2568
+ subtitle1: SUBTITLE_SCHEMA,
2569
+ table1: TABLE_SCHEMA,
2570
+ tgroup: TGROUP_SCHEMA,
2231
2571
  table: HTML_TABLE_SCHEMA,
2232
2572
  thead: THEAD_SCHEMA,
2233
2573
  tbody: TBODY_SCHEMA,
@@ -2299,7 +2639,10 @@ var INLINEEQUATION_SCHEMA = createSchema({
2299
2639
  defaultValue: "added"
2300
2640
  }
2301
2641
  ],
2302
- allowedChildrenCodes: [{ code: "mathphrase", required: true }]
2642
+ allowedChildrenCodes: [
2643
+ { code: "mathphrase", required: true },
2644
+ { code: "tag", required: false }
2645
+ ]
2303
2646
  });
2304
2647
 
2305
2648
  // src/schema/elementSchemas/inlineElements/link.ts
@@ -2386,16 +2729,20 @@ var findAttributeDefinitionByName = (definitions, name) => {
2386
2729
  // src/schema/helpers/findSchemaByCode.ts
2387
2730
  var findSchemaByCode = (code) => SCHEMAS[code];
2388
2731
 
2389
- // src/schema/helpers/matchesSchemaTag.ts
2390
- var matchesSchemaTag = (element, tag) => element.tagName.toUpperCase() === tag.toUpperCase();
2391
-
2392
2732
  // src/schema/helpers/findSchemaByElement.ts
2393
- var findSchemaByElement = (element) => {
2394
- const schema = Object.values(SCHEMAS).find(
2395
- (schema2) => matchesSchemaTag(element, schema2.tag) && (!schema2.matchesElement || schema2.matchesElement(element))
2396
- );
2397
- return schema;
2733
+ var schemasByTag;
2734
+ var getSchemasByTag = () => {
2735
+ if (schemasByTag) return schemasByTag;
2736
+ schemasByTag = /* @__PURE__ */ new Map();
2737
+ for (const schema of Object.values(SCHEMAS)) {
2738
+ const tag = schema.tag.toUpperCase();
2739
+ const schemas = schemasByTag.get(tag);
2740
+ if (schemas) schemas.push(schema);
2741
+ else schemasByTag.set(tag, [schema]);
2742
+ }
2743
+ return schemasByTag;
2398
2744
  };
2745
+ var findSchemaByElement = (element) => getSchemasByTag().get(element.tagName.toUpperCase())?.find((schema) => !schema.matchesElement || schema.matchesElement(element));
2399
2746
 
2400
2747
  // src/schema/helpers/isAttributeRestricted.ts
2401
2748
  var isAttributeRestricted = (attr) => typeof attr !== "string";
@@ -2403,12 +2750,402 @@ var isAttributeRestricted = (attr) => typeof attr !== "string";
2403
2750
  // src/schema/helpers/isTrackChangesSchema.ts
2404
2751
  var isTrackChangesSchema = (schema) => schema.code === "insertion" || schema.code === "deletion" || schema.code === "lineGroupRemoval";
2405
2752
 
2753
+ // src/schema/referenceSchemas/referenceTypeSchemas.ts
2754
+ var LINK_FIELDS = ["doi", "url"];
2755
+ var OTHER_MATERIAL_FIELDS = [
2756
+ "author",
2757
+ "editor",
2758
+ "title",
2759
+ "year",
2760
+ "containerTitle",
2761
+ "publisherPlace",
2762
+ "publisher",
2763
+ "volume",
2764
+ "issue",
2765
+ "pages",
2766
+ "accessDate",
2767
+ "genre",
2768
+ "eventTitle",
2769
+ "eventPlace",
2770
+ "documentNumber",
2771
+ "pubmedId",
2772
+ ...LINK_FIELDS
2773
+ ];
2774
+ var REFERENCE_TYPE_SCHEMAS = {
2775
+ monograph: {
2776
+ code: "monograph",
2777
+ label: "Book",
2778
+ legacyRoles: ["book"],
2779
+ allowedFields: [
2780
+ "author",
2781
+ "editor",
2782
+ "title",
2783
+ "year",
2784
+ "volume",
2785
+ "publisherPlace",
2786
+ "publisher",
2787
+ ...LINK_FIELDS
2788
+ ],
2789
+ requiredFields: ["title", "creators"],
2790
+ fieldLabels: { title: "Book title" }
2791
+ },
2792
+ serial: {
2793
+ code: "serial",
2794
+ label: "Journal issue",
2795
+ legacyRoles: [],
2796
+ allowedFields: ["title", "year", "volume", "issue", ...LINK_FIELDS],
2797
+ requiredFields: ["title"]
2798
+ },
2799
+ contribution: {
2800
+ code: "contribution",
2801
+ label: "Contributed book",
2802
+ legacyRoles: ["chapter"],
2803
+ allowedFields: [
2804
+ "author",
2805
+ "editor",
2806
+ "title",
2807
+ "year",
2808
+ "containerTitle",
2809
+ "publisherPlace",
2810
+ "publisher",
2811
+ "pages",
2812
+ ...LINK_FIELDS
2813
+ ],
2814
+ requiredFields: ["title", "containerTitle", "creators"],
2815
+ bibliomsetRelations: ["part", "book"],
2816
+ fieldLabels: { title: "Chapter title", containerTitle: "Book title" }
2817
+ },
2818
+ article: {
2819
+ code: "article",
2820
+ label: "Journal article",
2821
+ legacyRoles: ["journal", "article-journal"],
2822
+ allowedFields: [
2823
+ "author",
2824
+ "editor",
2825
+ "title",
2826
+ "year",
2827
+ "containerTitle",
2828
+ "volume",
2829
+ "issue",
2830
+ "pages",
2831
+ "genre",
2832
+ "publisher",
2833
+ "publisherPlace",
2834
+ "pubmedId",
2835
+ "accessDate",
2836
+ ...LINK_FIELDS
2837
+ ],
2838
+ requiredFields: ["title", "containerTitle"],
2839
+ bibliomsetRelations: ["article", "journal"],
2840
+ fieldLabels: { title: "Article title", containerTitle: "Journal title" }
2841
+ },
2842
+ message: {
2843
+ code: "message",
2844
+ label: "Email message",
2845
+ legacyRoles: [],
2846
+ allowedFields: ["author", "title", "year", ...LINK_FIELDS],
2847
+ requiredFields: ["title"]
2848
+ },
2849
+ website: {
2850
+ code: "website",
2851
+ label: "Website",
2852
+ legacyRoles: [],
2853
+ allowedFields: ["author", "title", "year", "accessDate", ...LINK_FIELDS],
2854
+ requiredFields: ["title"]
2855
+ },
2856
+ unpublished: {
2857
+ code: "unpublished",
2858
+ label: "Unpublished material",
2859
+ legacyRoles: [],
2860
+ allowedFields: [
2861
+ "author",
2862
+ "title",
2863
+ "year",
2864
+ "publisher",
2865
+ "genre",
2866
+ "eventTitle",
2867
+ "eventPlace",
2868
+ ...LINK_FIELDS
2869
+ ],
2870
+ requiredFields: ["title"],
2871
+ replacedElements: [
2872
+ { tag: "pubdate", replacement: "date" },
2873
+ { tag: "publishername", replacement: "orgname" }
2874
+ ]
2875
+ },
2876
+ case: {
2877
+ code: "case",
2878
+ label: "Case",
2879
+ legacyRoles: [],
2880
+ allowedFields: ["title", "year", "documentNumber", ...LINK_FIELDS],
2881
+ requiredFields: ["title"]
2882
+ },
2883
+ legislation: {
2884
+ code: "legislation",
2885
+ label: "Legislation",
2886
+ legacyRoles: [],
2887
+ allowedFields: [
2888
+ "title",
2889
+ "year",
2890
+ "documentNumber",
2891
+ "publisherPlace",
2892
+ ...LINK_FIELDS
2893
+ ],
2894
+ requiredFields: ["title"]
2895
+ },
2896
+ other: {
2897
+ code: "other",
2898
+ label: "Other material",
2899
+ legacyRoles: [],
2900
+ allowedFields: OTHER_MATERIAL_FIELDS,
2901
+ requiredFields: ["title"]
2902
+ },
2903
+ recording: {
2904
+ code: "recording",
2905
+ label: "Recording",
2906
+ legacyRoles: [],
2907
+ allowedFields: ["author", "title", "year", ...LINK_FIELDS],
2908
+ requiredFields: ["title", "year"],
2909
+ replacedElements: [{ tag: "author", replacement: "othercredit" }]
2910
+ },
2911
+ film: {
2912
+ code: "film",
2913
+ label: "Film",
2914
+ legacyRoles: [],
2915
+ allowedFields: ["title", "year", ...LINK_FIELDS],
2916
+ requiredFields: ["title"]
2917
+ }
2918
+ };
2919
+
2920
+ // src/schema/helpers/findReferenceTypeSchemaByElement.ts
2921
+ var findReferenceTypeSchemaByElement = (reference) => {
2922
+ const role = reference.getAttribute("role")?.trim().toLowerCase() ?? "";
2923
+ const schemas = Object.values(REFERENCE_TYPE_SCHEMAS);
2924
+ return schemas.find(
2925
+ (schema) => schema.code === role || schema.legacyRoles.includes(role)
2926
+ );
2927
+ };
2928
+
2929
+ // src/helpers/isDeletedElement.ts
2930
+ var isDeletedElement = (element) => {
2931
+ return !!closestElementBySchema({
2932
+ element,
2933
+ code: "deletion"
2934
+ });
2935
+ };
2936
+
2937
+ // src/helpers/closestElementBySchema.ts
2938
+ var closestElementBySchema = ({
2939
+ element,
2940
+ code,
2941
+ ignoreDeletedElements = false
2942
+ }) => {
2943
+ const schema = findSchemaByCode(code);
2944
+ if (!schema) return;
2945
+ const closestElement = element.closest(
2946
+ schema.tag.toLowerCase()
2947
+ );
2948
+ if (!closestElement) return;
2949
+ if (schema.matchesElement && !schema.matchesElement(closestElement)) {
2950
+ return;
2951
+ }
2952
+ if (ignoreDeletedElements && isDeletedElement(closestElement)) {
2953
+ return closestElementBySchema({
2954
+ element: closestElement,
2955
+ code,
2956
+ ignoreDeletedElements
2957
+ });
2958
+ }
2959
+ return closestElement;
2960
+ };
2961
+
2962
+ // src/helpers/isInTrackedDeletion.ts
2963
+ var isInTrackedDeletion = (element) => !!element.closest("span.del");
2964
+
2965
+ // src/helpers/hasLiveUri.ts
2966
+ var hasLiveUri = (link) => Array.from(link.querySelectorAll("uri")).some(
2967
+ (uri) => !isInTrackedDeletion(uri)
2968
+ );
2969
+
2970
+ // src/schema/helpers/findReferenceFieldByElement.ts
2971
+ var isContainerTitle = (title) => {
2972
+ const relation = closestElementBySchema({
2973
+ element: title,
2974
+ code: "bibliomset"
2975
+ })?.getAttribute("relation");
2976
+ return CONTAINER_BIBLIOMSET_RELATIONS.some(
2977
+ (containerRelation) => containerRelation === relation
2978
+ );
2979
+ };
2980
+ var isUnpublishedReference = (element) => {
2981
+ const reference = closestElementBySchema({
2982
+ element,
2983
+ code: "referenceBibliomixed"
2984
+ });
2985
+ return !!reference && findReferenceTypeSchemaByElement(reference)?.code === "unpublished";
2986
+ };
2987
+ var hasAcceptedChild = (element, tag) => Array.from(element.querySelectorAll(tag.toLowerCase())).some(
2988
+ (child) => !isInTrackedDeletion(child)
2989
+ );
2990
+ var isConferenceDates = (confgroup) => hasAcceptedChild(confgroup, CONFDATES_TAG) && !hasAcceptedChild(confgroup, CONFTITLE_TAG);
2991
+ var findReferenceFieldByElement = (element) => {
2992
+ switch (findSchemaByElement(element)?.code) {
2993
+ case "author":
2994
+ case "othercredit":
2995
+ return "author";
2996
+ case "editor":
2997
+ return "editor";
2998
+ case "title1":
2999
+ return isContainerTitle(element) ? "containerTitle" : "title";
3000
+ case "pubdate":
3001
+ return "year";
3002
+ case "date":
3003
+ return element.getAttribute("role") === ACCESSED_DATE_ROLE ? "accessDate" : "year";
3004
+ case "publishername":
3005
+ case "orgname":
3006
+ return "publisher";
3007
+ case "address":
3008
+ return isUnpublishedReference(element) ? "eventPlace" : "publisherPlace";
3009
+ case "volumenum":
3010
+ return "volume";
3011
+ case "issuenum":
3012
+ return "issue";
3013
+ case "pagenums":
3014
+ return "pages";
3015
+ case "link":
3016
+ if (element.hasAttribute(LINKEND_ATTRIBUTE)) return void 0;
3017
+ return hasLiveUri(element) ? "url" : "doi";
3018
+ case "bibliomisc":
3019
+ return element.getAttribute("role") === LEGAL_REFERENCE_BIBLIOMISC_ROLE ? "documentNumber" : "genre";
3020
+ case "confgroup":
3021
+ return isConferenceDates(element) ? "year" : "eventTitle";
3022
+ case "biblioid":
3023
+ return isPubMedIdBiblioid(element) ? "pubmedId" : void 0;
3024
+ default:
3025
+ return void 0;
3026
+ }
3027
+ };
3028
+
3029
+ // src/schema/referenceSchemas/referenceFieldSchemas.ts
3030
+ var REFERENCE_FIELD_SCHEMAS = {
3031
+ author: {
3032
+ code: "author",
3033
+ label: "Author",
3034
+ elementCodes: ["author", "othercredit"]
3035
+ },
3036
+ editor: {
3037
+ code: "editor",
3038
+ label: "Editor",
3039
+ elementCodes: ["editor"]
3040
+ },
3041
+ title: {
3042
+ code: "title",
3043
+ label: "Title",
3044
+ elementCodes: ["title1"]
3045
+ },
3046
+ year: {
3047
+ code: "year",
3048
+ label: "Date",
3049
+ elementCodes: ["pubdate", "date", "confgroup"]
3050
+ },
3051
+ containerTitle: {
3052
+ code: "containerTitle",
3053
+ label: "Container title",
3054
+ elementCodes: ["title1"]
3055
+ },
3056
+ publisherPlace: {
3057
+ code: "publisherPlace",
3058
+ label: "Publisher place",
3059
+ elementCodes: ["address"]
3060
+ },
3061
+ publisher: {
3062
+ code: "publisher",
3063
+ label: "Publisher or institution",
3064
+ elementCodes: ["publishername", "orgname"]
3065
+ },
3066
+ volume: {
3067
+ code: "volume",
3068
+ label: "Volume",
3069
+ elementCodes: ["volumenum"]
3070
+ },
3071
+ issue: {
3072
+ code: "issue",
3073
+ label: "Issue",
3074
+ elementCodes: ["issuenum"]
3075
+ },
3076
+ pages: {
3077
+ code: "pages",
3078
+ label: "Pages",
3079
+ elementCodes: ["pagenums"]
3080
+ },
3081
+ doi: {
3082
+ code: "doi",
3083
+ label: "DOI",
3084
+ elementCodes: ["link"]
3085
+ },
3086
+ url: {
3087
+ code: "url",
3088
+ label: "URL",
3089
+ elementCodes: ["link"]
3090
+ },
3091
+ accessDate: {
3092
+ code: "accessDate",
3093
+ label: "Access date",
3094
+ elementCodes: ["date"]
3095
+ },
3096
+ genre: {
3097
+ code: "genre",
3098
+ label: "Description",
3099
+ elementCodes: ["bibliomisc"]
3100
+ },
3101
+ eventTitle: {
3102
+ code: "eventTitle",
3103
+ label: "Conference title",
3104
+ elementCodes: ["confgroup"]
3105
+ },
3106
+ eventPlace: {
3107
+ code: "eventPlace",
3108
+ label: "Conference place",
3109
+ elementCodes: ["address"]
3110
+ },
3111
+ documentNumber: {
3112
+ code: "documentNumber",
3113
+ label: "Legal reference",
3114
+ elementCodes: ["bibliomisc"]
3115
+ },
3116
+ pubmedId: {
3117
+ code: "pubmedId",
3118
+ label: "PubMed ID",
3119
+ elementCodes: ["biblioid"]
3120
+ }
3121
+ };
3122
+
2406
3123
  // src/schema/shared/labelElements.ts
2407
3124
  var ElementLabel = {
2408
3125
  mark: "Mark",
2409
3126
  referenceBibliomixed: "Reference Bibliomixed",
2410
3127
  referenceBibliography: "Reference Bibliography",
2411
3128
  bibliodiv: "Bibliodiv",
3129
+ bibliomset: "Reference Block",
3130
+ editor: "Editor",
3131
+ othercredit: "Other Credit",
3132
+ translator: "Translator",
3133
+ collab: "Collaborator",
3134
+ pubdate: "Publication Date",
3135
+ date: "Date",
3136
+ publishername: "Publisher Name",
3137
+ address: "Address",
3138
+ city: "City",
3139
+ volumenum: "Volume Number",
3140
+ issuenum: "Issue Number",
3141
+ pagenums: "Page Numbers",
3142
+ pagenum: "Page Number",
3143
+ edition: "Edition",
3144
+ pubId: "Publication ID",
3145
+ biblioid: "Bibliographic ID",
3146
+ bibliomisc: "Reference Miscellany",
3147
+ confgroup: "Conference",
3148
+ conftitle: "Conference Title",
2412
3149
  indexterm: "Indexterm",
2413
3150
  primary: "Primary",
2414
3151
  secondary: "Secondary",
@@ -2549,46 +3286,15 @@ var IGNORED_ELEMENT_SELECTORS = [
2549
3286
  "span.ref-drag",
2550
3287
  "span#dummySpan"
2551
3288
  ];
2552
- var isIgnoredElement = (element) => IGNORED_ELEMENT_SELECTORS.some((selector) => element.matches(selector));
3289
+ var IGNORED_ELEMENT_SELECTOR = IGNORED_ELEMENT_SELECTORS.join(", ");
3290
+ var isIgnoredElement = (element) => element.tagName.toUpperCase() === "SPAN" && element.matches(IGNORED_ELEMENT_SELECTOR);
2553
3291
 
2554
3292
  // src/validation/helpers/isIgnoredValidation.ts
2555
3293
  var IGNORED_VALIDATION_ELEMENT_SELECTORS = [
2556
3294
  "referenceBibliomixed"
2557
3295
  ];
2558
3296
  var isIgnoredValidation = (code) => IGNORED_VALIDATION_ELEMENT_SELECTORS.includes(code);
2559
-
2560
- // src/helpers/closestElementBySchema.ts
2561
- var closestElementBySchema = ({
2562
- element,
2563
- code,
2564
- ignoreDeletedElements = false
2565
- }) => {
2566
- const schema = findSchemaByCode(code);
2567
- if (!schema) return;
2568
- const closestElement = element.closest(
2569
- schema.tag.toLowerCase()
2570
- );
2571
- if (!closestElement) return;
2572
- if (schema.matchesElement && !schema.matchesElement(closestElement)) {
2573
- return;
2574
- }
2575
- if (ignoreDeletedElements && isDeletedElement(closestElement)) {
2576
- return closestElementBySchema({
2577
- element: closestElement,
2578
- code,
2579
- ignoreDeletedElements
2580
- });
2581
- }
2582
- return closestElement;
2583
- };
2584
-
2585
- // src/helpers/isDeletedElement.ts
2586
- var isDeletedElement = (element) => {
2587
- return !!closestElementBySchema({
2588
- element,
2589
- code: "deletion"
2590
- });
2591
- };
3297
+ var isIgnoredValidationByAttribute = (element) => element.getAttribute(VALIDATION_IGNORED_ATTRIBUTE) === "true";
2592
3298
 
2593
3299
  // src/validation/utils/getElementsSelector.ts
2594
3300
  var getElementsSelector = ({
@@ -2626,12 +3332,14 @@ var generateValidationIssueId = () => {
2626
3332
  };
2627
3333
 
2628
3334
  // src/validation/helpers/addValidationIssue.ts
2629
- var createValidationIssue = (issue) => ({
3335
+ var createValidationIssue = (element, issue) => ({
3336
+ ...issue,
2630
3337
  id: generateValidationIssueId(),
2631
- ...issue
3338
+ store: element ? getStore(element) : issue.store,
3339
+ ignored: element ? isIgnoredValidationByAttribute(element) : false
2632
3340
  });
2633
- var addValidationIssue = (errors, issue) => {
2634
- errors.push(createValidationIssue(issue));
3341
+ var addValidationIssue = (errors, element, issue) => {
3342
+ errors.push(createValidationIssue(element, issue));
2635
3343
  };
2636
3344
 
2637
3345
  // src/validation/validateFootnotes.ts
@@ -2650,8 +3358,7 @@ var validateFootnoteNumber = (footnoteElement) => {
2650
3358
  FOOTNOTE_NUMBER_SCHEMA.tag
2651
3359
  );
2652
3360
  if (!footnoteNumber) {
2653
- addValidationIssue(errors, {
2654
- store: getStore(footnoteElement),
3361
+ addValidationIssue(errors, footnoteElement, {
2655
3362
  title: "Footnote number missing",
2656
3363
  kind: "missing",
2657
3364
  description: "The footnote number is missing. Please add it to the footnote.",
@@ -2682,8 +3389,7 @@ var validateConsecutiveFootnotes = (root) => {
2682
3389
  );
2683
3390
  if (!footnoteNumberElement) {
2684
3391
  errors.push(
2685
- createValidationIssue({
2686
- store: getStore(footnote),
3392
+ createValidationIssue(footnote, {
2687
3393
  title: "Footnote number missing",
2688
3394
  kind: "missing",
2689
3395
  description: "The footnote number is missing. Please add it to the footnote.",
@@ -2696,8 +3402,7 @@ var validateConsecutiveFootnotes = (root) => {
2696
3402
  continue;
2697
3403
  }
2698
3404
  errors.push(
2699
- createValidationIssue({
2700
- store: getStore(footnote),
3405
+ createValidationIssue(footnote, {
2701
3406
  title: "Non-consecutive footnote numbers",
2702
3407
  kind: "missing",
2703
3408
  description: `Footnote numbers must be consecutive, footnote number (${label}) expected to be (${expectedNumber}). Please reorder the footnotes.`,
@@ -2728,8 +3433,7 @@ var validateConsecutiveFootnoteCues = (root) => {
2728
3433
  continue;
2729
3434
  }
2730
3435
  errors.push(
2731
- createValidationIssue({
2732
- store: getStore(footnoteLink),
3436
+ createValidationIssue(footnoteLink, {
2733
3437
  title: "Non-consecutive footnote cues",
2734
3438
  kind: "missing",
2735
3439
  description: "Footnote cues must be consecutive. Please reorder the footnote cues.",
@@ -2742,10 +3446,11 @@ var validateConsecutiveFootnoteCues = (root) => {
2742
3446
  return errors;
2743
3447
  };
2744
3448
 
3449
+ // src/validation/helpers/hasLinkId.ts
3450
+ var hasLinkId = (ids, id) => "has" in ids ? ids.has(id) : ids.includes(id);
3451
+
2745
3452
  // src/validation/validateLinkend.ts
2746
- var findElementLinkedTo = (linkend, elementsToLink) => {
2747
- return elementsToLink.includes(linkend);
2748
- };
3453
+ var findElementLinkedTo = (linkend, elementsToLink) => hasLinkId(elementsToLink, linkend);
2749
3454
  var LINK_TO_CROSS_CHECK = [
2750
3455
  TABLE_LINK_ROLE,
2751
3456
  FIGURE_LINK_ROLE,
@@ -2773,8 +3478,7 @@ var validateLinkend = (linkElement, elementsToLink) => {
2773
3478
  );
2774
3479
  if (isLinkFootnoteCue) {
2775
3480
  return [
2776
- createValidationIssue({
2777
- store: getStore(linkElement),
3481
+ createValidationIssue(linkElement, {
2778
3482
  title: "Unlinked footnote cue",
2779
3483
  kind: "unlinked",
2780
3484
  description: "This footnote cue is not referenced to any footnote in this chapter. Please link it again manually.",
@@ -2795,8 +3499,7 @@ var validateLinkend = (linkElement, elementsToLink) => {
2795
3499
  }
2796
3500
  const isBlocker = LINK_BLOCKER_ROLES.includes(role.toLowerCase());
2797
3501
  return [
2798
- createValidationIssue({
2799
- store: getStore(linkElement),
3502
+ createValidationIssue(linkElement, {
2800
3503
  title: "Unlinked element",
2801
3504
  kind: "unlinked",
2802
3505
  description: "This link is not referenced to any element in the current chapter or any other chapter. Please link it again manually.",
@@ -2856,8 +3559,7 @@ var validateAttributes = (element, schema) => {
2856
3559
  continue;
2857
3560
  }
2858
3561
  if (!definition.values.includes(value)) {
2859
- addValidationIssue(errors, {
2860
- store: getStore(element),
3562
+ addValidationIssue(errors, element, {
2861
3563
  title: `Invalid attribute value "${value}" in element ${element.tagName}`,
2862
3564
  level: "warning",
2863
3565
  kind: "forbidden",
@@ -2872,8 +3574,7 @@ var validateAttributes = (element, schema) => {
2872
3574
  var validateElementAgainstSchema = (element, schema) => {
2873
3575
  const errors = [];
2874
3576
  if (!matchesSchemaTag(element, schema.tag)) {
2875
- addValidationIssue(errors, {
2876
- store: getStore(element),
3577
+ addValidationIssue(errors, element, {
2877
3578
  title: `Expected ${schema.tag}, got ${element.tagName}`,
2878
3579
  level: "warning",
2879
3580
  kind: "forbidden",
@@ -2903,8 +3604,7 @@ var validateRequiredChildren = (element, schema, childElements) => {
2903
3604
  `Please provide at least one ${elementLabel} in this ${parentLabel}.`,
2904
3605
  extraInstruction
2905
3606
  ].filter(Boolean).join(" ");
2906
- addValidationIssue(errors, {
2907
- store: getStore(element),
3607
+ addValidationIssue(errors, element, {
2908
3608
  title: `${elementLabel} missing`,
2909
3609
  level: "warning",
2910
3610
  kind: "missing",
@@ -2938,8 +3638,7 @@ var validateChildren = (element, schema) => {
2938
3638
  for (const child of childElements) {
2939
3639
  const childSchema = findSchemaByElement(child);
2940
3640
  if (!childSchema) {
2941
- addValidationIssue(errors, {
2942
- store: getStore(child),
3641
+ addValidationIssue(errors, child, {
2943
3642
  title: `No schema found for child element ${child.tagName}`,
2944
3643
  level: "warning",
2945
3644
  kind: "missing",
@@ -2951,8 +3650,7 @@ var validateChildren = (element, schema) => {
2951
3650
  (candidate) => candidate.code === childSchema.code
2952
3651
  );
2953
3652
  if (!allowedChild) {
2954
- addValidationIssue(errors, {
2955
- store: getStore(child),
3653
+ addValidationIssue(errors, child, {
2956
3654
  title: `Forbidden child element ${child.tagName}`,
2957
3655
  level: "warning",
2958
3656
  kind: "forbidden",
@@ -2973,9 +3671,7 @@ var getExtraInstruction = (schema, childSchema) => {
2973
3671
  };
2974
3672
 
2975
3673
  // src/validation/validateElementToLinkTo.ts
2976
- var findElementLinkedTo2 = (xmlid, linkElements) => {
2977
- return linkElements.includes(xmlid);
2978
- };
3674
+ var findElementLinkedTo2 = (xmlid, linkElements) => hasLinkId(linkElements, xmlid);
2979
3675
  var isFootnote = (element) => {
2980
3676
  return matchesSchemaTag(element, FOOTNOTE_SCHEMA.tag);
2981
3677
  };
@@ -3002,8 +3698,7 @@ var validateElementToLinkTo = (element, linkElements) => {
3002
3698
  if (isFootnote(element)) {
3003
3699
  const label = extractFootnoteNumber(element);
3004
3700
  return [
3005
- createValidationIssue({
3006
- store: getStore(element),
3701
+ createValidationIssue(element, {
3007
3702
  title: "Uncited footnote",
3008
3703
  kind: "uncited",
3009
3704
  description: `The footnote ${label} is not cited to any footnote cue in this chapter. Please reference it in the chapter.`,
@@ -3013,8 +3708,7 @@ var validateElementToLinkTo = (element, linkElements) => {
3013
3708
  }
3014
3709
  if (isReference(element)) {
3015
3710
  return [
3016
- createValidationIssue({
3017
- store: getStore(element),
3711
+ createValidationIssue(element, {
3018
3712
  title: "Uncited reference",
3019
3713
  kind: "uncited",
3020
3714
  description: "This reference is not cited in this chapter or any other chapter. Please add a link to this reference or delete it.",
@@ -3024,8 +3718,7 @@ var validateElementToLinkTo = (element, linkElements) => {
3024
3718
  }
3025
3719
  if (isTable(element)) {
3026
3720
  return [
3027
- createValidationIssue({
3028
- store: getStore(element),
3721
+ createValidationIssue(element, {
3029
3722
  title: "Uncited table",
3030
3723
  kind: "uncited",
3031
3724
  description: "This table is not cited in this chapter or any other chapter. Please add a link to this table or delete it.",
@@ -3035,8 +3728,7 @@ var validateElementToLinkTo = (element, linkElements) => {
3035
3728
  }
3036
3729
  if (isFigure(element)) {
3037
3730
  return [
3038
- createValidationIssue({
3039
- store: getStore(element),
3731
+ createValidationIssue(element, {
3040
3732
  title: "Uncited figure",
3041
3733
  kind: "uncited",
3042
3734
  description: "This figure is not cited in this chapter or any other chapter. Please add a link to this figure or delete it.",
@@ -3049,9 +3741,20 @@ var validateElementToLinkTo = (element, linkElements) => {
3049
3741
 
3050
3742
  // src/validation/validateWeblink.ts
3051
3743
  import Mark from "mark.js";
3744
+
3745
+ // src/validation/helpers/steps.ts
3746
+ var runSteps = (steps) => {
3747
+ for (; ; ) {
3748
+ const step = steps.next();
3749
+ if (step.done) return step.value;
3750
+ }
3751
+ };
3752
+
3753
+ // src/validation/validateWeblink.ts
3052
3754
  var EDGE_PUNCTUATION = `:;.,\\-\u2013\u2014\u2012_(){}[\\]!'"+=\xAB\xBB\u2039\u203A\u201C\u201D\u2018\u2019<>`;
3053
3755
  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}])?)?`;
3054
3756
  var WEB_URI_IN_TEXT_REGEX = new RegExp(WEB_URI_PATTERN, "gi");
3757
+ var POSSIBLE_WEBLINK_CLASS = "possible-weblink";
3055
3758
  var POSSIBLE_WEBLINK_EXCLUDE_SELECTORS = [
3056
3759
  "tag",
3057
3760
  "tag *",
@@ -3063,40 +3766,150 @@ var POSSIBLE_WEBLINK_EXCLUDE_SELECTORS = [
3063
3766
  "query *",
3064
3767
  "comment",
3065
3768
  "comment *",
3769
+ `.${POSSIBLE_WEBLINK_CLASS}`,
3770
+ `.${POSSIBLE_WEBLINK_CLASS} *`,
3066
3771
  ...IGNORED_ELEMENT_SELECTORS
3067
3772
  ];
3068
- var collectPossibleWebLinks = (content) => {
3069
- const clone = content.cloneNode(true);
3070
- const possibleWebLinks = /* @__PURE__ */ new Set();
3071
- const instance = new Mark(clone);
3773
+ var getPossibleWeblinks = (root) => {
3774
+ const possibleWeblinks = /* @__PURE__ */ new Map();
3775
+ const allWeblinkMatches = Array.from(
3776
+ root.getElementsByClassName(POSSIBLE_WEBLINK_CLASS)
3777
+ );
3778
+ for (const weblinkMatch of allWeblinkMatches) {
3779
+ const storeId = weblinkMatch.getAttribute(STORE_ATTRIBUTE);
3780
+ if (!storeId || possibleWeblinks.has(storeId)) continue;
3781
+ const elements = allWeblinkMatches.filter(
3782
+ (element) => element.getAttribute(STORE_ATTRIBUTE) === storeId
3783
+ );
3784
+ const weblink = elements.map((element) => element.textContent).join("");
3785
+ possibleWeblinks.set(storeId, {
3786
+ weblink,
3787
+ elements
3788
+ });
3789
+ }
3790
+ return possibleWeblinks;
3791
+ };
3792
+ var getWeblinkMatchId = (matchIndex) => `weblink-match-${matchIndex}`;
3793
+ var createWeblinkMatchTracker = () => {
3794
+ const matchedText = [];
3795
+ const matchedElements = [];
3796
+ const possibleWeblinks = /* @__PURE__ */ new Map();
3797
+ let matchIndex = 0;
3798
+ let currentMatchId = getWeblinkMatchId(matchIndex);
3799
+ const resetMatch = () => {
3800
+ matchIndex += 1;
3801
+ currentMatchId = getWeblinkMatchId(matchIndex);
3802
+ matchedText.length = 0;
3803
+ matchedElements.length = 0;
3804
+ };
3805
+ const composeWeblink = (element, url) => {
3806
+ element.setAttribute(STORE_ATTRIBUTE, currentMatchId);
3807
+ matchedText.push(element.textContent);
3808
+ matchedElements.push(element);
3809
+ if (matchedText.join("") !== url) return;
3810
+ possibleWeblinks.set(currentMatchId, {
3811
+ weblink: matchedText.join(""),
3812
+ elements: [...matchedElements]
3813
+ });
3814
+ resetMatch();
3815
+ };
3816
+ return { composeWeblink, possibleWeblinks };
3817
+ };
3818
+ var markPossibleWeblinks = (editor) => {
3819
+ const instance = new Mark(editor);
3820
+ const { composeWeblink, possibleWeblinks } = createWeblinkMatchTracker();
3821
+ let possibleWebLink = "";
3072
3822
  instance.markRegExp(WEB_URI_IN_TEXT_REGEX, {
3823
+ className: POSSIBLE_WEBLINK_CLASS,
3073
3824
  acrossElements: false,
3074
3825
  exclude: POSSIBLE_WEBLINK_EXCLUDE_SELECTORS,
3075
3826
  filter: (_textNode, term) => {
3076
- possibleWebLinks.add(term);
3827
+ possibleWebLink = term;
3077
3828
  return true;
3078
- }
3829
+ },
3830
+ each: (element) => composeWeblink(element, possibleWebLink)
3079
3831
  });
3080
- return possibleWebLinks;
3832
+ return possibleWeblinks;
3081
3833
  };
3082
- var validatePossibleWeblinks = (root) => {
3083
- const errors = [];
3084
- const possibleWebLinks = collectPossibleWebLinks(root);
3085
- for (const possibleWebLink of possibleWebLinks) {
3086
- errors.push(
3087
- createValidationIssue({
3088
- store: possibleWebLink,
3834
+ var TEXT_NODES_PER_STEP = 256;
3835
+ var MARK_EXCLUDED_PARENT_SELECTOR = [
3836
+ ...POSSIBLE_WEBLINK_EXCLUDE_SELECTORS,
3837
+ "script",
3838
+ "style",
3839
+ "title",
3840
+ "head",
3841
+ "html"
3842
+ ].join(", ");
3843
+ var createWeblinkMatchElement = (ownerDocument, text, storeId) => {
3844
+ const element = ownerDocument.createElement("mark");
3845
+ element.setAttribute("data-markjs", "true");
3846
+ element.setAttribute("class", POSSIBLE_WEBLINK_CLASS);
3847
+ element.setAttribute(STORE_ATTRIBUTE, storeId);
3848
+ element.textContent = text;
3849
+ return element;
3850
+ };
3851
+ function* findPossibleWeblinks(root) {
3852
+ const possibleWeblinks = /* @__PURE__ */ new Map();
3853
+ const ownerDocument = root.ownerDocument;
3854
+ const walker = ownerDocument.createTreeWalker(root, NodeFilter.SHOW_TEXT);
3855
+ const regex = new RegExp(WEB_URI_PATTERN, "gi");
3856
+ let nodesSinceStep = 0;
3857
+ for (let node = walker.nextNode(); node; node = walker.nextNode()) {
3858
+ if (++nodesSinceStep === TEXT_NODES_PER_STEP) {
3859
+ nodesSinceStep = 0;
3860
+ yield;
3861
+ }
3862
+ const text = node.textContent ?? "";
3863
+ if (!text) continue;
3864
+ const parent = node.parentNode;
3865
+ if (parent instanceof Element && parent.matches(MARK_EXCLUDED_PARENT_SELECTOR)) {
3866
+ continue;
3867
+ }
3868
+ regex.lastIndex = 0;
3869
+ for (let match = regex.exec(text); match; match = regex.exec(text)) {
3870
+ const storeId = getWeblinkMatchId(possibleWeblinks.size);
3871
+ possibleWeblinks.set(storeId, {
3872
+ weblink: match[0],
3873
+ elements: [createWeblinkMatchElement(ownerDocument, match[0], storeId)]
3874
+ });
3875
+ }
3876
+ }
3877
+ return possibleWeblinks;
3878
+ }
3879
+ var hasWeblinkMatches = (root) => root.getElementsByClassName(POSSIBLE_WEBLINK_CLASS).length > 0;
3880
+ function* validatePossibleWeblinksSteps(root) {
3881
+ const issues = [];
3882
+ let possibleWeblinks;
3883
+ if (hasWeblinkMatches(root)) {
3884
+ const cloneRoot = root.cloneNode(true);
3885
+ clearWeblinkMatches(cloneRoot);
3886
+ possibleWeblinks = markPossibleWeblinks(cloneRoot);
3887
+ } else {
3888
+ possibleWeblinks = yield* findPossibleWeblinks(root);
3889
+ }
3890
+ for (const [storeId, { elements }] of Array.from(possibleWeblinks)) {
3891
+ issues.push(
3892
+ createValidationIssue(null, {
3893
+ store: storeId,
3089
3894
  title: "Possible web link",
3090
3895
  kind: "possible-url",
3091
3896
  description: "This looks like a URL. Would you like to add weblink tags?",
3092
- level: "warning"
3897
+ level: "info",
3898
+ elements
3093
3899
  })
3094
3900
  );
3095
3901
  }
3096
- return errors;
3902
+ return issues;
3903
+ }
3904
+ var validatePossibleWeblinks = (root) => runSteps(validatePossibleWeblinksSteps(root));
3905
+ var clearWeblinkMatches = (editor) => {
3906
+ const instance = new Mark(editor);
3907
+ instance.unmark({
3908
+ className: POSSIBLE_WEBLINK_CLASS
3909
+ });
3097
3910
  };
3098
3911
 
3099
- // src/validation/validateHeadingHierarchy.ts
3912
+ // src/validation/validateHierarchy.ts
3100
3913
  var shouldSuppressWarning = (element) => {
3101
3914
  const closestBox = closestElementBySchema({
3102
3915
  element,
@@ -3105,46 +3918,66 @@ var shouldSuppressWarning = (element) => {
3105
3918
  });
3106
3919
  return !!closestBox;
3107
3920
  };
3108
- var getHierarchyLevel = (element) => {
3109
- const role = element.getAttribute("role");
3921
+ var isHeading = (elementHierarchy) => {
3922
+ return elementHierarchy === "heading";
3923
+ };
3924
+ var getValidLevels = (elementHierarchy) => {
3925
+ return isHeading(elementHierarchy) ? HEADING_LEVEL : BOX_LEVEL;
3926
+ };
3927
+ var getAttributeName2 = (elementHierarchy) => {
3928
+ return isHeading(elementHierarchy) ? "role" : "status";
3929
+ };
3930
+ var getElementSchemaCode = (elementHierarchy) => {
3931
+ return isHeading(elementHierarchy) ? HEADING_SCHEMA.code : BOX_SCHEMA.code;
3932
+ };
3933
+ var getHierarchyLevel = (element, elementHierarchy) => {
3934
+ const role = element.getAttribute(getAttributeName2(elementHierarchy));
3110
3935
  if (!role) return void 0;
3111
- const validHeadingLevel = HEADING_LEVEL.indexOf(role);
3112
- if (validHeadingLevel === -1) return void 0;
3113
- return validHeadingLevel;
3936
+ const index = getValidLevels(elementHierarchy).indexOf(role);
3937
+ if (index === -1) return void 0;
3938
+ return isHeading(elementHierarchy) ? index : index + 1;
3114
3939
  };
3115
- var validateHeadingHierarchy = (element) => {
3940
+ var validateHierarchy = (element, elementHierarchy) => {
3116
3941
  const errors = [];
3117
3942
  if (isDeletedElement(element)) {
3118
3943
  return errors;
3119
3944
  }
3120
- if (shouldSuppressWarning(element)) {
3945
+ if (shouldSuppressWarning(element) && isHeading(elementHierarchy)) {
3121
3946
  return errors;
3122
3947
  }
3123
- const level = getHierarchyLevel(element);
3948
+ const level = getHierarchyLevel(element, elementHierarchy);
3124
3949
  if (level === void 0) {
3125
3950
  return errors;
3126
3951
  }
3127
3952
  if (!element.parentElement) {
3128
3953
  return errors;
3129
3954
  }
3130
- const parentHeading = closestElementBySchema({
3955
+ const parentElement = closestElementBySchema({
3131
3956
  element: element.parentElement,
3132
- code: HEADING_SCHEMA.code,
3957
+ code: getElementSchemaCode(elementHierarchy),
3133
3958
  ignoreDeletedElements: true
3134
3959
  });
3135
- if (!parentHeading) {
3960
+ if (!parentElement) {
3136
3961
  if (level > 1) {
3137
- addValidationIssue(errors, {
3138
- store: getStore(element),
3139
- title: "Missing heading H1",
3140
- kind: "missing",
3141
- description: `H${level} is not under an H1. Please check the heading hierarchy.`,
3142
- level: "warning"
3143
- });
3962
+ if (isHeading(elementHierarchy)) {
3963
+ addValidationIssue(errors, element, {
3964
+ title: "Missing heading H1",
3965
+ kind: "missing",
3966
+ description: `H${level} is not under an H1. Please check the heading hierarchy.`,
3967
+ level: "warning"
3968
+ });
3969
+ } else {
3970
+ addValidationIssue(errors, element, {
3971
+ title: "Missing box level 1",
3972
+ kind: "missing",
3973
+ description: `Box level ${level} is not under a box level. Please check the box hierarchy.`,
3974
+ level: "warning"
3975
+ });
3976
+ }
3144
3977
  }
3145
3978
  return errors;
3146
3979
  }
3147
- const parentLevel = getHierarchyLevel(parentHeading);
3980
+ const parentLevel = getHierarchyLevel(parentElement, elementHierarchy);
3148
3981
  if (parentLevel === void 0) {
3149
3982
  return errors;
3150
3983
  }
@@ -3152,13 +3985,21 @@ var validateHeadingHierarchy = (element) => {
3152
3985
  if (level === expectedLevel) {
3153
3986
  return errors;
3154
3987
  }
3155
- addValidationIssue(errors, {
3156
- store: getStore(element),
3157
- title: "Invalid heading hierarchy",
3158
- kind: "forbidden",
3159
- description: `H${level} cannot follow H${parentLevel} directly. Please check the heading hierarchy.`,
3160
- level: "warning"
3161
- });
3988
+ if (isHeading(elementHierarchy)) {
3989
+ addValidationIssue(errors, element, {
3990
+ title: "Invalid heading hierarchy",
3991
+ kind: "forbidden",
3992
+ description: `H${level} cannot follow H${parentLevel} directly. Please check the heading hierarchy.`,
3993
+ level: "warning"
3994
+ });
3995
+ } else {
3996
+ addValidationIssue(errors, element, {
3997
+ title: "Invalid box hierarchy",
3998
+ kind: "forbidden",
3999
+ description: `Box level ${level} cannot follow box level ${parentLevel} directly. Please check the box hierarchy.`,
4000
+ level: "warning"
4001
+ });
4002
+ }
3162
4003
  return errors;
3163
4004
  };
3164
4005
 
@@ -3175,8 +4016,7 @@ var validateOlink = (element) => {
3175
4016
  if (isEmpty || isValidOrcid) {
3176
4017
  return errors;
3177
4018
  }
3178
- addValidationIssue(errors, {
3179
- store: getStore(element.parentElement ?? element),
4019
+ addValidationIssue(errors, element, {
3180
4020
  title: "Invalid ORCID",
3181
4021
  kind: "forbidden",
3182
4022
  description: "The ORCiD is not the correct format. Please check it and adjust.",
@@ -3185,62 +4025,439 @@ var validateOlink = (element) => {
3185
4025
  return errors;
3186
4026
  };
3187
4027
 
4028
+ // src/helpers/getReferenceFieldElements.ts
4029
+ var REFERENCE_PART_SELECTOR = REFERENCE_PART_CODES_ALLOWED_CHILDREN.map(
4030
+ ({ code }) => findSchemaByCode(code).tag.toLowerCase()
4031
+ ).join(", ");
4032
+ var REFERENCE_PART_OWNER_SELECTOR = `${REFERENCE_PART_SELECTOR}, ${URI_SCHEMA.tag.toLowerCase()}`;
4033
+ var getReferenceParts = (reference) => Array.from(
4034
+ reference.querySelectorAll(REFERENCE_PART_SELECTOR)
4035
+ ).filter((element) => {
4036
+ if (isInTrackedDeletion(element)) return false;
4037
+ const owner = element.parentElement?.closest(REFERENCE_PART_OWNER_SELECTOR);
4038
+ return !owner || !reference.contains(owner);
4039
+ });
4040
+ var getReferenceFieldElements = (reference) => getReferenceParts(reference).flatMap((element) => {
4041
+ const field = findReferenceFieldByElement(element);
4042
+ return field ? [{ field, element }] : [];
4043
+ });
4044
+
4045
+ // src/validation/validateReferenceMarkup.ts
4046
+ var PERSONNAME_ORDER_ROLES = ["first-last", "last-first"];
4047
+ var ARTIST_OTHERCLASS = "artist";
4048
+ var NOT_PERMITTED_ELEMENTS = [
4049
+ { tag: BIBLIOID_TAG.toLowerCase() },
4050
+ { tag: "publisher" },
4051
+ { tag: AUTHORGROUP_TAG.toLowerCase() }
4052
+ ];
4053
+ var BIBLIOMSET = BIBLIOMSET_TAG.toLowerCase();
4054
+ var PERSONNAME = PERSONNAME_TAG.toLowerCase();
4055
+ var CONFGROUP = CONFGROUP_TAG.toLowerCase();
4056
+ var LINK = LINK_TAG.toLowerCase();
4057
+ var URI = URI_SCHEMA.tag.toLowerCase();
4058
+ var NAME_PARTS = [SURNAME_TAG, FIRSTNAME_TAG, HONORIFIC_TAG].map((tag) => tag.toLowerCase()).join(", ");
4059
+ var CONFERENCE_FIELDS_AND_DELETIONS = [
4060
+ CONFTITLE_TAG,
4061
+ CONFDATES_TAG,
4062
+ ADDRESS_TAG
4063
+ ].map((tag) => tag.toLowerCase()).concat("span.del").join(", ");
4064
+ var LOOSE_MARKUP = [
4065
+ BIBLIOMSET,
4066
+ PERSONNAME,
4067
+ URI,
4068
+ NAME_PARTS,
4069
+ CONFDATES_TAG.toLowerCase()
4070
+ ].concat(NOT_PERMITTED_ELEMENTS.map(({ tag }) => tag)).join(", ");
4071
+ var hasValue = (element, attribute) => !!element.getAttribute(attribute)?.trim();
4072
+ var hasUntaggedConferenceText = (element) => Array.from(element.childNodes).some((child) => {
4073
+ if (child.nodeType === Node.TEXT_NODE) return !!child.textContent?.trim();
4074
+ return child instanceof Element && !child.matches(CONFERENCE_FIELDS_AND_DELETIONS) && hasUntaggedConferenceText(child);
4075
+ });
4076
+ var isExternalLink = (link) => !hasValue(link, LINKEND_ATTRIBUTE);
4077
+ var DOI_URL = /^https?:\/\/(?:dx\.)?doi\.org\//i;
4078
+ var pointsAtDoiOrg = (link) => DOI_URL.test(link.getAttribute(LINK_ATTRIBUTE)?.trim() ?? "");
4079
+ var hasNameOrder = (personname) => {
4080
+ const order = personname.getAttribute("role")?.replace(/\s+/g, "");
4081
+ return PERSONNAME_ORDER_ROLES.some((role) => role === order);
4082
+ };
4083
+ var hasLooseReferenceMarkup = (reference) => Array.from(reference.querySelectorAll(LOOSE_MARKUP)).some(
4084
+ (element) => !isInTrackedDeletion(element)
4085
+ );
4086
+ var validateReferenceMarkup = (reference, typeSchema) => {
4087
+ const select = (selector) => Array.from(reference.querySelectorAll(selector)).filter(
4088
+ (element) => !isInTrackedDeletion(element)
4089
+ );
4090
+ const relations = typeSchema.bibliomsetRelations ?? [];
4091
+ const sets = select(BIBLIOMSET);
4092
+ const misrelatedSets = sets.filter(
4093
+ (set) => !relations.some((relation) => relation === set.getAttribute("relation"))
4094
+ );
4095
+ const hasEverySet = relations.every(
4096
+ (relation) => sets.some((set) => set.getAttribute("relation") === relation)
4097
+ );
4098
+ const rules = {
4099
+ missing_id: hasValue(reference, XMLID_ATTRIBUTE) ? [] : [reference],
4100
+ bibliomset_relation: misrelatedSets,
4101
+ bibliomset_missing: hasEverySet || misrelatedSets.length > 0 ? [] : [reference],
4102
+ bibliomset_repeated: sets.filter(
4103
+ (set, index) => sets.slice(0, index).some(
4104
+ (earlier) => earlier.getAttribute("relation") === set.getAttribute("relation")
4105
+ )
4106
+ ),
4107
+ bibliomset_title: sets.filter(
4108
+ (set) => !Array.from(set.querySelectorAll(TITLE_TAG.toLowerCase())).some(
4109
+ (title) => !isInTrackedDeletion(title)
4110
+ )
4111
+ ),
4112
+ bibliomset_nested: sets.filter(
4113
+ (set) => !!set.parentElement?.closest(BIBLIOMSET)
4114
+ ),
4115
+ part_editor: select(EDITOR_TAG.toLowerCase()).filter(
4116
+ (editor) => editor.closest(BIBLIOMSET)?.getAttribute("relation") === PART_BIBLIOMSET_RELATION
4117
+ ),
4118
+ personname_role: select(PERSONNAME).filter(
4119
+ (personname) => !hasNameOrder(personname)
4120
+ ),
4121
+ name_outside_personname: select(NAME_PARTS).filter(
4122
+ (part) => !part.closest(PERSONNAME)
4123
+ ),
4124
+ othercredit_artist: typeSchema.code === "recording" ? select(OTHERCREDIT_TAG.toLowerCase()).filter(
4125
+ (credit) => credit.getAttribute("otherclass") !== ARTIST_OTHERCLASS
4126
+ ) : [],
4127
+ link_without_target: select(LINK).filter(
4128
+ (link) => isExternalLink(link) && !hasValue(link, LINK_ATTRIBUTE)
4129
+ ),
4130
+ doi_inside_uri: select(LINK).filter(
4131
+ (link) => isExternalLink(link) && hasLiveUri(link) && pointsAtDoiOrg(link)
4132
+ ),
4133
+ doi_outside_doi_org: select(LINK).filter(
4134
+ (link) => isExternalLink(link) && hasValue(link, LINK_ATTRIBUTE) && !hasLiveUri(link) && !pointsAtDoiOrg(link)
4135
+ ),
4136
+ uri_outside_link: select(URI).filter(
4137
+ (uri) => !uri.closest(LINK) && !uri.closest(REFERENCE_PART_SELECTOR)
4138
+ ),
4139
+ confgroup_text: select(CONFGROUP).filter(hasUntaggedConferenceText),
4140
+ confdates_outside_confgroup: select(CONFDATES_TAG.toLowerCase()).filter(
4141
+ (dates) => !dates.closest(CONFGROUP)
4142
+ )
4143
+ };
4144
+ const wrongElements = [
4145
+ ...typeSchema.replacedElements ?? [],
4146
+ ...NOT_PERMITTED_ELEMENTS
4147
+ ].map(
4148
+ ({ tag, replacement }) => ({
4149
+ code: "wrong_element",
4150
+ tag,
4151
+ replacement,
4152
+ elements: select(tag).filter((element) => !isPubMedIdBiblioid(element))
4153
+ })
4154
+ );
4155
+ const markup = Object.entries(rules).map(
4156
+ ([rule, elements]) => ({
4157
+ code: "markup",
4158
+ rule,
4159
+ elements
4160
+ })
4161
+ );
4162
+ return [...wrongElements, ...markup].filter(
4163
+ ({ elements }) => elements.length > 0
4164
+ );
4165
+ };
4166
+
4167
+ // src/validation/validateReferenceStructure.ts
4168
+ var validateReferenceStructure = (reference) => {
4169
+ const typeSchema = findReferenceTypeSchemaByElement(reference);
4170
+ if (!typeSchema) return [{ code: "unknown_type" }];
4171
+ const issues = [];
4172
+ const present = /* @__PURE__ */ new Set();
4173
+ for (const { field } of getReferenceFieldElements(reference)) {
4174
+ if (!present.has(field) && !typeSchema.allowedFields.includes(field)) {
4175
+ issues.push({ code: "not_allowed", field });
4176
+ }
4177
+ present.add(field);
4178
+ }
4179
+ for (const field of typeSchema.requiredFields) {
4180
+ const isSatisfied = field === "creators" ? present.has("author") || present.has("editor") : present.has(field);
4181
+ if (!isSatisfied) issues.push({ code: "missing", field });
4182
+ }
4183
+ return [...issues, ...validateReferenceMarkup(reference, typeSchema)];
4184
+ };
4185
+ 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;
4186
+ var getReferenceStructureIssueElements = (reference, issue) => {
4187
+ if (issue.code === "not_allowed") {
4188
+ return getReferenceFieldElements(reference).filter(({ field }) => field === issue.field).map(({ element }) => element);
4189
+ }
4190
+ if (issue.code !== "markup" && issue.code !== "wrong_element") return [];
4191
+ const found = validateReferenceStructure(reference).find(
4192
+ (candidate) => isSameMarkupIssue(candidate, issue)
4193
+ );
4194
+ return (found?.elements ?? []).filter((element) => element !== reference);
4195
+ };
4196
+
4197
+ // src/validation/validateReference.ts
4198
+ var getFieldLabel = (field, typeSchema) => {
4199
+ if (field === "creators") {
4200
+ return typeSchema.allowedFields.includes("editor") ? "Author or editor" : "Author";
4201
+ }
4202
+ return typeSchema.fieldLabels?.[field] ?? REFERENCE_FIELD_SCHEMAS[field].label;
4203
+ };
4204
+ var getBibliomsetRelationCopy = (typeSchema) => {
4205
+ const relations = typeSchema.bibliomsetRelations ?? [];
4206
+ 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.`;
4207
+ };
4208
+ var getMarkupCopy = (rule, typeSchema) => {
4209
+ switch (rule) {
4210
+ case "missing_id":
4211
+ return {
4212
+ title: "Reference ID missing",
4213
+ kind: "missing",
4214
+ description: "Every reference needs an xml:id. Please add one."
4215
+ };
4216
+ case "bibliomset_relation":
4217
+ return {
4218
+ title: "Wrong bibliomset for this reference type",
4219
+ kind: "forbidden",
4220
+ description: getBibliomsetRelationCopy(typeSchema)
4221
+ };
4222
+ case "bibliomset_missing":
4223
+ return {
4224
+ title: "Bibliomset missing",
4225
+ kind: "missing",
4226
+ description: `${typeSchema.label} references need one bibliomset with the relation ${(typeSchema.bibliomsetRelations ?? []).join(" and one with ")}. Please wrap the details in them.`
4227
+ };
4228
+ case "bibliomset_repeated":
4229
+ return {
4230
+ title: "Bibliomset repeated",
4231
+ kind: "forbidden",
4232
+ description: "A reference holds one bibliomset of each relation. Please move the details of the repeated bibliomset into the first one."
4233
+ };
4234
+ case "bibliomset_title":
4235
+ return {
4236
+ title: "Bibliomset without a title",
4237
+ kind: "missing",
4238
+ description: "Every bibliomset must contain a title. Please move its title into it or remove the bibliomset."
4239
+ };
4240
+ case "bibliomset_nested":
4241
+ return {
4242
+ title: "Bibliomset inside another bibliomset",
4243
+ kind: "forbidden",
4244
+ description: "A bibliomset cannot sit inside another bibliomset. Please move it out so the two sit side by side."
4245
+ };
4246
+ case "part_editor":
4247
+ return {
4248
+ title: "Editor tagged in the chapter part",
4249
+ kind: "forbidden",
4250
+ 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."
4251
+ };
4252
+ case "personname_role":
4253
+ return {
4254
+ title: "Name order not set",
4255
+ kind: "missing",
4256
+ description: `Every personname needs a role of ${PERSONNAME_ORDER_ROLES.join(" or ")}. Please set the name order.`
4257
+ };
4258
+ case "name_outside_personname":
4259
+ return {
4260
+ title: "Name not wrapped in personname",
4261
+ kind: "forbidden",
4262
+ description: "A surname, firstname or honorific must sit inside a personname. Please wrap the name parts."
4263
+ };
4264
+ case "othercredit_artist":
4265
+ return {
4266
+ title: "Artist credit not marked",
4267
+ kind: "missing",
4268
+ description: `The othercredit of a recording needs otherclass="${ARTIST_OTHERCLASS}". Please set it.`
4269
+ };
4270
+ case "link_without_target":
4271
+ return {
4272
+ title: "Link incomplete",
4273
+ kind: "missing",
4274
+ description: "A link needs an xlink:href. Please complete the link."
4275
+ };
4276
+ case "doi_outside_doi_org":
4277
+ return {
4278
+ title: "DOI not pointing at doi.org",
4279
+ kind: "forbidden",
4280
+ 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."
4281
+ };
4282
+ case "doi_inside_uri":
4283
+ return {
4284
+ title: "DOI tagged as a URL",
4285
+ kind: "forbidden",
4286
+ description: "A DOI link holds the DOI directly, without a uri inside it. Please remove the uri."
4287
+ };
4288
+ case "uri_outside_link":
4289
+ return {
4290
+ title: "URL not wrapped in a link",
4291
+ kind: "forbidden",
4292
+ description: "A uri must sit inside a link that carries the xlink:href. Please wrap it in a link."
4293
+ };
4294
+ case "confgroup_text":
4295
+ return {
4296
+ title: "Text directly inside confgroup",
4297
+ kind: "forbidden",
4298
+ description: "A confgroup cannot hold text directly. Please tag the text as conftitle or confdates."
4299
+ };
4300
+ case "confdates_outside_confgroup":
4301
+ return {
4302
+ title: "Conference dates outside confgroup",
4303
+ kind: "forbidden",
4304
+ description: "Conference dates must sit inside a confgroup. Please wrap them in one."
4305
+ };
4306
+ }
4307
+ };
4308
+ var getIssueCopy = (issue, typeSchema) => {
4309
+ if (issue.code === "unknown_type" || !typeSchema) {
4310
+ return {
4311
+ title: "Reference type not set",
4312
+ kind: "missing",
4313
+ description: "This reference has no recognised type, so its structure cannot be checked. Please set its reference type."
4314
+ };
4315
+ }
4316
+ const typeLabel = typeSchema.label.toLowerCase();
4317
+ if (issue.code === "markup") return getMarkupCopy(issue.rule, typeSchema);
4318
+ if (issue.code === "wrong_element") {
4319
+ return {
4320
+ title: `${issue.tag} not allowed`,
4321
+ kind: "forbidden",
4322
+ 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.`
4323
+ };
4324
+ }
4325
+ const fieldLabel = getFieldLabel(issue.field, typeSchema);
4326
+ switch (issue.code) {
4327
+ case "missing":
4328
+ return {
4329
+ title: `${fieldLabel} missing`,
4330
+ kind: "missing",
4331
+ description: `Please tag the ${fieldLabel.toLowerCase()} in this ${typeLabel} reference.`
4332
+ };
4333
+ case "not_allowed":
4334
+ return {
4335
+ title: `${fieldLabel} not allowed`,
4336
+ kind: "forbidden",
4337
+ description: `${fieldLabel} is not used by ${typeLabel} references. Please untag or delete it.`
4338
+ };
4339
+ }
4340
+ };
4341
+ var validateReference = (reference) => {
4342
+ if (isDeletedElement(reference)) return [];
4343
+ const isBibliographyEntry = !!closestElementBySchema({
4344
+ element: reference,
4345
+ code: "referenceBibliography"
4346
+ });
4347
+ if (!isBibliographyEntry) return [];
4348
+ const isTagged = getReferenceParts(reference).length > 0 || hasLooseReferenceMarkup(reference);
4349
+ if (!isTagged) return [];
4350
+ const typeSchema = findReferenceTypeSchemaByElement(reference);
4351
+ return validateReferenceStructure(reference).map(
4352
+ (issue) => createValidationIssue(reference, {
4353
+ level: "warning",
4354
+ elements: getReferenceStructureIssueElements(reference, issue),
4355
+ ...getIssueCopy(issue, typeSchema)
4356
+ })
4357
+ );
4358
+ };
4359
+
3188
4360
  // src/validation/validateXml.ts
3189
- var validateElement = (element, root, elementsToLink, linkElements, schemasToValidateAgainst) => {
4361
+ var ELEMENTS_PER_STEP = 64;
4362
+ var DEFAULT_TIME_BUDGET_MS = 8;
4363
+ var validateOwnElement = (element, {
4364
+ elementsToLink,
4365
+ linkElements,
4366
+ schemasToValidateAgainst,
4367
+ errors
4368
+ }) => {
3190
4369
  if (isIgnoredElement(element)) {
3191
- return [];
4370
+ return false;
3192
4371
  }
3193
- const errors = [];
3194
4372
  const schema = findSchemaByElement(element);
3195
- if (schema) {
3196
- if (schemasToValidateAgainst.includes(schema.code)) {
3197
- errors.push(...validateElementAgainstSchema(element, schema));
3198
- }
3199
- if (schema.tag === FOOTNOTE_SCHEMA.tag) {
3200
- errors.push(...validateFootnoteNumber(element));
3201
- }
3202
- if (schema.code === HEADING_SCHEMA.code) {
3203
- errors.push(...validateHeadingHierarchy(element));
3204
- }
3205
- if (schema.code === OLINK_SCHEMA.code) {
3206
- errors.push(...validateOlink(element));
3207
- }
3208
- errors.push(...validateLinkend(element, elementsToLink));
3209
- errors.push(...validateElementToLinkTo(element, linkElements));
3210
- if (isIgnoredValidation(schema.code)) {
3211
- return errors;
3212
- }
4373
+ if (!schema) {
4374
+ return true;
3213
4375
  }
3214
- for (const child of Array.from(element.children)) {
4376
+ if (schemasToValidateAgainst.includes(schema.code)) {
3215
4377
  errors.push(
3216
- ...validateElement(
3217
- child,
3218
- root,
3219
- elementsToLink,
3220
- linkElements,
3221
- schemasToValidateAgainst
3222
- )
4378
+ ...schema.code === BIBLIOMIXED_SCHEMA.code ? validateReference(element) : validateElementAgainstSchema(element, schema)
3223
4379
  );
3224
4380
  }
3225
- return errors;
4381
+ if (schema.tag === FOOTNOTE_SCHEMA.tag) {
4382
+ errors.push(...validateFootnoteNumber(element));
4383
+ }
4384
+ if (schema.code === HEADING_SCHEMA.code) {
4385
+ errors.push(...validateHierarchy(element, "heading"));
4386
+ }
4387
+ if (schema.code === BOX_SCHEMA.code) {
4388
+ errors.push(...validateHierarchy(element, "box"));
4389
+ }
4390
+ if (schema.code === OLINK_SCHEMA.code) {
4391
+ errors.push(...validateOlink(element));
4392
+ }
4393
+ errors.push(...validateLinkend(element, elementsToLink));
4394
+ errors.push(...validateElementToLinkTo(element, linkElements));
4395
+ return !isIgnoredValidation(schema.code);
3226
4396
  };
3227
- var validateXml = (xml, elementsToLink, linkElements, schemasToValidateAgainst) => {
4397
+ function* validateElements(xml, context) {
4398
+ const pending = Array.from(xml.children).reverse();
4399
+ let elementsSinceStep = 0;
4400
+ for (let element = pending.pop(); element; element = pending.pop()) {
4401
+ if (validateOwnElement(element, context)) {
4402
+ const { children } = element;
4403
+ for (let index = children.length - 1; index >= 0; index -= 1) {
4404
+ pending.push(children[index]);
4405
+ }
4406
+ }
4407
+ if (++elementsSinceStep === ELEMENTS_PER_STEP) {
4408
+ elementsSinceStep = 0;
4409
+ yield;
4410
+ }
4411
+ }
4412
+ }
4413
+ function* validateXmlSteps(xml, elementsToLink, linkElements, schemasToValidateAgainst) {
3228
4414
  const errors = [];
3229
4415
  errors.push(...validateConsecutiveFootnotes(xml));
3230
4416
  errors.push(...validateConsecutiveFootnoteCues(xml));
3231
- errors.push(...validatePossibleWeblinks(xml));
3232
- for (const child of Array.from(xml.children)) {
3233
- errors.push(
3234
- ...validateElement(
3235
- child,
3236
- xml,
3237
- elementsToLink,
3238
- linkElements,
3239
- schemasToValidateAgainst
3240
- )
3241
- );
3242
- }
4417
+ yield;
4418
+ errors.push(...yield* validatePossibleWeblinksSteps(xml));
4419
+ yield* validateElements(xml, {
4420
+ elementsToLink: new Set(elementsToLink),
4421
+ linkElements: new Set(linkElements),
4422
+ schemasToValidateAgainst,
4423
+ errors
4424
+ });
3243
4425
  return errors;
4426
+ }
4427
+ var validateXml = (xml, elementsToLink, linkElements, schemasToValidateAgainst) => runSteps(
4428
+ validateXmlSteps(
4429
+ xml,
4430
+ elementsToLink,
4431
+ linkElements,
4432
+ schemasToValidateAgainst
4433
+ )
4434
+ );
4435
+ var yieldToMainThread = () => {
4436
+ const scheduler = globalThis.scheduler;
4437
+ if (scheduler?.yield) return scheduler.yield();
4438
+ return new Promise((resolve) => setTimeout(resolve, 0));
4439
+ };
4440
+ var throwIfAborted = (signal) => {
4441
+ if (!signal?.aborted) return;
4442
+ throw signal.reason ?? new DOMException("Aborted", "AbortError");
4443
+ };
4444
+ var validateXmlAsync = async (xml, elementsToLink, linkElements, schemasToValidateAgainst, { signal, timeBudgetMs = DEFAULT_TIME_BUDGET_MS } = {}) => {
4445
+ const steps = validateXmlSteps(
4446
+ xml,
4447
+ elementsToLink,
4448
+ linkElements,
4449
+ schemasToValidateAgainst
4450
+ );
4451
+ let sliceStart = performance.now();
4452
+ for (; ; ) {
4453
+ throwIfAborted(signal);
4454
+ const step = steps.next();
4455
+ if (step.done) return step.value;
4456
+ if (performance.now() - sliceStart >= timeBudgetMs) {
4457
+ await yieldToMainThread();
4458
+ sliceStart = performance.now();
4459
+ }
4460
+ }
3244
4461
  };
3245
4462
 
3246
4463
  // src/helpers/getElementLinks.ts
@@ -3341,6 +4558,13 @@ export {
3341
4558
  LAYOUT_USER_ATTRIBUTE,
3342
4559
  LEFT_INDENT_ATTRIBUTE,
3343
4560
  LINKEND_ATTRIBUTE,
4561
+ LINK_BLOCKER_ROLES,
4562
+ LINK_TO_CROSS_CHECK,
4563
+ POSSIBLE_WEBLINK_CLASS,
4564
+ POSSIBLE_WEBLINK_EXCLUDE_SELECTORS,
4565
+ REFERENCE_FIELD_SCHEMAS,
4566
+ REFERENCE_PART_SELECTOR,
4567
+ REFERENCE_TYPE_SCHEMAS,
3344
4568
  RIGHT_INDENT_ATTRIBUTE,
3345
4569
  SCHEMAS,
3346
4570
  SPACE_ABOVE_ATTRIBUTE,
@@ -3353,22 +4577,47 @@ export {
3353
4577
  TRACK_CHANGES_ATTR_DATA_TIME,
3354
4578
  TRACK_CHANGES_ATTR_DATA_USERID,
3355
4579
  TRACK_CHANGES_ATTR_DATA_USERNAME,
4580
+ VALIDATION_IGNORED_ATTRIBUTE,
3356
4581
  XMLID_ATTRIBUTE,
4582
+ clearWeblinkMatches,
3357
4583
  closestElementBySchema,
3358
4584
  createElement,
4585
+ extractFootnoteNumber,
3359
4586
  findAttributeDefinitionByName,
4587
+ findElementLinkedTo,
4588
+ findReferenceFieldByElement,
4589
+ findReferenceTypeSchemaByElement,
3360
4590
  findSchemaByCode,
3361
4591
  findSchemaByElement,
3362
4592
  getAdjacentElement,
3363
4593
  getAttributeName,
4594
+ getEffectiveChildElements,
3364
4595
  getElementLinks,
4596
+ getPossibleWeblinks,
4597
+ getReferenceFieldElements,
4598
+ getReferenceParts,
4599
+ getReferenceStructureIssueElements,
3365
4600
  getStore,
3366
4601
  isAttributeRestricted,
3367
4602
  isDeletedElement,
3368
4603
  isIgnoredAttribute,
3369
4604
  isIgnoredElement,
3370
4605
  isTrackChangesSchema,
4606
+ markPossibleWeblinks,
3371
4607
  queryAllElementsBySchema,
3372
4608
  queryElementBySchema,
3373
- validateXml
4609
+ validateAttributes,
4610
+ validateConsecutiveFootnoteCues,
4611
+ validateConsecutiveFootnotes,
4612
+ validateElementAgainstSchema,
4613
+ validateElementToLinkTo,
4614
+ validateFootnoteNumber,
4615
+ validateHierarchy,
4616
+ validateLinkend,
4617
+ validateOlink,
4618
+ validatePossibleWeblinks,
4619
+ validatePossibleWeblinksSteps,
4620
+ validateReferenceStructure,
4621
+ validateXml,
4622
+ validateXmlAsync
3374
4623
  };