@jx3box/jx3box-editor 0.9.1 → 0.9.5

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.
@@ -0,0 +1,19 @@
1
+ .c-markdown-toolbar-item{
2
+ .mr(5px);
3
+ .pointer;
4
+ padding: 2px 5px 3px 5px;
5
+
6
+ &:hover{
7
+ background: #e9e9eb;
8
+ .r(4px);
9
+ }
10
+ }
11
+ .c-markdown-store-item{
12
+ .none;
13
+ }
14
+
15
+ .c-markdown{
16
+ .markdown-body .hljs{
17
+ background-color:#f6f8fa;
18
+ }
19
+ }
package/package.json CHANGED
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "@jx3box/jx3box-editor",
3
- "version": "0.9.1",
3
+ "version": "0.9.5",
4
4
  "description": "JX3BOX Article & Editor",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
+ "dev": "env DEV_SERVER=true vue-cli-service serve",
7
8
  "serve": "vue-cli-service serve",
8
9
  "build": "vue-cli-service build",
9
10
  "lint": "vue-cli-service lint",
10
11
  "inspect": "vue inspect > output.js",
11
- "update": "npm --registry https://registry.npmjs.org install @jx3box/jx3box-common@latest @jx3box/jx3box-macro@latest @jx3box/jx3box-talent@latest @jx3box/jx3box-emotion@latest @jx3box/jx3box-data@latest",
12
+ "update": "npm --registry https://registry.npmjs.org install @jx3box/jx3box-common@latest @jx3box/jx3box-macro@latest @jx3box/jx3box-talent@latest @jx3box/jx3box-emotion@latest @jx3box/jx3box-data@latest @jx3box/markdown@latest",
12
13
  "article": "vue-cli-service build --target lib --name jx3box_article src/Article.vue --mode production",
13
14
  "tinymce": "vue-cli-service build --target lib --name tinymce src/Tinymce.vue && cp public/tinymce.html dist/tinymce.html"
14
15
  },
@@ -35,6 +36,7 @@
35
36
  "@jx3box/jx3box-emotion": "^1.0.10",
36
37
  "@jx3box/jx3box-macro": "^1.0.1",
37
38
  "@jx3box/jx3box-talent": "^1.1.2",
39
+ "@jx3box/markdown": "0.0.7",
38
40
  "@tinymce/tinymce-vue": "^3.2.2",
39
41
  "axios": "^0.19.2",
40
42
  "core-js": "^3.6.5",
package/readme.md CHANGED
@@ -7,7 +7,8 @@
7
7
  $ npm install
8
8
  $ npm run serve
9
9
  $ open http://localhost:8080 //文章渲染
10
- $ open http://localhost:8080/tinymce //编辑器
10
+ $ open http://localhost:8080/tinymce //tinymce编辑器
11
+ $ open http://localhost:8080/markdown //markdown编辑器
11
12
  $ tinymce http://localhost:5000
