feat: VivesPOS landing on Winter CMS 1.2 — theme + plugin + Dockerfile
Some checks are pending
Module sub-split / Sub-split (push) Waiting to run

- Base: wintercms/winter branch 1.2 (full framework)
- Theme vivespos: Canvas 7 + Bootstrap 5 CDN, custom CSS
- Layout: deferred GTM/GA4 tracking, JSON-LD SoftwareApplication
- Partials: hero (offline-first), features, modes (offline/nube toggle),
  screenshots, pricing (3 planes), comparison, FAQ, CTA
- Plugin VivesPOS.Site with ContactForm
- Dockerfile: PHP 8.2 Apache, port 80, healthcheck
- Added winter/wn-pages, blog, sitemap, seo plugins
- Active theme set to vivespos
This commit is contained in:
2026-08-21 19:29:00 -06:00
commit 1f72193a64
3266 changed files with 531480 additions and 0 deletions

View File

@@ -0,0 +1,169 @@
div[data-control="media-manager"]:focus{outline:none}
div[data-control="media-manager"] audio,
div[data-control="media-manager"] video{width:100%}
div[data-control="media-manager"] video{background:#ecf0f1;max-height:225px}
div[data-control="media-manager"] .file-icon{fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;display:inline-block}
div[data-control="media-manager"] .file-icon-extension{font-family:'ArialMT','Arial',sans-serif;font-size:4em;font-weight:900;fill:#fff}
div[data-control="media-manager"] .file-icon-label{fill:#576D7E;fill-rule:nonzero}
div[data-control="media-manager"] .file-icon-css,
div[data-control="media-manager"] .file-icon-less,
div[data-control="media-manager"] .file-icon-scss{fill:#B73FD9}
div[data-control="media-manager"] .file-icon-html,
div[data-control="media-manager"] .file-icon-xml{fill:#EA9B47}
div[data-control="media-manager"] .file-icon-js,
div[data-control="media-manager"] .file-icon-json{fill:#A9A9A9}
div[data-control="media-manager"] .file-icon-pdf{fill:#E30713}
div[data-control="media-manager"] .file-icon-txt{fill:#248BD0}
div[data-control="media-manager"] .file-icon-ai{fill:#F29200}
div[data-control="media-manager"] .file-icon-eps{fill:#F9B234}
div[data-control="media-manager"] .file-icon-psd{fill:#2DAAE2}
div[data-control="media-manager"] .file-icon-ttf,
div[data-control="media-manager"] .file-icon-otf,
div[data-control="media-manager"] .file-icon-woff,
div[data-control="media-manager"] .file-icon-woff2{fill:#C4CA10}
div[data-control="media-manager"] .file-icon-doc,
div[data-control="media-manager"] .file-icon-docx,
div[data-control="media-manager"] .file-icon-rtf,
div[data-control="media-manager"] .file-icon-odt{fill:#0F70B7}
div[data-control="media-manager"] .file-icon-csv,
div[data-control="media-manager"] .file-icon-ods,
div[data-control="media-manager"] .file-icon-xls,
div[data-control="media-manager"] .file-icon-xlsx{fill:#3BAA34}
div[data-control="media-manager"] .file-icon-odp,
div[data-control="media-manager"] .file-icon-ppt,
div[data-control="media-manager"] .file-icon-pptx{fill:#D04526}
div[data-control="media-manager"] .file-icon-rar,
div[data-control="media-manager"] .file-icon-tar,
div[data-control="media-manager"] .file-icon-zip{fill:#363A56}
div[data-control="media-manager"] .media-player-fallback{font-size:13px;color:#95a5a6;background:#ecf0f1;line-height:180%}
div[data-control="media-manager"] .media-player-fallback.panel-embedded{padding:20px;margin:-20px -20px 0 -20px}
div[data-control="media-manager"] .empty-library{padding:20px;text-align:center}
div[data-control="media-manager"] p.thumbnail-error-message{font-size:12px;margin:10px;line-height:160%;color:#bdc3c7}
div[data-control="media-manager"] .media-list{padding:0 0 0 20px;margin:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
div[data-control="media-manager"] .media-list li{display:inline-block;vertical-align:top;margin:0 20px 20px 0;overflow:hidden;cursor:pointer;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}
div[data-control="media-manager"] .media-list li:focus{outline:none}
div[data-control="media-manager"] .media-list li .icon-container{display:table}
div[data-control="media-manager"] .media-list li .icon-container i{color:#95a5a6;display:inline-block}
div[data-control="media-manager"] .media-list li .icon-container div{display:table-cell;text-align:center;vertical-align:middle}
div[data-control="media-manager"] .media-list li .icon-container.image>div.icon-wrapper{display:none}
div[data-control="media-manager"] .media-list li h4{font-weight:600;font-size:13px;color:#2b3e50;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:150%;margin:15px 0 5px 0;padding-right:0;-webkit-transition:padding 0.1s;transition:padding 0.1s;position:relative}
div[data-control="media-manager"] .media-list li h4 a{position:absolute;right:0;top:0;font-size:15px;color:#2b3e50;display:none}
div[data-control="media-manager"] .media-list li h4 a:hover{color:#2da7c7;text-decoration:none}
div[data-control="media-manager"] .media-list li p.size{font-size:12px;color:#95a5a6}
div[data-control="media-manager"] .media-list li .image-placeholder{position:relative}
div[data-control="media-manager"] .media-list li .image-placeholder i{padding-top:0;padding-left:2px}
div[data-control="media-manager"] .media-list li .image-placeholder[data-loading] i{display:none}
div[data-control="media-manager"] .media-list li .image-placeholder[data-loading]:after{background-image:url('../../../../../../modules/system/assets/ui/images/loader-transparent.svg');background-position:50% 50%;content:' ';-webkit-animation:spin 1s linear infinite;animation:spin 1s linear infinite;background-size:28px 28px;position:absolute;width:28px;height:28px;top:50%;left:50%;margin-top:-14px;margin-left:-14px}
div[data-control="media-manager"] .media-list li i.icon-chain-broken{padding:0;color:#bdc3c7}
div[data-control="media-manager"] .media-list li[data-item-type=folder] i{color:#48b2ce}
div[data-control="media-manager"] .media-list.list li{height:75px;width:260px;border:1px solid #ecf0f1;background:#f6f8f9;box-sizing:content-box}
div[data-control="media-manager"] .media-list.list li .icon-container{border-right:1px solid #f6f8f9;width:75px;height:75px;float:left}
div[data-control="media-manager"] .media-list.list li .icon-container img{max-height:75px}
div[data-control="media-manager"] .media-list.list li .icon-container i{font-size:35px}
div[data-control="media-manager"] .media-list.list li .icon-container svg{max-height:44px}
div[data-control="media-manager"] .media-list.list li .icon-container.image{border-right:1px solid #ecf0f1 !important}
div[data-control="media-manager"] .media-list.list li .icon-container p.thumbnail-error-message{display:none}
div[data-control="media-manager"] .media-list.list .icon-wrapper{width:75px}
div[data-control="media-manager"] .media-list.list li .info{margin-left:90px}
div[data-control="media-manager"] .media-list.list li .image-placeholder{width:75px;height:75px}
div[data-control="media-manager"] .media-list.list li[data-root] h4{margin-top:27px}
div[data-control="media-manager"] .media-list.list li.selected{background:#48b2ce !important}
div[data-control="media-manager"] .media-list.list li.selected i,
div[data-control="media-manager"] .media-list.list li.selected p.size{color:#ecf0f1}
div[data-control="media-manager"] .media-list.list li.selected h4{color:white}
div[data-control="media-manager"] .media-list.list li.selected .icon-container{border-right-color:#48b2ce !important}
div[data-control="media-manager"] .media-list.list h4{padding-right:15px}
div[data-control="media-manager"] .media-list.list h4 a{right:15px}
div[data-control="media-manager"] .media-list.tiles li{width:167px;margin-bottom:25px}
div[data-control="media-manager"] .media-list.tiles .icon-wrapper{width:167px}
div[data-control="media-manager"] .media-list.tiles li .image-placeholder{width:165px;height:165px}
div[data-control="media-manager"] .media-list.tiles li .image-placeholder[data-loading]:after{background-image:url('../../../../../../modules/system/assets/ui/images/loader-transparent.svg');background-position:50% 50%;content:' ';-webkit-animation:spin 1s linear infinite;animation:spin 1s linear infinite;background-size:55px 55px;position:absolute;width:55px;height:55px;top:50%;left:50%;margin-top:-27.5px;margin-left:-27.5px}
div[data-control="media-manager"] .media-list.tiles li .icon-container{width:165px;height:165px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;border:1px solid #ecf0f1;overflow:hidden;background:#f6f8f9;box-sizing:content-box}
div[data-control="media-manager"] .media-list.tiles li .icon-container img{max-height:165px}
div[data-control="media-manager"] .media-list.tiles li .icon-container i{font-size:55px}
div[data-control="media-manager"] .media-list.tiles li .icon-container svg{max-height:65px}
div[data-control="media-manager"] .media-list.tiles li .icon-container p{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"}
div[data-control="media-manager"] .media-list.tiles li.selected .icon-container{background:#48b2ce !important;border-color:#2581b8}
div[data-control="media-manager"] .media-list.tiles li.selected .icon-container i,
div[data-control="media-manager"] .media-list.tiles li.selected .icon-container p{color:#ecf0f1}
div[data-control="media-manager"] .media-list.tiles li.selected h4{color:#2581b8}
div[data-control="media-manager"] .media-list.tiles i.icon-chain-broken{margin-top:47px}
div[data-control="media-manager"] .media-list.tiles p.size{margin-bottom:0}
div[data-control="media-manager"] [data-control="sidebar-labels"]{word-wrap:break-word}
div[data-control="media-manager"] .sidebar-group{margin-bottom:20px}
div[data-control="media-manager"] .sidebar-image-placeholder-container,
div[data-control="media-manager"] .sidebar-document-placeholder-container{display:table;width:100%}
div[data-control="media-manager"] .sidebar-image-placeholder,
div[data-control="media-manager"] .sidebar-document-placeholder{display:table-cell;position:relative;vertical-align:middle;text-align:center;border-bottom:1px solid #ecf0f1;box-sizing:content-box}
div[data-control="media-manager"] .sidebar-image-placeholder{height:225px}
div[data-control="media-manager"] .sidebar-image-placeholder[data-loading]{background:#ecf0f1}
div[data-control="media-manager"] .sidebar-image-placeholder[data-loading]:after{background-image:url('../../../../../../modules/system/assets/ui/images/loader-transparent.svg');background-position:50% 50%;content:' ';-webkit-animation:spin 1s linear infinite;animation:spin 1s linear infinite;background-size:62px 62px;position:absolute;width:62px;height:62px;top:50%;left:50%;margin-top:-31px;margin-left:-31px}
div[data-control="media-manager"] .sidebar-image-placeholder i.icon-chain-broken,
div[data-control="media-manager"] .sidebar-image-placeholder i.icon-crop,
div[data-control="media-manager"] .sidebar-image-placeholder i.icon-asterisk,
div[data-control="media-manager"] .sidebar-image-placeholder i.icon-level-up{color:#bdc3c7;font-size:55px}
div[data-control="media-manager"] .sidebar-image-placeholder.no-border{border-bottom:none}
div[data-control="media-manager"] .sidebar-image-placeholder p{font-size:12px;margin:10px;line-height:160%;color:#bdc3c7;margin-top:25px}
div[data-control="media-manager"] .sidebar-image-placeholder img{max-width:100%;max-height:225px}
div[data-control="media-manager"] .sidebar-document-placeholder{height:155px}
div[data-control="media-manager"] .sidebar-document-placeholder svg{width:100px;height:100px}
div[data-control="media-manager"] .list-container{position:relative;z-index:100}
div[data-control="media-manager"] .list-container .no-data{font-size:13px}
div[data-control="media-manager"] .list-container p.no-data{padding:0 20px 20px 20px}
div[data-control="media-manager"] .list-container li.no-data{padding-top:20px;display:block !important;width:100% !important;border:none !important;background:transparent !important;cursor:default !important}
div[data-control="media-manager"] .list-container table.table.data tbody tr:not(.no-data):active td{background:#48b2ce !important}
div[data-control="media-manager"] [data-control="item-list"]{position:relative;display:table-cell}
div[data-control="media-manager"] .control-scrollpad{position:absolute;left:0;top:0;min-height:300px}
div[data-control="media-manager"] .scroll-wrapper{position:relative}
div[data-control="media-manager"] table.table{table-layout:fixed;margin-bottom:0;white-space:nowrap}
div[data-control="media-manager"] table.table div.no-wrap-text{overflow:hidden;text-overflow:ellipsis}
div[data-control="media-manager"] table.table div.item-title{position:relative;padding-right:0;-webkit-transition:padding 0.1s;transition:padding 0.1s}
div[data-control="media-manager"] table.table div.item-title a{position:absolute;right:0;top:0;display:none}
div[data-control="media-manager"] table.table tr:hover div.item-title{padding-right:25px}
div[data-control="media-manager"] table.table tr:hover div.item-title a{display:block}
div[data-control="media-manager"] table.table tr[data-item-type=folder] i.icon-folder{color:#48b2ce}
div[data-control="media-manager"] table.table tr:focus{outline:none}
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;padding:0 20px}
div[data-control="media-manager"] .upload-progress h5{margin:0 0 10px 0;font-size:13px;color:#2b3e50;font-weight:600}
div[data-control="media-manager"] .upload-progress h5 span{display:inline-block;margin-left:10px;color:#95a5a6;font-size:15px}
div[data-control="media-manager"] .upload-progress .progress-controls{padding-right:30px;position:relative}
div[data-control="media-manager"] .upload-progress .progress-controls .controls{position:absolute;right:0;bottom:0}
div[data-control="media-manager"] .upload-progress .progress-controls .controls a{display:block;position:relative;top:7px;right:3px;color:#95a5a6;font-size:16px;cursor:pointer!important}
div[data-control="media-manager"] .upload-progress .progress-controls .controls a:hover{text-decoration:none;color:#2da7c7}
div[data-control="media-manager"] .dz-preview{display:none}
div[data-control="media-manager"] button[data-command="toggle-sidebar"].sidebar-hidden{-webkit-transform:rotate(180deg) translate(0,0);-ms-transform:rotate(180deg) translate(0,0);transform:rotate(180deg) translate(0,0)}
[data-control="media-manager-crop-tool"] .image_area{position:absolute;width:100%;height:100%;overflow:auto}
[data-control="media-manager-crop-tool"] .image_area .jcrop-holder{background-color:transparent!important}
[data-control="media-manager-crop-tool"] img{cursor:crosshair;display:block}
[data-control="media-manager-crop-tool"].has-rulers .ruler-container .layout-relative{overflow:hidden}
[data-control="media-manager-crop-tool"].has-rulers .ruler-container.horizontal .layout-cell{height:20px}
[data-control="media-manager-crop-tool"].has-rulers .ruler-container.horizontal .layout-relative{width:100%}
[data-control="media-manager-crop-tool"].has-rulers .ruler-container.vertical{width:20px}
[data-control="media-manager-crop-tool"].has-rulers .ruler-container.vertical .layout-relative{height:100%}
[data-control="media-manager-crop-tool"].has-rulers .ruler{position:absolute;height:20px;margin-left:-3px;background:#555}
[data-control="media-manager-crop-tool"].has-rulers .ruler ul{margin:0;padding:0;white-space:nowrap;font-size:0}
[data-control="media-manager-crop-tool"].has-rulers .ruler li{margin:0;padding:0 0 0 40px;list-style:none;display:inline-block;width:24px;margin:0 -10px 0 -14px;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;text-align:left;position:relative;font-size:10px;line-height:20px;color:#ecf0f1;font-family:Arial,sans-serif}
[data-control="media-manager-crop-tool"].has-rulers .ruler li:before,
[data-control="media-manager-crop-tool"].has-rulers .ruler li:after{content:' ';position:absolute;border-left:1px solid #8e8e8e}
[data-control="media-manager-crop-tool"].has-rulers .ruler li:before{height:20px;top:0;left:-3px}
[data-control="media-manager-crop-tool"].has-rulers .ruler li:after{height:3px;bottom:0;left:20px}
[data-control="media-manager-crop-tool"].has-rulers .ruler li:first-child:after{display:none}
[data-control="media-manager-crop-tool"].has-rulers .ruler[data-control=v-ruler]{-webkit-transform:rotateZ(90deg);-ms-transform:rotateZ(90deg);transform:rotateZ(90deg);-webkit-transform-origin:left top;-moz-transform-origin:left top;-ms-transform-origin:left top;transform-origin:left top;left:23px;top:-23px}
[data-control="media-manager-crop-tool"].has-rulers .ruler[data-control=v-ruler] li:after{top:0;left:auto}
body:not(.no-select) div[data-control="media-manager"] .media-list.tiles li:hover .icon-container{background:#48b2ce !important;border-color:#2581b8}
body:not(.no-select) div[data-control="media-manager"] .media-list.tiles li:hover .icon-container i,
body:not(.no-select) div[data-control="media-manager"] .media-list.tiles li:hover .icon-container p{color:#ecf0f1}
body:not(.no-select) div[data-control="media-manager"] .media-list.tiles li:hover h4{color:#2581b8}
body:not(.no-select) div[data-control="media-manager"] .media-list.tiles li:hover h4{padding-right:20px !important}
body:not(.no-select) div[data-control="media-manager"] .media-list.list li:hover{background:#48b2ce !important}
body:not(.no-select) div[data-control="media-manager"] .media-list.list li:hover i,
body:not(.no-select) div[data-control="media-manager"] .media-list.list li:hover p.size{color:#ecf0f1}
body:not(.no-select) div[data-control="media-manager"] .media-list.list li:hover h4{color:white}
body:not(.no-select) div[data-control="media-manager"] .media-list.list li:hover .icon-container{border-right-color:#48b2ce !important}
body:not(.no-select) div[data-control="media-manager"] .media-list.list li:hover h4{padding-right:35px !important}
body:not(.no-select) div[data-control="media-manager"] .media-list li:hover h4 a{display:block}
@media (max-width:1280px){div[data-control="media-manager"] .media-list.list li{width:230px}}
@media (max-width:1024px){div[data-control="media-manager"] .media-list.list li{display:block;width:auto}}
@media (max-width:768px){div[data-control="media-manager"] [data-control="preview-sidebar"],div[data-control="media-manager"] [data-command="toggle-sidebar"]{display:none!important}div[data-control="media-manager"] .media-list.list{padding:0}div[data-control="media-manager"] .media-list.list li{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;margin:0;border-right:none;border-left:none;border-bottom:none}}
@media (max-width:480px){div[data-control="media-manager"] [data-control="left-sidebar"]{display:none!important}}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

@@ -0,0 +1,543 @@
+function($){"use strict";if($.wn.mediaManager===undefined)$.wn.mediaManager={}
var Base=$.wn.foundation.base,BaseProto=Base.prototype
var MediaManager=function(element,options){this.$el=$(element)
this.$form=this.$el.closest('form')
this.options=options
Base.call(this)
this.selectTimer=null
this.sidebarPreviewElement=null
this.itemListElement=null
this.scrollContentElement=null
this.thumbnailQueue=[]
this.activeThumbnailQueueLength=0
this.sidebarThumbnailAjax=null
this.selectionMarker=null
this.dropzone=null
this.searchTrackInputTimer=null
this.navigationAjax=null
this.dblTouchTimer=null
this.dblTouchFlag=null
this.itemListPosition=null
this.init()}
MediaManager.prototype=Object.create(BaseProto)
MediaManager.prototype.constructor=MediaManager
MediaManager.prototype.dispose=function(){this.unregisterHandlers()
this.clearSelectTimer()
this.destroyUploader()
this.clearSearchTrackInputTimer()
this.releaseNavigationAjax()
this.clearDblTouchTimer()
this.removeAttachedControls()
this.removeScroll()
this.$el.removeData('oc.mediaManager')
this.$el=null
this.$form=null
this.sidebarPreviewElement=null
this.itemListElement=null
this.scrollContentElement=null
this.sidebarThumbnailAjax=null
this.selectionMarker=null
this.thumbnailQueue=[]
this.navigationAjax=null
BaseProto.dispose.call(this)}
MediaManager.prototype.getSelectedItems=function(returnNotProcessed,allowRootItem){var items=this.$el.get(0).querySelectorAll('[data-type="media-item"].selected'),result=[]
if(!allowRootItem){var filteredItems=[]
for(var i=0,len=items.length;i<len;i++){var item=items[i]
if(!item.hasAttribute('data-root'))filteredItems.push(item)}items=filteredItems}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'),sizeBytes:item.getAttribute('data-size-bytes'),lastModified:item.getAttribute('data-last-modified-ts'),documentType:item.getAttribute('data-document-type'),folder:item.getAttribute('data-folder'),publicUrl:item.getAttribute('data-public-url')}
result.push(itemDetails)}return result}
MediaManager.prototype.init=function(){this.itemListElement=this.$el.find('[data-control="item-list"]').get(0)
this.scrollContentElement=this.itemListElement.querySelector('.scroll-wrapper')
if(this.options.bottomToolbar){this.$el.find('[data-control="bottom-toolbar"]').removeClass('hide')
if(this.options.cropAndInsertButton)this.$el.find('[data-popup-command="crop-and-insert"]').removeClass('hide')}this.registerHandlers()
this.updateSidebarPreview()
this.generateThumbnails()
this.initUploader()
this.initScroll()}
MediaManager.prototype.registerHandlers=function(){this.$el.on('dblclick',this.proxy(this.onNavigate))
this.$el.on('click.tree-path','ul.tree-path, [data-control="sidebar-labels"]',this.proxy(this.onNavigate))
this.$el.on('click.command','[data-command]',this.proxy(this.onCommandClick))
this.$el.on('click.item','[data-type="media-item"]',this.proxy(this.onItemClick))
this.$el.on('touchend','[data-type="media-item"]',this.proxy(this.onItemTouch))
this.$el.on('change','[data-control="sorting"]',this.proxy(this.onSortingChanged))
this.$el.on('input','[data-control="search"]',this.proxy(this.onSearchChanged))
this.$el.on('mediarefresh',this.proxy(this.refresh))
this.$el.on('shown.oc.popup','[data-command="create-folder"]',this.proxy(this.onFolderPopupShown))
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))}
MediaManager.prototype.unregisterHandlers=function(){this.$el.off('dblclick',this.proxy(this.onNavigate))
this.$el.off('click.tree-path',this.proxy(this.onNavigate))
this.$el.off('click.command',this.proxy(this.onCommandClick))
this.$el.off('click.item',this.proxy(this.onItemClick))
this.$el.off('touchend','[data-type="media-item"]',this.proxy(this.onItemTouch))
this.$el.off('change','[data-control="sorting"]',this.proxy(this.onSortingChanged))
this.$el.off('keyup','[data-control="search"]',this.proxy(this.onSearchChanged))
this.$el.off('shown.oc.popup','[data-command="create-folder"]',this.proxy(this.onFolderPopupShown))
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))
this.itemListElement.removeEventListener('mousemove',this.proxy(this.onListMouseMove))}document.removeEventListener('mouseup',this.proxy(this.onListMouseUp))}
MediaManager.prototype.changeView=function(view){var data={view:view,path:this.$el.find('[data-type="current-folder"]').val()}
this.execNavigationRequest('onChangeView',data)}
MediaManager.prototype.setFilter=function(filter){var data={filter:filter,path:this.$el.find('[data-type="current-folder"]').val()}
this.execNavigationRequest('onSetFilter',data)}
MediaManager.prototype.isSearchMode=function(){return this.$el.find('[data-type="search-mode"]').val()=='true'}
MediaManager.prototype.initScroll=function(){this.$el.find('.control-scrollpad').scrollpad()}
MediaManager.prototype.updateScroll=function(){this.$el.find('.control-scrollpad').scrollpad('update')}
MediaManager.prototype.removeScroll=function(){this.$el.find('.control-scrollpad').scrollpad('dispose')}
MediaManager.prototype.scrollToTop=function(){this.$el.find('.control-scrollpad').scrollpad('scrollToStart')}
MediaManager.prototype.removeAttachedControls=function(){this.$el.find('[data-control=toolbar]').toolbar('dispose')
this.$el.find('[data-control=sorting]').select2('destroy')}
MediaManager.prototype.clearSelectTimer=function(){if(this.selectTimer===null)return
clearTimeout(this.selectTimer)
this.selectTimer=null}
MediaManager.prototype.selectItem=function(node,expandSelection){if(!expandSelection){var items=this.$el.get(0).querySelectorAll('[data-type="media-item"].selected')
for(var i=0,len=items.length;i<len;i++){items[i].setAttribute('class','')}node.setAttribute('class','selected')}else{if(node.getAttribute('class')=='selected')node.setAttribute('class','')
else node.setAttribute('class','selected')}node.focus()
this.clearSelectTimer()
if(this.isPreviewSidebarVisible()){this.selectTimer=setTimeout(this.proxy(this.updateSidebarPreview),100)}if(node.hasAttribute('data-root')&&!expandSelection){this.toggleMoveAndDelete(true)}else{this.toggleMoveAndDelete(false)}if(expandSelection){this.unselectRoot()}}
MediaManager.prototype.toggleMoveAndDelete=function(value){$('[data-command=delete]',this.$el).prop('disabled',value)
$('[data-command=move]',this.$el).prop('disabled',value)}
MediaManager.prototype.unselectRoot=function(){var rootItem=this.$el.get(0).querySelector('[data-type="media-item"][data-root].selected')
if(rootItem)rootItem.setAttribute('class','')}
MediaManager.prototype.clearDblTouchTimer=function(){if(this.dblTouchTimer===null)return
clearTimeout(this.dblTouchTimer)
this.dblTouchTimer=null}
MediaManager.prototype.clearDblTouchFlag=function(){this.dblTouchFlag=false}
MediaManager.prototype.selectFirstItem=function(){var firstItem=this.itemListElement.querySelector('[data-type="media-item"]:first-child')
if(firstItem){this.selectItem(firstItem)}}
MediaManager.prototype.selectRelative=function(next,expandSelection){var currentSelection=this.getSelectedItems(true,true)
if(currentSelection.length==0){this.selectFirstItem()
return}var itemToSelect=null
if(next){var lastItem=currentSelection[currentSelection.length-1]
if(lastItem)itemToSelect=lastItem.nextElementSibling}else{var firstItem=currentSelection[0]
if(firstItem)itemToSelect=firstItem.previousElementSibling}if(itemToSelect)this.selectItem(itemToSelect,expandSelection)}
MediaManager.prototype.gotoFolder=function(path,resetSearch){var data={path:path,resetSearch:resetSearch!==undefined?1:0}
this.execNavigationRequest('onGoToFolder',data)}
MediaManager.prototype.afterNavigate=function(){this.scrollToTop()
this.generateThumbnails()
this.updateSidebarPreview(true)
this.selectFirstItem()
this.updateScroll()}
MediaManager.prototype.refresh=function(){var data={path:this.$el.find('[data-type="current-folder"]').val(),clearCache:true}
this.execNavigationRequest('onGoToFolder',data)}
MediaManager.prototype.execNavigationRequest=function(handler,data,element){if(element===undefined)element=this.$form
if(this.navigationAjax!==null){try{this.navigationAjax.abort()}catch(e){}this.releaseNavigationAjax()}$.wn.stripeLoadIndicator.show()
this.navigationAjax=element.request(this.options.alias+'::'+handler,{data:data}).always(function(){$.wn.stripeLoadIndicator.hide()}).done(this.proxy(this.afterNavigate)).always(this.proxy(this.releaseNavigationAjax))}
MediaManager.prototype.releaseNavigationAjax=function(){this.navigationAjax=null}
MediaManager.prototype.navigateToItem=function($item){if(!$item.length||!$item.data('path').length)return
if($item.data('item-type')=='folder'){if(!$item.data('clear-search'))this.gotoFolder($item.data('path'))
else{this.resetSearch()
this.gotoFolder($item.data('path'),true)}}else if($item.data('item-type')=='file'){this.$el.trigger('popupcommand',['insert'])}}
MediaManager.prototype.isPreviewSidebarVisible=function(){return!this.$el.find('[data-control="preview-sidebar"]').hasClass('hide')}
MediaManager.prototype.toggleSidebar=function(ev){var isVisible=this.isPreviewSidebarVisible(),$sidebar=this.$el.find('[data-control="preview-sidebar"]'),$button=$(ev.target)
if(!isVisible){$sidebar.removeClass('hide')
this.updateSidebarPreview()
$button.removeClass('sidebar-hidden')}else{$sidebar.addClass('hide')
$button.addClass('sidebar-hidden')}this.$form.request(this.options.alias+'::onSetSidebarVisible',{data:{visible:(isVisible?0:1)}})}
MediaManager.prototype.updateSidebarMediaPreview=function(items){var previewPanel=this.sidebarPreviewElement,previewContainer=previewPanel.querySelector('[data-control="media-preview-container"]'),template=''
for(var i=0,len=previewContainer.children.length;i<len;i++){previewContainer.removeChild(previewContainer.children[i])}if(items.length==1&&!items[0].hasAttribute('data-root')){var item=items[0],documentType=item.getAttribute('data-document-type')
switch(documentType){case'audio':template=previewPanel.querySelector('[data-control="audio-template"]').innerHTML
break;case'video':template=previewPanel.querySelector('[data-control="video-template"]').innerHTML
break;case'image':template=previewPanel.querySelector('[data-control="image-template"]').innerHTML
break;case'document':template=previewPanel.querySelector('[data-control="document-template"]').innerHTML
break;}previewContainer.innerHTML=template.replace('{src}',item.getAttribute('data-public-url')).replace('{path}',item.getAttribute('data-path')).replace('{last-modified}',item.getAttribute('data-last-modified-ts'))
if(documentType=='document')this.loadSidebarDocumentIcon(item)
if(documentType=='image')this.loadSidebarThumbnail()}else if(items.length==1&&items[0].hasAttribute('data-root')){template=previewPanel.querySelector('[data-control="go-up"]').innerHTML
previewContainer.innerHTML=template}else if(items.length==0){template=previewPanel.querySelector('[data-control="no-selection-template"]').innerHTML
previewContainer.innerHTML=template}else{template=previewPanel.querySelector('[data-control="multi-selection-template"]').innerHTML
previewContainer.innerHTML=template}}
MediaManager.prototype.updateSidebarPreview=function(resetSidebar){if(!this.sidebarPreviewElement)this.sidebarPreviewElement=this.$el.get(0).querySelector('[data-control="preview-sidebar"]')
var items=resetSidebar===undefined?this.$el.get(0).querySelectorAll('[data-type="media-item"].selected'):[],previewPanel=this.sidebarPreviewElement
if(items.length==0){this.sidebarPreviewElement.querySelector('[data-control="sidebar-labels"]').setAttribute('class','hide')}else if(items.length==1&&!items[0].hasAttribute('data-root')){this.sidebarPreviewElement.querySelector('[data-control="sidebar-labels"]').setAttribute('class','panel')
var item=items[0],lastModified=item.getAttribute('data-last-modified')
previewPanel.querySelector('[data-label="size"]').textContent=item.getAttribute('data-size')
previewPanel.querySelector('[data-label="title"]').textContent=item.getAttribute('data-title')
previewPanel.querySelector('[data-label="last-modified"]').textContent=lastModified
previewPanel.querySelector('[data-label="public-url"]').setAttribute('href',item.getAttribute('data-public-url'))
if(lastModified)previewPanel.querySelector('[data-control="last-modified"]').setAttribute('class','')
else previewPanel.querySelector('[data-control="last-modified"]').setAttribute('class','hide')
if(this.isSearchMode()){previewPanel.querySelector('[data-control="item-folder"]').setAttribute('class','')
var folderNode=previewPanel.querySelector('[data-label="folder"]')
folderNode.textContent=item.getAttribute('data-folder')
folderNode.setAttribute('data-path',item.getAttribute('data-folder'))}else{previewPanel.querySelector('[data-control="item-folder"]').setAttribute('class','hide')}}else{this.sidebarPreviewElement.querySelector('[data-control="sidebar-labels"]').setAttribute('class','hide')}this.updateSidebarMediaPreview(items)}
MediaManager.prototype.loadSidebarDocumentIcon=function(item){var sidebarDocument=this.sidebarPreviewElement.querySelector('[data-control="sidebar-document"]'),svg=item.querySelector('svg')
sidebarDocument.innerHTML=svg.outerHTML}
MediaManager.prototype.loadSidebarThumbnail=function(){if(this.sidebarThumbnailAjax){try{this.sidebarThumbnailAjax.abort()}catch(e){}this.sidebarThumbnailAjax=null}var sidebarThumbnail=this.sidebarPreviewElement.querySelector('[data-control="sidebar-thumbnail"]')
if(!sidebarThumbnail)return
var data={path:sidebarThumbnail.getAttribute('data-path'),lastModified:sidebarThumbnail.getAttribute('data-last-modified')}
this.sidebarThumbnailAjax=this.$form.request(this.options.alias+'::onGetSidebarThumbnail',{data:data}).done(this.proxy(this.replaceSidebarPlaceholder)).always(this.proxy(this.releaseSidebarThumbnailAjax))}
MediaManager.prototype.replaceSidebarPlaceholder=function(response){if(!this.sidebarPreviewElement)return
var sidebarThumbnail=this.sidebarPreviewElement.querySelector('[data-control="sidebar-thumbnail"]')
if(!sidebarThumbnail)return
if(!response.markup)return
sidebarThumbnail.innerHTML=response.markup
sidebarThumbnail.removeAttribute('data-loading')}
MediaManager.prototype.releaseSidebarThumbnailAjax=function(){this.sidebarThumbnailAjax=null}
MediaManager.prototype.generateThumbnails=function(){this.thumbnailQueue=[]
var placeholders=this.itemListElement.querySelectorAll('[data-type="media-item"] div.image-placeholder')
for(var i=(placeholders.length-1);i>=0;i--)this.thumbnailQueue.push({id:placeholders[i].getAttribute('id'),width:placeholders[i].getAttribute('data-width'),height:placeholders[i].getAttribute('data-height'),path:placeholders[i].getAttribute('data-path'),lastModified:placeholders[i].getAttribute('data-last-modified')})
this.handleThumbnailQueue()}
MediaManager.prototype.handleThumbnailQueue=function(){var maxThumbnailQueueLength=2,maxThumbnailBatchLength=3
if(this.activeThumbnailQueueLength>=maxThumbnailQueueLength)return
for(var i=this.activeThumbnailQueueLength;i<maxThumbnailQueueLength&&this.thumbnailQueue.length>0;i++){var batch=[]
for(var j=0;j<maxThumbnailBatchLength&&this.thumbnailQueue.length>0;j++)batch.push(this.thumbnailQueue.pop())
this.activeThumbnailQueueLength++
this.handleThumbnailBatch(batch).always(this.proxy(this.placeholdersUpdated))}}
MediaManager.prototype.handleThumbnailBatch=function(batch){var data={batch:batch}
for(var i=0,len=batch.length;i<len;i++){var placeholder=document.getElementById(batch[i].id)
if(placeholder)placeholder.setAttribute('data-loading','true')}var promise=this.$form.request(this.options.alias+'::onGenerateThumbnails',{data:data})
promise.done(this.proxy(this.replacePlaceholder))
return promise}
MediaManager.prototype.replacePlaceholder=function(response){if(!response.generatedThumbnails)return
for(var i=0,len=response.generatedThumbnails.length;i<len;i++){var thumbnailInfo=response.generatedThumbnails[i]
if(!thumbnailInfo.id||!thumbnailInfo.markup)continue
var node=document.getElementById(thumbnailInfo.id)
if(!node)continue
var placeholderContainer=node.parentNode
if(placeholderContainer)placeholderContainer.innerHTML=thumbnailInfo.markup}}
MediaManager.prototype.placeholdersUpdated=function(){this.activeThumbnailQueueLength--
this.handleThumbnailQueue()}
MediaManager.prototype.getRelativePosition=function(element,pageX,pageY,startPosition){var absolutePosition=startPosition!==undefined?startPosition:$.wn.foundation.element.absolutePosition(element,true)
return{x:(pageX-absolutePosition.left),y:(pageY-absolutePosition.top+this.scrollContentElement.scrollTop)}}
MediaManager.prototype.createSelectionMarker=function(){if(this.selectionMarker)return
this.selectionMarker=document.createElement('div')
this.selectionMarker.setAttribute('data-control','selection-marker')
this.scrollContentElement.insertBefore(this.selectionMarker,this.scrollContentElement.firstChild)}
MediaManager.prototype.doObjectsCollide=function(aTop,aLeft,aWidth,aHeight,bTop,bLeft,bWidth,bHeight){return!(((aTop+aHeight)<(bTop))||(aTop>(bTop+bHeight))||((aLeft+aWidth)<bLeft)||(aLeft>(bLeft+bWidth)))}
MediaManager.prototype.initUploader=function(){if(!this.itemListElement||this.options.readOnly)return
var uploaderOptions={clickable:this.$el.find('[data-control="upload"]').get(0),url:this.options.url,paramName:'file_data',timeout:0,headers:{},createImageThumbnails:false}
var token=$('meta[name="csrf-token"]').attr('content')
if(token){uploaderOptions.headers['X-CSRF-TOKEN']=token}this.dropzone=new Dropzone(this.$el.get(0),uploaderOptions)
this.dropzone.on('addedfile',this.proxy(this.uploadFileAdded))
this.dropzone.on('totaluploadprogress',this.proxy(this.uploadUpdateTotalProgress))
this.dropzone.on('queuecomplete',this.proxy(this.uploadQueueComplete))
this.dropzone.on('sending',this.proxy(this.uploadSending))
this.dropzone.on('error',this.proxy(this.uploadError))
this.dropzone.on('success',this.proxy(this.uploadSuccess))
Snowboard.globalEvent("widgets.mediamanager.initUploader",this);}
MediaManager.prototype.destroyUploader=function(){if(!this.dropzone)return
this.dropzone.destroy()
this.dropzone=null}
MediaManager.prototype.uploadFileAdded=function(){this.showUploadUi()
this.setUploadProgress(0)
this.$el.find('[data-command="cancel-uploading"]').removeClass('hide')
this.$el.find('[data-command="close-uploader"]').addClass('hide')}
MediaManager.prototype.showUploadUi=function(){this.$el.find('[data-control="upload-ui"]').removeClass('hide')}
MediaManager.prototype.hideUploadUi=function(){this.$el.find('[data-control="upload-ui"]').addClass('hide')}
MediaManager.prototype.uploadUpdateTotalProgress=function(uploadProgress,totalBytes,totalBytesSent){this.setUploadProgress(uploadProgress)
var fileNumberLabel=this.$el.get(0).querySelector('[data-label="file-number-and-progress"]'),messageTemplate=fileNumberLabel.getAttribute('data-message-template'),fileNumber=this.dropzone.getUploadingFiles().length+this.dropzone.getQueuedFiles().length
if(uploadProgress>=100){uploadProgress=99}fileNumberLabel.innerHTML=messageTemplate.replace(':number',fileNumber).replace(':percents',Math.round(uploadProgress)+'%')}
MediaManager.prototype.setUploadProgress=function(value){var progressBar=this.$el.get(0).querySelector('[data-control="upload-progress-bar"]')
progressBar.setAttribute('style','width: '+value+'%')
progressBar.setAttribute('class','progress-bar')}
MediaManager.prototype.uploadQueueComplete=function(){this.$el.find('[data-command="cancel-uploading"]').addClass('hide')
this.$el.find('[data-command="close-uploader"]').removeClass('hide')
this.refresh()}
MediaManager.prototype.uploadSending=function(file,xhr,formData){formData.append('path',this.$el.find('[data-type="current-folder"]').val())
xhr.setRequestHeader('X-WINTER-REQUEST-HANDLER',this.options.uploadHandler)}
MediaManager.prototype.uploadCancelAll=function(){this.dropzone.removeAllFiles(true)
this.hideUploadUi()}
MediaManager.prototype.updateUploadBar=function(templateName,classNames){var fileNumberLabel=this.$el.get(0).querySelector('[data-label="file-number-and-progress"]'),successTemplate=fileNumberLabel.getAttribute('data-'+templateName+'-template'),progressBar=this.$el.get(0).querySelector('[data-control="upload-progress-bar"]')
fileNumberLabel.innerHTML=successTemplate;progressBar.setAttribute('class',classNames)}
MediaManager.prototype.uploadSuccess=function(){this.updateUploadBar('success','progress-bar progress-bar-success');}
MediaManager.prototype.uploadError=function(file,message){this.updateUploadBar('error','progress-bar progress-bar-danger');if(file.xhr.status===413){message='Server rejected the file because it was too large, try increasing post_max_size';}if(!message){message='Error uploading file'}$.wn.alert(message)}
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}var path=selectedItems[0].getAttribute('data-path')
new $.wn.mediaManager.imageCropPopup(path,{alias:this.options.alias,onDone:callback})}
MediaManager.prototype.onImageCropped=function(result){this.$el.trigger('popupcommand',['insert-cropped',result])}
MediaManager.prototype.clearSearchTrackInputTimer=function(){if(this.searchTrackInputTimer===null)return
clearTimeout(this.searchTrackInputTimer)
this.searchTrackInputTimer=null}
MediaManager.prototype.updateSearchResults=function(){var $searchField=this.$el.find('[data-control="search"]'),data={search:$searchField.val()}
this.execNavigationRequest('onSearch',data,$searchField)}
MediaManager.prototype.resetSearch=function(){this.$el.find('[data-control="search"]').val('')}
MediaManager.prototype.onSearchChanged=function(ev){var value=ev.currentTarget.value
if(this.lastSearchValue!==undefined&&this.lastSearchValue==value)return
this.lastSearchValue=value
this.clearSearchTrackInputTimer()
this.searchTrackInputTimer=window.setTimeout(this.proxy(this.updateSearchResults),300)}
MediaManager.prototype.deleteItems=function(){var items=this.$el.get(0).querySelectorAll('[data-type="media-item"].selected')
if(!items.length){$.wn.alert(this.options.deleteEmpty)
return}$.wn.confirm(this.options.deleteConfirm,this.proxy(this.deleteConfirmation))}
MediaManager.prototype.deleteConfirmation=function(confirmed){if(!confirmed)return
var items=this.$el.get(0).querySelectorAll('[data-type="media-item"].selected'),paths=[]
for(var i=0,len=items.length;i<len;i++){if(items[i].hasAttribute('data-root')){continue;}paths.push({'path':items[i].getAttribute('data-path'),'type':items[i].getAttribute('data-item-type')})}var data={paths:paths}
$.wn.stripeLoadIndicator.show()
this.$form.request(this.options.alias+'::onDeleteItem',{data:data}).always(function(){$.wn.stripeLoadIndicator.hide()}).done(this.proxy(this.afterNavigate))}
MediaManager.prototype.createFolder=function(ev){$(ev.target).popup({content:this.$el.find('[data-control="new-folder-template"]').html(),zIndex:1200})}
MediaManager.prototype.onFolderPopupShown=function(ev,button,popup){$(popup).find('input[name=name]').focus()
$(popup).on('submit.media','form',this.proxy(this.onNewFolderSubmit))}
MediaManager.prototype.onFolderPopupHidden=function(ev,button,popup){$(popup).off('.media','form')}
MediaManager.prototype.onNewFolderSubmit=function(ev){var data={name:$(ev.target).find('input[name=name]').val(),path:this.$el.find('[data-type="current-folder"]').val()}
$.wn.stripeLoadIndicator.show()
this.$form.request(this.options.alias+'::onCreateFolder',{data:data}).always(function(){$.wn.stripeLoadIndicator.hide()}).done(this.proxy(this.folderCreated))
ev.preventDefault()
return false}
MediaManager.prototype.folderCreated=function(){this.$el.find('button[data-command="create-folder"]').popup('hide')
this.afterNavigate()}
MediaManager.prototype.moveItems=function(ev){var items=this.$el.get(0).querySelectorAll('[data-type="media-item"].selected')
if(!items.length){$.wn.alert(this.options.moveEmpty)
return}var data={exclude:[],path:this.$el.find('[data-type="current-folder"]').val()}
for(var i=0,len=items.length;i<len;i++){var item=items[i],path=item.getAttribute('data-path')
if(item.getAttribute('data-item-type')=='folder')data.exclude.push(path)}$(ev.target).popup({handler:this.options.alias+'::onLoadMovePopup',extraData:data,zIndex:1200})}
MediaManager.prototype.onMovePopupShown=function(ev,button,popup){$(popup).on('submit.media','form',this.proxy(this.onMoveItemsSubmit))}
MediaManager.prototype.onMoveItemsSubmit=function(ev){var items=this.$el.get(0).querySelectorAll('[data-type="media-item"].selected'),data={dest:$(ev.target).find('select[name=dest]').val(),originalPath:$(ev.target).find('input[name=originalPath]').val(),files:[],folders:[]}
for(var i=0,len=items.length;i<len;i++){var item=items[i],path=item.getAttribute('data-path')
if(item.getAttribute('data-item-type')=='folder')data.folders.push(path)
else data.files.push(path)}$.wn.stripeLoadIndicator.show()
this.$form.request(this.options.alias+'::onMoveItems',{data:data}).always(function(){$.wn.stripeLoadIndicator.hide()}).done(this.proxy(this.itemsMoved))
ev.preventDefault()
return false}
MediaManager.prototype.onMovePopupHidden=function(ev,button,popup){$(popup).off('.media','form')}
MediaManager.prototype.itemsMoved=function(){this.$el.find('button[data-command="move"]').popup('hide')
this.afterNavigate()}
MediaManager.prototype.onNavigate=function(ev){var $item=$(ev.target).closest('[data-type="media-item"]')
this.navigateToItem($item)
if($(ev.target).data('label')!='public-url')return false}
MediaManager.prototype.onCommandClick=function(ev){var command=$(ev.currentTarget).data('command')
switch(command){case'refresh':this.refresh()
break;case'change-view':this.changeView($(ev.currentTarget).data('view'))
break;case'cancel-uploading':this.uploadCancelAll()
break;case'close-uploader':this.hideUploadUi()
break;case'set-filter':this.setFilter($(ev.currentTarget).data('filter'))
break;case'delete':this.deleteItems()
break;case'create-folder':this.createFolder(ev)
break;case'move':this.moveItems(ev)
break;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}
MediaManager.prototype.onItemClick=function(ev){if(ev.target.tagName=='I'&&ev.target.hasAttribute('data-rename-control'))return
this.selectItem(ev.currentTarget,ev.shiftKey)}
MediaManager.prototype.onItemTouch=function(ev){ev.preventDefault()
ev.stopPropagation()
if(this.dblTouchFlag){this.onNavigate(ev)
this.dblTouchFlag=null}else{this.onItemClick(ev)
this.dblTouchFlag=true}this.clearDblTouchTimer()
this.dblTouchTimer=setTimeout(this.proxy(this.clearDblTouchFlag),300)}
MediaManager.prototype.onListMouseDown=function(ev){this.itemListElement.addEventListener('mousemove',this.proxy(this.onListMouseMove))
document.addEventListener('mouseup',this.proxy(this.onListMouseUp))
this.itemListPosition=$.wn.foundation.element.absolutePosition(this.itemListElement,true)
var pagePosition=$.wn.foundation.event.pageCoordinates(ev),relativePosition=this.getRelativePosition(this.itemListElement,pagePosition.x,pagePosition.y,this.itemListPosition)
this.selectionStartPoint=relativePosition
this.selectionStarted=false}
MediaManager.prototype.onListMouseUp=function(ev){this.itemListElement.removeEventListener('mousemove',this.proxy(this.onListMouseMove))
document.removeEventListener('mouseup',this.proxy(this.onListMouseUp))
$(document.body).removeClass('no-select')
if(this.selectionStarted){this.unselectRoot()
var items=this.itemListElement.querySelectorAll('[data-type="media-item"]:not([data-root])'),selectionPosition=$.wn.foundation.element.absolutePosition(this.selectionMarker,true)
for(var index=0,len=items.length;index<len;index++){var item=items[index],itemPosition=$.wn.foundation.element.absolutePosition(item,true)
if(this.doObjectsCollide(selectionPosition.top,selectionPosition.left,this.selectionMarker.offsetWidth,this.selectionMarker.offsetHeight,itemPosition.top,itemPosition.left,item.offsetWidth,item.offsetHeight)){if(!ev.shiftKey)item.setAttribute('class','selected')
else{if(item.getAttribute('class')=='selected')item.setAttribute('class','')
else item.setAttribute('class','selected')}}else if(!ev.shiftKey)item.setAttribute('class','')}this.updateSidebarPreview()
this.selectionMarker.setAttribute('class','hide')}this.selectionStarted=false}
MediaManager.prototype.onListMouseMove=function(ev){var pagePosition=$.wn.foundation.event.pageCoordinates(ev),relativePosition=this.getRelativePosition(this.itemListElement,pagePosition.x,pagePosition.y,this.itemListPosition)
var deltaX=relativePosition.x-this.selectionStartPoint.x,deltaY=relativePosition.y-this.selectionStartPoint.y
if(!this.selectionStarted&&(Math.abs(deltaX)>2||Math.abs(deltaY)>2)){this.createSelectionMarker()
this.selectionMarker.setAttribute('class','')
this.selectionStarted=true
$(document.body).addClass('no-select')}if(this.selectionStarted){if(deltaX>=0){this.selectionMarker.style.left=this.selectionStartPoint.x+'px'
this.selectionMarker.style.width=deltaX+'px'}else{this.selectionMarker.style.left=relativePosition.x+'px'
this.selectionMarker.style.width=Math.abs(deltaX)+'px'}if(deltaY>=0){this.selectionMarker.style.height=deltaY+'px'
this.selectionMarker.style.top=this.selectionStartPoint.y+'px'}else{this.selectionMarker.style.top=relativePosition.y+'px'
this.selectionMarker.style.height=Math.abs(deltaY)+'px'}}}
MediaManager.prototype.onSortingChanged=function(ev){var $target=$(ev.target),data={path:this.$el.find('[data-type="current-folder"]').val()}
if($target.data('sort')=='by'){data.sortBy=$target.val();}else if($target.data('sort')=='direction'){data.sortDirection=$target.val()}this.execNavigationRequest('onSetSorting',data)}
MediaManager.prototype.onKeyDown=function(ev){var eventHandled=false
switch(ev.key){case'Enter':var items=this.getSelectedItems(true,true)
if(items.length>0)this.navigateToItem($(items[0]))
eventHandled=true
break;case'ArrowRight':case'ArrowDown':this.selectRelative(true,ev.shiftKey)
eventHandled=true
break;case'ArrowLeft':case'ArrowUp':this.selectRelative(false,ev.shiftKey)
eventHandled=true
break;}if(eventHandled){ev.preventDefault()
ev.stopPropagation()}}
MediaManager.DEFAULTS={url:window.location,uploadHandler:null,alias:'',deleteEmpty:'Please select files to delete.',deleteConfirm:'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}
var old=$.fn.mediaManager
$.fn.mediaManager=function(option){var args=Array.prototype.slice.call(arguments,1),result=undefined
this.each(function(){var $this=$(this)
var data=$this.data('oc.mediaManager')
var options=$.extend({},MediaManager.DEFAULTS,$this.data(),typeof option=='object'&&option)
if(!data)$this.data('oc.mediaManager',(data=new MediaManager(this,options)))
if(typeof option=='string')result=data[option].apply(data,args)
if(typeof result!='undefined')return false})
return result?result:this}
$.fn.mediaManager.Constructor=MediaManager
$.fn.mediaManager.noConflict=function(){$.fn.mediaManager=old
return this}
$(document).on('render',function(){$('div[data-control=media-manager]').mediaManager()})}(window.jQuery);+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=$('<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',zIndex:1200})}
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){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=$('<img>').attr('src',url)
$img.one('load',this.proxy(this.initJCrop))
$imageArea.append($img)
this.imageArea.scrollTop=0
this.imageArea.scrollLeft=0
this.onImageScroll()}
MediaManagerImageCropPopup.prototype.undoResizing=function(){this.updateImage(this.$popupElement.find('input[data-control=original-url]').val(),this.$popupElement.find('input[data-control=original-width]').val(),this.$popupElement.find('input[data-control=original-height]').val())}
MediaManagerImageCropPopup.prototype.updateSelectionSizeLabel=function(width,height){if(width==0&&height==0){this.selectionSizeLabel.setAttribute('class','hide')
return}this.selectionSizeLabel.setAttribute('class','')
this.selectionSizeLabel.querySelector('[data-label=selection-width]').textContent=parseInt(width)
this.selectionSizeLabel.querySelector('[data-label=selection-height]').textContent=parseInt(height)}
MediaManagerImageCropPopup.prototype.onPopupHidden=function(event,element,popup){$(document).trigger('mousedown')
this.dispose()}
MediaManagerImageCropPopup.prototype.onPopupShown=function(event,element,popup){this.$popupElement=popup
this.$popupElement.on('change','[data-control="selection-mode"]',this.proxy(this.onSelectionModeChanged))
this.$popupElement.on('click','[data-command]',this.proxy(this.onCommandClick))
this.$popupElement.on('shown.oc.popup','button[data-command=resize]',this.proxy(this.onResizePopupShown))
this.$popupElement.on('hidden.oc.popup','button[data-command=resize]',this.proxy(this.onResizePopupHidden))
this.imageArea=popup.find('[data-control=media-manager-crop-tool]').get(0).querySelector('.image_area')
this.selectionSizeLabel=popup.find('[data-label="selection-size"]').get(0)
this.getWidthInput().on('change',this.proxy(this.onSizeInputChange))
this.getHeightInput().on('change',this.proxy(this.onSizeInputChange))
this.initRulers()
this.initJCrop()
this.applySelectionMode()}
MediaManagerImageCropPopup.prototype.onSelectionModeChanged=function(){var mode=this.getSelectionMode(),$widthInput=this.getWidthInput(),$heightInput=this.getHeightInput()
if(mode==='normal'){$widthInput.attr('disabled','disabled')
$heightInput.attr('disabled','disabled')}else{$widthInput.removeAttr('disabled')
$heightInput.removeAttr('disabled')
$widthInput.val(this.fixDimensionValue($widthInput.val()))
$heightInput.val(this.fixDimensionValue($heightInput.val()))}this.applySelectionMode()}
MediaManagerImageCropPopup.prototype.onImageScroll=function(){var scrollTop=this.imageArea.scrollTop,scrollLeft=this.imageArea.scrollLeft
if(this.prevScrollTop!=scrollTop){this.prevScrollTop=scrollTop
this.vRulerHolder.scrollTop=scrollTop}if(this.prevScrollLeft!=scrollLeft){this.prevScrollLeft=scrollLeft
this.hRulerHolder.scrollLeft=scrollLeft}}
MediaManagerImageCropPopup.prototype.onSizeInputChange=function(ev){var $target=$(ev.target)
$target.val(this.fixDimensionValue($target.val()))
this.applySelectionMode()}
MediaManagerImageCropPopup.prototype.onCommandClick=function(ev){var command=$(ev.currentTarget).data('command')
switch(command){case'insert':this.cropAndInsert()
break
case'resize':this.showResizePopup()
break
case'undo-resizing':this.undoResizing()
break}}
MediaManagerImageCropPopup.prototype.onSelectionChanged=function(c){this.updateSelectionSizeLabel(c.w,c.h)}
MediaManagerImageCropPopup.DEFAULTS={alias:undefined,onDone:undefined}
$.wn.mediaManager.imageCropPopup=MediaManagerImageCropPopup}(window.jQuery);

View File

@@ -0,0 +1,12 @@
/*
* This is a bundle file, you can compile this by running
*
* php artisan winter:util compile assets
*
* @see build-min.js
*
=require mediamanager.js
=require mediamanager.imagecroppopup.js
*/

View File

@@ -0,0 +1,6 @@
/*
These scripts will be included globally as part of the backend.
=require mediamanager.popup.js
*/

View File

@@ -0,0 +1,478 @@
/*
* 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 = $('<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',
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 = $('<img>').attr('src', url)
$img.one('load', this.proxy(this.initJCrop))
$imageArea.append($img)
this.imageArea.scrollTop = 0
this.imageArea.scrollLeft = 0
this.onImageScroll()
}
MediaManagerImageCropPopup.prototype.undoResizing = function() {
this.updateImage(
this.$popupElement.find('input[data-control=original-url]').val(),
this.$popupElement.find('input[data-control=original-width]').val(),
this.$popupElement.find('input[data-control=original-height]').val()
)
}
MediaManagerImageCropPopup.prototype.updateSelectionSizeLabel = function(width, height) {
if (width == 0 && height == 0) {
this.selectionSizeLabel.setAttribute('class', 'hide')
return
}
this.selectionSizeLabel.setAttribute('class', '')
this.selectionSizeLabel.querySelector('[data-label=selection-width]').textContent = parseInt(width)
this.selectionSizeLabel.querySelector('[data-label=selection-height]').textContent = parseInt(height)
}
// 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
this.$popupElement.on('change', '[data-control="selection-mode"]', this.proxy(this.onSelectionModeChanged))
this.$popupElement.on('click', '[data-command]', this.proxy(this.onCommandClick))
this.$popupElement.on('shown.oc.popup', 'button[data-command=resize]', this.proxy(this.onResizePopupShown))
this.$popupElement.on('hidden.oc.popup', 'button[data-command=resize]', this.proxy(this.onResizePopupHidden))
this.imageArea = popup.find('[data-control=media-manager-crop-tool]').get(0).querySelector('.image_area')
this.selectionSizeLabel = popup.find('[data-label="selection-size"]').get(0)
this.getWidthInput().on('change', this.proxy(this.onSizeInputChange))
this.getHeightInput().on('change', this.proxy(this.onSizeInputChange))
this.initRulers()
this.initJCrop()
this.applySelectionMode()
}
MediaManagerImageCropPopup.prototype.onSelectionModeChanged = function() {
var mode = this.getSelectionMode(),
$widthInput = this.getWidthInput(),
$heightInput = this.getHeightInput()
if (mode === 'normal') {
$widthInput.attr('disabled', 'disabled')
$heightInput.attr('disabled', 'disabled')
}
else {
$widthInput.removeAttr('disabled')
$heightInput.removeAttr('disabled')
$widthInput.val(this.fixDimensionValue($widthInput.val()))
$heightInput.val(this.fixDimensionValue($heightInput.val()))
}
this.applySelectionMode()
}
MediaManagerImageCropPopup.prototype.onImageScroll = function() {
var scrollTop = this.imageArea.scrollTop,
scrollLeft = this.imageArea.scrollLeft
if (this.prevScrollTop != scrollTop) {
this.prevScrollTop = scrollTop
this.vRulerHolder.scrollTop = scrollTop
}
if (this.prevScrollLeft != scrollLeft) {
this.prevScrollLeft = scrollLeft
this.hRulerHolder.scrollLeft = scrollLeft
}
}
MediaManagerImageCropPopup.prototype.onSizeInputChange = function(ev) {
var $target = $(ev.target)
$target.val(this.fixDimensionValue($target.val()))
this.applySelectionMode()
}
MediaManagerImageCropPopup.prototype.onCommandClick = function(ev) {
var command = $(ev.currentTarget).data('command')
switch (command) {
case 'insert':
this.cropAndInsert()
break
case 'resize':
this.showResizePopup()
break
case 'undo-resizing':
this.undoResizing()
break
}
}
MediaManagerImageCropPopup.prototype.onSelectionChanged = function(c) {
this.updateSelectionSizeLabel(c.w, c.h)
}
MediaManagerImageCropPopup.DEFAULTS = {
alias: undefined,
onDone: undefined
}
$.wn.mediaManager.imageCropPopup = MediaManagerImageCropPopup
}(window.jQuery);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,141 @@
/*
* Media manager popup
*/
+function ($) { "use strict";
if ($.wn.mediaManager === undefined)
$.wn.mediaManager = {}
var Base = $.wn.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.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.')
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,
mode: this.options.mode || 'all',
}
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)
}
MediaManagerPopup.prototype.insertCroppedImage = function(imageItem) {
if (this.options.onInsert !== undefined)
this.options.onInsert.call(this, [imageItem])
}
// 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().mediaManager('selectFirstItem')
}
MediaManagerPopup.prototype.onPopupCommand = function(ev, command, param) {
switch (command) {
case 'insert' :
this.insertMedia()
break;
case 'insert-cropped' :
this.insertCroppedImage(param)
break;
}
return false
}
MediaManagerPopup.DEFAULTS = {
alias: undefined,
bottomToolbar: true,
cropAndInsertButton: false,
onInsert: undefined,
onClose: undefined
}
$.wn.mediaManager.popup = MediaManagerPopup
}(window.jQuery);

View File

@@ -0,0 +1,803 @@
@import "../../../../../backend/assets/less/core/boot.less";
@color-media-list-hover-bg: mix(white, @brand-secondary, 13%);
.media-selected-tiles() {
.icon-container {
background: @color-media-list-hover-bg !important;
border-color: #2581b8;
i, p {
color: #ecf0f1;
}
}
h4 {
color: #2581b8;
}
}
.media-selected-list() {
background: @color-media-list-hover-bg !important;
i, p.size {
color: #ecf0f1;
}
h4 {
color: white;
}
.icon-container {
border-right-color: @color-media-list-hover-bg !important;
}
}
div[data-control="media-manager"] {
&:focus {
outline: none;
}
.loading-indicator-pseudo-absolute(@size) {
background-image: url('../../../../../../modules/system/assets/ui/images/loader-transparent.svg');
background-position: 50% 50%;
content: ' ';
.animation(spin 1s linear infinite);
background-size: @size @size;
position: absolute;
width: @size;
height: @size;
top: 50%;
left: 50%;
margin-top: -(@size / 2);
margin-left: -(@size / 2);
}
audio, video {
width: 100%;
}
video {
background: #ecf0f1;
max-height: 225px;
}
.file-icon {
fill-rule: evenodd;
clip-rule: evenodd;
stroke-linejoin: round;
stroke-miterlimit: 2;
display: inline-block;
&-extension {
font-family: 'ArialMT','Arial',sans-serif;
font-size: 4em;
font-weight: 900;
fill: #fff;
}
&-label {
fill: #576D7E; /* Default color */
fill-rule: nonzero;
}
&-css,
&-less,
&-scss {
fill: #B73FD9;
}
&-html,
&-xml {
fill: #EA9B47;
}
&-js,
&-json {
fill: #A9A9A9;
}
&-pdf {
fill: #E30713;
}
&-txt {
fill: #248BD0;
}
&-ai {
fill: #F29200;
}
&-eps {
fill: #F9B234;
}
&-psd {
fill: #2DAAE2;
}
&-ttf,
&-otf,
&-woff,
&-woff2 {
fill: #C4CA10;
}
&-doc,
&-docx,
&-rtf,
&-odt {
fill: #0F70B7;
}
&-csv,
&-ods,
&-xls,
&-xlsx {
fill: #3BAA34;
}
&-odp,
&-ppt,
&-pptx {
fill: #D04526;
}
&-rar,
&-tar,
&-zip {
fill: #363A56;
}
}
.media-player-fallback {
font-size: 13px;
color: #95a5a6;
background: #ecf0f1;
line-height: 180%;
&.panel-embedded {
padding: 20px;
margin: -20px -20px 0 -20px;
}
}
.icon-message() {
font-size: 12px;
margin: 10px;
line-height: 160%;
color: #bdc3c7;
}
.empty-library {
padding: 20px;
text-align: center;
}
p.thumbnail-error-message {
.icon-message();
}
.media-list {
padding: 0 0 0 20px;
margin: 0;
.user-select(none);
li {
display: inline-block;
vertical-align: top;
margin: 0 20px 20px 0;
overflow: hidden;
cursor: pointer;
.border-radius(3px);
&:focus {
outline: none;
}
.icon-container {
display: table;
i {
color: #95a5a6;
display: inline-block;
}
div {
display: table-cell;
text-align: center;
vertical-align: middle;
}
}
.icon-container.image {
> div.icon-wrapper {
display: none;
}
}
h4 {
font-weight: 600;
font-size: 13px;
color: #2b3e50;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
line-height: 150%;
margin: 15px 0 5px 0;
padding-right: 0;
.transition(padding 0.1s);
position: relative;
a {
position: absolute;
right: 0;
top: 0;
font-size: 15px;
color: #2b3e50;
display: none;
&:hover {
color: @link-color;
text-decoration: none;
}
}
}
p.size {
font-size: 12px;
color: #95a5a6;
}
.image-placeholder {
position: relative;
i {
padding-top: 0;
padding-left: 2px;
}
&[data-loading] {
i {
display: none;
}
}
&[data-loading]:after {
.loading-indicator-pseudo-absolute(28px);
}
}
i.icon-chain-broken {
padding: 0;
color: #bdc3c7;
}
&[data-item-type=folder] i {
color: @color-media-list-hover-bg;
}
}
&.list {
li {
height: 75px;
width: 260px;
border: 1px solid #ecf0f1;
background: #f6f8f9;
box-sizing: content-box;
}
li .icon-container {
border-right: 1px solid #f6f8f9;
width: 75px;
height: 75px;
float: left;
img {
max-height: 75px;
}
i {
font-size: 35px;
}
svg {
max-height: 44px;
}
&.image {
border-right: 1px solid #ecf0f1!important;
}
p.thumbnail-error-message {
display: none;
}
}
.icon-wrapper {
width: 75px;
}
li .info {
margin-left: 90px;
}
li .image-placeholder {
width: 75px;
height: 75px;
}
li[data-root] h4 {
margin-top: 27px;
}
li.selected {
.media-selected-list();
}
h4 {
padding-right: 15px;
a {
right: 15px;
}
}
}
&.tiles {
li {
width: 167px;
margin-bottom: 25px;
}
.icon-wrapper {
width: 167px;
}
li .image-placeholder {
width: 165px;
height: 165px;
&[data-loading]:after {
.loading-indicator-pseudo-absolute(55px);
}
}
li .icon-container {
width: 165px;
height: 165px;
.border-radius(3px);
border: 1px solid #ecf0f1;
overflow: hidden;
background: #f6f8f9;
box-sizing: content-box;
img {
max-height: 165px;
}
i {
font-size: 55px;
}
svg {
max-height: 65px;
}
p {
font-family: @font-family-base;
}
}
li.selected {
.media-selected-tiles();
}
i.icon-chain-broken {
margin-top: 47px;
}
p.size {
margin-bottom: 0;
}
}
}
[data-control="sidebar-labels"] {
word-wrap: break-word;
}
.sidebar-group {
margin-bottom: 20px;
}
.sidebar-image-placeholder-container,
.sidebar-document-placeholder-container {
display: table;
width: 100%;
}
.sidebar-image-placeholder,
.sidebar-document-placeholder {
display: table-cell;
position: relative;
vertical-align: middle;
text-align: center;
border-bottom: 1px solid #ecf0f1;
box-sizing: content-box;
}
.sidebar-image-placeholder {
height: 225px;
&[data-loading] {
background: #ecf0f1;
&:after {
.loading-indicator-pseudo-absolute(62px);
}
}
i.icon-chain-broken, i.icon-crop, i.icon-asterisk, i.icon-level-up {
color: #bdc3c7;
font-size: 55px;
}
&.no-border {
border-bottom: none;
}
p {
.icon-message();
margin-top: 25px;
}
img {
max-width: 100%;
max-height: 225px;
}
}
.sidebar-document-placeholder {
height: 155px;
svg {
width: 100px;
height: 100px;
}
}
.list-container {
position: relative;
z-index: 100;
.no-data {
font-size: 13px;
}
p.no-data {
padding: 0 20px 20px 20px;
}
li.no-data {
padding-top: 20px;
display: block !important;
width: 100% !important;
border: none !important;
background: transparent !important;
cursor: default !important;
}
table.table.data {
tbody tr:not(.no-data):active td {
background: @color-list-hover-bg !important;
}
}
}
[data-control="item-list"] {
position: relative;
display: table-cell;
}
.control-scrollpad {
position: absolute;
left: 0;
top: 0;
// Prevents erratic rendering issues when the height is
// sometimes calculated as 0 then repeatedly redrawn
min-height: 300px;
}
.scroll-wrapper {
position: relative;
}
table.table {
table-layout: fixed;
margin-bottom: 0;
white-space: nowrap;
div.no-wrap-text {
overflow: hidden;
text-overflow: ellipsis;
}
div.item-title {
position: relative;
padding-right: 0;
.transition(padding 0.1s);
a {
position: absolute;
right: 0;
top: 0;
display: none;
}
}
tr:hover div.item-title {
padding-right: 25px;
a {
display: block;
}
}
tr[data-item-type=folder] i.icon-folder {
color: @color-media-list-hover-bg;
}
tr:focus {
outline: none;
}
}
div[data-control="selection-marker"] {
position: absolute;
z-index: 250;
border: 1px dashed #95a5a6;
background: rgba(0,0,0,0.1);
}
.upload-progress {
background: @body-bg;
padding: 0 20px;
h5 {
margin: 0 0 10px 0;
font-size: 13px;
color: #2b3e50;
font-weight: 600;
span {
display: inline-block;
margin-left: 10px;
color: #95a5a6;
font-size: 15px;
}
}
.progress-controls {
padding-right: 30px;
position: relative;
.controls {
position: absolute;
right: 0;
bottom: 0;
a {
display: block;
position: relative;
top: 7px;
right: 3px;
color: #95a5a6;
font-size: 16px;
cursor: pointer!important;
&:hover {
text-decoration: none;
color: @link-color;
}
}
}
}
}
.dz-preview {
display: none;
}
button[data-command="toggle-sidebar"] {
&.sidebar-hidden {
.transform( ~'rotate(180deg) translate(0, 0)' );
}
}
}
[data-control="media-manager-crop-tool"] {
.image_area {
position: absolute;
width: 100%;
height: 100%;
overflow: auto;
.jcrop-holder {
background-color: transparent!important;
}
}
img {
cursor: crosshair;
display: block;
}
&.has-rulers {
.ruler-container {
.layout-relative {
overflow: hidden;
}
&.horizontal {
.layout-cell {
height: 20px;
}
.layout-relative {
width: 100%;
}
}
&.vertical {
width: 20px;
.layout-relative {
height: 100%;
}
}
}
.ruler {
position: absolute;
height: 20px;
margin-left: -3px;
background: #555;
ul {
margin: 0;
padding: 0;
white-space: nowrap;
font-size: 0;
}
li {
margin: 0;
padding: 0 0 0 40px;
list-style: none;
display: inline-block;
width: 24px;
margin: 0px -10px 0px -14px;
.box-sizing(content-box);
text-align: left;
position: relative;
font-size: 10px;
line-height: 20px;
color: #ecf0f1;
font-family: Arial, sans-serif;
&:before, &:after {
content: ' ';
position: absolute;
border-left: 1px solid #8e8e8e;
}
&:before {
height: 20px;
top: 0;
left: -3px;
}
&:after {
height: 3px;
bottom: 0;
left: 20px;
}
&:first-child:after {
display: none;
}
}
}
.ruler[data-control=v-ruler] {
.transform(~'rotateZ(90deg)');
.transform-origin(~'left top');
left: 23px;
top: -23px;
& li:after {
top: 0;
left: auto;
}
}
}
}
body:not(.no-select) {
div[data-control="media-manager"] .media-list {
&.tiles {
li:hover {
.media-selected-tiles();
}
li:hover h4 {
padding-right: 20px !important;
}
}
&.list {
li:hover {
.media-selected-list();
}
li:hover h4 {
padding-right: 35px !important;
}
}
li {
&:hover h4 a {
display: block;
}
}
}
}
@media (max-width: 1280px) {
div[data-control="media-manager"] {
.media-list {
&.list {
li {
width: 230px;
}
}
}
}
}
@media (max-width: 1024px) {
div[data-control="media-manager"] {
.media-list {
&.list {
li {
display: block;
width: auto;
}
}
}
}
}
@media (max-width: @screen-sm) {
div[data-control="media-manager"] {
[data-control="preview-sidebar"],
[data-command="toggle-sidebar"] {
display: none!important;
}
.media-list {
&.list {
padding: 0;
li {
.border-radius(0);
margin: 0;
border-right: none;
border-left: none;
border-bottom: none;
}
}
}
}
}
@media (max-width: 480px) {
div[data-control="media-manager"] {
[data-control="left-sidebar"] {
display: none!important;
}
}
}

View File

@@ -0,0 +1,70 @@
<div
data-control="media-manager"
class="layout"
data-alias="<?= $this->alias ?>"
data-upload-handler="<?= $this->getEventHandler('onUpload') ?>"
data-delete-empty="<?= e(trans('backend::lang.media.delete_empty')) ?>"
data-delete-confirm="<?= e(trans('backend::lang.media.delete_confirm')) ?>"
data-move-empty="<?= e(trans('backend::lang.media.move_empty')) ?>"
data-select-single-image="<?= e(trans('backend::lang.media.select_single_image')) ?>"
data-selection-not-image="<?= e(trans('backend::lang.media.selection_not_image')) ?>"
data-bottom-toolbar="<?= $this->bottomToolbar ? 'true' : 'false' ?>"
data-crop-and-insert-button="<?= $this->cropAndInsertButton ? 'true' : 'false' ?>"
data-read-only="<?= $this->readOnly ? 'true' : 'false'; ?>"
tabindex="0"
>
<?= $this->makePartial('toolbar') ?>
<?= (!$this->readOnly) ? $this->makePartial('upload-progress') : '' ?>
<div class="layout-row whiteboard">
<div class="layout">
<div class="layout-row">
<div class="layout-cell panel w-200 border-right" data-control="left-sidebar">
<?= $this->makePartial('left-sidebar') ?>
</div>
<div class="layout-cell">
<div class="layout">
<div class="layout-row min-size">
<?= $this->makePartial('folder-toolbar') ?>
</div>
<div class="layout-row">
<!-- Main area -->
<div class="layout">
<div class="layout-row">
<div class="layout">
<!-- Main area - list -->
<div data-control="item-list">
<div class="control-scrollpad">
<div class="scroll-wrapper"> <!-- This element is required for the scrollpad control -->
<div id="<?= $this->getId('item-list') ?>" >
<?= $this->makePartial('item-list') ?>
</div>
</div>
</div>
</div>
<div class="layout-cell w-300 panel border-left no-padding <?= !$sidebarVisible ? 'hide' : null ?>" data-control="preview-sidebar">
<!-- Right sidebar -->
<?= $this->makePartial('right-sidebar') ?>
</div>
</div>
</div>
<div class="layout-row min-size hide" data-control="bottom-toolbar">
<?= $this->makePartial('bottom-toolbar') ?>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<?= $this->makePartial('new-folder-form') ?>
</div>

View File

@@ -0,0 +1,30 @@
<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('backend::lang.media.insert')) ?>
</button>
<?php if (!$this->readOnly): ?>
<button
type="button"
data-command="popup-command"
data-popup-command="crop-and-insert"
class="btn btn-primary hide">
<?= e(trans('backend::lang.media.crop_and_insert')) ?>
</button>
<?php endif; ?>
<button
type="button"
data-dismiss="popup"
class="btn btn-default no-margin-right">
<?= e(trans('backend::lang.form.cancel')) ?>
</button>
</div>
</div>
</div>

View File

@@ -0,0 +1,33 @@
<div class="layout"
data-control="media-manager-crop-tool"
<?php if ($dimensions): ?>
data-image-width="<?= $dimensions[0] ?>"
data-image-height="<?= $dimensions[1] ?>"
<?php endif ?>
>
<div class="layout-row min-size ruler-container horizontal hide">
<div class="layout-cell">
<div class="layout-relative">
<div class="ruler" data-control="h-ruler"></div>
</div>
</div>
</div>
<div class="layout-row">
<div class="layout">
<div class="layout-row">
<div class="layout-cell ruler-container vertical hide">
<div class="layout-relative">
<div class="ruler" data-control="v-ruler"></div>
</div>
</div>
<div class="layout-cell">
<div class="layout-relative">
<div class="image_area">
<img src="<?= $imageUrl ?>"/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,40 @@
<?php
$selectionModes = [
Backend\Widgets\MediaManager::SELECTION_MODE_NORMAL => trans('backend::lang.media.selection_mode_normal'),
Backend\Widgets\MediaManager::SELECTION_MODE_FIXED_RATIO => trans('backend::lang.media.selection_mode_fixed_ratio'),
Backend\Widgets\MediaManager::SELECTION_MODE_FIXED_SIZE => trans('backend::lang.media.selection_mode_fixed_size')
];
$sizeDisabledAttr = $currentSelectionMode == Backend\Widgets\MediaManager::SELECTION_MODE_NORMAL ? 'disabled="disabled"' : null;
?>
<div class="control-toolbar toolbar-padded">
<div class="toolbar-item toolbar-primary">
<div data-control="toolbar">
<label class="standalone"><?= e(trans('backend::lang.media.image_size')) ?> <span data-label="width"><?= $dimensions[0] ?></span> x <span data-label="height"><?= $dimensions[1] ?></span></label>
<div class="btn-group offset-right">
<button type="button" class="btn btn-primary standalone" data-command="resize"
><?= e(trans('backend::lang.media.resize')) ?></button>
<button type="button" class="btn btn-primary wn-icon-undo empty" data-command="undo-resizing"></button>
</div>
<label for="mmcropimagewidth"><?= e(trans('backend::lang.media.selection_mode')) ?></label>
<select name="selectionMode" class="form-control custom-select w-150" data-control="selection-mode">
<?php foreach ($selectionModes as $mode => $name): ?>
<option <?= $mode == $currentSelectionMode ? 'selected="selected"' : null ?> value="<?= $mode ?>"><?= e($name) ?></option>
<?php endforeach ?>
</select>
<label for="mmcropimagewidth"><?= e(trans('backend::lang.media.width')) ?></label>
<input id="mmcropimagewidth" type="text" class="form-control w-100" data-control="crop-width-input" name="selectionWidth" value="<?= e($currentSelectionWidth) ?>" <?= $sizeDisabledAttr ?>/>
<label for="mmcropimageheight"><?= e(trans('backend::lang.media.height')) ?></label>
<input id="mmcropimageheight" type="text" class="form-control w-100" data-control="crop-height-input" name="selectionHeight" value="<?= e($currentSelectionHeight) ?>" <?= $sizeDisabledAttr ?>/>
<label class="standalone hide" data-label="selection-size"><?= e(trans('backend::lang.media.selected_size')) ?> <span data-label="selection-width"></span> x <span data-label="selection-height"></span></label>
</div>
</div>
</div>

View File

@@ -0,0 +1,64 @@
<h3 class="section"><?= e(trans('backend::lang.media.display')) ?></h3>
<ul class="nav nav-stacked selector-group">
<li
role="presentation"
<?php if ($currentFilter == Backend\Widgets\MediaManager::FILTER_ALL): ?>
class="active"
<?php endif ?>
>
<a href="#" data-command="set-filter" data-filter="<?= Backend\Widgets\MediaManager::FILTER_ALL ?>">
<i class="icon-recycle"></i>
<?= e(trans('backend::lang.media.filter_all')) ?>
</a>
</li>
<li
role="presentation"
<?php if ($currentFilter == System\Classes\MediaLibraryItem::FILE_TYPE_IMAGE): ?>
class="active"
<?php endif ?>
>
<a href="#" data-command="set-filter" data-filter="<?= System\Classes\MediaLibraryItem::FILE_TYPE_IMAGE ?>">
<i class="icon-picture-o"></i>
<?= e(trans('backend::lang.media.filter_images')) ?>
</a>
</li>
<li
role="presentation"
<?php if ($currentFilter == System\Classes\MediaLibraryItem::FILE_TYPE_VIDEO): ?>
class="active"
<?php endif ?>
>
<a href="#" data-command="set-filter" data-filter="<?= System\Classes\MediaLibraryItem::FILE_TYPE_VIDEO ?>">
<i class="icon-video-camera"></i>
<?= e(trans('backend::lang.media.filter_video')) ?>
</a>
</li>
<li
role="presentation"
<?php if ($currentFilter == System\Classes\MediaLibraryItem::FILE_TYPE_AUDIO): ?>
class="active"
<?php endif ?>
>
<a href="#" data-command="set-filter" data-filter="<?= System\Classes\MediaLibraryItem::FILE_TYPE_AUDIO ?>">
<i class="icon-volume-up"></i>
<?= e(trans('backend::lang.media.filter_audio')) ?>
</a>
</li>
<li
role="presentation"
<?php if ($currentFilter == System\Classes\MediaLibraryItem::FILE_TYPE_DOCUMENT): ?>
class="active"
<?php endif ?>
>
<a href="#" data-command="set-filter" data-filter="<?= System\Classes\MediaLibraryItem::FILE_TYPE_DOCUMENT ?>">
<i class="icon-file"></i>
<?= e(trans('backend::lang.media.filter_documents')) ?>
</a>
</li>
</ul>

View File

@@ -0,0 +1,13 @@
<ul class="tree-path">
<li class="root"><a href="javascript:;" data-type="media-item" data-item-type="folder" data-path="/" data-clear-search="true"><?= e(trans('backend::lang.media.library')) ?></a></li>
<?php if (!$searchMode): ?>
<?php foreach ($pathSegments as $folder => $path): ?>
<?php if ($path != '/'): ?>
<li><a href="javascript:;" data-type="media-item" data-item-type="folder" data-path="<?= e($path) ?>"><?= basename($folder) ?></a></li>
<?php endif ?>
<?php endforeach?>
<?php else: ?>
<li><a href="javascript:;" data-type="media-item"><?= e(trans('backend::lang.media.search')) ?></a></li>
<?php endif ?>
</ul>

View File

@@ -0,0 +1,16 @@
<div class="panel padding-less border-bottom triangle-down">
<div class="layout">
<div class="layout-cell">
<div class="layout-row" id="<?= $this->getId('folder-path') ?>">
<?= $this->makePartial('folder-path') ?>
</div>
</div>
<div class="layout-cell">
<button
type="button"
data-command="toggle-sidebar"
class="wn-icon-sign-out btn-icon pull-right larger <?= !$sidebarVisible ? 'sidebar-hidden' : null ?>">
</button>
</div>
</div>
</div>

View File

@@ -0,0 +1,63 @@
<?php
$listElementId = $this->getId('item-list');
?>
<ul class="media-list <?= $listClass ?>">
<?php if (count($items) > 0 || !$isRootFolder): ?>
<?php if (!$isRootFolder && !$searchMode): ?>
<li tabindex="0" data-type="media-item" data-item-type="folder" data-root data-path="<?= e(dirname($currentFolder)) ?>">
<div class="icon-container folder">
<div class="icon-wrapper"><i class="icon-arrow-turn-up"></i></div>
</div>
<div class="info">
<h4 title="<?= e(trans('backend::lang.media.return_to_parent')) ?>"><?= e(trans('backend::lang.media.return_to_parent_label')) ?></h4>
</div>
</li>
<?php endif ?>
<?php foreach ($items as $item): ?>
<?php
$itemType = $item->getFileType();
?>
<li data-type="media-item"
data-item-type="<?= $item->type ?>"
data-path="<?= e($item->path) ?>"
data-title="<?= e(basename($item->path)) ?>"
data-size="<?= e($item->sizeToString()) ?>"
data-size-bytes="<?= $item->size ?>"
data-last-modified="<?= e($item->lastModifiedAsString()) ?>"
data-last-modified-ts="<?= $item->lastModified ?>"
data-public-url="<?= e($item->publicUrl) ?>"
data-document-type="<?= e($itemType) ?>"
data-folder="<?= e(dirname($item->path)) ?>"
tabindex="0"
>
<?= $this->makePartial('item-icon', ['itemType'=>$itemType, 'item'=>$item]) ?>
<div class="info">
<h4 title="<?= e(basename($item->path)) ?>">
<?= e(basename($item->path)) ?>
<?php if (!$this->readOnly): ?>
<a
href="#"
data-rename
data-control="popup"
data-z-index="1200"
data-request-data="path: '<?= e($item->path) ?>', listId: '<?= $listElementId ?>', type: '<?= $item->type ?>'"
data-handler="<?= $this->getEventHandler('onLoadRenamePopup') ?>"
><i data-rename-control class="icon-terminal"></i></a>
<?php endif; ?>
</h4>
<p class="size"><?= e($item->sizeToString()) ?></p>
</div>
</li>
<?php endforeach ?>
<?php endif ?>
<?php if (count($items) == 0 && $searchMode): ?>
<li class="no-data">
<?= e(trans('backend::lang.media.no_files_found')) ?>
</li>
<?php endif ?>
</ul>

View File

@@ -0,0 +1,42 @@
<?= Form::open(['class'=>'layout', 'onsubmit'=>'return false']) ?>
<div class="layout-row min-size">
<?= $this->makePartial('crop-toolbar') ?>
</div>
<div class="layout-row whiteboard">
<?= $this->makePartial('crop-tool-image-area') ?>
</div>
<div class="layout-row min-size whiteboard">
<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('backend::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>
</div>
<input type="hidden" name="path" value="<?= e($path) ?>">
<input type="hidden" data-control="dimension-width" value="<?= $dimensions[0] ?>">
<input type="hidden" data-control="dimension-height" value="<?= $dimensions[1] ?>">
<input type="hidden" data-control="original-width" value="<?= $dimensions[0] ?>">
<input type="hidden" data-control="original-height" value="<?= $dimensions[1] ?>">
<input type="hidden" data-control="original-ratio" value="<?= $originalRatio ?>">
<input type="hidden" data-control="original-url" value="<?= e($imageUrl) ?>">
<?= $this->makePartial('resize-image-form') ?>
<?= Form::close() ?>

View File

@@ -0,0 +1,45 @@
<div class="icon-container <?= $itemType ?>">
<div class="icon-wrapper">
<?php
$itemIconClass = $this->itemTypeToIconClass($item, $itemType);
$extension = substr(strtolower(pathinfo($item->path, PATHINFO_EXTENSION)), 0, 4) ?? '???';
if ($itemIconClass == 'icon-file'): ?>
<svg class="file-icon" viewBox="0 0 250 250" xml:space="preserve">
<path d="M62.5,0c-8.594,0 -15.625,7.031 -15.625,15.625l0,218.75c0,8.594 7.031,15.625 15.625,15.625l156.25,0c8.594,0 15.625,-7.031 15.625,-15.625l0,-171.875l-62.5,-62.5l-109.375,0Z" style="fill:#e2e5e7;fill-rule:nonzero;"/>
<path d="M187.5,62.5l46.875,0l-62.5,-62.5l0,46.875c0,8.594 7.031,15.625 15.625,15.625Z" style="fill:#b0b7bd;fill-rule:nonzero;"/>
<path d="M234.375,109.375l-46.875,-46.875l46.875,0l0,46.875Z" style="fill:#cad1d8;fill-rule:nonzero;"/>
<path d="M195.313,210.938l-148.438,-0.001l0,7.813l148.438,0c4.296,0 7.812,-3.516 7.812,-7.813l-0,-7.812c-0,4.297 -3.516,7.813 -7.813,7.813Z" style="fill:#cad1d8;fill-rule:nonzero;"/>
<!-- Colour label -->
<path class="file-icon-label file-icon-<?= $extension ?>" d="M203.125,203.125c0,4.297 -3.516,7.813 -7.813,7.813l-171.875,-0c-4.296,-0 -7.812,-3.516 -7.812,-7.813l-0,-78.125c-0,-4.297 3.516,-7.813 7.812,-7.813l171.875,0.001c4.297,-0.001 7.813,3.515 7.813,7.812l0,78.125Z"/>
<!-- Extension text node -->
<text class="file-icon-extension" x="43%" y="170px" dominant-baseline="middle" text-anchor="middle"><?= strtoupper($extension) ?></text>
</svg>
<?php else :?>
<i class="<?= $itemIconClass ?>"></i>
<?php endif ?>
</div>
<?php if (
$itemType == System\Classes\MediaLibraryItem::FILE_TYPE_IMAGE
&& $thumbnailUrl = $this->getResizedImageUrl($item->path, $thumbnailParams)
): ?>
<div>
<?php if (!$thumbnailUrl): ?>
<div
class="image-placeholder"
data-width="<?= $thumbnailParams['width'] ?>"
data-height="<?= $thumbnailParams['height'] ?>"
data-path="<?= e($item->path) ?>"
data-last-modified="<?= $item->lastModified ?>"
id="<?= $this->getPlaceholderId($item) ?>"
>
<div class="icon-wrapper"><i class="<?= $this->itemTypeToIconClass($item, $itemType) ?>"></i></div>
</div>
<?php else: ?>
<?= $this->makePartial('thumbnail-image', [
'imageUrl' => $thumbnailUrl,
]) ?>
<?php endif ?>
</div>
<?php endif ?>
</div>

View File

@@ -0,0 +1,17 @@
<div class="panel no-padding padding-top">
<input type="hidden" data-type="current-folder" value="<?= e($currentFolder) ?>"/>
<input type="hidden" data-type="search-mode" value="<?= $searchMode ? 'true' : 'false' ?>"/>
<div class="list-container">
<?php if (count($items) == 0 && $isRootFolder && !$searchMode): ?>
<div class="empty-library"><?= e(trans('backend::lang.media.empty_library')) ?></div>
<?php endif ?>
<?php if ($viewMode == Backend\Widgets\MediaManager::VIEW_MODE_GRID): ?>
<?= $this->makePartial('list-grid') ?>
<?php elseif ($viewMode == Backend\Widgets\MediaManager::VIEW_MODE_LIST): ?>
<?= $this->makePartial('list-list') ?>
<?php else: ?>
<?= $this->makePartial('list-tiles') ?>
<?php endif ?>
</div>
</div>

View File

@@ -0,0 +1,50 @@
<div data-control="media-preview-container"></div>
<script type="text/template" data-control="audio-template">
<div class="panel no-padding-bottom">
<audio src="{src}" controls>
<div class="media-player-fallback panel-embedded">Your browser doesn't support HTML5 audio.</div>
</audio>
</div>
</script>
<script type="text/template" data-control="video-template">
<video src="{src}" controls poster="<?= Url::asset('modules/backend/widgets/mediamanager/assets/images/video-poster.png') ?>">
<div class="panel media-player-fallback">Your browser doesn't support HTML5 video.</div>
</video>
</script>
<script type="text/template" data-control="image-template">
<div class="sidebar-image-placeholder-container"><div class="sidebar-image-placeholder" data-path="{path}" data-last-modified="{last-modified}" data-loading="true" data-control="sidebar-thumbnail"></div></div>
</script>
<script type="text/template" data-control="document-template">
<div class="sidebar-document-placeholder-container"><div class="sidebar-document-placeholder" data-path="{path}" data-last-modified="{last-modified}" data-control="sidebar-document"></div></div>
</script>
<script type="text/template" data-control="no-selection-template">
<div class="sidebar-image-placeholder-container">
<div class="sidebar-image-placeholder no-border">
<i class="icon-crop"></i>
<p><?= e(trans('backend::lang.media.nothing_selected')) ?></p>
</div>
</div>
</script>
<script type="text/template" data-control="multi-selection-template">
<div class="sidebar-image-placeholder-container">
<div class="sidebar-image-placeholder no-border">
<i class="icon-asterisk"></i>
<p><?= e(trans('backend::lang.media.multiple_selected')) ?></p>
</div>
</div>
</script>
<script type="text/template" data-control="go-up">
<div class="sidebar-image-placeholder-container">
<div class="sidebar-image-placeholder no-border">
<i class="icon-level-up"></i>
<p><?= e(trans('backend::lang.media.return_to_parent')) ?></p>
</div>
</div>
</script>

View File

@@ -0,0 +1,7 @@
<?php if ($this->getFilterDisplay()): ?>
<div id="<?= $this->getId('filters') ?>">
<?= $this->makePartial('filters') ?>
</div>
<?php endif; ?>
<?= $this->makePartial('sorting') ?>

View File

@@ -0,0 +1,70 @@
<?php
$listElementId = $this->getId('item-list');
?>
<table class="table data">
<col />
<col width="130px" />
<col width="130px" />
<tbody class="icons clickable">
<?php if (count($items) > 0 || !$isRootFolder): ?>
<?php if (!$isRootFolder && !$searchMode): ?>
<tr data-type="media-item" data-item-type="folder" data-root data-path="<?= e(dirname($currentFolder)) ?>" tabindex="0">
<td><i class="icon-arrow-turn-up"></i>..</td>
<td></td>
<td></td>
</tr>
<?php endif ?>
<?php foreach ($items as $item):
$itemType = $item->getFileType();
?>
<tr data-type="media-item"
data-item-type="<?= $item->type ?>"
data-path="<?= e($item->path) ?>"
data-title="<?= e(basename($item->path)) ?>"
data-size="<?= e($item->sizeToString()) ?>"
data-size-bytes="<?= $item->size ?>"
data-last-modified="<?= e($item->lastModifiedAsString()) ?>"
data-last-modified-ts="<?= $item->lastModified ?>"
data-public-url="<?= e($item->publicUrl) ?>"
data-document-type="<?= e($itemType) ?>"
data-folder="<?= e(dirname($item->path)) ?>"
tabindex="0"
>
<td>
<div class="item-title no-wrap-text">
<i class="<?= $this->itemTypeToIconClass($item, $itemType) ?>"></i> <?= e(basename($item->path)) ?>
<?php if (!$this->readOnly): ?>
<a
href="#"
data-rename
data-control="popup"
data-request-data="path: '<?= e($item->path) ?>', listId: '<?= $listElementId ?>', type: '<?= $item->type ?>'"
data-handler="<?= $this->getEventHandler('onLoadRenamePopup') ?>"
data-z-index="1200"
><i data-rename-control class="icon-terminal"></i></a>
<?php endif; ?>
</div>
</td>
<td><?= e($item->sizeToString()) ?></td>
<td><?= e($item->lastModifiedAsString()) ?></td>
<?php if ($searchMode): ?>
<td title="<?= e(dirname($item->path)) ?>">
<div class="no-wrap-text"><?= e(dirname($item->path)) ?></div>
</td>
<?php endif ?>
</tr>
<?php endforeach ?>
<?php endif ?>
</tbody>
</table>
<?php if (count($items) == 0 && $searchMode): ?>
<p class="no-data">
<?= e(trans('backend::lang.media.no_files_found')) ?>
</p>
<?php endif ?>

View File

@@ -0,0 +1 @@
<?= $this->makePartial('generic-list', ['listClass' => 'list']) ?>

View File

@@ -0,0 +1 @@
<?= $this->makePartial('generic-list', ['listClass' => 'tiles']) ?>

View File

@@ -0,0 +1,35 @@
<?= Form::open() ?>
<div class="modal-header">
<button type="button" class="close" data-dismiss="popup">&times;</button>
<h4 class="modal-title"><?= e(trans('backend::lang.media.move_popup_title')) ?></h4>
</div>
<div class="modal-body">
<div class="form-group">
<label><?= e(trans('backend::lang.media.move_destination')) ?></label>
<select
class="form-control custom-select"
name="dest"
data-placeholder="<?= e(trans('backend::lang.media.move_please_select')) ?>">
<option></option>
<?php foreach ($folders as $path => $folder): ?>
<option value="<?= e($path) ?>"><?= e($folder) ?></option>
<?php endforeach ?>
</select>
<input type="hidden" name="originalPath" value="<?= e($originalPath) ?>">
</div>
</div>
<div class="modal-footer">
<button
type="submit"
class="btn btn-primary">
<?= e(trans('backend::lang.media.move_button')) ?>
</button>
<button
type="button"
class="btn btn-default"
data-dismiss="popup">
<?= e(trans('backend::lang.form.cancel')) ?>
</button>
</div>
</form>

View File

@@ -0,0 +1,32 @@
<script type="text/template" data-control="new-folder-template">
<?= Form::open() ?>
<div class="modal-header">
<button type="button" class="close" data-dismiss="popup">&times;</button>
<h4 class="modal-title"><?= e(trans('backend::lang.media.new_folder_title')) ?></h4>
</div>
<div class="modal-body">
<div class="form-group">
<label><?= e(trans('backend::lang.media.folder_name')) ?></label>
<input
type="text"
class="form-control"
name="name"
value=""
autocomplete="off" />
</div>
</div>
<div class="modal-footer">
<button
type="submit"
class="btn btn-primary">
<?= e(trans('backend::lang.form.apply')) ?>
</button>
<button
type="button"
class="btn btn-default"
data-dismiss="popup">
<?= e(trans('backend::lang.form.cancel')) ?>
</button>
</div>
</form>
</script>

View File

@@ -0,0 +1,3 @@
<?= Form::open(['class'=>'layout', 'onsubmit'=>'return false']) ?>
<?= $this->render() ?>
<?= Form::close() ?>

View File

@@ -0,0 +1,56 @@
<?= Form::ajax($this->getEventHandler('onApplyName'), [
'success' => "\$el.trigger('close.oc.popup'); \$('#".$listId."').trigger('mediarefresh');",
'data-stripe-load-indicator' => 1,
'id' => 'media-rename-popup-form'
]) ?>
<div class="modal-header">
<button type="button" class="close" data-dismiss="popup">&times;</button>
<h4 class="modal-title"><?= e(trans('backend::lang.media.rename_popup_title')) ?></h4>
</div>
<div class="modal-body">
<div class="form-group">
<label><?= e(trans('backend::lang.media.rename_new_name')) ?></label>
<input
type="text"
name="name"
value="<?= e($name) ?>"
class="form-control"
autocomplete="off"
default-focus />
</div>
<input type="hidden" name="originalName" value="<?= e($name) ?>">
<input type="hidden" name="type" value="<?= e($type) ?>">
<input type="hidden" name="originalPath" value="<?= e($originalPath) ?>" />
</div>
<div class="modal-footer">
<button
type="submit"
class="btn btn-primary">
<?= e(trans('backend::lang.form.apply')) ?>
</button>
<button
type="button"
class="btn btn-default"
data-dismiss="popup">
<?= e(trans('backend::lang.form.cancel')) ?>
</button>
</div>
<script>
setTimeout(
function(){ $('#media-rename-popup-form input.form-control').focus() },
310
)
$('#media-rename-popup-form').on('oc.beforeRequest', function(ev){
var originalName = $('#media-rename-popup-form [name=originalName]').val(),
newName = $.trim($('#media-rename-popup-form [name=name]').val())
if (originalName == newName || newName.length == 0) {
alert('Please enter a new name')
ev.preventDefault()
}
})
</script>
<?= Form::close() ?>

View File

@@ -0,0 +1,31 @@
<script type="text/template" data-control="resize-template">
<?= Form::open() ?>
<div class="modal-header">
<button type="button" class="close" data-dismiss="popup">&times;</button>
<h4 class="modal-title"><?= e(trans('backend::lang.media.resize_image')) ?></h4>
</div>
<div class="modal-body">
<div class="form-group span-left">
<label><?= e(trans('backend::lang.media.width')) ?></label>
<input type="text" class="form-control" name="width" value="" />
</div>
<div class="form-group span-right">
<label><?= e(trans('backend::lang.media.height')) ?></label>
<input type="text" class="form-control" name="height" value="" />
</div>
</div>
<div class="modal-footer">
<button
type="submit"
class="btn btn-primary">
<?= e(trans('backend::lang.form.apply')) ?>
</button>
<button
type="button"
class="btn btn-default"
data-dismiss="popup">
<?= e(trans('backend::lang.form.cancel')) ?>
</button>
</div>
</form>
</script>

View File

@@ -0,0 +1,26 @@
<?= $this->makePartial('item-sidebar-preview') ?>
<div class="panel hide" data-control="sidebar-labels">
<label><?= e(trans('backend::lang.media.title')) ?></label>
<p data-label="title"></p>
<table class="name-value-list">
<tr>
<th><?= e(trans('backend::lang.media.size')) ?></th>
<td data-label="size"></td>
</tr>
<tr>
<th><?= e(trans('backend::lang.media.public_url')) ?></th>
<td><a href="#" data-label="public-url" target="_blank"><?= e(trans('backend::lang.media.click_here')) ?></a></td>
</tr>
<tr data-control="last-modified">
<th><?= e(trans('backend::lang.media.last_modified')) ?></th>
<td data-label="last-modified"></td>
</tr>
<tr data-control="item-folder" class="hide">
<th><?= e(trans('backend::lang.media.folder')) ?></th>
<td><a href="#" data-type="media-item" data-item-type="folder" data-label="folder" data-clear-search="true"></a></td>
</tr>
</table>
</div>

View File

@@ -0,0 +1,46 @@
<?php
$sortModes = [
System\Classes\MediaLibrary::SORT_BY_TITLE => trans('backend::lang.media.title'),
System\Classes\MediaLibrary::SORT_BY_SIZE => trans('backend::lang.media.size'),
System\Classes\MediaLibrary::SORT_BY_MODIFIED => trans('backend::lang.media.last_modified')
];
$sortDirections = [
System\Classes\MediaLibrary::SORT_DIRECTION_ASC => trans('backend::lang.media.direction_asc'),
System\Classes\MediaLibrary::SORT_DIRECTION_DESC => trans('backend::lang.media.direction_desc')
];
?>
<div class="sidebar-group">
<h3 class="section"><?= e(trans('backend::lang.media.order_by')) ?></h3>
<select
name="sorting"
class="form-control custom-select select-no-search"
data-control="sorting"
data-sort="by">
<?php foreach ($sortModes as $code => $title): ?>
<option
<?= $code == $sortBy ? 'selected="selected"' : '' ?>
value="<?= $code ?>"
><?= e($title) ?></option>
<?php endforeach ?>
</select>
</div>
<div class="sidebar-group">
<h3 class="section"><?= e(trans('backend::lang.media.direction')) ?></h3>
<select
name="sorting"
class="form-control custom-select select-no-search"
data-control="sorting"
data-sort="direction">
<?php foreach ($sortDirections as $code => $title): ?>
<option
<?= $code == $sortDirection ? 'selected="selected"' : '' ?>
value="<?= $code ?>"
><?= e($title) ?></option>
<?php endforeach ?>
</select>
</div>

View File

@@ -0,0 +1,6 @@
<?php if ($imageUrl): ?>
<img src="<?= $imageUrl ?>"/>
<?php else: ?>
<i class="icon-chain-broken" title="<?= e(trans('backend::lang.media.thumbnail_error')) ?>"></i>
<p class="thumbnail-error-message"><?= e(trans('backend::lang.media.thumbnail_error')) ?></p>
<?php endif ?>

View File

@@ -0,0 +1,42 @@
<div class="layout-row min-size">
<div class="control-toolbar toolbar-padded">
<div class="toolbar-item toolbar-primary">
<div data-control="toolbar">
<?php if (!$this->readOnly): ?>
<div class="btn-group offset-right">
<button type="button" class="btn btn-primary wn-icon-upload" data-control="upload"><?= e(trans('backend::lang.media.upload')) ?></button>
<button type="button" class="btn btn-primary wn-icon-folder" data-command="create-folder"><?= e(trans('backend::lang.media.add_folder')) ?></button>
</div>
<?php endif; ?>
<button type="button" class="btn btn-default wn-icon-refresh empty offset-right" data-command="refresh"></button>
<?php if (!$this->readOnly): ?>
<div class="btn-group offset-right">
<button type="button" class="btn btn-default wn-icon-reply-all" data-command="move"><?= e(trans('backend::lang.media.move')) ?></button>
<button type="button" class="btn btn-default wn-icon-trash" data-command="delete"><?= e(trans('backend::lang.media.delete')) ?></button>
</div>
<?php endif; ?>
<div class="btn-group offset-right" id="<?= $this->getId('view-mode-buttons') ?>">
<?= $this->makePartial('view-mode-buttons') ?>
</div>
</div>
</div>
<div class="toolbar-item" data-calculate-width>
<div class="relative loading-indicator-container size-input-text">
<input
type="text"
name="search"
value="<?= e($searchTerm) ?>"
class="form-control icon search growable"
placeholder="<?= e(trans('backend::lang.media.search')) ?>"
data-control="search"
autocomplete="off"
data-load-indicator
data-load-indicator-opaque
/>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,24 @@
<div class="layout-row min-size hide" data-control="upload-ui">
<div class="layout">
<div class="upload-progress">
<h5
data-label="file-number-and-progress"
data-message-template="<?= e(trans('backend::lang.media.uploading_file_num')) ?> &lt;span&gt;:percents&lt;/span&gt;"
data-success-template="<?= e(trans('backend::lang.media.uploading_complete')) ?>"
data-error-template="<?= e(trans('backend::lang.media.uploading_error')) ?>"
></h5>
<div class="progress-controls">
<div class="progress">
<div class="progress-bar" role="progressbar" style="width: 0;" data-control="upload-progress-bar">
</div>
</div>
<div class="controls">
<a href="#" data-command="cancel-uploading"><i class="icon-times-circle" title=""></i></a>
<a class="hide" href="#" data-command="close-uploader"><i class="icon-check-circle" title=""></i></a>
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,18 @@
<button
type="button"
class="btn btn-default wn-icon-align-justify empty <?= $viewMode == Backend\Widgets\MediaManager::VIEW_MODE_GRID ? 'on' : '' ?>"
data-command="change-view"
data-view="<?= Backend\Widgets\MediaManager::VIEW_MODE_GRID ?>">
</button>
<button
type="button"
class="btn btn-default wn-icon-th empty <?= $viewMode == Backend\Widgets\MediaManager::VIEW_MODE_LIST ? 'on' : '' ?>"
data-command="change-view"
data-view="<?= Backend\Widgets\MediaManager::VIEW_MODE_LIST ?>">
</button>
<button
type="button"
class="btn btn-default wn-icon-th-large empty <?= $viewMode == Backend\Widgets\MediaManager::VIEW_MODE_TILES ? 'on' : '' ?>"
data-command="change-view"
data-view="<?= Backend\Widgets\MediaManager::VIEW_MODE_TILES ?>">
</button>