UNPKG

@staszek998/v-html

Version:

Simple Vue component capable of rendering the passed-in HTML string without wrapping it within a redundant HTML tag.

88 lines 3 kB
"use strict"; /******************************************************************************* * @copyright 2021 IDEALIGN Stanisław Gregor ******************************************************************************/ Object.defineProperty(exports, "__esModule", { value: true }); exports.VHTML = void 0; const tslib_1 = require("tslib"); const vue_1 = tslib_1.__importDefault(require("vue")); /** * Extracts the contents from the passed-in `<slot>`. * * @param slot - The `<slot>` which contents we wont to resolve. * * @author Stanisław Gregor, Vitim.us * * @see https://stackoverflow.com/a/52749314/11869579 */ const getSlotContents = (slot) => { if (typeof slot === 'undefined' || !Array.isArray(slot) || slot.length === 0) { return ''; } /** * The contents from all the VNodes in the `<slot>`. */ const textContents = slot.map(vnode => { if (typeof vnode.text === 'string') { return vnode.text; } if (typeof vnode.elm !== 'undefined' && typeof vnode.elm.textContent === 'string') { return vnode.elm.textContent; } return ''; }); return textContents.join(''); }; /** * Simple functional component that accepts HTML string and renders it as-is. * Why? Because `v-html` directive is not always an option 😉 * * @author Stanisław Gregor, Thorsten Lünborg * * @see https://forum.vuejs.org/t/raw-html-without-a-parent-element-via-v-html/87160 * @see https://jsfiddle.net/Linusborg/mfqjk5hm/ */ exports.VHTML = vue_1.default.extend({ functional: true, name: 'VHTML', props: { /** * The HTML string to render. */ html: { type: String, required: false } }, render(h, ctx) { /** * Determines whether the `[html]` prop has been specified. */ const hasHtmlProp = typeof ctx.props.html === 'string'; /** * Determines whether the default `<slot>` has been populated. */ const hasDefaultSlot = typeof ctx.slots().default !== 'undefined' && Array.isArray(ctx.slots().default) && ctx.slots().default.length > 0; /** * The HTML that is to be rendered. */ let content; if (hasHtmlProp && hasDefaultSlot) { console.warn('VHTML: Received both [html] prop AND default <slot> - returning only the HTML from the <slot>.'); content = ''; } else if (hasHtmlProp) { content = ctx.props.html; } else if (hasDefaultSlot) { content = getSlotContents(ctx.slots().default); } else { console.warn('VHTML: Expected to find the HTML string in [html] prop OR inside the default <slot>, but none was present!'); content = ''; } return new vue_1.default({ template: `<div>${content}</div>` }).$mount()._vnode.children; } }); //# sourceMappingURL=VHTML.js.map