@skhema/embed 0.1.6 → 0.1.9
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/components/SkhemaComponent.d.ts +0 -1
- package/dist/components/SkhemaComponent.d.ts.map +1 -1
- package/dist/components/SkhemaElement.d.ts +0 -1
- package/dist/components/SkhemaElement.d.ts.map +1 -1
- package/dist/components/types.d.ts +6 -0
- package/dist/components/types.d.ts.map +1 -1
- package/dist/embed.min.js +1 -1
- package/dist/embed.min.js.map +1 -1
- package/dist/index.cjs +83 -237
- package/dist/index.cjs.map +1 -1
- package/dist/index.es.js +41 -194
- package/dist/index.es.js.map +1 -1
- package/dist/styles/design-tokens.d.ts +1 -1
- package/dist/styles/design-tokens.d.ts.map +1 -1
- package/dist/tokens.cjs +16 -0
- package/dist/tokens.cjs.map +1 -0
- package/dist/tokens.d.ts +17 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/tokens.es.js +16 -0
- package/dist/tokens.es.js.map +1 -0
- package/dist/utils/author-attribution.d.ts +16 -0
- package/dist/utils/author-attribution.d.ts.map +1 -0
- package/dist/validation-CNWaQfh_.cjs +231 -0
- package/dist/validation-CNWaQfh_.cjs.map +1 -0
- package/dist/validation-MSiRF5Wt.js +232 -0
- package/dist/validation-MSiRF5Wt.js.map +1 -0
- package/package.json +10 -4
package/dist/index.cjs
CHANGED
|
@@ -1,117 +1,40 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
},
|
|
15
|
-
initiatives: {
|
|
16
|
-
bg: "oklch(0.6 0.06 155 / 0.15)",
|
|
17
|
-
text: "oklch(0.6 0.06 155)",
|
|
18
|
-
border: "oklch(0.6 0.06 155 / 0.3)"
|
|
19
|
-
},
|
|
20
|
-
measures: {
|
|
21
|
-
bg: "oklch(0.6 0.06 300 / 0.15)",
|
|
22
|
-
text: "oklch(0.6 0.06 300)",
|
|
23
|
-
border: "oklch(0.6 0.06 300 / 0.3)"
|
|
24
|
-
},
|
|
25
|
-
support: {
|
|
26
|
-
bg: "oklch(0.65 0.06 65 / 0.15)",
|
|
27
|
-
text: "oklch(0.65 0.06 65)",
|
|
28
|
-
border: "oklch(0.65 0.06 65 / 0.3)"
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
const SHARED_CARD_STYLES = `
|
|
32
|
-
/* Monospace acronym badge */
|
|
33
|
-
.skhema-acronym-badge {
|
|
34
|
-
display: inline-flex;
|
|
35
|
-
align-items: center;
|
|
36
|
-
font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
|
|
37
|
-
font-size: 10px;
|
|
38
|
-
font-weight: 600;
|
|
39
|
-
padding: 2px 6px;
|
|
40
|
-
border-radius: 2px;
|
|
41
|
-
letter-spacing: 0.02em;
|
|
42
|
-
flex-shrink: 0;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/* Footer attribution tagline */
|
|
46
|
-
.skhema-footer-attribution {
|
|
47
|
-
font-size: 11px;
|
|
48
|
-
color: var(--skhema-text-muted);
|
|
49
|
-
line-height: 1.4;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
.skhema-footer-attribution a {
|
|
53
|
-
color: var(--skhema-text-muted);
|
|
54
|
-
text-decoration: underline;
|
|
55
|
-
text-decoration-color: var(--skhema-border);
|
|
56
|
-
text-underline-offset: 2px;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
.skhema-footer-attribution a:hover {
|
|
60
|
-
color: var(--skhema-text);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/* Contributor line in footer */
|
|
64
|
-
.skhema-contributor-line {
|
|
65
|
-
display: flex;
|
|
66
|
-
align-items: center;
|
|
67
|
-
gap: 6px;
|
|
68
|
-
font-size: 12px;
|
|
69
|
-
color: var(--skhema-text-muted);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
.skhema-contributor-line svg {
|
|
73
|
-
width: 14px;
|
|
74
|
-
height: 14px;
|
|
75
|
-
flex-shrink: 0;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/* Save button — primary brand color */
|
|
79
|
-
.skhema-save-btn {
|
|
80
|
-
display: inline-flex;
|
|
81
|
-
align-items: center;
|
|
82
|
-
gap: 6px;
|
|
83
|
-
background: var(--skhema-primary);
|
|
84
|
-
color: white;
|
|
85
|
-
border: none;
|
|
86
|
-
padding: 6px 14px;
|
|
87
|
-
border-radius: calc(var(--skhema-radius) + 2px);
|
|
88
|
-
font-size: 12px;
|
|
89
|
-
font-weight: 500;
|
|
90
|
-
text-decoration: none;
|
|
91
|
-
cursor: pointer;
|
|
92
|
-
transition: background 0.15s ease;
|
|
93
|
-
white-space: nowrap;
|
|
3
|
+
const validation = require("./validation-CNWaQfh_.cjs");
|
|
4
|
+
function readAuthorAttribution(element) {
|
|
5
|
+
const authorName = element.getAttribute("author-name") || element.getAttribute("contributor-name");
|
|
6
|
+
if (!authorName?.trim()) {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
const authorSlug = element.getAttribute("author-slug")?.trim();
|
|
10
|
+
return {
|
|
11
|
+
authorName: authorName.trim(),
|
|
12
|
+
authorSlug: authorSlug || void 0
|
|
13
|
+
};
|
|
94
14
|
}
|
|
95
|
-
|
|
96
|
-
.
|
|
97
|
-
background: var(--skhema-primary-hover);
|
|
15
|
+
function escapeHtml(text) {
|
|
16
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
98
17
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
18
|
+
function formatAuthorAttributionHtml(authorName, authorSlug) {
|
|
19
|
+
const label = `By ${escapeHtml(authorName)}`;
|
|
20
|
+
if (authorSlug) {
|
|
21
|
+
return `<a href="https://skhema.com/contributors/${encodeURIComponent(authorSlug)}" class="skhema-author-link" target="_blank" rel="noopener noreferrer">${label}</a>`;
|
|
22
|
+
}
|
|
23
|
+
return `<span class="skhema-author-text">${label}</span>`;
|
|
102
24
|
}
|
|
103
|
-
|
|
104
|
-
.
|
|
105
|
-
outline: 2px solid var(--skhema-primary);
|
|
106
|
-
outline-offset: 2px;
|
|
25
|
+
function formatContributorIdFallback(contributorId) {
|
|
26
|
+
return contributorId.split(/[_-]/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
107
27
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
28
|
+
function resolveAuthorFooterHtml(element, contributorId) {
|
|
29
|
+
const attribution = readAuthorAttribution(element);
|
|
30
|
+
if (attribution) {
|
|
31
|
+
return formatAuthorAttributionHtml(
|
|
32
|
+
attribution.authorName,
|
|
33
|
+
attribution.authorSlug
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
return `<span class="skhema-author-text">By ${escapeHtml(formatContributorIdFallback(contributorId))}</span>`;
|
|
112
37
|
}
|
|
113
|
-
`;
|
|
114
|
-
const USER_ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>`;
|
|
115
38
|
const ANALYTICS_ENDPOINT = "https://analytics.skhema.com/functions/v1/embed-manage";
|
|
116
39
|
const TRACKING_COOKIE_NAME = "_sk";
|
|
117
40
|
const TRACKING_EXPIRY_HOURS = 24;
|
|
@@ -485,43 +408,6 @@ function shouldTrackAnalytics(element) {
|
|
|
485
408
|
const trackAnalytics = element.getAttribute("track-analytics");
|
|
486
409
|
return trackAnalytics !== "false";
|
|
487
410
|
}
|
|
488
|
-
function isValidComponentType(componentType) {
|
|
489
|
-
const validTypes = Object.values(types.COMPONENT_TYPES).map((t) => t.value);
|
|
490
|
-
return validTypes.includes(componentType);
|
|
491
|
-
}
|
|
492
|
-
function validateElementBelongsToComponent(elementType, componentType) {
|
|
493
|
-
if (!isValidComponentType(componentType)) return false;
|
|
494
|
-
const validElements = types.SKHEMA_MAPPING.elementFlow[componentType];
|
|
495
|
-
if (!validElements) return false;
|
|
496
|
-
return validElements.some((e) => e.value === elementType);
|
|
497
|
-
}
|
|
498
|
-
function getComponentTypeLabel(componentType) {
|
|
499
|
-
const type = Object.values(types.COMPONENT_TYPES).find(
|
|
500
|
-
(t) => t.value === componentType
|
|
501
|
-
);
|
|
502
|
-
return type?.label || componentType;
|
|
503
|
-
}
|
|
504
|
-
function getComponentTypeAcronym(componentType) {
|
|
505
|
-
const type = Object.values(types.COMPONENT_TYPES).find(
|
|
506
|
-
(t) => t.value === componentType
|
|
507
|
-
);
|
|
508
|
-
return type?.acronym || componentType.substring(0, 2).toUpperCase();
|
|
509
|
-
}
|
|
510
|
-
function resolveComponentType(elementType) {
|
|
511
|
-
for (const [componentValue, elements] of Object.entries(
|
|
512
|
-
types.SKHEMA_MAPPING.elementFlow
|
|
513
|
-
)) {
|
|
514
|
-
if (elements.some((e) => e.value === elementType)) {
|
|
515
|
-
return componentValue;
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
return "diagnosis";
|
|
519
|
-
}
|
|
520
|
-
function getElementTypesForComponent(componentType) {
|
|
521
|
-
if (!isValidComponentType(componentType)) return [];
|
|
522
|
-
const elements = types.SKHEMA_MAPPING.elementFlow[componentType];
|
|
523
|
-
return elements?.map((e) => e.value) || [];
|
|
524
|
-
}
|
|
525
411
|
function generateContentHash(content) {
|
|
526
412
|
let hash = 0;
|
|
527
413
|
const cleanContent = content.trim().substring(0, 200);
|
|
@@ -610,49 +496,13 @@ function validateContentSecurity(content) {
|
|
|
610
496
|
issues
|
|
611
497
|
};
|
|
612
498
|
}
|
|
613
|
-
function isValidElementType(elementType) {
|
|
614
|
-
const validTypes = Object.values(types.ELEMENT_TYPES).map((type) => type.value);
|
|
615
|
-
return validTypes.includes(elementType);
|
|
616
|
-
}
|
|
617
|
-
function validateAttributes(element) {
|
|
618
|
-
const errors = [];
|
|
619
|
-
const elementType = element.getAttribute("element-type");
|
|
620
|
-
const contributorId = element.getAttribute("contributor-id");
|
|
621
|
-
if (!elementType) {
|
|
622
|
-
errors.push("Missing required attribute: element-type");
|
|
623
|
-
} else if (!isValidElementType(elementType)) {
|
|
624
|
-
const validTypes = Object.values(types.ELEMENT_TYPES).map((t) => t.value).join(", ");
|
|
625
|
-
errors.push(
|
|
626
|
-
`Invalid element-type "${elementType}". Valid types: ${validTypes}`
|
|
627
|
-
);
|
|
628
|
-
}
|
|
629
|
-
if (!contributorId) {
|
|
630
|
-
errors.push("Missing required attribute: contributor-id");
|
|
631
|
-
} else if (contributorId.trim().length === 0) {
|
|
632
|
-
errors.push("contributor-id cannot be empty");
|
|
633
|
-
}
|
|
634
|
-
return {
|
|
635
|
-
isValid: errors.length === 0,
|
|
636
|
-
errors,
|
|
637
|
-
elementType: isValidElementType(elementType || "") ? elementType : void 0,
|
|
638
|
-
contributorId: contributorId || void 0
|
|
639
|
-
};
|
|
640
|
-
}
|
|
641
|
-
function getElementTypeLabel(elementType) {
|
|
642
|
-
const type = Object.values(types.ELEMENT_TYPES).find((t) => t.value === elementType);
|
|
643
|
-
return type?.label || elementType;
|
|
644
|
-
}
|
|
645
|
-
function getElementTypeAcronym(elementType) {
|
|
646
|
-
const type = Object.values(types.ELEMENT_TYPES).find((t) => t.value === elementType);
|
|
647
|
-
return type?.acronym || elementType.substring(0, 2).toUpperCase();
|
|
648
|
-
}
|
|
649
499
|
function generateStructuredData(content, elementType, contributorId, sourceUrl) {
|
|
650
500
|
return {
|
|
651
501
|
"@context": "https://schema.org",
|
|
652
502
|
"@type": "AnalysisContent",
|
|
653
503
|
text: content,
|
|
654
504
|
analysisType: elementType,
|
|
655
|
-
category: getElementTypeLabel(elementType),
|
|
505
|
+
category: validation.getElementTypeLabel(elementType),
|
|
656
506
|
contributor: contributorId,
|
|
657
507
|
url: generateRedirectUrl(content, elementType, contributorId),
|
|
658
508
|
provider: {
|
|
@@ -684,7 +534,7 @@ function generateRedirectUrl(content, elementType, contributorId, options = {})
|
|
|
684
534
|
return `${baseUrl}?type=contributor&contributor_id=${contributorId}&element_type=${elementType}&content_hash=${contentHash}&${params.toString()}`;
|
|
685
535
|
}
|
|
686
536
|
function createMetaTags(content, elementType, contributorId) {
|
|
687
|
-
const label = getElementTypeLabel(elementType);
|
|
537
|
+
const label = validation.getElementTypeLabel(elementType);
|
|
688
538
|
return `
|
|
689
539
|
<div itemscope itemtype="https://schema.org/AnalysisContent" style="display:none;">
|
|
690
540
|
<meta itemprop="analysisType" content="${elementType}">
|
|
@@ -696,7 +546,7 @@ function createMetaTags(content, elementType, contributorId) {
|
|
|
696
546
|
`;
|
|
697
547
|
}
|
|
698
548
|
function generateComponentStructuredData(title, componentType, contributorId, elements, sourceUrl) {
|
|
699
|
-
const componentLabel = getComponentTypeLabel(componentType);
|
|
549
|
+
const componentLabel = validation.getComponentTypeLabel(componentType);
|
|
700
550
|
return {
|
|
701
551
|
"@context": "https://schema.org",
|
|
702
552
|
"@type": "CreativeWork",
|
|
@@ -713,7 +563,7 @@ function generateComponentStructuredData(title, componentType, contributorId, el
|
|
|
713
563
|
"@type": "AnalysisContent",
|
|
714
564
|
text: el.content,
|
|
715
565
|
analysisType: el.elementType,
|
|
716
|
-
category: getElementTypeLabel(el.elementType)
|
|
566
|
+
category: validation.getElementTypeLabel(el.elementType)
|
|
717
567
|
})),
|
|
718
568
|
provider: {
|
|
719
569
|
"@type": "Organization",
|
|
@@ -743,7 +593,7 @@ function generateComponentRedirectUrl(componentHash, componentType, contributorI
|
|
|
743
593
|
return `${baseUrl}?type=component&component_type=${componentType}&component_hash=${componentHash}&contributor_id=${contributorId}&${params.toString()}`;
|
|
744
594
|
}
|
|
745
595
|
function createAriaAttributes(elementType) {
|
|
746
|
-
const label = getElementTypeLabel(elementType);
|
|
596
|
+
const label = validation.getElementTypeLabel(elementType);
|
|
747
597
|
return {
|
|
748
598
|
role: "article",
|
|
749
599
|
"aria-label": `${label} - Strategic element`,
|
|
@@ -887,7 +737,7 @@ const styles$1 = `
|
|
|
887
737
|
gap: 12px;
|
|
888
738
|
}
|
|
889
739
|
|
|
890
|
-
${SHARED_CARD_STYLES}
|
|
740
|
+
${validation.SHARED_CARD_STYLES}
|
|
891
741
|
|
|
892
742
|
/* Error state */
|
|
893
743
|
.skhema-error {
|
|
@@ -1031,6 +881,8 @@ class SkhemaComponent extends HTMLElement {
|
|
|
1031
881
|
return [
|
|
1032
882
|
"component-type",
|
|
1033
883
|
"contributor-id",
|
|
884
|
+
"author-name",
|
|
885
|
+
"author-slug",
|
|
1034
886
|
"contributor-name",
|
|
1035
887
|
"title",
|
|
1036
888
|
"theme",
|
|
@@ -1080,13 +932,13 @@ class SkhemaComponent extends HTMLElement {
|
|
|
1080
932
|
});
|
|
1081
933
|
}
|
|
1082
934
|
render() {
|
|
1083
|
-
const
|
|
1084
|
-
if (!
|
|
1085
|
-
this.renderError("Invalid component attributes",
|
|
935
|
+
const validation2 = this.validateComponentAttributes();
|
|
936
|
+
if (!validation2.isValid) {
|
|
937
|
+
this.renderError("Invalid component attributes", validation2.errors);
|
|
1086
938
|
return;
|
|
1087
939
|
}
|
|
1088
|
-
const componentType =
|
|
1089
|
-
const contributorId =
|
|
940
|
+
const componentType = validation2.componentType;
|
|
941
|
+
const contributorId = validation2.contributorId;
|
|
1090
942
|
const title = this.getAttribute("title") || "";
|
|
1091
943
|
const childElements = this.gatherChildElements(componentType);
|
|
1092
944
|
if (childElements.length === 0) {
|
|
@@ -1125,7 +977,7 @@ class SkhemaComponent extends HTMLElement {
|
|
|
1125
977
|
const contributorId = this.getAttribute("contributor-id");
|
|
1126
978
|
if (!componentType) {
|
|
1127
979
|
errors.push("Missing required attribute: component-type");
|
|
1128
|
-
} else if (!isValidComponentType(componentType)) {
|
|
980
|
+
} else if (!validation.isValidComponentType(componentType)) {
|
|
1129
981
|
errors.push(`Invalid component-type "${componentType}"`);
|
|
1130
982
|
}
|
|
1131
983
|
if (!contributorId) {
|
|
@@ -1136,7 +988,7 @@ class SkhemaComponent extends HTMLElement {
|
|
|
1136
988
|
return {
|
|
1137
989
|
isValid: errors.length === 0,
|
|
1138
990
|
errors,
|
|
1139
|
-
componentType: isValidComponentType(componentType || "") ? componentType : void 0,
|
|
991
|
+
componentType: validation.isValidComponentType(componentType || "") ? componentType : void 0,
|
|
1140
992
|
contributorId: contributorId || void 0
|
|
1141
993
|
};
|
|
1142
994
|
}
|
|
@@ -1148,14 +1000,14 @@ class SkhemaComponent extends HTMLElement {
|
|
|
1148
1000
|
for (const child of children) {
|
|
1149
1001
|
const data = child.getElementData?.();
|
|
1150
1002
|
if (!data) continue;
|
|
1151
|
-
if (!validateElementBelongsToComponent(data.elementType, componentType)) {
|
|
1003
|
+
if (!validation.validateElementBelongsToComponent(data.elementType, componentType)) {
|
|
1152
1004
|
console.warn(
|
|
1153
1005
|
`skhema-component: element type "${data.elementType}" does not belong to component type "${componentType}"`
|
|
1154
1006
|
);
|
|
1155
1007
|
}
|
|
1156
1008
|
elements.push(data);
|
|
1157
1009
|
}
|
|
1158
|
-
const orderedTypes = getElementTypesForComponent(componentType);
|
|
1010
|
+
const orderedTypes = validation.getElementTypesForComponent(componentType);
|
|
1159
1011
|
elements.sort((a, b) => {
|
|
1160
1012
|
const aIdx = orderedTypes.indexOf(a.elementType);
|
|
1161
1013
|
const bIdx = orderedTypes.indexOf(b.elementType);
|
|
@@ -1168,11 +1020,10 @@ class SkhemaComponent extends HTMLElement {
|
|
|
1168
1020
|
renderContent(elements) {
|
|
1169
1021
|
if (!this.contentData) return;
|
|
1170
1022
|
const { component_type, contributor_id, title } = this.contentData;
|
|
1171
|
-
const componentLabel = getComponentTypeLabel(component_type);
|
|
1172
|
-
const acronym = getComponentTypeAcronym(component_type);
|
|
1173
|
-
const colors = COMPONENT_COLORS[component_type];
|
|
1174
|
-
const
|
|
1175
|
-
const displayName = contributorName || this.formatContributorName(contributor_id);
|
|
1023
|
+
const componentLabel = validation.getComponentTypeLabel(component_type);
|
|
1024
|
+
const acronym = validation.getComponentTypeAcronym(component_type);
|
|
1025
|
+
const colors = validation.COMPONENT_COLORS[component_type];
|
|
1026
|
+
const authorFooterHtml = resolveAuthorFooterHtml(this, contributor_id);
|
|
1176
1027
|
const themeAttribute = this.getAttribute("theme") || "auto";
|
|
1177
1028
|
const actualTheme = this.getActualTheme(themeAttribute);
|
|
1178
1029
|
const redirectUrl = generateComponentRedirectUrl(
|
|
@@ -1186,7 +1037,7 @@ class SkhemaComponent extends HTMLElement {
|
|
|
1186
1037
|
const elementSectionsHtml = groupedElements.map(
|
|
1187
1038
|
(group) => `
|
|
1188
1039
|
<div class="skhema-element-group">
|
|
1189
|
-
<div class="skhema-element-label">${getElementTypeLabel(group.elementType)}</div>
|
|
1040
|
+
<div class="skhema-element-label">${validation.getElementTypeLabel(group.elementType)}</div>
|
|
1190
1041
|
${group.items.map(
|
|
1191
1042
|
(item) => `<div class="skhema-element-content">${sanitizeContent(item.content)}</div>`
|
|
1192
1043
|
).join("")}
|
|
@@ -1220,8 +1071,8 @@ class SkhemaComponent extends HTMLElement {
|
|
|
1220
1071
|
<div class="skhema-footer">
|
|
1221
1072
|
<div class="skhema-footer-row">
|
|
1222
1073
|
<span class="skhema-contributor-line">
|
|
1223
|
-
${USER_ICON_SVG}
|
|
1224
|
-
${
|
|
1074
|
+
${validation.USER_ICON_SVG}
|
|
1075
|
+
${authorFooterHtml}
|
|
1225
1076
|
</span>
|
|
1226
1077
|
<a href="${redirectUrl}"
|
|
1227
1078
|
class="skhema-save-btn"
|
|
@@ -1285,9 +1136,6 @@ class SkhemaComponent extends HTMLElement {
|
|
|
1285
1136
|
}
|
|
1286
1137
|
return "light";
|
|
1287
1138
|
}
|
|
1288
|
-
formatContributorName(contributorId) {
|
|
1289
|
-
return contributorId.split(/[_-]/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
1290
|
-
}
|
|
1291
1139
|
addPreconnectHints() {
|
|
1292
1140
|
if (document.querySelector(
|
|
1293
1141
|
'link[rel="preconnect"][href*="analytics.skhema.com"]'
|
|
@@ -1559,7 +1407,7 @@ const styles = `
|
|
|
1559
1407
|
gap: 12px;
|
|
1560
1408
|
}
|
|
1561
1409
|
|
|
1562
|
-
${SHARED_CARD_STYLES}
|
|
1410
|
+
${validation.SHARED_CARD_STYLES}
|
|
1563
1411
|
|
|
1564
1412
|
/* Element type label next to badge */
|
|
1565
1413
|
.skhema-type-label {
|
|
@@ -1730,6 +1578,8 @@ class SkhemaElement extends HTMLElement {
|
|
|
1730
1578
|
return [
|
|
1731
1579
|
"element-type",
|
|
1732
1580
|
"contributor-id",
|
|
1581
|
+
"author-name",
|
|
1582
|
+
"author-slug",
|
|
1733
1583
|
"contributor-name",
|
|
1734
1584
|
"content",
|
|
1735
1585
|
"source-url",
|
|
@@ -1742,11 +1592,11 @@ class SkhemaElement extends HTMLElement {
|
|
|
1742
1592
|
this.componentConnected = true;
|
|
1743
1593
|
if (this.closest("skhema-component")) {
|
|
1744
1594
|
this.nestedMode = true;
|
|
1745
|
-
const validation = validateAttributes(this);
|
|
1746
|
-
if (!validation.isValid) {
|
|
1595
|
+
const validation$1 = validation.validateAttributes(this);
|
|
1596
|
+
if (!validation$1.isValid) {
|
|
1747
1597
|
console.warn(
|
|
1748
1598
|
"skhema-element: invalid attributes in nested mode",
|
|
1749
|
-
validation.errors
|
|
1599
|
+
validation$1.errors
|
|
1750
1600
|
);
|
|
1751
1601
|
return;
|
|
1752
1602
|
}
|
|
@@ -1756,8 +1606,8 @@ class SkhemaElement extends HTMLElement {
|
|
|
1756
1606
|
return;
|
|
1757
1607
|
}
|
|
1758
1608
|
this.contentData = {
|
|
1759
|
-
contributor_id: validation.contributorId,
|
|
1760
|
-
element_type: validation.elementType,
|
|
1609
|
+
contributor_id: validation$1.contributorId,
|
|
1610
|
+
element_type: validation$1.elementType,
|
|
1761
1611
|
content,
|
|
1762
1612
|
content_hash: generateContentHash(content),
|
|
1763
1613
|
source_url: this.getAttribute("source-url") || window.location.href,
|
|
@@ -1805,9 +1655,9 @@ class SkhemaElement extends HTMLElement {
|
|
|
1805
1655
|
};
|
|
1806
1656
|
}
|
|
1807
1657
|
render() {
|
|
1808
|
-
const validation = validateAttributes(this);
|
|
1809
|
-
if (!validation.isValid) {
|
|
1810
|
-
this.renderError("Invalid component attributes", validation.errors);
|
|
1658
|
+
const validation$1 = validation.validateAttributes(this);
|
|
1659
|
+
if (!validation$1.isValid) {
|
|
1660
|
+
this.renderError("Invalid component attributes", validation$1.errors);
|
|
1811
1661
|
return;
|
|
1812
1662
|
}
|
|
1813
1663
|
const content = this.getContent();
|
|
@@ -1826,8 +1676,8 @@ class SkhemaElement extends HTMLElement {
|
|
|
1826
1676
|
return;
|
|
1827
1677
|
}
|
|
1828
1678
|
this.contentData = {
|
|
1829
|
-
contributor_id: validation.contributorId,
|
|
1830
|
-
element_type: validation.elementType,
|
|
1679
|
+
contributor_id: validation$1.contributorId,
|
|
1680
|
+
element_type: validation$1.elementType,
|
|
1831
1681
|
content,
|
|
1832
1682
|
content_hash: generateContentHash(content),
|
|
1833
1683
|
source_url: this.getAttribute("source-url") || window.location.href,
|
|
@@ -1843,7 +1693,7 @@ class SkhemaElement extends HTMLElement {
|
|
|
1843
1693
|
renderContent() {
|
|
1844
1694
|
if (!this.contentData) return;
|
|
1845
1695
|
const { element_type, contributor_id, content } = this.contentData;
|
|
1846
|
-
const label = getElementTypeLabel(element_type);
|
|
1696
|
+
const label = validation.getElementTypeLabel(element_type);
|
|
1847
1697
|
const redirectUrl = generateRedirectUrl(
|
|
1848
1698
|
content,
|
|
1849
1699
|
element_type,
|
|
@@ -1851,11 +1701,10 @@ class SkhemaElement extends HTMLElement {
|
|
|
1851
1701
|
);
|
|
1852
1702
|
const themeAttribute = this.getAttribute("theme") || "auto";
|
|
1853
1703
|
const actualTheme = this.getActualTheme(themeAttribute);
|
|
1854
|
-
const
|
|
1855
|
-
const
|
|
1856
|
-
const
|
|
1857
|
-
const
|
|
1858
|
-
const colors = COMPONENT_COLORS[componentType];
|
|
1704
|
+
const authorFooterHtml = resolveAuthorFooterHtml(this, contributor_id);
|
|
1705
|
+
const componentType = validation.resolveComponentType(element_type);
|
|
1706
|
+
const acronym = validation.getComponentTypeAcronym(componentType);
|
|
1707
|
+
const colors = validation.COMPONENT_COLORS[componentType];
|
|
1859
1708
|
const ariaAttrs = createAriaAttributes(element_type);
|
|
1860
1709
|
Object.entries(ariaAttrs).forEach(([key, value]) => {
|
|
1861
1710
|
this.setAttribute(key, value);
|
|
@@ -1879,8 +1728,8 @@ class SkhemaElement extends HTMLElement {
|
|
|
1879
1728
|
<div class="skhema-footer">
|
|
1880
1729
|
<div class="skhema-footer-row">
|
|
1881
1730
|
<span class="skhema-contributor-line">
|
|
1882
|
-
${USER_ICON_SVG}
|
|
1883
|
-
${
|
|
1731
|
+
${validation.USER_ICON_SVG}
|
|
1732
|
+
${authorFooterHtml}
|
|
1884
1733
|
</span>
|
|
1885
1734
|
<a href="${redirectUrl}"
|
|
1886
1735
|
class="skhema-save-btn"
|
|
@@ -1927,9 +1776,6 @@ class SkhemaElement extends HTMLElement {
|
|
|
1927
1776
|
}
|
|
1928
1777
|
return "light";
|
|
1929
1778
|
}
|
|
1930
|
-
formatContributorName(contributorId) {
|
|
1931
|
-
return contributorId.split(/[_-]/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
1932
|
-
}
|
|
1933
1779
|
addPreconnectHints() {
|
|
1934
1780
|
if (document.querySelector(
|
|
1935
1781
|
'link[rel="preconnect"][href*="analytics.skhema.com"]'
|
|
@@ -2125,6 +1971,15 @@ if (typeof window !== "undefined") {
|
|
|
2125
1971
|
);
|
|
2126
1972
|
}
|
|
2127
1973
|
}
|
|
1974
|
+
exports.getComponentTypeAcronym = validation.getComponentTypeAcronym;
|
|
1975
|
+
exports.getComponentTypeLabel = validation.getComponentTypeLabel;
|
|
1976
|
+
exports.getElementTypeAcronym = validation.getElementTypeAcronym;
|
|
1977
|
+
exports.getElementTypeLabel = validation.getElementTypeLabel;
|
|
1978
|
+
exports.isValidComponentType = validation.isValidComponentType;
|
|
1979
|
+
exports.isValidElementType = validation.isValidElementType;
|
|
1980
|
+
exports.resolveComponentType = validation.resolveComponentType;
|
|
1981
|
+
exports.validateAttributes = validation.validateAttributes;
|
|
1982
|
+
exports.validateElementBelongsToComponent = validation.validateElementBelongsToComponent;
|
|
2128
1983
|
exports.SkhemaComponent = SkhemaComponent;
|
|
2129
1984
|
exports.SkhemaElement = SkhemaElement;
|
|
2130
1985
|
exports.default = SkhemaElement;
|
|
@@ -2133,18 +1988,9 @@ exports.generateComponentRedirectUrl = generateComponentRedirectUrl;
|
|
|
2133
1988
|
exports.generateComponentStructuredData = generateComponentStructuredData;
|
|
2134
1989
|
exports.generateRedirectUrl = generateRedirectUrl;
|
|
2135
1990
|
exports.generateStructuredData = generateStructuredData;
|
|
2136
|
-
exports.getComponentTypeAcronym = getComponentTypeAcronym;
|
|
2137
|
-
exports.getComponentTypeLabel = getComponentTypeLabel;
|
|
2138
|
-
exports.getElementTypeAcronym = getElementTypeAcronym;
|
|
2139
|
-
exports.getElementTypeLabel = getElementTypeLabel;
|
|
2140
|
-
exports.isValidComponentType = isValidComponentType;
|
|
2141
|
-
exports.isValidElementType = isValidElementType;
|
|
2142
1991
|
exports.registerSkhemaComponent = registerSkhemaComponent;
|
|
2143
1992
|
exports.registerSkhemaElement = registerSkhemaElement;
|
|
2144
|
-
exports.resolveComponentType = resolveComponentType;
|
|
2145
1993
|
exports.shouldTrackAnalytics = shouldTrackAnalytics;
|
|
2146
1994
|
exports.trackComponentClick = trackComponentClick;
|
|
2147
1995
|
exports.trackComponentEmbedLoad = trackComponentEmbedLoad;
|
|
2148
|
-
exports.validateAttributes = validateAttributes;
|
|
2149
|
-
exports.validateElementBelongsToComponent = validateElementBelongsToComponent;
|
|
2150
1996
|
//# sourceMappingURL=index.cjs.map
|