@nextcloud/vue
Version:
Nextcloud vue components
450 lines (449 loc) • 15.2 kB
JavaScript
require('../assets/NcRichText-zt8ALFHi.css');
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
const Vue = require("vue");
const referencePickerModal = require("./referencePickerModal-BkBu4cnq.cjs");
const autolink = require("./autolink-BAgL31EZ.cjs");
const axios = require("@nextcloud/axios");
const _public = require("@nextcloud/sharing/public");
const auth = require("@nextcloud/auth");
const router = require("@nextcloud/router");
const _pluginVue2_normalizer = require("./_plugin-vue2_normalizer-V0q-tHlQ.cjs");
const NcCheckboxRadioSwitch = require("./NcCheckboxRadioSwitch-RjEq0SqY.cjs");
const unistUtilVisit = require("unist-util-visit");
const unistBuilder = require("unist-builder");
const GenRandomId = require("./GenRandomId-BQDud3d4.cjs");
const unified = require("unified");
const remarkParse = require("remark-parse");
const remarkGfm = require("remark-gfm");
const breaks = require("remark-breaks");
const remark2rehype = require("remark-rehype");
const rehype2react = require("rehype-react");
const rehypeExternalLinks = require("rehype-external-links");
const vueRouter = require("vue-router");
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
const axios__default = /* @__PURE__ */ _interopDefault(axios);
const remarkParse__default = /* @__PURE__ */ _interopDefault(remarkParse);
const remarkGfm__default = /* @__PURE__ */ _interopDefault(remarkGfm);
const breaks__default = /* @__PURE__ */ _interopDefault(breaks);
const remark2rehype__default = /* @__PURE__ */ _interopDefault(remark2rehype);
const rehype2react__default = /* @__PURE__ */ _interopDefault(rehype2react);
const rehypeExternalLinks__default = /* @__PURE__ */ _interopDefault(rehypeExternalLinks);
const _sfc_main$1 = {
name: "NcReferenceList",
components: {
NcReferenceWidget: referencePickerModal.NcReferenceWidget
},
props: {
text: {
type: String,
default: ""
},
referenceData: {
type: Object,
default: null
},
limit: {
type: Number,
default: 1
},
displayFallback: {
type: Boolean,
default: false
},
interactive: {
type: Boolean,
default: true
},
interactiveOptIn: {
type: Boolean,
default: false
}
},
data() {
return {
references: null,
loading: true
};
},
computed: {
isVisible() {
return this.loading || this.displayedReferences.length !== 0;
},
values() {
if (this.referenceData) {
return this.referenceData;
}
if (this.displayFallback && !this.loading && !this.references) {
return [this.fallbackReference];
}
return this.references ? Object.values(this.references) : [];
},
firstReference() {
return this.values[0] ?? null;
},
displayedReferences() {
return this.values.slice(0, this.limit);
},
fallbackReference() {
return {
accessible: true,
openGraphObject: {
id: this.text,
link: this.text,
name: this.text
},
richObjectType: "open-graph"
};
}
},
watch: {
text: "fetch"
},
mounted() {
this.fetch();
},
methods: {
fetch() {
this.loading = true;
if (this.referenceData) {
this.references = null;
this.loading = false;
return;
}
if (!new RegExp(autolink.URL_PATTERN).exec(this.text)) {
this.references = null;
this.loading = false;
return;
}
this.resolve().then((response) => {
this.references = response.data.ocs.data.references;
this.loading = false;
this.$emit("loaded");
}).catch((error) => {
console.error("Failed to extract references", error);
this.loading = false;
this.$emit("loaded");
});
},
resolve() {
const match = new RegExp(autolink.URL_PATTERN).exec(this.text.trim());
const isPublic = auth.getCurrentUser() === null;
if (this.limit === 1 && match) {
return isPublic ? axios__default.default.get(router.generateOcsUrl("references/resolvePublic") + `?reference=${encodeURIComponent(match[0])}&sharingToken=${_public.getSharingToken()}`) : axios__default.default.get(router.generateOcsUrl("references/resolve") + `?reference=${encodeURIComponent(match[0])}`);
}
return isPublic ? axios__default.default.post(router.generateOcsUrl("references/extractPublic"), {
text: this.text,
resolve: true,
limit: this.limit,
sharingToken: _public.getSharingToken()
}) : axios__default.default.post(router.generateOcsUrl("references/extract"), {
text: this.text,
resolve: true,
limit: this.limit
});
}
}
};
var _sfc_render$1 = function render() {
var _vm = this, _c = _vm._self._c;
return _vm.isVisible ? _c("div", { staticClass: "widgets--list", class: { "icon-loading": _vm.loading } }, _vm._l(_vm.displayedReferences, function(reference) {
return _c("NcReferenceWidget", { key: reference?.openGraphObject?.id, attrs: { "reference": reference, "interactive": _vm.interactive, "interactive-opt-in": _vm.interactiveOptIn } });
}), 1) : _vm._e();
};
var _sfc_staticRenderFns$1 = [];
var __component__$1 = /* @__PURE__ */ _pluginVue2_normalizer.normalizeComponent(
_sfc_main$1,
_sfc_render$1,
_sfc_staticRenderFns$1,
false,
null,
"2677cf0e"
);
const NcReferenceList = __component__$1.exports;
const remarkPlaceholder = function() {
return function(ast) {
unistUtilVisit.visit(ast, (node) => node.type === "text", visitor);
function visitor(node, index, parent) {
const placeholders = node.value.split(/(\{[a-z\-_.0-9]+\})/ig).map((entry, index2, list) => {
const matches = entry.match(/^\{([a-z\-_.0-9]+)\}$/i);
if (!matches) {
return unistBuilder.u("text", entry);
}
const [, component] = matches;
return unistBuilder.u("element", {
tagName: `#${component}`
});
});
parent.children.splice(index, 1, ...placeholders);
}
};
};
const prepareTextNode = ({ h, context }, text) => {
if (context.autolink) {
text = autolink.parseUrl(text);
}
if (Array.isArray(text)) {
return text.map((entry) => {
if (typeof entry === "string") {
return entry;
}
const { component, props } = entry;
const componentClass = component.name === "NcLink" ? void 0 : "rich-text--component";
return h(component, {
props,
class: componentClass
});
});
}
return text;
};
const remarkUnescape = function() {
return function(tree) {
unistUtilVisit.visit(
tree,
(node) => ["text", "code", "inlineCode"].includes(node.type),
(node, index, parent) => {
parent.children.splice(index, 1, {
...node,
value: node.value.replace(/</gmi, "<").replace(/>/gmi, ">")
});
return [unistUtilVisit.SKIP, index + 1];
}
);
};
};
const rehypeHighlight = Vue.ref(null);
async function importRehypeHighlightLibrary() {
const module2 = await import("rehype-highlight");
rehypeHighlight.value = module2.default;
}
const _sfc_main = {
name: "NcRichText",
components: {
NcReferenceList
},
props: {
text: {
type: String,
default: ""
},
arguments: {
type: Object,
default: () => {
return {};
}
},
referenceLimit: {
type: Number,
default: 0
},
referenceInteractive: {
type: Boolean,
default: true
},
referenceInteractiveOptIn: {
type: Boolean,
default: false
},
/** Provide data upfront to avoid extra http request */
references: {
type: Object,
default: null
},
/** Provide basic Markdown syntax */
useMarkdown: {
type: Boolean,
default: false
},
/** Provide GitHub Flavored Markdown syntax */
useExtendedMarkdown: {
type: Boolean,
default: false
},
/** Provide event from rendered markdown inputs */
interactive: {
type: Boolean,
default: false
},
autolink: {
type: Boolean,
default: true
}
},
emits: ["interact:todo"],
data() {
return {
parentId: GenRandomId.GenRandomId(5)
};
},
methods: {
renderPlaintext(h) {
const context = this;
const placeholders = this.text.split(/(\{[a-z\-_.0-9]+\})/ig).map(function(entry, index, list) {
const matches = entry.match(/^\{([a-z\-_.0-9]+)\}$/i);
if (!matches) {
return prepareTextNode({ h, context }, entry);
}
const argumentId = matches[1];
const argument = context.arguments[argumentId];
if (typeof argument === "object") {
const { component, props } = argument;
return h(component, {
props,
class: "rich-text--component"
});
}
if (argument) {
return h("span", { class: "rich-text--fallback" }, argument);
}
return entry;
});
return h("div", { class: "rich-text--wrapper" }, [
h("div", {}, placeholders.flat()),
this.referenceLimit > 0 ? h("div", { class: "rich-text--reference-widget" }, [
h(NcReferenceList, {
props: {
text: this.text,
referenceData: this.references,
interactive: this.referenceInteractive,
interactiveOptIn: this.referenceInteractiveOptIn
}
})
]) : null
]);
},
renderMarkdown(h) {
const renderedMarkdown = unified.unified().use(remarkParse__default.default).use(autolink.remarkAutolink, {
autolink: this.autolink,
useMarkdown: this.useMarkdown,
useExtendedMarkdown: this.useExtendedMarkdown
}).use(remarkUnescape).use(this.useExtendedMarkdown ? remarkGfm__default.default : void 0).use(breaks__default.default).use(remark2rehype__default.default, {
handlers: {
component(toHast, node) {
return toHast(node, node.component, { value: node.value });
}
}
}).use(this.useExtendedMarkdown ? rehypeHighlight.value : void 0).use(remarkPlaceholder).use(rehypeExternalLinks__default.default, {
target: "_blank",
rel: ["noopener noreferrer"]
}).use(rehype2react__default.default, {
createElement: (tag, attrs, children) => {
if (!tag.startsWith("#")) {
if (this.useExtendedMarkdown) {
if (tag === "code" && !rehypeHighlight.value && attrs?.attrs?.class?.includes("language")) {
importRehypeHighlightLibrary();
}
let nestedNode = null;
if (tag === "li" && Array.isArray(children) && children[0].tag === "input" && children[0].data.attrs.type === "checkbox") {
const [inputNode, ...labelParts] = children;
const nestedNodeIndex = labelParts.findIndex((child) => ["ul", "ol", "li", "blockquote", "pre"].includes(child.tag));
if (nestedNodeIndex !== -1) {
nestedNode = labelParts[nestedNodeIndex];
labelParts.splice(nestedNodeIndex);
}
const id = this.parentId + "-markdown-input-" + GenRandomId.GenRandomId(5);
const inputComponent = h(NcCheckboxRadioSwitch.NcCheckboxRadioSwitch, {
attrs: {
...inputNode.data.attrs,
id,
disabled: !this.interactive
},
on: {
"update:checked": () => {
this.$emit("interact:todo", id);
}
}
}, labelParts);
return h(tag, attrs, [inputComponent, nestedNode]);
}
}
if (tag === "a") {
const route = autolink.getRoute(this.$router, attrs.attrs.href);
if (route) {
delete attrs.attrs.href;
delete attrs.attrs.target;
return h(vueRouter.RouterLink, {
...attrs,
props: {
to: route
}
}, children);
}
}
return h(tag, attrs, children);
}
const placeholder = this.arguments[tag.slice(1)];
if (!placeholder) {
return h("span", { ...{ attrs }, ...{ class: "rich-text--fallback" } }, [`{${tag.slice(1)}}`]);
}
if (!placeholder.component) {
return h("span", attrs, [placeholder]);
}
return h(
placeholder.component,
{
attrs,
props: placeholder.props,
class: "rich-text--component"
},
children
);
},
prefix: false
}).processSync(
this.text.replace(/<[^>]+>/g, (match) => match.replace(/</g, "<")).replace(/>/gmi, ">")
).result;
return h("div", { class: "rich-text--wrapper rich-text--wrapper-markdown" }, [
renderedMarkdown,
this.referenceLimit > 0 ? h("div", { class: "rich-text--reference-widget" }, [
h(NcReferenceList, {
props: {
text: this.text,
referenceData: this.references,
interactive: this.referenceInteractive,
interactiveOptIn: this.referenceInteractiveOptIn
}
})
]) : null
]);
}
},
render(h) {
return this.useMarkdown || this.useExtendedMarkdown ? this.renderMarkdown(h) : this.renderPlaintext(h);
}
};
const _sfc_render = null;
const _sfc_staticRenderFns = null;
var __component__ = /* @__PURE__ */ _pluginVue2_normalizer.normalizeComponent(
_sfc_main,
_sfc_render,
_sfc_staticRenderFns,
false,
null,
"1de82f09"
);
const NcRichText = __component__.exports;
exports.NcReferenceList = NcReferenceList;
exports.NcRichText = NcRichText;