@nextcloud/vue
Version:
Nextcloud vue components
141 lines (140 loc) • 5.18 kB
JavaScript
import '../assets/autolink.css';
import { getBaseUrl, getRootUrl } from "@nextcloud/router";
import { u } from "unist-builder";
import { visitParents, SKIP } from "unist-util-visit-parents";
import { defineComponent, openBlock, createElementBlock, normalizeClass, renderSlot, createTextVNode, toDisplayString } from "vue";
import { _ as _export_sfc } from "./_plugin-vue_export-helper.mjs";
import { l as logger } from "./logger.mjs";
const _hoisted_1 = ["href"];
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "NcRichTextExternalLink",
props: {
href: {},
decorateExternal: { type: Boolean, default: false }
},
setup(__props) {
return (_ctx, _cache) => {
return openBlock(), createElementBlock("a", {
href: __props.href,
rel: "noopener noreferrer",
target: "_blank",
class: normalizeClass([_ctx.$style.externalLink, {
[_ctx.$style.externalLink_decorated]: __props.decorateExternal
}])
}, [
renderSlot(_ctx.$slots, "default", {}, () => [
createTextVNode(toDisplayString(__props.href), 1)
])
], 10, _hoisted_1);
};
}
});
const externalLink = "_externalLink_w8FTU";
const externalLink_decorated = "_externalLink_decorated_qC1DY";
const style0 = {
"material-design-icon": "_material-design-icon_F3CKl",
externalLink,
externalLink_decorated
};
const cssModules = {
"$style": style0
};
const NcRichTextExternalLink = /* @__PURE__ */ _export_sfc(_sfc_main, [["__cssModules", cssModules]]);
/*!
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
const URL_PATTERN = /(\s|^)(https?:\/\/)([-A-Z0-9+_.]+(?::[0-9]+)?(?:\/[-A-Z0-9+&@#%?=~_|!:,.;()]*)*)(\s|$)/ig;
const URL_PATTERN_AUTOLINK = /(\s|\(|^)((https?:\/\/)([-A-Z0-9+_.]+[-A-Z0-9]+(?::[0-9]+)?(?:\/[-A-Z0-9+&@#%?=~_|!:,.;()]*)*))(?=\s|\)|$)/ig;
function remarkAutolink({ autolink, useMarkdown, useExtendedMarkdown }) {
return function(tree) {
if (useExtendedMarkdown || !useMarkdown || !autolink) {
return;
}
visitParents(tree, (node) => node.type === "text", (node, ancestors) => {
if (ancestors.some((ancestor) => ancestor.type === "link" || ancestor.type === "linkReference")) {
return;
}
const parent = ancestors.at(-1);
const index = parent.children.indexOf(node) ?? 0;
const parsed = parseUrl(node.value);
const parsedNodes = typeof parsed === "string" ? [u("text", parsed)] : parsed.map((n) => {
if (typeof n === "string") {
return u("text", n);
}
return u("link", {
url: n.props.href
}, [u("text", n.props.href)]);
}).filter((x) => x).flat();
parent.children.splice(index, 1, ...parsedNodes);
return [SKIP, index + parsedNodes.length];
});
};
}
function parseUrl(text) {
let match = URL_PATTERN_AUTOLINK.exec(text);
const list = [];
let start = 0;
while (match !== null) {
let href = match[2];
let textAfter;
let textBefore = text.substring(start, match.index + match[1].length);
if (href[0] === " ") {
textBefore += href[0];
href = href.substring(1).trim();
}
const lastChar = href[href.length - 1];
if (lastChar === "." || lastChar === "," || lastChar === ";" || match[0][0] === "(" && lastChar === ")") {
href = href.substring(0, href.length - 1);
textAfter = lastChar;
}
list.push(textBefore);
list.push({ component: NcRichTextExternalLink, props: { href: href.trim(), decorateExternal: true } });
if (textAfter) {
list.push(textAfter);
}
start = match.index + match[0].length;
match = URL_PATTERN_AUTOLINK.exec(text);
}
list.push(text.substring(start));
const joinedText = list.map((item) => typeof item === "string" ? item : item.props.href).join("");
if (text === joinedText) {
return list;
}
logger.error("[NcRichText] Failed to reassemble the chunked text: " + text);
return text;
}
function getRoute(router, url) {
const removePrefix = (str, prefix) => str.startsWith(prefix) ? str.slice(prefix.length) : str;
const removePrefixes = (str, ...prefixes) => prefixes.reduce((acc, prefix) => removePrefix(acc, prefix), str);
if (!router) {
return null;
}
const isAbsoluteURL = /^https?:\/\//.test(url);
const isNonHttpLink = /^[a-z][a-z0-9+.-]*:.+/.test(url);
if (!isAbsoluteURL && isNonHttpLink) {
return null;
}
if (isAbsoluteURL && !url.startsWith(getBaseUrl())) {
return null;
}
if (!isAbsoluteURL && !url.startsWith("/")) {
return null;
}
const relativeUrl = isAbsoluteURL ? removePrefixes(url, getBaseUrl(), "/index.php") : url;
const relativeRouterBase = removePrefixes(router.options.history.base, getRootUrl(), "/index.php");
const potentialRouterPath = removePrefixes(relativeUrl, relativeRouterBase) || "/";
const route = router.resolve(potentialRouterPath);
if (!route.matched.length) {
return null;
}
return route.fullPath;
}
export {
NcRichTextExternalLink as N,
URL_PATTERN as U,
getRoute as g,
parseUrl as p,
remarkAutolink as r
};
//# sourceMappingURL=autolink.mjs.map