Implemented image inserting to Redactor.
This commit is contained in:
parent
cb0c483857
commit
332d92f538
|
|
@ -78,7 +78,7 @@ var Base=function(){this.proxiedMethods={}}
|
|||
Base.prototype.dispose=function()
|
||||
{for(var key in this.proxiedMethods){this.proxiedMethods[key]=null}
|
||||
this.proxiedMethods=null}
|
||||
Base.prototype.proxy=function(method,name){if(method.ocProxyId===undefined){$.oc.foundation._proxyCounter++
|
||||
Base.prototype.proxy=function(method){if(method.ocProxyId===undefined){$.oc.foundation._proxyCounter++
|
||||
method.ocProxyId=$.oc.foundation._proxyCounter}
|
||||
if(this.proxiedMethods[method.ocProxyId]!==undefined)
|
||||
return this.proxiedMethods[method.ocProxyId]
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@
|
|||
/*
|
||||
* Creates a proxied method reference or returns an existing proxied method.
|
||||
*/
|
||||
Base.prototype.proxy = function(method, name) {
|
||||
Base.prototype.proxy = function(method) {
|
||||
if (method.ocProxyId === undefined) {
|
||||
$.oc.foundation._proxyCounter++
|
||||
method.ocProxyId = $.oc.foundation._proxyCounter
|
||||
|
|
|
|||
|
|
@ -254,6 +254,10 @@ to{background-position:0 0}
|
|||
.redactor-toolbar li a{color:#404040;font-size:14px;width:20px;line-height:20px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
|
||||
.redactor-toolbar li a:hover{background-color:#999999;color:#ffffff}
|
||||
.redactor-toolbar li a:active,.redactor-toolbar li a.redactor-act{background-color:#404040;color:#ffffff}
|
||||
.redactor-toolbar li a.fa-redactor-btn{padding:9px 10px;line-height:20px}
|
||||
.redactor-toolbar li a.oc-redactor-button i:before{font-size:16px !important}
|
||||
.redactor-toolbar li a.oc-autumn-button{color:#c03f31}
|
||||
.redactor-toolbar li a.oc-autumn-button:hover{color:white !important}
|
||||
.redactor-editor{border:none;font-size:13px;color:#555555;padding:15px}
|
||||
.field-richeditor.stretch .redactor-box{display:block;position:relative;height:100% !important;width:100% !important;-webkit-border-radius:0 !important;-moz-border-radius:0 !important;border-radius:0 !important;overflow:hidden}
|
||||
.field-richeditor.stretch .redactor-box .redactor-toolbar{-webkit-border-radius:0 !important;-moz-border-radius:0 !important;border-radius:0 !important;display:block;border-bottom:none;position:absolute;width:100%;top:0}
|
||||
|
|
|
|||
|
|
@ -1877,8 +1877,8 @@ self.$form.trigger('change')
|
|||
if(self.$dataLocker)
|
||||
self.$dataLocker.val(self.syncBefore(this.$editor.html()))}}
|
||||
if(this.options.fullpage){redactorOptions.fullpage=true}
|
||||
redactorOptions.plugins=['cleanup','fullscreen','figure','quote','table']
|
||||
redactorOptions.buttons=['formatting','bold','italic','unorderedlist','orderedlist','image','link','horizontalrule','html'],this.$textarea.redactor(redactorOptions)}
|
||||
redactorOptions.plugins=['cleanup','fullscreen','figure','quote','table','mediamanager','image']
|
||||
redactorOptions.buttons=['formatting','bold','italic','unorderedlist','orderedlist','link','horizontalrule','html'],this.$textarea.redactor(redactorOptions)}
|
||||
RichEditor.prototype.build=function(redactor){this.updateLayout()
|
||||
$(window).resize($.proxy(this.updateLayout,this))
|
||||
$(window).on('oc.updateUi',$.proxy(this.updateLayout,this))
|
||||
|
|
|
|||
|
|
@ -81,8 +81,8 @@
|
|||
// redactorOptions.plugins = ['cleanup', 'fullscreen', 'figure', 'image', 'quote', 'table']
|
||||
// redactorOptions.buttons = ['formatting', 'bold', 'italic', 'unorderedlist', 'orderedlist', 'link', 'horizontalrule', 'html'],
|
||||
|
||||
redactorOptions.plugins = ['cleanup', 'fullscreen', 'figure', 'quote', 'table']
|
||||
redactorOptions.buttons = ['formatting', 'bold', 'italic', 'unorderedlist', 'orderedlist', 'image', 'link', 'horizontalrule', 'html'],
|
||||
redactorOptions.plugins = ['cleanup', 'fullscreen', 'figure', 'quote', 'table', 'mediamanager', 'image']
|
||||
redactorOptions.buttons = ['formatting', 'bold', 'italic', 'unorderedlist', 'orderedlist', 'link', 'horizontalrule', 'html'],
|
||||
|
||||
this.$textarea.redactor(redactorOptions)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,6 +86,25 @@
|
|||
background-color: @color-richeditor-toolbar-btn-bg-active;
|
||||
color: @color-richeditor-toolbar-btn-color-hover;
|
||||
}
|
||||
|
||||
// For some reasin the line height for fa- buttons was set to 1
|
||||
// and padding was not matching other buttons. -ab Apr 01 2015
|
||||
&.fa-redactor-btn {
|
||||
padding: 9px 10px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
&.oc-redactor-button i:before {
|
||||
font-size: 16px!important;
|
||||
}
|
||||
|
||||
&.oc-autumn-button {
|
||||
color: #c03f31;
|
||||
|
||||
&:hover {
|
||||
color: white!important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -274,6 +274,8 @@ return [
|
|||
'move_dest_src_match' => 'Please select another destination folder.',
|
||||
'empty_library' => 'The Media Library is empty. Upload files or create folders to get started.',
|
||||
'insert' => 'Insert',
|
||||
'crop_and_insert' => 'Crop & Insert'
|
||||
'crop_and_insert' => 'Crop & Insert',
|
||||
'select_single_image' => 'Please select a single image.',
|
||||
'selection_not_image' => 'The selected item is not an image.'
|
||||
]
|
||||
];
|
||||
|
|
|
|||
|
|
@ -32,6 +32,16 @@ class MediaManager extends WidgetBase
|
|||
|
||||
protected $brokenImageHash = null;
|
||||
|
||||
/**
|
||||
* @var boolean Determines whether the bottom toolbar is visible.
|
||||
*/
|
||||
public $bottomToolbar = false;
|
||||
|
||||
/**
|
||||
* @var boolean Determines whether the Crop & Insert button is visible.
|
||||
*/
|
||||
public $cropAndInsertButton = false;
|
||||
|
||||
public function __construct($controller, $alias)
|
||||
{
|
||||
$this->alias = $alias;
|
||||
|
|
@ -358,9 +368,17 @@ class MediaManager extends WidgetBase
|
|||
|
||||
public function onLoadPopup()
|
||||
{
|
||||
$this->bottomToolbar = Input::get('bottomToolbar', $this->bottomToolbar);
|
||||
$this->cropAndInsertButton = Input::get('cropAndInsertButton', $this->cropAndInsertButton);
|
||||
|
||||
return $this->makePartial('popup-body');
|
||||
}
|
||||
|
||||
public function onLoadImageCropPopup()
|
||||
{
|
||||
return $this->makePartial('image-crop-popup-body');
|
||||
}
|
||||
|
||||
//
|
||||
// Methods for th internal use
|
||||
//
|
||||
|
|
@ -514,9 +532,9 @@ class MediaManager extends WidgetBase
|
|||
{
|
||||
$this->addCss('css/mediamanager.css', 'core');
|
||||
|
||||
// TODO: combine and load combined
|
||||
// TODO: combine and minify
|
||||
$this->addJs('js/mediamanager.js', 'core');
|
||||
$this->addJs('js/mediamanager.popup.js', 'core');
|
||||
$this->addJs('js/mediamanager.imagecroppopup.js', 'core');
|
||||
}
|
||||
|
||||
protected function setViewMode($viewMode)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
div[data-control="media-manager"]:focus {
|
||||
outline: none;
|
||||
}
|
||||
div[data-control="media-manager"] audio,
|
||||
div[data-control="media-manager"] video {
|
||||
width: 100%;
|
||||
|
|
@ -343,6 +346,7 @@ div[data-control="media-manager"] div[data-control="selection-marker"] {
|
|||
position: absolute;
|
||||
z-index: 250;
|
||||
border: 1px dashed #95a5a6;
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
div[data-control="media-manager"] .upload-progress {
|
||||
background: #f9f9f9;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Media manager image editor popup
|
||||
*/
|
||||
+function ($) { "use strict";
|
||||
|
||||
if ($.oc.mediaManager === undefined)
|
||||
$.oc.mediaManager = {}
|
||||
|
||||
var Base = $.oc.foundation.base,
|
||||
BaseProto = Base.prototype
|
||||
|
||||
var MediaManagerImageCropPopup = function(path, options) {
|
||||
this.$popupRootElement = null
|
||||
|
||||
this.options = $.extend({}, MediaManagerImageCropPopup.DEFAULTS, options)
|
||||
this.path = path
|
||||
|
||||
Base.call(this)
|
||||
|
||||
this.init()
|
||||
this.show()
|
||||
}
|
||||
|
||||
MediaManagerImageCropPopup.prototype = Object.create(BaseProto)
|
||||
MediaManagerImageCropPopup.prototype.constructor = MediaManagerImageCropPopup
|
||||
|
||||
MediaManagerImageCropPopup.prototype.dispose = function() {
|
||||
this.unregisterHandlers()
|
||||
|
||||
this.$popupRootElement.remove()
|
||||
this.$popupRootElement = null
|
||||
this.$popupElement = null
|
||||
|
||||
BaseProto.dispose.call(this)
|
||||
}
|
||||
|
||||
MediaManagerImageCropPopup.prototype.init = function() {
|
||||
if (this.options.alias === undefined)
|
||||
throw new Error('Media Manager image crop popup option "alias" is not set.')
|
||||
|
||||
this.$popupRootElement = $('<div/>')
|
||||
this.registerHandlers()
|
||||
}
|
||||
|
||||
MediaManagerImageCropPopup.prototype.show = function() {
|
||||
var data = {
|
||||
path: this.path
|
||||
}
|
||||
|
||||
this.$popupRootElement.popup({
|
||||
extraData: data,
|
||||
size: 'adaptive',
|
||||
adaptiveHeight: true,
|
||||
handler: this.options.alias + '::onLoadImageCropPopup'
|
||||
})
|
||||
}
|
||||
|
||||
MediaManagerImageCropPopup.prototype.registerHandlers = function() {
|
||||
this.$popupRootElement.one('hide.oc.popup', this.proxy(this.onPopupHidden))
|
||||
this.$popupRootElement.one('shown.oc.popup', this.proxy(this.onPopupShown))
|
||||
}
|
||||
|
||||
MediaManagerImageCropPopup.prototype.unregisterHandlers = function() {
|
||||
}
|
||||
|
||||
MediaManagerImageCropPopup.prototype.hide = function() {
|
||||
if (this.$popupElement)
|
||||
this.$popupElement.trigger('close.oc.popup')
|
||||
}
|
||||
|
||||
// EVENT HANDLERS
|
||||
// ============================
|
||||
|
||||
MediaManagerImageCropPopup.prototype.onPopupHidden = function(event, element, popup) {
|
||||
// Release clickedElement reference inside redactor.js
|
||||
// If we don't do it, the image editor popup DOM elements
|
||||
// won't be removed from the memory.
|
||||
$(document).trigger('mousedown')
|
||||
|
||||
this.dispose()
|
||||
}
|
||||
|
||||
MediaManagerImageCropPopup.prototype.onPopupShown = function(event, element, popup) {
|
||||
this.$popupElement = popup
|
||||
}
|
||||
|
||||
MediaManagerImageCropPopup.DEFAULTS = {
|
||||
alias: undefined,
|
||||
onDone: undefined
|
||||
}
|
||||
|
||||
$.oc.mediaManager.imageCropPopup = MediaManagerImageCropPopup
|
||||
}(window.jQuery);
|
||||
|
|
@ -6,7 +6,8 @@
|
|||
*/
|
||||
+function ($) { "use strict";
|
||||
|
||||
$.oc.mediaManager = {}
|
||||
if ($.oc.mediaManager === undefined)
|
||||
$.oc.mediaManager = {}
|
||||
|
||||
var Base = $.oc.foundation.base,
|
||||
BaseProto = Base.prototype
|
||||
|
|
@ -19,7 +20,6 @@
|
|||
this.$form = this.$el.closest('form')
|
||||
|
||||
this.options = options
|
||||
|
||||
Base.call(this)
|
||||
|
||||
// State properties
|
||||
|
|
@ -73,6 +73,30 @@
|
|||
BaseProto.dispose.call(this)
|
||||
}
|
||||
|
||||
MediaManager.prototype.getSelectedItems = function(returnNotProcessed) {
|
||||
var items = this.$el.get(0).querySelectorAll('[data-type="media-item"].selected'),
|
||||
result = []
|
||||
|
||||
if (returnNotProcessed === true)
|
||||
return items
|
||||
|
||||
for (var i=0, len=items.length; i < len; i++) {
|
||||
var item = items[i],
|
||||
itemDetails = {
|
||||
itemType: item.getAttribute('data-item-type'),
|
||||
path: item.getAttribute('data-path'),
|
||||
title: item.getAttribute('data-title'),
|
||||
documentType: item.getAttribute('data-document-type'),
|
||||
folder: item.getAttribute('data-folder'),
|
||||
publicUrl: item.getAttribute('data-public-url')
|
||||
}
|
||||
|
||||
result.push(itemDetails)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// MEDIA MANAGER INTERNAL METHODS
|
||||
// ============================
|
||||
|
||||
|
|
@ -84,7 +108,7 @@
|
|||
this.$el.find('[data-control="bottom-toolbar"]').removeClass('hide')
|
||||
|
||||
if (this.options.cropAndInsertButton)
|
||||
this.$el.find('[data-command="crop-and-insert"]').removeClass('hide')
|
||||
this.$el.find('[data-popup-command="crop-and-insert"]').removeClass('hide')
|
||||
}
|
||||
|
||||
this.registerHandlers()
|
||||
|
|
@ -116,6 +140,7 @@
|
|||
this.$el.on('hidden.oc.popup', '[data-command="create-folder"]', this.proxy(this.onFolderPopupHidden))
|
||||
this.$el.on('shown.oc.popup', '[data-command="move"]', this.proxy(this.onMovePopupShown))
|
||||
this.$el.on('hidden.oc.popup', '[data-command="move"]', this.proxy(this.onMovePopupHidden))
|
||||
this.$el.on('keydown', this.proxy(this.onKeyDown))
|
||||
|
||||
if (this.itemListElement)
|
||||
this.itemListElement.addEventListener('mousedown', this.proxy(this.onListMouseDown))
|
||||
|
|
@ -137,6 +162,7 @@
|
|||
this.$el.off('hidden.oc.popup', '[data-command="create-folder"]', this.proxy(this.onFolderPopupHidden))
|
||||
this.$el.off('shown.oc.popup', '[data-command="move"]', this.proxy(this.onMovePopupShown))
|
||||
this.$el.off('hidden.oc.popup', '[data-command="move"]', this.proxy(this.onMovePopupHidden))
|
||||
this.$el.off('keydown', this.proxy(this.onKeyDown))
|
||||
|
||||
if (this.itemListElement) {
|
||||
this.itemListElement.removeEventListener('mousedown', this.proxy(this.onListMouseDown))
|
||||
|
|
@ -437,6 +463,9 @@
|
|||
}
|
||||
|
||||
MediaManager.prototype.replaceSidebarPlaceholder = function(response) {
|
||||
if (!this.sidebarPreviewElement)
|
||||
return
|
||||
|
||||
var sidebarThumbnail = this.sidebarPreviewElement.querySelector('[data-control="sidebar-thumbnail"]')
|
||||
if (!sidebarThumbnail)
|
||||
return
|
||||
|
|
@ -674,6 +703,33 @@
|
|||
})
|
||||
}
|
||||
|
||||
//
|
||||
// Cropping images
|
||||
//
|
||||
|
||||
MediaManager.prototype.cropSelectedImage = function(callback) {
|
||||
var selectedItems = this.getSelectedItems(true)
|
||||
|
||||
if (selectedItems.length != 1) {
|
||||
alert(this.options.selectSingleImage)
|
||||
return
|
||||
}
|
||||
|
||||
if (selectedItems[0].getAttribute('data-document-type') !== 'image') {
|
||||
alert(this.options.selectionNotImage)
|
||||
return
|
||||
}
|
||||
|
||||
new $.oc.mediaManager.imageCropPopup(
|
||||
selectedItems[0].getAttribute('data-path'), {
|
||||
alias: this.options.alias
|
||||
})
|
||||
}
|
||||
|
||||
MediaManager.prototype.onImageCropped = function(imageItem) {
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Search
|
||||
//
|
||||
|
|
@ -890,6 +946,11 @@
|
|||
this.resetSearch()
|
||||
this.gotoFolder($item.data('path'), true)
|
||||
}
|
||||
}
|
||||
else if ($item.data('item-type') == 'file') {
|
||||
// Trigger the Insert popup command if a file item
|
||||
// was double clicked.
|
||||
this.$el.trigger('popupcommand', ['insert'])
|
||||
}
|
||||
|
||||
return false
|
||||
|
|
@ -926,6 +987,14 @@
|
|||
case 'toggle-sidebar':
|
||||
this.toggleSidebar(ev)
|
||||
break;
|
||||
case 'popup-command':
|
||||
var popupCommand = $(ev.currentTarget).data('popup-command')
|
||||
|
||||
if (popupCommand !== 'crop-and-insert')
|
||||
this.$el.trigger('popupcommand', [popupCommand])
|
||||
else
|
||||
this.cropSelectedImage(this.proxy(this.onImageCropped))
|
||||
break;
|
||||
}
|
||||
|
||||
return false
|
||||
|
|
@ -1057,6 +1126,23 @@
|
|||
this.execNavigationRequest('onSetSorting', data)
|
||||
}
|
||||
|
||||
MediaManager.prototype.onKeyDown = function(ev) {
|
||||
var eventHandled = false
|
||||
|
||||
if (ev.which == 13) {
|
||||
// Trigger the Insert popup command when Enter
|
||||
// key is pressed
|
||||
this.$el.trigger('popupcommand', ['insert'])
|
||||
|
||||
eventHandled = true
|
||||
}
|
||||
|
||||
if (eventHandled) {
|
||||
ev.preventDefault()
|
||||
ev.stopPropagation()
|
||||
}
|
||||
}
|
||||
|
||||
// MEDIA MANAGER PLUGIN DEFINITION
|
||||
// ============================
|
||||
|
||||
|
|
@ -1065,6 +1151,8 @@
|
|||
deleteEmpty: 'Please select files to delete.',
|
||||
deleteConfirm: 'Do you really want to delete the selected file(s)?',
|
||||
moveEmpty: 'Please select files to move.',
|
||||
selectSingleImage: 'Please select a single image.',
|
||||
selectionNotImage: 'The selected item is not an image.',
|
||||
bottomToolbar: false,
|
||||
cropAndInsertButton: false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,38 +1,131 @@
|
|||
/*
|
||||
* Media manager popup
|
||||
*
|
||||
*/
|
||||
+function ($) { "use strict";
|
||||
|
||||
if ($.oc.mediaManager === undefined)
|
||||
$.oc.mediaManager = {}
|
||||
|
||||
var Base = $.oc.foundation.base,
|
||||
BaseProto = Base.prototype
|
||||
|
||||
var MediaManagerPopup = function(options) {
|
||||
this.$popupRootElement = null
|
||||
|
||||
this.options = $.extend({}, MediaManagerPopup.DEFAULTS, options)
|
||||
|
||||
Base.call(this)
|
||||
|
||||
this.init()
|
||||
this.show()
|
||||
}
|
||||
|
||||
MediaManagerPopup.prototype = Object.create(BaseProto)
|
||||
MediaManagerPopup.prototype.constructor = MediaManagerPopup
|
||||
|
||||
MediaManagerPopup.prototype.show = function() {
|
||||
var $popupRootElement = $('<div/>')
|
||||
MediaManagerPopup.prototype.dispose = function() {
|
||||
this.unregisterHandlers()
|
||||
|
||||
this.$popupRootElement.remove()
|
||||
this.$popupRootElement = null
|
||||
this.$popupElement = null
|
||||
|
||||
BaseProto.dispose.call(this)
|
||||
}
|
||||
|
||||
MediaManagerPopup.prototype.init = function() {
|
||||
if (this.options.alias === undefined)
|
||||
throw new Error('Media Manager popup option "alias" is not set.')
|
||||
|
||||
$popupRootElement.popup({
|
||||
this.$popupRootElement = $('<div/>')
|
||||
this.registerHandlers()
|
||||
}
|
||||
|
||||
MediaManagerPopup.prototype.registerHandlers = function() {
|
||||
this.$popupRootElement.one('hide.oc.popup', this.proxy(this.onPopupHidden))
|
||||
this.$popupRootElement.one('shown.oc.popup', this.proxy(this.onPopupShown))
|
||||
}
|
||||
|
||||
MediaManagerPopup.prototype.unregisterHandlers = function() {
|
||||
this.$popupElement.off('popupcommand', this.proxy(this.onPopupCommand))
|
||||
this.$popupRootElement.off('popupcommand', this.proxy(this.onPopupCommand))
|
||||
}
|
||||
|
||||
MediaManagerPopup.prototype.show = function() {
|
||||
var data = {
|
||||
bottomToolbar: this.options.bottomToolbar ? 1 : 0,
|
||||
cropAndInsertButton: this.options.cropAndInsertButton ? 1 : 0
|
||||
}
|
||||
console.log(data)
|
||||
this.$popupRootElement.popup({
|
||||
extraData: data,
|
||||
size: 'adaptive',
|
||||
adaptiveHeight: true,
|
||||
handler: this.options.alias + '::onLoadPopup'
|
||||
})
|
||||
}
|
||||
|
||||
MediaManagerPopup.prototype.hide = function() {
|
||||
if (this.$popupElement)
|
||||
this.$popupElement.trigger('close.oc.popup')
|
||||
}
|
||||
|
||||
MediaManagerPopup.prototype.getMediaManagerElement = function() {
|
||||
return this.$popupElement.find('[data-control="media-manager"]')
|
||||
}
|
||||
|
||||
MediaManagerPopup.prototype.insertMedia = function() {
|
||||
var items = this.getMediaManagerElement().mediaManager('getSelectedItems')
|
||||
|
||||
if (this.options.onInsert !== undefined)
|
||||
this.options.onInsert.call(this, items)
|
||||
}
|
||||
|
||||
// EVENT HANDLERS
|
||||
// ============================
|
||||
|
||||
MediaManagerPopup.prototype.onPopupHidden = function(event, element, popup) {
|
||||
var mediaManager = this.getMediaManagerElement()
|
||||
|
||||
mediaManager.mediaManager('dispose')
|
||||
mediaManager.remove()
|
||||
|
||||
// Release clickedElement reference inside redactor.js
|
||||
// If we don't do it, the Media Manager popup DOM elements
|
||||
// won't be removed from the memory.
|
||||
$(document).trigger('mousedown')
|
||||
|
||||
this.dispose()
|
||||
|
||||
if (this.options.onClose !== undefined)
|
||||
this.options.onClose.call(this)
|
||||
}
|
||||
|
||||
MediaManagerPopup.prototype.onPopupShown = function(event, element, popup) {
|
||||
this.$popupElement = popup
|
||||
this.$popupElement.on('popupcommand', this.proxy(this.onPopupCommand))
|
||||
|
||||
// Unfocus the Redactor field, otherwise all keyboard commands
|
||||
// in the Media Manager popup translate to Redactor.
|
||||
this.getMediaManagerElement().find('[data-control="sorting"]').focus().blur()
|
||||
}
|
||||
|
||||
MediaManagerPopup.prototype.onPopupCommand = function(ev, command) {
|
||||
switch (command) {
|
||||
case 'insert' :
|
||||
this.insertMedia()
|
||||
break;
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
MediaManagerPopup.DEFAULTS = {
|
||||
alias: undefined
|
||||
alias: undefined,
|
||||
bottomToolbar: true,
|
||||
cropAndInsertButton: false,
|
||||
onInsert: undefined,
|
||||
onClose: undefined
|
||||
}
|
||||
|
||||
$.oc.mediaManager.popup = MediaManagerPopup
|
||||
|
|
|
|||
|
|
@ -0,0 +1,131 @@
|
|||
if (!RedactorPlugins) var RedactorPlugins = {};
|
||||
|
||||
RedactorPlugins.mediamanager = function()
|
||||
{
|
||||
// This plugin uses Redactor's undocumented internals directly (this.link).
|
||||
// If Redactor changes the internal link API, we will need
|
||||
// to rewrite the code.
|
||||
|
||||
function hideLinkTooltips() {
|
||||
$('.redactor-link-tooltip').remove()
|
||||
}
|
||||
|
||||
return {
|
||||
init: function()
|
||||
{
|
||||
// Insert link button
|
||||
var buttonInsertLink = this.button.add('mmInsertMediaLink', 'Insert Media Link');
|
||||
|
||||
this.button.setAwesome('mmInsertMediaLink', 'icon-link');
|
||||
buttonInsertLink.addClass('oc-redactor-button oc-autumn-button')
|
||||
this.button.addCallback(buttonInsertLink, this.mediamanager.onInsertLink);
|
||||
|
||||
// Insert image button
|
||||
var buttonInsertImage = this.button.add('mmInsertImageLink', 'Insert Media Image');
|
||||
buttonInsertImage.addClass('re-image oc-autumn-button')
|
||||
buttonInsertImage.removeClass('redactor-btn-image')
|
||||
this.button.addCallback(buttonInsertImage, this.mediamanager.onInsertImage);
|
||||
},
|
||||
|
||||
onInsertLink: function(buttonName)
|
||||
{
|
||||
var that = this
|
||||
hideLinkTooltips()
|
||||
|
||||
this.selection.save()
|
||||
this.link.getData()
|
||||
|
||||
new $.oc.mediaManager.popup({
|
||||
alias: 'ocmediamanager',
|
||||
cropAndInsertButton: false,
|
||||
onInsert: function(items) {
|
||||
if (!items.length) {
|
||||
alert('Please select files to insert links to.')
|
||||
return
|
||||
}
|
||||
|
||||
if (items.length > 1) {
|
||||
alert('Please select a single file.')
|
||||
return
|
||||
}
|
||||
|
||||
var text = that.link.text,
|
||||
textIsEmpty = $.trim(text) === ''
|
||||
|
||||
for (var i=0, len=items.length; i<len; i++) {
|
||||
var text = textIsEmpty ? items[i].title : text
|
||||
|
||||
that.link.set(text, items[i].publicUrl, '')
|
||||
}
|
||||
|
||||
this.hide()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
onInsertImage: function(buttonName)
|
||||
{
|
||||
hideLinkTooltips()
|
||||
|
||||
if (!this.selection.getCurrent())
|
||||
this.focus.setStart();
|
||||
|
||||
this.selection.save()
|
||||
|
||||
var that = this
|
||||
|
||||
new $.oc.mediaManager.popup({
|
||||
alias: 'ocmediamanager',
|
||||
cropAndInsertButton: true,
|
||||
onInsert: function(items) {
|
||||
if (!items.length) {
|
||||
alert('Please select image(s) to insert.')
|
||||
return
|
||||
}
|
||||
that.selection.restore()
|
||||
|
||||
// The code is partially borrowed from redactor.js, image plugin
|
||||
|
||||
var isP = that.utils.isCurrentOrParent('P'),
|
||||
html = '',
|
||||
imagesInserted = 0
|
||||
|
||||
for (var i=0, len=items.length; i<len; i++) {
|
||||
if (items[i].documentType !== 'image') {
|
||||
alert('The file "'+items[i].title+'" is not an image.')
|
||||
continue
|
||||
}
|
||||
|
||||
var $img = $('<img>')
|
||||
.attr('src', items[i].publicUrl)
|
||||
.attr('data-redactor-inserted-image', 'true')
|
||||
|
||||
html += that.utils.getOuterHtml($img)
|
||||
imagesInserted++
|
||||
}
|
||||
|
||||
if (imagesInserted > 0) {
|
||||
if (isP)
|
||||
html = '<blockquote>' + html + '</blockquote>'
|
||||
|
||||
that.selection.restore()
|
||||
that.buffer.set()
|
||||
that.insert.html(html, false);
|
||||
|
||||
var $image = that.$editor.find('img[data-redactor-inserted-image=true]').removeAttr('data-redactor-inserted-image')
|
||||
|
||||
if (isP)
|
||||
$image.parent().contents().unwrap().wrap('<p />')
|
||||
else {
|
||||
if (that.opts.linebreaks)
|
||||
$image.before('<br>').after('<br>')
|
||||
}
|
||||
}
|
||||
|
||||
if (imagesInserted !== 0)
|
||||
this.hide()
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
@ -32,6 +32,10 @@
|
|||
}
|
||||
|
||||
div[data-control="media-manager"] {
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.loading-indicator-pseudo-absolute(@size) {
|
||||
background-image: url(../../../../../../modules/backend/assets/images/loading-indicator-transparent.svg);
|
||||
background-position: 50% 50%;
|
||||
|
|
@ -403,6 +407,7 @@ div[data-control="media-manager"] {
|
|||
position: absolute;
|
||||
z-index: 250;
|
||||
border: 1px dashed #95a5a6;
|
||||
background: rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.upload-progress {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,11 @@
|
|||
data-delete-empty="<?= e(trans('cms::lang.media.delete_empty')) ?>"
|
||||
data-delete-confirm="<?= e(trans('cms::lang.media.delete_confirm')) ?>"
|
||||
data-move-empty="<?= e(trans('cms::lang.media.move_empty')) ?>"
|
||||
data-select-single-image="<?= e(trans('cms::lang.media.select_single_image')) ?>"
|
||||
data-selection-not-image="<?= e(trans('cms::lang.media.selection_not_image')) ?>"
|
||||
data-bottom-toolbar="<?= $this->bottomToolbar ? 'true' : 'false' ?>"
|
||||
data-crop-and-insert-button="<?= $this->cropAndInsertButton ? 'true' : 'false' ?>"
|
||||
tabindex="0"
|
||||
>
|
||||
|
||||
<?= $this->makePartial('toolbar') ?>
|
||||
|
|
@ -48,32 +53,7 @@
|
|||
</div>
|
||||
|
||||
<div class="layout-row min-size hide" data-control="bottom-toolbar">
|
||||
<div class="panel no-padding-bottom border-top">
|
||||
<div class="form-buttons">
|
||||
<div class="pull-right">
|
||||
<button
|
||||
type="button"
|
||||
data-command="insert"
|
||||
class="btn btn-primary">
|
||||
<?= e(trans('cms::lang.media.insert')) ?>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
data-command="crop-and-insert"
|
||||
class="btn btn-primary hide">
|
||||
<?= e(trans('cms::lang.media.crop_and_insert')) ?>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
data-command="insert"
|
||||
class="btn btn-default no-margin-right">
|
||||
<?= e(trans('backend::lang.form.cancel')) ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?= $this->makePartial('bottom-toolbar') ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
<div class="panel no-padding-bottom border-top">
|
||||
<div class="form-buttons">
|
||||
<div class="pull-right">
|
||||
<button
|
||||
type="button"
|
||||
data-command="popup-command"
|
||||
data-popup-command="insert"
|
||||
class="btn btn-primary">
|
||||
<?= e(trans('cms::lang.media.insert')) ?>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
data-command="popup-command"
|
||||
data-popup-command="crop-and-insert"
|
||||
class="btn btn-primary hide">
|
||||
<?= e(trans('cms::lang.media.crop_and_insert')) ?>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
data-dismiss="popup"
|
||||
class="btn btn-default no-margin-right">
|
||||
<?= e(trans('backend::lang.form.cancel')) ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<?= Form::open(['class'=>'layout', 'onsubmit'=>'return false']) ?>
|
||||
<p>Something</p>
|
||||
<?= Form::close() ?>
|
||||
Loading…
Reference in New Issue