c7ae5ec385739ddf4d40c521439ffb053f0caefe
1 /* © 2011 Benoît Pin, MINES ParisTech */
6 var reImage
= /^image\//;
8 var PlinnCKDDUploader = function(editor
) {
10 this.uploadUrl
= editor
.config
.baseHref
+ 'attachments/put_upload';
11 this.uploadQueue
= [];
12 this._uploadQueueRunning
= false;
14 editor
.document
.on('dragenter', function(e
) {self
.dragenter(e
);});
15 editor
.document
.on('dragover', function(e
) {self
.dragover(e
);});
16 editor
.document
.on('drop', function(e
) {self
.drop(e
);});
20 PlinnCKDDUploader
.prototype.dragenter = function(e
) {
23 disablePropagation(evt
);
26 PlinnCKDDUploader
.prototype.dragover = function(e
) {
29 disablePropagation(evt
);
30 evt
= getEventObject(evt
);
31 var dt
= evt
.dataTransfer
;
32 dt
.dropEffect
= 'copy';
35 PlinnCKDDUploader
.prototype.drop = function(e
) {
38 disablePropagation(evt
);
40 var dt
= evt
.dataTransfer
;
41 dt
.dropEffect
= 'copy';
42 this.handleFiles(dt
.files
);
45 PlinnCKDDUploader
.prototype.createFileProxy = function(file
) {
46 var container
= new CKEDITOR
.dom
.element('span');
47 var rel
= CKEDITOR
.dom
.element
.createFromHtml('<span style="position:relative"/>');
48 container
.append(rel
);
49 var progressBar
= CKEDITOR
.dom
.element
.createFromHtml(
50 '<span style="display:block; position:absolute; background:#ef8e32; height:4px; border-radius:2px; width:0; left:0; top:1em"/>');
51 rel
.append(progressBar
);
52 var link
= new CKEDITOR
.dom
.element('a');
53 link
.setAttribute('href', '#');
54 link
.appendText(file
.name
);
55 container
.append(link
);
59 proxy
.container
= container
;
60 proxy
.progressBar
= progressBar
;
65 // Methods about upload
66 PlinnCKDDUploader
.prototype.handleFiles = function(files
) {
68 for (i
=0 ; i
<files
.length
; i
++) {
70 if (reImage
.test(file
.type
)) {
74 proxy
= this.createFileProxy(file
);
75 this.editor
.insertElement(proxy
.container
);
76 this.editor
.insertText(' ');
77 this.uploadQueuePush(proxy
);
84 PlinnCKDDUploader
.prototype.beforeUpload = function(item
) {
85 this.uploadedItem
= item
;
86 this.progressBar
= item
.progressBar
;
87 this.progressBarMaxSize
= item
.container
.getSize('width');
91 PlinnCKDDUploader
.prototype.upload = function(item
) {
92 // item.file must be the file to be uploaded
93 this.beforeUpload(item
);
94 var reader
= new FileReader();
95 var req
= new XMLHttpRequest();
100 addListener(req
.upload
, 'progress', function(evt
){self
.progressHandler(evt
);});
101 addListener(req
, 'readystatechange',
103 if (req
.readyState
=== 4) {
104 self
.uploadCompleteHandler(req
);
108 req
.open("PUT", this.uploadUrl
);
109 req
.setRequestHeader("Content-Type", file
.type
);
110 req
.setRequestHeader("X-File-Name", encodeURI(file
.name
));
111 addListener(reader
, 'load',
114 req
.sendAsBinary(evt
.target
.result
);
118 reader
.readAsBinaryString(file
);
122 PlinnCKDDUploader
.prototype.uploadCompleteHandlerCB = function(req
) {
123 var item
= this.uploadedItem
;
124 var data
= req
.responseXML
.documentElement
;
125 var link
= new CKEDITOR
.dom
.element('a');
126 link
.setAttribute('href', 'attachments/' + data
.getAttribute('id'));
127 link
.appendText(data
.getAttribute('title'));
128 link
.replace(item
.container
);
131 PlinnCKDDUploader
.prototype.uploadCompleteHandler = function(req
) {
132 this.uploadCompleteHandlerCB(req
);
133 this.uploadQueueLoadNext();
136 PlinnCKDDUploader
.prototype.progressHandlerCB = function(progress
) {
137 // 0 <= progress <= 1
138 var size
= this.progressBarMaxSize
* progress
;
139 size
= Math
.round(size
);
140 this.progressBar
.setStyle('width', String(size
) + 'px');
143 PlinnCKDDUploader
.prototype.progressHandler = function(evt
) {
144 if (evt
.lengthComputable
) {
145 var progress
= evt
.loaded
/ evt
.total
;
146 this.progressHandlerCB(progress
);
150 // Methods about queue
151 PlinnCKDDUploader
.prototype.uploadQueuePush = function(item
) {
152 this.uploadQueue
.push(item
);
153 if (!this._uploadQueueRunning
) {
154 this.startUploadQueue();
158 PlinnCKDDUploader
.prototype.startUploadQueue = function() {
159 this._uploadQueueRunning
= true;
160 this.uploadQueueLoadNext();
163 PlinnCKDDUploader
.prototype.uploadQueueLoadNext = function() {
164 var item
= this.uploadQueue
.shift();
169 this._uploadQueueRunning
= false;
173 var reSize
= /getResizedImage\?size=(\d+)_(\d+)$/;
175 function updateImageSizeUrlParameters(img
) {
176 if (reSize
.test(img
.src
)){
177 var matches
= reSize
.exec(img
.src
);
178 var srcWidth
= parseInt(matches
[1], 10);
179 var srcHeight
= parseInt(matches
[2], 10);
181 var imgWidth
= parseInt((img
.style
.width
) ? img
.style
.width
: img
.width
, 10);
182 var imgHeight
= parseInt((img
.style
.height
) ? img
.style
.height
: img
.height
, 10);
184 if ((imgWidth
&& imgHeight
) && srcWidth
!== imgWidth
&& srcHeight
!== imgHeight
) {
185 var newUrl
= img
.getAttribute('src', 2).replace(reSize
, 'getResizedImage?size=' + imgWidth
+ '_' + imgHeight
);
186 img
.width
= imgWidth
;
187 img
.height
= imgHeight
;
193 function openPlinnImageDialog(path
, editor
) {
194 var winOptions
= "location=no,menubar=no,toolbar=no,dependent=yes,dialog=yes,minimizable=no,modal=yes,alwaysRaised=yes" +
201 var win
= open(path
+ 'dialog/plinn_image.html', 'PlinnImageDialog', winOptions
);
202 win
.dialogArguments
= {};
203 win
.dialogArguments
.editor
= editor
;
204 win
.dialogArguments
.pluginPath
= path
;
205 win
.dialogArguments
.CKEDITOR
= CKEDITOR
;
209 CKEDITOR
.plugins
.add( 'plinn_image',
211 init : function( editor
)
213 /* Add listener on getData event to compute images
214 src attributes before saving data.
216 editor
.on('instanceReady', function(){
219 var tmpDiv
= document
.createElement('div');
220 tmpDiv
.innerHTML
= evt
.data
.dataValue
;
221 var images
= tmpDiv
.getElementsByTagName('IMG');
223 for (i
= 0 ; i
< images
.length
; i
++) {
224 updateImageSizeUrlParameters(images
[i
]);}
225 evt
.data
.dataValue
= tmpDiv
.innerHTML
;
228 // drag & drop upload initialisation
229 var dd
= new PlinnCKDDUploader(editor
);
233 var pluginPath
= this.path
;
234 var allowed
= 'img[alt,!src]{border-style,border-width,float,height,margin,margin-bottom,margin-left,margin-right,margin-top,width}';
235 var required
= 'img[alt,src]';
236 var command
= editor
.addCommand('plinn_image',
238 exec : function(editor
){openPlinnImageDialog(pluginPath
, editor
);},
239 allowedContent
: allowed
,
240 requiredContent
: required
244 editor
.ui
.addButton('PlinnImage',
246 label
: editor
.lang
.common
.image
,
247 icon
: pluginPath
+ 'dialog/plinn_image.png',
248 command
: 'plinn_image'