/* * Media manager image editor popup */ +function ($) { "use strict"; if ($.wn.mediaManager === undefined) $.wn.mediaManager = {} var Base = $.wn.foundation.base, BaseProto = Base.prototype var MediaManagerImageCropPopup = function(path, options) { this.$popupRootElement = null this.$popupElement = null this.selectionSizeLabel = null this.imageArea = null this.hRulerHolder = null this.vRulerHolder = null this.rulersVisible = false this.prevScrollTop = 0 this.prevScrollLeft = 0 this.jCrop = 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.removeAttachedControls() this.$popupRootElement.remove() this.$popupRootElement = null this.$popupElement = null this.selectionSizeLabel = null this.imageArea = null this.hRulerHolder = null this.vRulerHolder = 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 = $('
') 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', zIndex: 1200 // Media Manager can be opened in a popup, so this new popup should have a higher z-index }) } 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() { this.$popupElement.off('change', '[data-control="selection-mode"]', this.proxy(this.onSelectionModeChanged)) this.$popupElement.off('click', '[data-command]', this.proxy(this.onCommandClick)) this.$popupElement.off('shown.oc.popup', 'button[data-command=resize]', this.proxy(this.onResizePopupShown)) this.$popupElement.off('hidden.oc.popup', 'button[data-command=resize]', this.proxy(this.onResizePopupHidden)) if (this.rulersVisible) { var $cropToolRoot = this.$popupElement.find('[data-control=media-manager-crop-tool]') this.imageArea.removeEventListener('scroll', this.proxy(this.onImageScroll)) } this.getWidthInput().off('change', this.proxy(this.onSizeInputChange)) this.getHeightInput().off('change', this.proxy(this.onSizeInputChange)) } MediaManagerImageCropPopup.prototype.removeAttachedControls = function() { if (this.$popupElement) { // Note - the controls are destroyed and removed from DOM. If they're just destroyed, // the JS plugins could be re-attached to them on window.onresize. -ab this.$popupElement.find('[data-control="selection-mode"]').select2('destroy').remove() this.$popupElement.find('[data-control=toolbar]').toolbar('dispose').remove() this.jCrop.destroy() } this.jCrop = null } MediaManagerImageCropPopup.prototype.hide = function() { if (this.$popupElement) this.$popupElement.trigger('close.oc.popup') } MediaManagerImageCropPopup.prototype.getSelectionMode = function() { return this.$popupElement.find('[data-control="selection-mode"]').val() } MediaManagerImageCropPopup.prototype.initRulers = function() { if (!Modernizr.csstransforms) return var $cropToolRoot = this.$popupElement.find('[data-control=media-manager-crop-tool]'), width = $cropToolRoot.data('image-width'), height = $cropToolRoot.data('image-height') if (!width || !height) return if ($cropToolRoot.width() > width) width = $(window).width() if ($cropToolRoot.height() > height) height = $(window).height() $cropToolRoot.find('.ruler-container').removeClass('hide') $cropToolRoot.addClass('has-rulers') var $hRuler = $cropToolRoot.find('[data-control=h-ruler]'), $vRuler = $cropToolRoot.find('[data-control=v-ruler]'), hTicks = width / 40 + 1, vTicks = height / 40 + 1 this.createRulerTicks($hRuler, hTicks) this.createRulerTicks($vRuler, vTicks) this.rulersVisible = true this.imageArea.addEventListener('scroll', this.proxy(this.onImageScroll)) this.hRulerHolder = $cropToolRoot.find('.ruler-container.horizontal .layout-relative').get(0) this.vRulerHolder = $cropToolRoot.find('.ruler-container.vertical .layout-relative').get(0) } MediaManagerImageCropPopup.prototype.createRulerTicks = function($rulerElement, count) { var list = document.createElement('ul') for (var i=0; i <= count; i++) { var li = document.createElement('li') li.textContent = i*40 list.appendChild(li) } $rulerElement.append(list) } MediaManagerImageCropPopup.prototype.initJCrop = function() { this.jCrop = $.Jcrop($(this.imageArea).find('img').get(0), { shade: true, onChange: this.proxy(this.onSelectionChanged) }) } MediaManagerImageCropPopup.prototype.fixDimensionValue = function(value) { var result = value.replace(/[^0-9]+/, '') if (!result.length) result = 200 if (result == '0') result = 1 return result } MediaManagerImageCropPopup.prototype.getWidthInput = function() { return this.$popupElement.find('[data-control="crop-width-input"]') } MediaManagerImageCropPopup.prototype.getHeightInput = function() { return this.$popupElement.find('[data-control="crop-height-input"]') } MediaManagerImageCropPopup.prototype.applySelectionMode = function() { if (!this.jCrop) return var $widthInput = this.getWidthInput(), $heightInput = this.getHeightInput(), width = this.fixDimensionValue($widthInput.val()), height = this.fixDimensionValue($heightInput.val()), mode = this.getSelectionMode() switch (mode) { case 'fixed-ratio' : this.jCrop.setOptions({ aspectRatio: width/height, minSize: [0, 0], maxSize: [0, 0], allowResize: true }) break case 'fixed-size' : this.jCrop.setOptions({ aspectRatio: 0, minSize: [width, height], maxSize: [width, height], allowResize: false }) break case 'normal' : this.jCrop.setOptions({ aspectRatio: 0, minSize: [0, 0], maxSize: [0, 0], allowResize: true }) break } } MediaManagerImageCropPopup.prototype.cropAndInsert = function() { var data = { img: $(this.imageArea).find('img').attr('src'), selection: this.jCrop.tellSelect() } $.wn.stripeLoadIndicator.show() this.$popupElement .find('form') .request(this.options.alias+'::onCropImage', { data: data }) .always(function() { $.wn.stripeLoadIndicator.hide() }) .done(this.proxy(this.onImageCropped)) } MediaManagerImageCropPopup.prototype.onImageCropped = function(response) { this.hide() if (this.options.onDone !== undefined) { this.options.onDone(response) } } MediaManagerImageCropPopup.prototype.showResizePopup = function() { this.$popupElement.find('button[data-command=resize]').popup({ content: this.$popupElement.find('[data-control="resize-template"]').html(), zIndex: 1220 }) } MediaManagerImageCropPopup.prototype.onResizePopupShown = function(ev, button, popup) { var $popup = $(popup), $widthControl = $popup.find('input[name=width]'), $heightControl = $popup.find('input[name=height]'), imageWidth = this.fixDimensionValue(this.$popupElement.find('input[data-control=dimension-width]').val()), imageHeight = this.fixDimensionValue(this.$popupElement.find('input[data-control=dimension-height]').val()) $widthControl.val(imageWidth) $heightControl.val(imageHeight) $widthControl.focus() $popup.on('submit.media', 'form', this.proxy(this.onResizeSubmit)) $widthControl.on('keyup.media', this.proxy(this.onResizeDimensionKeyUp)) $heightControl.on('keyup.media', this.proxy(this.onResizeDimensionKeyUp)) $widthControl.on('change.media', this.proxy(this.onResizeDimensionChanged)) $heightControl.on('change.media', this.proxy(this.onResizeDimensionChanged)) } MediaManagerImageCropPopup.prototype.onResizePopupHidden = function(ev, button, popup) { var $popup = $(popup), $widthControl = $popup.find('input[name=width]'), $heightControl = $popup.find('input[name=height]') $popup.off('.media', 'form') $widthControl.off('.media') $heightControl.off('.media') } MediaManagerImageCropPopup.prototype.onResizeDimensionKeyUp = function(ev) { var $target = $(ev.target), targetValue = this.fixDimensionValue($target.val()), otherDimensionName = $target.attr('name') == 'width' ? 'height' : 'width', $otherInput = $target.closest('form').find('input[name='+otherDimensionName+']'), ratio = this.$popupElement.find('[data-control=original-ratio]').val(), value = otherDimensionName == 'height' ? targetValue / ratio : targetValue * ratio $otherInput.val(Math.round(value)) } MediaManagerImageCropPopup.prototype.onResizeDimensionChanged = function(ev) { var $target = $(ev.target) $target.val(this.fixDimensionValue($target.val())) } MediaManagerImageCropPopup.prototype.onResizeSubmit = function(ev) { var data = { cropSessionKey: this.$popupElement.find('input[name=cropSessionKey]').val(), path: this.$popupElement.find('input[name=path]').val() } $.wn.stripeLoadIndicator.show() $(ev.target).request(this.options.alias+'::onResizeImage', { data: data }).always(function() { $.wn.stripeLoadIndicator.hide() }).done(this.proxy(this.imageResized)) ev.preventDefault() return false } MediaManagerImageCropPopup.prototype.imageResized = function(response) { this.$popupElement.find('button[data-command=resize]').popup('hide') this.updateImage(response.url, response.dimensions[0], response.dimensions[1]) } MediaManagerImageCropPopup.prototype.updateImage = function(url, width, hegiht) { this.jCrop.destroy() this.$popupElement.find('span[data-label=width]').text(width) this.$popupElement.find('span[data-label=height]').text(hegiht) this.$popupElement.find('input[data-control=dimension-width]').val(width) this.$popupElement.find('input[data-control=dimension-height]').val(hegiht) var $imageArea = $(this.imageArea) $imageArea.find('img').remove() var $img = $('