12
13
  ```
13
14
 
package/service/cms.js ADDED
@@ -0,0 +1,7 @@
1
+ import { $cms } from "@jx3box/jx3box-common/js/https";
2
+
3
+ function uploadFile(data) {
4
+ return $cms().post(`/api/cms/upload`, data);
5
+ }
6
+
7
+ export { uploadFile };
@@ -0,0 +1,150 @@
1
+ <template>
2
+ <div class="c-markdown">
3
+ <input class="c-markdown-store-item" id="c-markdown-store-images" type="file" @change="uploadImages" ref="markdownImages" multiple :accept="allow_image_types" />
4
+ <input class="c-markdown-store-item" id="c-markdown-store-files" type="file" @change="uploadFiles" ref="markdownFiles" multiple />
5
+ <mavon-editor class="c-markdown-box" ref="md" v-model="data" :editable="editable" :navigation="false" @change="updateData">
6
+ <template slot="left-toolbar-after">
7
+ <span class="c-markdown-toolbar-image c-markdown-toolbar-item" title="上传图片" @click="selectImages"><i class="el-icon-picture-outline-round"></i></span>
8
+ <span class="c-markdown-toolbar-file c-markdown-toolbar-item" title="上传附件" @click="selectFiles"><i class="el-icon-paperclip"></i></span>
9
+ </template>
10
+ </mavon-editor>
11
+ </div>
12
+ </template>
13
+
14
+ <script>
15
+ import { uploadFile } from "../service/cms";
16
+ export default {
17
+ name: "Markdown",
18
+ props: {
19
+ content: {
20
+ type: String,
21
+ },
22
+ editable: {
23
+ type: Boolean,
24
+ default: true,
25
+ },
26
+ },
27
+ components: {},
28
+ data: function() {
29
+ return {
30
+ data: this.content,
31
+ allow_image_types: ["image/png", "image/jpeg", "image/gif", "image/bmp", "image/webp"],
32
+ allow_file_types: [],
33
+ image_ext: ["png", "jpg", "gif", "bmp", "webp"],
34
+ files: [],
35
+ resolved_files: [],
36
+ };
37
+ },
38
+ model: {
39
+ prop: "content",
40
+ event: "update",
41
+ },
42
+ watch: {
43
+ data: function(newval) {
44
+ this.$emit("update", newval);
45
+ },
46
+ content: function(newval) {
47
+ this.data = newval;
48
+ },
49
+ // 监听过滤后的文件列表
50
+ files_list: function(list) {
51
+ this.bulkUpload(list);
52
+ },
53
+ },
54
+ computed: {
55
+ files_list: function() {
56
+ let files = Array.from(this.files);
57
+ return files;
58
+ },
59
+ $md: function() {
60
+ return this.$refs.md;
61
+ },
62
+ },
63
+ methods: {
64
+ // 点击上传按钮
65
+ selectImages: function() {
66
+ document.getElementById("c-markdown-store-images").dispatchEvent(new MouseEvent("click"));
67
+ },
68
+ selectFiles: function() {
69
+ document.getElementById("c-markdown-store-files").dispatchEvent(new MouseEvent("click"));
70
+ },
71
+ // 监听选择结果变化
72
+ uploadImages: function(e) {
73
+ this.files = this.$refs.markdownImages.files;
74
+ },
75
+ uploadFiles: function(e) {
76
+ this.files = this.$refs.markdownFiles.files;
77
+ },
78
+ // 批量上传
79
+ bulkUpload: function(list) {
80
+ // 存在有效数据队列时
81
+ if (!list || !list.length) return;
82
+
83
+ // 上传队列
84
+ let queue = [];
85
+ for (let item of list) {
86
+ let formdata = new FormData();
87
+ formdata.append("file", item);
88
+ queue.push(uploadFile(formdata));
89
+ }
90
+
91
+ // 回调处理
92
+ Promise.allSettled(queue)
93
+ .then((results) => {
94
+ results.forEach((result, i) => {
95
+ if (result.status == "fulfilled") {
96
+ let url = result.value.data?.data?.[0];
97
+ this.resolved_files.push({
98
+ url: url,
99
+ filename: list[i]["name"],
100
+ type: list[i]["type"],
101
+ ext: list[i]["name"].split(".").pop(),
102
+ });
103
+ }
104
+ });
105
+ this.insertFiles();
106
+ })
107
+ .finally(() => {
108
+ // 上传完成后清空input
109
+ this.images = [];
110
+ this.files = [];
111
+ this.resolved_files = [];
112
+ });
113
+ },
114
+ // 插入正文
115
+ insertFiles: function() {
116
+ for (let item of this.resolved_files) {
117
+ // 插入图片
118
+ if (this.image_ext.includes(item.ext)) {
119
+ this.$md.insertText(this.$md.getTextareaDom(), {
120
+ prefix: `![${item.filename}](${item.url})`,
121
+ subfix: "",
122
+ str: "",
123
+ });
124
+ // 插入文字链接
125
+ } else {
126
+ this.$md.insertText(this.$md.getTextareaDom(), {
127
+ prefix: `[${item.filename}](${item.url})`,
128
+ subfix: "",
129
+ str: "",
130
+ });
131
+ }
132
+ }
133
+ },
134
+ // 更新触发
135
+ updateData: function(data, render) {
136
+ this.$emit("updateData", {
137
+ data,
138
+ render,
139
+ });
140
+ },
141
+ },
142
+ filters: {},
143
+ created: function() {},
144
+ mounted: function() {},
145
+ };
146
+ </script>
147
+
148
+ <style lang="less">
149
+ @import "../assets/css/markdown.less";
150
+ </style>
package/src/Upload.vue CHANGED
@@ -28,6 +28,7 @@
28
28
  :file-list="fileList"
29
29
  :on-change="change"
30
30
  ref="uploadbox"
31
+ :accept="accept"
31
32
  >
32
33
  <!-- :accept="accept" -->
33
34
  <i slot="default" class="el-icon-plus"></i>
@@ -86,13 +87,12 @@ const imgtypes = ["jpg", "png", "gif", "bmp", "webp"];
86
87
 
87
88
  export default {
88
89
  name: "Upload",
89
- props: ["text"],
90
+ props: ["text",'onlyImage','desc','accept'],
90
91
  data: function () {
91
92
  return {
92
93
  API: API,
93
94
  dialogVisible: false,
94
- tip:
95
- "一次最多同时上传10个文件(不超过5M),格式限常见的图片、文档、数据表及压缩包",
95
+ tip: this.desc || "一次最多同时上传10个文件(不超过5M),格式限常见的图片、文档、数据表及压缩包",
96
96
  btn_txt: this.text || "上传附件",
97
97
 
98
98
  fileList: [],
@@ -129,6 +129,12 @@ export default {
129
129
  // return;
130
130
  // }
131
131
 
132
+ // 分析文件类型
133
+ let ext = file.name.split(".").pop();
134
+ let is_img = imgtypes.includes(ext);
135
+
136
+ if(this.onlyImage && !is_img) return
137
+
132
138
  // 构建数据
133
139
  let fdata = new FormData();
134
140
  fdata.append("file", file.raw);
@@ -149,10 +155,6 @@ export default {
149
155
  // 修改path
150
156
  file.url = res.data.data && res.data.data[0];
151
157
 
152
- // 分析文件类型
153
- let ext = file.name.split(".").pop();
154
- let is_img = imgtypes.includes(ext);
155
-
156
158
  // 额外赋值
157
159
  file.is_img = is_img;
158
160
  file.selected = true;
package/vue.config.js CHANGED
@@ -18,6 +18,12 @@ module.exports = {
18
18
  template : 'public/tinymce.html',
19
19
  filename:'tinymce/index.html',
20
20
  },
21
+ markdown : {
22
+ title : 'Markdown编辑器',
23
+ entry:'demo/M.js',
24
+ template : 'public/article.html',
25
+ filename:'markdown/index.html',
26
+ },
21
27
  },
22
28
 
23
29
 
@@ -48,16 +54,22 @@ module.exports = {
48
54
  '/',
49
55
 
50
56
  //❤️ Porxy ~
51
- // devServer: {
52
- // proxy: {
53
- // "/api": {
54
- // "target": process.env["DEV_SERVER"] == "true" ? "http://localhost:51818" : "https://next.jx3box.com",
55
- // "onProxyReq": function (request) {
56
- // request.setHeader("origin", "");
57
- // }
58
- // }
59
- // }
60
- // },
57
+ devServer: {
58
+ proxy: {
59
+ "/api/cms": {
60
+ "target": process.env["DEV_SERVER"] == "true" ? "http://localhost:5120" : "https://cms.jx3box.com",
61
+ "onProxyReq": function (request) {
62
+ request.setHeader("origin", "");
63
+ }
64
+ },
65
+ "/api": {
66
+ "target": process.env["DEV_SERVER"] == "true" ? "http://localhost:51818" : "https://next.jx3box.com",
67
+ "onProxyReq": function (request) {
68
+ request.setHeader("origin", "");
69
+ }
70
+ }
71
+ }
72
+ },
61
73
 
62
74
  chainWebpack: config => {
63
75