diff --git a/.vscode/settings.json b/.vscode/settings.json index a88242f..501b8ba 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -102,5 +102,6 @@ "i18n-ally.localesPaths": [ "src/locale", "src/pages/i18n" - ] + ], + "i18n-ally.keystyle": "nested" } diff --git a/src/api/halo-plugin/photo.ts b/src/api/halo-plugin/photo.ts index 33bee3d..116d5a1 100644 --- a/src/api/halo-plugin/photo.ts +++ b/src/api/halo-plugin/photo.ts @@ -1,11 +1,45 @@ import { http } from '@/http/alova' +import type { IHaloListResponseBase } from '@/api/types/halo' + +export interface IQueryPhotoGroupsRequest { + page?: number + size?: number +} + +export interface IQueryPhotosRequest { + group?: string + ungrouped?: boolean + tag?: string + keyword?: string + labelSelector?: string + fieldSelector?: string + sort?: string + page?: number + size?: number +} + +export interface IPhoto { + metadata: { + creationTimestamp: string + generateName: string + name: string + version: string + } + permalink: string + spec: { + cover: string + displayName: string + groupName: string + url: string + } +} /** * 获取图库分组列表 * @param params 获取图库分组列表请求参数 * @returns 获取图库分组列表响应参数 */ -export function queryPhotoGroups(params: any) { +export function queryPhotoGroups(params: IQueryPhotoGroupsRequest) { return http.Get(`/apis/api.photo.halo.run/v1alpha1/photogroups`, { params, meta: { @@ -33,8 +67,8 @@ export function queryPhotoTags(params: any) { * @param params 获取图库列表请求参数 * @returns 获取图库列表响应参数 */ -export function queryPhotos(params: any) { - return http.Get(`/apis/api.photo.halo.run/v1alpha1/photos`, { +export function queryPhotos(params: IQueryPhotosRequest) { + return http.Get>(`/apis/api.photo.halo.run/v1alpha1/photos`, { params, meta: { isHalo: true, diff --git a/src/api/types/halo.ts b/src/api/types/halo.ts new file mode 100644 index 0000000..5148748 --- /dev/null +++ b/src/api/types/halo.ts @@ -0,0 +1,23 @@ +/** + * Halo 列表响应基础结构 + * @template T 列表项类型 + */ +export interface IHaloListResponseBase { + page: number + size: number + total: number + items: T[] + first: boolean + hasNext: boolean + hasPrevious: boolean + last: boolean + totalPages: number +} + +/** + * Halo 列表请求基础结构 + */ +export interface IHaloListRequestBase { + page?: number + size?: number +} diff --git a/src/components/mp-html/components/mp-html/editable/config.js b/src/components/mp-html/components/mp-html/editable/config.js new file mode 100644 index 0000000..8a21a3a --- /dev/null +++ b/src/components/mp-html/components/mp-html/editable/config.js @@ -0,0 +1,11 @@ +// 以下项目可以删减或更换顺序,但不能添加或更改名字 +export default { + // 普通标签的菜单项 + node: ['大小', '斜体', '粗体', '下划线', '居中', '缩进', '上移', '下移', '删除'], + // 图片的菜单项 + img: ['换图', '宽度', '超链接', '预览图', '禁用预览', '上移', '下移', '删除'], + // 链接的菜单项 + link: ['更换链接', '上移', '下移', '删除'], + // 音视频的菜单项 + media: ['封面', '循环', '自动播放', '上移', '下移', '删除'] +} diff --git a/src/components/mp-html/components/mp-html/editable/index.js b/src/components/mp-html/components/mp-html/editable/index.js new file mode 100644 index 0000000..a6daf8a --- /dev/null +++ b/src/components/mp-html/components/mp-html/editable/index.js @@ -0,0 +1,532 @@ +/** + * @fileoverview editable 插件 + */ +import config from './config' +import Parser from '../parser' + +function Editable (vm) { + this.vm = vm + this.editHistory = [] // 历史记录 + this.editI = -1 // 历史记录指针 + vm._mask = [] // 蒙版被点击时进行的操作 + + vm._setData = function (path, val) { + const paths = path.split('.') + let target = vm + for (let i = 0; i < paths.length - 1; i++) { + target = target[paths[i]] + } + vm.$set(target, paths.pop(), val) + } + + /** + * @description 移动历史记录指针 + * @param {Number} num 移动距离 + */ + const move = num => { + setTimeout(() => { + const item = this.editHistory[this.editI + num] + if (item) { + this.editI += num + vm._setData(item.key, item.value) + } + }, 200) + } + vm.undo = () => move(-1) // 撤销 + vm.redo = () => move(1) // 重做 + + /** + * @description 更新记录 + * @param {String} path 更新内容路径 + * @param {*} oldVal 旧值 + * @param {*} newVal 新值 + * @param {Boolean} set 是否更新到视图 + * @private + */ + vm._editVal = (path, oldVal, newVal, set) => { + // 当前指针后的内容去除 + while (this.editI < this.editHistory.length - 1) { + this.editHistory.pop() + } + + // 最多存储 30 条操作记录 + while (this.editHistory.length > 30) { + this.editHistory.pop() + this.editI-- + } + + const last = this.editHistory[this.editHistory.length - 1] + if (!last || last.key !== path) { + if (last) { + // 去掉上一次的新值 + this.editHistory.pop() + this.editI-- + } + // 存入这一次的旧值 + this.editHistory.push({ + key: path, + value: oldVal + }) + this.editI++ + } + + // 存入本次的新值 + this.editHistory.push({ + key: path, + value: newVal + }) + this.editI++ + + // 更新到视图 + if (set) { + vm._setData(path, newVal) + } + } + + /** + * @description 获取菜单项 + * @private + */ + vm._getItem = function (node, up, down) { + let items + let i + if (node.name === 'img') { + items = config.img.slice(0) + if (!vm.getSrc) { + i = items.indexOf('换图') + if (i !== -1) { + items.splice(i, 1) + } + i = items.indexOf('超链接') + if (i !== -1) { + items.splice(i, 1) + } + i = items.indexOf('预览图') + if (i !== -1) { + items.splice(i, 1) + } + } + i = items.indexOf('禁用预览') + if (i !== -1 && node.attrs.ignore) { + items[i] = '启用预览' + } + } else if (node.name === 'a') { + items = config.link.slice(0) + if (!vm.getSrc) { + i = items.indexOf('更换链接') + if (i !== -1) { + items.splice(i, 1) + } + } + } else if (node.name === 'video' || node.name === 'audio') { + items = config.media.slice(0) + i = items.indexOf('封面') + if (!vm.getSrc && i !== -1) { + items.splice(i, 1) + } + i = items.indexOf('循环') + if (node.attrs.loop && i !== -1) { + items[i] = '不循环' + } + i = items.indexOf('自动播放') + if (node.attrs.autoplay && i !== -1) { + items[i] = '不自动播放' + } + } else { + items = config.node.slice(0) + } + if (!up) { + i = items.indexOf('上移') + if (i !== -1) { + items.splice(i, 1) + } + } + if (!down) { + i = items.indexOf('下移') + if (i !== -1) { + items.splice(i, 1) + } + } + return items + } + + /** + * @description 显示 tooltip + * @param {object} obj + * @private + */ + vm._tooltip = function (obj) { + vm.$set(vm, 'tooltip', { + top: obj.top, + items: obj.items + }) + vm._tooltipcb = obj.success + } + + /** + * @description 显示滚动条 + * @param {object} obj + * @private + */ + vm._slider = function (obj) { + vm.$set(vm, 'slider', { + min: obj.min, + max: obj.max, + value: obj.value, + top: obj.top + }) + vm._slideringcb = obj.changing + vm._slidercb = obj.change + } + + /** + * @description 点击蒙版 + * @private + */ + vm._maskTap = function () { + // 隐藏所有悬浮窗 + while (vm._mask.length) { + (vm._mask.pop())() + } + if (vm.tooltip) { + vm.$set(vm, 'tooltip', null) + } + if (vm.slider) { + vm.$set(vm, 'slider', null) + } + } + + /** + * @description 插入节点 + * @param {Object} node + */ + function insert (node) { + if (vm._edit) { + vm._edit.insert(node) + } else { + const nodes = vm.nodes.slice(0) + nodes.push(node) + vm._editVal('nodes', vm.nodes, nodes, true) + } + } + + /** + * @description 在光标处插入指定 html 内容 + * @param {String} html 内容 + */ + vm.insertHtml = html => { + this.inserting = true + const arr = new Parser(vm).parse(html) + this.inserting = undefined + for (let i = 0; i < arr.length; i++) { + insert(arr[i]) + } + } + + /** + * @description 在光标处插入图片 + */ + vm.insertImg = function () { + vm.getSrc && vm.getSrc('img').then(src => { + if (typeof src === 'string') { + src = [src] + } + const parser = new Parser(vm) + for (let i = 0; i < src.length; i++) { + insert({ + name: 'img', + attrs: { + src: parser.getUrl(src[i]) + } + }) + } + }).catch(() => { }) + } + + /** + * @description 在光标处插入一个链接 + */ + vm.insertLink = function () { + vm.getSrc && vm.getSrc('link').then(url => { + insert({ + name: 'a', + attrs: { + href: url + }, + children: [{ + type: 'text', + text: url + }] + }) + }).catch(() => { }) + } + + /** + * @description 在光标处插入一个表格 + * @param {Number} rows 行数 + * @param {Number} cols 列数 + */ + vm.insertTable = function (rows, cols) { + const table = { + name: 'table', + attrs: { + style: 'display:table;width:100%;margin:10px 0;text-align:center;border-spacing:0;border-collapse:collapse;border:1px solid gray' + }, + children: [] + } + for (let i = 0; i < rows; i++) { + const tr = { + name: 'tr', + attrs: {}, + children: [] + } + for (let j = 0; j < cols; j++) { + tr.children.push({ + name: 'td', + attrs: { + style: 'padding:2px;border:1px solid gray' + }, + children: [{ + type: 'text', + text: '' + }] + }) + } + table.children.push(tr) + } + insert(table) + } + + /** + * @description 插入视频/音频 + * @param {Object} node + */ + function insertMedia (node) { + if (typeof node.src === 'string') { + node.src = [node.src] + } + const parser = new Parser(vm) + // 拼接主域名 + for (let i = 0; i < node.src.length; i++) { + node.src[i] = parser.getUrl(node.src[i]) + } + insert({ + name: 'div', + attrs: { + style: 'text-align:center' + }, + children: [node] + }) + } + + /** + * @description 在光标处插入一个视频 + */ + vm.insertVideo = function () { + vm.getSrc && vm.getSrc('video').then(src => { + insertMedia({ + name: 'video', + attrs: { + controls: 'T' + }, + children: [], + src, + // #ifdef APP-PLUS + html: `` + // #endif + }) + }).catch(() => { }) + } + + /** + * @description 在光标处插入一个音频 + */ + vm.insertAudio = function () { + vm.getSrc && vm.getSrc('audio').then(attrs => { + let src + if (attrs.src) { + src = attrs.src + attrs.src = undefined + } else { + src = attrs + attrs = {} + } + attrs.controls = 'T' + insertMedia({ + name: 'audio', + attrs, + children: [], + src + }) + }).catch(() => { }) + } + + /** + * @description 在光标处插入一段文本 + */ + vm.insertText = function () { + insert({ + name: 'p', + attrs: {}, + children: [{ + type: 'text', + text: '' + }] + }) + } + + /** + * @description 清空内容 + */ + vm.clear = function () { + vm._maskTap() + vm._edit = undefined + vm.$set(vm, 'nodes', [{ + name: 'p', + attrs: {}, + children: [{ + type: 'text', + text: '' + }] + }]) + } + + /** + * @description 获取编辑后的 html + */ + vm.getContent = function () { + let html = ''; + // 递归遍历获取 + (function traversal (nodes, table) { + for (let i = 0; i < nodes.length; i++) { + let item = nodes[i] + if (item.type === 'text') { + html += item.text.replace(/&/g, '&').replace(//g, '>').replace(/\n/g, '
').replace(/\xa0/g, ' ') // 编码实体 + } else { + if (item.name === 'img') { + item.attrs.i = '' + // 还原被转换的 svg + if ((item.attrs.src || '').includes('data:image/svg+xml;utf8,')) { + html += item.attrs.src.substr(24).replace(/%23/g, '#').replace(' 1) { + item.children = [] + for (let j = 0; j < item.src.length; j++) { + item.children.push({ + name: 'source', + attrs: { + src: item.src[j] + } + }) + } + } else { + item.attrs.src = item.src[0] + } + } else if (item.name === 'div' && (item.attrs.style || '').includes('overflow:auto') && (item.children[0] || {}).name === 'table') { + // 还原滚动层 + item = item.children[0] + } + // 还原 table + if (item.name === 'table') { + item = JSON.parse(JSON.stringify(item)) + table = item.attrs + if ((item.attrs.style || '').includes('display:grid')) { + item.attrs.style = item.attrs.style.split('display:grid')[0] + const children = [{ + name: 'tr', + attrs: {}, + children: [] + }] + for (let j = 0; j < item.children.length; j++) { + item.children[j].attrs.style = item.children[j].attrs.style.replace(/grid-[^;]+;*/g, '') + if (item.children[j].r !== children.length) { + children.push({ + name: 'tr', + attrs: {}, + children: [item.children[j]] + }) + } else { + children[children.length - 1].children.push(item.children[j]) + } + } + item.children = children + } + } + html += '<' + item.name + for (const attr in item.attrs) { + let val = item.attrs[attr] + if (!val) continue + if (val === 'T' || val === true) { + // bool 型省略值 + html += ' ' + attr + continue + } else if (item.name[0] === 't' && attr === 'style' && table) { + // 取消为了显示 table 添加的 style + val = val.replace(/;*display:table[^;]*/, '') + if (table.border) { + val = val.replace(/border[^;]+;*/g, $ => $.includes('collapse') ? $ : '') + } + if (table.cellpadding) { + val = val.replace(/padding[^;]+;*/g, '') + } + if (!val) continue + } + html += ' ' + attr + '="' + val.replace(/"/g, '"') + '"' + } + html += '>' + if (item.children) { + traversal(item.children, table) + html += '' + } + } + } + })(vm.nodes) + + // 其他插件处理 + for (let i = vm.plugins.length; i--;) { + if (vm.plugins[i].onGetContent) { + html = vm.plugins[i].onGetContent(html) || html + } + } + + return html + } +} + +Editable.prototype.onUpdate = function (content, config) { + if (this.vm.editable) { + this.vm._maskTap() + config.entities.amp = '&' + if (!this.inserting) { + this.vm._edit = undefined + if (!content) { + setTimeout(() => { + this.vm.$set(this.vm, 'nodes', [{ + name: 'p', + attrs: {}, + children: [{ + type: 'text', + text: '' + }] + }]) + }, 0) + } + } + } +} + +Editable.prototype.onParse = function (node) { + // 空白单元格可编辑 + if (this.vm.editable && (node.name === 'td' || node.name === 'th') && !this.vm.getText(node.children)) { + node.children.push({ + type: 'text', + text: '' + }) + } +} + +export default Editable diff --git a/src/components/mp-html/components/mp-html/emoji/index.js b/src/components/mp-html/components/mp-html/emoji/index.js new file mode 100644 index 0000000..fafcb49 --- /dev/null +++ b/src/components/mp-html/components/mp-html/emoji/index.js @@ -0,0 +1,203 @@ +/** + * @fileoverview emoji 插件 + */ +const reg = /\[(\S+?)\]/g +const data = { + 笑脸: '😄', + 生病: '😷', + 破涕为笑: '😂', + 吐舌: '😝', + 脸红: '😳', + 恐惧: '😱', + 失望: '😔', + 无语: '😒', + 眨眼: '😉', + 酷: '😎', + 哭: '😭', + 痴迷: '😍', + 吻: '😘', + 思考: '🤔', + 困惑: '😕', + 颠倒: '🙃', + 钱: '🤑', + 惊讶: '😲', + 白眼: '🙄', + 叹气: '😤', + 睡觉: '😴', + 书呆子: '🤓', + 愤怒: '😡', + 面无表情: '😑', + 张嘴: '😮', + 量体温: '🤒', + 呕吐: '🤮', + 光环: '😇', + 幽灵: '👻', + 外星人: '👽', + 机器人: '🤖', + 捂眼镜: '🙈', + 捂耳朵: '🙉', + 捂嘴: '🙊', + 婴儿: '👶', + 男孩: '👦', + 女孩: '👧', + 男人: '👨', + 女人: '👩', + 老人: '👴', + 老妇人: '👵', + 警察: '👮', + 王子: '🤴', + 公主: '🤴', + 举手: '🙋', + 跑步: '🏃', + 家庭: '👪', + 眼睛: '👀', + 鼻子: '👃', + 耳朵: '👂', + 舌头: '👅', + 嘴: '👄', + 心: '❤️', + 心碎: '💔', + 雪人: '☃️', + 情书: '💌', + 大便: '💩', + 闹钟: '⏰', + 眼镜: '👓', + 雨伞: '☂️', + 音乐: '🎵', + 话筒: '🎤', + 游戏机: '🎮', + 喇叭: '📢', + 耳机: '🎧', + 礼物: '🎁', + 电话: '📞', + 电脑: '💻', + 打印机: '🖨️', + 手电筒: '🔦', + 灯泡: '💡', + 书本: '📖', + 信封: '✉️', + 药丸: '💊', + 口红: '💄', + 手机: '📱', + 相机: '📷', + 电视: '📺', + 中: '🀄', + 垃圾桶: '🚮', + 厕所: '🚾', + 感叹号: '❗', + 禁: '🈲', + 可: '🉑', + 彩虹: '🌈', + 旋风: '🌀', + 雷电: '⚡', + 雪花: '❄️', + 星星: '⭐', + 水滴: '💧', + 玫瑰: '🌹', + 加油: '💪', + 左: '👈', + 右: '👉', + 上: '👆', + 下: '👇', + 手掌: '🖐️', + 好的: '👌', + 好: '👍', + 差: '👎', + 胜利: '✌', + 拳头: '👊', + 挥手: '👋', + 鼓掌: '👏', + 猴子: '🐒', + 狗: '🐶', + 狼: '🐺', + 猫: '🐱', + 老虎: '🐯', + 马: '🐎', + 独角兽: '🦄', + 斑马: '🦓', + 鹿: '🦌', + 牛: '🐮', + 猪: '🐷', + 羊: '🐏', + 长颈鹿: '🦒', + 大象: '🐘', + 老鼠: '🐭', + 蝙蝠: '🦇', + 刺猬: '🦔', + 熊猫: '🐼', + 鸽子: '🕊️', + 鸭子: '🦆', + 兔子: '🐇', + 老鹰: '🦅', + 青蛙: '🐸', + 蛇: '🐍', + 龙: '🐉', + 鲸鱼: '🐳', + 海豚: '🐬', + 足球: '⚽', + 棒球: '⚾', + 篮球: '🏀', + 排球: '🏐', + 橄榄球: '🏉', + 网球: '🎾', + 骰子: '🎲', + 鸡腿: '🍗', + 蛋糕: '🎂', + 啤酒: '🍺', + 饺子: '🥟', + 汉堡: '🍔', + 薯条: '🍟', + 意大利面: '🍝', + 干杯: '🥂', + 筷子: '🥢', + 糖果: '🍬', + 奶瓶: '🍼', + 爆米花: '🍿', + 邮局: '🏤', + 医院: '🏥', + 银行: '🏦', + 酒店: '🏨', + 学校: '🏫', + 城堡: '🏰', + 火车: '🚂', + 高铁: '🚄', + 地铁: '🚇', + 公交: '🚌', + 救护车: '🚑', + 消防车: '🚒', + 警车: '🚓', + 出租车: '🚕', + 汽车: '🚗', + 货车: '🚛', + 自行车: '🚲', + 摩托: '🛵', + 红绿灯: '🚥', + 帆船: '⛵', + 游轮: '🛳️', + 轮船: '⛴️', + 飞机: '✈️', + 直升机: '🚁', + 缆车: '🚠', + 警告: '⚠️', + 禁止: '⛔' +} + +function Emoji () { + +} + +Emoji.prototype.onUpdate = function (content) { + return content.replace(reg, ($, $1) => { + if (data[$1]) return data[$1] + return $ + }) +} + +Emoji.prototype.onGetContent = function (content) { + for (const item in data) { + content = content.replace(new RegExp(data[item], 'g'), '[' + item + ']') + } + return content +} + +export default Emoji diff --git a/src/components/mp-html/components/mp-html/highlight/config.js b/src/components/mp-html/components/mp-html/highlight/config.js new file mode 100644 index 0000000..b6f0142 --- /dev/null +++ b/src/components/mp-html/components/mp-html/highlight/config.js @@ -0,0 +1,5 @@ +export default { + copyByLongPress: true, // 是否需要长按代码块时显示复制代码内容菜单 + showLanguageName: true, // 是否在代码块右上角显示语言的名称 + showLineNumber: true // 是否显示行号 +} diff --git a/src/components/mp-html/components/mp-html/highlight/index.js b/src/components/mp-html/components/mp-html/highlight/index.js new file mode 100644 index 0000000..4f83d48 --- /dev/null +++ b/src/components/mp-html/components/mp-html/highlight/index.js @@ -0,0 +1,96 @@ +/** + * @fileoverview highlight 插件 + * Include prismjs (https://prismjs.com) + */ +import prism from './prism.min' +import config from './config' +import Parser from '../parser' + +function Highlight (vm) { + this.vm = vm +} + +Highlight.prototype.onParse = function (node, vm) { + if (node.name === 'pre') { + if (vm.options.editable) { + node.attrs.class = (node.attrs.class || '') + ' hl-pre' + return + } + let i + for (i = node.children.length; i--;) { + if (node.children[i].name === 'code') break + } + if (i === -1) return + const code = node.children[i] + let className = code.attrs.class + ' ' + node.attrs.class + i = className.indexOf('language-') + if (i === -1) { + i = className.indexOf('lang-') + if (i === -1) { + className = 'language-text' + i = 9 + } else { + i += 5 + } + } else { + i += 9 + } + let j + for (j = i; j < className.length; j++) { + if (className[j] === ' ') break + } + const lang = className.substring(i, j) + if (code.children.length) { + const text = this.vm.getText(code.children).replace(/&/g, '&') + if (!text) return + if (node.c) { + node.c = undefined + } + if (prism.languages[lang]) { + code.children = (new Parser(this.vm).parse( + // 加一层 pre 保留空白符 + '
' + prism.highlight(text, prism.languages[lang], lang).replace(/token /g, 'hl-') + '
'))[0].children + } + node.attrs.class = 'hl-pre' + code.attrs.class = 'hl-code' + if (config.showLanguageName) { + node.children.push({ + name: 'div', + attrs: { + class: 'hl-language', + style: 'user-select:none' + }, + children: [{ + type: 'text', + text: lang + }] + }) + } + if (config.copyByLongPress) { + node.attrs.style += (node.attrs.style || '') + ';user-select:none' + node.attrs['data-content'] = text + vm.expose() + } + if (config.showLineNumber) { + const line = text.split('\n').length; const children = [] + for (let k = line; k--;) { + children.push({ + name: 'span', + attrs: { + class: 'span' + } + }) + } + node.children.push({ + name: 'span', + attrs: { + class: 'line-numbers-rows' + }, + children + }) + } + } + } +} + +export default Highlight diff --git a/src/components/mp-html/components/mp-html/highlight/prism.min.js b/src/components/mp-html/components/mp-html/highlight/prism.min.js new file mode 100644 index 0000000..0b67d39 --- /dev/null +++ b/src/components/mp-html/components/mp-html/highlight/prism.min.js @@ -0,0 +1,7 @@ +/*! PrismJS 1.22.0 +https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript */ +var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(u){var c=/\blang(?:uage)?-([\w-]+)\b/i,n=0,M={manual:u.Prism&&u.Prism.manual,disableWorkerMessageHandler:u.Prism&&u.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof W?new W(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&").replace(/=l.reach);k+=y.value.length,y=y.next){var b=y.value;if(t.length>n.length)return;if(!(b instanceof W)){var x=1;if(h&&y!=t.tail.prev){m.lastIndex=k;var w=m.exec(n);if(!w)break;var A=w.index+(f&&w[1]?w[1].length:0),P=w.index+w[0].length,S=k;for(S+=y.value.length;S<=A;)y=y.next,S+=y.value.length;if(S-=y.value.length,k=S,y.value instanceof W)continue;for(var E=y;E!==t.tail&&(Sl.reach&&(l.reach=j);var C=y.prev;L&&(C=I(t,C,L),k+=L.length),z(t,C,x);var _=new W(o,g?M.tokenize(O,g):O,v,O);y=I(t,C,_),N&&I(t,y,N),1"+a.content+""},!u.document)return u.addEventListener&&(M.disableWorkerMessageHandler||u.addEventListener("message",function(e){var n=JSON.parse(e.data),t=n.language,r=n.code,a=n.immediateClose;u.postMessage(M.highlight(r,M.languages[t],t)),a&&u.close()},!1)),M;var e=M.util.currentScript();function t(){M.manual||M.highlightAll()}if(e&&(M.filename=e.src,e.hasAttribute("data-manual")&&(M.manual=!0)),!M.manual){var r=document.readyState;"loading"===r||"interactive"===r&&e&&e.defer?document.addEventListener("DOMContentLoaded",t):window.requestAnimationFrame?window.requestAnimationFrame(t):window.setTimeout(t,16)}return M}(_self);export default Prism;"undefined"!=typeof global&&(global.Prism=Prism); +Prism.languages.markup={comment://,prolog:/<\?[\s\S]+?\?>/,doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/,name:/[^\s<>'"]+/}},cdata://i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.languages.markup.doctype.inside["internal-subset"].inside=Prism.languages.markup,Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))}),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(a,e){var s={};s["language-"+e]={pattern:/(^$)/i,lookbehind:!0,inside:Prism.languages[e]},s.cdata=/^$/i;var n={"included-cdata":{pattern://i,inside:s}};n["language-"+e]={pattern:/[\s\S]+/,inside:Prism.languages[e]};var t={};t[a]={pattern:RegExp("(<__[^]*?>)(?:))*\\]\\]>|(?!)".replace(/__/g,function(){return a}),"i"),lookbehind:!0,greedy:!0,inside:n},Prism.languages.insertBefore("markup","cdata",t)}}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.ssml=Prism.languages.xml,Prism.languages.atom=Prism.languages.xml,Prism.languages.rss=Prism.languages.xml; +!function(e){var t=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+[\s\S]*?(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\((?!\s*\))\s*)(?:[^()]|\((?:[^()]|\([^()]*\))*\))+?(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|(?:[^\\\\\r\n()\"']|\\\\[^])*)\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:RegExp("[^{}\\s](?:[^{};\"']|"+t.source+")*?(?=\\s*\\{)"),string:{pattern:t,greedy:!0},property:/[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,important:/!important\b/i,function:/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var s=e.languages.markup;s&&(s.tag.addInlined("style","css"),e.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/(^|["'\s])style\s*=\s*(?:"[^"]*"|'[^']*')/i,lookbehind:!0,inside:{"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{style:{pattern:/(["'])[\s\S]+(?=["']$)/,lookbehind:!0,alias:"language-css",inside:e.languages.css},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},"attr-name":/^style/i}}},s.tag))}(Prism); +Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,boolean:/\b(?:true|false)\b/,function:/\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/}; +Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])[_$A-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\.(?:prototype|constructor))/,lookbehind:!0}],keyword:[{pattern:/((?:^|})\s*)(?:catch|finally)\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|function|(?:get|set)(?=\s*[\[$\w\xA0-\uFFFF])|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],number:/\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)?)*|\B\.(?:\d(?:_\d)?)+)(?:[Ee][+-]?(?:\d(?:_\d)?)+)?/,function:/#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyus]{0,6}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:Prism.languages.regex},"regex-flags":/[a-z]+$/,"regex-delimiter":/^\/|\/$/}},"function-variable":{pattern:/#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)?\s*\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\))/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*=>)/i,inside:Prism.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*=>)/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*\{)/,lookbehind:!0,inside:Prism.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),Prism.languages.insertBefore("javascript","string",{"template-string":{pattern:/`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}|(?!\${)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\${|}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&Prism.languages.markup.tag.addInlined("script","javascript"),Prism.languages.js=Prism.languages.javascript; diff --git a/src/components/mp-html/components/mp-html/img-cache/index.js b/src/components/mp-html/components/mp-html/img-cache/index.js new file mode 100644 index 0000000..d920f03 --- /dev/null +++ b/src/components/mp-html/components/mp-html/img-cache/index.js @@ -0,0 +1,138 @@ +const data = { + name: 'imgcache', + prefix: 'imgcache_' +} +function ImgCache (vm) { + this.vm = vm // 保存实例在其他周期使用 + this.i = 0 // 用于标记第几张图 + vm.imgCache = { + get list () { + return uni + .getStorageInfoSync() + .keys.filter((key) => key.startsWith(data.prefix)) + .map((key) => key.split(data.prefix)[1]) + }, + get (url) { + return uni.getStorageSync(data.prefix + url) + }, + delete (url) { + const path = uni.getStorageSync(data.prefix + url) + if (!path) return false + plus.io.resolveLocalFileSystemURL(path, (entry) => { + entry.remove() + }) + uni.removeStorageSync(data.prefix + url) + return true + }, + async add (url) { + const filename = await download(url) + if (filename) { + uni.setStorageSync(data.prefix + url, filename) + return 'file://' + plus.io.convertLocalFileSystemURL(filename) + } + return null + }, + clear () { + uni + .getStorageInfoSync() + .keys.filter((key) => key.startsWith(data.prefix)) + .forEach((key) => { + uni.removeStorageSync(key) + }) + + plus.io.resolveLocalFileSystemURL(`_doc/${data.name}/`, (entry) => { + entry.removeRecursively( + (entry) => { + console.log(`${data.name}缓存删除成功`, entry) + }, + (e) => { + console.log(`${data.name}缓存删除失败`, e) + } + ) + }) + } + } +} + +// #ifdef APP-PLUS +ImgCache.prototype.onParse = function (node, parser) { + // 启用本插件 && 解析图片标签 && 拥有src属性 && 是网络图片 + if ( + this.vm.ImgCache && + node.name === 'img' && + node.attrs.src && + /^https?:\/\//.test(node.attrs.src) + ) { + const src = node.attrs.src + node.attrs.src = '' + node.attrs.i = this.vm.imgList.length + this.i++ + parser.expose() + + async function getUrl (path) { + if (await resolveFile(path)) return path + const filename = await download(src) + filename && uni.setStorageSync(data.prefix + src, filename) + return filename + } + + uni.getStorage({ + key: data.prefix + src, + success: async (res) => { + const path = await getUrl(res.data) + const url = path + ? 'file://' + plus.io.convertLocalFileSystemURL(path) + : src + node.attrs.src = url + this.vm.imgList[node.attrs.i] = path || src + }, + fail: async () => { + const path = await getUrl() + const url = path + ? 'file://' + plus.io.convertLocalFileSystemURL(path) + : src + node.attrs.src = url + this.vm.imgList[node.attrs.i] = path || src + } + }) + } +} + +const taskQueue = new Set() + +function download (url) { + return new Promise((resolve) => { + if (taskQueue.has(url)) return + taskQueue.add(url) + const suffix = /.+\.(jpg|jpeg|png|bmp|gif|webp)/.exec(url) + const name = `${makeid(8)}_${Date.now()}${suffix ? '.' + suffix[1] : ''}` + const task = plus.downloader.createDownload( + url, + { filename: `_doc/${data.name}/${name}` }, + (download, status) => { + taskQueue.delete(url) + resolve(status === 200 ? download.filename : null) + } + ) + task.start() + }) +} + +// 判断文件存在 +function resolveFile (url) { + return new Promise((resolve) => { + plus.io.resolveLocalFileSystemURL(url, resolve, () => resolve(null)) + }) +} + +// 生成uuid +function makeid (length) { + let result = '' + const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' + for (let i = 0; i < length; i++) { + result += characters.charAt(Math.floor(Math.random() * characters.length)) + } + return result +} +// #endif + +export default ImgCache diff --git a/src/components/mp-html/components/mp-html/markdown/index.js b/src/components/mp-html/components/mp-html/markdown/index.js new file mode 100644 index 0000000..8900403 --- /dev/null +++ b/src/components/mp-html/components/mp-html/markdown/index.js @@ -0,0 +1,34 @@ +/** + * @fileoverview markdown 插件 + * Include marked (https://github.com/markedjs/marked) + * Include github-markdown-css (https://github.com/sindresorhus/github-markdown-css) + */ +import marked from './marked.min' +let index = 0 + +function Markdown (vm) { + this.vm = vm + vm._ids = {} +} + +Markdown.prototype.onUpdate = function (content) { + if (this.vm.markdown) { + return marked(content) + } +} + +Markdown.prototype.onParse = function (node, vm) { + if (vm.options.markdown) { + // 中文 id 需要转换,否则无法跳转 + if (vm.options.useAnchor && node.attrs && /[\u4e00-\u9fa5]/.test(node.attrs.id)) { + const id = 't' + index++ + this.vm._ids[node.attrs.id] = id + node.attrs.id = id + } + if (node.name === 'p' || node.name === 'table' || node.name === 'tr' || node.name === 'th' || node.name === 'td' || node.name === 'blockquote' || node.name === 'pre' || node.name === 'code') { + node.attrs.class = `md-${node.name} ${node.attrs.class || ''}` + } + } +} + +export default Markdown diff --git a/src/components/mp-html/components/mp-html/markdown/marked.min.js b/src/components/mp-html/components/mp-html/markdown/marked.min.js new file mode 100644 index 0000000..2efcf53 --- /dev/null +++ b/src/components/mp-html/components/mp-html/markdown/marked.min.js @@ -0,0 +1,6 @@ +/*! + * marked - a markdown parser + * Copyright (c) 2011-2020, Christopher Jeffrey. (MIT Licensed) + * https://github.com/markedjs/marked + */ +function t(){"use strict";function i(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function n(e){return c[e]}var e,t=(function(t){function e(){return{baseUrl:null,breaks:!1,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:null,sanitize:!1,sanitizer:null,silent:!1,smartLists:!1,smartypants:!1,tokenizer:null,walkTokens:null,xhtml:!1}}t.exports={defaults:e(),getDefaults:e,changeDefaults:function(e){t.exports.defaults=e}}}(e={exports:{}}),e.exports),r=(t.defaults,t.getDefaults,t.changeDefaults,/[&<>"']/),l=/[&<>"']/g,a=/[<>"']|&(?!#?\w+;)/,o=/[<>"']|&(?!#?\w+;)/g,c={"&":"&","<":"<",">":">",'"':""","'":"'"};var u=/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi;function h(e){return e.replace(u,function(e,t){return"colon"===(t=t.toLowerCase())?":":"#"===t.charAt(0)?"x"===t.charAt(1)?String.fromCharCode(parseInt(t.substring(2),16)):String.fromCharCode(+t.substring(1)):""})}var g=/(^|[^\[])\^/g;var f=/[^\w:]/g,d=/^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;var k={},b=/^[^:]+:\/*[^/]*$/,m=/^([^:]+:)[\s\S]*$/,x=/^([^:]+:\/*[^/]*)[\s\S]*$/;function w(e,t){k[" "+e]||(b.test(e)?k[" "+e]=e+"/":k[" "+e]=v(e,"/",!0));var n=-1===(e=k[" "+e]).indexOf(":");return"//"===t.substring(0,2)?n?t:e.replace(m,"$1")+t:"/"===t.charAt(0)?n?t:e.replace(x,"$1")+t:e+t}function v(e,t,n){var r=e.length;if(0===r)return"";for(var i=0;it)n.splice(t);else for(;n.length>=1,e+=e;return n+e},q=t.defaults,O=v,C=R,U=_,j=T;function E(e,t,n){var r=t.href,i=t.title?U(t.title):null,t=e[1].replace(/\\([\[\]])/g,"$1");return"!"!==e[0].charAt(0)?{type:"link",raw:n,href:r,title:i,text:t}:{type:"image",raw:n,href:r,title:i,text:U(t)}}var D=function(){function e(e){this.options=e||q}var t=e.prototype;return t.space=function(e){e=this.rules.block.newline.exec(e);if(e)return 1=n.length?e.slice(n.length):e}).join("\n")}(n,t[3]||"");return{type:"code",raw:n,lang:t[2]&&t[2].trim(),text:e}}},t.heading=function(e){e=this.rules.block.heading.exec(e);if(e)return{type:"heading",raw:e[0],depth:e[1].length,text:e[2]}},t.nptable=function(e){e=this.rules.block.nptable.exec(e);if(e){var t={type:"table",header:C(e[1].replace(/^ *| *\| *$/g,"")),align:e[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:e[3]?e[3].replace(/\n$/,"").split("\n"):[],raw:e[0]};if(t.header.length===t.align.length){for(var n=t.align.length,r=0;r ?/gm,"");return{type:"blockquote",raw:t[0],text:e}}},t.list=function(e){e=this.rules.block.list.exec(e);if(e){for(var t,n,r,i,s,l=e[0],a=e[2],o=1g[0].length||3/i.test(e[0])&&(t=!1),!n&&/^<(pre|code|kbd|script)(\s|>)/i.test(e[0])?n=!0:n&&/^<\/(pre|code|kbd|script)(\s|>)/i.test(e[0])&&(n=!1),{type:this.options.sanitize?"text":"html",raw:e[0],inLink:t,inRawBlock:n,text:this.options.sanitize?this.options.sanitizer?this.options.sanitizer(e[0]):U(e[0]):e[0]}},t.link=function(e){var t=this.rules.inline.link.exec(e);if(t){e=j(t[2],"()");-1$/,"$1"))&&e.replace(this.rules.inline._escapes,"$1"),title:r&&r.replace(this.rules.inline._escapes,"$1")},t[0])}},t.reflink=function(e,t){if((n=this.rules.inline.reflink.exec(e))||(n=this.rules.inline.nolink.exec(e))){e=(n[2]||n[1]).replace(/\s+/g," ");if((e=t[e.toLowerCase()])&&e.href)return E(n,e,n[0]);var n=n[0].charAt(0);return{type:"text",raw:n,text:n}}},t.strong=function(e,t,n){void 0===n&&(n="");var r=this.rules.inline.strong.start.exec(e);if(r&&(!r[1]||r[1]&&(""===n||this.rules.inline.punctuation.exec(n)))){t=t.slice(-1*e.length);var i,s="**"===r[0]?this.rules.inline.strong.endAst:this.rules.inline.strong.endUnd;for(s.lastIndex=0;null!=(r=s.exec(t));)if(i=this.rules.inline.strong.middle.exec(t.slice(0,r.index+3)))return{type:"strong",raw:e.slice(0,i[0].length),text:e.slice(2,i[0].length-2)}}},t.em=function(e,t,n){void 0===n&&(n="");var r=this.rules.inline.em.start.exec(e);if(r&&(!r[1]||r[1]&&(""===n||this.rules.inline.punctuation.exec(n)))){t=t.slice(-1*e.length);var i,s="*"===r[0]?this.rules.inline.em.endAst:this.rules.inline.em.endUnd;for(s.lastIndex=0;null!=(r=s.exec(t));)if(i=this.rules.inline.em.middle.exec(t.slice(0,r.index+2)))return{type:"em",raw:e.slice(0,i[0].length),text:e.slice(1,i[0].length-1)}}},t.codespan=function(e){var t=this.rules.inline.code.exec(e);if(t){var n=t[2].replace(/\n/g," "),r=/[^ ]/.test(n),e=n.startsWith(" ")&&n.endsWith(" ");return r&&e&&(n=n.substring(1,n.length-1)),n=U(n,!0),{type:"codespan",raw:t[0],text:n}}},t.br=function(e){e=this.rules.inline.br.exec(e);if(e)return{type:"br",raw:e[0]}},t.del=function(e){e=this.rules.inline.del.exec(e);if(e)return{type:"del",raw:e[0],text:e[2]}},t.autolink=function(e,t){e=this.rules.inline.autolink.exec(e);if(e){var n,t="@"===e[2]?"mailto:"+(n=U(this.options.mangle?t(e[1]):e[1])):n=U(e[1]);return{type:"link",raw:e[0],text:n,href:t,tokens:[{type:"text",raw:n,text:n}]}}},t.url=function(e,t){var n,r,i,s;if(n=this.rules.inline.url.exec(e)){if("@"===n[2])i="mailto:"+(r=U(this.options.mangle?t(n[0]):n[0]));else{for(;s=n[0],n[0]=this.rules.inline._backpedal.exec(n[0])[0],s!==n[0];);r=U(n[0]),i="www."===n[1]?"http://"+r:r}return{type:"link",raw:n[0],text:r,href:i,tokens:[{type:"text",raw:r,text:r}]}}},t.inlineText=function(e,t,n){e=this.rules.inline.text.exec(e);if(e){n=t?this.options.sanitize?this.options.sanitizer?this.options.sanitizer(e[0]):U(e[0]):e[0]:U(this.options.smartypants?n(e[0]):e[0]);return{type:"text",raw:e[0],text:n}}},e}(),R=$,T=z,$=A,z={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:/^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?:\n+|$)|$)/,hr:/^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,heading:/^ {0,3}(#{1,6}) +([^\n]*?)(?: +#+)? *(?:\n+|$)/,blockquote:/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,list:/^( {0,3})(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?! {0,3}bull )\n*|\s*$)/,html:"^ {0,3}(?:<(script|pre|style)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|\\n*|$)|\\n*|$)|)[\\s\\S]*?(?:\\n{2,}|$)|<(?!script|pre|style)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:\\n{2,}|$)|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:\\n{2,}|$))",def:/^ {0,3}\[(label)\]: *\n? *]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/,nptable:R,table:R,lheading:/^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/,_paragraph:/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html)[^\n]+)*)/,text:/^[^\n]+/,_label:/(?!\s*\])(?:\\[\[\]]|[^\[\]])+/,_title:/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/};z.def=T(z.def).replace("label",z._label).replace("title",z._title).getRegex(),z.bullet=/(?:[*+-]|\d{1,9}[.)])/,z.item=/^( *)(bull) ?[^\n]*(?:\n(?! *bull ?)[^\n]*)*/,z.item=T(z.item,"gm").replace(/bull/g,z.bullet).getRegex(),z.listItemStart=T(/^( *)(bull)/).replace("bull",z.bullet).getRegex(),z.list=T(z.list).replace(/bull/g,z.bullet).replace("hr","\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def","\\n+(?="+z.def.source+")").getRegex(),z._tag="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",z._comment=/|$)/,z.html=T(z.html,"i").replace("comment",z._comment).replace("tag",z._tag).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),z.paragraph=T(z._paragraph).replace("hr",z.hr).replace("heading"," {0,3}#{1,6} ").replace("|lheading","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|!--)").replace("tag",z._tag).getRegex(),z.blockquote=T(z.blockquote).replace("paragraph",z.paragraph).getRegex(),z.normal=$({},z),z.gfm=$({},z.normal,{nptable:"^ *([^|\\n ].*\\|.*)\\n {0,3}([-:]+ *\\|[-| :]*)(?:\\n((?:(?!\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)",table:"^ *\\|(.+)\\n {0,3}\\|?( *[-:]+[-| :]*)(?:\\n *((?:(?!\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)"}),z.gfm.nptable=T(z.gfm.nptable).replace("hr",z.hr).replace("heading"," {0,3}#{1,6} ").replace("blockquote"," {0,3}>").replace("code"," {4}[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|!--)").replace("tag",z._tag).getRegex(),z.gfm.table=T(z.gfm.table).replace("hr",z.hr).replace("heading"," {0,3}#{1,6} ").replace("blockquote"," {0,3}>").replace("code"," {4}[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|!--)").replace("tag",z._tag).getRegex(),z.pedantic=$({},z.normal,{html:T("^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))").replace("comment",z._comment).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *(?:#+ *)?(?:\n+|$)/,fences:R,paragraph:T(z.normal._paragraph).replace("hr",z.hr).replace("heading"," *#{1,6} *[^\n]").replace("lheading",z.lheading).replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").getRegex()});R={escape:/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,autolink:/^<(scheme:[^\s\x00-\x1f<>]*|email)>/,url:R,tag:"^comment|^|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^",link:/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,reflink:/^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/,nolink:/^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/,reflinkSearch:"reflink|nolink(?!\\()",strong:{start:/^(?:(\*\*(?=[*punctuation]))|\*\*)(?![\s])|__/,middle:/^\*\*(?:(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)|\*(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)*?\*)+?\*\*$|^__(?![\s])((?:(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)|_(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)*?_)+?)__$/,endAst:/[^punctuation\s]\*\*(?!\*)|[punctuation]\*\*(?!\*)(?:(?=[punctuation_\s]|$))/,endUnd:/[^\s]__(?!_)(?:(?=[punctuation*\s])|$)/},em:{start:/^(?:(\*(?=[punctuation]))|\*)(?![*\s])|_/,middle:/^\*(?:(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)|\*(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)*?\*)+?\*$|^_(?![_\s])(?:(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)|_(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)*?_)+?_$/,endAst:/[^punctuation\s]\*(?!\*)|[punctuation]\*(?!\*)(?:(?=[punctuation_\s]|$))/,endUnd:/[^\s]_(?!_)(?:(?=[punctuation*\s])|$)/},code:/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,br:/^( {2,}|\\)\n(?!\s*$)/,del:R,text:/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\?@\\[\\]`^{|}~"};R.punctuation=T(R.punctuation).replace(/punctuation/g,R._punctuation).getRegex(),R._blockSkip="\\[[^\\]]*?\\]\\([^\\)]*?\\)|`[^`]*?`|<[^>]*?>",R._overlapSkip="__[^_]*?__|\\*\\*\\[^\\*\\]*?\\*\\*",R._comment=T(z._comment).replace("(?:--\x3e|$)","--\x3e").getRegex(),R.em.start=T(R.em.start).replace(/punctuation/g,R._punctuation).getRegex(),R.em.middle=T(R.em.middle).replace(/punctuation/g,R._punctuation).replace(/overlapSkip/g,R._overlapSkip).getRegex(),R.em.endAst=T(R.em.endAst,"g").replace(/punctuation/g,R._punctuation).getRegex(),R.em.endUnd=T(R.em.endUnd,"g").replace(/punctuation/g,R._punctuation).getRegex(),R.strong.start=T(R.strong.start).replace(/punctuation/g,R._punctuation).getRegex(),R.strong.middle=T(R.strong.middle).replace(/punctuation/g,R._punctuation).replace(/overlapSkip/g,R._overlapSkip).getRegex(),R.strong.endAst=T(R.strong.endAst,"g").replace(/punctuation/g,R._punctuation).getRegex(),R.strong.endUnd=T(R.strong.endUnd,"g").replace(/punctuation/g,R._punctuation).getRegex(),R.blockSkip=T(R._blockSkip,"g").getRegex(),R.overlapSkip=T(R._overlapSkip,"g").getRegex(),R._escapes=/\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g,R._scheme=/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/,R._email=/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/,R.autolink=T(R.autolink).replace("scheme",R._scheme).replace("email",R._email).getRegex(),R._attribute=/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/,R.tag=T(R.tag).replace("comment",R._comment).replace("attribute",R._attribute).getRegex(),R._label=/(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/,R._href=/<(?:\\[<>]?|[^\s<>\\])*>|[^\s\x00-\x1f]*/,R._title=/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/,R.link=T(R.link).replace("label",R._label).replace("href",R._href).replace("title",R._title).getRegex(),R.reflink=T(R.reflink).replace("label",R._label).getRegex(),R.reflinkSearch=T(R.reflinkSearch,"g").replace("reflink",R.reflink).replace("nolink",R.nolink).getRegex(),R.normal=$({},R),R.pedantic=$({},R.normal,{strong:{start:/^__|\*\*/,middle:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,endAst:/\*\*(?!\*)/g,endUnd:/__(?!_)/g},em:{start:/^_|\*/,middle:/^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,endAst:/\*(?!\*)/g,endUnd:/_(?!_)/g},link:T(/^!?\[(label)\]\((.*?)\)/).replace("label",R._label).getRegex(),reflink:T(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",R._label).getRegex()}),R.gfm=$({},R.normal,{escape:T(R.escape).replace("])","~|])").getRegex(),_extended_email:/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,url:/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,_backpedal:/(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,text:/^([`~]+|[^`~])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\'+(n?e:V(e,!0))+"\n":"
"+(n?e:V(e,!0))+"
\n"},t.blockquote=function(e){return"
\n"+e+"
\n"},t.html=function(e){return e},t.heading=function(e,t,n,r){return this.options.headerIds?"'+e+"\n":""+e+"\n"},t.hr=function(){return this.options.xhtml?"
\n":"
\n"},t.list=function(e,t,n){var r=t?"ol":"ul";return"<"+r+(t&&1!==n?' start="'+n+'"':"")+">\n"+e+"\n"},t.listitem=function(e){return"
  • "+e+"
  • \n"},t.checkbox=function(e){return" "},t.paragraph=function(e){return"

    "+e+"

    \n"},t.table=function(e,t){return"\n\n"+e+"\n"+(t=t&&""+t+"")+"
    \n"},t.tablerow=function(e){return"\n"+e+"\n"},t.tablecell=function(e,t){var n=t.header?"th":"td";return(t.align?"<"+n+' align="'+t.align+'">':"<"+n+">")+e+"\n"},t.strong=function(e){return""+e+""},t.em=function(e){return""+e+""},t.codespan=function(e){return""+e+""},t.br=function(){return this.options.xhtml?"
    ":"
    "},t.del=function(e){return""+e+""},t.link=function(e,t,n){if(null===(e=G(this.options.sanitize,this.options.baseUrl,e)))return n;e='"},t.image=function(e,t,n){if(null===(e=G(this.options.sanitize,this.options.baseUrl,e)))return n;n=''+n+'":">"},t.text=function(e){return e},e}(),J=function(){function e(){}var t=e.prototype;return t.strong=function(e){return e},t.em=function(e){return e},t.codespan=function(e){return e},t.del=function(e){return e},t.html=function(e){return e},t.text=function(e){return e},t.link=function(e,t,n){return""+n},t.image=function(e,t,n){return""+n},t.br=function(){return""},e}(),K=function(){function e(){this.seen={}}var t=e.prototype;return t.serialize=function(e){return e.toLowerCase().trim().replace(/<[!\/a-z].*?>/gi,"").replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g,"").replace(/\s/g,"-")},t.getNextSafeSlug=function(e,t){var n=e,r=0;if(this.seen.hasOwnProperty(n))for(r=this.seen[e];n=e+"-"+ ++r,this.seen.hasOwnProperty(n););return t||(this.seen[e]=r,this.seen[n]=0),n},t.slug=function(e,t){void 0===t&&(t={});var n=this.serialize(e);return this.getNextSafeSlug(n,t.dryrun)},e}(),Q=t.defaults,Y=y,ee=function(){function n(e){this.options=e||Q,this.options.renderer=this.options.renderer||new H,this.renderer=this.options.renderer,this.renderer.options=this.options,this.textRenderer=new J,this.slugger=new K}n.parse=function(e,t){return new n(t).parse(e)},n.parseInline=function(e,t){return new n(t).parseInline(e)};var e=n.prototype;return e.parse=function(e,t){void 0===t&&(t=!0);for(var n,r,i,s,l,a,o,c,u,p,h,g,f,d,k,b="",m=e.length,x=0;xAn error occurred:

    "+re(e.message+"",!0)+"
    ";throw e}}return se.options=se.setOptions=function(e){return te(se.defaults,e),ie(se.defaults),se},se.getDefaults=_,se.defaults=t,se.use=function(a){var t,n=te({},a);a.renderer&&function(){var e,l=se.defaults.renderer||new H;for(e in a.renderer)!function(i){var s=l[i];l[i]=function(){for(var e=arguments.length,t=new Array(e),n=0;nAn error occurred:

    "+re(e.message+"",!0)+"
    ";throw e}},se.Parser=ee,se.parser=ee.parse,se.Renderer=H,se.TextRenderer=J,se.Lexer=W,se.lexer=W.lex,se.Tokenizer=D,se.Slugger=K,se.parse=se};export default t(); \ No newline at end of file diff --git a/src/components/mp-html/components/mp-html/mp-html.vue b/src/components/mp-html/components/mp-html/mp-html.vue new file mode 100644 index 0000000..8476403 --- /dev/null +++ b/src/components/mp-html/components/mp-html/mp-html.vue @@ -0,0 +1,579 @@ + + + + + diff --git a/src/components/mp-html/components/mp-html/node/node.vue b/src/components/mp-html/components/mp-html/node/node.vue new file mode 100644 index 0000000..9d71b58 --- /dev/null +++ b/src/components/mp-html/components/mp-html/node/node.vue @@ -0,0 +1,1119 @@ +