@lupinum/ginko-content 0.3.4 → 0.3.6
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/cms-contract/render-policy.js +4 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +6 -1
- package/dist/runtime/app/components/ContentRendererInline.vue +3 -1
- package/dist/runtime/app/components/internal/ContentRendererMarkdown.vue +3 -1
- package/dist/runtime/app/components/internal/MarkdownRenderer.d.ts +9 -0
- package/dist/runtime/app/components/internal/MarkdownRenderer.js +15 -4
- package/dist/runtime/markdown/plugins.d.ts +5 -0
- package/dist/runtime/markdown/plugins.js +4 -3
- package/dist/web-types.json +9 -1
- package/package.json +1 -1
|
@@ -158,6 +158,10 @@ const isSafeBindingValue = (value) => {
|
|
|
158
158
|
};
|
|
159
159
|
const SHIKI_COLOR = /^#(?:[0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i;
|
|
160
160
|
const SHIKI_STYLE_VALUES = {
|
|
161
|
+
// Shiki marks inline code with `display: inline`; @shikijs/transformers marks
|
|
162
|
+
// highlighted and diff lines with `display: inline-block`. Nothing else is emitted,
|
|
163
|
+
// so nothing else is accepted.
|
|
164
|
+
display: /^(?:inline|inline-block)$/,
|
|
161
165
|
color: SHIKI_COLOR,
|
|
162
166
|
"--shiki-light": SHIKI_COLOR,
|
|
163
167
|
"--shiki-dark": SHIKI_COLOR,
|
|
@@ -170,7 +174,6 @@ const SHIKI_STYLE_VALUES = {
|
|
|
170
174
|
};
|
|
171
175
|
const isSafeShikiStyle = (value) => {
|
|
172
176
|
if (typeof value !== "string") return false;
|
|
173
|
-
if (value.trim() === "display: inline") return true;
|
|
174
177
|
const declarations = value.split(";");
|
|
175
178
|
if (!declarations.length || declarations.some((declaration) => !declaration)) return false;
|
|
176
179
|
const seen = /* @__PURE__ */ new Set();
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -30,7 +30,7 @@ import { createRouterMatcher } from 'vue-router';
|
|
|
30
30
|
import { globby } from 'globby';
|
|
31
31
|
|
|
32
32
|
const name = "@lupinum/ginko-content";
|
|
33
|
-
const version = "0.3.
|
|
33
|
+
const version = "0.3.6";
|
|
34
34
|
const peerDependencies = {
|
|
35
35
|
nuxt: ">=4.4.7 <5"};
|
|
36
36
|
|
|
@@ -1415,6 +1415,11 @@ const registerContentNitroConfig = ({
|
|
|
1415
1415
|
nitroConfig.externals = defu(typeof nitroConfig.externals === "object" ? nitroConfig.externals : {}, {
|
|
1416
1416
|
inline: [
|
|
1417
1417
|
resolveModuleFile("."),
|
|
1418
|
+
// The generated virtual modules import authored app files (content.config.ts and
|
|
1419
|
+
// transformers). Nitro's dev server externalizes them by default, which hands raw
|
|
1420
|
+
// TypeScript to Node's ESM loader and fails on any import Node cannot resolve on its
|
|
1421
|
+
// own — extensionless relative imports, aliases. They must be bundled instead.
|
|
1422
|
+
withTrailingSlash(resolve$1(nuxt.options.buildDir, "content")),
|
|
1418
1423
|
...runtimeInlineDependencies
|
|
1419
1424
|
]
|
|
1420
1425
|
});
|
|
@@ -4,7 +4,7 @@ import { computed, onServerPrefetch, shallowRef, useAttrs, watch } from "vue";
|
|
|
4
4
|
import { useRuntimeConfig, useState } from "#imports";
|
|
5
5
|
import MarkdownRenderer from "./internal/MarkdownRenderer.js";
|
|
6
6
|
import { useUnwrap } from "../composables/useUnwrap";
|
|
7
|
-
import { resolveMarkdownPlugins, resolveMarkdownRendererComponents } from "../../markdown/plugins";
|
|
7
|
+
import { resolveMarkdownPlugins, resolveMarkdownRendererComponents, resolveMarkdownRendererFallbackComponents } from "../../markdown/plugins";
|
|
8
8
|
import { toMarkdownRoot } from "../../../core/markdown/tree";
|
|
9
9
|
import { parseComark } from "../../../core/markdown/parse-comark";
|
|
10
10
|
import { loadContentComponentEntries } from "../../../integrations/vue/content-components";
|
|
@@ -44,6 +44,7 @@ const initialState = useState(stateKey, () => ({
|
|
|
44
44
|
tree: null
|
|
45
45
|
}));
|
|
46
46
|
const tree = shallowRef(initialState.value.tree);
|
|
47
|
+
const fallbackComponents = resolveMarkdownRendererFallbackComponents();
|
|
47
48
|
const resolvedComponents = computed(() => ({
|
|
48
49
|
...Object.fromEntries(loadContentComponentEntries({
|
|
49
50
|
type: "root",
|
|
@@ -92,6 +93,7 @@ watch(
|
|
|
92
93
|
:tag="tag"
|
|
93
94
|
:prose="prose"
|
|
94
95
|
:components="resolvedComponents"
|
|
96
|
+
:fallback-components="fallbackComponents"
|
|
95
97
|
v-bind="rendererAttrs"
|
|
96
98
|
/>
|
|
97
99
|
</template>
|
|
@@ -7,7 +7,7 @@ import MarkdownRenderer from "./MarkdownRenderer.js";
|
|
|
7
7
|
import { useLocalePath } from "../../composables/content-i18n";
|
|
8
8
|
import { resolveMarkdownRenderRefs, rewriteMarkdownRefLinks } from "../../../../core/references/resolve";
|
|
9
9
|
import { loadContentComponentEntries } from "../../../../integrations/vue/content-components";
|
|
10
|
-
import { resolveMarkdownRendererComponents } from "../../../markdown/plugins";
|
|
10
|
+
import { resolveMarkdownRendererComponents, resolveMarkdownRendererFallbackComponents } from "../../../markdown/plugins";
|
|
11
11
|
import { isMarkdownRoot } from "../../../../core/markdown/tree";
|
|
12
12
|
const props = defineProps({
|
|
13
13
|
value: {
|
|
@@ -79,6 +79,7 @@ const renderedBody = computed(() => {
|
|
|
79
79
|
}
|
|
80
80
|
return props.unwrap ? unwrapRoot(body.value, props.unwrap) : body.value;
|
|
81
81
|
});
|
|
82
|
+
const fallbackComponents = resolveMarkdownRendererFallbackComponents();
|
|
82
83
|
const resolvedComponents = computed(() => {
|
|
83
84
|
if (!renderedBody.value) {
|
|
84
85
|
return props.components;
|
|
@@ -108,6 +109,7 @@ const rendererAttrs = computed(() => {
|
|
|
108
109
|
:default-locale="defaultLocale"
|
|
109
110
|
:locales="locales"
|
|
110
111
|
:components="resolvedComponents"
|
|
112
|
+
:fallback-components="fallbackComponents"
|
|
111
113
|
:render-policy="renderPolicy"
|
|
112
114
|
:data-content-id="debug ? value.id : void 0"
|
|
113
115
|
v-bind="rendererAttrs"
|
|
@@ -11,6 +11,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
11
11
|
type: PropType<Record<string, any>>;
|
|
12
12
|
default: () => {};
|
|
13
13
|
};
|
|
14
|
+
fallbackComponents: {
|
|
15
|
+
type: PropType<Record<string, any>>;
|
|
16
|
+
default: () => {};
|
|
17
|
+
};
|
|
14
18
|
prose: {
|
|
15
19
|
type: PropType<boolean | undefined>;
|
|
16
20
|
default: undefined;
|
|
@@ -56,6 +60,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
56
60
|
type: PropType<Record<string, any>>;
|
|
57
61
|
default: () => {};
|
|
58
62
|
};
|
|
63
|
+
fallbackComponents: {
|
|
64
|
+
type: PropType<Record<string, any>>;
|
|
65
|
+
default: () => {};
|
|
66
|
+
};
|
|
59
67
|
prose: {
|
|
60
68
|
type: PropType<boolean | undefined>;
|
|
61
69
|
default: undefined;
|
|
@@ -97,6 +105,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
97
105
|
components: Record<string, any>;
|
|
98
106
|
tag: string;
|
|
99
107
|
class: string | unknown[] | Record<string, any>;
|
|
108
|
+
fallbackComponents: Record<string, any>;
|
|
100
109
|
prose: boolean | undefined;
|
|
101
110
|
dataContentId: string;
|
|
102
111
|
renderPolicy: PortableComponentPolicyV1;
|
|
@@ -23,7 +23,7 @@ export function localizeMarkdownNodeProps(props, locale, defaultLocale, locales
|
|
|
23
23
|
localizeLinkProps(localizedProps, locale, defaultLocale, locales);
|
|
24
24
|
return localizedProps;
|
|
25
25
|
}
|
|
26
|
-
function resolveVueComponent(name, components, registry, prose, seen = /* @__PURE__ */ new Set()) {
|
|
26
|
+
function resolveVueComponent(name, components, registry, fallbacks, prose, seen = /* @__PURE__ */ new Set()) {
|
|
27
27
|
if (seen.has(name)) {
|
|
28
28
|
return null;
|
|
29
29
|
}
|
|
@@ -40,7 +40,7 @@ function resolveVueComponent(name, components, registry, prose, seen = /* @__PUR
|
|
|
40
40
|
const explicit = components[candidate];
|
|
41
41
|
if (explicit) {
|
|
42
42
|
if (typeof explicit === "string" && explicit !== candidate && !htmlTags.includes(explicit)) {
|
|
43
|
-
return resolveVueComponent(explicit, components, registry, prose, seen) || explicit;
|
|
43
|
+
return resolveVueComponent(explicit, components, registry, fallbacks, prose, seen) || explicit;
|
|
44
44
|
}
|
|
45
45
|
return explicit;
|
|
46
46
|
}
|
|
@@ -51,6 +51,12 @@ function resolveVueComponent(name, components, registry, prose, seen = /* @__PUR
|
|
|
51
51
|
return registered;
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
|
+
for (const candidate of candidates) {
|
|
55
|
+
const fallback = fallbacks[candidate];
|
|
56
|
+
if (fallback) {
|
|
57
|
+
return fallback;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
54
60
|
return null;
|
|
55
61
|
}
|
|
56
62
|
function renderNode(node, options, key, parent) {
|
|
@@ -72,8 +78,8 @@ function renderNode(node, options, key, parent) {
|
|
|
72
78
|
if (parent?.tag === "pre") {
|
|
73
79
|
component = tag;
|
|
74
80
|
} else {
|
|
75
|
-
const resolvedAs = typeof nodeProps.as === "string" ? resolveVueComponent(nodeProps.as, options.components, options.registry, options.prose) : null;
|
|
76
|
-
const resolvedComponent = resolvedAs || resolveVueComponent(tag, options.components, options.registry, options.prose);
|
|
81
|
+
const resolvedAs = typeof nodeProps.as === "string" ? resolveVueComponent(nodeProps.as, options.components, options.registry, options.fallbacks, options.prose) : null;
|
|
82
|
+
const resolvedComponent = resolvedAs || resolveVueComponent(tag, options.components, options.registry, options.fallbacks, options.prose);
|
|
77
83
|
if (resolvedComponent) {
|
|
78
84
|
component = resolvedComponent;
|
|
79
85
|
} else if (htmlTags.includes(tag)) {
|
|
@@ -143,6 +149,10 @@ export default defineComponent({
|
|
|
143
149
|
type: Object,
|
|
144
150
|
default: () => ({})
|
|
145
151
|
},
|
|
152
|
+
fallbackComponents: {
|
|
153
|
+
type: Object,
|
|
154
|
+
default: () => ({})
|
|
155
|
+
},
|
|
146
156
|
prose: {
|
|
147
157
|
type: Boolean,
|
|
148
158
|
default: void 0
|
|
@@ -184,6 +194,7 @@ export default defineComponent({
|
|
|
184
194
|
const children = (props.tree.children || []).map((node, index) => renderNode(node, {
|
|
185
195
|
components: props.components,
|
|
186
196
|
registry,
|
|
197
|
+
fallbacks: props.fallbackComponents,
|
|
187
198
|
prose: props.prose,
|
|
188
199
|
locale: props.locale,
|
|
189
200
|
defaultLocale: props.defaultLocale,
|
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
import type { ResolvedMarkdownPlugin } from '../../types/content';
|
|
2
2
|
export { resolveMarkdownPlugins } from '../../parsers/markdown-plugins';
|
|
3
|
+
/**
|
|
4
|
+
* Builtin prose components resolve after the app's component registry, so an
|
|
5
|
+
* app-registered ProseImg (or a tags remap) wins over the bundled default.
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolveMarkdownRendererFallbackComponents(): Record<string, unknown>;
|
|
3
8
|
export declare function resolveMarkdownRendererComponents(plugins: ResolvedMarkdownPlugin[]): Record<string, unknown>;
|
|
@@ -23,10 +23,11 @@ const builtinMarkdownPlugins = {
|
|
|
23
23
|
const builtinMarkdownComponents = {
|
|
24
24
|
ProseImg: defineAsyncComponent(async () => await import("../app/components/Prose/ProseImg.vue"))
|
|
25
25
|
};
|
|
26
|
+
export function resolveMarkdownRendererFallbackComponents() {
|
|
27
|
+
return { ...builtinMarkdownComponents };
|
|
28
|
+
}
|
|
26
29
|
export function resolveMarkdownRendererComponents(plugins) {
|
|
27
|
-
const components = {
|
|
28
|
-
...builtinMarkdownComponents
|
|
29
|
-
};
|
|
30
|
+
const components = {};
|
|
30
31
|
for (const plugin of plugins) {
|
|
31
32
|
const builtin = builtinMarkdownPlugins[plugin.name];
|
|
32
33
|
if (builtin?.componentName && builtin.component) {
|
package/dist/web-types.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"framework": "vue",
|
|
3
3
|
"name": "@lupinum/ginko-content",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.6",
|
|
5
5
|
"contributions": {
|
|
6
6
|
"html": {
|
|
7
7
|
"description-markup": "markdown",
|
|
@@ -202,6 +202,14 @@
|
|
|
202
202
|
},
|
|
203
203
|
"default": "() => ({})"
|
|
204
204
|
},
|
|
205
|
+
{
|
|
206
|
+
"name": "fallbackComponents",
|
|
207
|
+
"value": {
|
|
208
|
+
"kind": "expression",
|
|
209
|
+
"type": "Record<string, any>"
|
|
210
|
+
},
|
|
211
|
+
"default": "() => ({})"
|
|
212
|
+
},
|
|
205
213
|
{
|
|
206
214
|
"name": "prose",
|
|
207
215
|
"value": {
|