plugin.js 5.91 KB
/**
 * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
 * For licensing, see LICENSE.md or http://ckeditor.com/license
 */

'use strict';

( function() {
	CKEDITOR.plugins.add( 'uploadimage', {
		requires: 'uploadwidget',

		onLoad: function() {
			CKEDITOR.addCss(
				'.cke_upload_uploading img{' +
					'opacity: 0.3' +
				'}'
			);
		},

		init: function( editor ) {
			// Do not execute this paste listener if it will not be possible to upload file.
			if ( !CKEDITOR.plugins.clipboard.isFileApiSupported ) {
				return;
			}

			var fileTools = CKEDITOR.fileTools,
				uploadUrl = fileTools.getUploadUrl( editor.config, 'image' );

			if ( !uploadUrl ) {
				CKEDITOR.error( 'uploadimage-config' );
				return;
      }
      
			// Handle images which are available in the dataTransfer.
			fileTools.addUploadWidget( editor, 'uploadimage', {
				supportedTypes: /image\/(jpeg|png|gif|bmp)/,

				uploadUrl: uploadUrl,

				fileToElement: function() {
					var img = new CKEDITOR.dom.element( 'img' );
					img.setAttribute( 'src', loadingImage );
					return img;
				},

				parts: {
					img: 'img'
				},

				onUploading: function( upload ) {
					// Show the image during the upload.
					this.parts.img.setAttribute( 'src', upload.data );
				},

				onUploaded: function( upload ) {
          // Width and height could be returned by server (#13519).
          var img = this.parts.img;
					var $img = this.parts.img.$,
						width = upload.responseData.width || $img.naturalWidth,
            height = upload.responseData.height || $img.naturalHeight;
          // img.setAttributes({
          //   'src': upload.responseData.data.imgSrc,
          //   'data-cke-saved-src': upload.responseData.data.imgSrc,
          // });
          // editor.fire('saveSnapshot');
          var range = editor.getSelection().getRanges()[0];
          var startOffset = range.startOffset;
          var endOffset = range.endOffset;
          // fix: chenjm 复制图片后光标定位到图片后
          range.setStart(range.startContainer, range.startOffset + 1);
          range.setEnd(range.endContainer, range.endOffset);
          // range.moveToElementEditEnd(this.editor.editable());
          range.select();

					// Set width and height to prevent blinking.
					//this.replaceWith( '<img src="' + upload.url + '" ' +
					//	'width="' + width + '" ' +
					//	'height="' + height + '">' );

          // zxt - 20170731
          // chenjm 2020-01-02 上传图片默认带上当前图片的宽高
          var imgStr = editor.getImageDom ? editor.getImageDom(upload.responseData.data) : '';
          this.replaceWith(imgStr);
          setTimeout(function() {
            editor.fire('saveSnapshot');
            editor.fire('change');
          }, 0);
          // editor.setData(editor.getData()) //trigger onchange fuck....
          
				}
			} );

			// Handle images which are not available in the dataTransfer.
			// This means that we need to read them from the <img src="data:..."> elements.
			editor.on( 'paste', function( evt ) {
				// For performance reason do not parse data if it does not contain img tag and data attribute.
				if ( !evt.data.dataValue.match( /<img[\s\S]+data:/i ) ) {
					return;
				}

				var data = evt.data,
					// Prevent XSS attacks.
					tempDoc = document.implementation.createHTMLDocument( '' ),
					temp = new CKEDITOR.dom.element( tempDoc.body ),
          imgs, img, i, k, filterImgs = [];

				// Without this isReadOnly will not works properly.
				temp.data( 'cke-editable', 1 );

				temp.appendHtml( data.dataValue );

        imgs = temp.find( 'img' );

        // chenjm 先过滤一次得到需要转换的filterImgs
				for ( i = 0; i < imgs.count(); i++ ) {
					img = imgs.getItem( i );
					// Image have to contain src=data:...
					var isDataInSrc = img.getAttribute( 'src' ) && img.getAttribute( 'src' ).substring( 0, 5 ) == 'data:',
						  isRealObject = img.data( 'cke-realelement' ) === null;

					// We are not uploading images in non-editable blocs and fake objects (#13003).
					if ( isDataInSrc && isRealObject && !img.data( 'cke-upload-id' ) && !img.isReadOnly( 1 ) ) {
						filterImgs.push({
              img: img,
              index: i,
            });
					}
        }



        var imgCount = filterImgs.length;
        var count = 0;
        var list = [], d;

				for ( k = 0; k < imgCount; k++ ) {
          var uploadImg = filterImgs[k].img;
          var loader = editor.uploadRepository.create( uploadImg.getAttribute( 'src' ) );
          loader.upload(uploadUrl, {}, function(curLoader) {
            count ++;
            var fileData = curLoader.responseData
            // fix: 复制word的时候无法上传显示图片问题
            var imgSrc = fileData.data && fileData.data.imgSrc ? fileData.data.imgSrc : '';
            // var currentImg = temp.find('img').getItem(index);
            // currentImg.setAttributes({
            //   'src': imgSrc,
            //   'data-cke-widget-data': imgSrc,
            // });
            list.push({
              before: curLoader.data,
              now: imgSrc,
            })
            if (count == imgCount) {
              var data = editor.getData();
              for (d = 0; d < imgCount; d ++) {
                var listItem = list[d];
                data = data.replace(listItem.before, listItem.now);
              }
              editor.setData(data);
            }
          });

          // fileTools.markElement( img, 'uploadimage', loader.id );
				}

				// data.dataValue = temp.getHtml();
			} );
		}
	} );

	// jscs:disable maximumLineLength
	// Black rectangle which is shown before image is loaded.
	var loadingImage = 'data:image/gif;base64,R0lGODlhDgAOAIAAAAAAAP///yH5BAAAAAAALAAAAAAOAA4AAAIMhI+py+0Po5y02qsKADs=';
	// jscs:enable maximumLineLength

	/**
	 * The URL where images should be uploaded.
	 *
	 * @since 4.5
	 * @cfg {String} [imageUploadUrl='' (empty string = disabled)]
	 * @member CKEDITOR.config
	 */
} )();