pro-editor-schema 1.3.0 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +102 -53
- package/dist/index.d.mts +66 -28
- package/dist/index.d.ts +66 -28
- package/dist/index.js +387 -235
- package/dist/index.mjs +378 -231
- package/package.json +15 -3
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// src/schema/
|
|
1
|
+
// src/schema/helpers/createSchema.ts
|
|
2
2
|
var createSchema = (params) => {
|
|
3
3
|
return params;
|
|
4
4
|
};
|
|
@@ -40,10 +40,13 @@ var TRACK_CHANGES_ATTRS = [
|
|
|
40
40
|
];
|
|
41
41
|
var ELE_ID_ATTRIBUTE = "ele-id";
|
|
42
42
|
var STORE_ATTRIBUTE = "store";
|
|
43
|
+
var XMLID_ATTRIBUTE = "xmlid";
|
|
44
|
+
var LINKEND_ATTRIBUTE = "linkend";
|
|
43
45
|
var ID_ATTRS = [STORE_ATTRIBUTE, ELE_ID_ATTRIBUTE];
|
|
44
46
|
|
|
45
47
|
// src/schema/shared/allowedAtomsChildren.ts
|
|
46
48
|
var ATOM_CODES_ALLOWED_CHILDREN = [
|
|
49
|
+
{ code: "mark", required: false },
|
|
47
50
|
{ code: "indexterm", required: false },
|
|
48
51
|
{ code: "b", required: false },
|
|
49
52
|
{ code: "i", required: false },
|
|
@@ -87,6 +90,7 @@ var QUATERNARY_TAG = "QUATERNARY";
|
|
|
87
90
|
var BOOKMARK_TAG = "BOOKMARK";
|
|
88
91
|
var SEE_TAG = "SEE";
|
|
89
92
|
var REFERENCE_MARK_TAG = "REFERENCE";
|
|
93
|
+
var MARK_TAG = "MARK";
|
|
90
94
|
|
|
91
95
|
// src/schema/elementSchemas/atoms/b.ts
|
|
92
96
|
var B_SCHEMA = createSchema({
|
|
@@ -528,6 +532,23 @@ var ABBR_SCHEMA = createSchema({
|
|
|
528
532
|
allowedChildrenCodes: [...ATOM_CODES_ALLOWED_CHILDREN]
|
|
529
533
|
});
|
|
530
534
|
|
|
535
|
+
// src/schema/elementSchemas/atoms/mark.ts
|
|
536
|
+
var MARK_SCHEMA = createSchema({
|
|
537
|
+
code: "mark",
|
|
538
|
+
kind: "atom",
|
|
539
|
+
tag: MARK_TAG,
|
|
540
|
+
requiredAttributes: ["id"],
|
|
541
|
+
optionalAttributes: [
|
|
542
|
+
"data-markjs",
|
|
543
|
+
{
|
|
544
|
+
name: "data-replaceable",
|
|
545
|
+
values: ["true", "false"],
|
|
546
|
+
defaultValue: "true"
|
|
547
|
+
}
|
|
548
|
+
],
|
|
549
|
+
allowedChildrenCodes: [...ATOM_CODES_ALLOWED_CHILDREN]
|
|
550
|
+
});
|
|
551
|
+
|
|
531
552
|
// src/schema/elementSchemas/atoms/index.ts
|
|
532
553
|
var ATOM_SCHEMAS = {
|
|
533
554
|
indexterm: INDEXTERM_SCHEMA,
|
|
@@ -555,7 +576,8 @@ var ATOM_SCHEMAS = {
|
|
|
555
576
|
comment: COMMENT_SCHEMA,
|
|
556
577
|
query: QUERY_SCHEMA,
|
|
557
578
|
reply: REPLY_SCHEMA,
|
|
558
|
-
abbreviation: ABBR_SCHEMA
|
|
579
|
+
abbreviation: ABBR_SCHEMA,
|
|
580
|
+
mark: MARK_SCHEMA
|
|
559
581
|
};
|
|
560
582
|
|
|
561
583
|
// src/schema/elementSchemas/elements/elementsTags.ts
|
|
@@ -622,7 +644,7 @@ var EPIGRAPH_TAG = "EPIGRAPH";
|
|
|
622
644
|
var INFO_TAG = "INFO1";
|
|
623
645
|
var POEM_TAG = "POEM";
|
|
624
646
|
var BIBLIOMIXED_TAG = "BIBLIOMIXED";
|
|
625
|
-
var REFERENCE_BIBLIOGRAPHY_TAG = "
|
|
647
|
+
var REFERENCE_BIBLIOGRAPHY_TAG = "BIBLIOGRAPHY";
|
|
626
648
|
var BIBLIODIV_TAG = "BIBLIODIV";
|
|
627
649
|
var MATHPHRASE_TAG = "MATHPHRASE";
|
|
628
650
|
var MATH_TAG = "MATH";
|
|
@@ -1981,7 +2003,7 @@ var FOOTNOTE_SECTION_SCHEMA = createSchema({
|
|
|
1981
2003
|
});
|
|
1982
2004
|
|
|
1983
2005
|
// src/schema/elementSchemas/elements/heading.ts
|
|
1984
|
-
var HEADING_LEVEL = ["H1", "H2", "H3", "H4", "H5", "H6"];
|
|
2006
|
+
var HEADING_LEVEL = ["H0", "H1", "H2", "H3", "H4", "H5", "H6"];
|
|
1985
2007
|
var HEADING_ROLES = [...HEADING_LEVEL, "vignette_group"];
|
|
1986
2008
|
var HEADING_SCHEMA = createSchema({
|
|
1987
2009
|
code: "heading",
|
|
@@ -2052,6 +2074,7 @@ var POEM_SCHEMA = createSchema({
|
|
|
2052
2074
|
optionalAttributes: [...TRACK_CHANGES_ATTRS, "role", "trackmsg"],
|
|
2053
2075
|
defaultChildCode: "line",
|
|
2054
2076
|
allowedChildrenCodes: [
|
|
2077
|
+
{ code: "title1", required: false },
|
|
2055
2078
|
{ code: "line", required: false },
|
|
2056
2079
|
{ code: "linegroup", required: false },
|
|
2057
2080
|
{ code: "source1", required: false }
|
|
@@ -2347,55 +2370,10 @@ var SCHEMAS = {
|
|
|
2347
2370
|
...INLINE_ELEMENT_SCHEMAS
|
|
2348
2371
|
};
|
|
2349
2372
|
|
|
2350
|
-
// src/schema/
|
|
2351
|
-
var IGNORED_ELEMENT_SELECTORS = [
|
|
2352
|
-
"span.rhlabel",
|
|
2353
|
-
"span.printlabel",
|
|
2354
|
-
"span.refIcon",
|
|
2355
|
-
"span.missLink",
|
|
2356
|
-
"span.ref-drag",
|
|
2357
|
-
"span#dummySpan"
|
|
2358
|
-
];
|
|
2359
|
-
var IGNORED_VALIDATION_ELEMENT_SELECTORS = [
|
|
2360
|
-
"referenceBibliomixed"
|
|
2361
|
-
];
|
|
2362
|
-
|
|
2363
|
-
// src/schema/shared/ignoredAttributes.ts
|
|
2364
|
-
var IGNORED_ATTRIBUTES = [
|
|
2365
|
-
// Styling & layout
|
|
2366
|
-
"class",
|
|
2367
|
-
"style",
|
|
2368
|
-
// Editor state
|
|
2369
|
-
"contenteditable",
|
|
2370
|
-
"draggable",
|
|
2371
|
-
"data-prevpos",
|
|
2372
|
-
"tabindex",
|
|
2373
|
-
// Browser behaviour
|
|
2374
|
-
"spellcheck",
|
|
2375
|
-
"translate",
|
|
2376
|
-
"lang",
|
|
2377
|
-
"dir",
|
|
2378
|
-
"hidden",
|
|
2379
|
-
"data-gramm"
|
|
2380
|
-
];
|
|
2381
|
-
var IGNORED_ATTRIBUTES_STARTS_WITH = ["er-", "er_", "drop", "drag"];
|
|
2382
|
-
|
|
2383
|
-
// src/schema/utils/utils.ts
|
|
2384
|
-
var isTrackChangesSchema = (schema) => schema.code === "insertion" || schema.code === "deletion" || schema.code === "lineGroupRemoval";
|
|
2385
|
-
var isIgnoredAttribute = (attribute) => IGNORED_ATTRIBUTES.includes(attribute) || IGNORED_ATTRIBUTES_STARTS_WITH.some(
|
|
2386
|
-
(startsWith) => attribute.startsWith(startsWith)
|
|
2387
|
-
);
|
|
2388
|
-
var isIgnoredElement = (element) => IGNORED_ELEMENT_SELECTORS.some((selector) => element.matches(selector));
|
|
2389
|
-
var isIgnoredValidation = (code) => IGNORED_VALIDATION_ELEMENT_SELECTORS.includes(code);
|
|
2390
|
-
var findSchemaByCode = (code) => SCHEMAS[code];
|
|
2391
|
-
var findSchemaByElement = (element) => {
|
|
2392
|
-
const schema = Object.values(SCHEMAS).find(
|
|
2393
|
-
(schema2) => schema2.tag == element.tagName && (!schema2.matchesElement || schema2.matchesElement(element))
|
|
2394
|
-
);
|
|
2395
|
-
return schema;
|
|
2396
|
-
};
|
|
2397
|
-
var isAttributeRestricted = (attr) => typeof attr !== "string";
|
|
2373
|
+
// src/schema/helpers/getAttributeName.ts
|
|
2398
2374
|
var getAttributeName = (attribute) => typeof attribute === "string" ? attribute.toLowerCase() : attribute.name.toLowerCase();
|
|
2375
|
+
|
|
2376
|
+
// src/schema/helpers/findAttributeDefinitionByName.ts
|
|
2399
2377
|
var findAttributeDefinitionByName = (definitions, name) => {
|
|
2400
2378
|
for (const def of definitions) {
|
|
2401
2379
|
if (getAttributeName(def) === name.toLowerCase()) {
|
|
@@ -2405,47 +2383,29 @@ var findAttributeDefinitionByName = (definitions, name) => {
|
|
|
2405
2383
|
return void 0;
|
|
2406
2384
|
};
|
|
2407
2385
|
|
|
2408
|
-
// src/schema/
|
|
2409
|
-
var
|
|
2410
|
-
schemaCode,
|
|
2411
|
-
attributes
|
|
2412
|
-
}) => {
|
|
2413
|
-
const schema = findSchemaByCode(schemaCode);
|
|
2414
|
-
const element = document.createElement(schema.tag.toLowerCase());
|
|
2415
|
-
for (const [name, value] of Object.entries(attributes)) {
|
|
2416
|
-
if (!value) continue;
|
|
2417
|
-
element.setAttribute(name, String(value));
|
|
2418
|
-
}
|
|
2419
|
-
return element;
|
|
2420
|
-
};
|
|
2386
|
+
// src/schema/helpers/findSchemaByCode.ts
|
|
2387
|
+
var findSchemaByCode = (code) => SCHEMAS[code];
|
|
2421
2388
|
|
|
2422
|
-
// src/schema/
|
|
2423
|
-
var
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
}
|
|
2430
|
-
return element;
|
|
2431
|
-
};
|
|
2432
|
-
var queryAllElementsBySchema = (content, schemaCode) => {
|
|
2433
|
-
const schema = findSchemaByCode(schemaCode);
|
|
2434
|
-
const elements = content.querySelectorAll(
|
|
2435
|
-
schema.tag.toLowerCase()
|
|
2389
|
+
// src/schema/helpers/matchesSchemaTag.ts
|
|
2390
|
+
var matchesSchemaTag = (element, tag) => element.tagName.toUpperCase() === tag.toUpperCase();
|
|
2391
|
+
|
|
2392
|
+
// 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))
|
|
2436
2396
|
);
|
|
2437
|
-
|
|
2438
|
-
for (const element of elements) {
|
|
2439
|
-
if (schema.matchesElement && !schema.matchesElement(element)) {
|
|
2440
|
-
continue;
|
|
2441
|
-
}
|
|
2442
|
-
matchingElements.push(element);
|
|
2443
|
-
}
|
|
2444
|
-
return matchingElements;
|
|
2397
|
+
return schema;
|
|
2445
2398
|
};
|
|
2446
2399
|
|
|
2400
|
+
// src/schema/helpers/isAttributeRestricted.ts
|
|
2401
|
+
var isAttributeRestricted = (attr) => typeof attr !== "string";
|
|
2402
|
+
|
|
2403
|
+
// src/schema/helpers/isTrackChangesSchema.ts
|
|
2404
|
+
var isTrackChangesSchema = (schema) => schema.code === "insertion" || schema.code === "deletion" || schema.code === "lineGroupRemoval";
|
|
2405
|
+
|
|
2447
2406
|
// src/schema/shared/labelElements.ts
|
|
2448
2407
|
var ElementLabel = {
|
|
2408
|
+
mark: "Mark",
|
|
2449
2409
|
referenceBibliomixed: "Reference Bibliomixed",
|
|
2450
2410
|
referenceBibliography: "Reference Bibliography",
|
|
2451
2411
|
bibliodiv: "Bibliodiv",
|
|
@@ -2580,40 +2540,54 @@ var DEPENDENT_FORBIDDEN_ELEMENTS = [
|
|
|
2580
2540
|
}
|
|
2581
2541
|
];
|
|
2582
2542
|
|
|
2583
|
-
// src/
|
|
2584
|
-
var
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
var
|
|
2593
|
-
id: generateValidationIssueId(),
|
|
2594
|
-
...issue
|
|
2595
|
-
});
|
|
2596
|
-
var addValidationIssue = (errors, issue) => {
|
|
2597
|
-
errors.push(createValidationIssue(issue));
|
|
2598
|
-
};
|
|
2543
|
+
// src/helpers/isIgnoredElement.ts
|
|
2544
|
+
var IGNORED_ELEMENT_SELECTORS = [
|
|
2545
|
+
"span.rhlabel",
|
|
2546
|
+
"span.printlabel",
|
|
2547
|
+
"span.refIcon",
|
|
2548
|
+
"span.missLink",
|
|
2549
|
+
"span.ref-drag",
|
|
2550
|
+
"span#dummySpan"
|
|
2551
|
+
];
|
|
2552
|
+
var isIgnoredElement = (element) => IGNORED_ELEMENT_SELECTORS.some((selector) => element.matches(selector));
|
|
2599
2553
|
|
|
2600
|
-
// src/validation/
|
|
2601
|
-
var
|
|
2602
|
-
|
|
2603
|
-
|
|
2554
|
+
// src/validation/helpers/isIgnoredValidation.ts
|
|
2555
|
+
var IGNORED_VALIDATION_ELEMENT_SELECTORS = [
|
|
2556
|
+
"referenceBibliomixed"
|
|
2557
|
+
];
|
|
2558
|
+
var isIgnoredValidation = (code) => IGNORED_VALIDATION_ELEMENT_SELECTORS.includes(code);
|
|
2604
2559
|
|
|
2605
|
-
// src/
|
|
2606
|
-
var
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
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;
|
|
2610
2574
|
}
|
|
2611
|
-
|
|
2575
|
+
if (ignoreDeletedElements && isDeletedElement(closestElement)) {
|
|
2576
|
+
return closestElementBySchema({
|
|
2577
|
+
element: closestElement,
|
|
2578
|
+
code,
|
|
2579
|
+
ignoreDeletedElements
|
|
2580
|
+
});
|
|
2581
|
+
}
|
|
2582
|
+
return closestElement;
|
|
2612
2583
|
};
|
|
2613
2584
|
|
|
2614
|
-
// src/
|
|
2585
|
+
// src/helpers/isDeletedElement.ts
|
|
2615
2586
|
var isDeletedElement = (element) => {
|
|
2616
|
-
return !!
|
|
2587
|
+
return !!closestElementBySchema({
|
|
2588
|
+
element,
|
|
2589
|
+
code: "deletion"
|
|
2590
|
+
});
|
|
2617
2591
|
};
|
|
2618
2592
|
|
|
2619
2593
|
// src/validation/utils/getElementsSelector.ts
|
|
@@ -2629,63 +2603,35 @@ var getElementsSelector = ({
|
|
|
2629
2603
|
return elements;
|
|
2630
2604
|
};
|
|
2631
2605
|
|
|
2632
|
-
// src/validation/
|
|
2633
|
-
var
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
TABLE_LINK_ROLE,
|
|
2638
|
-
FIGURE_LINK_ROLE,
|
|
2639
|
-
EQUATION_LINK_ROLE,
|
|
2640
|
-
FOOTNOTE_LINK_ROLE,
|
|
2641
|
-
REFERENCE_LINK_ROLE
|
|
2642
|
-
];
|
|
2643
|
-
var LINK_BLOCKER_ROLES = [
|
|
2644
|
-
TABLE_LINK_ROLE,
|
|
2645
|
-
FIGURE_LINK_ROLE,
|
|
2646
|
-
EQUATION_LINK_ROLE,
|
|
2647
|
-
FOOTNOTE_LINK_ROLE
|
|
2648
|
-
];
|
|
2649
|
-
var validateLinkend = (linkElement, elementsToLink) => {
|
|
2650
|
-
const linkend = linkElement.getAttribute("linkend");
|
|
2651
|
-
if (!linkend) {
|
|
2652
|
-
return [];
|
|
2653
|
-
}
|
|
2654
|
-
const isLinkFootnoteCue = linkElement.tagName.toUpperCase() === FOOTNOTE_LINK_SCHEMA.tag;
|
|
2655
|
-
if (isLinkFootnoteCue) {
|
|
2656
|
-
if (findElementLinkedTo(linkend, elementsToLink)) {
|
|
2657
|
-
return [];
|
|
2658
|
-
}
|
|
2659
|
-
return [
|
|
2660
|
-
createValidationIssue({
|
|
2661
|
-
store: getStore(linkElement),
|
|
2662
|
-
title: "Unlinked footnote cue",
|
|
2663
|
-
kind: "unlinked",
|
|
2664
|
-
description: "This footnote cue is not referenced to any footnote in this chapter. Please link it again manually.",
|
|
2665
|
-
level: "blocker"
|
|
2666
|
-
})
|
|
2667
|
-
];
|
|
2668
|
-
}
|
|
2669
|
-
const role = linkElement.getAttribute("role");
|
|
2670
|
-
if (!role) {
|
|
2671
|
-
return [];
|
|
2672
|
-
}
|
|
2673
|
-
if (!LINK_TO_CROSS_CHECK.includes(role)) {
|
|
2674
|
-
return [];
|
|
2606
|
+
// src/validation/utils/retrieveTextIgnoringNodesWithSelector.ts
|
|
2607
|
+
var retrieveTextIgnoringNodesWithSelector = (element, selector = ".del") => {
|
|
2608
|
+
const clonedElement = element.cloneNode(true);
|
|
2609
|
+
for (const delElement of clonedElement.querySelectorAll(selector)) {
|
|
2610
|
+
delElement.remove();
|
|
2675
2611
|
}
|
|
2676
|
-
|
|
2677
|
-
|
|
2612
|
+
return clonedElement.textContent || "";
|
|
2613
|
+
};
|
|
2614
|
+
|
|
2615
|
+
// src/helpers/getStore.ts
|
|
2616
|
+
var getStore = (element) => {
|
|
2617
|
+
return element.getAttribute(STORE_ATTRIBUTE) || "";
|
|
2618
|
+
};
|
|
2619
|
+
|
|
2620
|
+
// src/validation/helpers/generateValidationIssueId.ts
|
|
2621
|
+
var generateValidationIssueId = () => {
|
|
2622
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
2623
|
+
return crypto.randomUUID();
|
|
2678
2624
|
}
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2625
|
+
return `${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
2626
|
+
};
|
|
2627
|
+
|
|
2628
|
+
// src/validation/helpers/addValidationIssue.ts
|
|
2629
|
+
var createValidationIssue = (issue) => ({
|
|
2630
|
+
id: generateValidationIssueId(),
|
|
2631
|
+
...issue
|
|
2632
|
+
});
|
|
2633
|
+
var addValidationIssue = (errors, issue) => {
|
|
2634
|
+
errors.push(createValidationIssue(issue));
|
|
2689
2635
|
};
|
|
2690
2636
|
|
|
2691
2637
|
// src/validation/validateFootnotes.ts
|
|
@@ -2698,15 +2644,11 @@ var extractFootnoteNumber = (footnote) => {
|
|
|
2698
2644
|
}
|
|
2699
2645
|
return footnoteNumber;
|
|
2700
2646
|
};
|
|
2701
|
-
var
|
|
2647
|
+
var validateFootnoteNumber = (footnoteElement) => {
|
|
2702
2648
|
const errors = [];
|
|
2703
|
-
const linkend = footnoteElement.getAttribute("xmlid") || "";
|
|
2704
2649
|
const footnoteNumber = footnoteElement.querySelector(
|
|
2705
2650
|
FOOTNOTE_NUMBER_SCHEMA.tag
|
|
2706
2651
|
);
|
|
2707
|
-
if (findElementLinkedTo(linkend, linkElements)) {
|
|
2708
|
-
return errors;
|
|
2709
|
-
}
|
|
2710
2652
|
if (!footnoteNumber) {
|
|
2711
2653
|
addValidationIssue(errors, {
|
|
2712
2654
|
store: getStore(footnoteElement),
|
|
@@ -2716,14 +2658,6 @@ var validateFootnoteCue = (footnoteElement, linkElements) => {
|
|
|
2716
2658
|
level: "blocker"
|
|
2717
2659
|
});
|
|
2718
2660
|
}
|
|
2719
|
-
const label = extractFootnoteNumber(footnoteNumber);
|
|
2720
|
-
addValidationIssue(errors, {
|
|
2721
|
-
store: getStore(footnoteElement),
|
|
2722
|
-
title: "Unreferenced footnote",
|
|
2723
|
-
kind: "unlinked",
|
|
2724
|
-
description: `The footnote ${label} is not referenced to any footnote cue in this chapter. Please reference it in the chapter.`,
|
|
2725
|
-
level: "blocker"
|
|
2726
|
-
});
|
|
2727
2661
|
return errors;
|
|
2728
2662
|
};
|
|
2729
2663
|
var validateConsecutiveFootnotes = (root) => {
|
|
@@ -2808,6 +2742,92 @@ var validateConsecutiveFootnoteCues = (root) => {
|
|
|
2808
2742
|
return errors;
|
|
2809
2743
|
};
|
|
2810
2744
|
|
|
2745
|
+
// src/validation/validateLinkend.ts
|
|
2746
|
+
var findElementLinkedTo = (linkend, elementsToLink) => {
|
|
2747
|
+
return elementsToLink.includes(linkend);
|
|
2748
|
+
};
|
|
2749
|
+
var LINK_TO_CROSS_CHECK = [
|
|
2750
|
+
TABLE_LINK_ROLE,
|
|
2751
|
+
FIGURE_LINK_ROLE,
|
|
2752
|
+
EQUATION_LINK_ROLE,
|
|
2753
|
+
FOOTNOTE_LINK_ROLE,
|
|
2754
|
+
REFERENCE_LINK_ROLE
|
|
2755
|
+
];
|
|
2756
|
+
var LINK_BLOCKER_ROLES = [
|
|
2757
|
+
TABLE_LINK_ROLE,
|
|
2758
|
+
FIGURE_LINK_ROLE,
|
|
2759
|
+
EQUATION_LINK_ROLE,
|
|
2760
|
+
FOOTNOTE_LINK_ROLE
|
|
2761
|
+
];
|
|
2762
|
+
var validateLinkend = (linkElement, elementsToLink) => {
|
|
2763
|
+
const linkend = linkElement.getAttribute("linkend");
|
|
2764
|
+
if (!linkend) {
|
|
2765
|
+
return [];
|
|
2766
|
+
}
|
|
2767
|
+
if (findElementLinkedTo(linkend, elementsToLink)) {
|
|
2768
|
+
return [];
|
|
2769
|
+
}
|
|
2770
|
+
const isLinkFootnoteCue = matchesSchemaTag(
|
|
2771
|
+
linkElement,
|
|
2772
|
+
FOOTNOTE_LINK_SCHEMA.tag
|
|
2773
|
+
);
|
|
2774
|
+
if (isLinkFootnoteCue) {
|
|
2775
|
+
return [
|
|
2776
|
+
createValidationIssue({
|
|
2777
|
+
store: getStore(linkElement),
|
|
2778
|
+
title: "Unlinked footnote cue",
|
|
2779
|
+
kind: "unlinked",
|
|
2780
|
+
description: "This footnote cue is not referenced to any footnote in this chapter. Please link it again manually.",
|
|
2781
|
+
level: "blocker"
|
|
2782
|
+
})
|
|
2783
|
+
];
|
|
2784
|
+
}
|
|
2785
|
+
const isLink = matchesSchemaTag(linkElement, LINK_SCHEMA.tag);
|
|
2786
|
+
if (!isLink) {
|
|
2787
|
+
return [];
|
|
2788
|
+
}
|
|
2789
|
+
const role = linkElement.getAttribute("role");
|
|
2790
|
+
if (!role) {
|
|
2791
|
+
return [];
|
|
2792
|
+
}
|
|
2793
|
+
if (!LINK_TO_CROSS_CHECK.includes(role)) {
|
|
2794
|
+
return [];
|
|
2795
|
+
}
|
|
2796
|
+
const isBlocker = LINK_BLOCKER_ROLES.includes(role.toLowerCase());
|
|
2797
|
+
return [
|
|
2798
|
+
createValidationIssue({
|
|
2799
|
+
store: getStore(linkElement),
|
|
2800
|
+
title: "Unlinked element",
|
|
2801
|
+
kind: "unlinked",
|
|
2802
|
+
description: "This link is not referenced to any element in the current chapter or any other chapter. Please link it again manually.",
|
|
2803
|
+
level: isBlocker ? "blocker" : "warning"
|
|
2804
|
+
})
|
|
2805
|
+
];
|
|
2806
|
+
};
|
|
2807
|
+
|
|
2808
|
+
// src/helpers/isIgnoredAttribute.ts
|
|
2809
|
+
var IGNORED_ATTRIBUTES = [
|
|
2810
|
+
// Styling & layout
|
|
2811
|
+
"class",
|
|
2812
|
+
"style",
|
|
2813
|
+
// Editor state
|
|
2814
|
+
"contenteditable",
|
|
2815
|
+
"draggable",
|
|
2816
|
+
"data-prevpos",
|
|
2817
|
+
"tabindex",
|
|
2818
|
+
// Browser behaviour
|
|
2819
|
+
"spellcheck",
|
|
2820
|
+
"translate",
|
|
2821
|
+
"lang",
|
|
2822
|
+
"dir",
|
|
2823
|
+
"hidden",
|
|
2824
|
+
"data-gramm"
|
|
2825
|
+
];
|
|
2826
|
+
var IGNORED_ATTRIBUTES_STARTS_WITH = ["er-", "er_", "drop", "drag"];
|
|
2827
|
+
var isIgnoredAttribute = (attribute) => IGNORED_ATTRIBUTES.includes(attribute) || IGNORED_ATTRIBUTES_STARTS_WITH.some(
|
|
2828
|
+
(startsWith) => attribute.startsWith(startsWith)
|
|
2829
|
+
);
|
|
2830
|
+
|
|
2811
2831
|
// src/validation/validateAttributes.ts
|
|
2812
2832
|
var validateAttributes = (element, schema) => {
|
|
2813
2833
|
const errors = [];
|
|
@@ -2851,7 +2871,7 @@ var validateAttributes = (element, schema) => {
|
|
|
2851
2871
|
// src/validation/validateChildren.ts
|
|
2852
2872
|
var validateElementAgainstSchema = (element, schema) => {
|
|
2853
2873
|
const errors = [];
|
|
2854
|
-
if (element
|
|
2874
|
+
if (!matchesSchemaTag(element, schema.tag)) {
|
|
2855
2875
|
addValidationIssue(errors, {
|
|
2856
2876
|
store: getStore(element),
|
|
2857
2877
|
title: `Expected ${schema.tag}, got ${element.tagName}`,
|
|
@@ -2952,27 +2972,79 @@ var getExtraInstruction = (schema, childSchema) => {
|
|
|
2952
2972
|
return "";
|
|
2953
2973
|
};
|
|
2954
2974
|
|
|
2955
|
-
// src/validation/
|
|
2975
|
+
// src/validation/validateElementToLinkTo.ts
|
|
2956
2976
|
var findElementLinkedTo2 = (xmlid, linkElements) => {
|
|
2957
2977
|
return linkElements.includes(xmlid);
|
|
2958
2978
|
};
|
|
2959
|
-
var
|
|
2960
|
-
|
|
2979
|
+
var isFootnote = (element) => {
|
|
2980
|
+
return matchesSchemaTag(element, FOOTNOTE_SCHEMA.tag);
|
|
2981
|
+
};
|
|
2982
|
+
var isReference = (element) => {
|
|
2983
|
+
return matchesSchemaTag(element, BIBLIOMIXED_SCHEMA.tag) || !!closestElementBySchema({
|
|
2984
|
+
element,
|
|
2985
|
+
code: "referenceBibliography"
|
|
2986
|
+
});
|
|
2987
|
+
};
|
|
2988
|
+
var isTable = (element) => {
|
|
2989
|
+
return matchesSchemaTag(element, TABLE_SCHEMA.tag);
|
|
2990
|
+
};
|
|
2991
|
+
var isFigure = (element) => {
|
|
2992
|
+
return matchesSchemaTag(element, FIGURE_SCHEMA.tag);
|
|
2993
|
+
};
|
|
2994
|
+
var validateElementToLinkTo = (element, linkElements) => {
|
|
2995
|
+
const xmlid = element.getAttribute("xmlid");
|
|
2961
2996
|
if (!xmlid) {
|
|
2962
2997
|
return [];
|
|
2963
2998
|
}
|
|
2964
2999
|
if (findElementLinkedTo2(xmlid, linkElements)) {
|
|
2965
3000
|
return [];
|
|
2966
3001
|
}
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
3002
|
+
if (isFootnote(element)) {
|
|
3003
|
+
const label = extractFootnoteNumber(element);
|
|
3004
|
+
return [
|
|
3005
|
+
createValidationIssue({
|
|
3006
|
+
store: getStore(element),
|
|
3007
|
+
title: "Uncited footnote",
|
|
3008
|
+
kind: "uncited",
|
|
3009
|
+
description: `The footnote ${label} is not cited to any footnote cue in this chapter. Please reference it in the chapter.`,
|
|
3010
|
+
level: "blocker"
|
|
3011
|
+
})
|
|
3012
|
+
];
|
|
3013
|
+
}
|
|
3014
|
+
if (isReference(element)) {
|
|
3015
|
+
return [
|
|
3016
|
+
createValidationIssue({
|
|
3017
|
+
store: getStore(element),
|
|
3018
|
+
title: "Uncited reference",
|
|
3019
|
+
kind: "uncited",
|
|
3020
|
+
description: "This reference is not cited in this chapter or any other chapter. Please add a link to this reference or delete it.",
|
|
3021
|
+
level: "warning"
|
|
3022
|
+
})
|
|
3023
|
+
];
|
|
3024
|
+
}
|
|
3025
|
+
if (isTable(element)) {
|
|
3026
|
+
return [
|
|
3027
|
+
createValidationIssue({
|
|
3028
|
+
store: getStore(element),
|
|
3029
|
+
title: "Uncited table",
|
|
3030
|
+
kind: "uncited",
|
|
3031
|
+
description: "This table is not cited in this chapter or any other chapter. Please add a link to this table or delete it.",
|
|
3032
|
+
level: "warning"
|
|
3033
|
+
})
|
|
3034
|
+
];
|
|
3035
|
+
}
|
|
3036
|
+
if (isFigure(element)) {
|
|
3037
|
+
return [
|
|
3038
|
+
createValidationIssue({
|
|
3039
|
+
store: getStore(element),
|
|
3040
|
+
title: "Uncited figure",
|
|
3041
|
+
kind: "uncited",
|
|
3042
|
+
description: "This figure is not cited in this chapter or any other chapter. Please add a link to this figure or delete it.",
|
|
3043
|
+
level: "warning"
|
|
3044
|
+
})
|
|
3045
|
+
];
|
|
3046
|
+
}
|
|
3047
|
+
return [];
|
|
2976
3048
|
};
|
|
2977
3049
|
|
|
2978
3050
|
// src/validation/validateWeblink.ts
|
|
@@ -3024,30 +3096,20 @@ var validatePossibleWeblinks = (root) => {
|
|
|
3024
3096
|
return errors;
|
|
3025
3097
|
};
|
|
3026
3098
|
|
|
3027
|
-
// src/validation/utils/getParentElement.ts
|
|
3028
|
-
var getParentElement = ({
|
|
3029
|
-
element,
|
|
3030
|
-
schemaCode,
|
|
3031
|
-
filterDeletedNodes
|
|
3032
|
-
}) => {
|
|
3033
|
-
let current = element.parentElement;
|
|
3034
|
-
while (current) {
|
|
3035
|
-
const isValidParent = findSchemaByElement(current)?.code === schemaCode;
|
|
3036
|
-
const isFilterDeleted = filterDeletedNodes && isDeletedElement(current);
|
|
3037
|
-
if (isValidParent || isFilterDeleted) {
|
|
3038
|
-
return current;
|
|
3039
|
-
}
|
|
3040
|
-
current = current.parentElement;
|
|
3041
|
-
}
|
|
3042
|
-
return void 0;
|
|
3043
|
-
};
|
|
3044
|
-
|
|
3045
3099
|
// src/validation/validateHeadingHierarchy.ts
|
|
3100
|
+
var shouldSuppressWarning = (element) => {
|
|
3101
|
+
const closestBox = closestElementBySchema({
|
|
3102
|
+
element,
|
|
3103
|
+
code: BOX_SCHEMA.code,
|
|
3104
|
+
ignoreDeletedElements: true
|
|
3105
|
+
});
|
|
3106
|
+
return !!closestBox;
|
|
3107
|
+
};
|
|
3046
3108
|
var getHierarchyLevel = (element) => {
|
|
3047
3109
|
const role = element.getAttribute("role");
|
|
3048
3110
|
if (!role) return void 0;
|
|
3049
|
-
const validHeadingLevel = HEADING_LEVEL.indexOf(role)
|
|
3050
|
-
if (
|
|
3111
|
+
const validHeadingLevel = HEADING_LEVEL.indexOf(role);
|
|
3112
|
+
if (validHeadingLevel === -1) return void 0;
|
|
3051
3113
|
return validHeadingLevel;
|
|
3052
3114
|
};
|
|
3053
3115
|
var validateHeadingHierarchy = (element) => {
|
|
@@ -3055,17 +3117,23 @@ var validateHeadingHierarchy = (element) => {
|
|
|
3055
3117
|
if (isDeletedElement(element)) {
|
|
3056
3118
|
return errors;
|
|
3057
3119
|
}
|
|
3120
|
+
if (shouldSuppressWarning(element)) {
|
|
3121
|
+
return errors;
|
|
3122
|
+
}
|
|
3058
3123
|
const level = getHierarchyLevel(element);
|
|
3059
3124
|
if (level === void 0) {
|
|
3060
3125
|
return errors;
|
|
3061
3126
|
}
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3127
|
+
if (!element.parentElement) {
|
|
3128
|
+
return errors;
|
|
3129
|
+
}
|
|
3130
|
+
const parentHeading = closestElementBySchema({
|
|
3131
|
+
element: element.parentElement,
|
|
3132
|
+
code: HEADING_SCHEMA.code,
|
|
3133
|
+
ignoreDeletedElements: true
|
|
3066
3134
|
});
|
|
3067
3135
|
if (!parentHeading) {
|
|
3068
|
-
if (level
|
|
3136
|
+
if (level > 1) {
|
|
3069
3137
|
addValidationIssue(errors, {
|
|
3070
3138
|
store: getStore(element),
|
|
3071
3139
|
title: "Missing heading H1",
|
|
@@ -3095,7 +3163,7 @@ var validateHeadingHierarchy = (element) => {
|
|
|
3095
3163
|
};
|
|
3096
3164
|
|
|
3097
3165
|
// src/validation/validateOlink.ts
|
|
3098
|
-
var ORCID_PATTERN = /^\d{4}-\d{4}-\d{4}-\d{
|
|
3166
|
+
var ORCID_PATTERN = /^\d{4}-\d{4}-\d{4}-\d{3}[\dX]$/;
|
|
3099
3167
|
var validateOlink = (element) => {
|
|
3100
3168
|
const errors = [];
|
|
3101
3169
|
if (isDeletedElement(element)) {
|
|
@@ -3128,14 +3196,8 @@ var validateElement = (element, root, elementsToLink, linkElements, schemasToVal
|
|
|
3128
3196
|
if (schemasToValidateAgainst.includes(schema.code)) {
|
|
3129
3197
|
errors.push(...validateElementAgainstSchema(element, schema));
|
|
3130
3198
|
}
|
|
3131
|
-
if (schema.tag === LINK_SCHEMA.tag || schema.tag === FOOTNOTE_LINK_SCHEMA.tag) {
|
|
3132
|
-
errors.push(...validateLinkend(element, elementsToLink));
|
|
3133
|
-
}
|
|
3134
|
-
if (schema.tag === BIBLIOMIXED_SCHEMA.tag) {
|
|
3135
|
-
errors.push(...validateReferenceCited(element, linkElements));
|
|
3136
|
-
}
|
|
3137
3199
|
if (schema.tag === FOOTNOTE_SCHEMA.tag) {
|
|
3138
|
-
errors.push(...
|
|
3200
|
+
errors.push(...validateFootnoteNumber(element));
|
|
3139
3201
|
}
|
|
3140
3202
|
if (schema.code === HEADING_SCHEMA.code) {
|
|
3141
3203
|
errors.push(...validateHeadingHierarchy(element));
|
|
@@ -3143,6 +3205,8 @@ var validateElement = (element, root, elementsToLink, linkElements, schemasToVal
|
|
|
3143
3205
|
if (schema.code === OLINK_SCHEMA.code) {
|
|
3144
3206
|
errors.push(...validateOlink(element));
|
|
3145
3207
|
}
|
|
3208
|
+
errors.push(...validateLinkend(element, elementsToLink));
|
|
3209
|
+
errors.push(...validateElementToLinkTo(element, linkElements));
|
|
3146
3210
|
if (isIgnoredValidation(schema.code)) {
|
|
3147
3211
|
return errors;
|
|
3148
3212
|
}
|
|
@@ -3178,6 +3242,84 @@ var validateXml = (xml, elementsToLink, linkElements, schemasToValidateAgainst)
|
|
|
3178
3242
|
}
|
|
3179
3243
|
return errors;
|
|
3180
3244
|
};
|
|
3245
|
+
|
|
3246
|
+
// src/helpers/getElementLinks.ts
|
|
3247
|
+
var getElementLinks = (contentChaptersToValidate) => {
|
|
3248
|
+
const elementsToLink = [];
|
|
3249
|
+
const linkedElements = [];
|
|
3250
|
+
for (const chapter of contentChaptersToValidate) {
|
|
3251
|
+
const parser = new DOMParser();
|
|
3252
|
+
const content = parser.parseFromString(chapter, "text/html");
|
|
3253
|
+
const elementsXMLID = content.querySelectorAll(`[${XMLID_ATTRIBUTE}]`);
|
|
3254
|
+
for (const elementWithXMLID of elementsXMLID) {
|
|
3255
|
+
const linkValue = elementWithXMLID.getAttribute(XMLID_ATTRIBUTE);
|
|
3256
|
+
if (!linkValue) continue;
|
|
3257
|
+
elementsToLink.push(linkValue);
|
|
3258
|
+
}
|
|
3259
|
+
const elementsLinkend = content.querySelectorAll(`[${LINKEND_ATTRIBUTE}]`);
|
|
3260
|
+
for (const elementWithLinkend of elementsLinkend) {
|
|
3261
|
+
const linkendValue = elementWithLinkend.getAttribute(LINKEND_ATTRIBUTE);
|
|
3262
|
+
if (!linkendValue) continue;
|
|
3263
|
+
linkedElements.push(linkendValue);
|
|
3264
|
+
}
|
|
3265
|
+
}
|
|
3266
|
+
return { elementsToLink, linkedElements };
|
|
3267
|
+
};
|
|
3268
|
+
|
|
3269
|
+
// src/helpers/createElement.ts
|
|
3270
|
+
var createElement = ({
|
|
3271
|
+
schemaCode,
|
|
3272
|
+
attributes
|
|
3273
|
+
}) => {
|
|
3274
|
+
const schema = findSchemaByCode(schemaCode);
|
|
3275
|
+
const element = document.createElement(schema.tag.toLowerCase());
|
|
3276
|
+
for (const [name, value] of Object.entries(attributes)) {
|
|
3277
|
+
if (!value) continue;
|
|
3278
|
+
element.setAttribute(name, String(value));
|
|
3279
|
+
}
|
|
3280
|
+
return element;
|
|
3281
|
+
};
|
|
3282
|
+
|
|
3283
|
+
// src/helpers/queryElementBySchema.ts
|
|
3284
|
+
var queryElementBySchema = (content, schemaCode) => {
|
|
3285
|
+
const schema = findSchemaByCode(schemaCode);
|
|
3286
|
+
const element = content.querySelector(schema.tag.toLowerCase());
|
|
3287
|
+
if (!element) return void 0;
|
|
3288
|
+
if (schema.matchesElement && !schema.matchesElement(element)) {
|
|
3289
|
+
return void 0;
|
|
3290
|
+
}
|
|
3291
|
+
return element;
|
|
3292
|
+
};
|
|
3293
|
+
var queryAllElementsBySchema = (content, schemaCode) => {
|
|
3294
|
+
const schema = findSchemaByCode(schemaCode);
|
|
3295
|
+
const elements = content.querySelectorAll(
|
|
3296
|
+
schema.tag.toLowerCase()
|
|
3297
|
+
);
|
|
3298
|
+
const matchingElements = [];
|
|
3299
|
+
for (const element of elements) {
|
|
3300
|
+
if (schema.matchesElement && !schema.matchesElement(element)) {
|
|
3301
|
+
continue;
|
|
3302
|
+
}
|
|
3303
|
+
matchingElements.push(element);
|
|
3304
|
+
}
|
|
3305
|
+
return matchingElements;
|
|
3306
|
+
};
|
|
3307
|
+
|
|
3308
|
+
// src/helpers/getAdjacentElement.ts
|
|
3309
|
+
var getAdjacentElement = ({
|
|
3310
|
+
element,
|
|
3311
|
+
direction,
|
|
3312
|
+
code
|
|
3313
|
+
}) => {
|
|
3314
|
+
let current = element;
|
|
3315
|
+
while (current) {
|
|
3316
|
+
const sibling = direction === "next" ? current.nextElementSibling : current.previousElementSibling;
|
|
3317
|
+
if (sibling instanceof HTMLElement) {
|
|
3318
|
+
return closestElementBySchema({ element: sibling, code }) || queryElementBySchema(sibling, code);
|
|
3319
|
+
}
|
|
3320
|
+
current = current.parentElement;
|
|
3321
|
+
}
|
|
3322
|
+
};
|
|
3181
3323
|
export {
|
|
3182
3324
|
ALIGNMENT_ATTRIBUTE,
|
|
3183
3325
|
ATOM_SCHEMAS,
|
|
@@ -3190,7 +3332,6 @@ export {
|
|
|
3190
3332
|
IGNORED_ATTRIBUTES,
|
|
3191
3333
|
IGNORED_ATTRIBUTES_STARTS_WITH,
|
|
3192
3334
|
IGNORED_ELEMENT_SELECTORS,
|
|
3193
|
-
IGNORED_VALIDATION_ELEMENT_SELECTORS,
|
|
3194
3335
|
INDENT_TYPE_ATTRIBUTE,
|
|
3195
3336
|
INLINE_ELEMENT_SCHEMAS,
|
|
3196
3337
|
LAYOUT_ATTRIBUTES,
|
|
@@ -3199,6 +3340,7 @@ export {
|
|
|
3199
3340
|
LAYOUT_TABLE_PLACEMENT_ATTRIBUTE,
|
|
3200
3341
|
LAYOUT_USER_ATTRIBUTE,
|
|
3201
3342
|
LEFT_INDENT_ATTRIBUTE,
|
|
3343
|
+
LINKEND_ATTRIBUTE,
|
|
3202
3344
|
RIGHT_INDENT_ATTRIBUTE,
|
|
3203
3345
|
SCHEMAS,
|
|
3204
3346
|
SPACE_ABOVE_ATTRIBUTE,
|
|
@@ -3211,15 +3353,20 @@ export {
|
|
|
3211
3353
|
TRACK_CHANGES_ATTR_DATA_TIME,
|
|
3212
3354
|
TRACK_CHANGES_ATTR_DATA_USERID,
|
|
3213
3355
|
TRACK_CHANGES_ATTR_DATA_USERNAME,
|
|
3356
|
+
XMLID_ATTRIBUTE,
|
|
3357
|
+
closestElementBySchema,
|
|
3214
3358
|
createElement,
|
|
3215
3359
|
findAttributeDefinitionByName,
|
|
3216
3360
|
findSchemaByCode,
|
|
3217
3361
|
findSchemaByElement,
|
|
3362
|
+
getAdjacentElement,
|
|
3218
3363
|
getAttributeName,
|
|
3364
|
+
getElementLinks,
|
|
3365
|
+
getStore,
|
|
3219
3366
|
isAttributeRestricted,
|
|
3367
|
+
isDeletedElement,
|
|
3220
3368
|
isIgnoredAttribute,
|
|
3221
3369
|
isIgnoredElement,
|
|
3222
|
-
isIgnoredValidation,
|
|
3223
3370
|
isTrackChangesSchema,
|
|
3224
3371
|
queryAllElementsBySchema,
|
|
3225
3372
|
queryElementBySchema,
|