Merge branch 'MDL-47750' of https://github.com/timhunt/moodle
This commit is contained in:
Vendored
+160
-88
@@ -243,6 +243,7 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
|
||||
});
|
||||
this.editor.delegate('dblclick', this._displayDialogue, 'img', this);
|
||||
this.editor.delegate('click', this._handleClick, 'img', this);
|
||||
this.editor.on('paste', this._handlePaste, this);
|
||||
this.editor.on('drop', this._handleDragDrop, this);
|
||||
|
||||
// e.preventDefault needed to stop the default event from clobbering the desired behaviour in some browsers.
|
||||
@@ -259,118 +260,189 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
|
||||
*
|
||||
* @method _handleDragDrop
|
||||
* @param {EventFacade} e
|
||||
* @return mixed
|
||||
* @return {boolean} false if we handled the event, else true.
|
||||
* @private
|
||||
*/
|
||||
_handleDragDrop: function(e) {
|
||||
if (!e._event || !e._event.dataTransfer) {
|
||||
// Drop not fully supported in this browser.
|
||||
return true;
|
||||
}
|
||||
|
||||
return this._handlePasteOrDropHelper(e, e._event.dataTransfer);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handles paste events where - if the thing being pasted is an image.
|
||||
*
|
||||
* @method _handlePaste
|
||||
* @param {EventFacade} e
|
||||
* @return {boolean} false if we handled the event, else true.
|
||||
* @private
|
||||
*/
|
||||
_handlePaste: function(e) {
|
||||
if (!e._event || !e._event.clipboardData) {
|
||||
// Paste not fully supported in this browser.
|
||||
return true;
|
||||
}
|
||||
|
||||
return this._handlePasteOrDropHelper(e, e._event.clipboardData);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle a drag and drop event with an image.
|
||||
*
|
||||
* @method _handleDragDrop
|
||||
* @param {EventFacade} e
|
||||
* @param {DataTransfer} dataTransfer
|
||||
* @return {boolean} false if we handled the event, else true.
|
||||
* @private
|
||||
*/
|
||||
_handlePasteOrDropHelper: function(e, dataTransfer) {
|
||||
|
||||
var items = dataTransfer.items,
|
||||
didUpload = false;
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
var item = items[i];
|
||||
if (item.kind !== 'file') {
|
||||
continue;
|
||||
}
|
||||
if (!this._isImage(item.type)) {
|
||||
continue;
|
||||
}
|
||||
this._uploadImage(item.getAsFile());
|
||||
didUpload = true;
|
||||
}
|
||||
|
||||
if (didUpload) {
|
||||
// We handled this.
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return false;
|
||||
} else {
|
||||
// Let someone else try to handle it.
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Is this file an image?
|
||||
*
|
||||
* @method _isImage
|
||||
* @param {string} mimeType the file's mime type.
|
||||
* @return {boolean} true if the file has an image mimeType.
|
||||
* @private
|
||||
*/
|
||||
_isImage: function(mimeType) {
|
||||
return mimeType.indexOf('image/') === 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Used by _handleDragDrop and _handlePaste to upload an image and insert it.
|
||||
*
|
||||
* @method _uploadImage
|
||||
* @param {File} fileToSave
|
||||
* @private
|
||||
*/
|
||||
_uploadImage: function(fileToSave) {
|
||||
|
||||
var self = this,
|
||||
host = this.get('host'),
|
||||
template = Y.Handlebars.compile(IMAGETEMPLATE);
|
||||
|
||||
host.saveSelection();
|
||||
e = e._event;
|
||||
|
||||
// Only handle the event if an image file was dropped in.
|
||||
var handlesDataTransfer = (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length);
|
||||
if (handlesDataTransfer && /^image\//.test(e.dataTransfer.files[0].type)) {
|
||||
var options = host.get('filepickeroptions').image,
|
||||
savepath = (options.savepath === undefined) ? '/' : options.savepath,
|
||||
formData = new FormData(),
|
||||
timestamp = 0,
|
||||
uploadid = "",
|
||||
xhr = new XMLHttpRequest(),
|
||||
imagehtml = "",
|
||||
keys = Object.keys(options.repositories);
|
||||
|
||||
var options = host.get('filepickeroptions').image,
|
||||
savepath = (options.savepath === undefined) ? '/' : options.savepath,
|
||||
formData = new FormData(),
|
||||
timestamp = 0,
|
||||
uploadid = "",
|
||||
xhr = new XMLHttpRequest(),
|
||||
imagehtml = "",
|
||||
keys = Object.keys(options.repositories);
|
||||
formData.append('repo_upload_file', fileToSave);
|
||||
formData.append('itemid', options.itemid);
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
formData.append('repo_upload_file', e.dataTransfer.files[0]);
|
||||
formData.append('itemid', options.itemid);
|
||||
|
||||
// List of repositories is an object rather than an array. This makes iteration more awkward.
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
if (options.repositories[keys[i]].type === 'upload') {
|
||||
formData.append('repo_id', options.repositories[keys[i]].id);
|
||||
break;
|
||||
}
|
||||
// List of repositories is an object rather than an array. This makes iteration more awkward.
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
if (options.repositories[keys[i]].type === 'upload') {
|
||||
formData.append('repo_id', options.repositories[keys[i]].id);
|
||||
break;
|
||||
}
|
||||
formData.append('env', options.env);
|
||||
formData.append('sesskey', M.cfg.sesskey);
|
||||
formData.append('client_id', options.client_id);
|
||||
formData.append('savepath', savepath);
|
||||
formData.append('ctx_id', options.context.id);
|
||||
}
|
||||
formData.append('env', options.env);
|
||||
formData.append('sesskey', M.cfg.sesskey);
|
||||
formData.append('client_id', options.client_id);
|
||||
formData.append('savepath', savepath);
|
||||
formData.append('ctx_id', options.context.id);
|
||||
|
||||
// Insert spinner as a placeholder.
|
||||
timestamp = new Date().getTime();
|
||||
uploadid = 'moodleimage_' + Math.round(Math.random() * 100000) + '-' + timestamp;
|
||||
host.focus();
|
||||
host.restoreSelection();
|
||||
imagehtml = template({
|
||||
url: M.util.image_url("i/loading_small", 'moodle'),
|
||||
alt: M.util.get_string('uploading', COMPONENTNAME),
|
||||
id: uploadid
|
||||
});
|
||||
host.insertContentAtFocusPoint(imagehtml);
|
||||
self.markUpdated();
|
||||
// Insert spinner as a placeholder.
|
||||
timestamp = new Date().getTime();
|
||||
uploadid = 'moodleimage_' + Math.round(Math.random() * 100000) + '-' + timestamp;
|
||||
host.focus();
|
||||
host.restoreSelection();
|
||||
imagehtml = template({
|
||||
url: M.util.image_url("i/loading_small", 'moodle'),
|
||||
alt: M.util.get_string('uploading', COMPONENTNAME),
|
||||
id: uploadid
|
||||
});
|
||||
host.insertContentAtFocusPoint(imagehtml);
|
||||
self.markUpdated();
|
||||
|
||||
// Kick off a XMLHttpRequest.
|
||||
xhr.onreadystatechange = function() {
|
||||
var placeholder = self.editor.one('#' + uploadid),
|
||||
result,
|
||||
file,
|
||||
newhtml,
|
||||
newimage;
|
||||
// Kick off a XMLHttpRequest.
|
||||
xhr.onreadystatechange = function() {
|
||||
var placeholder = self.editor.one('#' + uploadid),
|
||||
result,
|
||||
file,
|
||||
newhtml,
|
||||
newimage;
|
||||
|
||||
if (xhr.readyState === 4) {
|
||||
if (xhr.status === 200) {
|
||||
result = JSON.parse(xhr.responseText);
|
||||
if (result) {
|
||||
if (result.error) {
|
||||
if (placeholder) {
|
||||
placeholder.remove(true);
|
||||
}
|
||||
return new M.core.ajaxException(result);
|
||||
}
|
||||
|
||||
file = result;
|
||||
if (result.event && result.event === 'fileexists') {
|
||||
// A file with this name is already in use here - rename to avoid conflict.
|
||||
// Chances are, it's a different image (stored in a different folder on the user's computer).
|
||||
// If the user wants to reuse an existing image, they can copy/paste it within the editor.
|
||||
file = result.newfile;
|
||||
}
|
||||
|
||||
// Replace placeholder with actual image.
|
||||
newhtml = template({
|
||||
url: file.url,
|
||||
presentation: true
|
||||
});
|
||||
newimage = Y.Node.create(newhtml);
|
||||
if (xhr.readyState === 4) {
|
||||
if (xhr.status === 200) {
|
||||
result = JSON.parse(xhr.responseText);
|
||||
if (result) {
|
||||
if (result.error) {
|
||||
if (placeholder) {
|
||||
placeholder.replace(newimage);
|
||||
} else {
|
||||
self.editor.appendChild(newimage);
|
||||
placeholder.remove(true);
|
||||
}
|
||||
self.markUpdated();
|
||||
throw new M.core.ajaxException(result);
|
||||
}
|
||||
} else {
|
||||
Y.use('moodle-core-notification-alert', function() {
|
||||
new M.core.alert({message: M.util.get_string('servererror', 'moodle')});
|
||||
|
||||
file = result;
|
||||
if (result.event && result.event === 'fileexists') {
|
||||
// A file with this name is already in use here - rename to avoid conflict.
|
||||
// Chances are, it's a different image (stored in a different folder on the user's computer).
|
||||
// If the user wants to reuse an existing image, they can copy/paste it within the editor.
|
||||
file = result.newfile;
|
||||
}
|
||||
|
||||
// Replace placeholder with actual image.
|
||||
newhtml = template({
|
||||
url: file.url,
|
||||
presentation: true
|
||||
});
|
||||
newimage = Y.Node.create(newhtml);
|
||||
if (placeholder) {
|
||||
placeholder.remove(true);
|
||||
placeholder.replace(newimage);
|
||||
} else {
|
||||
self.editor.appendChild(newimage);
|
||||
}
|
||||
self.markUpdated();
|
||||
}
|
||||
} else {
|
||||
Y.use('moodle-core-notification-alert', function() {
|
||||
new M.core.alert({message: M.util.get_string('servererror', 'moodle')});
|
||||
});
|
||||
if (placeholder) {
|
||||
placeholder.remove(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.open("POST", M.cfg.wwwroot + '/repository/repository_ajax.php?action=upload', true);
|
||||
xhr.send(formData);
|
||||
return false;
|
||||
}
|
||||
|
||||
},
|
||||
}
|
||||
};
|
||||
xhr.open("POST", M.cfg.wwwroot + '/repository/repository_ajax.php?action=upload', true);
|
||||
xhr.send(formData);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle a click on an image.
|
||||
|
||||
Vendored
+3
-3
File diff suppressed because one or more lines are too long
Vendored
+160
-88
@@ -243,6 +243,7 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
|
||||
});
|
||||
this.editor.delegate('dblclick', this._displayDialogue, 'img', this);
|
||||
this.editor.delegate('click', this._handleClick, 'img', this);
|
||||
this.editor.on('paste', this._handlePaste, this);
|
||||
this.editor.on('drop', this._handleDragDrop, this);
|
||||
|
||||
// e.preventDefault needed to stop the default event from clobbering the desired behaviour in some browsers.
|
||||
@@ -259,118 +260,189 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
|
||||
*
|
||||
* @method _handleDragDrop
|
||||
* @param {EventFacade} e
|
||||
* @return mixed
|
||||
* @return {boolean} false if we handled the event, else true.
|
||||
* @private
|
||||
*/
|
||||
_handleDragDrop: function(e) {
|
||||
if (!e._event || !e._event.dataTransfer) {
|
||||
// Drop not fully supported in this browser.
|
||||
return true;
|
||||
}
|
||||
|
||||
return this._handlePasteOrDropHelper(e, e._event.dataTransfer);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handles paste events where - if the thing being pasted is an image.
|
||||
*
|
||||
* @method _handlePaste
|
||||
* @param {EventFacade} e
|
||||
* @return {boolean} false if we handled the event, else true.
|
||||
* @private
|
||||
*/
|
||||
_handlePaste: function(e) {
|
||||
if (!e._event || !e._event.clipboardData) {
|
||||
// Paste not fully supported in this browser.
|
||||
return true;
|
||||
}
|
||||
|
||||
return this._handlePasteOrDropHelper(e, e._event.clipboardData);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle a drag and drop event with an image.
|
||||
*
|
||||
* @method _handleDragDrop
|
||||
* @param {EventFacade} e
|
||||
* @param {DataTransfer} dataTransfer
|
||||
* @return {boolean} false if we handled the event, else true.
|
||||
* @private
|
||||
*/
|
||||
_handlePasteOrDropHelper: function(e, dataTransfer) {
|
||||
|
||||
var items = dataTransfer.items,
|
||||
didUpload = false;
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
var item = items[i];
|
||||
if (item.kind !== 'file') {
|
||||
continue;
|
||||
}
|
||||
if (!this._isImage(item.type)) {
|
||||
continue;
|
||||
}
|
||||
this._uploadImage(item.getAsFile());
|
||||
didUpload = true;
|
||||
}
|
||||
|
||||
if (didUpload) {
|
||||
// We handled this.
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return false;
|
||||
} else {
|
||||
// Let someone else try to handle it.
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Is this file an image?
|
||||
*
|
||||
* @method _isImage
|
||||
* @param {string} mimeType the file's mime type.
|
||||
* @return {boolean} true if the file has an image mimeType.
|
||||
* @private
|
||||
*/
|
||||
_isImage: function(mimeType) {
|
||||
return mimeType.indexOf('image/') === 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Used by _handleDragDrop and _handlePaste to upload an image and insert it.
|
||||
*
|
||||
* @method _uploadImage
|
||||
* @param {File} fileToSave
|
||||
* @private
|
||||
*/
|
||||
_uploadImage: function(fileToSave) {
|
||||
|
||||
var self = this,
|
||||
host = this.get('host'),
|
||||
template = Y.Handlebars.compile(IMAGETEMPLATE);
|
||||
|
||||
host.saveSelection();
|
||||
e = e._event;
|
||||
|
||||
// Only handle the event if an image file was dropped in.
|
||||
var handlesDataTransfer = (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length);
|
||||
if (handlesDataTransfer && /^image\//.test(e.dataTransfer.files[0].type)) {
|
||||
var options = host.get('filepickeroptions').image,
|
||||
savepath = (options.savepath === undefined) ? '/' : options.savepath,
|
||||
formData = new FormData(),
|
||||
timestamp = 0,
|
||||
uploadid = "",
|
||||
xhr = new XMLHttpRequest(),
|
||||
imagehtml = "",
|
||||
keys = Object.keys(options.repositories);
|
||||
|
||||
var options = host.get('filepickeroptions').image,
|
||||
savepath = (options.savepath === undefined) ? '/' : options.savepath,
|
||||
formData = new FormData(),
|
||||
timestamp = 0,
|
||||
uploadid = "",
|
||||
xhr = new XMLHttpRequest(),
|
||||
imagehtml = "",
|
||||
keys = Object.keys(options.repositories);
|
||||
formData.append('repo_upload_file', fileToSave);
|
||||
formData.append('itemid', options.itemid);
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
formData.append('repo_upload_file', e.dataTransfer.files[0]);
|
||||
formData.append('itemid', options.itemid);
|
||||
|
||||
// List of repositories is an object rather than an array. This makes iteration more awkward.
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
if (options.repositories[keys[i]].type === 'upload') {
|
||||
formData.append('repo_id', options.repositories[keys[i]].id);
|
||||
break;
|
||||
}
|
||||
// List of repositories is an object rather than an array. This makes iteration more awkward.
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
if (options.repositories[keys[i]].type === 'upload') {
|
||||
formData.append('repo_id', options.repositories[keys[i]].id);
|
||||
break;
|
||||
}
|
||||
formData.append('env', options.env);
|
||||
formData.append('sesskey', M.cfg.sesskey);
|
||||
formData.append('client_id', options.client_id);
|
||||
formData.append('savepath', savepath);
|
||||
formData.append('ctx_id', options.context.id);
|
||||
}
|
||||
formData.append('env', options.env);
|
||||
formData.append('sesskey', M.cfg.sesskey);
|
||||
formData.append('client_id', options.client_id);
|
||||
formData.append('savepath', savepath);
|
||||
formData.append('ctx_id', options.context.id);
|
||||
|
||||
// Insert spinner as a placeholder.
|
||||
timestamp = new Date().getTime();
|
||||
uploadid = 'moodleimage_' + Math.round(Math.random() * 100000) + '-' + timestamp;
|
||||
host.focus();
|
||||
host.restoreSelection();
|
||||
imagehtml = template({
|
||||
url: M.util.image_url("i/loading_small", 'moodle'),
|
||||
alt: M.util.get_string('uploading', COMPONENTNAME),
|
||||
id: uploadid
|
||||
});
|
||||
host.insertContentAtFocusPoint(imagehtml);
|
||||
self.markUpdated();
|
||||
// Insert spinner as a placeholder.
|
||||
timestamp = new Date().getTime();
|
||||
uploadid = 'moodleimage_' + Math.round(Math.random() * 100000) + '-' + timestamp;
|
||||
host.focus();
|
||||
host.restoreSelection();
|
||||
imagehtml = template({
|
||||
url: M.util.image_url("i/loading_small", 'moodle'),
|
||||
alt: M.util.get_string('uploading', COMPONENTNAME),
|
||||
id: uploadid
|
||||
});
|
||||
host.insertContentAtFocusPoint(imagehtml);
|
||||
self.markUpdated();
|
||||
|
||||
// Kick off a XMLHttpRequest.
|
||||
xhr.onreadystatechange = function() {
|
||||
var placeholder = self.editor.one('#' + uploadid),
|
||||
result,
|
||||
file,
|
||||
newhtml,
|
||||
newimage;
|
||||
// Kick off a XMLHttpRequest.
|
||||
xhr.onreadystatechange = function() {
|
||||
var placeholder = self.editor.one('#' + uploadid),
|
||||
result,
|
||||
file,
|
||||
newhtml,
|
||||
newimage;
|
||||
|
||||
if (xhr.readyState === 4) {
|
||||
if (xhr.status === 200) {
|
||||
result = JSON.parse(xhr.responseText);
|
||||
if (result) {
|
||||
if (result.error) {
|
||||
if (placeholder) {
|
||||
placeholder.remove(true);
|
||||
}
|
||||
return new M.core.ajaxException(result);
|
||||
}
|
||||
|
||||
file = result;
|
||||
if (result.event && result.event === 'fileexists') {
|
||||
// A file with this name is already in use here - rename to avoid conflict.
|
||||
// Chances are, it's a different image (stored in a different folder on the user's computer).
|
||||
// If the user wants to reuse an existing image, they can copy/paste it within the editor.
|
||||
file = result.newfile;
|
||||
}
|
||||
|
||||
// Replace placeholder with actual image.
|
||||
newhtml = template({
|
||||
url: file.url,
|
||||
presentation: true
|
||||
});
|
||||
newimage = Y.Node.create(newhtml);
|
||||
if (xhr.readyState === 4) {
|
||||
if (xhr.status === 200) {
|
||||
result = JSON.parse(xhr.responseText);
|
||||
if (result) {
|
||||
if (result.error) {
|
||||
if (placeholder) {
|
||||
placeholder.replace(newimage);
|
||||
} else {
|
||||
self.editor.appendChild(newimage);
|
||||
placeholder.remove(true);
|
||||
}
|
||||
self.markUpdated();
|
||||
throw new M.core.ajaxException(result);
|
||||
}
|
||||
} else {
|
||||
Y.use('moodle-core-notification-alert', function() {
|
||||
new M.core.alert({message: M.util.get_string('servererror', 'moodle')});
|
||||
|
||||
file = result;
|
||||
if (result.event && result.event === 'fileexists') {
|
||||
// A file with this name is already in use here - rename to avoid conflict.
|
||||
// Chances are, it's a different image (stored in a different folder on the user's computer).
|
||||
// If the user wants to reuse an existing image, they can copy/paste it within the editor.
|
||||
file = result.newfile;
|
||||
}
|
||||
|
||||
// Replace placeholder with actual image.
|
||||
newhtml = template({
|
||||
url: file.url,
|
||||
presentation: true
|
||||
});
|
||||
newimage = Y.Node.create(newhtml);
|
||||
if (placeholder) {
|
||||
placeholder.remove(true);
|
||||
placeholder.replace(newimage);
|
||||
} else {
|
||||
self.editor.appendChild(newimage);
|
||||
}
|
||||
self.markUpdated();
|
||||
}
|
||||
} else {
|
||||
Y.use('moodle-core-notification-alert', function() {
|
||||
new M.core.alert({message: M.util.get_string('servererror', 'moodle')});
|
||||
});
|
||||
if (placeholder) {
|
||||
placeholder.remove(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.open("POST", M.cfg.wwwroot + '/repository/repository_ajax.php?action=upload', true);
|
||||
xhr.send(formData);
|
||||
return false;
|
||||
}
|
||||
|
||||
},
|
||||
}
|
||||
};
|
||||
xhr.open("POST", M.cfg.wwwroot + '/repository/repository_ajax.php?action=upload', true);
|
||||
xhr.send(formData);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle a click on an image.
|
||||
|
||||
+160
-88
@@ -241,6 +241,7 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
|
||||
});
|
||||
this.editor.delegate('dblclick', this._displayDialogue, 'img', this);
|
||||
this.editor.delegate('click', this._handleClick, 'img', this);
|
||||
this.editor.on('paste', this._handlePaste, this);
|
||||
this.editor.on('drop', this._handleDragDrop, this);
|
||||
|
||||
// e.preventDefault needed to stop the default event from clobbering the desired behaviour in some browsers.
|
||||
@@ -257,118 +258,189 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
|
||||
*
|
||||
* @method _handleDragDrop
|
||||
* @param {EventFacade} e
|
||||
* @return mixed
|
||||
* @return {boolean} false if we handled the event, else true.
|
||||
* @private
|
||||
*/
|
||||
_handleDragDrop: function(e) {
|
||||
if (!e._event || !e._event.dataTransfer) {
|
||||
// Drop not fully supported in this browser.
|
||||
return true;
|
||||
}
|
||||
|
||||
return this._handlePasteOrDropHelper(e, e._event.dataTransfer);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handles paste events where - if the thing being pasted is an image.
|
||||
*
|
||||
* @method _handlePaste
|
||||
* @param {EventFacade} e
|
||||
* @return {boolean} false if we handled the event, else true.
|
||||
* @private
|
||||
*/
|
||||
_handlePaste: function(e) {
|
||||
if (!e._event || !e._event.clipboardData) {
|
||||
// Paste not fully supported in this browser.
|
||||
return true;
|
||||
}
|
||||
|
||||
return this._handlePasteOrDropHelper(e, e._event.clipboardData);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle a drag and drop event with an image.
|
||||
*
|
||||
* @method _handleDragDrop
|
||||
* @param {EventFacade} e
|
||||
* @param {DataTransfer} dataTransfer
|
||||
* @return {boolean} false if we handled the event, else true.
|
||||
* @private
|
||||
*/
|
||||
_handlePasteOrDropHelper: function(e, dataTransfer) {
|
||||
|
||||
var items = dataTransfer.items,
|
||||
didUpload = false;
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
var item = items[i];
|
||||
if (item.kind !== 'file') {
|
||||
continue;
|
||||
}
|
||||
if (!this._isImage(item.type)) {
|
||||
continue;
|
||||
}
|
||||
this._uploadImage(item.getAsFile());
|
||||
didUpload = true;
|
||||
}
|
||||
|
||||
if (didUpload) {
|
||||
// We handled this.
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return false;
|
||||
} else {
|
||||
// Let someone else try to handle it.
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Is this file an image?
|
||||
*
|
||||
* @method _isImage
|
||||
* @param {string} mimeType the file's mime type.
|
||||
* @return {boolean} true if the file has an image mimeType.
|
||||
* @private
|
||||
*/
|
||||
_isImage: function(mimeType) {
|
||||
return mimeType.indexOf('image/') === 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Used by _handleDragDrop and _handlePaste to upload an image and insert it.
|
||||
*
|
||||
* @method _uploadImage
|
||||
* @param {File} fileToSave
|
||||
* @private
|
||||
*/
|
||||
_uploadImage: function(fileToSave) {
|
||||
|
||||
var self = this,
|
||||
host = this.get('host'),
|
||||
template = Y.Handlebars.compile(IMAGETEMPLATE);
|
||||
|
||||
host.saveSelection();
|
||||
e = e._event;
|
||||
|
||||
// Only handle the event if an image file was dropped in.
|
||||
var handlesDataTransfer = (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length);
|
||||
if (handlesDataTransfer && /^image\//.test(e.dataTransfer.files[0].type)) {
|
||||
var options = host.get('filepickeroptions').image,
|
||||
savepath = (options.savepath === undefined) ? '/' : options.savepath,
|
||||
formData = new FormData(),
|
||||
timestamp = 0,
|
||||
uploadid = "",
|
||||
xhr = new XMLHttpRequest(),
|
||||
imagehtml = "",
|
||||
keys = Object.keys(options.repositories);
|
||||
|
||||
var options = host.get('filepickeroptions').image,
|
||||
savepath = (options.savepath === undefined) ? '/' : options.savepath,
|
||||
formData = new FormData(),
|
||||
timestamp = 0,
|
||||
uploadid = "",
|
||||
xhr = new XMLHttpRequest(),
|
||||
imagehtml = "",
|
||||
keys = Object.keys(options.repositories);
|
||||
formData.append('repo_upload_file', fileToSave);
|
||||
formData.append('itemid', options.itemid);
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
formData.append('repo_upload_file', e.dataTransfer.files[0]);
|
||||
formData.append('itemid', options.itemid);
|
||||
|
||||
// List of repositories is an object rather than an array. This makes iteration more awkward.
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
if (options.repositories[keys[i]].type === 'upload') {
|
||||
formData.append('repo_id', options.repositories[keys[i]].id);
|
||||
break;
|
||||
}
|
||||
// List of repositories is an object rather than an array. This makes iteration more awkward.
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
if (options.repositories[keys[i]].type === 'upload') {
|
||||
formData.append('repo_id', options.repositories[keys[i]].id);
|
||||
break;
|
||||
}
|
||||
formData.append('env', options.env);
|
||||
formData.append('sesskey', M.cfg.sesskey);
|
||||
formData.append('client_id', options.client_id);
|
||||
formData.append('savepath', savepath);
|
||||
formData.append('ctx_id', options.context.id);
|
||||
}
|
||||
formData.append('env', options.env);
|
||||
formData.append('sesskey', M.cfg.sesskey);
|
||||
formData.append('client_id', options.client_id);
|
||||
formData.append('savepath', savepath);
|
||||
formData.append('ctx_id', options.context.id);
|
||||
|
||||
// Insert spinner as a placeholder.
|
||||
timestamp = new Date().getTime();
|
||||
uploadid = 'moodleimage_' + Math.round(Math.random() * 100000) + '-' + timestamp;
|
||||
host.focus();
|
||||
host.restoreSelection();
|
||||
imagehtml = template({
|
||||
url: M.util.image_url("i/loading_small", 'moodle'),
|
||||
alt: M.util.get_string('uploading', COMPONENTNAME),
|
||||
id: uploadid
|
||||
});
|
||||
host.insertContentAtFocusPoint(imagehtml);
|
||||
self.markUpdated();
|
||||
// Insert spinner as a placeholder.
|
||||
timestamp = new Date().getTime();
|
||||
uploadid = 'moodleimage_' + Math.round(Math.random() * 100000) + '-' + timestamp;
|
||||
host.focus();
|
||||
host.restoreSelection();
|
||||
imagehtml = template({
|
||||
url: M.util.image_url("i/loading_small", 'moodle'),
|
||||
alt: M.util.get_string('uploading', COMPONENTNAME),
|
||||
id: uploadid
|
||||
});
|
||||
host.insertContentAtFocusPoint(imagehtml);
|
||||
self.markUpdated();
|
||||
|
||||
// Kick off a XMLHttpRequest.
|
||||
xhr.onreadystatechange = function() {
|
||||
var placeholder = self.editor.one('#' + uploadid),
|
||||
result,
|
||||
file,
|
||||
newhtml,
|
||||
newimage;
|
||||
// Kick off a XMLHttpRequest.
|
||||
xhr.onreadystatechange = function() {
|
||||
var placeholder = self.editor.one('#' + uploadid),
|
||||
result,
|
||||
file,
|
||||
newhtml,
|
||||
newimage;
|
||||
|
||||
if (xhr.readyState === 4) {
|
||||
if (xhr.status === 200) {
|
||||
result = JSON.parse(xhr.responseText);
|
||||
if (result) {
|
||||
if (result.error) {
|
||||
if (placeholder) {
|
||||
placeholder.remove(true);
|
||||
}
|
||||
return new M.core.ajaxException(result);
|
||||
}
|
||||
|
||||
file = result;
|
||||
if (result.event && result.event === 'fileexists') {
|
||||
// A file with this name is already in use here - rename to avoid conflict.
|
||||
// Chances are, it's a different image (stored in a different folder on the user's computer).
|
||||
// If the user wants to reuse an existing image, they can copy/paste it within the editor.
|
||||
file = result.newfile;
|
||||
}
|
||||
|
||||
// Replace placeholder with actual image.
|
||||
newhtml = template({
|
||||
url: file.url,
|
||||
presentation: true
|
||||
});
|
||||
newimage = Y.Node.create(newhtml);
|
||||
if (xhr.readyState === 4) {
|
||||
if (xhr.status === 200) {
|
||||
result = JSON.parse(xhr.responseText);
|
||||
if (result) {
|
||||
if (result.error) {
|
||||
if (placeholder) {
|
||||
placeholder.replace(newimage);
|
||||
} else {
|
||||
self.editor.appendChild(newimage);
|
||||
placeholder.remove(true);
|
||||
}
|
||||
self.markUpdated();
|
||||
throw new M.core.ajaxException(result);
|
||||
}
|
||||
} else {
|
||||
Y.use('moodle-core-notification-alert', function() {
|
||||
new M.core.alert({message: M.util.get_string('servererror', 'moodle')});
|
||||
|
||||
file = result;
|
||||
if (result.event && result.event === 'fileexists') {
|
||||
// A file with this name is already in use here - rename to avoid conflict.
|
||||
// Chances are, it's a different image (stored in a different folder on the user's computer).
|
||||
// If the user wants to reuse an existing image, they can copy/paste it within the editor.
|
||||
file = result.newfile;
|
||||
}
|
||||
|
||||
// Replace placeholder with actual image.
|
||||
newhtml = template({
|
||||
url: file.url,
|
||||
presentation: true
|
||||
});
|
||||
newimage = Y.Node.create(newhtml);
|
||||
if (placeholder) {
|
||||
placeholder.remove(true);
|
||||
placeholder.replace(newimage);
|
||||
} else {
|
||||
self.editor.appendChild(newimage);
|
||||
}
|
||||
self.markUpdated();
|
||||
}
|
||||
} else {
|
||||
Y.use('moodle-core-notification-alert', function() {
|
||||
new M.core.alert({message: M.util.get_string('servererror', 'moodle')});
|
||||
});
|
||||
if (placeholder) {
|
||||
placeholder.remove(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.open("POST", M.cfg.wwwroot + '/repository/repository_ajax.php?action=upload', true);
|
||||
xhr.send(formData);
|
||||
return false;
|
||||
}
|
||||
|
||||
},
|
||||
}
|
||||
};
|
||||
xhr.open("POST", M.cfg.wwwroot + '/repository/repository_ajax.php?action=upload', true);
|
||||
xhr.send(formData);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle a click on an image.
|
||||
|
||||
Reference in New Issue
Block a user