diff options
Diffstat (limited to 'sources/plugins/clipboard/dialogs/paste.js')
-rw-r--r-- | sources/plugins/clipboard/dialogs/paste.js | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/sources/plugins/clipboard/dialogs/paste.js b/sources/plugins/clipboard/dialogs/paste.js new file mode 100644 index 0000000..80ce29f --- /dev/null +++ b/sources/plugins/clipboard/dialogs/paste.js | |||
@@ -0,0 +1,254 @@ | |||
1 | /** | ||
2 | * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved. | ||
3 | * For licensing, see LICENSE.md or http://ckeditor.com/license | ||
4 | */ | ||
5 | |||
6 | CKEDITOR.dialog.add( 'paste', function( editor ) { | ||
7 | var lang = editor.lang.clipboard, | ||
8 | clipboard = CKEDITOR.plugins.clipboard, | ||
9 | lastDataTransfer; | ||
10 | |||
11 | function onPasteFrameLoad( win ) { | ||
12 | var doc = new CKEDITOR.dom.document( win.document ), | ||
13 | body = doc.getBody(), | ||
14 | script = doc.getById( 'cke_actscrpt' ); | ||
15 | |||
16 | script && script.remove(); | ||
17 | |||
18 | body.setAttribute( 'contenteditable', true ); | ||
19 | |||
20 | // Forward dataTransfer (#13883). | ||
21 | body.on( clipboard.mainPasteEvent, function( evt ) { | ||
22 | var dataTransfer = clipboard.initPasteDataTransfer( evt ); | ||
23 | |||
24 | if ( !lastDataTransfer ) { | ||
25 | lastDataTransfer = dataTransfer; | ||
26 | } else | ||
27 | // For two paste with the same dataTransfer we can use that dataTransfer (two internal pastes are | ||
28 | // considered as an internal paste). | ||
29 | if ( dataTransfer != lastDataTransfer ) { | ||
30 | // If there were two paste with different DataTransfer objects create a new, empty, data transfer | ||
31 | // and use it (one internal and one external paste are considered as external paste). | ||
32 | lastDataTransfer = clipboard.initPasteDataTransfer(); | ||
33 | } | ||
34 | } ); | ||
35 | |||
36 | // IE before version 8 will leave cursor blinking inside the document after | ||
37 | // editor blurred unless we clean up the selection. (#4716) | ||
38 | if ( CKEDITOR.env.ie && CKEDITOR.env.version < 8 ) { | ||
39 | doc.getWindow().on( 'blur', function() { | ||
40 | doc.$.selection.empty(); | ||
41 | } ); | ||
42 | } | ||
43 | |||
44 | doc.on( 'keydown', function( e ) { | ||
45 | var domEvent = e.data, | ||
46 | key = domEvent.getKeystroke(), | ||
47 | processed; | ||
48 | |||
49 | switch ( key ) { | ||
50 | case 27: | ||
51 | this.hide(); | ||
52 | processed = 1; | ||
53 | break; | ||
54 | |||
55 | case 9: | ||
56 | case CKEDITOR.SHIFT + 9: | ||
57 | this.changeFocus( 1 ); | ||
58 | processed = 1; | ||
59 | } | ||
60 | |||
61 | processed && domEvent.preventDefault(); | ||
62 | }, this ); | ||
63 | |||
64 | editor.fire( 'ariaWidget', new CKEDITOR.dom.element( win.frameElement ) ); | ||
65 | |||
66 | // Handle pending focus. | ||
67 | if ( doc.getWindow().getFrame().removeCustomData( 'pendingFocus' ) ) | ||
68 | body.focus(); | ||
69 | } | ||
70 | |||
71 | // If pasteDialogCommit wasn't canceled by e.g. editor.getClipboardData | ||
72 | // then fire paste event. | ||
73 | // Do not use editor#paste, because it would start from beforePaste event. | ||
74 | editor.on( 'pasteDialogCommit', function( evt ) { | ||
75 | if ( evt.data ) | ||
76 | editor.fire( 'paste', { | ||
77 | type: 'auto', | ||
78 | dataValue: evt.data.dataValue, | ||
79 | method: 'paste', | ||
80 | dataTransfer: evt.data.dataTransfer || clipboard.initPasteDataTransfer() | ||
81 | } ); | ||
82 | }, null, null, 1000 ); | ||
83 | |||
84 | return { | ||
85 | title: lang.title, | ||
86 | |||
87 | minWidth: CKEDITOR.env.ie && CKEDITOR.env.quirks ? 370 : 350, | ||
88 | minHeight: CKEDITOR.env.quirks ? 250 : 245, | ||
89 | onShow: function() { | ||
90 | // FIREFOX BUG: Force the browser to render the dialog to make the to-be- | ||
91 | // inserted iframe editable. (#3366) | ||
92 | this.parts.dialog.$.offsetHeight; | ||
93 | |||
94 | this.setupContent(); | ||
95 | |||
96 | // Set dialog title to the custom value (set e.g. in editor.openDialog callback) and reset this value. | ||
97 | // If custom title not set, use default one. | ||
98 | this.parts.title.setHtml( this.customTitle || lang.title ); | ||
99 | this.customTitle = null; | ||
100 | }, | ||
101 | |||
102 | onLoad: function() { | ||
103 | if ( ( CKEDITOR.env.ie7Compat || CKEDITOR.env.ie6Compat ) && editor.lang.dir == 'rtl' ) | ||
104 | this.parts.contents.setStyle( 'overflow', 'hidden' ); | ||
105 | }, | ||
106 | |||
107 | onOk: function() { | ||
108 | this.commitContent(); | ||
109 | }, | ||
110 | |||
111 | contents: [ { | ||
112 | id: 'general', | ||
113 | label: editor.lang.common.generalTab, | ||
114 | elements: [ | ||
115 | { | ||
116 | type: 'html', | ||
117 | id: 'securityMsg', | ||
118 | html: '<div style="white-space:normal;width:340px">' + lang.securityMsg + '</div>' | ||
119 | }, | ||
120 | { | ||
121 | type: 'html', | ||
122 | id: 'pasteMsg', | ||
123 | html: '<div style="white-space:normal;width:340px">' + lang.pasteMsg + '</div>' | ||
124 | }, | ||
125 | { | ||
126 | type: 'html', | ||
127 | id: 'editing_area', | ||
128 | style: 'width:100%;height:100%', | ||
129 | html: '', | ||
130 | focus: function() { | ||
131 | var iframe = this.getInputElement(), | ||
132 | doc = iframe.getFrameDocument(), | ||
133 | body = doc.getBody(); | ||
134 | |||
135 | // Frame content may not loaded at the moment. | ||
136 | if ( !body || body.isReadOnly() ) | ||
137 | iframe.setCustomData( 'pendingFocus', 1 ); | ||
138 | else | ||
139 | body.focus(); | ||
140 | }, | ||
141 | setup: function() { | ||
142 | var dialog = this.getDialog(); | ||
143 | var htmlToLoad = '<html dir="' + editor.config.contentsLangDirection + '"' + | ||
144 | ' lang="' + ( editor.config.contentsLanguage || editor.langCode ) + '">' + | ||
145 | '<head><style>body{margin:3px;height:95%;word-break:break-all;}</style></head><body>' + | ||
146 | '<script id="cke_actscrpt" type="text/javascript">' + | ||
147 | 'window.parent.CKEDITOR.tools.callFunction(' + CKEDITOR.tools.addFunction( onPasteFrameLoad, dialog ) + ',this);' + | ||
148 | '</script></body>' + | ||
149 | '</html>'; | ||
150 | |||
151 | var src = | ||
152 | CKEDITOR.env.air ? | ||
153 | 'javascript:void(0)' : // jshint ignore:line | ||
154 | ( CKEDITOR.env.ie && !CKEDITOR.env.edge ) ? | ||
155 | 'javascript:void((function(){' + encodeURIComponent( // jshint ignore:line | ||
156 | 'document.open();' + | ||
157 | '(' + CKEDITOR.tools.fixDomain + ')();' + | ||
158 | 'document.close();' | ||
159 | ) + '})())"' | ||
160 | : ''; | ||
161 | |||
162 | var iframe = CKEDITOR.dom.element.createFromHtml( '<iframe' + | ||
163 | ' class="cke_pasteframe"' + | ||
164 | ' frameborder="0" ' + | ||
165 | ' allowTransparency="true"' + | ||
166 | ' src="' + src + '"' + | ||
167 | ' aria-label="' + lang.pasteArea + '"' + | ||
168 | ' aria-describedby="' + dialog.getContentElement( 'general', 'pasteMsg' ).domId + '"' + | ||
169 | '></iframe>' ); | ||
170 | |||
171 | // Reset last data transfer. | ||
172 | lastDataTransfer = null; | ||
173 | |||
174 | iframe.on( 'load', function( e ) { | ||
175 | e.removeListener(); | ||
176 | |||
177 | var doc = iframe.getFrameDocument(); | ||
178 | doc.write( htmlToLoad ); | ||
179 | |||
180 | editor.focusManager.add( doc.getBody() ); | ||
181 | |||
182 | if ( CKEDITOR.env.air ) | ||
183 | onPasteFrameLoad.call( this, doc.getWindow().$ ); | ||
184 | }, dialog ); | ||
185 | |||
186 | iframe.setCustomData( 'dialog', dialog ); | ||
187 | |||
188 | var container = this.getElement(); | ||
189 | container.setHtml( '' ); | ||
190 | container.append( iframe ); | ||
191 | |||
192 | // IE need a redirect on focus to make | ||
193 | // the cursor blinking inside iframe. (#5461) | ||
194 | if ( CKEDITOR.env.ie && !CKEDITOR.env.edge ) { | ||
195 | var focusGrabber = CKEDITOR.dom.element.createFromHtml( '<span tabindex="-1" style="position:absolute" role="presentation"></span>' ); | ||
196 | focusGrabber.on( 'focus', function() { | ||
197 | // Since fixDomain is called in src attribute, | ||
198 | // IE needs some slight delay to correctly move focus. | ||
199 | setTimeout( function() { | ||
200 | iframe.$.contentWindow.focus(); | ||
201 | } ); | ||
202 | } ); | ||
203 | container.append( focusGrabber ); | ||
204 | |||
205 | // Override focus handler on field. | ||
206 | this.focus = function() { | ||
207 | focusGrabber.focus(); | ||
208 | this.fire( 'focus' ); | ||
209 | }; | ||
210 | } | ||
211 | |||
212 | this.getInputElement = function() { | ||
213 | return iframe; | ||
214 | }; | ||
215 | |||
216 | // Force container to scale in IE. | ||
217 | if ( CKEDITOR.env.ie ) { | ||
218 | container.setStyle( 'display', 'block' ); | ||
219 | container.setStyle( 'height', ( iframe.$.offsetHeight + 2 ) + 'px' ); | ||
220 | } | ||
221 | }, | ||
222 | commit: function() { | ||
223 | var editor = this.getDialog().getParentEditor(), | ||
224 | body = this.getInputElement().getFrameDocument().getBody(), | ||
225 | bogus = body.getBogus(), | ||
226 | html; | ||
227 | bogus && bogus.remove(); | ||
228 | |||
229 | // Saving the contents so changes until paste is complete will not take place (#7500) | ||
230 | html = body.getHtml(); | ||
231 | |||
232 | // Opera needs some time to think about what has happened and what it should do now. | ||
233 | setTimeout( function() { | ||
234 | editor.fire( 'pasteDialogCommit', { | ||
235 | dataValue: html, | ||
236 | // Avoid error if there was no paste so lastDataTransfer is null. | ||
237 | dataTransfer: lastDataTransfer || clipboard.initPasteDataTransfer() | ||
238 | } ); | ||
239 | }, 0 ); | ||
240 | } | ||
241 | } | ||
242 | ] | ||
243 | } ] | ||
244 | }; | ||
245 | } ); | ||
246 | |||
247 | /** | ||
248 | * Internal event to pass paste dialog's data to the listeners. | ||
249 | * | ||
250 | * @private | ||
251 | * @event pasteDialogCommit | ||
252 | * @member CKEDITOR.editor | ||
253 | * @param {CKEDITOR.editor} editor This editor instance. | ||
254 | */ | ||