mirror of
https://github.com/purocean/yn.git
synced 2026-09-24 15:46:02 +08:00
refactor: add constant
This commit is contained in:
@@ -52,6 +52,7 @@ import { revealLineInCenter } from '@fe/services/editor'
|
||||
import { showExport, toUri } from '@fe/services/document'
|
||||
import { getContextMenuItems, toggleAutoPreview } from '@fe/services/view'
|
||||
import { useContextMenu } from '@fe/support/ui/context-menu'
|
||||
import { DOM_ATTR_NAME } from '@fe/support/constant'
|
||||
import { useI18n } from '@fe/services/i18n'
|
||||
import { getLogger } from '@fe/utils'
|
||||
import type { RenderEnv } from '@fe/types'
|
||||
@@ -236,7 +237,7 @@ export default defineComponent({
|
||||
return
|
||||
}
|
||||
|
||||
const nodes = refViewWrapper.value!.querySelectorAll<HTMLElement>('.markdown-body .source-line')
|
||||
const nodes = refViewWrapper.value!.querySelectorAll<HTMLElement>(`.markdown-body [${DOM_ATTR_NAME.SOURCE_LINE_START}]`)
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
const el = nodes[i]
|
||||
const lineNumber = parseInt(el.dataset.sourceLine || '0')
|
||||
|
||||
@@ -13,6 +13,7 @@ import * as base from '@fe/services/base'
|
||||
import * as api from '@fe/support/api'
|
||||
import * as embed from '@fe/support/embed'
|
||||
import * as args from '@fe/support/args'
|
||||
import * as constant from '@fe/support/constant'
|
||||
import * as doc from '@fe/services/document'
|
||||
import * as view from '@fe/services/view'
|
||||
import * as tree from '@fe/services/tree'
|
||||
@@ -29,6 +30,7 @@ const ctx = {
|
||||
base,
|
||||
api,
|
||||
args,
|
||||
constant,
|
||||
store,
|
||||
action,
|
||||
doc,
|
||||
|
||||
@@ -11,6 +11,7 @@ import { refreshTree } from '@fe/services/tree'
|
||||
import { upload } from '@fe/services/base'
|
||||
import { isSameRepo } from '@fe/services/document'
|
||||
import { useToast } from '@fe/support/ui/toast'
|
||||
import { DOM_CLASS_NAME } from '@fe/support/constant'
|
||||
import { t } from '@fe/services/i18n'
|
||||
|
||||
async function uploadFile (file: any, asImage: boolean) {
|
||||
@@ -24,7 +25,7 @@ async function uploadFile (file: any, asImage: boolean) {
|
||||
if (asImage) {
|
||||
insert(`})\n`)
|
||||
} else {
|
||||
insert(`[${dayjs().format('YYYY-MM-DD HH:mm')}] [${file.name} (${(file.size / 1024).toFixed(2)}KiB)](${encodeMarkdownLink(assetPath)}){.open}\n`)
|
||||
insert(`[${dayjs().format('YYYY-MM-DD HH:mm')}] [${file.name} (${(file.size / 1024).toFixed(2)}KiB)](${encodeMarkdownLink(assetPath)}){.${DOM_CLASS_NAME.MARK_OPEN}}\n`)
|
||||
}
|
||||
|
||||
refreshTree()
|
||||
|
||||
@@ -40,7 +40,7 @@ const MarkdownItPlugin = (md: Markdown) => {
|
||||
},
|
||||
iframeProps: {
|
||||
...token.meta?.attrs,
|
||||
class: 'source-line applet-iframe',
|
||||
class: 'applet-iframe',
|
||||
height: '20px',
|
||||
}
|
||||
})
|
||||
|
||||
@@ -138,7 +138,7 @@ const Echarts = defineComponent({
|
||||
return h('img', { src: imgSrc.value })
|
||||
}
|
||||
|
||||
return h('div', { ...props.attrs, class: 'source-line echarts-wrapper' }, [
|
||||
return h('div', { ...props.attrs, class: 'echarts-wrapper' }, [
|
||||
h('div', { class: 'echarts-action no-print' }, [
|
||||
h('button', { class: 'small', onClick: () => exportData('png') }, 'PNG'),
|
||||
]),
|
||||
|
||||
@@ -185,7 +185,7 @@ function math_plugin (md: any, options: any) {
|
||||
options.displayMode = true
|
||||
try {
|
||||
const html = katex.renderToString(latex, options)
|
||||
return h('p', { ...token.meta?.attrs, class: 'source-line', key: html, innerHTML: html }, '')
|
||||
return h('p', { ...token.meta?.attrs, key: html, innerHTML: html }, '')
|
||||
} catch (error: any) {
|
||||
if (options.throwOnError) { console.warn(error) }
|
||||
return h('code', {}, `${error.message} [${latex}]`)
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Plugin } from '@fe/context'
|
||||
import store from '@fe/support/store'
|
||||
import { sleep } from '@fe/utils'
|
||||
import { isElectron } from '@fe/support/env'
|
||||
import { DOM_ATTR_NAME, DOM_CLASS_NAME } from '@fe/support/constant'
|
||||
import { basename, dirname, join, resolve } from '@fe/utils/path'
|
||||
import { switchDoc } from '@fe/services/document'
|
||||
import { getRepo, openExternal, openPath } from '@fe/services/base'
|
||||
@@ -27,8 +28,8 @@ const handleLink = (link: HTMLAnchorElement, view: HTMLElement) => {
|
||||
} else if (/^file:\/\//i.test(href)) {
|
||||
openPath(decodeURI(href.replace(/^file:\/\//i, '')))
|
||||
return true
|
||||
} else if (link.classList.contains('open')) {
|
||||
const path = link.getAttribute('origin-href') || decodeURI(href)
|
||||
} else if (link.classList.contains(DOM_CLASS_NAME.MARK_OPEN)) {
|
||||
const path = link.getAttribute(DOM_ATTR_NAME.ORIGIN_HREF) || decodeURI(href)
|
||||
openPath(join(getRepo(fileRepo)?.path || '/', path))
|
||||
return true
|
||||
} else { // relative link
|
||||
@@ -97,7 +98,8 @@ function convertLink (state: StateCore) {
|
||||
}
|
||||
|
||||
const link = (token: Token) => {
|
||||
const attrName = token.tag === 'a' ? 'href' : 'src'
|
||||
const isAnchor = token.tag === 'a'
|
||||
const attrName = isAnchor ? 'href' : 'src'
|
||||
const attrVal = decodeURIComponent(token.attrGet(attrName) || '')
|
||||
if (!attrVal) {
|
||||
return
|
||||
@@ -110,7 +112,7 @@ function convertLink (state: StateCore) {
|
||||
const basePath = dirname(path)
|
||||
const fileName = basename(attrVal)
|
||||
|
||||
if (token.tag === 'a') {
|
||||
if (isAnchor) {
|
||||
// keep markdown file.
|
||||
if (fileName.endsWith('.md')) {
|
||||
return
|
||||
@@ -122,10 +124,13 @@ function convertLink (state: StateCore) {
|
||||
}
|
||||
|
||||
// open other file in os
|
||||
token.attrPush(['class', 'open'])
|
||||
token.attrPush(['class', DOM_CLASS_NAME.MARK_OPEN])
|
||||
} else {
|
||||
token.attrSet(DOM_ATTR_NAME.LOCAL_IMAGE, 'true')
|
||||
}
|
||||
|
||||
token.attrSet(`origin-${attrName}`, attrVal)
|
||||
const originAttr = isAnchor ? DOM_ATTR_NAME.ORIGIN_HREF : DOM_ATTR_NAME.ORIGIN_SRC
|
||||
token.attrSet(originAttr, attrVal)
|
||||
|
||||
const val = attrVal.replace(/[#?].*$/, '')
|
||||
|
||||
@@ -166,15 +171,15 @@ export default {
|
||||
}
|
||||
|
||||
ctx.registerHook('VIEW_ON_GET_HTML_FILTER_NODE', async ({ node, options }) => {
|
||||
const srcAttr = node.getAttribute('src')
|
||||
// local image
|
||||
if (srcAttr?.startsWith('api/')) {
|
||||
const srcAttr = node.getAttribute('src')
|
||||
if (srcAttr && node.getAttribute(DOM_ATTR_NAME.LOCAL_IMAGE)) {
|
||||
if (options.inlineLocalImage) {
|
||||
try {
|
||||
const res: Response = await ctx.api.fetchHttp(srcAttr)
|
||||
const base64Url = await ctx.utils.fileToBase64URL(await res.blob())
|
||||
node.setAttribute('src', base64Url)
|
||||
node.removeAttribute('origin-src')
|
||||
node.removeAttribute(DOM_ATTR_NAME.ORIGIN_SRC)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
@@ -183,10 +188,10 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
const originSrc = node.getAttribute('origin-src')
|
||||
const originSrc = node.getAttribute(DOM_ATTR_NAME.ORIGIN_SRC)
|
||||
if (originSrc) {
|
||||
node.setAttribute('src', originSrc)
|
||||
node.removeAttribute('origin-src')
|
||||
node.removeAttribute(DOM_ATTR_NAME.ORIGIN_SRC)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import { refreshTree } from '@fe/services/tree'
|
||||
import { buildSrc, IFrame } from '@fe/support/embed'
|
||||
import { getCurrentLanguage, t, useI18n } from '@fe/services/i18n'
|
||||
import { FLAG_DEMO } from '@fe/support/args'
|
||||
import { DOM_ATTR_NAME } from '@fe/support/constant'
|
||||
import Mask from '@fe/components/Mask.vue'
|
||||
|
||||
const logger = getLogger('plugin-markdown-luckysheet')
|
||||
@@ -330,7 +331,7 @@ const MarkdownItPlugin = (md: Markdown) => {
|
||||
return linkTemp(tokens, idx, options, env, slf)
|
||||
}
|
||||
|
||||
const url = token.attrGet('origin-href')
|
||||
const url = token.attrGet(DOM_ATTR_NAME.ORIGIN_HREF)
|
||||
if (!url || url.includes(':')) {
|
||||
return linkTemp(tokens, idx, options, env, slf)
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ const Mermaid = defineComponent({
|
||||
onMounted(() => setTimeout(render, 0))
|
||||
|
||||
return () => {
|
||||
return h('div', { ...props.attrs, class: 'source-line mermaid-wrapper' }, [
|
||||
return h('div', { ...props.attrs, class: 'mermaid-wrapper' }, [
|
||||
h('div', { class: 'mermaid-action no-print' }, [
|
||||
h('button', { class: 'small', onClick: () => exportData() }, 'SVG'),
|
||||
]),
|
||||
|
||||
@@ -367,7 +367,7 @@ const MindMap = defineComponent({
|
||||
removeHook('I18N_CHANGE_LANGUAGE', onLanguageChange)
|
||||
})
|
||||
|
||||
return () => h('div', { ...props.attrs, ref: container, class: 'source-line mind-map reduce-brightness' })
|
||||
return () => h('div', { ...props.attrs, ref: container, class: 'mind-map reduce-brightness' })
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -193,7 +193,7 @@ const Plantuml = defineComponent({
|
||||
...props.attrs,
|
||||
ref: img,
|
||||
alt: 'plantuml',
|
||||
class: 'source-line plantuml-img',
|
||||
class: 'plantuml-img',
|
||||
style,
|
||||
src: src.value,
|
||||
onLoad
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { createVNode, Fragment, Comment, Text, VNode } from 'vue'
|
||||
import Token from 'markdown-it/lib/token'
|
||||
import Renderer from 'markdown-it/lib/renderer'
|
||||
import type Token from 'markdown-it/lib/token'
|
||||
import type Renderer from 'markdown-it/lib/renderer'
|
||||
import { escapeHtml, unescapeAll } from 'markdown-it/lib/common/utils'
|
||||
import { Plugin } from '@fe/context'
|
||||
import { DOM_ATTR_NAME } from '@fe/support/constant'
|
||||
import type { Plugin } from '@fe/context'
|
||||
|
||||
const attrNameReg = /^[a-zA-Z_:][a-zA-Z0-9:._-]*$/
|
||||
const defaultRules = {} as any
|
||||
@@ -36,9 +37,8 @@ export function setSourceLine (token: Token, env?: Record<string, any>) {
|
||||
const [lineStart, lineEnd] = getLine(token, env)
|
||||
|
||||
if (token.map) {
|
||||
token.attrJoin('class', 'source-line')
|
||||
token.attrSet('data-source-line', String(lineStart + 1))
|
||||
token.attrSet('data-source-line-end', String(lineEnd + 1))
|
||||
token.attrSet(DOM_ATTR_NAME.SOURCE_LINE_START, String(lineStart + 1))
|
||||
token.attrSet(DOM_ATTR_NAME.SOURCE_LINE_END, String(lineEnd + 1))
|
||||
if (!token.meta.attrs) {
|
||||
token.meta.attrs = {}
|
||||
}
|
||||
@@ -58,9 +58,17 @@ defaultRules.code_inline = function (tokens: Token[], idx: number, _: any, __: a
|
||||
defaultRules.code_block = function (tokens: Token[], idx: number, _: any, __: any, slf: Renderer) {
|
||||
const token = tokens[idx]
|
||||
const attrs: any = slf.renderAttrs(token)
|
||||
const preAttrs = {
|
||||
[DOM_ATTR_NAME.SOURCE_LINE_START]: attrs[DOM_ATTR_NAME.SOURCE_LINE_START],
|
||||
[DOM_ATTR_NAME.SOURCE_LINE_END]: attrs[DOM_ATTR_NAME.SOURCE_LINE_END],
|
||||
}
|
||||
|
||||
delete attrs[DOM_ATTR_NAME.SOURCE_LINE_START]
|
||||
delete attrs[DOM_ATTR_NAME.SOURCE_LINE_END]
|
||||
|
||||
return createVNode(
|
||||
'pre',
|
||||
{},
|
||||
preAttrs,
|
||||
[createVNode('code', attrs, [createVNode(Text, {}, token.content)])]
|
||||
)
|
||||
}
|
||||
@@ -88,11 +96,23 @@ defaultRules.fence = function (tokens: Token[], idx: number, options: any, _: an
|
||||
return highlighted + '\n'
|
||||
}
|
||||
|
||||
const buildVNode = (attrs: any) => createVNode(
|
||||
'pre',
|
||||
{ 'data-info': info, 'data-lang': langName },
|
||||
[createVNode('code', { key: highlighted, ...attrs, innerHTML: highlighted }, [])]
|
||||
)
|
||||
const buildVNode = (attrs: any) => {
|
||||
const preAttrs = {
|
||||
'data-info': info,
|
||||
'data-lang': langName,
|
||||
[DOM_ATTR_NAME.SOURCE_LINE_START]: attrs[DOM_ATTR_NAME.SOURCE_LINE_START],
|
||||
[DOM_ATTR_NAME.SOURCE_LINE_END]: attrs[DOM_ATTR_NAME.SOURCE_LINE_END],
|
||||
}
|
||||
|
||||
delete attrs[DOM_ATTR_NAME.SOURCE_LINE_START]
|
||||
delete attrs[DOM_ATTR_NAME.SOURCE_LINE_END]
|
||||
|
||||
return createVNode(
|
||||
'pre',
|
||||
preAttrs,
|
||||
[createVNode('code', { key: highlighted, ...attrs, innerHTML: highlighted }, [])]
|
||||
)
|
||||
}
|
||||
|
||||
// If language exists, inject class gently, without modifying original token.
|
||||
// May be, one day we will add .deepClone() for token and simplify this part, but
|
||||
@@ -272,9 +292,5 @@ export default {
|
||||
md.renderer.renderAttrs = renderAttrs
|
||||
md.renderer.renderToken = renderToken
|
||||
})
|
||||
|
||||
ctx.registerHook('VIEW_ON_GET_HTML_FILTER_NODE', ({ node }) => {
|
||||
node.classList.remove('source-line')
|
||||
})
|
||||
}
|
||||
} as Plugin
|
||||
|
||||
@@ -39,7 +39,7 @@ export default {
|
||||
return true
|
||||
}
|
||||
|
||||
if (target.tagName === 'INPUT' && target.parentElement!.classList.contains('source-line')) {
|
||||
if (target.tagName === 'INPUT' && target.parentElement!.dataset.sourceLine) {
|
||||
const line = parseInt(target.parentElement!.dataset.sourceLine || '0')
|
||||
const checked = (target as HTMLInputElement).checked
|
||||
ctx.action.getActionHandler(actionName)(line, checked)
|
||||
|
||||
@@ -66,7 +66,7 @@ export default {
|
||||
if (
|
||||
ctx.store.state.showEditor &&
|
||||
!ctx.store.state.presentation &&
|
||||
target.classList.contains('source-line') &&
|
||||
target.dataset.sourceLine &&
|
||||
window.getSelection()!.toString().length < 1
|
||||
) {
|
||||
ctx.view.disableSyncScrollAwhile(() => {
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
export const DOM_ATTR_NAME = {
|
||||
SOURCE_LINE_START: 'data-source-line',
|
||||
SOURCE_LINE_END: 'data-source-line-end',
|
||||
ORIGIN_SRC: 'origin-src',
|
||||
ORIGIN_HREF: 'origin-href',
|
||||
LOCAL_IMAGE: 'local-image',
|
||||
}
|
||||
|
||||
export const DOM_CLASS_NAME = {
|
||||
MARK_OPEN: 'open'
|
||||
}
|
||||
Reference in New Issue
Block a user