@jx3box/jx3box-editor 3.2.1 → 3.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/global.less +1 -0
- package/package.json +7 -7
- package/src/Article.vue +23 -23
- package/src/ArticleMarkdown.vue +17 -17
- package/src/BoxResource.vue +3 -3
- package/src/GameText.vue +1 -1
- package/src/ItemSimple.vue +1 -1
- package/src/Markdown.vue +1 -1
- package/src/Resource.vue +1 -1
- package/src/Tinymce.vue +3 -3
- package/src/Upload.vue +1 -1
- package/src/assets/css/tinymce/h.less +35 -9
- package/src/assets/css/tinymce/nextpage.less +1 -0
- package/src/assets/css/tinymce/pz.less +0 -5
- package/src/assets/css/tinymce/table.less +4 -4
- package/src/assets/js/katex.js +193 -142
- package/src/assets/js/pz_iframe.js +11 -11
- package/src/components/Author.vue +2 -2
- package/src/components/Combo.vue +1 -1
- package/src/components/PostAuthor.vue +1 -1
- package/src/components/SkillMartial.vue +1 -1
package/config/global.less
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jx3box/jx3box-editor",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.3",
|
|
4
4
|
"description": "JX3BOX Article & Editor",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@element-plus/icons-vue": "^2.0.10",
|
|
17
17
|
"@imengyu/vue3-context-menu": "^1.5.4",
|
|
18
|
-
"@jx3box/jx3box-common": "^9.2.
|
|
19
|
-
"@jx3box/jx3box-data": "^3.9.
|
|
20
|
-
"@jx3box/jx3box-emotion": "^1.3.
|
|
21
|
-
"@jx3box/jx3box-macro": "^1.0.
|
|
22
|
-
"@jx3box/jx3box-talent": "^1.3.
|
|
18
|
+
"@jx3box/jx3box-common": "^9.2.1",
|
|
19
|
+
"@jx3box/jx3box-data": "^3.9.4",
|
|
20
|
+
"@jx3box/jx3box-emotion": "^1.3.0",
|
|
21
|
+
"@jx3box/jx3box-macro": "^1.0.3",
|
|
22
|
+
"@jx3box/jx3box-talent": "^1.3.13",
|
|
23
23
|
"@tinymce/tinymce-vue": "^5.0.0",
|
|
24
24
|
"axios": "^0.19.2",
|
|
25
25
|
"cheerio": "^1.1.2",
|
|
@@ -89,6 +89,6 @@
|
|
|
89
89
|
},
|
|
90
90
|
"repository": {
|
|
91
91
|
"type": "git",
|
|
92
|
-
"url": "git+https://github.com/
|
|
92
|
+
"url": "git+https://github.com/JX3BOX/jx3box-editor.git"
|
|
93
93
|
}
|
|
94
94
|
}
|
package/src/Article.vue
CHANGED
|
@@ -59,38 +59,38 @@ import Vditor from "vditor";
|
|
|
59
59
|
import "github-markdown-css/github-markdown-light.css";
|
|
60
60
|
|
|
61
61
|
// XSS
|
|
62
|
-
import execFilterXSS from "./assets/js/xss
|
|
62
|
+
import execFilterXSS from "./assets/js/xss";
|
|
63
63
|
|
|
64
64
|
// 基本文本
|
|
65
|
-
import execLazyload from "./assets/js/img
|
|
66
|
-
import execFilterIframe from "./assets/js/iframe
|
|
67
|
-
import execFilterLink from "./assets/js/a
|
|
68
|
-
import execSplitPages from "./assets/js/nextpage
|
|
69
|
-
import normalizeMarkdownForVditor from "./assets/js/normalizeMarkdownForVditor
|
|
65
|
+
import execLazyload from "./assets/js/img";
|
|
66
|
+
import execFilterIframe from "./assets/js/iframe";
|
|
67
|
+
import execFilterLink from "./assets/js/a";
|
|
68
|
+
import execSplitPages from "./assets/js/nextpage";
|
|
69
|
+
import normalizeMarkdownForVditor from "./assets/js/normalizeMarkdownForVditor";
|
|
70
70
|
|
|
71
71
|
// 扩展文本
|
|
72
|
-
import renderFoldBlock from "./assets/js/fold
|
|
73
|
-
import renderDirectory from "./assets/js/directory
|
|
74
|
-
import renderKatex from "./assets/js/katex
|
|
75
|
-
import renderCode from "./assets/js/code
|
|
76
|
-
import renderImgPreview from "./assets/js/renderImgPreview
|
|
72
|
+
import renderFoldBlock from "./assets/js/fold";
|
|
73
|
+
import renderDirectory from "./assets/js/directory";
|
|
74
|
+
import renderKatex from "./assets/js/katex";
|
|
75
|
+
import renderCode from "./assets/js/code";
|
|
76
|
+
import renderImgPreview from "./assets/js/renderImgPreview";
|
|
77
77
|
|
|
78
78
|
// 魔盒
|
|
79
|
-
import renderMacro from "./assets/js/macro
|
|
80
|
-
import renderTalent from "./assets/js/qixue
|
|
81
|
-
import renderTalent2 from "./assets/js/talent2
|
|
82
|
-
import renderPzIframe from "./assets/js/pz_iframe
|
|
83
|
-
import renderCombo from "./assets/js/combo
|
|
84
|
-
import renderAudio from "./assets/js/audio
|
|
85
|
-
import Author from "./components/Author
|
|
79
|
+
import renderMacro from "./assets/js/macro";
|
|
80
|
+
import renderTalent from "./assets/js/qixue";
|
|
81
|
+
import renderTalent2 from "./assets/js/talent2";
|
|
82
|
+
import renderPzIframe from "./assets/js/pz_iframe";
|
|
83
|
+
import renderCombo from "./assets/js/combo";
|
|
84
|
+
import renderAudio from "./assets/js/audio";
|
|
85
|
+
import Author from "./components/Author";
|
|
86
86
|
import PostAuthor from "./components/PostAuthor.vue";
|
|
87
87
|
|
|
88
88
|
// 剑三
|
|
89
|
-
import Item from "./Item
|
|
90
|
-
import Buff from "./Buff
|
|
91
|
-
import Skill from "./Skill
|
|
92
|
-
import Npc from "./Npc
|
|
93
|
-
import renderJx3Element from "./assets/js/jx3_element
|
|
89
|
+
import Item from "./Item";
|
|
90
|
+
import Buff from "./Buff";
|
|
91
|
+
import Skill from "./Skill";
|
|
92
|
+
import Npc from "./Npc";
|
|
93
|
+
import renderJx3Element from "./assets/js/jx3_element";
|
|
94
94
|
|
|
95
95
|
export default {
|
|
96
96
|
name: "Article",
|
package/src/ArticleMarkdown.vue
CHANGED
|
@@ -27,27 +27,27 @@
|
|
|
27
27
|
import markdownRender from "@jx3box/markdown/src/render.vue";
|
|
28
28
|
|
|
29
29
|
// 基本文本
|
|
30
|
-
import execLazyload from "./assets/js/img
|
|
31
|
-
import execFilterIframe from "./assets/js/iframe
|
|
32
|
-
import execFilterLink from "./assets/js/a
|
|
33
|
-
import execFilterXSS from "./assets/js/script
|
|
30
|
+
import execLazyload from "./assets/js/img";
|
|
31
|
+
import execFilterIframe from "./assets/js/iframe";
|
|
32
|
+
import execFilterLink from "./assets/js/a";
|
|
33
|
+
import execFilterXSS from "./assets/js/script";
|
|
34
34
|
|
|
35
35
|
// 扩展文本
|
|
36
|
-
import renderDirectory from "./assets/js/directory
|
|
37
|
-
import renderMacro from "./assets/js/macro
|
|
38
|
-
import renderTalent from "./assets/js/qixue
|
|
39
|
-
import renderTalent2 from "./assets/js/talent2
|
|
40
|
-
import renderKatexAll from "./assets/js/katex
|
|
41
|
-
import renderCode from "./assets/js/code
|
|
36
|
+
import renderDirectory from "./assets/js/directory";
|
|
37
|
+
import renderMacro from "./assets/js/macro";
|
|
38
|
+
import renderTalent from "./assets/js/qixue";
|
|
39
|
+
import renderTalent2 from "./assets/js/talent2";
|
|
40
|
+
import { renderKatexAll } from "./assets/js/katex";
|
|
41
|
+
import renderCode from "./assets/js/code";
|
|
42
42
|
|
|
43
43
|
// 剑三
|
|
44
|
-
import Item from "./Item
|
|
45
|
-
import Buff from "./Buff
|
|
46
|
-
import Skill from "./Skill
|
|
47
|
-
import Npc from "./Npc
|
|
48
|
-
import renderJx3Element from "./assets/js/jx3_element
|
|
49
|
-
import renderImgPreview from "./assets/js/renderImgPreview
|
|
50
|
-
import renderAudio from "./assets/js/audio
|
|
44
|
+
import Item from "./Item";
|
|
45
|
+
import Buff from "./Buff";
|
|
46
|
+
import Skill from "./Skill";
|
|
47
|
+
import Npc from "./Npc";
|
|
48
|
+
import renderJx3Element from "./assets/js/jx3_element";
|
|
49
|
+
import renderImgPreview from "./assets/js/renderImgPreview";
|
|
50
|
+
import renderAudio from "./assets/js/audio";
|
|
51
51
|
|
|
52
52
|
import { xssOptions } from "./assets/data/markdown_whitelist.json";
|
|
53
53
|
|
package/src/BoxResource.vue
CHANGED
|
@@ -190,9 +190,9 @@
|
|
|
190
190
|
</template>
|
|
191
191
|
|
|
192
192
|
<script>
|
|
193
|
-
import { loadStat } from "./service/database
|
|
194
|
-
import { loadAuthors, loadEmotions, getLetterPaper } from "./service/cms
|
|
195
|
-
import { getUserInfo } from "./service/author
|
|
193
|
+
import { loadStat } from "./service/database";
|
|
194
|
+
import { loadAuthors, loadEmotions, getLetterPaper } from "./service/cms";
|
|
195
|
+
import { getUserInfo } from "./service/author";
|
|
196
196
|
import JX3BOX from "@jx3box/jx3box-common/data/jx3box.json";
|
|
197
197
|
import { getLink, showAvatar, resolveImagePath } from "@jx3box/jx3box-common/js/utils";
|
|
198
198
|
import User from "@jx3box/jx3box-common/js/user";
|
package/src/GameText.vue
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
<script>
|
|
13
13
|
import { extractTextContent, getLink, iconLink } from "@jx3box/jx3box-common/js/utils";
|
|
14
|
-
import { getResource as getResourceFromNode } from "./service/resource
|
|
14
|
+
import { getResource as getResourceFromNode } from "./service/resource";
|
|
15
15
|
import { escape } from "lodash";
|
|
16
16
|
import gameFonts from "./assets/data/game_font.json";
|
|
17
17
|
|
package/src/ItemSimple.vue
CHANGED
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
</template>
|
|
39
39
|
|
|
40
40
|
<script>
|
|
41
|
-
import Item from "./Item
|
|
41
|
+
import Item from "./Item";
|
|
42
42
|
import icon_url from "./assets/js/item/icon_url.js";
|
|
43
43
|
import item_color from "./assets/js/item/color.js";
|
|
44
44
|
import item_border from "./assets/js/item/border.js";
|
package/src/Markdown.vue
CHANGED
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
import Vditor from "vditor";
|
|
36
36
|
import "vditor/dist/index.css";
|
|
37
37
|
import "github-markdown-css/github-markdown-light.css";
|
|
38
|
-
import normalizeMarkdownForVditor from "./assets/js/normalizeMarkdownForVditor
|
|
38
|
+
import normalizeMarkdownForVditor from "./assets/js/normalizeMarkdownForVditor";
|
|
39
39
|
|
|
40
40
|
const { __cms } = JX3BOX;
|
|
41
41
|
const UPLOAD_API = `${__cms}api/cms/upload`;
|
package/src/Resource.vue
CHANGED
|
@@ -286,7 +286,7 @@
|
|
|
286
286
|
|
|
287
287
|
<script>
|
|
288
288
|
import { ArrowDown, Histogram } from "@element-plus/icons-vue";
|
|
289
|
-
import { loadResource, loadStat, getIcons } from "./service/database
|
|
289
|
+
import { loadResource, loadStat, getIcons } from "./service/database";
|
|
290
290
|
import JX3BOX from "@jx3box/jx3box-common/data/jx3box.json";
|
|
291
291
|
import detach_types from "./assets/data/detach_type.json";
|
|
292
292
|
import { iconLink, getLink as resolveLink } from "@jx3box/jx3box-common/js/utils";
|
package/src/Tinymce.vue
CHANGED
|
@@ -42,9 +42,9 @@ const { __cdn, __imgPath, __cms } = JX3BOX;
|
|
|
42
42
|
// 开发环境走 devServer proxy,避免跨域导致粘贴图片上传“看起来没反应”
|
|
43
43
|
const apiUrl = process.env.NODE_ENV === "development" ? "/api/cms/upload/tinymce" : __cms + "api/cms/upload/tinymce";
|
|
44
44
|
|
|
45
|
-
import Upload from "./Upload
|
|
46
|
-
import Resource from "./Resource
|
|
47
|
-
import BoxResource from "./BoxResource
|
|
45
|
+
import Upload from "./Upload";
|
|
46
|
+
import Resource from "./Resource";
|
|
47
|
+
import BoxResource from "./BoxResource";
|
|
48
48
|
import Emotion from "@jx3box/jx3box-emotion/src/Emotion.vue";
|
|
49
49
|
|
|
50
50
|
import axios from "axios";
|
package/src/Upload.vue
CHANGED
|
@@ -88,7 +88,7 @@ import axios from "axios";
|
|
|
88
88
|
import { Delete, Plus, UploadFilled, ZoomIn } from "@element-plus/icons-vue";
|
|
89
89
|
import JX3BOX from "@jx3box/jx3box-common/data/jx3box.json";
|
|
90
90
|
import allow_types from "@jx3box/jx3box-common/data/conf";
|
|
91
|
-
import { showImgPreview } from "./assets/js/renderImgPreview
|
|
91
|
+
import { showImgPreview } from "./assets/js/renderImgPreview";
|
|
92
92
|
const { __cms } = JX3BOX;
|
|
93
93
|
const API = __cms + "api/cms/upload";
|
|
94
94
|
const imgtypes = ["jpg", "png", "gif", "bmp", "webp", "jpeg", "svg"];
|
|
@@ -32,12 +32,11 @@
|
|
|
32
32
|
|
|
33
33
|
h4 {
|
|
34
34
|
font-size: 15px;
|
|
35
|
-
padding: 8px 10px;
|
|
35
|
+
padding: 8px 10px 8px 20px;
|
|
36
36
|
|
|
37
37
|
background-color: #fafbfc;
|
|
38
38
|
border-radius: 6px;
|
|
39
|
-
border-left:4px solid @primary;
|
|
40
|
-
|
|
39
|
+
// border-left:4px solid @primary;
|
|
41
40
|
|
|
42
41
|
position: relative;
|
|
43
42
|
overflow: hidden;
|
|
@@ -45,17 +44,39 @@
|
|
|
45
44
|
// border: 1px solid @primary;
|
|
46
45
|
&::before {
|
|
47
46
|
content: "";
|
|
48
|
-
font-size: 20px;
|
|
49
47
|
display: block;
|
|
50
48
|
position: absolute;
|
|
51
|
-
width:
|
|
52
|
-
height:
|
|
53
|
-
top:
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
width: 5px;
|
|
50
|
+
height: 60%;
|
|
51
|
+
top: 50%;
|
|
52
|
+
transform: translateY(-50%);
|
|
53
|
+
left: 10px;
|
|
54
|
+
background-color: @primary;
|
|
55
|
+
border-radius: 10px;
|
|
56
|
+
transition: all 0.2s ease;
|
|
56
57
|
// border-bottom-right-radius: 20px;
|
|
57
58
|
// border-bottom-left-radius: 20px;
|
|
58
59
|
}
|
|
60
|
+
// &::after {
|
|
61
|
+
// content: "";
|
|
62
|
+
// display: block;
|
|
63
|
+
// position: absolute;
|
|
64
|
+
// width: 5px;
|
|
65
|
+
// height: 60%;
|
|
66
|
+
// top: 50%;
|
|
67
|
+
// transform: translateY(-50%);
|
|
68
|
+
// left: 10px;
|
|
69
|
+
// background-color: @v4yellow;
|
|
70
|
+
// border-radius: 10px;
|
|
71
|
+
// z-index: 2;
|
|
72
|
+
// display: none;
|
|
73
|
+
// }
|
|
74
|
+
|
|
75
|
+
&:hover {
|
|
76
|
+
&::before {
|
|
77
|
+
background-color: @v4yellow;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
59
80
|
}
|
|
60
81
|
|
|
61
82
|
h5 {
|
|
@@ -74,6 +95,11 @@
|
|
|
74
95
|
bottom: -1px;
|
|
75
96
|
left: 0;
|
|
76
97
|
}
|
|
98
|
+
&:hover{
|
|
99
|
+
&::after {
|
|
100
|
+
background-color: @v4yellow;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
77
103
|
}
|
|
78
104
|
|
|
79
105
|
h6 {
|
|
@@ -12,17 +12,17 @@
|
|
|
12
12
|
line-height:2.2;
|
|
13
13
|
color:@color;
|
|
14
14
|
|
|
15
|
-
td,
|
|
16
|
-
th {
|
|
15
|
+
td,th {
|
|
17
16
|
padding: 6px 10px;
|
|
18
|
-
}
|
|
19
|
-
td {
|
|
20
17
|
border: 1px solid #eee;
|
|
21
18
|
}
|
|
22
19
|
th {
|
|
23
20
|
background-color: #fafbfc;
|
|
24
21
|
font-weight: 500;
|
|
25
22
|
}
|
|
23
|
+
tr{
|
|
24
|
+
background-color:#fff;
|
|
25
|
+
}
|
|
26
26
|
tr:nth-child(2n + 1) {
|
|
27
27
|
background-color: #fafbfc;
|
|
28
28
|
}
|
package/src/assets/js/katex.js
CHANGED
|
@@ -2,6 +2,181 @@ import $ from 'jquery';
|
|
|
2
2
|
import katex from 'katex';
|
|
3
3
|
import 'katex/dist/katex.min.css';
|
|
4
4
|
|
|
5
|
+
function isEscaped(text, index) {
|
|
6
|
+
let count = 0;
|
|
7
|
+
for (let i = index - 1; i >= 0 && text[i] === '\\'; i--) {
|
|
8
|
+
count++;
|
|
9
|
+
}
|
|
10
|
+
return count % 2 === 1;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function findUnescaped(text, token, start) {
|
|
14
|
+
let index = start;
|
|
15
|
+
while (index < text.length) {
|
|
16
|
+
const found = text.indexOf(token, index);
|
|
17
|
+
if (found === -1) return -1;
|
|
18
|
+
if (!isEscaped(text, found)) return found;
|
|
19
|
+
index = found + token.length;
|
|
20
|
+
}
|
|
21
|
+
return -1;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function getTextNodes(container, shouldAccept) {
|
|
25
|
+
const walker = document.createTreeWalker(
|
|
26
|
+
container,
|
|
27
|
+
NodeFilter.SHOW_TEXT,
|
|
28
|
+
{
|
|
29
|
+
acceptNode: function (node) {
|
|
30
|
+
// 跳过已渲染的节点
|
|
31
|
+
if (
|
|
32
|
+
node.parentNode &&
|
|
33
|
+
(node.parentNode.classList?.contains('katex') ||
|
|
34
|
+
node.parentNode.closest("pre, code, .katex"))
|
|
35
|
+
) {
|
|
36
|
+
return NodeFilter.FILTER_REJECT;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return shouldAccept(node.nodeValue || '') ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
|
|
40
|
+
},
|
|
41
|
+
}
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const nodesToReplace = [];
|
|
45
|
+
while (walker.nextNode()) {
|
|
46
|
+
nodesToReplace.push(walker.currentNode);
|
|
47
|
+
}
|
|
48
|
+
return nodesToReplace;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function collectInlineMatches(text) {
|
|
52
|
+
const matches = [];
|
|
53
|
+
let index = 0;
|
|
54
|
+
|
|
55
|
+
while (index < text.length) {
|
|
56
|
+
const parenStart = text.indexOf('\\(', index);
|
|
57
|
+
const dollarStart = text.indexOf('$', index);
|
|
58
|
+
const candidates = [parenStart, dollarStart].filter((value) => value !== -1 && !isEscaped(text, value));
|
|
59
|
+
const start = candidates.length ? Math.min(...candidates) : -1;
|
|
60
|
+
if (start === -1) break;
|
|
61
|
+
|
|
62
|
+
if (text.slice(start, start + 2) === '\\(') {
|
|
63
|
+
const end = findUnescaped(text, '\\)', start + 2);
|
|
64
|
+
if (end !== -1) {
|
|
65
|
+
const raw = text.slice(start + 2, end);
|
|
66
|
+
if (raw && !raw.includes('\n')) {
|
|
67
|
+
matches.push({
|
|
68
|
+
start,
|
|
69
|
+
end: end + 2,
|
|
70
|
+
raw,
|
|
71
|
+
full: text.slice(start, end + 2),
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
index = end + 2;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
} else if (text[start] === '$' && text[start + 1] !== '$') {
|
|
78
|
+
const end = findUnescaped(text, '$', start + 1);
|
|
79
|
+
if (end !== -1 && text[end + 1] !== '$') {
|
|
80
|
+
const raw = text.slice(start + 1, end);
|
|
81
|
+
if (raw && !raw.includes('\n')) {
|
|
82
|
+
matches.push({
|
|
83
|
+
start,
|
|
84
|
+
end: end + 1,
|
|
85
|
+
raw,
|
|
86
|
+
full: text.slice(start, end + 1),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
index = end + 1;
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
index = start + 1;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return matches;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function collectBlockMatches(text) {
|
|
101
|
+
const matches = [];
|
|
102
|
+
let index = 0;
|
|
103
|
+
|
|
104
|
+
while (index < text.length) {
|
|
105
|
+
const dollarStart = text.indexOf('$$', index);
|
|
106
|
+
const bracketStart = text.indexOf('\\[', index);
|
|
107
|
+
const candidates = [dollarStart, bracketStart].filter((value) => value !== -1 && !isEscaped(text, value));
|
|
108
|
+
const start = candidates.length ? Math.min(...candidates) : -1;
|
|
109
|
+
if (start === -1) break;
|
|
110
|
+
|
|
111
|
+
if (text.slice(start, start + 2) === '$$') {
|
|
112
|
+
const end = findUnescaped(text, '$$', start + 2);
|
|
113
|
+
if (end !== -1) {
|
|
114
|
+
const raw = text.slice(start + 2, end).trim();
|
|
115
|
+
if (raw) {
|
|
116
|
+
matches.push({
|
|
117
|
+
start,
|
|
118
|
+
end: end + 2,
|
|
119
|
+
raw,
|
|
120
|
+
full: text.slice(start, end + 2),
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
index = end + 2;
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
} else if (text.slice(start, start + 2) === '\\[') {
|
|
127
|
+
const end = findUnescaped(text, '\\]', start + 2);
|
|
128
|
+
if (end !== -1) {
|
|
129
|
+
const raw = text.slice(start + 2, end).trim();
|
|
130
|
+
if (raw) {
|
|
131
|
+
matches.push({
|
|
132
|
+
start,
|
|
133
|
+
end: end + 2,
|
|
134
|
+
raw,
|
|
135
|
+
full: text.slice(start, end + 2),
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
index = end + 2;
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
index = start + 1;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return matches;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function replaceTextNode(node, matches, renderMatch, logPrefix) {
|
|
150
|
+
if (!matches.length) return;
|
|
151
|
+
|
|
152
|
+
const text = node.nodeValue || '';
|
|
153
|
+
const frag = document.createDocumentFragment();
|
|
154
|
+
let lastIndex = 0;
|
|
155
|
+
|
|
156
|
+
matches.forEach((match) => {
|
|
157
|
+
if (match.start > lastIndex) {
|
|
158
|
+
frag.appendChild(document.createTextNode(text.slice(lastIndex, match.start)));
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
try {
|
|
162
|
+
frag.appendChild(renderMatch(match.raw));
|
|
163
|
+
} catch (e) {
|
|
164
|
+
frag.appendChild(document.createTextNode(match.full));
|
|
165
|
+
console.error(logPrefix, match.raw, e.message);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
lastIndex = match.end;
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
if (lastIndex < text.length) {
|
|
172
|
+
frag.appendChild(document.createTextNode(text.slice(lastIndex)));
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (frag.hasChildNodes()) {
|
|
176
|
+
node.parentNode.replaceChild(frag, node);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
5
180
|
function renderKatexBlock(selector = ".w-latex") {
|
|
6
181
|
try {
|
|
7
182
|
$(selector).each(function() {
|
|
@@ -39,60 +214,11 @@ function renderKatexBlock(selector = ".w-latex") {
|
|
|
39
214
|
}
|
|
40
215
|
|
|
41
216
|
function renderKatexInline(container = document.body) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
NodeFilter.SHOW_TEXT,
|
|
48
|
-
{
|
|
49
|
-
acceptNode: function (node) {
|
|
50
|
-
// 跳过已渲染的节点
|
|
51
|
-
if (
|
|
52
|
-
node.parentNode &&
|
|
53
|
-
(node.parentNode.classList?.contains('katex') ||
|
|
54
|
-
node.parentNode.closest("pre, code, .katex"))
|
|
55
|
-
) {
|
|
56
|
-
return NodeFilter.FILTER_REJECT;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const value = node.nodeValue || '';
|
|
60
|
-
if (value.includes("\\(") || value.includes("$")) {
|
|
61
|
-
return NodeFilter.FILTER_ACCEPT;
|
|
62
|
-
}
|
|
63
|
-
return NodeFilter.FILTER_REJECT;
|
|
64
|
-
},
|
|
65
|
-
}
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
const nodesToReplace = [];
|
|
69
|
-
while (walker.nextNode()) {
|
|
70
|
-
nodesToReplace.push(walker.currentNode);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
nodesToReplace.forEach((node) => {
|
|
74
|
-
const text = node.nodeValue;
|
|
75
|
-
const frag = document.createDocumentFragment();
|
|
76
|
-
let lastIndex = 0;
|
|
77
|
-
|
|
78
|
-
// 重置正则状态
|
|
79
|
-
inlineRegex.lastIndex = 0;
|
|
80
|
-
|
|
81
|
-
const matches = [...text.matchAll(inlineRegex)];
|
|
82
|
-
|
|
83
|
-
matches.forEach((match) => {
|
|
84
|
-
const fullMatch = match[0];
|
|
85
|
-
const parenContent = match[2];
|
|
86
|
-
const dollarContent = match[3];
|
|
87
|
-
const raw = parenContent || dollarContent;
|
|
88
|
-
const matchStart = match.index;
|
|
89
|
-
|
|
90
|
-
// 添加匹配前的文本
|
|
91
|
-
if (matchStart > lastIndex) {
|
|
92
|
-
frag.appendChild(document.createTextNode(text.slice(lastIndex, matchStart)));
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
try {
|
|
217
|
+
getTextNodes(container, (value) => value.includes("\\(") || value.includes("$")).forEach((node) => {
|
|
218
|
+
replaceTextNode(
|
|
219
|
+
node,
|
|
220
|
+
collectInlineMatches(node.nodeValue || ''),
|
|
221
|
+
(raw) => {
|
|
96
222
|
const span = document.createElement("span");
|
|
97
223
|
span.className = "katex-inline";
|
|
98
224
|
span.innerHTML = katex.renderToString(raw, {
|
|
@@ -101,81 +227,19 @@ function renderKatexInline(container = document.body) {
|
|
|
101
227
|
strict: false,
|
|
102
228
|
trust: true
|
|
103
229
|
});
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
lastIndex = matchStart + fullMatch.length;
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
// 添加剩余文本
|
|
114
|
-
if (lastIndex < text.length) {
|
|
115
|
-
frag.appendChild(document.createTextNode(text.slice(lastIndex)));
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if (frag.hasChildNodes()) {
|
|
119
|
-
node.parentNode.replaceChild(frag, node);
|
|
120
|
-
}
|
|
230
|
+
return span;
|
|
231
|
+
},
|
|
232
|
+
"Inline render error:"
|
|
233
|
+
);
|
|
121
234
|
});
|
|
122
235
|
}
|
|
123
236
|
|
|
124
237
|
function renderKatexDisplayBlock(container = document.body) {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
NodeFilter.SHOW_TEXT,
|
|
131
|
-
{
|
|
132
|
-
acceptNode: function (node) {
|
|
133
|
-
// 跳过已渲染的节点
|
|
134
|
-
if (
|
|
135
|
-
node.parentNode &&
|
|
136
|
-
(node.parentNode.classList?.contains('katex') ||
|
|
137
|
-
node.parentNode.closest("pre, code, .katex"))
|
|
138
|
-
) {
|
|
139
|
-
return NodeFilter.FILTER_REJECT;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
const value = node.nodeValue || '';
|
|
143
|
-
if (value.includes("$$") || value.includes("\\[")) {
|
|
144
|
-
return NodeFilter.FILTER_ACCEPT;
|
|
145
|
-
}
|
|
146
|
-
return NodeFilter.FILTER_REJECT;
|
|
147
|
-
},
|
|
148
|
-
}
|
|
149
|
-
);
|
|
150
|
-
|
|
151
|
-
const nodesToReplace = [];
|
|
152
|
-
while (walker.nextNode()) {
|
|
153
|
-
nodesToReplace.push(walker.currentNode);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
nodesToReplace.forEach((node) => {
|
|
157
|
-
const text = node.nodeValue;
|
|
158
|
-
const frag = document.createDocumentFragment();
|
|
159
|
-
let lastIndex = 0;
|
|
160
|
-
|
|
161
|
-
// 重置正则状态
|
|
162
|
-
blockRegex.lastIndex = 0;
|
|
163
|
-
|
|
164
|
-
const matches = [...text.matchAll(blockRegex)];
|
|
165
|
-
|
|
166
|
-
matches.forEach((match) => {
|
|
167
|
-
const fullMatch = match[0];
|
|
168
|
-
const dollarContent = match[2];
|
|
169
|
-
const bracketContent = match[3];
|
|
170
|
-
const raw = (dollarContent || bracketContent).trim();
|
|
171
|
-
const matchStart = match.index;
|
|
172
|
-
|
|
173
|
-
// 添加匹配前的文本
|
|
174
|
-
if (matchStart > lastIndex) {
|
|
175
|
-
frag.appendChild(document.createTextNode(text.slice(lastIndex, matchStart)));
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
try {
|
|
238
|
+
getTextNodes(container, (value) => value.includes("$$") || value.includes("\\[")).forEach((node) => {
|
|
239
|
+
replaceTextNode(
|
|
240
|
+
node,
|
|
241
|
+
collectBlockMatches(node.nodeValue || ''),
|
|
242
|
+
(raw) => {
|
|
179
243
|
const div = document.createElement("div");
|
|
180
244
|
div.className = "katex-block";
|
|
181
245
|
div.innerHTML = katex.renderToString(raw, {
|
|
@@ -184,23 +248,10 @@ function renderKatexDisplayBlock(container = document.body) {
|
|
|
184
248
|
strict: false,
|
|
185
249
|
trust: true
|
|
186
250
|
});
|
|
187
|
-
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
lastIndex = matchStart + fullMatch.length;
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
// 添加剩余文本
|
|
197
|
-
if (lastIndex < text.length) {
|
|
198
|
-
frag.appendChild(document.createTextNode(text.slice(lastIndex)));
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
if (frag.hasChildNodes()) {
|
|
202
|
-
node.parentNode.replaceChild(frag, node);
|
|
203
|
-
}
|
|
251
|
+
return div;
|
|
252
|
+
},
|
|
253
|
+
"Block render error:"
|
|
254
|
+
);
|
|
204
255
|
});
|
|
205
256
|
}
|
|
206
257
|
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import $ from "jquery";
|
|
2
|
-
function buildIframe(str)
|
|
2
|
+
function buildIframe(str){
|
|
3
3
|
let _str = new URLSearchParams(str);
|
|
4
|
-
let mode = _str.get(
|
|
4
|
+
let mode = _str.get('mode')
|
|
5
5
|
|
|
6
|
-
if
|
|
7
|
-
return `<
|
|
8
|
-
}
|
|
9
|
-
return `<
|
|
6
|
+
if(mode == 'vertical'){
|
|
7
|
+
return `<iframe class="w-pz-iframe" src="${str}" scrolling="no" width="750" height="3468" style="border:none;background:none;max-width:100%;overflow:hidden;"></iframe>`
|
|
8
|
+
}else{
|
|
9
|
+
return `<iframe class="w-pz-iframe" src="${str}" scrolling="no" width="1280" height="720" style="border:none;background:none;max-width:100%;overflow:hidden;"></iframe>`
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
function renderPzIframe(selector = ".e-pz-iframe")
|
|
13
|
+
function renderPzIframe(selector = ".e-pz-iframe"){
|
|
14
14
|
try {
|
|
15
|
-
$(selector).each(function
|
|
15
|
+
$(selector).each(function(i, ele) {
|
|
16
16
|
// 获取嵌入源地址
|
|
17
|
-
let url =
|
|
17
|
+
let url = $(this).text();
|
|
18
18
|
|
|
19
19
|
// 构建嵌入源码
|
|
20
|
-
let code = buildIframe(url)
|
|
20
|
+
let code = buildIframe(url)
|
|
21
21
|
|
|
22
22
|
// 挂载点
|
|
23
23
|
$(this).after(code);
|
|
@@ -27,4 +27,4 @@ function renderPzIframe(selector = ".e-pz-iframe") {
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
export default renderPzIframe
|
|
30
|
+
export default renderPzIframe
|
|
@@ -70,8 +70,8 @@
|
|
|
70
70
|
|
|
71
71
|
<script>
|
|
72
72
|
import { authorLink, getLink, getMedalLink, getThumbnail } from "@jx3box/jx3box-common/js/utils";
|
|
73
|
-
import { getUserInfo, getUserMedals, getUserPublicTeams } from "../service/author
|
|
74
|
-
import { getDecoration, getDecorationJson } from "../service/cms
|
|
73
|
+
import { getUserInfo, getUserMedals, getUserPublicTeams } from "../service/author";
|
|
74
|
+
import { getDecoration, getDecorationJson } from "../service/cms";
|
|
75
75
|
import User from "@jx3box/jx3box-common/js/user";
|
|
76
76
|
import JX3BOX from "@jx3box/jx3box-common/data/jx3box.json";
|
|
77
77
|
import Avatar from "./Avatar.vue";
|
package/src/components/Combo.vue
CHANGED
|
@@ -154,7 +154,7 @@ import { h } from "vue";
|
|
|
154
154
|
import { ElIcon } from "element-plus";
|
|
155
155
|
import { Check, Close } from "@element-plus/icons-vue";
|
|
156
156
|
import { iconLink } from "@jx3box/jx3box-common/js/utils";
|
|
157
|
-
import { getSkill } from "../service/resource
|
|
157
|
+
import { getSkill } from "../service/resource";
|
|
158
158
|
import SkillMartial from "./SkillMartial.vue";
|
|
159
159
|
|
|
160
160
|
import Sortable from "sortablejs";
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
|
|
28
28
|
<script>
|
|
29
29
|
import { authorLink } from "@jx3box/jx3box-common/js/utils";
|
|
30
|
-
import { getEmotion } from "../service/author
|
|
30
|
+
import { getEmotion } from "../service/author";
|
|
31
31
|
import JX3BOX from "@jx3box/jx3box-common/data/jx3box.json";
|
|
32
32
|
import dayjs from "dayjs";
|
|
33
33
|
import Avatar from "./Avatar.vue";
|
|
@@ -178,7 +178,7 @@ import {
|
|
|
178
178
|
getSkills,
|
|
179
179
|
getTalents,
|
|
180
180
|
getMobileForceSkillList,
|
|
181
|
-
} from "../service/node
|
|
181
|
+
} from "../service/node";
|
|
182
182
|
import kungfumap_std from "@jx3box/jx3box-data/data/martial/kungfu_std.json";
|
|
183
183
|
import kungfumap_origin from "@jx3box/jx3box-data/data/martial/kungfu_origin.json";
|
|
184
184
|
import { flattenDeep, uniqBy } from "lodash";
|