biso24-editor 1.3.0
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/CKEditor4/.eslintrc.json +4 -0
- package/CKEditor4/CHANGES.md +2182 -0
- package/CKEditor4/LICENSE.md +1436 -0
- package/CKEditor4/README.md +39 -0
- package/CKEditor4/SECURITY.md +10 -0
- package/CKEditor4/adapters/jquery.js +158 -0
- package/CKEditor4/bender-runner.config.json +16 -0
- package/CKEditor4/build-config.js +100 -0
- package/CKEditor4/ckeditor.js +30065 -0
- package/CKEditor4/config.js +39 -0
- package/CKEditor4/contents.css +161 -0
- package/CKEditor4/lang/vi.js +475 -0
- package/CKEditor4/plugins/a11yhelp/dialogs/a11yhelp.js +143 -0
- package/CKEditor4/plugins/a11yhelp/dialogs/lang/vi.js +122 -0
- package/CKEditor4/plugins/ajax/plugin.js +241 -0
- package/CKEditor4/plugins/autocomplete/plugin.js +1655 -0
- package/CKEditor4/plugins/autocomplete/skins/default.css +38 -0
- package/CKEditor4/plugins/custompaste/plugin.js +57 -0
- package/CKEditor4/plugins/dialog/dialogDefinition.js +4 -0
- package/CKEditor4/plugins/dialog/styles/dialog.css +18 -0
- package/CKEditor4/plugins/font/lang/vi.js +14 -0
- package/CKEditor4/plugins/font/plugin.js +535 -0
- package/CKEditor4/plugins/icons.png +0 -0
- package/CKEditor4/plugins/icons_hidpi.png +0 -0
- package/CKEditor4/plugins/image2/dialogs/image2.js +558 -0
- package/CKEditor4/plugins/image2/icons/hidpi/image.png +0 -0
- package/CKEditor4/plugins/image2/icons/image.png +0 -0
- package/CKEditor4/plugins/image2/lang/vi.js +21 -0
- package/CKEditor4/plugins/image2/plugin.js +1708 -0
- package/CKEditor4/plugins/justify/icons/hidpi/justifyblock.png +0 -0
- package/CKEditor4/plugins/justify/icons/hidpi/justifycenter.png +0 -0
- package/CKEditor4/plugins/justify/icons/hidpi/justifyleft.png +0 -0
- package/CKEditor4/plugins/justify/icons/hidpi/justifyright.png +0 -0
- package/CKEditor4/plugins/justify/icons/justifyblock.png +0 -0
- package/CKEditor4/plugins/justify/icons/justifycenter.png +0 -0
- package/CKEditor4/plugins/justify/icons/justifyleft.png +0 -0
- package/CKEditor4/plugins/justify/icons/justifyright.png +0 -0
- package/CKEditor4/plugins/justify/plugin.js +266 -0
- package/CKEditor4/plugins/justify_group/icons/hidpi/justifycenter.png +0 -0
- package/CKEditor4/plugins/justify_group/icons/justifycenter.png +0 -0
- package/CKEditor4/plugins/justify_group/plugin.js +64 -0
- package/CKEditor4/plugins/lineheight/LICENSE +22 -0
- package/CKEditor4/plugins/lineheight/README.md +2 -0
- package/CKEditor4/plugins/lineheight/lang/vi.js +3 -0
- package/CKEditor4/plugins/lineheight/plugin.js +99 -0
- package/CKEditor4/plugins/lineheight/readme.txt +30 -0
- package/CKEditor4/plugins/link/dialogs/anchor.js +82 -0
- package/CKEditor4/plugins/link/dialogs/link.js +777 -0
- package/CKEditor4/plugins/link/images/anchor.png +0 -0
- package/CKEditor4/plugins/link/images/hidpi/anchor.png +0 -0
- package/CKEditor4/plugins/magicline/images/hidpi/icon-rtl.png +0 -0
- package/CKEditor4/plugins/magicline/images/hidpi/icon.png +0 -0
- package/CKEditor4/plugins/magicline/images/icon-rtl.png +0 -0
- package/CKEditor4/plugins/magicline/images/icon.png +0 -0
- package/CKEditor4/plugins/mentions/plugin.js +471 -0
- package/CKEditor4/plugins/menubutton/plugin.js +99 -0
- package/CKEditor4/plugins/pastefromword/filter/default.js +849 -0
- package/CKEditor4/plugins/pastetools/filter/common.js +445 -0
- package/CKEditor4/plugins/pastetools/filter/image.js +163 -0
- package/CKEditor4/plugins/pdffile/icons/exporttopdf.png +0 -0
- package/CKEditor4/plugins/pdffile/icons/hidpi/exporttopdf.png +0 -0
- package/CKEditor4/plugins/pdffile/plugin.js +36 -0
- package/CKEditor4/plugins/placeholder_button/plugin.js +31 -0
- package/CKEditor4/plugins/sourcedialog/dialogs/sourcedialog.js +88 -0
- package/CKEditor4/plugins/sourcedialog/icons/hidpi/sourcedialog-rtl.png +0 -0
- package/CKEditor4/plugins/sourcedialog/icons/hidpi/sourcedialog.png +0 -0
- package/CKEditor4/plugins/sourcedialog/icons/sourcedialog-rtl.png +0 -0
- package/CKEditor4/plugins/sourcedialog/icons/sourcedialog.png +0 -0
- package/CKEditor4/plugins/sourcedialog/lang/vi.js +9 -0
- package/CKEditor4/plugins/sourcedialog/plugin.js +30 -0
- package/CKEditor4/plugins/textmatch/plugin.js +331 -0
- package/CKEditor4/plugins/textwatcher/plugin.js +295 -0
- package/CKEditor4/plugins/widget/images/handle.png +0 -0
- package/CKEditor4/plugins/wordfile/icons/exporttoword.png +0 -0
- package/CKEditor4/plugins/wordfile/icons/hidpi/exporttoword.png +0 -0
- package/CKEditor4/plugins/wordfile/icons/hidpi/importfromword.png +0 -0
- package/CKEditor4/plugins/wordfile/icons/importfromword.png +0 -0
- package/CKEditor4/plugins/wordfile/plugin.js +161 -0
- package/CKEditor4/skins/moono-lisa/dialog.css +685 -0
- package/CKEditor4/skins/moono-lisa/dialog_ie.css +721 -0
- package/CKEditor4/skins/moono-lisa/dialog_ie8.css +746 -0
- package/CKEditor4/skins/moono-lisa/dialog_iequirks.css +724 -0
- package/CKEditor4/skins/moono-lisa/editor.css +1551 -0
- package/CKEditor4/skins/moono-lisa/editor_gecko.css +1556 -0
- package/CKEditor4/skins/moono-lisa/editor_ie.css +1588 -0
- package/CKEditor4/skins/moono-lisa/editor_ie8.css +1639 -0
- package/CKEditor4/skins/moono-lisa/editor_iequirks.css +1632 -0
- package/CKEditor4/skins/moono-lisa/icons.png +0 -0
- package/CKEditor4/skins/moono-lisa/icons_hidpi.png +0 -0
- package/CKEditor4/skins/moono-lisa/images/arrow.png +0 -0
- package/CKEditor4/skins/moono-lisa/images/close.png +0 -0
- package/CKEditor4/skins/moono-lisa/images/hidpi/close.png +0 -0
- package/CKEditor4/skins/moono-lisa/images/hidpi/lock-open.png +0 -0
- package/CKEditor4/skins/moono-lisa/images/hidpi/lock.png +0 -0
- package/CKEditor4/skins/moono-lisa/images/hidpi/refresh.png +0 -0
- package/CKEditor4/skins/moono-lisa/images/lock-open.png +0 -0
- package/CKEditor4/skins/moono-lisa/images/lock.png +0 -0
- package/CKEditor4/skins/moono-lisa/images/refresh.png +0 -0
- package/CKEditor4/skins/moono-lisa/images/spinner.gif +0 -0
- package/CKEditor4/skins/moono-lisa/readme.md +46 -0
- package/CKEditor4/styles.js +136 -0
- package/CKEditor4/vendor/promise.js +385 -0
- package/README.md +3 -0
- package/package.json +9 -0
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
( function() {
|
|
9
|
+
|
|
10
|
+
CKEDITOR.plugins.add( 'textwatcher', {} );
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* API exposed by the [Text Watcher](https://ckeditor.com/cke4/addon/textwatcher) plugin.
|
|
14
|
+
*
|
|
15
|
+
* Class implementing the text watcher — a base for features like
|
|
16
|
+
* autocomplete. It fires the {@link #matched} and {@link #unmatched} events
|
|
17
|
+
* based on changes in the text and the position of the caret in the editor.
|
|
18
|
+
*
|
|
19
|
+
* To check whether the text matches some criteria, the text watcher uses
|
|
20
|
+
* a callback function which should return the matching text and a {@link CKEDITOR.dom.range}
|
|
21
|
+
* for that text.
|
|
22
|
+
*
|
|
23
|
+
* Since the text watcher works on the DOM where searching for text
|
|
24
|
+
* is pretty complicated, it is usually recommended to use the {@link CKEDITOR.plugins.textMatch#match}
|
|
25
|
+
* function.
|
|
26
|
+
*
|
|
27
|
+
* Example:
|
|
28
|
+
*
|
|
29
|
+
* ```javascript
|
|
30
|
+
* function textTestCallback( range ) {
|
|
31
|
+
* // You do not want to autocomplete a non-empty selection.
|
|
32
|
+
* if ( !range.collapsed ) {
|
|
33
|
+
* return null;
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
36
|
+
* // Use the text match plugin which does the tricky job of doing
|
|
37
|
+
* // a text search in the DOM. The matchCallback function should return
|
|
38
|
+
* // a matching fragment of the text.
|
|
39
|
+
* return CKEDITOR.plugins.textMatch.match( range, matchCallback );
|
|
40
|
+
* }
|
|
41
|
+
*
|
|
42
|
+
* function matchCallback( text, offset ) {
|
|
43
|
+
* // Get the text before the caret.
|
|
44
|
+
* var left = text.slice( 0, offset ),
|
|
45
|
+
* // Will look for an '@' character followed by word characters.
|
|
46
|
+
* match = left.match( /@\w*$/ );
|
|
47
|
+
*
|
|
48
|
+
* if ( !match ) {
|
|
49
|
+
* return null;
|
|
50
|
+
* }
|
|
51
|
+
* return { start: match.index, end: offset };
|
|
52
|
+
* }
|
|
53
|
+
*
|
|
54
|
+
* // Initialize the text watcher.
|
|
55
|
+
* var textWatcher = new CKEDITOR.plugins.textWatcher( editor, textTestCallback );
|
|
56
|
+
* // Start listening.
|
|
57
|
+
* textWatcher.attach();
|
|
58
|
+
*
|
|
59
|
+
* // Handle text matching.
|
|
60
|
+
* textWatcher.on( 'matched', function( evt ) {
|
|
61
|
+
* autocomplete.setQuery( evt.data.text );
|
|
62
|
+
* } );
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* @class CKEDITOR.plugins.textWatcher
|
|
66
|
+
* @since 4.10.0
|
|
67
|
+
* @mixins CKEDITOR.event
|
|
68
|
+
* @constructor Creates the text watcher instance.
|
|
69
|
+
* @param {CKEDITOR.editor} editor The editor instance to watch in.
|
|
70
|
+
* @param {Function} callback Callback executed when the text watcher
|
|
71
|
+
* thinks that something might have changed.
|
|
72
|
+
* @param {Number} [throttle=0] Throttle interval, see {@link #throttle}.
|
|
73
|
+
* @param {CKEDITOR.dom.range} callback.range The range representing the caret position.
|
|
74
|
+
* @param {Object} [callback.return=null] Matching text data (`null` if nothing matches).
|
|
75
|
+
* @param {String} callback.return.text The matching text.
|
|
76
|
+
* @param {CKEDITOR.dom.range} callback.return.range A range in the DOM for the text that matches.
|
|
77
|
+
*/
|
|
78
|
+
function TextWatcher( editor, callback, throttle ) {
|
|
79
|
+
/**
|
|
80
|
+
* The editor instance which the text watcher watches.
|
|
81
|
+
*
|
|
82
|
+
* @readonly
|
|
83
|
+
* @property {CKEDITOR.editor}
|
|
84
|
+
*/
|
|
85
|
+
this.editor = editor;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* The last matched text.
|
|
89
|
+
*
|
|
90
|
+
* @readonly
|
|
91
|
+
* @property {String}
|
|
92
|
+
*/
|
|
93
|
+
this.lastMatched = null;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Whether the next check should be ignored. See the {@link #consumeNext} method.
|
|
97
|
+
*
|
|
98
|
+
* @readonly
|
|
99
|
+
*/
|
|
100
|
+
this.ignoreNext = false;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* The callback passed to the {@link CKEDITOR.plugins.textWatcher} constructor.
|
|
104
|
+
*
|
|
105
|
+
* @readonly
|
|
106
|
+
* @property {Function}
|
|
107
|
+
*/
|
|
108
|
+
this.callback = callback;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Keys that should be ignored by the {@link #check} method.
|
|
112
|
+
*
|
|
113
|
+
* @readonly
|
|
114
|
+
* @property {Number[]}
|
|
115
|
+
*/
|
|
116
|
+
this.ignoredKeys = [
|
|
117
|
+
16, // Shift
|
|
118
|
+
17, // Ctrl
|
|
119
|
+
18, // Alt
|
|
120
|
+
91, // Cmd
|
|
121
|
+
35, // End
|
|
122
|
+
36, // Home
|
|
123
|
+
37, // Left
|
|
124
|
+
38, // Up
|
|
125
|
+
39, // Right
|
|
126
|
+
40, // Down
|
|
127
|
+
33, // PageUp
|
|
128
|
+
34 // PageUp
|
|
129
|
+
];
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Listeners registered by this text watcher.
|
|
133
|
+
*
|
|
134
|
+
* @private
|
|
135
|
+
*/
|
|
136
|
+
this._listeners = [];
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Indicates throttle threshold mitigating text checks.
|
|
140
|
+
*
|
|
141
|
+
* Higher levels of the throttle threshold will create a delay for text watcher checks
|
|
142
|
+
* but also improve its performance.
|
|
143
|
+
*
|
|
144
|
+
* See the {@link CKEDITOR.tools#throttle throttle} feature for more information.
|
|
145
|
+
*
|
|
146
|
+
* @readonly
|
|
147
|
+
* @property {Number} [throttle=0]
|
|
148
|
+
*/
|
|
149
|
+
this.throttle = throttle || 0;
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* The {@link CKEDITOR.tools#throttle throttle buffer} used to mitigate text checks.
|
|
153
|
+
*
|
|
154
|
+
* @private
|
|
155
|
+
*/
|
|
156
|
+
this._buffer = CKEDITOR.tools.throttle( this.throttle, testTextMatch, this );
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Event fired when the text is no longer matching.
|
|
160
|
+
*
|
|
161
|
+
* @event matched
|
|
162
|
+
* @param {Object} data The value returned by the {@link #callback}.
|
|
163
|
+
* @param {String} data.text
|
|
164
|
+
* @param {CKEDITOR.dom.range} data.range
|
|
165
|
+
*/
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Event fired when the text stops matching.
|
|
169
|
+
*
|
|
170
|
+
* @event unmatched
|
|
171
|
+
*/
|
|
172
|
+
|
|
173
|
+
function testTextMatch( selectionRange ) {
|
|
174
|
+
var matched = this.callback( selectionRange );
|
|
175
|
+
|
|
176
|
+
if ( matched ) {
|
|
177
|
+
if ( matched.text == this.lastMatched ) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
this.lastMatched = matched.text;
|
|
182
|
+
this.fire( 'matched', matched );
|
|
183
|
+
} else if ( this.lastMatched ) {
|
|
184
|
+
this.unmatch();
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
TextWatcher.prototype = {
|
|
190
|
+
/**
|
|
191
|
+
* Attaches the text watcher to the {@link #editor}.
|
|
192
|
+
*
|
|
193
|
+
* @chainable
|
|
194
|
+
*/
|
|
195
|
+
attach: function() {
|
|
196
|
+
var editor = this.editor;
|
|
197
|
+
|
|
198
|
+
this._listeners.push( editor.on( 'contentDom', onContentDom, this ) );
|
|
199
|
+
this._listeners.push( editor.on( 'blur', unmatch, this ) );
|
|
200
|
+
this._listeners.push( editor.on( 'beforeModeUnload', unmatch, this ) );
|
|
201
|
+
this._listeners.push( editor.on( 'setData', unmatch, this ) );
|
|
202
|
+
this._listeners.push( editor.on( 'afterCommandExec', unmatch, this ) );
|
|
203
|
+
|
|
204
|
+
// Attach if editor is already initialized.
|
|
205
|
+
if ( editor.editable() ) {
|
|
206
|
+
onContentDom.call( this );
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return this;
|
|
210
|
+
|
|
211
|
+
function onContentDom() {
|
|
212
|
+
var editable = editor.editable();
|
|
213
|
+
|
|
214
|
+
this._listeners.push( editable.attachListener( editable, 'keyup', check, this ) );
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// CKEditor's event system has a limitation that one function (in this case this.check)
|
|
218
|
+
// cannot be used as listener for the same event more than once. Hence, wrapper function.
|
|
219
|
+
function check( evt ) {
|
|
220
|
+
this.check( evt );
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function unmatch() {
|
|
224
|
+
this.unmatch();
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Triggers a text check. Fires the {@link #matched} and {@link #unmatched} events.
|
|
230
|
+
* The {@link #matched} event will not be fired twice in a row for the same text
|
|
231
|
+
* unless the text watcher is {@link #unmatch reset}.
|
|
232
|
+
*
|
|
233
|
+
* @param {CKEDITOR.dom.event/CKEDITOR.eventInfo} [evt]
|
|
234
|
+
*/
|
|
235
|
+
check: function( evt ) {
|
|
236
|
+
if ( this.ignoreNext ) {
|
|
237
|
+
this.ignoreNext = false;
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Ignore control keys, so they don't trigger the check.
|
|
242
|
+
if ( evt && evt.name == 'keyup' && ( CKEDITOR.tools.array.indexOf( this.ignoredKeys, evt.data.getKey() ) != -1 ) ) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
var sel = this.editor.getSelection();
|
|
247
|
+
if ( !sel ) {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
var selectionRange = sel.getRanges()[ 0 ];
|
|
252
|
+
if ( !selectionRange ) {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
this._buffer.input( selectionRange );
|
|
257
|
+
},
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Ignores the next {@link #check}.
|
|
261
|
+
*
|
|
262
|
+
* @chainable
|
|
263
|
+
*/
|
|
264
|
+
consumeNext: function() {
|
|
265
|
+
this.ignoreNext = true;
|
|
266
|
+
return this;
|
|
267
|
+
},
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Resets the state and fires the {@link #unmatched} event.
|
|
271
|
+
*
|
|
272
|
+
* @chainable
|
|
273
|
+
*/
|
|
274
|
+
unmatch: function() {
|
|
275
|
+
this.lastMatched = null;
|
|
276
|
+
this.fire( 'unmatched' );
|
|
277
|
+
return this;
|
|
278
|
+
},
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Destroys the text watcher instance. The DOM event listeners will be cleaned up.
|
|
282
|
+
*/
|
|
283
|
+
destroy: function() {
|
|
284
|
+
CKEDITOR.tools.array.forEach( this._listeners, function( obj ) {
|
|
285
|
+
obj.removeListener();
|
|
286
|
+
} );
|
|
287
|
+
this._listeners = [];
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
CKEDITOR.event.implementOn( TextWatcher.prototype );
|
|
292
|
+
|
|
293
|
+
CKEDITOR.plugins.textWatcher = TextWatcher;
|
|
294
|
+
|
|
295
|
+
} )();
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A plugin to enable placeholder tokens to be inserted into the CKEditor message. Use on its own or with teh placeholder plugin.
|
|
3
|
+
* The default format is compatible with the placeholders syntex
|
|
4
|
+
*
|
|
5
|
+
* @version 0.1
|
|
6
|
+
* @Author Troy Lutton
|
|
7
|
+
* @license MIT
|
|
8
|
+
*
|
|
9
|
+
* This is a pure modification for the placeholders plugin. All credit goes to Stuart Sillitoe for creating the original (stuartsillitoe.co.uk)
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
const INSERTHTMLFILE_ALLOWED_EXTENSIONS = ['docx', 'txt']; //, 'txt', 'htm', 'html'
|
|
13
|
+
|
|
14
|
+
CKEDITOR.plugins.add('wordfile', {
|
|
15
|
+
icons: 'exporttoword,importfromword',
|
|
16
|
+
hidpi: true,
|
|
17
|
+
init: function (editor) {
|
|
18
|
+
// add the menu to the editor
|
|
19
|
+
|
|
20
|
+
editor.addCommand('exporttoword', {
|
|
21
|
+
exec: function (editor) {
|
|
22
|
+
const preHtml = `
|
|
23
|
+
<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-html40">
|
|
24
|
+
<head><meta charset="utf-8"><title></title></head><body>`;
|
|
25
|
+
const postHtml = '</body></html>';
|
|
26
|
+
const html = preHtml + (editor.getData() || '').toString() + postHtml;
|
|
27
|
+
|
|
28
|
+
const blob = new Blob(['\ufeff', html], {
|
|
29
|
+
type: 'application/msword',
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const link = document.createElement('a');
|
|
33
|
+
link.href = URL.createObjectURL(blob);
|
|
34
|
+
link.download = 'document.doc';
|
|
35
|
+
link.click();
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// editor.ui.addButton('exporttoword', {
|
|
40
|
+
// label: 'Xuất tệp Word',
|
|
41
|
+
// command: 'exporttoword',
|
|
42
|
+
// className: 'wordfile',
|
|
43
|
+
// toolbar: 'others',
|
|
44
|
+
// });
|
|
45
|
+
|
|
46
|
+
const inputElement = document.createElement('input');
|
|
47
|
+
inputElement.type = 'file';
|
|
48
|
+
inputElement.style.display = 'none';
|
|
49
|
+
inputElement.id = 'importfromword-input';
|
|
50
|
+
inputElement.setAttribute('accept', INSERTHTMLFILE_ALLOWED_EXTENSIONS.map((item) => `.${item}`).toString());
|
|
51
|
+
inputElement.onchange = async (event) => {
|
|
52
|
+
var file = event.target.files[0];
|
|
53
|
+
var fileUrl = URL.createObjectURL(file);
|
|
54
|
+
var extension = file.name.split('.').pop();
|
|
55
|
+
var rawFile = new XMLHttpRequest();
|
|
56
|
+
|
|
57
|
+
if (INSERTHTMLFILE_ALLOWED_EXTENSIONS.indexOf(extension) == -1) {
|
|
58
|
+
var extList = '';
|
|
59
|
+
for (var i in INSERTHTMLFILE_ALLOWED_EXTENSIONS) {
|
|
60
|
+
if (extList != '') {
|
|
61
|
+
extList = extList + ', ';
|
|
62
|
+
}
|
|
63
|
+
extList = extList + INSERTHTMLFILE_ALLOWED_EXTENSIONS[i];
|
|
64
|
+
}
|
|
65
|
+
alert(lang.extensionError + ' ' + extList + '');
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (['docx', 'doc'].includes(extension) && editor.getCommand('docx')) {
|
|
70
|
+
const docx = editor.getCommand('docx');
|
|
71
|
+
const tempContainer = document.createElement('div');
|
|
72
|
+
docx
|
|
73
|
+
.renderAsync(await (await fetch(fileUrl)).arrayBuffer(), tempContainer, null, {
|
|
74
|
+
className: '',
|
|
75
|
+
useBase64URL: true,
|
|
76
|
+
breakPages: true,
|
|
77
|
+
inWrapper: false,
|
|
78
|
+
ignoreWidth: true,
|
|
79
|
+
ignoreHeight: true,
|
|
80
|
+
renderHeaders: false,
|
|
81
|
+
renderFooters: false,
|
|
82
|
+
trimXmlDeclaration: true,
|
|
83
|
+
})
|
|
84
|
+
.then((x) => {
|
|
85
|
+
const spans = tempContainer.querySelectorAll('span');
|
|
86
|
+
|
|
87
|
+
spans.forEach((span) => {
|
|
88
|
+
if (span.querySelector('div') && span.children.length === 1) {
|
|
89
|
+
const div = document.createElement('div');
|
|
90
|
+
|
|
91
|
+
for (let i = 0; i < span.attributes.length; i++) {
|
|
92
|
+
div.setAttribute(span.attributes[i].name, span.attributes[i].value);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
while (span.firstChild) {
|
|
96
|
+
div.appendChild(span.firstChild);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
span.parentNode.replaceChild(div, span);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
const pTags = tempContainer.querySelectorAll('p');
|
|
103
|
+
|
|
104
|
+
pTags.forEach((pTag) => {
|
|
105
|
+
if (pTag.querySelector('div') && pTag.children.length === 1) {
|
|
106
|
+
const div = document.createElement('div');
|
|
107
|
+
|
|
108
|
+
for (let i = 0; i < pTag.attributes.length; i++) {
|
|
109
|
+
div.setAttribute(pTag.attributes[i].name, pTag.attributes[i].value);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
while (pTag.firstChild) {
|
|
113
|
+
div.appendChild(pTag.firstChild);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
pTag.parentNode.replaceChild(div, pTag);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
const htmlValue = tempContainer.innerHTML;
|
|
121
|
+
editor.setData(htmlValue.replaceAll('application/octet-stream;', 'image/png;'));
|
|
122
|
+
});
|
|
123
|
+
} else {
|
|
124
|
+
rawFile.open('GET', fileUrl, false);
|
|
125
|
+
rawFile.onreadystatechange = function () {
|
|
126
|
+
if (rawFile.readyState === 4) {
|
|
127
|
+
if (rawFile.status === 200 || (rawFile.status == 0 && rawFile.responseText.length > 0)) {
|
|
128
|
+
editor.insertHtml(rawFile.responseText);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
rawFile.send(null);
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
editor.addCommand('importfromword', {
|
|
137
|
+
exec: function (editor) {
|
|
138
|
+
const element = editor.element.$.querySelector('#importfromword-label');
|
|
139
|
+
if (element) {
|
|
140
|
+
editor.element.$.appendChild(inputElement);
|
|
141
|
+
element.click();
|
|
142
|
+
editor.element.$.removeChild(inputElement);
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
editor.ui.addButton('importfromword', {
|
|
147
|
+
label: 'Nhập tệp Word',
|
|
148
|
+
className: 'wordfile',
|
|
149
|
+
toolbar: 'others',
|
|
150
|
+
command: 'importfromword',
|
|
151
|
+
});
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
afterInit: function (editor) {
|
|
155
|
+
const labelElement = document.createElement('label');
|
|
156
|
+
labelElement.setAttribute('for', 'importfromword-input');
|
|
157
|
+
labelElement.id = 'importfromword-label';
|
|
158
|
+
|
|
159
|
+
editor.element.$.appendChild(labelElement);
|
|
160
|
+
},
|
|
161
|
+
});
|