diff --git a/src/component/MenuLeft/Setting.js b/src/component/MenuLeft/Setting.js index 573b8324..9d7bf85a 100644 --- a/src/component/MenuLeft/Setting.js +++ b/src/component/MenuLeft/Setting.js @@ -3,6 +3,7 @@ import {Menu, Dropdown} from "antd"; import SyncScroll from "./Setting/SyncScroll"; import ContainImgName from "./Setting/ContainImgName"; +import Link2xwl from "./Setting/Link2xwl"; import "./common.css"; @@ -14,6 +15,9 @@ const menu = ( + + + ); diff --git a/src/component/MenuLeft/Setting/Link2xwl.js b/src/component/MenuLeft/Setting/Link2xwl.js new file mode 100644 index 00000000..b7680ebc --- /dev/null +++ b/src/component/MenuLeft/Setting/Link2xwl.js @@ -0,0 +1,27 @@ +import React, {Component} from "react"; +import {observer, inject} from "mobx-react"; + +import {RIGHT_SYMBOL} from "../../../utils/constant"; +import "../common.css"; + +@inject("navbar") +@observer +class Link2xwl extends Component { + handleClick = () => { + const {isLink2xwl} = this.props.navbar; + this.props.navbar.setLink2xwl(!isLink2xwl); + }; + + render() { + return ( +
+ + {this.props.navbar.isLink2xwl && {RIGHT_SYMBOL}} + 微信外链支持[小外链] + +
+ ); + } +} + +export default Link2xwl; diff --git a/src/store/navbar.js b/src/store/navbar.js index 7c036e3c..a658909a 100644 --- a/src/store/navbar.js +++ b/src/store/navbar.js @@ -7,6 +7,7 @@ import { PREVIEW_TYPE, IS_SYNC_SCROLL, IS_CONTAIN_IMG_NAME, + IS_LINK_2_XWL, IS_MAC_CODE, } from "../utils/constant"; import TEMPLATE from "../template/index"; @@ -19,6 +20,9 @@ class Navbar { // 是否保留图片名称 @observable isContainImgName = false; + // 是否保留图片名称 + @observable isLink2xwl = false; + // 主题序号 @observable templateNum; @@ -43,6 +47,12 @@ class Navbar { window.localStorage.setItem(IS_CONTAIN_IMG_NAME, isContainImgName); }; + @action + setLink2xwl = (isLink2xwl) => { + this.isLink2xwl = isLink2xwl; + window.localStorage.setItem(IS_LINK_2_XWL, isLink2xwl); + }; + @action setTemplateNum = (templateNum) => { this.templateNum = templateNum; @@ -100,6 +110,10 @@ if (!window.localStorage.getItem(IS_CONTAIN_IMG_NAME)) { window.localStorage.setItem(IS_CONTAIN_IMG_NAME, false); } +if (!window.localStorage.getItem(IS_LINK_2_XWL)) { + window.localStorage.setItem(IS_LINK_2_XWL, false); +} + if (!window.localStorage.getItem(IS_MAC_CODE)) { window.localStorage.setItem(IS_MAC_CODE, false); } @@ -115,6 +129,7 @@ store.codeNum = parseInt(window.localStorage.getItem(CODE_NUM), 10); store.previewType = window.localStorage.getItem(PREVIEW_TYPE); store.isSyncScroll = window.localStorage.getItem(IS_SYNC_SCROLL) === "true"; store.isContainImgName = window.localStorage.getItem(IS_CONTAIN_IMG_NAME) === "true"; +store.isLink2xwl = window.localStorage.getItem(IS_LINK_2_XWL) === "true"; store.isMacCode = window.localStorage.getItem(IS_MAC_CODE) === "true"; // 初始化代码主题 diff --git a/src/utils/constant.js b/src/utils/constant.js index c81fec7c..771c0310 100644 --- a/src/utils/constant.js +++ b/src/utils/constant.js @@ -25,6 +25,7 @@ export const THEME_LIST = "theme_list"; export const PREVIEW_TYPE = "preview_type"; export const IS_SYNC_SCROLL = "is_sync_scroll"; export const IS_CONTAIN_IMG_NAME = "is_contain_img_name"; +export const IS_LINK_2_XWL = "is_link_2_xwl"; export const IS_MAC_CODE = "is_mac_code"; export const NEWEST_VERSION = "newest_version"; export const ALIOSS_IMAGE_HOSTING = "alioss_image_hosting"; diff --git a/src/utils/helper.js b/src/utils/helper.js index ad7c8363..b8989500 100644 --- a/src/utils/helper.js +++ b/src/utils/helper.js @@ -8,6 +8,7 @@ import markdownItRuby from "markdown-it-ruby"; import markdownItImsize from "markdown-it-imsize"; import markdownItSpan from "./markdown-it-span"; +import markdownItLink2xwl from "./markdown-it-link2xwl"; import markdownItTableContainer from "./markdown-it-table-container"; import markdownItLinkfoot from "./markdown-it-linkfoot"; import markdownItImageFlow from "./markdown-it-imageflow"; @@ -94,7 +95,8 @@ markdownParser .use(markdownItLiReplacer) // li 标签中加入 p 标签 .use(markdownItImageFlow) // 横屏移动插件 .use(markdownItMultiquote) // 给多级引用加 class - .use(markdownItImsize); + .use(markdownItImsize) + .use(markdownItLink2xwl); export const replaceStyle = (id, css) => { const style = document.getElementById(id); diff --git a/src/utils/markdown-it-link2xwl.js b/src/utils/markdown-it-link2xwl.js new file mode 100644 index 00000000..9745684b --- /dev/null +++ b/src/utils/markdown-it-link2xwl.js @@ -0,0 +1,71 @@ +import {IS_LINK_2_XWL} from "./constant"; + +("use strict"); + +// Adapted from https://github.com/markdown-it/markdown-it/blob/fbc6b0fed563ba7c00557ab638fd19752f8e759d/docs/architecture.md + +function applyAttributes(idx, tokens, attributes) { + var href = tokens[idx].attrs[tokens[idx].attrIndex("href")][1]; + Object.keys(attributes).forEach(function(attr) { + var attrIndex; + var value = attributes[attr]; + + if (attr === "className") { + // when dealing with applying classes + // programatically, some programmers + // may prefer to use the className syntax + attr = "class"; + } + + // go?to=https://new.qq.com/omn/20201027/20201027A04Q7A00.html + if (attr === "data-miniprogram-path") { + value = "go?to=" + encodeURIComponent(href); + } + + attrIndex = tokens[idx].attrIndex(attr); + + if (attrIndex < 0) { + // attr doesn't exist, add new attribute + tokens[idx].attrPush([attr, value]); + } else { + // attr already exists, overwrite it + tokens[idx].attrs[attrIndex][1] = value; // replace value of existing attr + } + }); +} + +export default function markdownitLinkAttributes(md, configs) { + configs = { + attrs: { + "data-miniprogram-appid": "wxe81de4a47ea1ab33", + "data-miniprogram-path": "", + "data-miniprogram-nickname": "小外链", + "data-miniprogram-type": "text", + "data-miniprogram-servicetype": "", + }, + }; + + if (!configs) { + configs = []; + } else { + configs = Array.isArray(configs) ? configs : [configs]; + } + + Object.freeze(configs); + + var defaultRender = md.renderer.rules.link_open || this.defaultRender; + + md.renderer.rules.link_open = function(tokens, idx, options, env, self) { + var isLink2xwl = window.localStorage.getItem(IS_LINK_2_XWL); + if (configs.attrs && isLink2xwl !== "false") { + applyAttributes(idx, tokens, configs.attrs); + } + + // pass token to default renderer. + return defaultRender(tokens, idx, options, env, self); + }; +} + +markdownitLinkAttributes.defaultRender = function(tokens, idx, options, env, self) { + return self.renderToken(tokens, idx, options); +};