UNPKG

vue-highlight.js

Version:

Highlight.js syntax highlighter component for Vue.

626 lines (562 loc) 21.4 kB
var VueHighlightJS = (function (hljs, Vue) { 'use strict'; hljs = hljs && hljs.hasOwnProperty('default') ? hljs['default'] : hljs; Vue = Vue && Vue.hasOwnProperty('default') ? Vue['default'] : Vue; /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ /* global Reflect, Promise */ var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } function __decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } function unwrapExports (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x.default : x; } function createCommonjsModule(fn, module) { return module = { exports: {} }, fn(module, module.exports), module.exports; } var vueClassComponent_common = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, '__esModule', { value: true }); function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var Vue$1 = _interopDefault(Vue); var reflectionIsSupported = typeof Reflect !== 'undefined' && Reflect.defineMetadata; function copyReflectionMetadata(to, from) { forwardMetadata(to, from); Object.getOwnPropertyNames(from.prototype).forEach(function (key) { forwardMetadata(to.prototype, from.prototype, key); }); Object.getOwnPropertyNames(from).forEach(function (key) { forwardMetadata(to, from, key); }); } function forwardMetadata(to, from, propertyKey) { var metaKeys = propertyKey ? Reflect.getOwnMetadataKeys(from, propertyKey) : Reflect.getOwnMetadataKeys(from); metaKeys.forEach(function (metaKey) { var metadata = propertyKey ? Reflect.getOwnMetadata(metaKey, from, propertyKey) : Reflect.getOwnMetadata(metaKey, from); if (propertyKey) { Reflect.defineMetadata(metaKey, metadata, to, propertyKey); } else { Reflect.defineMetadata(metaKey, metadata, to); } }); } var fakeArray = { __proto__: [] }; var hasProto = fakeArray instanceof Array; function createDecorator(factory) { return function (target, key, index) { var Ctor = typeof target === 'function' ? target : target.constructor; if (!Ctor.__decorators__) { Ctor.__decorators__ = []; } if (typeof index !== 'number') { index = undefined; } Ctor.__decorators__.push(function (options) { return factory(options, key, index); }); }; } function mixins() { var Ctors = []; for (var _i = 0; _i < arguments.length; _i++) { Ctors[_i] = arguments[_i]; } return Vue$1.extend({ mixins: Ctors }); } function isPrimitive(value) { var type = typeof value; return value == null || (type !== 'object' && type !== 'function'); } function collectDataFromConstructor(vm, Component) { // override _init to prevent to init as Vue instance var originalInit = Component.prototype._init; Component.prototype._init = function () { var _this = this; // proxy to actual vm var keys = Object.getOwnPropertyNames(vm); // 2.2.0 compat (props are no longer exposed as self properties) if (vm.$options.props) { for (var key in vm.$options.props) { if (!vm.hasOwnProperty(key)) { keys.push(key); } } } keys.forEach(function (key) { if (key.charAt(0) !== '_') { Object.defineProperty(_this, key, { get: function () { return vm[key]; }, set: function (value) { vm[key] = value; }, configurable: true }); } }); }; // should be acquired class property values var data = new Component(); // restore original _init to avoid memory leak (#209) Component.prototype._init = originalInit; // create plain data object var plainData = {}; Object.keys(data).forEach(function (key) { if (data[key] !== undefined) { plainData[key] = data[key]; } }); return plainData; } var $internalHooks = [ 'data', 'beforeCreate', 'created', 'beforeMount', 'mounted', 'beforeDestroy', 'destroyed', 'beforeUpdate', 'updated', 'activated', 'deactivated', 'render', 'errorCaptured' // 2.5 ]; function componentFactory(Component, options) { if (options === void 0) { options = {}; } options.name = options.name || Component._componentTag || Component.name; // prototype props. var proto = Component.prototype; Object.getOwnPropertyNames(proto).forEach(function (key) { if (key === 'constructor') { return; } // hooks if ($internalHooks.indexOf(key) > -1) { options[key] = proto[key]; return; } var descriptor = Object.getOwnPropertyDescriptor(proto, key); if (descriptor.value !== void 0) { // methods if (typeof descriptor.value === 'function') { (options.methods || (options.methods = {}))[key] = descriptor.value; } else { // typescript decorated data (options.mixins || (options.mixins = [])).push({ data: function () { var _a; return _a = {}, _a[key] = descriptor.value, _a; } }); } } else if (descriptor.get || descriptor.set) { // computed properties (options.computed || (options.computed = {}))[key] = { get: descriptor.get, set: descriptor.set }; } }); (options.mixins || (options.mixins = [])).push({ data: function () { return collectDataFromConstructor(this, Component); } }); // decorate options var decorators = Component.__decorators__; if (decorators) { decorators.forEach(function (fn) { return fn(options); }); delete Component.__decorators__; } // find super var superProto = Object.getPrototypeOf(Component.prototype); var Super = superProto instanceof Vue$1 ? superProto.constructor : Vue$1; var Extended = Super.extend(options); forwardStaticMembers(Extended, Component, Super); if (reflectionIsSupported) { copyReflectionMetadata(Extended, Component); } return Extended; } function forwardStaticMembers(Extended, Original, Super) { // We have to use getOwnPropertyNames since Babel registers methods as non-enumerable Object.getOwnPropertyNames(Original).forEach(function (key) { // `prototype` should not be overwritten if (key === 'prototype') { return; } // Some browsers does not allow reconfigure built-in properties var extendedDescriptor = Object.getOwnPropertyDescriptor(Extended, key); if (extendedDescriptor && !extendedDescriptor.configurable) { return; } var descriptor = Object.getOwnPropertyDescriptor(Original, key); // If the user agent does not support `__proto__` or its family (IE <= 10), // the sub class properties may be inherited properties from the super class in TypeScript. // We need to exclude such properties to prevent to overwrite // the component options object which stored on the extended constructor (See #192). // If the value is a referenced value (object or function), // we can check equality of them and exclude it if they have the same reference. // If it is a primitive value, it will be forwarded for safety. if (!hasProto) { // Only `cid` is explicitly exluded from property forwarding // because we cannot detect whether it is a inherited property or not // on the no `__proto__` environment even though the property is reserved. if (key === 'cid') { return; } var superDescriptor = Object.getOwnPropertyDescriptor(Super, key); if (!isPrimitive(descriptor.value) && superDescriptor && superDescriptor.value === descriptor.value) { return; } } Object.defineProperty(Extended, key, descriptor); }); } function Component(options) { if (typeof options === 'function') { return componentFactory(options); } return function (Component) { return componentFactory(Component, options); }; } Component.registerHooks = function registerHooks(keys) { $internalHooks.push.apply($internalHooks, keys); }; exports.default = Component; exports.createDecorator = createDecorator; exports.mixins = mixins; }); var Component = unwrapExports(vueClassComponent_common); var vueClassComponent_common_1 = vueClassComponent_common.createDecorator; var vueClassComponent_common_2 = vueClassComponent_common.mixins; /** vue-property-decorator verson 7.3.0 MIT LICENSE copyright 2018 kaorun343 */ /** * decorator of a prop * @param options the options for the prop * @return PropertyDecorator | void */ function Prop(options) { if (options === void 0) { options = {}; } return vueClassComponent_common_1(function (componentOptions, k) { (componentOptions.props || (componentOptions.props = {}))[k] = options; }); } /** * Escape code. * * @export * @param {string} code Code. * @returns {string} */ function escape(code) { if (typeof code === 'string') { return code .replace(/&/g, '&amp;') .replace(/"/g, '&quot;') .replace(/'/g, '&apos;') .replace(/</g, '&lt;') .replace(/>/g, '&gt;'); } else { return code; } } /** * Deeply get concatenated text from slot. * * @export * @param {VNode[]} slot A slot. (The collection of VNode) * @returns {string} */ function getSlotText(slot) { if (Array.isArray(slot)) { return slot .map(function (node) { if (Array.isArray(node.children) && node.children.length > 0) { return getSlotText(node.children); } else { return node.text; } }) .join(''); } else { return ''; } } // detect either spaces or tabs but not both to properly handle tabs // for indentation and spaces for alignment const INDENT_RE = /^(?:( )+|\t+)/; function getMostUsed(indents) { let result = 0; let maxUsed = 0; let maxWeight = 0; for (const entry of indents) { // TODO: use destructuring when targeting Node.js 6 const key = entry[0]; const val = entry[1]; const u = val[0]; const w = val[1]; if (u > maxUsed || (u === maxUsed && w > maxWeight)) { maxUsed = u; maxWeight = w; result = Number(key); } } return result; } var detectIndent = str => { if (typeof str !== 'string') { throw new TypeError('Expected a string'); } // used to see if tabs or spaces are the most used let tabs = 0; let spaces = 0; // remember the size of previous line's indentation let prev = 0; // remember how many indents/unindents as occurred for a given size // and how much lines follow a given indentation // // indents = { // 3: [1, 0], // 4: [1, 5], // 5: [1, 0], // 12: [1, 0], // } const indents = new Map(); // pointer to the array of last used indent let current; // whether the last action was an indent (opposed to an unindent) let isIndent; for (const line of str.split(/\n/g)) { if (!line) { // ignore empty lines continue; } let indent; const matches = line.match(INDENT_RE); if (matches) { indent = matches[0].length; if (matches[1]) { spaces++; } else { tabs++; } } else { indent = 0; } const diff = indent - prev; prev = indent; if (diff) { // an indent or unindent has been detected isIndent = diff > 0; current = indents.get(isIndent ? diff : -diff); if (current) { current[0]++; } else { current = [1, 0]; indents.set(diff, current); } } else if (current) { // if the last action was an indent, increment the weight current[1] += Number(isIndent); } } const amount = getMostUsed(indents); let type; let indent; if (!amount) { type = null; indent = ''; } else if (spaces >= tabs) { type = 'space'; indent = ' '.repeat(amount); } else { type = 'tab'; indent = '\t'.repeat(amount); } return { amount, type, indent }; }; var stripIndent = str => { const match = str.match(/^[ \t]*(?=\S)/gm); if (!match) { return str; } // TODO: use spread operator when targeting Node.js 6 const indent = Math.min.apply(Math, match.map(x => x.length)); // eslint-disable-line const re = new RegExp(`^[ \\t]{${indent}}`, 'gm'); return indent > 0 ? str.replace(re, '') : str; }; var indentString = (str, count, opts) => { // Support older versions: use the third parameter as options.indent // TODO: Remove the workaround in the next major version const options = typeof opts === 'object' ? Object.assign({indent: ' '}, opts) : {indent: opts || ' '}; count = count === undefined ? 1 : count; if (typeof str !== 'string') { throw new TypeError(`Expected \`input\` to be a \`string\`, got \`${typeof str}\``); } if (typeof count !== 'number') { throw new TypeError(`Expected \`count\` to be a \`number\`, got \`${typeof count}\``); } if (typeof options.indent !== 'string') { throw new TypeError(`Expected \`options.indent\` to be a \`string\`, got \`${typeof options.indent}\``); } if (count === 0) { return str; } const regex = options.includeEmptyLines ? /^/mg : /^(?!\s*$)/mg; return str.replace(regex, options.indent.repeat(count)); } ; var redent = (str, count, indent) => indentString(stripIndent(str), count || 0, indent); /** * Indent code. * * @export * @param {string} code Code. * @returns {string} */ function indentCode(code) { if (typeof code === 'string') { var indent = detectIndent(code).indent || '\t'; code = redent(code, 0, indent); return code.trim(); } else { return code; } } var inlineStyles = { display: 'inline !important', 'vertical-align': 'middle' }; var HighlightCode = /** @class */ (function (_super) { __extends(HighlightCode, _super); function HighlightCode() { return _super !== null && _super.apply(this, arguments) || this; } Object.defineProperty(HighlightCode.prototype, "hasCode", { get: function () { return typeof this.code === 'string' && this.code.length > 0; }, enumerable: true, configurable: true }); HighlightCode.prototype.render = function (h) { var _a; var _b = this, hasCode = _b.hasCode, inline = _b.inline, auto = _b.auto; var lang = this.lang; var code = hasCode ? this.code : getSlotText(this.$slots.default); // If no `code`, get text from default slot. // Indent code if not use inline mode. if (!inline) { code = indentCode(code); } var highlightedCode; try { if (auto) { (_a = hljs.highlightAuto(code), lang = _a.language, highlightedCode = _a.value); } else { highlightedCode = lang ? hljs.highlight(lang, code).value : escape(code); // If no `lang`, just display plain code. } } catch (err) { highlightedCode = escape(code); console.error(err); } return h(!inline ? 'pre' : 'span', [ h('code', { class: ['hljs'].concat((lang ? [lang] : [])), style: inline ? inlineStyles : {}, domProps: { innerHTML: highlightedCode } }) ]); }; __decorate([ Prop(String) ], HighlightCode.prototype, "lang", void 0); __decorate([ Prop({ type: Boolean, default: false }) ], HighlightCode.prototype, "inline", void 0); __decorate([ Prop(String) ], HighlightCode.prototype, "code", void 0); __decorate([ Prop(Boolean) ], HighlightCode.prototype, "auto", void 0); HighlightCode = __decorate([ Component({ name: 'HighlightCode' }) ], HighlightCode); return HighlightCode; }(Vue)); /** * Install Vue Highlight.js as plugin. * * @param {typeof Vue} vue Vue * @param {Options} [options={ languages: {} }] Options */ var install = function (vue, options) { if (options === void 0) { options = { languages: {} }; } var languages = options.languages; { // Register additional `vue` language from highlight.js `xml` in web bundle var xml_1 = window.hljs.getLanguage('xml'); window.hljs.registerLanguage('vue', function () { return xml_1; }); } vue.component('highlight-code', HighlightCode); }; if (typeof window !== 'undefined' && window.Vue) { install(window.Vue); } var index = { install: install }; return index; }(hljs, Vue)); //# sourceMappingURL=vue-highlight.web.js.map