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,157 @@
.field-fileupload .upload-object{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;position:relative;outline:none;overflow:hidden;display:inline-block;vertical-align:top}
.field-fileupload .upload-object img{width:100%;height:100%}
.field-fileupload .upload-object .icon-container{display:table;opacity:0.6}
.field-fileupload .upload-object .icon-container i{color:#95a5a6;display:inline-block}
.field-fileupload .upload-object .icon-container div{display:table-cell;text-align:center;vertical-align:middle}
.field-fileupload .upload-object .icon-container.image>div.icon-wrapper{display:none}
.field-fileupload .upload-object h4{font-size:13px;color:#2A3E51;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}
.field-fileupload .upload-object h4 a{position:absolute;right:0;top:0;display:none;font-weight:400}
.field-fileupload .upload-object p.size{font-size:12px;color:#95a5a6}
.field-fileupload .upload-object p.size strong{font-weight:400}
.field-fileupload .upload-object .meta .drag-handle{position:absolute;bottom:0;right:0;cursor:move;display:block}
.field-fileupload .upload-object .info h4 a,
.field-fileupload .upload-object .meta a.upload-remove-button,
.field-fileupload .upload-object .meta a.drag-handle{color:#2b3e50;display:none;font-size:13px;text-decoration:none}
.field-fileupload .upload-object .icon-container{position:relative}
.field-fileupload .upload-object .icon-container:after{background-image:url('../../../../../system/assets/ui/images/loader-transparent.svg');position:absolute;content:' ';width:40px;height:40px;left:50%;top:50%;margin-top:-20px;margin-left:-20px;display:block;background-size:40px 40px;background-position:50% 50%;-webkit-animation:spin 1s linear infinite;animation:spin 1s linear infinite}
.field-fileupload .upload-object.is-success .icon-container{opacity:1}
.field-fileupload .upload-object.is-success .icon-container:after{opacity:0;-webkit-transition:opacity 0.3s ease;transition:opacity 0.3s ease}
.field-fileupload .upload-object.is-error .icon-container:after{content:"";background:none;font-family:"Font Awesome 6 Free";font-weight:900;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-style:normal;font-variant:normal;text-rendering:auto;content:"\f071";-webkit-animation:none;animation:none;font-size:40px;color:#e01346;margin-top:-20px;margin-left:-20px;text-shadow:2px 2px 0 #fff}
.field-fileupload .upload-object.is-loading .icon-container{opacity:0.6}
.field-fileupload .upload-object.is-loading .icon-container:after{opacity:1;-webkit-transition:opacity 0.3s ease;transition:opacity 0.3s ease}
.field-fileupload .upload-object.is-success{cursor:pointer}
.field-fileupload .upload-object.is-success .progress-bar{opacity:0;-webkit-transition:opacity 0.3s ease;transition:opacity 0.3s ease}
.field-fileupload .upload-object.is-success:hover h4 a,
.field-fileupload .upload-object.is-success:hover .meta .upload-remove-button,
.field-fileupload .upload-object.is-success:hover .meta .drag-handle{display:block}
.field-fileupload .upload-object.is-error{cursor:pointer}
.field-fileupload .upload-object.is-error .icon-container{opacity:1}
.field-fileupload .upload-object.is-error .icon-container>img,
.field-fileupload .upload-object.is-error .icon-container>i{opacity:0.5}
.field-fileupload .upload-object.is-error .info h4{color:#e01346}
.field-fileupload .upload-object.is-error .info h4 a{display:none}
.field-fileupload .upload-object.is-error .meta{display:none}
.field-fileupload.is-sortable{position:relative}
.field-fileupload.is-sortable .upload-placeholder{position:relative;border:1px dotted #e0e0e0 !important}
.field-fileupload.is-sortable .upload-object.dragged{position:absolute;opacity:0.5;filter:alpha(opacity=50);z-index:2000}
.field-fileupload.is-sortable .upload-object.dragged .uploader-toolbar{display:none}
.field-fileupload.is-preview .upload-button,
.field-fileupload.is-preview .upload-remove-button,
.field-fileupload.is-preview .meta a.drag-handle{display:none !important}
@media (max-width:1024px){.field-fileupload .upload-object.is-success h4 a,.field-fileupload .upload-object.is-success .meta .upload-remove-button,.field-fileupload .upload-object.is-success .meta .drag-handle{display:block !important}}
.fileupload-config-form .fileupload-url-button{padding-left:0}
.fileupload-config-form .fileupload-url-button>i{color:#666}
.fileupload-config-form .file-upload-modal-image-header{background-color:#FEFEFE;background-image:-webkit-linear-gradient(45deg,#CBCBCB 25%,transparent 25%,transparent 75%,#CBCBCB 75%,#CBCBCB),-webkit-linear-gradient(45deg,#CBCBCB 25%,transparent 25%,transparent 75%,#CBCBCB 75%,#CBCBCB);background-image:-moz-linear-gradient(45deg,#CBCBCB 25%,transparent 25%,transparent 75%,#CBCBCB 75%,#CBCBCB),-moz-linear-gradient(45deg,#CBCBCB 25%,transparent 25%,transparent 75%,#CBCBCB 75%,#CBCBCB);background-image:-o-linear-gradient(45deg,#CBCBCB 25%,transparent 25%,transparent 75%,#CBCBCB 75%,#CBCBCB),-o-linear-gradient(45deg,#CBCBCB 25%,transparent 25%,transparent 75%,#CBCBCB 75%,#CBCBCB);background-image:-ms-linear-gradient(45deg,#CBCBCB 25%,transparent 25%,transparent 75%,#CBCBCB 75%,#CBCBCB),-ms-linear-gradient(45deg,#CBCBCB 25%,transparent 25%,transparent 75%,#CBCBCB 75%,#CBCBCB);background-image:linear-gradient(45deg,#CBCBCB 25%,transparent 25%,transparent 75%,#CBCBCB 75%,#CBCBCB),linear-gradient(45deg,#CBCBCB 25%,transparent 25%,transparent 75%,#CBCBCB 75%,#CBCBCB);-webkit-background-size:20px 20px;-moz-background-size:20px 20px;background-size:20px 20px;background-position:0 0,10px 10px}
.fileupload-config-form .file-upload-modal-image-header,
.fileupload-config-form .file-upload-modal-image-header img{border-top-right-radius:2px;border-top-left-radius:2px}
.fileupload-config-form .file-upload-modal-image-header .close{position:absolute;top:20px;right:20px;background:#BDC3C7;opacity:0.7;height:24px;width:22px;z-index:1}
.fileupload-config-form .file-upload-modal-image-header .close:hover,
.fileupload-config-form .file-upload-modal-image-header .close:focus{opacity:0.9}
.fileupload-config-form .file-upload-modal-image-header + .modal-body{padding-top:20px}
.field-fileupload.style-image-multi .upload-button,
.field-fileupload.style-image-multi .upload-object{margin:0 10px 10px 0}
.field-fileupload.style-image-multi .upload-button{display:block;border:2px dashed #BDC3C7;background-clip:content-box;background-color:#F9F9F9;position:relative;outline:none;float:left;width:76px;height:76px}
.field-fileupload.style-image-multi .upload-button .upload-button-icon{position:absolute;width:22px;height:22px;top:50%;left:50%;margin-top:-11px;margin-left:-11px}
.field-fileupload.style-image-multi .upload-button .upload-button-icon:before{text-align:center;display:block;font-size:22px;height:22px;width:22px;line-height:22px;color:#BDC3C7}
.field-fileupload.style-image-multi .upload-button .upload-button-icon.large-icon{width:34px;height:34px;top:50%;left:50%;margin-top:-17px;margin-left:-17px}
.field-fileupload.style-image-multi .upload-button .upload-button-icon.large-icon:before{font-size:34px;height:24px;width:24px;line-height:24px}
.field-fileupload.style-image-multi .upload-button:hover{border:2px dashed #2da7c7}
.field-fileupload.style-image-multi .upload-button:hover .upload-button-icon:before{color:#2da7c7}
.field-fileupload.style-image-multi .upload-button:focus{border:2px dashed #2da7c7}
.field-fileupload.style-image-multi .upload-button:focus .upload-button-icon:before{color:#2da7c7}
.field-fileupload.style-image-multi .upload-files-container{margin-left:90px}
.field-fileupload.style-image-multi .upload-object{background:#fff;border:1px solid #ecf0f1;width:260px}
.field-fileupload.style-image-multi .upload-object .progress-bar{display:block;width:100%;overflow:hidden;height:5px;background-color:#f5f5f5;border-radius:3px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);position:absolute;bottom:10px;left:0}
.field-fileupload.style-image-multi .upload-object .progress-bar .upload-progress{float:left;width:0%;height:100%;line-height:5px;color:#fff;background-color:#5fb6f5;-webkit-box-shadow:none;box-shadow:none;-webkit-transition:width 0.6s ease;transition:width 0.6s ease}
.field-fileupload.style-image-multi .upload-object .icon-container{border-right:1px solid #f6f8f9;float:left;overflow:hidden;width:75px;height:75px;display:flex;align-items:center;justify-content:center}
.field-fileupload.style-image-multi .upload-object .icon-container i{font-size:35px}
.field-fileupload.style-image-multi .upload-object .icon-container.image img{border-bottom-left-radius:3px;border-top-left-radius:3px;width:auto;height:auto;max-height:100%}
.field-fileupload.style-image-multi .upload-object .info{margin-left:90px}
.field-fileupload.style-image-multi .upload-object .info h4{padding-right:15px}
.field-fileupload.style-image-multi .upload-object .info h4 a{right:15px}
.field-fileupload.style-image-multi .upload-object .meta{position:absolute;bottom:0;left:0;right:0;margin:0 15px 0 90px}
.field-fileupload.style-image-multi .upload-object .meta a.drag-handle{bottom:15px}
.field-fileupload.style-image-multi .upload-object.upload-placeholder{height:75px;background-color:transparent}
.field-fileupload.style-image-multi .upload-object.upload-placeholder:after{opacity:0}
.field-fileupload.style-image-multi .upload-object:hover{background:#4da7e8 !important}
.field-fileupload.style-image-multi .upload-object:hover i,
.field-fileupload.style-image-multi .upload-object:hover p.size{color:#ecf0f1}
.field-fileupload.style-image-multi .upload-object:hover h4{color:white}
.field-fileupload.style-image-multi .upload-object:hover .icon-container{border-right-color:#4da7e8 !important}
.field-fileupload.style-image-multi .upload-object:hover h4{padding-right:35px}
.field-fileupload.style-image-multi.is-preview .upload-files-container{margin-left:0}
.form-sidebar .field-fileupload.style-image-multi .upload-files-container{margin-left:0}
.form-sidebar .field-fileupload.style-image-multi .upload-button{width:100%}
@media (max-width:1280px){.field-fileupload.style-image-multi .upload-object{width:230px}}
@media (max-width:1024px){.field-fileupload.style-image-multi .upload-button{width:100%}.field-fileupload.style-image-multi .upload-files-container{margin-left:0}.field-fileupload.style-image-multi .upload-object{margin-right:0;display:block;width:auto}}
.field-fileupload.style-image-single.is-populated .upload-button{display:none}
.field-fileupload.style-image-single .upload-button{display:block;border:2px dashed #BDC3C7;background-clip:content-box;background-color:#F9F9F9;position:relative;outline:none;min-height:100px;min-width:100px}
.field-fileupload.style-image-single .upload-button .upload-button-icon{position:absolute;width:22px;height:22px;top:50%;left:50%;margin-top:-11px;margin-left:-11px}
.field-fileupload.style-image-single .upload-button .upload-button-icon:before{text-align:center;display:block;font-size:22px;height:22px;width:22px;line-height:22px;color:#BDC3C7}
.field-fileupload.style-image-single .upload-button .upload-button-icon.large-icon{width:34px;height:34px;top:50%;left:50%;margin-top:-17px;margin-left:-17px}
.field-fileupload.style-image-single .upload-button .upload-button-icon.large-icon:before{font-size:34px;height:24px;width:24px;line-height:24px}
.field-fileupload.style-image-single .upload-button:hover{border:2px dashed #2da7c7}
.field-fileupload.style-image-single .upload-button:hover .upload-button-icon:before{color:#2da7c7}
.field-fileupload.style-image-single .upload-button:focus{border:2px dashed #2da7c7}
.field-fileupload.style-image-single .upload-button:focus .upload-button-icon:before{color:#2da7c7}
.field-fileupload.style-image-single .upload-object{padding-bottom:66px}
.field-fileupload.style-image-single .upload-object .icon-container{border:1px solid #f6f8f9;background:rgba(255,255,255,0.5)}
.field-fileupload.style-image-single .upload-object .icon-container.image img{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;display:block;max-width:100%;height:auto;min-height:100px;min-width:100px}
.field-fileupload.style-image-single .upload-object .progress-bar{display:block;width:100%;overflow:hidden;height:5px;background-color:#f5f5f5;border-radius:3px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);position:absolute;bottom:10px;left:0}
.field-fileupload.style-image-single .upload-object .progress-bar .upload-progress{float:left;width:0%;height:100%;line-height:5px;color:#fff;background-color:#5fb6f5;-webkit-box-shadow:none;box-shadow:none;-webkit-transition:width 0.6s ease;transition:width 0.6s ease}
.field-fileupload.style-image-single .upload-object .info{position:absolute;left:0;right:0;bottom:0;height:66px}
.field-fileupload.style-image-single .upload-object .meta{position:absolute;bottom:65px;left:0;right:0;margin:0 15px}
.field-fileupload.style-image-single .upload-object:hover h4{padding-right:20px}
@media (max-width:1024px){.field-fileupload.style-image-single .upload-object h4{padding-right:20px !important}}
.field-fileupload.style-file-multi .upload-button{margin-bottom:10px}
.field-fileupload.style-file-multi .upload-files-container{border:1px solid #eee;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;border-bottom:none;display:none}
.field-fileupload.style-file-multi.is-populated .upload-files-container{display:block}
.field-fileupload.style-file-multi .upload-object{display:block;width:100%;border-bottom:1px solid #eee;padding-left:10px}
.field-fileupload.style-file-multi .upload-object:nth-child(even){background-color:#f5f5f5}
.field-fileupload.style-file-multi .upload-object .icon-container{position:absolute;top:0;left:10px;width:15px;padding:11px 7px}
.field-fileupload.style-file-multi .upload-object .icon-container i{line-height:150%;font-size:15px}
.field-fileupload.style-file-multi .upload-object .icon-container img{display:none}
.field-fileupload.style-file-multi .upload-object .info{margin-left:35px;margin-right:15%}
.field-fileupload.style-file-multi .upload-object .info h4,
.field-fileupload.style-file-multi .upload-object .info p{margin:0;padding:11px 0;font-size:12px;font-weight:normal;line-height:150%;color:#666}
.field-fileupload.style-file-multi .upload-object .info h4{padding-right:15px}
.field-fileupload.style-file-multi .upload-object .info h4 a{padding:10px 0;right:15px}
.field-fileupload.style-file-multi .upload-object .info p.size{position:absolute;top:0;right:0;width:15%;display:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.field-fileupload.style-file-multi .upload-object .progress-bar{display:block;width:100%;overflow:hidden;height:5px;background-color:#f5f5f5;border-radius:3px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);position:absolute;top:18px;left:0}
.field-fileupload.style-file-multi .upload-object .progress-bar .upload-progress{float:left;width:0%;height:100%;line-height:5px;color:#fff;background-color:#5fb6f5;-webkit-box-shadow:none;box-shadow:none;-webkit-transition:width 0.6s ease;transition:width 0.6s ease}
.field-fileupload.style-file-multi .upload-object .meta{position:absolute;top:0;right:0;margin-right:15px;width:15%}
.field-fileupload.style-file-multi .upload-object .meta a.drag-handle{top:-2px;bottom:auto;line-height:150%;padding:10px 0}
.field-fileupload.style-file-multi .upload-object .icon-container:after{width:20px;height:20px;margin-top:-10px;margin-left:-10px;background-size:20px 20px}
.field-fileupload.style-file-multi .upload-object.is-error .icon-container:after{font-size:20px}
.field-fileupload.style-file-multi .upload-object.is-success .info p.size{display:block}
.field-fileupload.style-file-multi .upload-object.upload-placeholder{height:35px;background-color:transparent}
.field-fileupload.style-file-multi .upload-object.upload-placeholder:after{opacity:0}
.field-fileupload.style-file-multi .upload-object:hover{background:#4da7e8 !important}
.field-fileupload.style-file-multi .upload-object:hover i,
.field-fileupload.style-file-multi .upload-object:hover p.size{color:#ecf0f1}
.field-fileupload.style-file-multi .upload-object:hover h4{color:white}
.field-fileupload.style-file-multi .upload-object:hover .icon-container{border-right-color:#4da7e8 !important}
.field-fileupload.style-file-multi .upload-object:hover h4{padding-right:35px}
@media (max-width:1199px){.field-fileupload.style-file-multi .info{margin-right:20% !important}.field-fileupload.style-file-multi .info p.size{width:20% !important}.field-fileupload.style-file-multi .meta{width:20% !important}}
@media (max-width:991px){.field-fileupload.style-file-multi .upload-object h4{padding-right:35px !important}.field-fileupload.style-file-multi .info{margin-right:25% !important}.field-fileupload.style-file-multi .info p.size{width:25% !important;padding-right:35px !important}.field-fileupload.style-file-multi .meta{width:25% !important}}
.field-fileupload.style-file-single{background-color:#fff;border:1px solid #d1d6d9;overflow:hidden;position:relative;padding-right:30px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(209,214,217,0.25),0 1px 0 rgba(255,255,255,.5);box-shadow:inset 0 1px 0 rgba(209,214,217,0.25),0 1px 0 rgba(255,255,255,.5)}
.field-fileupload.style-file-single .upload-button{position:absolute;top:50%;margin-top:-44px;height:88px;background:transparent;right:-2px;color:#595959}
.field-fileupload.style-file-single .upload-button i{font-size:14px}
.field-fileupload.style-file-single .upload-button:hover{color:#333}
.field-fileupload.style-file-single .upload-empty-message{padding:8px 0 8px 11px;font-size:14px;cursor:pointer}
.field-fileupload.style-file-single.is-populated .upload-empty-message{display:none}
.field-fileupload.style-file-single .upload-object{display:block;width:100%;padding:7px 0 9px 0}
.field-fileupload.style-file-single .upload-object .icon-container{position:absolute;top:0;left:0;width:15px;padding:0 5px;margin:8px 0 0 7px;text-align:center}
.field-fileupload.style-file-single .upload-object .icon-container i{line-height:150%;font-size:15px}
.field-fileupload.style-file-single .upload-object .icon-container img{display:none}
.field-fileupload.style-file-single .upload-object .info{margin-left:34px;margin-right:15%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.field-fileupload.style-file-single .upload-object .info h4,
.field-fileupload.style-file-single .upload-object .info p{display:inline;margin:0;padding:0;font-size:13px;line-height:150%;color:#666}
.field-fileupload.style-file-single .upload-object .info p.size{font-weight:normal}
.field-fileupload.style-file-single .upload-object .info p.size:before{content:" - "}
.field-fileupload.style-file-single .upload-object .progress-bar{display:block;width:100%;overflow:hidden;height:5px;background-color:#f5f5f5;border-radius:3px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);position:absolute;top:50%;margin-top:-2px;right:5px}
.field-fileupload.style-file-single .upload-object .progress-bar .upload-progress{float:left;width:0%;height:100%;line-height:5px;color:#fff;background-color:#5fb6f5;-webkit-box-shadow:none;box-shadow:none;-webkit-transition:width 0.6s ease;transition:width 0.6s ease}
.field-fileupload.style-file-single .upload-object .meta{position:absolute;top:50%;margin-top:-44px;height:88px;right:0;width:15%}
.field-fileupload.style-file-single .upload-object .meta .upload-remove-button{position:absolute;top:50%;right:0;height:20px;margin-top:-10px;margin-right:10px;z-index:100}
.field-fileupload.style-file-single .upload-object .icon-container:after{width:20px;height:20px;margin-top:-10px;margin-left:-10px;background-size:20px 20px}
.field-fileupload.style-file-single .upload-object.is-error .icon-container:after{font-size:20px}

View File

@@ -0,0 +1,495 @@
/*
* File upload form field control
*
* Data attributes:
* - data-control="fileupload" - enables the file upload plugin
* - data-template - a Dropzone.js template to use for each item
* - data-error-template - a popover template used to show an error
* - data-sort-handler - AJAX handler for sorting postbacks
* - data-config-handler - AJAX handler for configuration popup
*
* JavaScript API:
* $('div').fileUploader()
*
* Dependancies:
* - Dropzone.js
*/
+function ($) { "use strict";
var Base = $.wn.foundation.base,
BaseProto = Base.prototype
// FILEUPLOAD CLASS DEFINITION
// ============================
var FileUpload = function (element, options) {
this.$el = $(element)
this.options = options || {}
$.wn.foundation.controlUtils.markDisposable(element)
Base.call(this)
this.init()
}
FileUpload.prototype = Object.create(BaseProto)
FileUpload.prototype.constructor = FileUpload
FileUpload.prototype.init = function() {
if (this.options.isMulti === null) {
this.options.isMulti = this.$el.hasClass('is-multi')
}
if (this.options.isPreview === null) {
this.options.isPreview = this.$el.hasClass('is-preview')
}
if (this.options.isSortable === null) {
this.options.isSortable = this.$el.hasClass('is-sortable')
}
this.$el.one('dispose-control', this.proxy(this.dispose))
this.$clickableElements = []
const uploadButtonEl = $('.upload-button', this.$el).get(0)
if (uploadButtonEl) {
this.$clickableElements.push(uploadButtonEl)
}
const uploadEmptyMessageEl = $('div.upload-empty-message', this.$el).get(0)
if (uploadEmptyMessageEl) {
this.$clickableElements.push(uploadEmptyMessageEl)
}
this.$filesContainer = $('.upload-files-container', this.$el)
this.uploaderOptions = {}
this.$el.on('click', '.upload-object.is-success', this.proxy(this.onClickSuccessObject))
this.$el.on('click', '.upload-object.is-error', this.proxy(this.onClickErrorObject))
// Stop here for preview mode
if (this.options.isPreview)
return
this.$el.on('click', '.upload-remove-button', this.proxy(this.onRemoveObject))
this.bindUploader()
if (this.options.isSortable) {
this.bindSortable()
}
}
FileUpload.prototype.dispose = function() {
this.$el.off('click', '.upload-object.is-success', this.proxy(this.onClickSuccessObject))
this.$el.off('click', '.upload-object.is-error', this.proxy(this.onClickErrorObject))
this.$el.off('click', '.upload-remove-button', this.proxy(this.onRemoveObject))
this.$el.off('dispose-control', this.proxy(this.dispose))
this.$el.removeData('oc.fileUpload')
this.$el = null
this.$clickableElements = null
this.$filesContainer = null
this.uploaderOptions = null
// In some cases options could contain callbacks,
// so it's better to clean them up too.
this.options = null
BaseProto.dispose.call(this)
}
//
// Uploading
//
FileUpload.prototype.bindUploader = function() {
this.uploaderOptions = {
url: this.options.url,
paramName: this.options.paramName,
clickable: this.$clickableElements,
previewsContainer: this.$filesContainer.get(0),
maxFiles: !this.options.isMulti ? 1 : null,
maxFilesize: this.options.maxFilesize,
timeout: 0,
headers: {}
}
if (this.options.fileTypes) {
this.uploaderOptions.acceptedFiles = this.options.fileTypes
}
if (this.options.template) {
this.uploaderOptions.previewTemplate = $(this.options.template).html()
}
this.uploaderOptions.thumbnailWidth = this.options.thumbnailWidth
? this.options.thumbnailWidth : null
this.uploaderOptions.thumbnailHeight = this.options.thumbnailHeight
? this.options.thumbnailHeight : null
this.uploaderOptions.resize = this.onResizeFileInfo
/*
* Add CSRF token to headers
*/
var token = $('meta[name="csrf-token"]').attr('content')
if (token) {
this.uploaderOptions.headers['X-CSRF-TOKEN'] = token
}
this.dropzone = new Dropzone(this.$el.get(0), this.uploaderOptions)
this.dropzone.on('addedfile', this.proxy(this.onUploadAddedFile))
this.dropzone.on('sending', this.proxy(this.onUploadSending))
this.dropzone.on('success', this.proxy(this.onUploadSuccess))
this.dropzone.on('error', this.proxy(this.onUploadError))
Snowboard.globalEvent("formwidgets.fileupload.initUploader", this);
}
FileUpload.prototype.onResizeFileInfo = function(file) {
var info,
targetWidth,
targetHeight
if (!this.options.thumbnailWidth && !this.options.thumbnailHeight) {
targetWidth = targetHeight = 100
}
else if (this.options.thumbnailWidth) {
targetWidth = this.options.thumbnailWidth
targetHeight = this.options.thumbnailWidth * file.height / file.width
}
else if (this.options.thumbnailHeight) {
targetWidth = this.options.thumbnailHeight * file.height / file.width
targetHeight = this.options.thumbnailHeight
}
// drawImage(image, srcX, srcY, srcWidth, srcHeight, trgX, trgY, trgWidth, trgHeight) takes an image, clips it to
// the rectangle (srcX, srcY, srcWidth, srcHeight), scales it to dimensions (trgWidth, trgHeight), and draws it
// on the canvas at coordinates (trgX, trgY).
info = {
srcX: 0,
srcY: 0,
srcWidth: file.width,
srcHeight: file.height,
trgX: 0,
trgY: 0,
trgWidth: targetWidth,
trgHeight: targetHeight
}
return info
}
FileUpload.prototype.onUploadAddedFile = function(file) {
var $object = $(file.previewElement).data('dzFileObject', file),
filesize = this.getFilesize(file)
// Change filesize format to match Winter\Storm\Filesystem\Filesystem::sizeToString() format
$(file.previewElement).find('[data-dz-size]').html('<strong>' + filesize.size + '</strong> ' + filesize.units)
// Remove any exisiting objects for single variety
if (!this.options.isMulti) {
this.removeFileFromElement($object.siblings())
}
this.evalIsPopulated()
}
FileUpload.prototype.onUploadSending = function(file, xhr, formData) {
this.addExtraFormData(formData)
xhr.setRequestHeader('X-WINTER-REQUEST-HANDLER', this.options.uploadHandler)
}
FileUpload.prototype.onUploadSuccess = function(file, response) {
var $preview = $(file.previewElement),
$img = $('.image img', $preview)
$preview.addClass('is-success')
if (response.id) {
$preview.data('id', response.id)
$preview.data('path', response.path)
$('.upload-remove-button', $preview).data('request-data', { file_id: response.id })
$img.attr('src', response.thumb)
}
this.triggerChange();
}
FileUpload.prototype.onUploadError = function(file, error) {
var $preview = $(file.previewElement)
$preview.addClass('is-error')
}
/*
* Trigger change event (Compatibility with winter.form.js)
*/
FileUpload.prototype.triggerChange = function() {
this.$el.closest('[data-field-name]').trigger('change.oc.formwidget')
}
/*
* Add the required additional data to the fileupload request
*/
FileUpload.prototype.addExtraFormData = function(formData) {
if (this.options.extraData) {
$.each(this.options.extraData, function (name, value) {
formData.append(name, value)
})
}
// Add the data from the containing form element to the upload request to
// ensure that the widget is properly initialized to handle the upload
var $form = this.$el.closest('form')
if ($form.length > 0) {
var requestParentData = $form.getRequestParentData()
$.each(requestParentData, function (key) {
formData.append(key, this)
})
}
}
FileUpload.prototype.removeFileFromElement = function($element) {
var self = this
$element.each(function() {
var $el = $(this),
obj = $el.data('dzFileObject')
if (obj) {
self.dropzone.removeFile(obj)
}
else {
$el.remove()
}
})
}
//
// Sorting
//
FileUpload.prototype.bindSortable = function() {
var
self = this,
placeholderEl = $('<div class="upload-object upload-placeholder"/>').css({
width: this.options.imageWidth,
height: this.options.imageHeight
})
this.$filesContainer.sortable({
itemSelector: 'div.upload-object.is-success',
nested: false,
tolerance: -100,
placeholder: placeholderEl,
handle: '.drag-handle',
onDrop: function ($item, container, _super) {
_super($item, container)
self.onSortAttachments()
},
distance: 10
})
}
FileUpload.prototype.onSortAttachments = function() {
if (this.options.sortHandler) {
/*
* Build an object of ID:ORDER
*/
var orderData = {}
this.$el.find('.upload-object.is-success')
.each(function(index){
var id = $(this).data('id')
orderData[id] = index + 1
})
this.$el.request(this.options.sortHandler, {
data: { sortOrder: orderData }
})
}
}
//
// User interaction
//
FileUpload.prototype.onRemoveObject = function(ev) {
var self = this,
$object = $(ev.target).closest('.upload-object')
$(ev.target)
.closest('.upload-remove-button')
.one('ajaxPromise', function(){
$object.addClass('is-loading')
})
.one('ajaxDone', function(){
self.removeFileFromElement($object)
self.evalIsPopulated()
self.triggerChange()
})
.request()
ev.stopPropagation()
}
FileUpload.prototype.onClickSuccessObject = function(ev) {
if ($(ev.target).closest('.meta').length) return
var $target = $(ev.target).closest('.upload-object')
if (!this.options.configHandler) {
window.open($target.data('path'))
return
}
$target.popup({
handler: this.options.configHandler,
extraData: { file_id: $target.data('id') }
})
$target.one('popupComplete', function(event, element, modal){
modal.one('ajaxDone', 'button[type=submit]', function(e, context, data) {
if (data.displayName) {
$('[data-dz-name]', $target).text(data.displayName)
}
})
})
}
FileUpload.prototype.onClickErrorObject = function(ev) {
var
self = this,
$target = $(ev.target).closest('.upload-object'),
errorMsg = $('[data-dz-errormessage]', $target).text(),
$template = $(this.options.errorTemplate)
// Remove any exisiting objects for single variety
if (!this.options.isMulti) {
this.removeFileFromElement($target.siblings())
}
$target.ocPopover({
content: Mustache.render($template.html(), { errorMsg: errorMsg }),
modal: true,
highlightModalTarget: true,
placement: 'top',
fallbackPlacement: 'left',
containerClass: 'popover-danger'
})
var $container = $target.data('oc.popover').$container
$container.one('click', '[data-remove-file]', function() {
$target.data('oc.popover').hide()
self.removeFileFromElement($target)
self.evalIsPopulated()
})
}
//
// Helpers
//
FileUpload.prototype.evalIsPopulated = function() {
var isPopulated = !!$('.upload-object', this.$filesContainer).length
this.$el.toggleClass('is-populated', isPopulated)
// Reset maxFiles counter
if (!isPopulated) {
this.dropzone.removeAllFiles()
}
}
/*
* Replicates the formatting of Winter\Storm\Filesystem\Filesystem::sizeToString(). This method will return
* an object with the file size amount and the unit used as `size` and `units` respectively.
*/
FileUpload.prototype.getFilesize = function (file) {
var formatter = new Intl.NumberFormat('en', {
style: 'decimal',
minimumFractionDigits: 2,
maximumFractionDigits: 2
}),
size = 0,
units = 'bytes'
if (file.size >= 1073741824) {
size = formatter.format(file.size / 1073741824)
units = 'GB'
} else if (file.size >= 1048576) {
size = formatter.format(file.size / 1048576)
units = 'MB'
} else if (file.size >= 1024) {
size = formatter.format(file.size / 1024)
units = 'KB'
} else if (file.size > 1) {
size = file.size
units = 'bytes'
} else if (file.size == 1) {
size = 1
units = 'byte'
}
return {
size: size,
units: units
}
}
FileUpload.DEFAULTS = {
url: window.location,
uploadHandler: null,
configHandler: null,
sortHandler: null,
extraData: {},
paramName: 'file_data',
fileTypes: null,
maxFilesize: 256,
template: null,
errorTemplate: null,
isMulti: null,
isPreview: null,
isSortable: null,
thumbnailWidth: 120,
thumbnailHeight: 120
}
// FILEUPLOAD PLUGIN DEFINITION
// ============================
var old = $.fn.fileUploader
$.fn.fileUploader = function (option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('oc.fileUpload')
var options = $.extend({}, FileUpload.DEFAULTS, $this.data(), typeof option == 'object' && option)
if (!data) $this.data('oc.fileUpload', (data = new FileUpload(this, options)))
if (typeof option == 'string') data[option].call($this)
})
}
$.fn.fileUploader.Constructor = FileUpload
// FILEUPLOAD NO CONFLICT
// =================
$.fn.fileUploader.noConflict = function () {
$.fn.fileUpload = old
return this
}
// FILEUPLOAD DATA-API
// ===============
$(document).render(function () {
$('[data-control="fileupload"]').fileUploader()
})
}(window.jQuery);

View File

@@ -0,0 +1,414 @@
.uploader-object-active() {
background: @fileupload-object-active-bg !important;
i, p.size {
color: #ecf0f1;
}
h4 {
color: white;
}
.icon-container {
border-right-color: @fileupload-object-active-bg !important;
}
}
.uploader-progress-bar() {
display: block;
width: 100%;
overflow: hidden;
height: @fileupload-progress-bar-height;
background-color: @fileupload-progress-bar-bg;
border-radius: @border-radius-base;
.box-shadow(inset 0 1px 2px rgba(0,0,0,.1));
.upload-progress {
float: left;
width: 0%;
height: 100%;
line-height: @fileupload-progress-bar-height;
color: @fileupload-progress-bar-color;
background-color: #5fb6f5;
.box-shadow(none);
.transition(width .6s ease);
}
}
.uploader-block-button() {
display: block;
border: 2px dashed #BDC3C7;
background-clip: content-box;
background-color: #F9F9F9;
position: relative;
outline: none;
.upload-button-icon {
position: absolute;
width: 22px;
height: 22px;
top: 50%;
left: 50%;
margin-top: -11px;
margin-left: -11px;
&:before {
text-align: center;
display: block;
font-size: 22px;
height: 22px;
width: 22px;
line-height: 22px;
color: #BDC3C7;
}
&.large-icon {
width: 34px;
height: 34px;
top: 50%;
left: 50%;
margin-top: -17px;
margin-left: -17px;
&:before {
font-size: 34px;
height: 24px;
width: 24px;
line-height: 24px;
}
}
}
&:hover {
border: 2px dashed @brand-secondary;
.upload-button-icon:before {
color: @brand-secondary;
}
}
&:focus {
border: 2px dashed @brand-secondary;
.upload-button-icon:before {
color: @brand-secondary;
}
}
}
.uploader-small-loader() {
width: 20px;
height: 20px;
margin-top: -10px;
margin-left: -10px;
background-size: 20px 20px;
}
.uploader-vertical-align() {
position: absolute;
top: 50%;
margin-top: -44px;
height: 88px;
}
//
// Shared
//
.field-fileupload {
//
// Uploaded item
//
.upload-object {
.border-radius(3px);
position: relative;
outline: none;
overflow: hidden;
display: inline-block;
vertical-align: top;
img {
width: 100%;
height: 100%;
}
.icon-container {
display: table;
opacity: .6;
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-size: 13px;
color: #2A3E51;
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;
display: none;
font-weight: 400;
}
}
p.size {
font-size: 12px;
color: #95a5a6;
strong { font-weight: 400; }
}
.meta {
.drag-handle {
position: absolute;
bottom: 0;
right: 0;
cursor: move;
display: block;
}
}
.info h4 a,
.meta a.upload-remove-button,
.meta a.drag-handle {
color: #2b3e50;
display: none;
font-size: 13px;
text-decoration: none;
}
}
//
// Loading State
//
.upload-object {
.icon-container {
position: relative;
}
.icon-container:after {
background-image: url('../../../../../system/assets/ui/images/loader-transparent.svg');
position: absolute;
content: ' ';
width: 40px;
height: 40px;
left: 50%;
top: 50%;
margin-top: -20px;
margin-left: -20px;
display: block;
background-size: 40px 40px;
background-position: 50% 50%;
.animation(spin 1s linear infinite);
}
&.is-success {
.icon-container {
opacity: 1;
}
.icon-container:after {
opacity: 0;
.transition(opacity .3s ease);
}
}
// Replaces the loader with an error symbol
&.is-error {
.icon-container:after {
content: "";
background: none;
.icon(@exclamation-triangle);
.animation(none);
font-size: 40px;
color: @brand-danger;
margin-top: -20px;
margin-left: -20px;
text-shadow: 2px 2px 0 #fff;
}
}
&.is-loading {
.icon-container {
opacity: .6;
}
.icon-container:after {
opacity: 1;
.transition(opacity .3s ease);
}
}
}
//
// Success state
//
.upload-object.is-success {
cursor: pointer;
.progress-bar {
opacity: 0;
.transition(opacity .3s ease);
}
&:hover {
h4 a,
.meta .upload-remove-button,
.meta .drag-handle { display: block; }
}
}
//
// Error State
//
.upload-object.is-error {
cursor: pointer;
.icon-container {
opacity: 1;
> img, > i {
opacity: .5;
}
}
.info h4 {
color: @brand-danger;
a {
display: none;
}
}
.meta {
display: none;
}
}
//
// Sortable
//
&.is-sortable {
position: relative;
.upload-placeholder {
position: relative;
border: 1px dotted #e0e0e0 !important;
}
.upload-object.dragged {
position: absolute;
.opacity(.5);
z-index: 2000;
.uploader-toolbar {
display: none;
}
}
}
//
// Preview mode
//
&.is-preview {
.upload-button,
.upload-remove-button,
.meta a.drag-handle {
display: none !important;
}
}
}
//
// Media
//
@media (max-width: 1024px) {
.field-fileupload {
.upload-object.is-success {
h4 a,
.meta .upload-remove-button,
.meta .drag-handle { display: block !important; }
}
}
}
//
// Config form
//
.fileupload-config-form {
.fileupload-url-button{
padding-left: 0;
> i {
color: #666;
}
}
.file-upload-modal-image-header {
// Photoshop transparent background
// Based on: http://lea.verou.me/css3patterns/#checkerboard
background-color: #FEFEFE;
background-image: -webkit-linear-gradient(45deg, #CBCBCB 25%, transparent 25%, transparent 75%, #CBCBCB 75%, #CBCBCB), -webkit-linear-gradient(45deg, #CBCBCB 25%, transparent 25%, transparent 75%, #CBCBCB 75%, #CBCBCB);
background-image: -moz-linear-gradient(45deg, #CBCBCB 25%, transparent 25%, transparent 75%, #CBCBCB 75%, #CBCBCB), -moz-linear-gradient(45deg, #CBCBCB 25%, transparent 25%, transparent 75%, #CBCBCB 75%, #CBCBCB);
background-image: -o-linear-gradient(45deg, #CBCBCB 25%, transparent 25%, transparent 75%, #CBCBCB 75%, #CBCBCB), -o-linear-gradient(45deg, #CBCBCB 25%, transparent 25%, transparent 75%, #CBCBCB 75%, #CBCBCB);
background-image: -ms-linear-gradient(45deg, #CBCBCB 25%, transparent 25%, transparent 75%, #CBCBCB 75%, #CBCBCB), -ms-linear-gradient(45deg, #CBCBCB 25%, transparent 25%, transparent 75%, #CBCBCB 75%, #CBCBCB);
background-image: linear-gradient(45deg, #CBCBCB 25%, transparent 25%, transparent 75%, #CBCBCB 75%, #CBCBCB), linear-gradient(45deg, #CBCBCB 25%, transparent 25%, transparent 75%, #CBCBCB 75%, #CBCBCB);
-webkit-background-size: 20px 20px;
-moz-background-size: 20px 20px;
background-size: 20px 20px;
background-position: 0 0, 10px 10px;
&, img {
.border-top-radius(2px);
}
.close {
position: absolute;
top: 20px;
right: 20px;
background: #BDC3C7;
opacity: .7;
height: 24px;
width: 22px;
z-index: 1;
&:hover, &:focus {
opacity: .9;
}
}
}
.file-upload-modal-image-header + .modal-body {
padding-top: @padding-standard;
}
}

View File

@@ -0,0 +1,176 @@
//
// Multi File
//
.field-fileupload.style-file-multi {
.upload-button {
margin-bottom: 10px;
}
.upload-files-container {
border: 1px solid @fileupload-list-border-color;
.border-radius(3px);
border-bottom: none;
display: none;
}
&.is-populated .upload-files-container {
display: block;
}
.upload-object {
display: block;
width: 100%;
border-bottom: 1px solid @fileupload-list-border-color;
padding-left: 10px;
&:nth-child(even) {
background-color: @fileupload-list-accent-bg;
}
.icon-container {
position: absolute;
top: 0;
left: 10px;
width: 15px;
padding: 11px 7px;
i {
line-height: 150%;
font-size: 15px;
}
img { display: none; }
}
.info {
margin-left: 35px;
margin-right: 15%;
h4, p {
margin: 0;
padding: 11px 0;
font-size: 12px;
font-weight: normal;
line-height: 150%;
color: #666666;
}
h4 {
padding-right: 15px;
a {
padding: 10px 0;
right: 15px;
}
}
p.size {
position: absolute;
top: 0;
right: 0;
width: 15%;
display: none;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.progress-bar {
.uploader-progress-bar();
position: absolute;
top: 18px;
left: 0;
}
.meta {
position: absolute;
top: 0;
right: 0;
margin-right: 15px;
width: 15%;
a.drag-handle {
top: -2px;
bottom: auto;
line-height: 150%;
padding: 10px 0;
}
}
.icon-container:after {
.uploader-small-loader();
}
&.is-error .icon-container:after {
font-size: 20px;
}
//
// Success
//
&.is-success {
.info p.size { display: block; }
}
//
// Sorting
//
&.upload-placeholder {
height: 35px;
background-color: transparent;
&:after { opacity: 0; }
}
//
// Hover
//
&:hover {
.uploader-object-active();
h4 { padding-right: 35px; }
}
}
}
//
// Media
//
@media (max-width: @screen-md-max) {
.field-fileupload.style-file-multi {
.info {
margin-right: 20% !important;
p.size {
width: 20% !important;
}
}
.meta {
width: 20% !important;
}
}
}
@media (max-width: @screen-sm-max) {
.field-fileupload.style-file-multi {
.upload-object {
h4 { padding-right: 35px !important; }
}
.info {
margin-right: 25% !important;
p.size {
width: 25% !important;
padding-right: 35px !important;
}
}
.meta {
width: 25% !important;
}
}
}

View File

@@ -0,0 +1,120 @@
//
// Single File
//
.field-fileupload.style-file-single {
background-color: @color-form-field-bg;
border: 1px solid @color-form-field-border;
overflow: hidden;
position: relative;
padding-right: 30px;
border-radius: 3px;
.box-shadow(@input-box-shadow);
.upload-button {
.uploader-vertical-align();
background: transparent;
right: -2px;
color: lighten(@color-form-field-recordfinder-btn, 15%);
i {
font-size: 14px;
}
&:hover {
color: @color-form-field-recordfinder-btn;
}
}
.upload-empty-message {
padding: 8px 0 8px 11px;
font-size: 14px;
cursor: pointer;
}
&.is-populated {
.upload-empty-message {
display: none;
}
}
.upload-object {
display: block;
width: 100%;
padding: 7px 0 9px 0;
.icon-container {
position: absolute;
top: 0;
left: 0;
width: 15px;
padding: 0 5px;
margin: 8px 0 0 7px;
text-align: center;
i {
line-height: 150%;
font-size: 15px;
}
img { display: none; }
}
.info {
margin-left: 34px;
margin-right: 15%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
h4, p {
display: inline;
margin: 0;
padding: 0;
font-size: 13px;
line-height: 150%;
color: #666666;
}
p.size {
font-weight: normal;
&:before {
content: " - ";
}
}
}
.progress-bar {
.uploader-progress-bar();
position: absolute;
top: 50%;
margin-top: -2px;
right: 5px;
}
.meta {
.uploader-vertical-align();
right: 0;
width: 15%;
.upload-remove-button {
position: absolute;
top: 50%;
right: 0;
height: 20px;
margin-top: -10px;
margin-right: 10px;
z-index: 100;
}
}
.icon-container:after {
.uploader-small-loader();
}
&.is-error .icon-container:after {
font-size: 20px;
}
}
}

View File

@@ -0,0 +1,139 @@
//
// Multi Image
//
.field-fileupload.style-image-multi {
.upload-button,
.upload-object {
margin: 0 10px 10px 0;
}
.upload-button {
.uploader-block-button();
float: left;
width: 76px;
height: 76px;
}
.upload-files-container {
margin-left: 90px;
}
.upload-object {
background: #fff;
border: 1px solid #ecf0f1;
width: 260px;
.progress-bar {
.uploader-progress-bar();
position: absolute;
bottom: 10px;
left: 0;
}
.icon-container {
border-right: 1px solid #f6f8f9;
float: left;
overflow: hidden;
width: 75px;
height: 75px;
display: flex;
align-items: center;
justify-content: center;
i {
font-size: 35px;
}
&.image img {
.border-left-radius(3px);
width: auto;
height: auto;
max-height: 100%;
}
}
.info {
margin-left: 90px;
h4 {
padding-right: 15px;
a {
right: 15px;
}
}
}
.meta {
position: absolute;
bottom: 0;
left: 0;
right: 0;
margin: 0 15px 0 90px;
a.drag-handle {
bottom: 15px;
}
}
&.upload-placeholder {
height: 75px;
background-color: transparent;
&:after { opacity: 0; }
}
&:hover {
.uploader-object-active();
h4 { padding-right: 35px; }
}
}
&.is-preview {
.upload-files-container {
margin-left: 0;
}
}
}
//
// On Sidebar
//
.form-sidebar .field-fileupload.style-image-multi .upload-files-container {
margin-left: 0px;
}
.form-sidebar .field-fileupload.style-image-multi .upload-button {
width: 100%;
}
//
// Media
//
@media (max-width: 1280px) {
.field-fileupload.style-image-multi {
.upload-object {
width: 230px;
}
}
}
@media (max-width: 1024px) {
.field-fileupload.style-image-multi {
.upload-button {
width: 100%;
}
.upload-files-container {
margin-left: 0;
}
.upload-object {
margin-right: 0;
display: block;
width: auto;
}
}
}

View File

@@ -0,0 +1,78 @@
//
// Single Image
//
.field-fileupload.style-image-single {
&.is-populated {
.upload-button {
display: none;
}
}
.upload-button {
.uploader-block-button();
min-height: 100px;
min-width: 100px;
}
.upload-object {
padding-bottom: 66px;
.icon-container {
border: 1px solid #f6f8f9;
background: rgba(255,255,255,.5);
&.image img {
.border-radius(3px);
.img-responsive();
// This is needed when the image is very large and
// being processed by dropzone on the client-side
// the image has no height or width.
min-height: 100px;
min-width: 100px;
}
}
.progress-bar {
.uploader-progress-bar();
position: absolute;
bottom: 10px;
left: 0;
}
.info {
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 66px;
}
.meta {
position: absolute;
bottom: 65px;
left: 0;
right: 0;
margin: 0 15px;
}
&:hover {
h4 { padding-right: 20px; }
}
}
}
//
// Media
//
@media (max-width: 1024px) {
.field-fileupload.style-image-single {
.upload-object {
h4 { padding-right: 20px !important; }
}
}
}

View File

@@ -0,0 +1,15 @@
@import "../../../../assets/less/core/boot.less";
@fileupload-progress-bar-height: 5px;
@fileupload-progress-bar-color: #fff;
@fileupload-progress-bar-bg: #f5f5f5;
@fileupload-inactive-icon: #808b93;
@fileupload-object-active-bg: #4da7e8;
@fileupload-list-accent-bg: #f5f5f5;
@fileupload-list-border-color: #eeeeee;
@import "fileupload.base.less";
@import "fileupload.imagemulti.less";
@import "fileupload.imagesingle.less";
@import "fileupload.filemulti.less";
@import "fileupload.filesingle.less";