2025-09-05 14:59:21 +08:00

127 lines
3.9 KiB
JavaScript

import { Transition, createStaticVNode, h } from "vue";
import { isString, isPromise, isArray, isObject } from "@vue/shared";
import { START_LOCATION } from "#build/pages";
export const _wrapInTransition = (props, children) => {
return { default: () => import.meta.client && props ? h(Transition, props === true ? {} : props, children) : children.default?.() };
};
const ROUTE_KEY_PARENTHESES_RE = /(:\w+)\([^)]+\)/g;
const ROUTE_KEY_SYMBOLS_RE = /(:\w+)[?+*]/g;
const ROUTE_KEY_NORMAL_RE = /:\w+/g;
function generateRouteKey(route) {
const source = route?.meta.key ?? route.path.replace(ROUTE_KEY_PARENTHESES_RE, "$1").replace(ROUTE_KEY_SYMBOLS_RE, "$1").replace(ROUTE_KEY_NORMAL_RE, (r) => route.params[r.slice(1)]?.toString() || "");
return typeof source === "function" ? source(route) : source;
}
export function isChangingPage(to, from) {
if (to === from || from === START_LOCATION) {
return false;
}
if (generateRouteKey(to) !== generateRouteKey(from)) {
return true;
}
const areComponentsSame = to.matched.every(
(comp, index) => comp.components && comp.components.default === from.matched[index]?.components?.default
);
if (areComponentsSame) {
return false;
}
return true;
}
export function createBuffer() {
let appendable = false;
const buffer = [];
return {
getBuffer() {
return buffer;
},
push(item) {
const isStringItem = isString(item);
if (appendable && isStringItem) {
buffer[buffer.length - 1] += item;
} else {
buffer.push(item);
}
appendable = isStringItem;
if (isPromise(item) || isArray(item) && item.hasAsync) {
buffer.hasAsync = true;
}
}
};
}
export function vforToArray(source) {
if (isArray(source)) {
return source;
} else if (isString(source)) {
return source.split("");
} else if (typeof source === "number") {
if (import.meta.dev && !Number.isInteger(source)) {
console.warn(`The v-for range expect an integer value but got ${source}.`);
}
const array = [];
for (let i = 0; i < source; i++) {
array[i] = i;
}
return array;
} else if (isObject(source)) {
if (source[Symbol.iterator]) {
return Array.from(
source,
(item) => item
);
} else {
const keys = Object.keys(source);
const array = new Array(keys.length);
for (let i = 0, l = keys.length; i < l; i++) {
const key = keys[i];
array[i] = source[key];
}
return array;
}
}
return [];
}
export function getFragmentHTML(element, withoutSlots = false) {
if (element) {
if (element.nodeName === "#comment" && element.nodeValue === "[") {
return getFragmentChildren(element, [], withoutSlots);
}
if (withoutSlots) {
const clone = element.cloneNode(true);
clone.querySelectorAll("[data-island-slot]").forEach((n) => {
n.innerHTML = "";
});
return [clone.outerHTML];
}
return [element.outerHTML];
}
}
function getFragmentChildren(element, blocks = [], withoutSlots = false) {
if (element && element.nodeName) {
if (isEndFragment(element)) {
return blocks;
} else if (!isStartFragment(element)) {
const clone = element.cloneNode(true);
if (withoutSlots) {
clone.querySelectorAll?.("[data-island-slot]").forEach((n) => {
n.innerHTML = "";
});
}
blocks.push(clone.outerHTML);
}
getFragmentChildren(element.nextSibling, blocks, withoutSlots);
}
return blocks;
}
export function elToStaticVNode(el, staticNodeFallback) {
const fragment = el ? getFragmentHTML(el) : staticNodeFallback ? [staticNodeFallback] : void 0;
if (fragment) {
return createStaticVNode(fragment.join(""), fragment.length);
}
return h("div");
}
export function isStartFragment(element) {
return element.nodeName === "#comment" && element.nodeValue === "[";
}
export function isEndFragment(element) {
return element.nodeName === "#comment" && element.nodeValue === "]";
}