540 lines
18 KiB
JavaScript
Executable File
540 lines
18 KiB
JavaScript
Executable File
/**
|
|
* Copyright © Magento, Inc. All rights reserved.
|
|
* See COPYING.txt for license details.
|
|
*/
|
|
|
|
/* global MediabrowserUtility, FORM_KEY, tinyMceEditors */
|
|
/* eslint-disable strict */
|
|
define([
|
|
'jquery',
|
|
'wysiwygAdapter',
|
|
'Magento_Ui/js/modal/prompt',
|
|
'Magento_Ui/js/modal/confirm',
|
|
'Magento_Ui/js/modal/alert',
|
|
'underscore',
|
|
'Magento_Ui/js/modal/modal',
|
|
'jquery/ui',
|
|
'jquery/jstree/jquery.jstree',
|
|
'mage/mage'
|
|
], function ($, wysiwyg, prompt, confirm, alert, _) {
|
|
window.MediabrowserUtility = {
|
|
windowId: 'modal_dialog_message',
|
|
modalLoaded: false,
|
|
targetElementId: false,
|
|
pathId: '',
|
|
|
|
/**
|
|
* @return {Number}
|
|
*/
|
|
getMaxZIndex: function () {
|
|
var max = 0,
|
|
cn = document.body.childNodes,
|
|
i, el, zIndex;
|
|
|
|
for (i = 0; i < cn.length; i++) {
|
|
el = cn[i];
|
|
zIndex = el.nodeType == 1 ? parseInt(el.style.zIndex, 10) || 0 : 0; //eslint-disable-line eqeqeq
|
|
|
|
if (zIndex < 10000) {
|
|
max = Math.max(max, zIndex);
|
|
}
|
|
}
|
|
|
|
return max + 10;
|
|
},
|
|
|
|
/**
|
|
* @param {*} url
|
|
* @param {*} width
|
|
* @param {*} height
|
|
* @param {*} title
|
|
* @param {Object} options
|
|
*/
|
|
openDialog: function (url, width, height, title, options) {
|
|
var windowId = this.windowId,
|
|
content = '<div class="popup-window" id="' + windowId + '"></div>';
|
|
|
|
if (this.modalLoaded) {
|
|
|
|
if (!_.isUndefined(options)) {
|
|
this.modal.modal('option', 'closed', options.closed);
|
|
}
|
|
|
|
this.modal.modal('openModal');
|
|
this.setTargetElementId(options, url);
|
|
this.setPathId(url);
|
|
$(window).trigger('reload.MediaGallery');
|
|
|
|
return;
|
|
}
|
|
|
|
this.modal = $(content).modal($.extend({
|
|
title: title || 'Insert File...',
|
|
modalClass: 'magento',
|
|
type: 'slide',
|
|
buttons: []
|
|
}, options));
|
|
|
|
this.modal.modal('openModal');
|
|
|
|
$.ajax({
|
|
url: url,
|
|
type: 'get',
|
|
context: $(this),
|
|
showLoader: true
|
|
|
|
}).done(function (data) {
|
|
this.modal.html(data).trigger('contentUpdated');
|
|
this.modalLoaded = true;
|
|
this.setTargetElementId(options, url);
|
|
this.setPathId(url);
|
|
}.bind(this));
|
|
|
|
},
|
|
|
|
/**
|
|
* Setter for endcoded path id
|
|
*/
|
|
setPathId: function (url) {
|
|
this.pathId = url.match(/(&|\/|%26)current_tree_path(=|\/)([\s\S].*?)(\/|$)/)[3];
|
|
},
|
|
|
|
/**
|
|
* Setter for targetElementId property
|
|
*
|
|
* @param {Object} options
|
|
* @param {String} url
|
|
*/
|
|
setTargetElementId: function (options, url) {
|
|
this.targetElementId = options && options.targetElementId ?
|
|
options.targetElementId
|
|
: url.match(/\/target_element_id\/([\s\S].*?)\//)[1];
|
|
},
|
|
|
|
/**
|
|
* Close dialog.
|
|
*/
|
|
closeDialog: function () {
|
|
this.modal.modal('closeModal');
|
|
}
|
|
};
|
|
|
|
$.widget('mage.mediabrowser', {
|
|
eventPrefix: 'mediabrowser',
|
|
options: {
|
|
contentsUrl: null,
|
|
onInsertUrl: null,
|
|
newFolderUrl: null,
|
|
deleteFolderUrl: null,
|
|
deleteFilesUrl: null,
|
|
headerText: null,
|
|
tree: null,
|
|
currentNode: null,
|
|
storeId: null,
|
|
showBreadcrumbs: null,
|
|
hidden: 'no-display'
|
|
},
|
|
|
|
/**
|
|
* Proxy creation
|
|
* @protected
|
|
*/
|
|
_create: function () {
|
|
this._on({
|
|
'click [data-row=file]': 'selectFile',
|
|
'dblclick [data-row=file]': 'insert',
|
|
'click #new_folder': 'newFolder',
|
|
'click #delete_folder': 'deleteFolder',
|
|
'click #delete_files': 'deleteFiles',
|
|
'click #insert_files': 'insertSelectedFiles',
|
|
'fileuploaddone': '_uploadDone',
|
|
'click [data-row=breadcrumb]': 'selectFolder'
|
|
});
|
|
|
|
$(window).on('reload.MediaGallery', $.proxy(this.reload, this));
|
|
this.activeNode = null;
|
|
//tree dont use event bubbling
|
|
this.tree = this.element.find('[data-role=tree]');
|
|
this.tree.on('select_node.jstree', $.proxy(this._selectNode, this));
|
|
},
|
|
|
|
/**
|
|
* @param {jQuery.Event} event
|
|
* @param {Object} data
|
|
* @private
|
|
*/
|
|
_selectNode: function (event, data) {
|
|
var node = data.node;
|
|
|
|
this.activeNode = node;
|
|
this.element.find('#delete_files, #insert_files').toggleClass(this.options.hidden, true);
|
|
this.element.find('#contents').toggleClass(this.options.hidden, false);
|
|
this.element.find('#delete_folder')
|
|
.toggleClass(this.options.hidden, node.id === 'root'); //eslint-disable-line eqeqeq
|
|
this.element.find('#content_header_text')
|
|
.html(node.id === 'root' ? this.headerText : node.text); //eslint-disable-line eqeqeq
|
|
|
|
this.drawBreadcrumbs(data);
|
|
this.loadFileList(node);
|
|
},
|
|
|
|
/**
|
|
* @return {*}
|
|
*/
|
|
reload: function (uploaded) {
|
|
return this.loadFileList(this.activeNode, uploaded);
|
|
},
|
|
|
|
/**
|
|
* @param {Object} element
|
|
* @param {*} value
|
|
*/
|
|
insertAtCursor: function (element, value) {
|
|
var sel, startPos, endPos, scrollTop;
|
|
|
|
if ('selection' in document) {
|
|
//For browsers like Internet Explorer
|
|
element.focus();
|
|
sel = document.selection.createRange();
|
|
sel.text = value;
|
|
element.focus();
|
|
} else if (element.selectionStart || element.selectionStart == '0') { //eslint-disable-line eqeqeq
|
|
//For browsers like Firefox and Webkit based
|
|
startPos = element.selectionStart;
|
|
endPos = element.selectionEnd;
|
|
scrollTop = element.scrollTop;
|
|
element.value = element.value.substring(0, startPos) + value +
|
|
element.value.substring(startPos, endPos) + element.value.substring(endPos, element.value.length);
|
|
element.focus();
|
|
element.selectionStart = startPos + value.length;
|
|
element.selectionEnd = startPos + value.length + element.value.substring(startPos, endPos).length;
|
|
element.scrollTop = scrollTop;
|
|
} else {
|
|
element.value += value;
|
|
element.focus();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* @param {Object} node
|
|
*/
|
|
loadFileList: function (node, uploaded) {
|
|
var contentBlock = this.element.find('#contents');
|
|
|
|
return $.ajax({
|
|
url: this.options.contentsUrl,
|
|
type: 'GET',
|
|
dataType: 'html',
|
|
data: {
|
|
'form_key': FORM_KEY,
|
|
node: node ? node.id : null
|
|
},
|
|
context: contentBlock,
|
|
showLoader: true
|
|
}).done(function (data) {
|
|
contentBlock.html(data).trigger('contentUpdated');
|
|
|
|
if (uploaded) {
|
|
contentBlock.find('.filecnt:last').trigger('click');
|
|
}
|
|
});
|
|
},
|
|
|
|
/**
|
|
* @param {jQuery.Event} event
|
|
*/
|
|
selectFolder: function (event) {
|
|
this.element.find('[data-id="' + $(event.currentTarget).data('node').id + '"]>a').trigger('click');
|
|
},
|
|
|
|
/**
|
|
* Insert selected files.
|
|
*/
|
|
insertSelectedFiles: function () {
|
|
this.element.find('[data-row=file].selected').trigger('dblclick');
|
|
},
|
|
|
|
/**
|
|
* @param {jQuery.Event} event
|
|
*/
|
|
selectFile: function (event) {
|
|
var fileRow = $(event.currentTarget);
|
|
|
|
fileRow.toggleClass('selected');
|
|
this.element.find('[data-row=file]').not(fileRow).removeClass('selected');
|
|
this.element.find('#delete_files, #insert_files')
|
|
.toggleClass(this.options.hidden, !fileRow.is('.selected'));
|
|
fileRow.trigger('selectfile');
|
|
},
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
_uploadDone: function () {
|
|
this.element.find('.file-row').remove();
|
|
this.reload(true);
|
|
},
|
|
|
|
/**
|
|
* @param {jQuery.Event} event
|
|
* @return {Boolean}
|
|
*/
|
|
insert: function (event) {
|
|
var fileRow = $(event.currentTarget),
|
|
targetEl;
|
|
|
|
if (!fileRow.prop('id')) {
|
|
return false;
|
|
}
|
|
targetEl = this.getTargetElement();
|
|
|
|
if (!targetEl.length) {
|
|
MediabrowserUtility.closeDialog();
|
|
throw 'Target element not found for content update';
|
|
}
|
|
|
|
return $.ajax({
|
|
url: this.options.onInsertUrl,
|
|
data: {
|
|
filename: fileRow.attr('id'),
|
|
node: this.activeNode.id,
|
|
store: this.options.storeId,
|
|
'as_is': typeof targetEl !== 'function' && targetEl.is('textarea') ? 1 : 0,
|
|
'force_static_path': typeof targetEl !== 'function' && targetEl.data('force_static_path') ? 1 : 0,
|
|
'form_key': FORM_KEY
|
|
},
|
|
context: this,
|
|
showLoader: true
|
|
}).done($.proxy(function (data) {
|
|
if (typeof targetEl === 'function') {
|
|
targetEl(data, {text: fileRow.find('img').attr('alt')});
|
|
} else if (targetEl.is('textarea')) {
|
|
this.insertAtCursor(targetEl.get(0), data);
|
|
} else {
|
|
targetEl
|
|
.val(data)
|
|
.data('size', fileRow.data('size'))
|
|
.data('mime-type', fileRow.data('mime-type'));
|
|
}
|
|
MediabrowserUtility.closeDialog();
|
|
|
|
if (typeof targetEl !== 'function') {
|
|
targetEl.focus();
|
|
jQuery(targetEl).trigger('change');
|
|
}
|
|
}, this));
|
|
},
|
|
|
|
/**
|
|
* Find document target element in next order:
|
|
* in acive file browser opener:
|
|
* - input field with ID: "src" in opener window
|
|
* - input field with ID: "href" in opener window
|
|
* in document:
|
|
* - element with target ID
|
|
*
|
|
* return {HTMLElement|null}
|
|
*/
|
|
getTargetElement: function () {
|
|
var mediaBrowser = window.MediabrowserUtility;
|
|
|
|
if (!_.isUndefined(wysiwyg) && wysiwyg.get(mediaBrowser.targetElementId)) {
|
|
return this.getMediaBrowserOpener() || window;
|
|
}
|
|
|
|
return $('#' + mediaBrowser.targetElementId);
|
|
},
|
|
|
|
/**
|
|
* Return opener Window object if it exists, not closed and editor is active
|
|
*
|
|
* return {Object|null}
|
|
*/
|
|
getMediaBrowserOpener: function () {
|
|
var targetElementId = window.MediabrowserUtility.targetElementId;
|
|
|
|
if (!_.isUndefined(wysiwyg) && wysiwyg.get(targetElementId) && !_.isUndefined(tinyMceEditors)) {
|
|
return tinyMceEditors.get(targetElementId).getMediaBrowserOpener();
|
|
}
|
|
|
|
return null;
|
|
},
|
|
|
|
/**
|
|
* New folder.
|
|
*/
|
|
newFolder: function () {
|
|
var self = this;
|
|
|
|
prompt({
|
|
title: this.options.newFolderPrompt,
|
|
actions: {
|
|
/**
|
|
* @param {*} folderName
|
|
*/
|
|
confirm: function (folderName) {
|
|
$.ajax({
|
|
url: self.options.newFolderUrl,
|
|
dataType: 'json',
|
|
data: {
|
|
name: folderName,
|
|
node: self.activeNode.id,
|
|
store: self.options.storeId,
|
|
'form_key': FORM_KEY
|
|
},
|
|
context: self.element,
|
|
showLoader: true
|
|
}).done($.proxy(function (data) {
|
|
if (data.error) {
|
|
alert({
|
|
content: data.message
|
|
});
|
|
} else {
|
|
self.tree.jstree(
|
|
'refresh_node',
|
|
self.element.find('[data-id="' + self.activeNode.id + '"]')
|
|
);
|
|
}
|
|
}, this));
|
|
|
|
return true;
|
|
}
|
|
}
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Delete folder.
|
|
*/
|
|
deleteFolder: function () {
|
|
var self = this;
|
|
|
|
confirm({
|
|
content: this.options.deleteFolderConfirmationMessage,
|
|
actions: {
|
|
/**
|
|
* Confirm.
|
|
*/
|
|
confirm: function () {
|
|
return $.ajax({
|
|
url: self.options.deleteFolderUrl,
|
|
dataType: 'json',
|
|
data: {
|
|
node: self.activeNode.id,
|
|
store: self.options.storeId,
|
|
'form_key': FORM_KEY
|
|
},
|
|
context: self.element,
|
|
showLoader: true
|
|
}).done($.proxy(function (data) {
|
|
if (data.error) {
|
|
alert({
|
|
content: data.message
|
|
});
|
|
} else {
|
|
self.tree.jstree('refresh', self.activeNode.id);
|
|
self.reload();
|
|
$(window).trigger('fileDeleted.mediabrowser', {
|
|
ids: self.activeNode.id
|
|
});
|
|
}
|
|
}, this));
|
|
},
|
|
|
|
/**
|
|
* @return {Boolean}
|
|
*/
|
|
cancel: function () {
|
|
return false;
|
|
}
|
|
}
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Delete files.
|
|
*/
|
|
deleteFiles: function () {
|
|
var self = this;
|
|
|
|
confirm({
|
|
content: this.options.deleteFileConfirmationMessage,
|
|
actions: {
|
|
/**
|
|
* Confirm.
|
|
*/
|
|
confirm: function () {
|
|
var selectedFiles = self.element.find('[data-row=file].selected'),
|
|
ids = selectedFiles.map(function () {
|
|
return $(this).attr('id');
|
|
}).toArray();
|
|
|
|
return $.ajax({
|
|
url: self.options.deleteFilesUrl,
|
|
data: {
|
|
files: ids,
|
|
store: self.options.storeId,
|
|
'form_key': FORM_KEY
|
|
},
|
|
context: self.element,
|
|
showLoader: true
|
|
}).done($.proxy(function (data) {
|
|
if (data.error) {
|
|
alert({
|
|
content: data.message
|
|
});
|
|
} else {
|
|
self.reload();
|
|
self.element.find('#delete_files, #insert_files').toggleClass(
|
|
self.options.hidden, true
|
|
);
|
|
|
|
$(window).trigger('fileDeleted.mediabrowser', {
|
|
ids: ids
|
|
});
|
|
}
|
|
}, this));
|
|
},
|
|
|
|
/**
|
|
* @return {Boolean}
|
|
*/
|
|
cancel: function () {
|
|
return false;
|
|
}
|
|
}
|
|
});
|
|
},
|
|
|
|
/**
|
|
* @param {Object} data
|
|
*/
|
|
drawBreadcrumbs: function (data) {
|
|
var node, breadcrumbs;
|
|
|
|
if (this.element.find('#breadcrumbs').length) {
|
|
this.element.find('#breadcrumbs').remove();
|
|
}
|
|
node = data.node;
|
|
|
|
if (node.id === 'root') { //eslint-disable-line eqeqeq
|
|
return;
|
|
}
|
|
breadcrumbs = $('<ul class="breadcrumbs" id="breadcrumbs"></ul>');
|
|
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
|
|
data.instance.get_path(node).each(function (name, index) {
|
|
if (index > 0) {
|
|
breadcrumbs.append($('<li>\/</li>')); //eslint-disable-line
|
|
}
|
|
breadcrumbs.append($('<li />').attr('data-row', 'breadcrumb').text(name));
|
|
|
|
});
|
|
// jscs:enable requireCamelCaseOrUpperCaseIdentifiers
|
|
|
|
breadcrumbs.insertAfter(this.element.find('#content_header'));
|
|
}
|
|
});
|
|
|
|
return window.MediabrowserUtility;
|
|
});
|