├── .babelrc
├── .editorconfig
├── .gitignore
├── CNAME
├── LICENSE
├── README.md
├── dist
├── yimo-vue-editor.js
└── yimo-vue-editor.js.map
├── example
├── html
│ ├── index.html
│ └── lang.html
└── vue
│ ├── App.vue
│ └── main.js
├── index.html
├── mock-server
├── api
│ └── upload.js
└── index.js
├── package.json
├── src
├── Editor.vue
├── assets
│ ├── css
│ │ └── wangEditor.css
│ ├── fonts
│ │ ├── icomoon.eot
│ │ ├── icomoon.svg
│ │ ├── icomoon.ttf
│ │ └── icomoon.woff
│ └── js
│ │ └── wangEditor.js
└── index.js
└── webpack.config.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["env", { "modules": false }],
4 | "stage-3"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | npm-debug.log
4 | yarn-error.log
5 |
6 | # Editor directories and files
7 | .idea
8 | *.suo
9 | *.ntvs*
10 | *.njsproj
11 | *.sln
12 | package-lock.json
--------------------------------------------------------------------------------
/CNAME:
--------------------------------------------------------------------------------
1 | vue-editor.yimo.link
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2019 yimogit
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # yimo-vue-editor
2 |
3 | Demo address: https://vue-editor.yimo.link/example/html/index.html
4 |
5 | > Vue-editor component based on wangeditor2.5.11 wrapper
6 | > wangEditor docs:https://www.kancloud.cn/wangfupeng/wangeditor2/113961
7 |
8 | ## Used in vue projects
9 |
10 | `npm install yimo-vue-editor --save`
11 |
12 | [](https://www.npmjs.com/package/yimo-vue-editor)
13 |
14 | ```
15 |
16 |
17 |
18 |
19 | import YimoVueEditor from 'yimo-vue-editor'
20 | export default {
21 | components: {
22 | YimoVueEditor
23 | }
24 | }
25 | ```
26 |
27 | ## Global introduction and configuration
28 |
29 | ``` js
30 | import YimoVueEditor from 'yimo-vue-editor'
31 |
32 | Vue.use(YimoVueEditor, {
33 | name: 'v-editor-app',//Custom name
34 | config: {
35 | uploadImgUrl:'/api/upload', // upload api
36 | printLog: false, // disabled console.log
37 | useLang: 'en' // lang config
38 | },//wagnEditor config
39 | uploadHandler: (type, resTxt) => {//Upload processing hook
40 | if (type === 'success') {
41 | var res = JSON.parse(resTxt)//Do not process the default look at the return value bit image path
42 | if (res.status !== 1) {
43 | return null
44 | }
45 | return res.data
46 | } else if (type === 'error') {
47 | //todo toast
48 | } else if (type === 'timeout') {
49 | //todo toast
50 | }
51 | return 'upload failed__'
52 | }
53 | })
54 | ```
55 |
56 | ## Parameter
57 |
58 | - value
59 | v-model Binding editor value
60 | - config
61 | wangEditor2.0 config ,[wangEditor docs](https://www.kancloud.cn/wangfupeng/wangeditor2/113975)
62 | - uploadHandler
63 | The processing of the return value after the image is uploaded, successfully returns the url to be inserted, fails to return an error prompt or prompts in the hook, etc.
64 | ```js
65 | var uploadHandler = (type, resTxt) => {
66 | if (type === 'success') {
67 | var res = JSON.parse(resTxt)
68 | if (res.status !== 1) {
69 | return null
70 | }
71 | return res.data.fileUrl
72 | } else if (type === 'error') {
73 | //todo toast
74 | } else if (type === 'timeout') {
75 | //todo toast
76 | }
77 | return 'upload failed__'
78 | }
79 | ```
80 |
81 | ## Modification
82 |
83 | - delete Map menu code
84 | - hide Emoticon menu
85 | - fix Upload multiple image insertion order issues (replace after tag placement)
86 | - add Link open state setting
87 | - add Hook after uploading
88 | - add upload append filename no null
89 | - add fullscreen scroll bar
90 |
91 | ## Points to pay attention to
92 |
93 | - ie9 upload image, upload using form+iframe, can't cross domain, and the return type needs to be text/html
94 | - The log is printed as a global parameter, subject to the last setting
95 |
--------------------------------------------------------------------------------
/example/html/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | yimo-vue-editor的使用
7 |
8 |
9 |
10 |
11 |
12 |
13 |
实例切换:{{caseType}}
14 |
15 |
16 |
17 |
单个编辑器:v-editor
18 |
19 |
全局配置的编辑器:v-editor-app
20 |
21 |
预览:
22 |
23 |
24 |
25 |
26 |
编辑器{{index+1}}:
27 |
28 |
29 |
30 |
预览编辑器{{index+1}}:
31 |
32 |
33 |
34 |
35 |
36 |
118 |
119 |
120 |
121 |
--------------------------------------------------------------------------------
/example/html/lang.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | yimo-vue-editor的使用
7 |
8 |
9 |
10 |
11 |
12 |
13 |
多语言配置
14 |
15 |
16 |
单个编辑器:v-editor
17 |
18 |
全局配置的编辑器:v-editor-app
19 |
20 |
预览:
21 |
22 |
23 |
24 |
25 |
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/example/vue/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
实例切换:{{ caseType }}
5 |
12 |
13 |
14 |
单个编辑器:v-editor
15 |
24 |
单个编辑器:v-editor-app
25 |
32 |
预览:
33 |
37 |
38 |
39 |
40 |
编辑器{{ index + 1 }}:
41 |
42 |
47 |
48 |
预览编辑器{{ index + 1 }}:
49 |
53 |
54 |
55 |
56 |
57 |
58 |
91 |
92 |
101 |
--------------------------------------------------------------------------------
/example/vue/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import VEditor from '../../src/index.js'
4 |
5 | Vue.use(VEditor, {
6 | name: 'v-editor-app',
7 | config: {},
8 | uploadHandler: (type, resTxt) => {
9 | if (type === 'success') {
10 | var res = JSON.parse(resTxt)
11 | if (res.status !== 1) {
12 | return null
13 | }
14 | return res.data.fileUrl
15 | } else if (type === 'error') {
16 | //todo toast
17 | } else if (type === 'timeout') {
18 | //todo toast
19 | }
20 | return '上传失败__'
21 | }
22 | })
23 | new Vue({
24 | el: '#app',
25 | render: h => h(App)
26 | })
27 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | yimo-vue-editor
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/mock-server/api/upload.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 登录
3 | *
4 | * @url /upload
5 | * POST
6 | */
7 | module.exports = function(req) {
8 | if (req.query.isIe9==='true') {
9 | req.res.set('Content-Type', 'text/html')
10 | }
11 | return {
12 | status: 1,
13 | data: {
14 | fileName: '@integer(0).jpg',
15 | filePath: '@image(200x200)',
16 | fileUrl: '@image(200x200)'
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/mock-server/index.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var express = require('express')
3 | var mockjs = require('express-mockjs')
4 | var app = express()
5 |
6 | // 自定义路径 '/api'
7 | var config = {
8 | port: 3000
9 | }
10 | app.use('/api', mockjs(path.join(__dirname, 'api')))
11 |
12 | // 获取port参数
13 | var args = process.argv
14 | for (let i = 0; i < args.length; i++) {
15 | if (args[i] === '--port' && i < args.length - 1 && args[i + 1] > 0) {
16 | config.port = args[i + 1]
17 | break
18 | }
19 | }
20 |
21 | console.log('mock-server[mockjs-lite]:http://localhost:' + config.port)
22 | // console.log('mockjs-lite定义:http://mockjs-lite.js.org/docs/examples.html')
23 | app.listen(config.port)
24 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "yimo-vue-editor",
3 | "description": "基于 wangeditor2.5.11 封装的 vue-editor 富文本编辑器组件",
4 | "version": "1.1.7",
5 | "author": "易墨 ",
6 | "license": "MIT",
7 | "private": false,
8 | "keywords": [
9 | "vue",
10 | "wangeditor"
11 | ],
12 | "scripts": {
13 | "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot --port 1122 ",
14 | "build": "cross-env NODE_ENV=production webpack --progress --hide-modules",
15 | "mock": "node mock-server/index.js --port 2233"
16 | },
17 | "main": "dist/yimo-vue-editor.js",
18 | "repository": {
19 | "type": "git",
20 | "url": "https://github.com/yimogit/yimo-vue-editor"
21 | },
22 | "dependencies": {
23 | "jquery": "^3.3.1",
24 | "vue": "^2.5.11"
25 | },
26 | "browserslist": [
27 | "> 1%",
28 | "last 2 versions",
29 | "not ie <= 8"
30 | ],
31 | "devDependencies": {
32 | "babel-core": "^6.26.0",
33 | "babel-loader": "^7.1.2",
34 | "babel-preset-env": "^1.6.0",
35 | "babel-preset-stage-3": "^6.24.1",
36 | "cross-env": "^5.0.5",
37 | "css-loader": "^0.28.7",
38 | "express-mockjs": "^0.4.9",
39 | "file-loader": "^1.1.4",
40 | "object-assign": "^4.1.1",
41 | "shelljs": "^0.8.2",
42 | "url-loader": "^1.1.2",
43 | "vue-loader": "^13.0.5",
44 | "vue-template-compiler": "^2.4.4",
45 | "webpack": "^3.6.0",
46 | "webpack-dev-server": "^2.9.1"
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/Editor.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
226 |
227 |
244 |
--------------------------------------------------------------------------------
/src/assets/css/wangEditor.css:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 | /* 编辑器边框颜色 */
3 | /* 菜单颜色、上边框颜色 */
4 | /* 菜单选中状态的颜色 */
5 | /* input focus 时的颜色 */
6 | /* 按钮颜色 */
7 | /* tab selected 状态下的颜色 */
8 | .wangEditor-container {
9 | position: relative;
10 | background-color: #fff;
11 | border: 1px solid #ccc;
12 | z-index: 1;
13 | width: 100%;
14 | }
15 | .wangEditor-container a:focus,
16 | .wangEditor-container button:focus {
17 | outline: none;
18 | }
19 | .wangEditor-container,
20 | .wangEditor-container * {
21 | margin: 0;
22 | padding: 0;
23 | box-sizing: border-box;
24 | line-height: 1;
25 | }
26 | .wangEditor-container img {
27 | border: none;
28 | }
29 | .wangEditor-container .clearfix:after {
30 | content: '';
31 | display: table;
32 | clear: both;
33 | }
34 | .wangEditor-container .clearfix {
35 | *zoom: 1;
36 | }
37 | .wangEditor-container textarea {
38 | border: none;
39 | }
40 | .wangEditor-container textarea:focus {
41 | outline: none;
42 | }
43 | .wangEditor-container .height-tip {
44 | position: absolute;
45 | width: 3px;
46 | background-color: #ccc;
47 | left: 0;
48 | transition: top 0.2s;
49 | }
50 | .wangEditor-container .txt-toolbar {
51 | position: absolute;
52 | background-color: #fff;
53 | padding: 3px 5px;
54 | border-top: 2px solid #666;
55 | box-shadow: 1px 3px 3px #999;
56 | border-left: 1px solid #ccc;
57 | border-bottom: 1px solid #999;
58 | border-right: 1px solid #999;
59 | }
60 | .wangEditor-container .txt-toolbar .tip-triangle {
61 | display: block;
62 | position: absolute;
63 | width: 0;
64 | height: 0;
65 | border: 5px solid;
66 | border-color: transparent transparent #666 transparent;
67 | top: -12px;
68 | left: 50%;
69 | margin-left: -5px;
70 | }
71 | .wangEditor-container .txt-toolbar a {
72 | color: #666;
73 | display: inline-block;
74 | margin: 0 3px;
75 | padding: 5px;
76 | text-decoration: none;
77 | border-radius: 3px;
78 | }
79 | .wangEditor-container .txt-toolbar a:hover {
80 | background-color: #f1f1f1;
81 | }
82 | .wangEditor-container .img-drag-point {
83 | display: block;
84 | position: absolute;
85 | width: 12px;
86 | height: 12px;
87 | border-radius: 50%;
88 | cursor: se-resize;
89 | background-color: #666;
90 | margin-left: -6px;
91 | margin-top: -6px;
92 | box-shadow: 1px 1px 5px #999;
93 | }
94 | .wangEditor-container .wangEditor-upload-progress {
95 | position: absolute;
96 | height: 1px;
97 | background: #1e88e5;
98 | width: 0;
99 | display: none;
100 | -webkit-transition: width 0.5s;
101 | -o-transition: width 0.5s;
102 | transition: width 0.5s;
103 | }
104 | .wangEditor-fullscreen {
105 | position: fixed;
106 | top: 0;
107 | bottom: 0;
108 | left: 0;
109 | right: 0;
110 | }
111 | .wangEditor-container .code-textarea {
112 | resize: none;
113 | width: 100%;
114 | font-size: 14px;
115 | line-height: 1.5;
116 | font-family: 'Verdana';
117 | color: #333;
118 | padding: 0 15px 0 15px;
119 | }
120 | .wangEditor-menu-container {
121 | width: 100%;
122 | border-bottom: 1px solid #f1f1f1;
123 | background-color: #fff;
124 | }
125 | .wangEditor-menu-container a {
126 | text-decoration: none;
127 | }
128 | .wangEditor-menu-container .menu-group {
129 | float: left;
130 | padding: 0 8px;
131 | border-right: 1px solid #f1f1f1;
132 | }
133 | .wangEditor-menu-container .menu-item {
134 | float: left;
135 | position: relative;
136 | text-align: center;
137 | height: 31px;
138 | width: 35px;
139 | }
140 | .wangEditor-menu-container .menu-item:hover {
141 | background-color: #f1f1f1;
142 | }
143 | .wangEditor-menu-container .menu-item a {
144 | display: block;
145 | text-align: center;
146 | color: #666;
147 | width: 100%;
148 | padding: 8px 0;
149 | font-size: 0.9em;
150 | }
151 | .wangEditor-menu-container .menu-item .selected {
152 | color: #1e88e5;
153 | }
154 | .wangEditor-menu-container .menu-item .active {
155 | background-color: #f1f1f1;
156 | }
157 | .wangEditor-menu-container .menu-item .disable {
158 | opacity: 0.5;
159 | filter: alpha(opacity=50);
160 | }
161 | .wangEditor-menu-container .menu-tip {
162 | display: block;
163 | position: absolute;
164 | z-index: 20;
165 | width: 60px;
166 | text-align: center;
167 | background-color: #666;
168 | color: #fff;
169 | padding: 7px 0;
170 | font-size: 12px;
171 | top: 100%;
172 | left: 50%;
173 | margin-left: -30px;
174 | border-radius: 2px;
175 | box-shadow: 1px 1px 5px #999;
176 | display: none;
177 | /*// 小三角
178 | .tip-triangle {
179 | display: block;
180 | position: absolute;
181 | width: 0;
182 | height: 0;
183 | border:5px solid;
184 | border-color: transparent transparent @fore-color transparent;
185 | top: -10px;
186 | left: 50%;
187 | margin-left: -5px;
188 | }*/
189 | }
190 | .wangEditor-menu-container .menu-tip-40 {
191 | width: 40px;
192 | margin-left: -20px;
193 | }
194 | .wangEditor-menu-container .menu-tip-50 {
195 | width: 50px;
196 | margin-left: -25px;
197 | }
198 | .wangEditor-menu-shadow {
199 | /*border-bottom-width: 0;*/
200 | border-bottom: 1px solid #f1f1f1;
201 | box-shadow: 0 1px 3px #999;
202 | }
203 | .wangEditor-container .wangEditor-txt {
204 | width: 100%;
205 | text-align: left;
206 | padding: 15px;
207 | padding-top: 0;
208 | margin-top: 5px;
209 | overflow-y: auto;
210 | }
211 | .wangEditor-container .wangEditor-txt p,
212 | .wangEditor-container .wangEditor-txt h1,
213 | .wangEditor-container .wangEditor-txt h2,
214 | .wangEditor-container .wangEditor-txt h3,
215 | .wangEditor-container .wangEditor-txt h4,
216 | .wangEditor-container .wangEditor-txt h5 {
217 | margin: 10px 0;
218 | line-height: 1.8;
219 | }
220 | .wangEditor-container .wangEditor-txt p *,
221 | .wangEditor-container .wangEditor-txt h1 *,
222 | .wangEditor-container .wangEditor-txt h2 *,
223 | .wangEditor-container .wangEditor-txt h3 *,
224 | .wangEditor-container .wangEditor-txt h4 *,
225 | .wangEditor-container .wangEditor-txt h5 * {
226 | line-height: 1.8;
227 | }
228 | .wangEditor-container .wangEditor-txt ul,
229 | .wangEditor-container .wangEditor-txt ol {
230 | padding-left: 20px;
231 | }
232 | .wangEditor-container .wangEditor-txt img {
233 | cursor: pointer;
234 | }
235 | .wangEditor-container .wangEditor-txt img.clicked {
236 | box-shadow: 1px 1px 10px #999;
237 | }
238 | .wangEditor-container .wangEditor-txt table.clicked {
239 | box-shadow: 1px 1px 10px #999;
240 | }
241 | .wangEditor-container .wangEditor-txt pre code {
242 | line-height: 1.5;
243 | }
244 | .wangEditor-container .wangEditor-txt:focus {
245 | outline: none;
246 | }
247 | .wangEditor-container .wangEditor-txt blockquote {
248 | display: block;
249 | border-left: 8px solid #d0e5f2;
250 | padding: 5px 10px;
251 | margin: 10px 0;
252 | line-height: 1.4;
253 | font-size: 100%;
254 | background-color: #f1f1f1;
255 | }
256 | .wangEditor-container .wangEditor-txt table {
257 | border: none;
258 | border-collapse: collapse;
259 | }
260 | .wangEditor-container .wangEditor-txt table td,
261 | .wangEditor-container .wangEditor-txt table th {
262 | border: 1px solid #999;
263 | padding: 3px 5px;
264 | min-width: 50px;
265 | height: 20px;
266 | }
267 | .wangEditor-container .wangEditor-txt pre {
268 | border: 1px solid #ccc;
269 | background-color: #f8f8f8;
270 | padding: 10px;
271 | margin: 5px 0px;
272 | font-size: 0.8em;
273 | border-radius: 3px;
274 | }
275 | .wangEditor-drop-list {
276 | display: none;
277 | position: absolute;
278 | background-color: #fff;
279 | overflow: hidden;
280 | z-index: 10;
281 | transition: height 0.7s;
282 | border-top: 1px solid #f1f1f1;
283 | box-shadow: 1px 3px 3px #999;
284 | border-left: 1px solid #ccc;
285 | border-bottom: 1px solid #999;
286 | border-right: 1px solid #999;
287 | }
288 | .wangEditor-drop-list a {
289 | text-decoration: none;
290 | display: block;
291 | color: #666;
292 | padding: 3px 5px;
293 | }
294 | .wangEditor-drop-list a:hover {
295 | background-color: #f1f1f1;
296 | }
297 | .wangEditor-drop-panel,
298 | .txt-toolbar {
299 | display: none;
300 | position: absolute;
301 | padding: 10px;
302 | font-size: 14px;
303 | /*border: 1px solid #cccccc;*/
304 | background-color: #fff;
305 | z-index: 10;
306 | border-top: 2px solid #666;
307 | box-shadow: 1px 3px 3px #999;
308 | border-left: 1px solid #ccc;
309 | border-bottom: 1px solid #999;
310 | border-right: 1px solid #999;
311 | }
312 | .wangEditor-drop-panel .tip-triangle,
313 | .txt-toolbar .tip-triangle {
314 | display: block;
315 | position: absolute;
316 | width: 0;
317 | height: 0;
318 | border: 5px solid;
319 | border-color: transparent transparent #666 transparent;
320 | top: -12px;
321 | left: 50%;
322 | margin-left: -5px;
323 | }
324 | .wangEditor-drop-panel a,
325 | .txt-toolbar a {
326 | text-decoration: none;
327 | }
328 | .wangEditor-drop-panel input[type='text'],
329 | .txt-toolbar input[type='text'] {
330 | border: none;
331 | border-bottom: 1px solid #ccc;
332 | font-size: 14px;
333 | height: 20px;
334 | color: #333;
335 | padding: 3px 0;
336 | }
337 | .wangEditor-drop-panel input[type='text']:focus,
338 | .txt-toolbar input[type='text']:focus {
339 | outline: none;
340 | border-bottom: 2px solid #1e88e5;
341 | }
342 | .wangEditor-drop-panel input[type='text'].block,
343 | .txt-toolbar input[type='text'].block {
344 | display: block;
345 | width: 100%;
346 | }
347 | .wangEditor-drop-panel textarea,
348 | .txt-toolbar textarea {
349 | border: 1px solid #ccc;
350 | }
351 | .wangEditor-drop-panel textarea:focus,
352 | .txt-toolbar textarea:focus {
353 | outline: none;
354 | border-color: #1e88e5;
355 | }
356 | .wangEditor-drop-panel button,
357 | .txt-toolbar button {
358 | font-size: 14px;
359 | color: #1e88e5;
360 | border: none;
361 | padding: 10px;
362 | background-color: #fff;
363 | cursor: pointer;
364 | border-radius: 3px;
365 | }
366 | .wangEditor-drop-panel button:hover,
367 | .txt-toolbar button:hover {
368 | background-color: #f1f1f1;
369 | }
370 | .wangEditor-drop-panel button:focus,
371 | .txt-toolbar button:focus {
372 | outline: none;
373 | }
374 | .wangEditor-drop-panel button.right,
375 | .txt-toolbar button.right {
376 | float: right;
377 | margin-left: 10px;
378 | }
379 | .wangEditor-drop-panel button.gray,
380 | .txt-toolbar button.gray {
381 | color: #999;
382 | }
383 | .wangEditor-drop-panel button.link,
384 | .txt-toolbar button.link {
385 | padding: 5px 10px;
386 | }
387 | .wangEditor-drop-panel button.link:hover,
388 | .txt-toolbar button.link:hover {
389 | background-color: #fff;
390 | text-decoration: underline;
391 | }
392 | .wangEditor-drop-panel .color-item,
393 | .txt-toolbar .color-item {
394 | display: block;
395 | float: left;
396 | width: 25px;
397 | height: 25px;
398 | text-align: center;
399 | padding: 2px;
400 | border-radius: 2px;
401 | text-decoration: underline;
402 | }
403 | .wangEditor-drop-panel .color-item:hover,
404 | .txt-toolbar .color-item:hover {
405 | background-color: #f1f1f1;
406 | }
407 | .wangEditor-drop-panel .list-menu-item,
408 | .txt-toolbar .list-menu-item {
409 | display: block;
410 | float: left;
411 | color: #333;
412 | padding: 5px 5px;
413 | border-radius: 2px;
414 | }
415 | .wangEditor-drop-panel .list-menu-item:hover,
416 | .txt-toolbar .list-menu-item:hover {
417 | background-color: #f1f1f1;
418 | }
419 | .wangEditor-drop-panel table.choose-table,
420 | .txt-toolbar table.choose-table {
421 | border: none;
422 | border-collapse: collapse;
423 | }
424 | .wangEditor-drop-panel table.choose-table td,
425 | .txt-toolbar table.choose-table td {
426 | border: 1px solid #ccc;
427 | width: 16px;
428 | height: 12px;
429 | }
430 | .wangEditor-drop-panel table.choose-table td.active,
431 | .txt-toolbar table.choose-table td.active {
432 | background-color: #ccc;
433 | opacity: 0.5;
434 | filter: alpha(opacity=50);
435 | }
436 | .wangEditor-drop-panel .panel-tab .tab-container,
437 | .txt-toolbar .panel-tab .tab-container {
438 | margin-bottom: 5px;
439 | }
440 | .wangEditor-drop-panel .panel-tab .tab-container a,
441 | .txt-toolbar .panel-tab .tab-container a {
442 | display: inline-block;
443 | color: #999;
444 | text-align: center;
445 | margin: 0 5px;
446 | padding: 5px 5px;
447 | }
448 | .wangEditor-drop-panel .panel-tab .tab-container a.selected,
449 | .txt-toolbar .panel-tab .tab-container a.selected {
450 | color: #1e88e5;
451 | border-bottom: 2px solid #1e88e5;
452 | }
453 | .wangEditor-drop-panel .panel-tab .content-container .content,
454 | .txt-toolbar .panel-tab .content-container .content {
455 | display: none;
456 | }
457 | .wangEditor-drop-panel .panel-tab .content-container .content a,
458 | .txt-toolbar .panel-tab .content-container .content a {
459 | display: inline-block;
460 | margin: 2px;
461 | padding: 2px;
462 | border-radius: 2px;
463 | }
464 | .wangEditor-drop-panel .panel-tab .content-container .content a:hover,
465 | .txt-toolbar .panel-tab .content-container .content a:hover {
466 | background-color: #f1f1f1;
467 | }
468 | .wangEditor-drop-panel .panel-tab .content-container .selected,
469 | .txt-toolbar .panel-tab .content-container .selected {
470 | display: block;
471 | }
472 | .wangEditor-drop-panel .panel-tab .emotion-content-container,
473 | .txt-toolbar .panel-tab .emotion-content-container {
474 | height: 200px;
475 | overflow-y: auto;
476 | }
477 | .wangEditor-drop-panel .upload-icon-container,
478 | .txt-toolbar .upload-icon-container {
479 | color: #ccc;
480 | text-align: center;
481 | margin: 20px 20px 15px 20px !important;
482 | padding: 5px !important;
483 | font-size: 65px;
484 | cursor: pointer;
485 | border: 2px dotted #f1f1f1;
486 | display: block !important;
487 | }
488 | .wangEditor-drop-panel .upload-icon-container:hover,
489 | .txt-toolbar .upload-icon-container:hover {
490 | color: #666;
491 | border-color: #ccc;
492 | }
493 | .wangEditor-modal {
494 | position: absolute;
495 | top: 50%;
496 | left: 50%;
497 | background-color: #fff;
498 | border-top: 1px solid #f1f1f1;
499 | box-shadow: 1px 3px 3px #999;
500 | border-top: 1px solid #ccc;
501 | border-left: 1px solid #ccc;
502 | border-bottom: 1px solid #999;
503 | border-right: 1px solid #999;
504 | }
505 | .wangEditor-modal .wangEditor-modal-close {
506 | position: absolute;
507 | top: 0;
508 | right: 0;
509 | margin-top: -25px;
510 | margin-right: -25px;
511 | font-size: 1.5em;
512 | color: #666;
513 | cursor: pointer;
514 | }
515 | @font-face {
516 | font-family: 'icomoon';
517 | src: url('../fonts/icomoon.eot');
518 | src: url('../fonts/icomoon.eot') format('embedded-opentype'),
519 | url('../fonts/icomoon.ttf') format('truetype'),
520 | url('../fonts/icomoon.woff') format('woff'),
521 | url('../fonts/icomoon.svg') format('svg');
522 | font-weight: normal;
523 | font-style: normal;
524 | }
525 | [class^='wangeditor-menu-img-'],
526 | [class*=' wangeditor-menu-img-'] {
527 | font-family: 'icomoon';
528 | speak: none;
529 | font-style: normal;
530 | font-weight: normal;
531 | font-variant: normal;
532 | text-transform: none;
533 | line-height: 1;
534 | /* Better Font Rendering =========== */
535 | -webkit-font-smoothing: antialiased;
536 | -moz-osx-font-smoothing: grayscale;
537 | }
538 | .wangeditor-menu-img-link:before {
539 | content: '\e800';
540 | }
541 | .wangeditor-menu-img-unlink:before {
542 | content: '\e801';
543 | }
544 | .wangeditor-menu-img-code:before {
545 | content: '\e802';
546 | }
547 | .wangeditor-menu-img-cancel:before {
548 | content: '\e803';
549 | }
550 | .wangeditor-menu-img-terminal:before {
551 | content: '\e804';
552 | }
553 | .wangeditor-menu-img-angle-down:before {
554 | content: '\e805';
555 | }
556 | .wangeditor-menu-img-font:before {
557 | content: '\e806';
558 | }
559 | .wangeditor-menu-img-bold:before {
560 | content: '\e807';
561 | }
562 | .wangeditor-menu-img-italic:before {
563 | content: '\e808';
564 | }
565 | .wangeditor-menu-img-header:before {
566 | content: '\e809';
567 | }
568 | .wangeditor-menu-img-align-left:before {
569 | content: '\e80a';
570 | }
571 | .wangeditor-menu-img-align-center:before {
572 | content: '\e80b';
573 | }
574 | .wangeditor-menu-img-align-right:before {
575 | content: '\e80c';
576 | }
577 | .wangeditor-menu-img-list-bullet:before {
578 | content: '\e80d';
579 | }
580 | .wangeditor-menu-img-indent-left:before {
581 | content: '\e80e';
582 | }
583 | .wangeditor-menu-img-indent-right:before {
584 | content: '\e80f';
585 | }
586 | .wangeditor-menu-img-list-numbered:before {
587 | content: '\e810';
588 | }
589 | .wangeditor-menu-img-underline:before {
590 | content: '\e811';
591 | }
592 | .wangeditor-menu-img-table:before {
593 | content: '\e812';
594 | }
595 | .wangeditor-menu-img-eraser:before {
596 | content: '\e813';
597 | }
598 | .wangeditor-menu-img-text-height:before {
599 | content: '\e814';
600 | }
601 | .wangeditor-menu-img-brush:before {
602 | content: '\e815';
603 | }
604 | .wangeditor-menu-img-pencil:before {
605 | content: '\e816';
606 | }
607 | .wangeditor-menu-img-minus:before {
608 | content: '\e817';
609 | }
610 | .wangeditor-menu-img-picture:before {
611 | content: '\e818';
612 | }
613 | .wangeditor-menu-img-file-image:before {
614 | content: '\e819';
615 | }
616 | .wangeditor-menu-img-cw:before {
617 | content: '\e81a';
618 | }
619 | .wangeditor-menu-img-ccw:before {
620 | content: '\e81b';
621 | }
622 | .wangeditor-menu-img-music:before {
623 | content: '\e911';
624 | }
625 | .wangeditor-menu-img-play:before {
626 | content: '\e912';
627 | }
628 | .wangeditor-menu-img-location:before {
629 | content: '\e947';
630 | }
631 | .wangeditor-menu-img-happy:before {
632 | content: '\e9df';
633 | }
634 | .wangeditor-menu-img-sigma:before {
635 | content: '\ea67';
636 | }
637 | .wangeditor-menu-img-enlarge2:before {
638 | content: '\e98b';
639 | }
640 | .wangeditor-menu-img-shrink2:before {
641 | content: '\e98c';
642 | }
643 | .wangeditor-menu-img-newspaper:before {
644 | content: '\e904';
645 | }
646 | .wangeditor-menu-img-camera:before {
647 | content: '\e90f';
648 | }
649 | .wangeditor-menu-img-video-camera:before {
650 | content: '\e914';
651 | }
652 | .wangeditor-menu-img-file-zip:before {
653 | content: '\e92b';
654 | }
655 | .wangeditor-menu-img-stack:before {
656 | content: '\e92e';
657 | }
658 | .wangeditor-menu-img-credit-card:before {
659 | content: '\e93f';
660 | }
661 | .wangeditor-menu-img-address-book:before {
662 | content: '\e944';
663 | }
664 | .wangeditor-menu-img-envelop:before {
665 | content: '\e945';
666 | }
667 | .wangeditor-menu-img-drawer:before {
668 | content: '\e95c';
669 | }
670 | .wangeditor-menu-img-download:before {
671 | content: '\e960';
672 | }
673 | .wangeditor-menu-img-upload:before {
674 | content: '\e961';
675 | }
676 | .wangeditor-menu-img-lock:before {
677 | content: '\e98f';
678 | }
679 | .wangeditor-menu-img-unlocked:before {
680 | content: '\e990';
681 | }
682 | .wangeditor-menu-img-wrench:before {
683 | content: '\e991';
684 | }
685 | .wangeditor-menu-img-eye:before {
686 | content: '\e9ce';
687 | }
688 | .wangeditor-menu-img-eye-blocked:before {
689 | content: '\e9d1';
690 | }
691 | .wangeditor-menu-img-command:before {
692 | content: '\ea4e';
693 | }
694 | .wangeditor-menu-img-font2:before {
695 | content: '\ea5c';
696 | }
697 | .wangeditor-menu-img-libreoffice:before {
698 | content: '\eade';
699 | }
700 | .wangeditor-menu-img-quotes-left:before {
701 | content: '\e977';
702 | }
703 | .wangeditor-menu-img-strikethrough:before {
704 | content: '\ea65';
705 | }
706 | .wangeditor-menu-img-desktop:before {
707 | content: '\f108';
708 | }
709 | .wangeditor-menu-img-tablet:before {
710 | content: '\f10a';
711 | }
712 | .wangeditor-menu-img-search-plus:before {
713 | content: '\f00e';
714 | }
715 | .wangeditor-menu-img-search-minus:before {
716 | content: '\f010';
717 | }
718 | .wangeditor-menu-img-trash-o:before {
719 | content: '\f014';
720 | }
721 | .wangeditor-menu-img-align-justify:before {
722 | content: '\f039';
723 | }
724 | .wangeditor-menu-img-arrows-v:before {
725 | content: '\f07d';
726 | }
727 | .wangeditor-menu-img-sigma2:before {
728 | content: '\ea68';
729 | }
730 | .wangeditor-menu-img-omega:before {
731 | content: '\e900';
732 | }
733 | .wangeditor-menu-img-cancel-circle:before {
734 | content: '\e901';
735 | }
736 | .hljs {
737 | display: block;
738 | overflow-x: auto;
739 | padding: 0.5em;
740 | color: #333;
741 | background: #f8f8f8;
742 | -webkit-text-size-adjust: none;
743 | }
744 | .hljs-comment,
745 | .diff .hljs-header {
746 | color: #998;
747 | font-style: italic;
748 | }
749 | .hljs-keyword,
750 | .css .rule .hljs-keyword,
751 | .hljs-winutils,
752 | .nginx .hljs-title,
753 | .hljs-subst,
754 | .hljs-request,
755 | .hljs-status {
756 | color: #333;
757 | font-weight: bold;
758 | }
759 | .hljs-number,
760 | .hljs-hexcolor,
761 | .ruby .hljs-constant {
762 | color: #008080;
763 | }
764 | .hljs-string,
765 | .hljs-tag .hljs-value,
766 | .hljs-doctag,
767 | .tex .hljs-formula {
768 | color: #d14;
769 | }
770 | .hljs-title,
771 | .hljs-id,
772 | .scss .hljs-preprocessor {
773 | color: #900;
774 | font-weight: bold;
775 | }
776 | .hljs-list .hljs-keyword,
777 | .hljs-subst {
778 | font-weight: normal;
779 | }
780 | .hljs-class .hljs-title,
781 | .hljs-type,
782 | .vhdl .hljs-literal,
783 | .tex .hljs-command {
784 | color: #458;
785 | font-weight: bold;
786 | }
787 | .hljs-tag,
788 | .hljs-tag .hljs-title,
789 | .hljs-rule .hljs-property,
790 | .django .hljs-tag .hljs-keyword {
791 | color: #000080;
792 | font-weight: normal;
793 | }
794 | .hljs-attribute,
795 | .hljs-variable,
796 | .lisp .hljs-body,
797 | .hljs-name {
798 | color: #008080;
799 | }
800 | .hljs-regexp {
801 | color: #009926;
802 | }
803 | .hljs-symbol,
804 | .ruby .hljs-symbol .hljs-string,
805 | .lisp .hljs-keyword,
806 | .clojure .hljs-keyword,
807 | .scheme .hljs-keyword,
808 | .tex .hljs-special,
809 | .hljs-prompt {
810 | color: #990073;
811 | }
812 | .hljs-built_in {
813 | color: #0086b3;
814 | }
815 | .hljs-preprocessor,
816 | .hljs-pragma,
817 | .hljs-pi,
818 | .hljs-doctype,
819 | .hljs-shebang,
820 | .hljs-cdata {
821 | color: #999;
822 | font-weight: bold;
823 | }
824 | .hljs-deletion {
825 | background: #fdd;
826 | }
827 | .hljs-addition {
828 | background: #dfd;
829 | }
830 | .diff .hljs-change {
831 | background: #0086b3;
832 | }
833 | .hljs-chunk {
834 | color: #aaa;
835 | }
836 |
--------------------------------------------------------------------------------
/src/assets/fonts/icomoon.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yimogit/yimo-vue-editor/b243fc99a6f548b4f0268190c9b4467a673c0906/src/assets/fonts/icomoon.eot
--------------------------------------------------------------------------------
/src/assets/fonts/icomoon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/src/assets/fonts/icomoon.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yimogit/yimo-vue-editor/b243fc99a6f548b4f0268190c9b4467a673c0906/src/assets/fonts/icomoon.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/icomoon.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yimogit/yimo-vue-editor/b243fc99a6f548b4f0268190c9b4467a673c0906/src/assets/fonts/icomoon.woff
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import YimoVueEditor from './Editor'
2 | import E from './assets/js/wangEditor.js'
3 |
4 | const instance = YimoVueEditor
5 |
6 | const install = (Vue, globalOptions) => {
7 | let compName = instance.name
8 | if (globalOptions) {
9 | compName = globalOptions.name || compName
10 | instance.props.globalOptions.default = () => globalOptions
11 | }
12 | Vue.component(compName, instance)
13 | }
14 | instance.install = install
15 | export default instance
16 | export { E, instance, install }
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var webpack = require('webpack')
3 |
4 | module.exports = {
5 | entry:
6 | process.env.NODE_ENV === 'production' ? './src/index.js' : './example/vue/main.js',
7 | output: {
8 | path: path.resolve(__dirname, './dist'),
9 | publicPath: '/dist/',
10 | filename: process.env.NODE_ENV === 'production'?'yimo-vue-editor.js':'build.js',
11 | library: 'YimoVueEditor', // 指定的就是你使用require时的模块名
12 | libraryTarget: 'umd', // 指定输出格式
13 | umdNamedDefine: true // 会对 UMD 的构建过程中的 AMD 模块进行命名。否则就使用匿名的 define
14 | },
15 | module: {
16 | rules: [
17 | {
18 | test: /\.css$/,
19 | use: ['vue-style-loader', 'css-loader']
20 | },
21 | {
22 | test: /\.vue$/,
23 | loader: 'vue-loader',
24 | options: {
25 | loaders: {}
26 | // other vue-loader options go here
27 | }
28 | },
29 | {
30 | test: /\.js$/,
31 | loader: 'babel-loader',
32 | exclude: /node_modules/
33 | },
34 | {
35 | test: /\.(png|jpg|gif)$/,
36 | loader: 'file-loader',
37 | options: {
38 | name: '[name].[ext]?[hash]'
39 | }
40 | },
41 | {
42 | test: /\.(svg|woff2?|eot|ttf|otf)(\?.*)?$/,
43 | loader: 'url-loader',
44 | options: {
45 | name: 'fonts/[name].[ext]?[hash]'
46 | }
47 | }
48 | ]
49 | },
50 | resolve: {
51 | alias: {
52 | vue$: 'vue/dist/vue.esm.js'
53 | },
54 | extensions: ['*', '.js', '.vue', '.json']
55 | },
56 | devServer: {
57 | proxy: {
58 | '/mockserver': {
59 | target: 'http://192.168.1.32:2233',
60 | changeOrigin: true,
61 | pathRewrite: {
62 | '^/mockserver': ''
63 | }
64 | }
65 | },
66 | host: 'localhost',
67 | historyApiFallback: true,
68 | noInfo: true,
69 | overlay: true
70 | },
71 | performance: {
72 | hints: false
73 | },
74 | devtool: '#eval-source-map'
75 | }
76 |
77 | if (process.env.NODE_ENV === 'production') {
78 | module.exports.devtool = '#source-map'
79 | // http://vue-loader.vuejs.org/en/workflow/production.html
80 | module.exports.plugins = (module.exports.plugins || []).concat([
81 | new webpack.DefinePlugin({
82 | 'process.env': {
83 | NODE_ENV: '"' + process.env.NODE_ENV + '"'
84 | }
85 | }),
86 | new webpack.optimize.UglifyJsPlugin({
87 | sourceMap: true,
88 | compress: {
89 | warnings: false
90 | }
91 | }),
92 | new webpack.LoaderOptionsPlugin({
93 | minimize: true
94 | })
95 | ])
96 | }
97 |
--------------------------------------------------------------------------------