@unhead/vue 0.2.0 → 0.2.3
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.cjs +199 -27
- package/dist/index.d.ts +23 -10
- package/dist/index.mjs +181 -21
- package/package.json +4 -4
- package/dist/runtime/server/index.d.ts +0 -2
- package/dist/runtime/server/index.mjs +0 -2
- package/dist/runtime/server/useHead.d.ts +0 -3
- package/dist/runtime/server/useHead.mjs +0 -5
- package/dist/runtime/server/useServerHead.d.ts +0 -3
- package/dist/runtime/server/useServerHead.mjs +0 -4
- package/dist/runtimes/client/index.d.ts +0 -2
- package/dist/runtimes/client/index.mjs +0 -2
- package/dist/runtimes/client/useHead.d.ts +0 -3
- package/dist/runtimes/client/useHead.mjs +0 -24
- package/dist/runtimes/client/useServerHead.d.ts +0 -3
- package/dist/runtimes/client/useServerHead.mjs +0 -2
package/dist/index.cjs
CHANGED
|
@@ -47,20 +47,151 @@ const VueReactiveInputPlugin = () => {
|
|
|
47
47
|
});
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const
|
|
50
|
+
function unpackToArray(input, options) {
|
|
51
|
+
const unpacked = [];
|
|
52
|
+
const kFn = options.resolveKeyData || ((ctx) => ctx.key);
|
|
53
|
+
const vFn = options.resolveValueData || ((ctx) => ctx.value);
|
|
54
|
+
for (const [k, v] of Object.entries(input)) {
|
|
55
|
+
unpacked.push(...(Array.isArray(v) ? v : [v]).map((i) => {
|
|
56
|
+
const ctx = { key: k, value: i };
|
|
57
|
+
const val = vFn(ctx);
|
|
58
|
+
if (typeof val === "object")
|
|
59
|
+
return unpackToArray(val, options);
|
|
60
|
+
if (Array.isArray(val))
|
|
61
|
+
return val;
|
|
62
|
+
return {
|
|
63
|
+
[typeof options.key === "function" ? options.key(ctx) : options.key]: kFn(ctx),
|
|
64
|
+
[typeof options.value === "function" ? options.value(ctx) : options.value]: val
|
|
65
|
+
};
|
|
66
|
+
}).flat());
|
|
67
|
+
}
|
|
68
|
+
return unpacked;
|
|
69
|
+
}
|
|
53
70
|
|
|
54
|
-
function
|
|
55
|
-
|
|
56
|
-
|
|
71
|
+
function unpackToString(value, options) {
|
|
72
|
+
return Object.entries(value).map(([key, value2]) => {
|
|
73
|
+
if (typeof value2 === "object")
|
|
74
|
+
value2 = unpackToString(value2, options);
|
|
75
|
+
if (options.resolve) {
|
|
76
|
+
const resolved = options.resolve({ key, value: value2 });
|
|
77
|
+
if (resolved)
|
|
78
|
+
return resolved;
|
|
79
|
+
}
|
|
80
|
+
if (typeof value2 === "number")
|
|
81
|
+
value2 = value2.toString();
|
|
82
|
+
if (typeof value2 === "string" && options.wrapValue) {
|
|
83
|
+
value2 = value2.replace(new RegExp(options.wrapValue, "g"), `\\${options.wrapValue}`);
|
|
84
|
+
value2 = `${options.wrapValue}${value2}${options.wrapValue}`;
|
|
85
|
+
}
|
|
86
|
+
return `${key}${options.keyValueSeparator || ""}${value2}`;
|
|
87
|
+
}).join(options.entrySeparator || "");
|
|
57
88
|
}
|
|
58
89
|
|
|
59
|
-
|
|
60
|
-
|
|
90
|
+
const MetaPackingSchema = {
|
|
91
|
+
robots: {
|
|
92
|
+
unpack: {
|
|
93
|
+
keyValueSeparator: ":"
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
contentSecurityPolicy: {
|
|
97
|
+
unpack: {
|
|
98
|
+
keyValueSeparator: " ",
|
|
99
|
+
entrySeparator: "; "
|
|
100
|
+
},
|
|
101
|
+
metaKey: "http-equiv"
|
|
102
|
+
},
|
|
103
|
+
fbAppId: {
|
|
104
|
+
keyValue: "fb:app_id",
|
|
105
|
+
metaKey: "property"
|
|
106
|
+
},
|
|
107
|
+
msapplicationTileImage: {
|
|
108
|
+
keyValue: "msapplication-TileImage"
|
|
109
|
+
},
|
|
110
|
+
msapplicationTileColor: {
|
|
111
|
+
keyValue: "msapplication-TileColor"
|
|
112
|
+
},
|
|
113
|
+
msapplicationConfig: {
|
|
114
|
+
keyValue: "msapplication-Config"
|
|
115
|
+
},
|
|
116
|
+
charset: {
|
|
117
|
+
metaKey: "charset"
|
|
118
|
+
},
|
|
119
|
+
contentType: {
|
|
120
|
+
metaKey: "http-equiv"
|
|
121
|
+
},
|
|
122
|
+
defaultStyle: {
|
|
123
|
+
metaKey: "http-equiv"
|
|
124
|
+
},
|
|
125
|
+
xUaCompatible: {
|
|
126
|
+
metaKey: "http-equiv"
|
|
127
|
+
},
|
|
128
|
+
refresh: {
|
|
129
|
+
metaKey: "http-equiv"
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
function resolveMetaKeyType(key) {
|
|
133
|
+
return PropertyPrefixKeys.test(key) ? "property" : MetaPackingSchema[key]?.metaKey || "name";
|
|
61
134
|
}
|
|
62
135
|
|
|
63
|
-
function
|
|
136
|
+
function unpackMeta(input) {
|
|
137
|
+
return unpackToArray(input, {
|
|
138
|
+
key({ key }) {
|
|
139
|
+
return resolveMetaKeyType(key);
|
|
140
|
+
},
|
|
141
|
+
value({ key }) {
|
|
142
|
+
return key === "charset" ? "charset" : "content";
|
|
143
|
+
},
|
|
144
|
+
resolveKeyData({ key }) {
|
|
145
|
+
return MetaPackingSchema[key]?.keyValue || fixKeyCase(key);
|
|
146
|
+
},
|
|
147
|
+
resolveValueData({ value, key }) {
|
|
148
|
+
if (typeof value === "object") {
|
|
149
|
+
const definition = MetaPackingSchema[key];
|
|
150
|
+
if (key === "refresh")
|
|
151
|
+
return `${value.seconds};url=${value.url}`;
|
|
152
|
+
return unpackToString(
|
|
153
|
+
changeKeyCasingDeep(value),
|
|
154
|
+
{
|
|
155
|
+
entrySeparator: ", ",
|
|
156
|
+
keyValueSeparator: "=",
|
|
157
|
+
resolve({ value: value2, key: key2 }) {
|
|
158
|
+
if (typeof value2 === "boolean")
|
|
159
|
+
return `${key2}`;
|
|
160
|
+
},
|
|
161
|
+
...definition?.unpack
|
|
162
|
+
}
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
return typeof value === "number" ? value.toString() : value;
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const PropertyPrefixKeys = /^(og|twitter|fb)/;
|
|
171
|
+
function fixKeyCase(key) {
|
|
172
|
+
key = key.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
173
|
+
if (PropertyPrefixKeys.test(key)) {
|
|
174
|
+
key = key.replace("secure-url", "secure_url").replace(/-/g, ":");
|
|
175
|
+
}
|
|
176
|
+
return key;
|
|
177
|
+
}
|
|
178
|
+
function changeKeyCasingDeep(input) {
|
|
179
|
+
if (Array.isArray(input)) {
|
|
180
|
+
return input.map((entry) => changeKeyCasingDeep(entry));
|
|
181
|
+
}
|
|
182
|
+
if (typeof input !== "object" || Array.isArray(input))
|
|
183
|
+
return input;
|
|
184
|
+
const output = {};
|
|
185
|
+
for (const [key, value] of Object.entries(input))
|
|
186
|
+
output[fixKeyCase(key)] = changeKeyCasingDeep(value);
|
|
187
|
+
return output;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const Vue3 = vue.version.startsWith("3");
|
|
191
|
+
vue.version.startsWith("2.");
|
|
192
|
+
const IsBrowser = typeof window !== "undefined";
|
|
193
|
+
|
|
194
|
+
function clientUseHead(input, options = {}) {
|
|
64
195
|
const head = injectHead();
|
|
65
196
|
const vm = vue.getCurrentInstance();
|
|
66
197
|
if (!vm) {
|
|
@@ -83,27 +214,56 @@ function useHead$1(input, options = {}) {
|
|
|
83
214
|
});
|
|
84
215
|
}
|
|
85
216
|
|
|
217
|
+
function serverUseHead(input, options = {}) {
|
|
218
|
+
const head = injectHead();
|
|
219
|
+
head.push(input, options);
|
|
220
|
+
}
|
|
221
|
+
|
|
86
222
|
function useServerHead(input, options = {}) {
|
|
87
|
-
|
|
88
|
-
useServerHead$1(input, options);
|
|
223
|
+
useHead(input, { ...options, mode: "server" });
|
|
89
224
|
}
|
|
225
|
+
const useServerTagTitle = (title) => useServerHead({ title });
|
|
226
|
+
const useServerTitleTemplate = (titleTemplate) => useServerHead({ titleTemplate });
|
|
227
|
+
const useServerTagMeta = (meta) => useServerHead({ meta: asArray(meta) });
|
|
228
|
+
const useServerTagMetaFlat = (meta) => {
|
|
229
|
+
const input = vue.ref({});
|
|
230
|
+
vue.watchEffect(() => {
|
|
231
|
+
input.value = unpackMeta(resolveUnrefHeadInput(meta));
|
|
232
|
+
});
|
|
233
|
+
return useServerHead({ meta: input });
|
|
234
|
+
};
|
|
235
|
+
const useServerTagLink = (link) => useServerHead({ link: asArray(link) });
|
|
236
|
+
const useServerTagScript = (script) => useServerHead({ script: asArray(script) });
|
|
237
|
+
const useServerTagStyle = (style) => useServerHead({ style: asArray(style) });
|
|
238
|
+
const useServerTagNoscript = (noscript) => useServerHead({ noscript: asArray(noscript) });
|
|
239
|
+
const useServerTagBase = (base) => useServerHead({ base });
|
|
240
|
+
const useServerHtmlAttrs = (attrs) => useServerHead({ htmlAttrs: attrs });
|
|
241
|
+
const useServerBodyAttrs = (attrs) => useHead({ bodyAttrs: attrs });
|
|
242
|
+
|
|
90
243
|
function useHead(input, options = {}) {
|
|
91
244
|
if (options.mode === "server" && IsBrowser || options.mode === "client" && !IsBrowser)
|
|
92
245
|
return;
|
|
93
|
-
IsBrowser ?
|
|
246
|
+
IsBrowser ? clientUseHead(input, options) : serverUseHead(input, options);
|
|
94
247
|
}
|
|
95
|
-
const
|
|
248
|
+
const useTagTitle = (title) => useHead({ title });
|
|
96
249
|
const useTitleTemplate = (titleTemplate) => useHead({ titleTemplate });
|
|
97
|
-
const
|
|
98
|
-
const
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
250
|
+
const useTagMeta = (meta) => useHead({ meta: asArray(meta) });
|
|
251
|
+
const useTagMetaFlat = (meta) => {
|
|
252
|
+
const input = vue.ref({});
|
|
253
|
+
vue.watchEffect(() => {
|
|
254
|
+
input.value = unpackMeta(resolveUnrefHeadInput(meta));
|
|
255
|
+
});
|
|
256
|
+
return useHead({ meta: input });
|
|
257
|
+
};
|
|
258
|
+
const useTagLink = (link) => useHead({ link: asArray(link) });
|
|
259
|
+
const useTagScript = (script) => useHead({ script: asArray(script) });
|
|
260
|
+
const useTagStyle = (style) => useHead({ style: asArray(style) });
|
|
261
|
+
const useTagNoscript = (noscript) => useHead({ noscript: asArray(noscript) });
|
|
262
|
+
const useTagBase = (base) => useHead({ base });
|
|
103
263
|
const useHtmlAttrs = (attrs) => useHead({ htmlAttrs: attrs });
|
|
104
264
|
const useBodyAttrs = (attrs) => useHead({ bodyAttrs: attrs });
|
|
105
265
|
|
|
106
|
-
const headSymbol =
|
|
266
|
+
const headSymbol = "usehead";
|
|
107
267
|
function injectHead() {
|
|
108
268
|
return vue.getCurrentInstance() && vue.inject(headSymbol) || unhead.getActiveHead();
|
|
109
269
|
}
|
|
@@ -184,17 +344,29 @@ exports.createHead = createHead;
|
|
|
184
344
|
exports.headSymbol = headSymbol;
|
|
185
345
|
exports.injectHead = injectHead;
|
|
186
346
|
exports.resolveUnrefHeadInput = resolveUnrefHeadInput;
|
|
187
|
-
exports.useBase = useBase;
|
|
188
347
|
exports.useBodyAttrs = useBodyAttrs;
|
|
189
348
|
exports.useHead = useHead;
|
|
190
349
|
exports.useHtmlAttrs = useHtmlAttrs;
|
|
191
|
-
exports.
|
|
192
|
-
exports.useMeta = useMeta;
|
|
193
|
-
exports.useNoscript = useNoscript;
|
|
194
|
-
exports.useScript = useScript;
|
|
350
|
+
exports.useServerBodyAttrs = useServerBodyAttrs;
|
|
195
351
|
exports.useServerHead = useServerHead;
|
|
196
|
-
exports.
|
|
197
|
-
exports.
|
|
352
|
+
exports.useServerHtmlAttrs = useServerHtmlAttrs;
|
|
353
|
+
exports.useServerTagBase = useServerTagBase;
|
|
354
|
+
exports.useServerTagLink = useServerTagLink;
|
|
355
|
+
exports.useServerTagMeta = useServerTagMeta;
|
|
356
|
+
exports.useServerTagMetaFlat = useServerTagMetaFlat;
|
|
357
|
+
exports.useServerTagNoscript = useServerTagNoscript;
|
|
358
|
+
exports.useServerTagScript = useServerTagScript;
|
|
359
|
+
exports.useServerTagStyle = useServerTagStyle;
|
|
360
|
+
exports.useServerTagTitle = useServerTagTitle;
|
|
361
|
+
exports.useServerTitleTemplate = useServerTitleTemplate;
|
|
362
|
+
exports.useTagBase = useTagBase;
|
|
363
|
+
exports.useTagLink = useTagLink;
|
|
364
|
+
exports.useTagMeta = useTagMeta;
|
|
365
|
+
exports.useTagMetaFlat = useTagMetaFlat;
|
|
366
|
+
exports.useTagNoscript = useTagNoscript;
|
|
367
|
+
exports.useTagScript = useTagScript;
|
|
368
|
+
exports.useTagStyle = useTagStyle;
|
|
369
|
+
exports.useTagTitle = useTagTitle;
|
|
198
370
|
exports.useTitleTemplate = useTitleTemplate;
|
|
199
371
|
for (const k in dom) {
|
|
200
372
|
if (k !== 'default' && !exports.hasOwnProperty(k)) exports[k] = dom[k];
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { MaybeComputedRef, MaybeRef } from '@vueuse/shared';
|
|
2
2
|
export { MaybeComputedRef } from '@vueuse/shared';
|
|
3
3
|
import * as _unhead_schema from '@unhead/schema';
|
|
4
|
-
import { Title as Title$1, TitleTemplate as TitleTemplate$1, EntryAugmentation, Base as Base$1, Link as Link$1, Meta as Meta$1, Style as Style$1, Script as Script$1, Noscript as Noscript$1, DataKeys, SchemaAugmentations, DefinedValueOrEmptyObject, MergeHead, BaseHtmlAttr, MaybeArray, BaseBodyAttr, HeadEntryOptions, HeadClient, CreateHeadOptions } from '@unhead/schema';
|
|
4
|
+
import { Title as Title$1, TitleTemplate as TitleTemplate$1, EntryAugmentation, Base as Base$1, Link as Link$1, Meta as Meta$1, Style as Style$1, Script as Script$1, Noscript as Noscript$1, DataKeys, SchemaAugmentations, DefinedValueOrEmptyObject, MergeHead, BaseHtmlAttr, MaybeArray, BaseBodyAttr, HeadEntryOptions, MetaFlatInput, HeadClient, CreateHeadOptions } from '@unhead/schema';
|
|
5
5
|
export { ActiveHeadEntry, Head, HeadClient, HeadEntryOptions, HeadTag, MergeHead } from '@unhead/schema';
|
|
6
6
|
import { RenderDomHeadOptions } from '@unhead/dom';
|
|
7
7
|
export * from '@unhead/dom';
|
|
@@ -114,20 +114,33 @@ declare const VueTriggerDomPatchingOnUpdatesPlugin: (options?: RenderDomHeadOpti
|
|
|
114
114
|
declare const VueReactiveInputPlugin: () => _unhead_schema.HeadPlugin;
|
|
115
115
|
|
|
116
116
|
declare function useServerHead<T extends MergeHead>(input: UseHeadInput<T>, options?: HeadEntryOptions): void;
|
|
117
|
+
declare const useServerTagTitle: (title: ReactiveHead['title']) => void;
|
|
118
|
+
declare const useServerTitleTemplate: (titleTemplate: ReactiveHead['titleTemplate']) => void;
|
|
119
|
+
declare const useServerTagMeta: (meta: Arrayable<Meta>) => void;
|
|
120
|
+
declare const useServerTagMetaFlat: (meta: MaybeComputedRefEntries<MetaFlatInput>) => void;
|
|
121
|
+
declare const useServerTagLink: (link: Arrayable<Link>) => void;
|
|
122
|
+
declare const useServerTagScript: (script: Arrayable<Script>) => void;
|
|
123
|
+
declare const useServerTagStyle: (style: Arrayable<Style>) => void;
|
|
124
|
+
declare const useServerTagNoscript: (noscript: Arrayable<Noscript>) => void;
|
|
125
|
+
declare const useServerTagBase: (base: ReactiveHead['base']) => void;
|
|
126
|
+
declare const useServerHtmlAttrs: (attrs: ReactiveHead['htmlAttrs']) => void;
|
|
127
|
+
declare const useServerBodyAttrs: (attrs: ReactiveHead['bodyAttrs']) => void;
|
|
128
|
+
|
|
117
129
|
declare function useHead<T extends MergeHead>(input: UseHeadInput<T>, options?: HeadEntryOptions): void;
|
|
118
|
-
declare const
|
|
130
|
+
declare const useTagTitle: (title: ReactiveHead['title']) => void;
|
|
119
131
|
declare const useTitleTemplate: (titleTemplate: ReactiveHead['titleTemplate']) => void;
|
|
120
|
-
declare const
|
|
121
|
-
declare const
|
|
122
|
-
declare const
|
|
123
|
-
declare const
|
|
124
|
-
declare const
|
|
125
|
-
declare const
|
|
132
|
+
declare const useTagMeta: (meta: Arrayable<Meta>) => void;
|
|
133
|
+
declare const useTagMetaFlat: (meta: MaybeComputedRefEntries<MetaFlatInput>) => void;
|
|
134
|
+
declare const useTagLink: (link: Arrayable<Link>) => void;
|
|
135
|
+
declare const useTagScript: (script: Arrayable<Script>) => void;
|
|
136
|
+
declare const useTagStyle: (style: Arrayable<Style>) => void;
|
|
137
|
+
declare const useTagNoscript: (noscript: Arrayable<Noscript>) => void;
|
|
138
|
+
declare const useTagBase: (base: ReactiveHead['base']) => void;
|
|
126
139
|
declare const useHtmlAttrs: (attrs: ReactiveHead['htmlAttrs']) => void;
|
|
127
140
|
declare const useBodyAttrs: (attrs: ReactiveHead['bodyAttrs']) => void;
|
|
128
141
|
|
|
129
142
|
declare type VueHeadClient<T extends MergeHead> = HeadClient<MaybeComputedRef<ReactiveHead<T>>> & Plugin;
|
|
130
|
-
declare const headSymbol
|
|
143
|
+
declare const headSymbol = "usehead";
|
|
131
144
|
declare function injectHead<T extends MergeHead>(): VueHeadClient<T>;
|
|
132
145
|
declare function createHead<T extends MergeHead>(options?: CreateHeadOptions): VueHeadClient<T>;
|
|
133
146
|
|
|
@@ -137,4 +150,4 @@ declare function createDomHead<T extends MergeHead>(options?: CreateHeadOptions
|
|
|
137
150
|
|
|
138
151
|
declare const HeadVuePlugin: Plugin;
|
|
139
152
|
|
|
140
|
-
export { Arrayable, Base, BodyAttributes, HeadVuePlugin, HtmlAttributes, Link, MaybeComputedRefEntries, Meta, Noscript, ReactiveHead, Script, Style, Title, TitleTemplate, UseHeadInput, VueHeadClient, VueReactiveInputPlugin, VueTriggerDomPatchingOnUpdatesPlugin, asArray, createDomHead, createHead, headSymbol, injectHead, resolveUnrefHeadInput,
|
|
153
|
+
export { Arrayable, Base, BodyAttributes, HeadVuePlugin, HtmlAttributes, Link, MaybeComputedRefEntries, Meta, Noscript, ReactiveHead, Script, Style, Title, TitleTemplate, UseHeadInput, VueHeadClient, VueReactiveInputPlugin, VueTriggerDomPatchingOnUpdatesPlugin, asArray, createDomHead, createHead, headSymbol, injectHead, resolveUnrefHeadInput, useBodyAttrs, useHead, useHtmlAttrs, useServerBodyAttrs, useServerHead, useServerHtmlAttrs, useServerTagBase, useServerTagLink, useServerTagMeta, useServerTagMetaFlat, useServerTagNoscript, useServerTagScript, useServerTagStyle, useServerTagTitle, useServerTitleTemplate, useTagBase, useTagLink, useTagMeta, useTagMetaFlat, useTagNoscript, useTagScript, useTagStyle, useTagTitle, useTitleTemplate };
|
package/dist/index.mjs
CHANGED
|
@@ -46,20 +46,151 @@ const VueReactiveInputPlugin = () => {
|
|
|
46
46
|
});
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const
|
|
49
|
+
function unpackToArray(input, options) {
|
|
50
|
+
const unpacked = [];
|
|
51
|
+
const kFn = options.resolveKeyData || ((ctx) => ctx.key);
|
|
52
|
+
const vFn = options.resolveValueData || ((ctx) => ctx.value);
|
|
53
|
+
for (const [k, v] of Object.entries(input)) {
|
|
54
|
+
unpacked.push(...(Array.isArray(v) ? v : [v]).map((i) => {
|
|
55
|
+
const ctx = { key: k, value: i };
|
|
56
|
+
const val = vFn(ctx);
|
|
57
|
+
if (typeof val === "object")
|
|
58
|
+
return unpackToArray(val, options);
|
|
59
|
+
if (Array.isArray(val))
|
|
60
|
+
return val;
|
|
61
|
+
return {
|
|
62
|
+
[typeof options.key === "function" ? options.key(ctx) : options.key]: kFn(ctx),
|
|
63
|
+
[typeof options.value === "function" ? options.value(ctx) : options.value]: val
|
|
64
|
+
};
|
|
65
|
+
}).flat());
|
|
66
|
+
}
|
|
67
|
+
return unpacked;
|
|
68
|
+
}
|
|
52
69
|
|
|
53
|
-
function
|
|
54
|
-
|
|
55
|
-
|
|
70
|
+
function unpackToString(value, options) {
|
|
71
|
+
return Object.entries(value).map(([key, value2]) => {
|
|
72
|
+
if (typeof value2 === "object")
|
|
73
|
+
value2 = unpackToString(value2, options);
|
|
74
|
+
if (options.resolve) {
|
|
75
|
+
const resolved = options.resolve({ key, value: value2 });
|
|
76
|
+
if (resolved)
|
|
77
|
+
return resolved;
|
|
78
|
+
}
|
|
79
|
+
if (typeof value2 === "number")
|
|
80
|
+
value2 = value2.toString();
|
|
81
|
+
if (typeof value2 === "string" && options.wrapValue) {
|
|
82
|
+
value2 = value2.replace(new RegExp(options.wrapValue, "g"), `\\${options.wrapValue}`);
|
|
83
|
+
value2 = `${options.wrapValue}${value2}${options.wrapValue}`;
|
|
84
|
+
}
|
|
85
|
+
return `${key}${options.keyValueSeparator || ""}${value2}`;
|
|
86
|
+
}).join(options.entrySeparator || "");
|
|
56
87
|
}
|
|
57
88
|
|
|
58
|
-
|
|
59
|
-
|
|
89
|
+
const MetaPackingSchema = {
|
|
90
|
+
robots: {
|
|
91
|
+
unpack: {
|
|
92
|
+
keyValueSeparator: ":"
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
contentSecurityPolicy: {
|
|
96
|
+
unpack: {
|
|
97
|
+
keyValueSeparator: " ",
|
|
98
|
+
entrySeparator: "; "
|
|
99
|
+
},
|
|
100
|
+
metaKey: "http-equiv"
|
|
101
|
+
},
|
|
102
|
+
fbAppId: {
|
|
103
|
+
keyValue: "fb:app_id",
|
|
104
|
+
metaKey: "property"
|
|
105
|
+
},
|
|
106
|
+
msapplicationTileImage: {
|
|
107
|
+
keyValue: "msapplication-TileImage"
|
|
108
|
+
},
|
|
109
|
+
msapplicationTileColor: {
|
|
110
|
+
keyValue: "msapplication-TileColor"
|
|
111
|
+
},
|
|
112
|
+
msapplicationConfig: {
|
|
113
|
+
keyValue: "msapplication-Config"
|
|
114
|
+
},
|
|
115
|
+
charset: {
|
|
116
|
+
metaKey: "charset"
|
|
117
|
+
},
|
|
118
|
+
contentType: {
|
|
119
|
+
metaKey: "http-equiv"
|
|
120
|
+
},
|
|
121
|
+
defaultStyle: {
|
|
122
|
+
metaKey: "http-equiv"
|
|
123
|
+
},
|
|
124
|
+
xUaCompatible: {
|
|
125
|
+
metaKey: "http-equiv"
|
|
126
|
+
},
|
|
127
|
+
refresh: {
|
|
128
|
+
metaKey: "http-equiv"
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
function resolveMetaKeyType(key) {
|
|
132
|
+
return PropertyPrefixKeys.test(key) ? "property" : MetaPackingSchema[key]?.metaKey || "name";
|
|
60
133
|
}
|
|
61
134
|
|
|
62
|
-
function
|
|
135
|
+
function unpackMeta(input) {
|
|
136
|
+
return unpackToArray(input, {
|
|
137
|
+
key({ key }) {
|
|
138
|
+
return resolveMetaKeyType(key);
|
|
139
|
+
},
|
|
140
|
+
value({ key }) {
|
|
141
|
+
return key === "charset" ? "charset" : "content";
|
|
142
|
+
},
|
|
143
|
+
resolveKeyData({ key }) {
|
|
144
|
+
return MetaPackingSchema[key]?.keyValue || fixKeyCase(key);
|
|
145
|
+
},
|
|
146
|
+
resolveValueData({ value, key }) {
|
|
147
|
+
if (typeof value === "object") {
|
|
148
|
+
const definition = MetaPackingSchema[key];
|
|
149
|
+
if (key === "refresh")
|
|
150
|
+
return `${value.seconds};url=${value.url}`;
|
|
151
|
+
return unpackToString(
|
|
152
|
+
changeKeyCasingDeep(value),
|
|
153
|
+
{
|
|
154
|
+
entrySeparator: ", ",
|
|
155
|
+
keyValueSeparator: "=",
|
|
156
|
+
resolve({ value: value2, key: key2 }) {
|
|
157
|
+
if (typeof value2 === "boolean")
|
|
158
|
+
return `${key2}`;
|
|
159
|
+
},
|
|
160
|
+
...definition?.unpack
|
|
161
|
+
}
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
return typeof value === "number" ? value.toString() : value;
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const PropertyPrefixKeys = /^(og|twitter|fb)/;
|
|
170
|
+
function fixKeyCase(key) {
|
|
171
|
+
key = key.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
172
|
+
if (PropertyPrefixKeys.test(key)) {
|
|
173
|
+
key = key.replace("secure-url", "secure_url").replace(/-/g, ":");
|
|
174
|
+
}
|
|
175
|
+
return key;
|
|
176
|
+
}
|
|
177
|
+
function changeKeyCasingDeep(input) {
|
|
178
|
+
if (Array.isArray(input)) {
|
|
179
|
+
return input.map((entry) => changeKeyCasingDeep(entry));
|
|
180
|
+
}
|
|
181
|
+
if (typeof input !== "object" || Array.isArray(input))
|
|
182
|
+
return input;
|
|
183
|
+
const output = {};
|
|
184
|
+
for (const [key, value] of Object.entries(input))
|
|
185
|
+
output[fixKeyCase(key)] = changeKeyCasingDeep(value);
|
|
186
|
+
return output;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const Vue3 = version.startsWith("3");
|
|
190
|
+
version.startsWith("2.");
|
|
191
|
+
const IsBrowser = typeof window !== "undefined";
|
|
192
|
+
|
|
193
|
+
function clientUseHead(input, options = {}) {
|
|
63
194
|
const head = injectHead();
|
|
64
195
|
const vm = getCurrentInstance();
|
|
65
196
|
if (!vm) {
|
|
@@ -82,27 +213,56 @@ function useHead$1(input, options = {}) {
|
|
|
82
213
|
});
|
|
83
214
|
}
|
|
84
215
|
|
|
216
|
+
function serverUseHead(input, options = {}) {
|
|
217
|
+
const head = injectHead();
|
|
218
|
+
head.push(input, options);
|
|
219
|
+
}
|
|
220
|
+
|
|
85
221
|
function useServerHead(input, options = {}) {
|
|
86
|
-
|
|
87
|
-
useServerHead$1(input, options);
|
|
222
|
+
useHead(input, { ...options, mode: "server" });
|
|
88
223
|
}
|
|
224
|
+
const useServerTagTitle = (title) => useServerHead({ title });
|
|
225
|
+
const useServerTitleTemplate = (titleTemplate) => useServerHead({ titleTemplate });
|
|
226
|
+
const useServerTagMeta = (meta) => useServerHead({ meta: asArray(meta) });
|
|
227
|
+
const useServerTagMetaFlat = (meta) => {
|
|
228
|
+
const input = ref({});
|
|
229
|
+
watchEffect(() => {
|
|
230
|
+
input.value = unpackMeta(resolveUnrefHeadInput(meta));
|
|
231
|
+
});
|
|
232
|
+
return useServerHead({ meta: input });
|
|
233
|
+
};
|
|
234
|
+
const useServerTagLink = (link) => useServerHead({ link: asArray(link) });
|
|
235
|
+
const useServerTagScript = (script) => useServerHead({ script: asArray(script) });
|
|
236
|
+
const useServerTagStyle = (style) => useServerHead({ style: asArray(style) });
|
|
237
|
+
const useServerTagNoscript = (noscript) => useServerHead({ noscript: asArray(noscript) });
|
|
238
|
+
const useServerTagBase = (base) => useServerHead({ base });
|
|
239
|
+
const useServerHtmlAttrs = (attrs) => useServerHead({ htmlAttrs: attrs });
|
|
240
|
+
const useServerBodyAttrs = (attrs) => useHead({ bodyAttrs: attrs });
|
|
241
|
+
|
|
89
242
|
function useHead(input, options = {}) {
|
|
90
243
|
if (options.mode === "server" && IsBrowser || options.mode === "client" && !IsBrowser)
|
|
91
244
|
return;
|
|
92
|
-
IsBrowser ?
|
|
245
|
+
IsBrowser ? clientUseHead(input, options) : serverUseHead(input, options);
|
|
93
246
|
}
|
|
94
|
-
const
|
|
247
|
+
const useTagTitle = (title) => useHead({ title });
|
|
95
248
|
const useTitleTemplate = (titleTemplate) => useHead({ titleTemplate });
|
|
96
|
-
const
|
|
97
|
-
const
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
249
|
+
const useTagMeta = (meta) => useHead({ meta: asArray(meta) });
|
|
250
|
+
const useTagMetaFlat = (meta) => {
|
|
251
|
+
const input = ref({});
|
|
252
|
+
watchEffect(() => {
|
|
253
|
+
input.value = unpackMeta(resolveUnrefHeadInput(meta));
|
|
254
|
+
});
|
|
255
|
+
return useHead({ meta: input });
|
|
256
|
+
};
|
|
257
|
+
const useTagLink = (link) => useHead({ link: asArray(link) });
|
|
258
|
+
const useTagScript = (script) => useHead({ script: asArray(script) });
|
|
259
|
+
const useTagStyle = (style) => useHead({ style: asArray(style) });
|
|
260
|
+
const useTagNoscript = (noscript) => useHead({ noscript: asArray(noscript) });
|
|
261
|
+
const useTagBase = (base) => useHead({ base });
|
|
102
262
|
const useHtmlAttrs = (attrs) => useHead({ htmlAttrs: attrs });
|
|
103
263
|
const useBodyAttrs = (attrs) => useHead({ bodyAttrs: attrs });
|
|
104
264
|
|
|
105
|
-
const headSymbol =
|
|
265
|
+
const headSymbol = "usehead";
|
|
106
266
|
function injectHead() {
|
|
107
267
|
return getCurrentInstance() && inject(headSymbol) || getActiveHead();
|
|
108
268
|
}
|
|
@@ -174,4 +334,4 @@ const HeadVuePlugin = function(_Vue) {
|
|
|
174
334
|
});
|
|
175
335
|
};
|
|
176
336
|
|
|
177
|
-
export { HeadVuePlugin, VueReactiveInputPlugin, VueTriggerDomPatchingOnUpdatesPlugin, asArray, createDomHead, createHead, headSymbol, injectHead, resolveUnrefHeadInput,
|
|
337
|
+
export { HeadVuePlugin, VueReactiveInputPlugin, VueTriggerDomPatchingOnUpdatesPlugin, asArray, createDomHead, createHead, headSymbol, injectHead, resolveUnrefHeadInput, useBodyAttrs, useHead, useHtmlAttrs, useServerBodyAttrs, useServerHead, useServerHtmlAttrs, useServerTagBase, useServerTagLink, useServerTagMeta, useServerTagMetaFlat, useServerTagNoscript, useServerTagScript, useServerTagStyle, useServerTagTitle, useServerTitleTemplate, useTagBase, useTagLink, useTagMeta, useTagMetaFlat, useTagNoscript, useTagScript, useTagStyle, useTagTitle, useTitleTemplate };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unhead/vue",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.3",
|
|
5
5
|
"packageManager": "pnpm@7.14.0",
|
|
6
6
|
"author": "Harlan Wilton <harlan@harlanzw.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
"vue": ">=2.7 || >=3"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@unhead/dom": "0.2.
|
|
37
|
-
"@unhead/schema": "0.2.
|
|
36
|
+
"@unhead/dom": "0.2.3",
|
|
37
|
+
"@unhead/schema": "0.2.3",
|
|
38
38
|
"@vueuse/shared": "latest",
|
|
39
|
-
"unhead": "0.2.
|
|
39
|
+
"unhead": "0.2.3"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"vue": "latest"
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { getCurrentInstance, onBeforeUnmount, ref, watch, watchEffect } from "vue";
|
|
2
|
-
import { injectHead, resolveUnrefHeadInput } from "../../index";
|
|
3
|
-
export function useHead(input, options = {}) {
|
|
4
|
-
const head = injectHead();
|
|
5
|
-
const vm = getCurrentInstance();
|
|
6
|
-
if (!vm) {
|
|
7
|
-
head.push(input, options);
|
|
8
|
-
return;
|
|
9
|
-
}
|
|
10
|
-
const resolvedInput = ref({});
|
|
11
|
-
watchEffect(() => {
|
|
12
|
-
resolvedInput.value = resolveUnrefHeadInput(input);
|
|
13
|
-
});
|
|
14
|
-
let entry;
|
|
15
|
-
watch(resolvedInput, (e) => {
|
|
16
|
-
if (!entry)
|
|
17
|
-
entry = head.push(e, options);
|
|
18
|
-
else
|
|
19
|
-
entry.patch(e);
|
|
20
|
-
}, { immediate: true });
|
|
21
|
-
onBeforeUnmount(() => {
|
|
22
|
-
entry?.dispose();
|
|
23
|
-
});
|
|
24
|
-
}
|