pro-editor-schema 0.2.21 → 0.2.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +133 -83
- package/dist/index.mjs +133 -83
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -244,7 +244,13 @@ var INSERTION_SCHEMA = createSchema({
|
|
|
244
244
|
tag: SPAN_TAG,
|
|
245
245
|
matchesElement: (element) => element.classList.contains("ins"),
|
|
246
246
|
requiredAttributes: [...TRACK_CHANGES_ATTRS, ...ID_ATTRS],
|
|
247
|
-
optionalAttributes: [
|
|
247
|
+
optionalAttributes: [
|
|
248
|
+
{
|
|
249
|
+
name: "role",
|
|
250
|
+
values: ["web-link", "figure-note-link", "figsource"],
|
|
251
|
+
defaultValue: ""
|
|
252
|
+
}
|
|
253
|
+
],
|
|
248
254
|
allowedChildrenCodes: [
|
|
249
255
|
...ATOM_CODES_ALLOWED_CHILDREN,
|
|
250
256
|
...INLINE_ELEMENT_CODES_ALLOWED_CHILDREN
|
|
@@ -2334,8 +2340,8 @@ var URI_SCHEMA = createSchema({
|
|
|
2334
2340
|
code: "uri",
|
|
2335
2341
|
kind: "inline",
|
|
2336
2342
|
tag: URI_TAG,
|
|
2337
|
-
requiredAttributes: [
|
|
2338
|
-
optionalAttributes: ["
|
|
2343
|
+
requiredAttributes: [],
|
|
2344
|
+
optionalAttributes: ["xlinkhref"],
|
|
2339
2345
|
allowedChildrenCodes: [...ATOM_CODES_ALLOWED_CHILDREN]
|
|
2340
2346
|
});
|
|
2341
2347
|
|
|
@@ -2601,6 +2607,84 @@ var retrieveTextIgnoringNodesWithSelector = (element, selector = ".del") => {
|
|
|
2601
2607
|
return clonedElement.textContent || "";
|
|
2602
2608
|
};
|
|
2603
2609
|
|
|
2610
|
+
// src/validation/utils/getElementsSelector.ts
|
|
2611
|
+
var getElementsSelector = ({
|
|
2612
|
+
element,
|
|
2613
|
+
selector,
|
|
2614
|
+
filterDeletedNodes
|
|
2615
|
+
}) => {
|
|
2616
|
+
const elements = element.querySelectorAll(selector);
|
|
2617
|
+
if (filterDeletedNodes) {
|
|
2618
|
+
return Array.from(elements).filter((element2) => {
|
|
2619
|
+
const hasDeletedParent = element2.closest(".del") !== null;
|
|
2620
|
+
if (hasDeletedParent) {
|
|
2621
|
+
return false;
|
|
2622
|
+
}
|
|
2623
|
+
return true;
|
|
2624
|
+
});
|
|
2625
|
+
}
|
|
2626
|
+
return Array.from(elements);
|
|
2627
|
+
};
|
|
2628
|
+
|
|
2629
|
+
// src/validation/validateLinkend.ts
|
|
2630
|
+
var findElementLinkedTo = (linkend, elementsToLink) => {
|
|
2631
|
+
return elementsToLink.includes(linkend);
|
|
2632
|
+
};
|
|
2633
|
+
var LINK_TO_CROSS_CHECK = [
|
|
2634
|
+
TABLE_LINK_ROLE,
|
|
2635
|
+
FIGURE_LINK_ROLE,
|
|
2636
|
+
EQUATION_LINK_ROLE,
|
|
2637
|
+
FOOTNOTE_LINK_ROLE,
|
|
2638
|
+
REFERENCE_LINK_ROLE
|
|
2639
|
+
];
|
|
2640
|
+
var LINK_BLOCKER_ROLES = [
|
|
2641
|
+
TABLE_LINK_ROLE,
|
|
2642
|
+
FIGURE_LINK_ROLE,
|
|
2643
|
+
EQUATION_LINK_ROLE,
|
|
2644
|
+
FOOTNOTE_LINK_ROLE
|
|
2645
|
+
];
|
|
2646
|
+
var validateLinkend = (linkElement, elementsToLink) => {
|
|
2647
|
+
const linkend = linkElement.getAttribute("linkend");
|
|
2648
|
+
if (!linkend) {
|
|
2649
|
+
return [];
|
|
2650
|
+
}
|
|
2651
|
+
const isLinkFootnoteCue = linkElement.tagName.toUpperCase() === FOOTNOTE_LINK_SCHEMA.tag;
|
|
2652
|
+
if (isLinkFootnoteCue) {
|
|
2653
|
+
if (findElementLinkedTo(linkend, elementsToLink)) {
|
|
2654
|
+
return [];
|
|
2655
|
+
}
|
|
2656
|
+
return [
|
|
2657
|
+
createValidationIssue({
|
|
2658
|
+
store: getStore(linkElement),
|
|
2659
|
+
title: "Unlinked footnote cue",
|
|
2660
|
+
kind: "unlinked",
|
|
2661
|
+
description: "This footnote cue is not referenced to any footnote in this chapter. Please link it again manually.",
|
|
2662
|
+
level: "blocker"
|
|
2663
|
+
})
|
|
2664
|
+
];
|
|
2665
|
+
}
|
|
2666
|
+
const role = linkElement.getAttribute("role");
|
|
2667
|
+
if (!role) {
|
|
2668
|
+
return [];
|
|
2669
|
+
}
|
|
2670
|
+
if (!LINK_TO_CROSS_CHECK.includes(role)) {
|
|
2671
|
+
return [];
|
|
2672
|
+
}
|
|
2673
|
+
if (findElementLinkedTo(linkend, elementsToLink)) {
|
|
2674
|
+
return [];
|
|
2675
|
+
}
|
|
2676
|
+
const isBlocker = LINK_BLOCKER_ROLES.includes(role.toLowerCase());
|
|
2677
|
+
return [
|
|
2678
|
+
createValidationIssue({
|
|
2679
|
+
store: getStore(linkElement),
|
|
2680
|
+
title: "Unlinked element",
|
|
2681
|
+
kind: "unlinked",
|
|
2682
|
+
description: "This link is not referenced to any element in the current chapter or any other chapter. Please link it again manually.",
|
|
2683
|
+
level: isBlocker ? "blocker" : "warning"
|
|
2684
|
+
})
|
|
2685
|
+
];
|
|
2686
|
+
};
|
|
2687
|
+
|
|
2604
2688
|
// src/validation/validateFootnotes.ts
|
|
2605
2689
|
var extractFootnoteNumber = (footnote) => {
|
|
2606
2690
|
if (!footnote) return "no label";
|
|
@@ -2611,16 +2695,13 @@ var extractFootnoteNumber = (footnote) => {
|
|
|
2611
2695
|
}
|
|
2612
2696
|
return footnoteNumber;
|
|
2613
2697
|
};
|
|
2614
|
-
var validateFootnoteCue = (footnoteElement,
|
|
2698
|
+
var validateFootnoteCue = (footnoteElement, linkElements) => {
|
|
2615
2699
|
const errors = [];
|
|
2616
2700
|
const linkend = footnoteElement.getAttribute("xmlid") || "";
|
|
2617
2701
|
const footnoteNumber = footnoteElement.querySelector(
|
|
2618
2702
|
FOOTNOTE_NUMBER_SCHEMA.tag
|
|
2619
2703
|
);
|
|
2620
|
-
|
|
2621
|
-
`${FOOTNOTE_LINK_SCHEMA.tag}[linkend='${CSS.escape(linkend)}']`
|
|
2622
|
-
);
|
|
2623
|
-
if (footnoteLink) {
|
|
2704
|
+
if (findElementLinkedTo(linkend, linkElements)) {
|
|
2624
2705
|
return errors;
|
|
2625
2706
|
}
|
|
2626
2707
|
if (!footnoteNumber) {
|
|
@@ -2642,8 +2723,12 @@ var validateFootnoteCue = (footnoteElement, root) => {
|
|
|
2642
2723
|
});
|
|
2643
2724
|
return errors;
|
|
2644
2725
|
};
|
|
2645
|
-
var validateConsecutiveFootnotes = (
|
|
2646
|
-
const footnotes =
|
|
2726
|
+
var validateConsecutiveFootnotes = (element) => {
|
|
2727
|
+
const footnotes = getElementsSelector({
|
|
2728
|
+
element,
|
|
2729
|
+
selector: FOOTNOTE_SCHEMA.tag,
|
|
2730
|
+
filterDeletedNodes: true
|
|
2731
|
+
});
|
|
2647
2732
|
if (footnotes.length === 0) {
|
|
2648
2733
|
return [];
|
|
2649
2734
|
}
|
|
@@ -2671,10 +2756,12 @@ var validateConsecutiveFootnotes = (root) => {
|
|
|
2671
2756
|
}
|
|
2672
2757
|
return [];
|
|
2673
2758
|
};
|
|
2674
|
-
var validateConsecutiveFootnoteCues = (
|
|
2675
|
-
const footnoteLinks =
|
|
2676
|
-
|
|
2677
|
-
|
|
2759
|
+
var validateConsecutiveFootnoteCues = (element) => {
|
|
2760
|
+
const footnoteLinks = getElementsSelector({
|
|
2761
|
+
element,
|
|
2762
|
+
selector: FOOTNOTE_LINK_SCHEMA.tag,
|
|
2763
|
+
filterDeletedNodes: true
|
|
2764
|
+
});
|
|
2678
2765
|
if (footnoteLinks.length === 0) {
|
|
2679
2766
|
return [];
|
|
2680
2767
|
}
|
|
@@ -2697,56 +2784,6 @@ var validateConsecutiveFootnoteCues = (root) => {
|
|
|
2697
2784
|
return [];
|
|
2698
2785
|
};
|
|
2699
2786
|
|
|
2700
|
-
// src/validation/validateLinkend.ts
|
|
2701
|
-
var findElementLinkedTo = (linkend, elementsToLink) => {
|
|
2702
|
-
return elementsToLink.includes(linkend);
|
|
2703
|
-
};
|
|
2704
|
-
var LINK_BLOCKER_ROLES = [
|
|
2705
|
-
TABLE_LINK_ROLE,
|
|
2706
|
-
FIGURE_LINK_ROLE,
|
|
2707
|
-
EQUATION_LINK_ROLE,
|
|
2708
|
-
FOOTNOTE_LINK_ROLE,
|
|
2709
|
-
CHAPTER_LINK_ROLE
|
|
2710
|
-
];
|
|
2711
|
-
var validateLinkend = (linkElement, elementsToLink) => {
|
|
2712
|
-
const linkend = linkElement.getAttribute("linkend");
|
|
2713
|
-
if (!linkend) {
|
|
2714
|
-
return [];
|
|
2715
|
-
}
|
|
2716
|
-
const isLinkFootnoteCue = linkElement.tagName.toUpperCase() === FOOTNOTE_LINK_SCHEMA.tag;
|
|
2717
|
-
if (isLinkFootnoteCue) {
|
|
2718
|
-
if (findElementLinkedTo(linkend, elementsToLink)) {
|
|
2719
|
-
return [];
|
|
2720
|
-
}
|
|
2721
|
-
return [
|
|
2722
|
-
createValidationIssue({
|
|
2723
|
-
store: getStore(linkElement),
|
|
2724
|
-
title: "Unlinked footnote cue",
|
|
2725
|
-
kind: "unlinked",
|
|
2726
|
-
description: "This footnote cue is not referenced to any footnote in this chapter. Please link it again manually.",
|
|
2727
|
-
level: "blocker"
|
|
2728
|
-
})
|
|
2729
|
-
];
|
|
2730
|
-
}
|
|
2731
|
-
const role = linkElement.getAttribute("role");
|
|
2732
|
-
if (!role) {
|
|
2733
|
-
return [];
|
|
2734
|
-
}
|
|
2735
|
-
if (findElementLinkedTo(linkend, elementsToLink)) {
|
|
2736
|
-
return [];
|
|
2737
|
-
}
|
|
2738
|
-
const isBlocker = LINK_BLOCKER_ROLES.includes(role.toLowerCase());
|
|
2739
|
-
return [
|
|
2740
|
-
createValidationIssue({
|
|
2741
|
-
store: getStore(linkElement),
|
|
2742
|
-
title: "Unlinked element",
|
|
2743
|
-
kind: "unlinked",
|
|
2744
|
-
description: "This link is not referenced to any element in the current chapter or any other chapter. Please link it again manually.",
|
|
2745
|
-
level: isBlocker ? "blocker" : "warning"
|
|
2746
|
-
})
|
|
2747
|
-
];
|
|
2748
|
-
};
|
|
2749
|
-
|
|
2750
2787
|
// src/validation/validateAttributes.ts
|
|
2751
2788
|
var validateAttributes = (element, schema) => {
|
|
2752
2789
|
const errors = [];
|
|
@@ -2878,21 +2915,6 @@ var validateChildren = (element, schema) => {
|
|
|
2878
2915
|
return errors;
|
|
2879
2916
|
};
|
|
2880
2917
|
|
|
2881
|
-
// src/validation/utils/getLinkableRoles.ts
|
|
2882
|
-
var getLinkableRoles = () => {
|
|
2883
|
-
const linkRoleDefinition = findAttributeDefinitionByName(
|
|
2884
|
-
LINK_SCHEMA.requiredAttributes,
|
|
2885
|
-
"role"
|
|
2886
|
-
);
|
|
2887
|
-
if (!linkRoleDefinition) {
|
|
2888
|
-
return [];
|
|
2889
|
-
}
|
|
2890
|
-
if (isAttributeRestricted(linkRoleDefinition)) {
|
|
2891
|
-
return linkRoleDefinition.values;
|
|
2892
|
-
}
|
|
2893
|
-
return [];
|
|
2894
|
-
};
|
|
2895
|
-
|
|
2896
2918
|
// src/validation/validateReferences.ts
|
|
2897
2919
|
var findElementLinkedTo2 = (xmlid, linkElements) => {
|
|
2898
2920
|
return linkElements.includes(xmlid);
|
|
@@ -2916,6 +2938,33 @@ var validateReferenceCited = (referenceElement, linkElements) => {
|
|
|
2916
2938
|
];
|
|
2917
2939
|
};
|
|
2918
2940
|
|
|
2941
|
+
// src/validation/validateUri.ts
|
|
2942
|
+
var WEB_URI_REGEX = /^(?:(?:https?):\/\/)?(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}(?::\d{1,5})?(?:\/[^\s]*)?$/i;
|
|
2943
|
+
var isValidUri = (uri) => {
|
|
2944
|
+
if (!uri || /\s/.test(uri)) {
|
|
2945
|
+
return false;
|
|
2946
|
+
}
|
|
2947
|
+
if (/^[a-z][a-z0-9+.-]*:/i.test(uri) && !/^https?:\/\//i.test(uri)) {
|
|
2948
|
+
return false;
|
|
2949
|
+
}
|
|
2950
|
+
return WEB_URI_REGEX.test(uri);
|
|
2951
|
+
};
|
|
2952
|
+
var validateUri = (uriElement) => {
|
|
2953
|
+
const url = uriElement.textContent.trim();
|
|
2954
|
+
if (isValidUri(url)) {
|
|
2955
|
+
return [];
|
|
2956
|
+
}
|
|
2957
|
+
return [
|
|
2958
|
+
createValidationIssue({
|
|
2959
|
+
store: getStore(uriElement),
|
|
2960
|
+
title: "URL cannot be reached",
|
|
2961
|
+
kind: "unlinked",
|
|
2962
|
+
description: "URL cannot be reached. Please check and adjust.",
|
|
2963
|
+
level: "warning"
|
|
2964
|
+
})
|
|
2965
|
+
];
|
|
2966
|
+
};
|
|
2967
|
+
|
|
2919
2968
|
// src/validation/validateXml.ts
|
|
2920
2969
|
var validateElement = (element, root, elementsToLink, linkElements, schemasToValidateAgainst) => {
|
|
2921
2970
|
if (isIgnoredElement(element)) {
|
|
@@ -2927,16 +2976,17 @@ var validateElement = (element, root, elementsToLink, linkElements, schemasToVal
|
|
|
2927
2976
|
if (schemasToValidateAgainst.includes(schema.code)) {
|
|
2928
2977
|
errors.push(...validateElementAgainstSchema(element, schema));
|
|
2929
2978
|
}
|
|
2930
|
-
|
|
2931
|
-
const linkableRoles = getLinkableRoles();
|
|
2932
|
-
if (schema.tag === LINK_SCHEMA.tag && role && linkableRoles.includes(role) || schema.tag === FOOTNOTE_LINK_SCHEMA.tag) {
|
|
2979
|
+
if (schema.tag === LINK_SCHEMA.tag || schema.tag === FOOTNOTE_LINK_SCHEMA.tag) {
|
|
2933
2980
|
errors.push(...validateLinkend(element, elementsToLink));
|
|
2934
2981
|
}
|
|
2935
2982
|
if (schema.tag === BIBLIOMIXED_SCHEMA.tag) {
|
|
2936
2983
|
errors.push(...validateReferenceCited(element, linkElements));
|
|
2937
2984
|
}
|
|
2938
2985
|
if (schema.tag === FOOTNOTE_SCHEMA.tag) {
|
|
2939
|
-
errors.push(...validateFootnoteCue(element,
|
|
2986
|
+
errors.push(...validateFootnoteCue(element, linkElements));
|
|
2987
|
+
}
|
|
2988
|
+
if (schema.tag === URI_SCHEMA.tag) {
|
|
2989
|
+
errors.push(...validateUri(element));
|
|
2940
2990
|
}
|
|
2941
2991
|
if (isIgnoredValidation(schema.code)) {
|
|
2942
2992
|
return errors;
|
package/dist/index.mjs
CHANGED
|
@@ -176,7 +176,13 @@ var INSERTION_SCHEMA = createSchema({
|
|
|
176
176
|
tag: SPAN_TAG,
|
|
177
177
|
matchesElement: (element) => element.classList.contains("ins"),
|
|
178
178
|
requiredAttributes: [...TRACK_CHANGES_ATTRS, ...ID_ATTRS],
|
|
179
|
-
optionalAttributes: [
|
|
179
|
+
optionalAttributes: [
|
|
180
|
+
{
|
|
181
|
+
name: "role",
|
|
182
|
+
values: ["web-link", "figure-note-link", "figsource"],
|
|
183
|
+
defaultValue: ""
|
|
184
|
+
}
|
|
185
|
+
],
|
|
180
186
|
allowedChildrenCodes: [
|
|
181
187
|
...ATOM_CODES_ALLOWED_CHILDREN,
|
|
182
188
|
...INLINE_ELEMENT_CODES_ALLOWED_CHILDREN
|
|
@@ -2266,8 +2272,8 @@ var URI_SCHEMA = createSchema({
|
|
|
2266
2272
|
code: "uri",
|
|
2267
2273
|
kind: "inline",
|
|
2268
2274
|
tag: URI_TAG,
|
|
2269
|
-
requiredAttributes: [
|
|
2270
|
-
optionalAttributes: ["
|
|
2275
|
+
requiredAttributes: [],
|
|
2276
|
+
optionalAttributes: ["xlinkhref"],
|
|
2271
2277
|
allowedChildrenCodes: [...ATOM_CODES_ALLOWED_CHILDREN]
|
|
2272
2278
|
});
|
|
2273
2279
|
|
|
@@ -2533,6 +2539,84 @@ var retrieveTextIgnoringNodesWithSelector = (element, selector = ".del") => {
|
|
|
2533
2539
|
return clonedElement.textContent || "";
|
|
2534
2540
|
};
|
|
2535
2541
|
|
|
2542
|
+
// src/validation/utils/getElementsSelector.ts
|
|
2543
|
+
var getElementsSelector = ({
|
|
2544
|
+
element,
|
|
2545
|
+
selector,
|
|
2546
|
+
filterDeletedNodes
|
|
2547
|
+
}) => {
|
|
2548
|
+
const elements = element.querySelectorAll(selector);
|
|
2549
|
+
if (filterDeletedNodes) {
|
|
2550
|
+
return Array.from(elements).filter((element2) => {
|
|
2551
|
+
const hasDeletedParent = element2.closest(".del") !== null;
|
|
2552
|
+
if (hasDeletedParent) {
|
|
2553
|
+
return false;
|
|
2554
|
+
}
|
|
2555
|
+
return true;
|
|
2556
|
+
});
|
|
2557
|
+
}
|
|
2558
|
+
return Array.from(elements);
|
|
2559
|
+
};
|
|
2560
|
+
|
|
2561
|
+
// src/validation/validateLinkend.ts
|
|
2562
|
+
var findElementLinkedTo = (linkend, elementsToLink) => {
|
|
2563
|
+
return elementsToLink.includes(linkend);
|
|
2564
|
+
};
|
|
2565
|
+
var LINK_TO_CROSS_CHECK = [
|
|
2566
|
+
TABLE_LINK_ROLE,
|
|
2567
|
+
FIGURE_LINK_ROLE,
|
|
2568
|
+
EQUATION_LINK_ROLE,
|
|
2569
|
+
FOOTNOTE_LINK_ROLE,
|
|
2570
|
+
REFERENCE_LINK_ROLE
|
|
2571
|
+
];
|
|
2572
|
+
var LINK_BLOCKER_ROLES = [
|
|
2573
|
+
TABLE_LINK_ROLE,
|
|
2574
|
+
FIGURE_LINK_ROLE,
|
|
2575
|
+
EQUATION_LINK_ROLE,
|
|
2576
|
+
FOOTNOTE_LINK_ROLE
|
|
2577
|
+
];
|
|
2578
|
+
var validateLinkend = (linkElement, elementsToLink) => {
|
|
2579
|
+
const linkend = linkElement.getAttribute("linkend");
|
|
2580
|
+
if (!linkend) {
|
|
2581
|
+
return [];
|
|
2582
|
+
}
|
|
2583
|
+
const isLinkFootnoteCue = linkElement.tagName.toUpperCase() === FOOTNOTE_LINK_SCHEMA.tag;
|
|
2584
|
+
if (isLinkFootnoteCue) {
|
|
2585
|
+
if (findElementLinkedTo(linkend, elementsToLink)) {
|
|
2586
|
+
return [];
|
|
2587
|
+
}
|
|
2588
|
+
return [
|
|
2589
|
+
createValidationIssue({
|
|
2590
|
+
store: getStore(linkElement),
|
|
2591
|
+
title: "Unlinked footnote cue",
|
|
2592
|
+
kind: "unlinked",
|
|
2593
|
+
description: "This footnote cue is not referenced to any footnote in this chapter. Please link it again manually.",
|
|
2594
|
+
level: "blocker"
|
|
2595
|
+
})
|
|
2596
|
+
];
|
|
2597
|
+
}
|
|
2598
|
+
const role = linkElement.getAttribute("role");
|
|
2599
|
+
if (!role) {
|
|
2600
|
+
return [];
|
|
2601
|
+
}
|
|
2602
|
+
if (!LINK_TO_CROSS_CHECK.includes(role)) {
|
|
2603
|
+
return [];
|
|
2604
|
+
}
|
|
2605
|
+
if (findElementLinkedTo(linkend, elementsToLink)) {
|
|
2606
|
+
return [];
|
|
2607
|
+
}
|
|
2608
|
+
const isBlocker = LINK_BLOCKER_ROLES.includes(role.toLowerCase());
|
|
2609
|
+
return [
|
|
2610
|
+
createValidationIssue({
|
|
2611
|
+
store: getStore(linkElement),
|
|
2612
|
+
title: "Unlinked element",
|
|
2613
|
+
kind: "unlinked",
|
|
2614
|
+
description: "This link is not referenced to any element in the current chapter or any other chapter. Please link it again manually.",
|
|
2615
|
+
level: isBlocker ? "blocker" : "warning"
|
|
2616
|
+
})
|
|
2617
|
+
];
|
|
2618
|
+
};
|
|
2619
|
+
|
|
2536
2620
|
// src/validation/validateFootnotes.ts
|
|
2537
2621
|
var extractFootnoteNumber = (footnote) => {
|
|
2538
2622
|
if (!footnote) return "no label";
|
|
@@ -2543,16 +2627,13 @@ var extractFootnoteNumber = (footnote) => {
|
|
|
2543
2627
|
}
|
|
2544
2628
|
return footnoteNumber;
|
|
2545
2629
|
};
|
|
2546
|
-
var validateFootnoteCue = (footnoteElement,
|
|
2630
|
+
var validateFootnoteCue = (footnoteElement, linkElements) => {
|
|
2547
2631
|
const errors = [];
|
|
2548
2632
|
const linkend = footnoteElement.getAttribute("xmlid") || "";
|
|
2549
2633
|
const footnoteNumber = footnoteElement.querySelector(
|
|
2550
2634
|
FOOTNOTE_NUMBER_SCHEMA.tag
|
|
2551
2635
|
);
|
|
2552
|
-
|
|
2553
|
-
`${FOOTNOTE_LINK_SCHEMA.tag}[linkend='${CSS.escape(linkend)}']`
|
|
2554
|
-
);
|
|
2555
|
-
if (footnoteLink) {
|
|
2636
|
+
if (findElementLinkedTo(linkend, linkElements)) {
|
|
2556
2637
|
return errors;
|
|
2557
2638
|
}
|
|
2558
2639
|
if (!footnoteNumber) {
|
|
@@ -2574,8 +2655,12 @@ var validateFootnoteCue = (footnoteElement, root) => {
|
|
|
2574
2655
|
});
|
|
2575
2656
|
return errors;
|
|
2576
2657
|
};
|
|
2577
|
-
var validateConsecutiveFootnotes = (
|
|
2578
|
-
const footnotes =
|
|
2658
|
+
var validateConsecutiveFootnotes = (element) => {
|
|
2659
|
+
const footnotes = getElementsSelector({
|
|
2660
|
+
element,
|
|
2661
|
+
selector: FOOTNOTE_SCHEMA.tag,
|
|
2662
|
+
filterDeletedNodes: true
|
|
2663
|
+
});
|
|
2579
2664
|
if (footnotes.length === 0) {
|
|
2580
2665
|
return [];
|
|
2581
2666
|
}
|
|
@@ -2603,10 +2688,12 @@ var validateConsecutiveFootnotes = (root) => {
|
|
|
2603
2688
|
}
|
|
2604
2689
|
return [];
|
|
2605
2690
|
};
|
|
2606
|
-
var validateConsecutiveFootnoteCues = (
|
|
2607
|
-
const footnoteLinks =
|
|
2608
|
-
|
|
2609
|
-
|
|
2691
|
+
var validateConsecutiveFootnoteCues = (element) => {
|
|
2692
|
+
const footnoteLinks = getElementsSelector({
|
|
2693
|
+
element,
|
|
2694
|
+
selector: FOOTNOTE_LINK_SCHEMA.tag,
|
|
2695
|
+
filterDeletedNodes: true
|
|
2696
|
+
});
|
|
2610
2697
|
if (footnoteLinks.length === 0) {
|
|
2611
2698
|
return [];
|
|
2612
2699
|
}
|
|
@@ -2629,56 +2716,6 @@ var validateConsecutiveFootnoteCues = (root) => {
|
|
|
2629
2716
|
return [];
|
|
2630
2717
|
};
|
|
2631
2718
|
|
|
2632
|
-
// src/validation/validateLinkend.ts
|
|
2633
|
-
var findElementLinkedTo = (linkend, elementsToLink) => {
|
|
2634
|
-
return elementsToLink.includes(linkend);
|
|
2635
|
-
};
|
|
2636
|
-
var LINK_BLOCKER_ROLES = [
|
|
2637
|
-
TABLE_LINK_ROLE,
|
|
2638
|
-
FIGURE_LINK_ROLE,
|
|
2639
|
-
EQUATION_LINK_ROLE,
|
|
2640
|
-
FOOTNOTE_LINK_ROLE,
|
|
2641
|
-
CHAPTER_LINK_ROLE
|
|
2642
|
-
];
|
|
2643
|
-
var validateLinkend = (linkElement, elementsToLink) => {
|
|
2644
|
-
const linkend = linkElement.getAttribute("linkend");
|
|
2645
|
-
if (!linkend) {
|
|
2646
|
-
return [];
|
|
2647
|
-
}
|
|
2648
|
-
const isLinkFootnoteCue = linkElement.tagName.toUpperCase() === FOOTNOTE_LINK_SCHEMA.tag;
|
|
2649
|
-
if (isLinkFootnoteCue) {
|
|
2650
|
-
if (findElementLinkedTo(linkend, elementsToLink)) {
|
|
2651
|
-
return [];
|
|
2652
|
-
}
|
|
2653
|
-
return [
|
|
2654
|
-
createValidationIssue({
|
|
2655
|
-
store: getStore(linkElement),
|
|
2656
|
-
title: "Unlinked footnote cue",
|
|
2657
|
-
kind: "unlinked",
|
|
2658
|
-
description: "This footnote cue is not referenced to any footnote in this chapter. Please link it again manually.",
|
|
2659
|
-
level: "blocker"
|
|
2660
|
-
})
|
|
2661
|
-
];
|
|
2662
|
-
}
|
|
2663
|
-
const role = linkElement.getAttribute("role");
|
|
2664
|
-
if (!role) {
|
|
2665
|
-
return [];
|
|
2666
|
-
}
|
|
2667
|
-
if (findElementLinkedTo(linkend, elementsToLink)) {
|
|
2668
|
-
return [];
|
|
2669
|
-
}
|
|
2670
|
-
const isBlocker = LINK_BLOCKER_ROLES.includes(role.toLowerCase());
|
|
2671
|
-
return [
|
|
2672
|
-
createValidationIssue({
|
|
2673
|
-
store: getStore(linkElement),
|
|
2674
|
-
title: "Unlinked element",
|
|
2675
|
-
kind: "unlinked",
|
|
2676
|
-
description: "This link is not referenced to any element in the current chapter or any other chapter. Please link it again manually.",
|
|
2677
|
-
level: isBlocker ? "blocker" : "warning"
|
|
2678
|
-
})
|
|
2679
|
-
];
|
|
2680
|
-
};
|
|
2681
|
-
|
|
2682
2719
|
// src/validation/validateAttributes.ts
|
|
2683
2720
|
var validateAttributes = (element, schema) => {
|
|
2684
2721
|
const errors = [];
|
|
@@ -2810,21 +2847,6 @@ var validateChildren = (element, schema) => {
|
|
|
2810
2847
|
return errors;
|
|
2811
2848
|
};
|
|
2812
2849
|
|
|
2813
|
-
// src/validation/utils/getLinkableRoles.ts
|
|
2814
|
-
var getLinkableRoles = () => {
|
|
2815
|
-
const linkRoleDefinition = findAttributeDefinitionByName(
|
|
2816
|
-
LINK_SCHEMA.requiredAttributes,
|
|
2817
|
-
"role"
|
|
2818
|
-
);
|
|
2819
|
-
if (!linkRoleDefinition) {
|
|
2820
|
-
return [];
|
|
2821
|
-
}
|
|
2822
|
-
if (isAttributeRestricted(linkRoleDefinition)) {
|
|
2823
|
-
return linkRoleDefinition.values;
|
|
2824
|
-
}
|
|
2825
|
-
return [];
|
|
2826
|
-
};
|
|
2827
|
-
|
|
2828
2850
|
// src/validation/validateReferences.ts
|
|
2829
2851
|
var findElementLinkedTo2 = (xmlid, linkElements) => {
|
|
2830
2852
|
return linkElements.includes(xmlid);
|
|
@@ -2848,6 +2870,33 @@ var validateReferenceCited = (referenceElement, linkElements) => {
|
|
|
2848
2870
|
];
|
|
2849
2871
|
};
|
|
2850
2872
|
|
|
2873
|
+
// src/validation/validateUri.ts
|
|
2874
|
+
var WEB_URI_REGEX = /^(?:(?:https?):\/\/)?(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}(?::\d{1,5})?(?:\/[^\s]*)?$/i;
|
|
2875
|
+
var isValidUri = (uri) => {
|
|
2876
|
+
if (!uri || /\s/.test(uri)) {
|
|
2877
|
+
return false;
|
|
2878
|
+
}
|
|
2879
|
+
if (/^[a-z][a-z0-9+.-]*:/i.test(uri) && !/^https?:\/\//i.test(uri)) {
|
|
2880
|
+
return false;
|
|
2881
|
+
}
|
|
2882
|
+
return WEB_URI_REGEX.test(uri);
|
|
2883
|
+
};
|
|
2884
|
+
var validateUri = (uriElement) => {
|
|
2885
|
+
const url = uriElement.textContent.trim();
|
|
2886
|
+
if (isValidUri(url)) {
|
|
2887
|
+
return [];
|
|
2888
|
+
}
|
|
2889
|
+
return [
|
|
2890
|
+
createValidationIssue({
|
|
2891
|
+
store: getStore(uriElement),
|
|
2892
|
+
title: "URL cannot be reached",
|
|
2893
|
+
kind: "unlinked",
|
|
2894
|
+
description: "URL cannot be reached. Please check and adjust.",
|
|
2895
|
+
level: "warning"
|
|
2896
|
+
})
|
|
2897
|
+
];
|
|
2898
|
+
};
|
|
2899
|
+
|
|
2851
2900
|
// src/validation/validateXml.ts
|
|
2852
2901
|
var validateElement = (element, root, elementsToLink, linkElements, schemasToValidateAgainst) => {
|
|
2853
2902
|
if (isIgnoredElement(element)) {
|
|
@@ -2859,16 +2908,17 @@ var validateElement = (element, root, elementsToLink, linkElements, schemasToVal
|
|
|
2859
2908
|
if (schemasToValidateAgainst.includes(schema.code)) {
|
|
2860
2909
|
errors.push(...validateElementAgainstSchema(element, schema));
|
|
2861
2910
|
}
|
|
2862
|
-
|
|
2863
|
-
const linkableRoles = getLinkableRoles();
|
|
2864
|
-
if (schema.tag === LINK_SCHEMA.tag && role && linkableRoles.includes(role) || schema.tag === FOOTNOTE_LINK_SCHEMA.tag) {
|
|
2911
|
+
if (schema.tag === LINK_SCHEMA.tag || schema.tag === FOOTNOTE_LINK_SCHEMA.tag) {
|
|
2865
2912
|
errors.push(...validateLinkend(element, elementsToLink));
|
|
2866
2913
|
}
|
|
2867
2914
|
if (schema.tag === BIBLIOMIXED_SCHEMA.tag) {
|
|
2868
2915
|
errors.push(...validateReferenceCited(element, linkElements));
|
|
2869
2916
|
}
|
|
2870
2917
|
if (schema.tag === FOOTNOTE_SCHEMA.tag) {
|
|
2871
|
-
errors.push(...validateFootnoteCue(element,
|
|
2918
|
+
errors.push(...validateFootnoteCue(element, linkElements));
|
|
2919
|
+
}
|
|
2920
|
+
if (schema.tag === URI_SCHEMA.tag) {
|
|
2921
|
+
errors.push(...validateUri(element));
|
|
2872
2922
|
}
|
|
2873
2923
|
if (isIgnoredValidation(schema.code)) {
|
|
2874
2924
|
return errors;
|