/** * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or http://ckeditor.com/license */ CKEDITOR.dialog.add( 'paste', function( editor ) { var lang = editor.lang.clipboard, clipboard = CKEDITOR.plugins.clipboard, lastDataTransfer; function onPasteFrameLoad( win ) { var doc = new CKEDITOR.dom.document( win.document ), body = doc.getBody(), script = doc.getById( 'cke_actscrpt' ); script && script.remove(); body.setAttribute( 'contenteditable', true ); // Forward dataTransfer (#13883). body.on( clipboard.mainPasteEvent, function( evt ) { var dataTransfer = clipboard.initPasteDataTransfer( evt ); if ( !lastDataTransfer ) { lastDataTransfer = dataTransfer; } else // For two paste with the same dataTransfer we can use that dataTransfer (two internal pastes are // considered as an internal paste). if ( dataTransfer != lastDataTransfer ) { // If there were two paste with different DataTransfer objects create a new, empty, data transfer // and use it (one internal and one external paste are considered as external paste). lastDataTransfer = clipboard.initPasteDataTransfer(); } } ); // IE before version 8 will leave cursor blinking inside the document after // editor blurred unless we clean up the selection. (#4716) if ( CKEDITOR.env.ie && CKEDITOR.env.version < 8 ) { doc.getWindow().on( 'blur', function() { doc.$.selection.empty(); } ); } doc.on( 'keydown', function( e ) { var domEvent = e.data, key = domEvent.getKeystroke(), processed; switch ( key ) { case 27: this.hide(); processed = 1; break; case 9: case CKEDITOR.SHIFT + 9: this.changeFocus( 1 ); processed = 1; } processed && domEvent.preventDefault(); }, this ); editor.fire( 'ariaWidget', new CKEDITOR.dom.element( win.frameElement ) ); // Handle pending focus. if ( doc.getWindow().getFrame().removeCustomData( 'pendingFocus' ) ) body.focus(); } // If pasteDialogCommit wasn't canceled by e.g. editor.getClipboardData // then fire paste event. // Do not use editor#paste, because it would start from beforePaste event. editor.on( 'pasteDialogCommit', function( evt ) { if ( evt.data ) editor.fire( 'paste', { type: 'auto', dataValue: evt.data.dataValue, method: 'paste', dataTransfer: evt.data.dataTransfer || clipboard.initPasteDataTransfer() } ); }, null, null, 1000 ); return { title: lang.title, minWidth: CKEDITOR.env.ie && CKEDITOR.env.quirks ? 370 : 350, minHeight: CKEDITOR.env.quirks ? 250 : 245, onShow: function() { // FIREFOX BUG: Force the browser to render the dialog to make the to-be- // inserted iframe editable. (#3366) this.parts.dialog.$.offsetHeight; this.setupContent(); // Set dialog title to the custom value (set e.g. in editor.openDialog callback) and reset this value. // If custom title not set, use default one. this.parts.title.setHtml( this.customTitle || lang.title ); this.customTitle = null; }, onLoad: function() { if ( ( CKEDITOR.env.ie7Compat || CKEDITOR.env.ie6Compat ) && editor.lang.dir == 'rtl' ) this.parts.contents.setStyle( 'overflow', 'hidden' ); }, onOk: function() { this.commitContent(); }, contents: [ { id: 'general', label: editor.lang.common.generalTab, elements: [ { type: 'html', id: 'securityMsg', html: '
' + lang.securityMsg + '
' }, { type: 'html', id: 'pasteMsg', html: '
' + lang.pasteMsg + '
' }, { type: 'html', id: 'editing_area', style: 'width:100%;height:100%', html: '', focus: function() { var iframe = this.getInputElement(), doc = iframe.getFrameDocument(), body = doc.getBody(); // Frame content may not loaded at the moment. if ( !body || body.isReadOnly() ) iframe.setCustomData( 'pendingFocus', 1 ); else body.focus(); }, setup: function() { var dialog = this.getDialog(); var htmlToLoad = '' + '' + '' + ''; var src = CKEDITOR.env.air ? 'javascript:void(0)' : // jshint ignore:line ( CKEDITOR.env.ie && !CKEDITOR.env.edge ) ? 'javascript:void((function(){' + encodeURIComponent( // jshint ignore:line 'document.open();' + '(' + CKEDITOR.tools.fixDomain + ')();' + 'document.close();' ) + '})())"' : ''; var iframe = CKEDITOR.dom.element.createFromHtml( '' ); // Reset last data transfer. lastDataTransfer = null; iframe.on( 'load', function( e ) { e.removeListener(); var doc = iframe.getFrameDocument(); doc.write( htmlToLoad ); editor.focusManager.add( doc.getBody() ); if ( CKEDITOR.env.air ) onPasteFrameLoad.call( this, doc.getWindow().$ ); }, dialog ); iframe.setCustomData( 'dialog', dialog ); var container = this.getElement(); container.setHtml( '' ); container.append( iframe ); // IE need a redirect on focus to make // the cursor blinking inside iframe. (#5461) if ( CKEDITOR.env.ie && !CKEDITOR.env.edge ) { var focusGrabber = CKEDITOR.dom.element.createFromHtml( '' ); focusGrabber.on( 'focus', function() { // Since fixDomain is called in src attribute, // IE needs some slight delay to correctly move focus. setTimeout( function() { iframe.$.contentWindow.focus(); } ); } ); container.append( focusGrabber ); // Override focus handler on field. this.focus = function() { focusGrabber.focus(); this.fire( 'focus' ); }; } this.getInputElement = function() { return iframe; }; // Force container to scale in IE. if ( CKEDITOR.env.ie ) { container.setStyle( 'display', 'block' ); container.setStyle( 'height', ( iframe.$.offsetHeight + 2 ) + 'px' ); } }, commit: function() { var editor = this.getDialog().getParentEditor(), body = this.getInputElement().getFrameDocument().getBody(), bogus = body.getBogus(), html; bogus && bogus.remove(); // Saving the contents so changes until paste is complete will not take place (#7500) html = body.getHtml(); // Opera needs some time to think about what has happened and what it should do now. setTimeout( function() { editor.fire( 'pasteDialogCommit', { dataValue: html, // Avoid error if there was no paste so lastDataTransfer is null. dataTransfer: lastDataTransfer || clipboard.initPasteDataTransfer() } ); }, 0 ); } } ] } ] }; } ); /** * Internal event to pass paste dialog's data to the listeners. * * @private * @event pasteDialogCommit * @member CKEDITOR.editor * @param {CKEDITOR.editor} editor This editor instance. */