X-Git-Url: https://scm.cri.ensmp.fr/git/ckeditor.git/blobdiff_plain/7c4f7ce0c90fd8b1413f4cc46eb5c84730d61e56..1cf0ceefbf8c570d340e08550253ec57c1267c03:/skins/ckeditor/plugins/plinn_image/plugin.js diff --git a/skins/ckeditor/plugins/plinn_image/plugin.js b/skins/ckeditor/plugins/plinn_image/plugin.js index 7f8f3f2..3e2606c 100644 --- a/skins/ckeditor/plugins/plinn_image/plugin.js +++ b/skins/ckeditor/plugins/plinn_image/plugin.js @@ -1,20 +1,305 @@ -/* © Benoît Pin, MINES ParisTech */ +/* © 2011 Benoît Pin, MINES ParisTech */ (function(){ +var reImage = /^image\//; +var MAX_PREVIEW = 2; + +var PlinnCKDDUploader = function(editor) { + this.editor = editor; + this.uploadUrl = editor.config.baseHref + 'attachments/put_upload'; + this.uploadQueue = []; + this._uploadQueueRunning = false; + this.previewQueue = []; + this._previewQueueRunning = false; + this.previewsLoaded = 0; + this.thumbnailSize = 310; + var self = this; + editor.document.on('dragenter', function(e) {self.dragenter(e);}); + editor.document.on('dragover', function(e) {self.dragover(e);}); + editor.document.on('drop', function(e) {self.drop(e);}); +}; + +// Drag and drop +PlinnCKDDUploader.prototype.dragenter = function(e) { + var evt = e.data.$; + disableDefault(evt); + disablePropagation(evt); +}; + +PlinnCKDDUploader.prototype.dragover = function(e) { + var evt = e.data.$; + disableDefault(evt); + disablePropagation(evt); + evt = getEventObject(evt); + var dt = evt.dataTransfer; + dt.dropEffect = 'copy'; +}; + +PlinnCKDDUploader.prototype.drop = function(e) { + var evt = e.data.$; + disableDefault(evt); + disablePropagation(evt); + getEventObject(evt); + var dt = evt.dataTransfer; + dt.dropEffect = 'copy'; + this.handleFiles(dt.files); +}; + +PlinnCKDDUploader.prototype.createLinkProxy = function(file) { + var container = new CKEDITOR.dom.element('span'); + var rel = CKEDITOR.dom.element.createFromHtml(''); + container.append(rel); + var progressBar = CKEDITOR.dom.element.createFromHtml( + ''); + rel.append(progressBar); + var link = new CKEDITOR.dom.element('a'); + link.setAttribute('href', '#'); + link.setStyle('opacity', 0.2); + link.appendText(file.name); + container.append(link); + + var proxy = {}; + proxy.file = file; + proxy.type = 'link'; + proxy.container = container; + proxy.progressBar = progressBar; + proxy.link = link; + return proxy; +}; + +PlinnCKDDUploader.prototype.createImageProxy = function(file) { + var container = new CKEDITOR.dom.element('span'); + var rel = CKEDITOR.dom.element.createFromHtml(''); + container.append(rel); + var progressBar = CKEDITOR.dom.element.createFromHtml( + ''); + rel.append(progressBar); + + var img = new CKEDITOR.dom.element('img'); + img.setAttribute('width', 310); + img.setAttribute('height', 290); + img.setStyle('opacity', 0.2); + img.setAttribute('src', 'no_image.jpg'); + img.placeholder = true; + var size = this.thumbnailSize; + var self = this; + + img.on('load', function(e) { + if (e.sender.placeholder) { + e.sender.placeholder = false; + return; + }; + var img$ = e.data.$.target; + if (img$.naturalWidth > img$.naturalHeight) { // landscape + img$.height = Math.round(size * img$.naturalHeight / img$.naturalWidth); + img$.width = size; + } + else { + img$.width = Math.round(size * img$.naturalWidth / img$.naturalHeight); + img$.height = size; + } + self.progressBarMaxSize = img$.width; + img$.style.opacity = 0.2; + }); + + container.append(img); + + var proxy = {}; + proxy.file = file; + proxy.type = 'image'; + proxy.container = container; + proxy.progressBar = progressBar; + proxy.img = img; + return proxy; +}; + +// Methods about upload +PlinnCKDDUploader.prototype.handleFiles = function(files) { + var file, i, proxy; + for (i=0 ; i 1 && i < files.length-1) { + this.editor.insertText('\n'); } + this.uploadQueuePush(proxy); + } +}; + + + +PlinnCKDDUploader.prototype.beforeUpload = function(item) { + this.uploadedItem = item; + this.progressBar = item.progressBar; + this.progressBarMaxSize = item.container.getSize('width'); +}; + + +PlinnCKDDUploader.prototype.upload = function(item) { + // item.file must be the file to be uploaded + this.beforeUpload(item); + var reader = new FileReader(); + var req = new XMLHttpRequest(); + var file = item.file; + + var self = this; + + addListener(req.upload, 'progress', function(evt){self.progressHandler(evt);}); + addListener(req, 'readystatechange', + function(evt) { + if (req.readyState === 4) { + self.uploadCompleteHandler(req); + } + }); + + req.open("PUT", this.uploadUrl); + req.setRequestHeader("Content-Type", file.type); + req.setRequestHeader("X-File-Name", encodeURI(file.name)); + addListener(reader, 'load', + function(evt){ + try { + req.sendAsBinary(evt.target.result); + } + catch(e){} + }); + reader.readAsBinaryString(file); +}; + + +PlinnCKDDUploader.prototype.uploadCompleteHandlerCB = function(req) { + var item = this.uploadedItem; + var data = req.responseXML.documentElement; + switch (item.type) { + case 'link' : + var link = new CKEDITOR.dom.element('a'); + link.setAttribute('href', 'attachments/' + data.getAttribute('id')); + link.appendText(data.getAttribute('title')); + link.replace(item.container); + break; + case 'image' : + var img = new CKEDITOR.dom.element('img'); + img.setAttribute('src', data.getAttribute('src')); + img.setAttribute('alt', data.getAttribute('title')); + img.setAttribute('width', data.getAttribute('width')); + img.setAttribute('height', data.getAttribute('height')); + img.replace(item.container); + this.previewsLoaded--; + this.previewQueueLoadNext(); + break; + } +}; + +PlinnCKDDUploader.prototype.uploadCompleteHandler = function(req) { + this.uploadCompleteHandlerCB(req); + this.uploadQueueLoadNext(); +}; + +PlinnCKDDUploader.prototype.progressHandlerCB = function(progress) { + // 0 <= progress <= 1 + var size = this.progressBarMaxSize * progress; + size = Math.round(size); + this.progressBar.setStyle('width', String(size) + 'px'); + var currentOpacity; + switch(this.uploadedItem.type) { + case 'link' : + currentOpacity = this.uploadedItem.link.getStyle('opacity'); + this.uploadedItem.link.setStyle('opacity', Math.max(currentOpacity, progress)); + break; + case 'image' : + currentOpacity = this.uploadedItem.img.getStyle('opacity'); + this.uploadedItem.img.setStyle('opacity', Math.max(currentOpacity, progress)); + break; + } +}; + +PlinnCKDDUploader.prototype.progressHandler = function(evt) { + if (evt.lengthComputable) { + var progress = evt.loaded / evt.total; + this.progressHandlerCB(progress); + } +}; + +// Methods about upload queue +PlinnCKDDUploader.prototype.uploadQueuePush = function(item) { + this.uploadQueue.push(item); + if (!this._uploadQueueRunning) { + this.startUploadQueue(); + } +}; + +PlinnCKDDUploader.prototype.startUploadQueue = function() { + this._uploadQueueRunning = true; + this.uploadQueueLoadNext(); +}; + +PlinnCKDDUploader.prototype.uploadQueueLoadNext = function() { + var item = this.uploadQueue.shift(); + if (item) { + this.upload(item); + } + else { + this._uploadQueueRunning = false; + } +}; + +// Methods about image preview queue. +PlinnCKDDUploader.prototype.previewQueuePush = function(proxy) { + this.previewQueue.push(proxy); + if (!this._previewQueueRunning) { + this.startPreviewQueue(); + } +}; + +PlinnCKDDUploader.prototype.startPreviewQueue = function() { + this._previewQueueRunning = true; + this.previewQueueLoadNext(); +}; + +PlinnCKDDUploader.prototype.previewQueueLoadNext = function() { + if (this.previewQueue.length && this.previewsLoaded < MAX_PREVIEW) { + var proxy = this.previewQueue.shift(); + this.previewUploadedImage(proxy); + this.previewsLoaded++; + } + else { + this._previewQueueRunning = false; + } +}; + +PlinnCKDDUploader.prototype.previewUploadedImage = function(proxy) { + var reader = new FileReader(); + var size = this.thumbnailSize; + var self = this; + + reader.onload = function(evt) { + proxy.img.setAttribute('src', evt.target.result); + setTimeout(function(){self.previewQueueLoadNext();}, 500); + }; + reader.readAsDataURL(proxy.file); +}; + + + var reSize = /getResizedImage\?size=(\d+)_(\d+)$/; function updateImageSizeUrlParameters(img) { if (reSize.test(img.src)){ var matches = reSize.exec(img.src); - var srcWidth = parseInt(matches[1]); - var srcHeight = parseInt(matches[2]); + var srcWidth = parseInt(matches[1], 10); + var srcHeight = parseInt(matches[2], 10); - var imgWidth = parseInt((img.style.width) ? img.style.width : img.width); - var imgHeight = parseInt((img.style.height) ? img.style.height : img.height); + var imgWidth = parseInt((img.style.width) ? img.style.width : img.width, 10); + var imgHeight = parseInt((img.style.height) ? img.style.height : img.height, 10); - if ((imgWidth && imgHeight) && srcWidth != imgWidth && srcHeight != imgHeight) { + if ((imgWidth && imgHeight) && srcWidth !== imgWidth && srcHeight !== imgHeight) { var newUrl = img.getAttribute('src', 2).replace(reSize, 'getResizedImage?size=' + imgWidth + '_' + imgHeight); img.width = imgWidth; img.height = imgHeight; @@ -23,6 +308,21 @@ function updateImageSizeUrlParameters(img) { } } +function openPlinnImageDialog(path, editor) { + var winOptions = "location=no,menubar=no,toolbar=no,dependent=yes,dialog=yes,minimizable=no,modal=yes,alwaysRaised=yes" + + ",resizable=yes" + + ",width=801" + + ",height=600"; + //",top=" + iTop + + //",left=" + iLeft ; + + var win = open(path + 'dialog/plinn_image.html', 'PlinnImageDialog', winOptions); + win.dialogArguments = {}; + win.dialogArguments.editor = editor; + win.dialogArguments.pluginPath = path; + win.dialogArguments.CKEDITOR = CKEDITOR; +} + CKEDITOR.plugins.add( 'plinn_image', { @@ -34,15 +334,39 @@ CKEDITOR.plugins.add( 'plinn_image', editor.on('instanceReady', function(){ editor.on('getData', function(evt) { - var body = evt.editor.document.$.body; - var images = body.getElementsByTagName('IMG'); - for (var i = 0 ; i < images.length ; i++) - updateImageSizeUrlParameters(images[i]); - evt.data.dataValue = evt.editor.document.$.body.innerHTML; + var tmpDiv = document.createElement('div'); + tmpDiv.innerHTML = evt.data.dataValue; + var images = tmpDiv.getElementsByTagName('IMG'); + var i; + for (i = 0 ; i < images.length ; i++) { + updateImageSizeUrlParameters(images[i]);} + evt.data.dataValue = tmpDiv.innerHTML; } ); + // drag & drop upload initialisation + var dd = new PlinnCKDDUploader(editor); }); + + + var pluginPath = this.path; + var allowed = 'img[alt,!src]{border-style,border-width,float,height,margin,margin-bottom,margin-left,margin-right,margin-top,width}'; + var required = 'img[alt,src]'; + var command = editor.addCommand('plinn_image', + { + exec : function(editor){openPlinnImageDialog(pluginPath, editor);}, + allowedContent: allowed, + requiredContent: required + } + ); + + editor.ui.addButton('PlinnImage', + { + label : editor.lang.common.image, + icon : pluginPath + 'dialog/plinn_image.png', + command : 'plinn_image' + }); } + }); -})(); +}());