Browse Source

Add a global dropzone for file dragging. Closes #198

pull/236/merge
Artur Arseniev 9 years ago
parent
commit
43b4f96d54
  1. 2
      dist/css/grapes.min.css
  2. 10
      src/asset_manager/config/config.js
  3. 4
      src/asset_manager/index.js
  4. 69
      src/asset_manager/view/FileUploader.js
  5. 18
      src/editor/index.js
  6. 3
      src/editor/model/Editor.js
  7. 1
      src/editor/view/EditorView.js
  8. 113
      src/styles/scss/_gjs_assets.scss
  9. 97
      src/styles/scss/main.scss

2
dist/css/grapes.min.css

File diff suppressed because one or more lines are too long

10
src/asset_manager/config/config.js

@ -21,4 +21,14 @@ module.exports = {
// // ...send somewhere
// }
uploadFile: '',
// Enable an upload dropzone on the entire editor (not document) when dragging
// files over it
dropzone: 1,
// Open the asset manager once files are been dropped via the dropzone
openAssetsOnDrop: 1,
// Any dropzone content to append inside dropzone element
dropzoneContent: '',
};

4
src/asset_manager/index.js

@ -206,6 +206,10 @@ module.exports = () => {
return this.rendered;
},
postRender(editorView) {
fu.initDropzone(editorView);
},
//-------
/**

69
src/asset_manager/view/FileUploader.js

@ -13,15 +13,17 @@ module.exports = Backbone.View.extend({
events: {},
initialize(o) {
this.options = o || {};
this.config = o.config || {};
this.pfx = this.config.stylePrefix || '';
this.target = this.collection || {};
this.uploadId = this.pfx + 'uploadFile';
this.disabled = !this.config.upload;
initialize(opts = {}) {
this.options = opts;
const c = opts.config || {};
this.config = c;
this.pfx = c.stylePrefix || '';
this.ppfx = c.pStylePrefix || '';
this.target = this.collection || {};
this.uploadId = this.pfx + 'uploadFile';
this.disabled = !c.upload;
this.events['change #' + this.uploadId] = 'uploadFile';
let uploadFile = this.config.uploadFile;
let uploadFile = c.uploadFile;
if (uploadFile) {
this.uploadFile = uploadFile.bind(this);
@ -94,6 +96,57 @@ module.exports = Backbone.View.extend({
}
},
initDropzone(ev) {
let addedCls = 0;
const c = this.config;
const em = ev.model;
const edEl = ev.el;
const editor = em && em.get('Editor');
const frameEl = ev.model.get('Canvas').getBody();;//.getBody();
const ppfx = this.ppfx;
const updatedCls = `${ppfx}dropzone-active`;
const dropzoneCls = `${ppfx}dropzone`;
const cleanEditorElCls = () => {
edEl.className = edEl.className.replace(updatedCls, '').trim();
addedCls = 0;
}
const onDragOver = () => {
if (!addedCls) {
edEl.className += ` ${updatedCls}`;
addedCls = 1;
}
return false;
};
const onDragLeave = () => {
cleanEditorElCls();
return false;
};
const onDrop = (e) => {
cleanEditorElCls();
e.preventDefault();
this.uploadFile(e);
if (c.openAssetsOnDrop && editor) {
const target = editor.getSelected();
editor.runCommand('open-assets', {target});
}
return false;
};
ev.$el.append(`<div class="${dropzoneCls}">${c.dropzoneContent}</div>`);
cleanEditorElCls();
if (c.dropzone && 'draggable' in edEl) {
edEl.ondragover = onDragOver;
edEl.ondragleave = onDragLeave;
edEl.ondrop = onDrop;
frameEl.ondragover = onDragOver;
frameEl.ondragleave = onDragLeave;
frameEl.ondrop = onDrop;
}
},
render() {
this.$el.html( this.template({
title: this.config.uploadText,

18
src/editor/index.js

@ -10,6 +10,7 @@
* * [getStyle](#getstyle)
* * [setStyle](#setstyle)
* * [getSelected](#getselected)
* * [getSelectedToStyle](#getselectedtostyle)
* * [setDevice](#setdevice)
* * [getDevice](#getdevice)
* * [runCommand](#runcommand)
@ -84,10 +85,9 @@ module.exports = config => {
if (!(name in c))
c[name] = defaults[name];
}
c.pStylePrefix = c.stylePrefix;
c.pStylePrefix = c.stylePrefix;
var em = new EditorModel(c);
var editorView = new EditorView({
model: em,
config: c,
@ -314,9 +314,9 @@ module.exports = config => {
},
/**
* Get stylable entity from the selected component.
* If you select the component without classes the entity is the Component
* itself and all changes will go inside its 'style' property. Otherwise,
* Get a stylable entity from the selected component.
* If you select a component without classes the entity is the Component
* itself and all changes will go inside its 'style' attribute. Otherwise,
* if the selected component has one or more classes, the function will
* return the corresponding CSS Rule
* @return {Model}
@ -516,7 +516,13 @@ module.exports = config => {
* @return {HTMLElement}
*/
render() {
return editorView.render().el;
editorView.render();
em.get('modules').forEach((module) => {
module.postRender && module.postRender(editorView);
});
return editorView.el;
},
};

3
src/editor/model/Editor.js

@ -32,6 +32,7 @@ module.exports = Backbone.Model.extend({
previousModel: null,
changesCount: 0,
storables: [],
modules: [],
toLoad: [],
opened: {},
device: '',
@ -40,6 +41,7 @@ module.exports = Backbone.Model.extend({
initialize(c) {
this.config = c;
this.set('Config', c);
this.set('modules', []);
if(c.el && c.fromElement)
this.config.components = c.el.innerHTML;
@ -117,6 +119,7 @@ module.exports = Backbone.Model.extend({
if(M.onLoad)
this.get('toLoad').push(M);
this.get('modules').push(M);
return this;
},

1
src/editor/view/EditorView.js

@ -3,6 +3,7 @@ var Backbone = require('backbone');
module.exports = Backbone.View.extend({
initialize() {
this.model.view = this;
this.pn = this.model.get('Panels');
this.conf = this.model.config;
this.className = this.conf.stylePrefix + 'editor';

113
src/styles/scss/_gjs_assets.scss

@ -0,0 +1,113 @@
.#{$app-prefix}dropzone {
display: none;
position: absolute;
top: 0;
left: 0;
z-index: 5;
width: 100%;
height: 100%;
}
.#{$app-prefix}dropzone-active {
.#{$app-prefix}dropzone {
display: block;
}
}
.#{$am-prefix}assets {
height: 290px;
overflow: auto;
clear: both;
}
.#{$am-prefix}assets-header {
padding: 5px;
}
.#{$am-prefix}add-asset {
.#{$am-prefix}add-field {
width: 70%;
float: left;
}
button{
width: 25%;
float: right;
}
}
.#{$am-prefix}add-field input {
padding: 6px;
}
.#{$am-prefix}assets-cont {
background-color: $mainDklColor;
border-radius: 3px;
box-sizing: border-box;
padding: 10px;
width: 45%;
float:right;
height: 325px;
overflow: hidden;
##{$am-prefix}preview-cont{
position: relative;
height: 70px; width: 30%;
background-color: $mainColor;
border-radius: 2px;
float: left;
overflow: hidden;
}
##{$am-prefix}preview{
position: absolute;
background-position: center center;
background-size: cover;
background-repeat: no-repeat;
height: 100%;
width: 100%;
z-index: 1;
}
##{$am-prefix}preview-bg{
position: absolute;
height: 100%;
width: 100%;
@include opacity(0.5);
z-index: 0;
}
.#{$am-prefix}highlight {
background-color: $mainLhColor;
}
.#{$am-prefix}asset {
border-bottom: 1px solid darken($mainDkColor, 3%);
padding: 5px;
cursor:pointer;
position: relative;
&:hover ##{$am-prefix}close { display: block;}
}
##{$am-prefix}close {
@extend .btn-cl;
position: absolute;
right: 5px;
top: 0;
display: none;
}
##{$am-prefix}meta {
width: 70%;
float: left;
font-size: 12px;
padding: 5px 0 0 5px;
box-sizing: border-box;
> div { margin-bottom: 5px;}
##{$am-prefix}dimensions {
font-size: 10px;
@include opacity(0.5);
}
}
}

97
src/styles/scss/main.scss

@ -922,103 +922,8 @@ $paddElClm: 5px 6px;
}
/********* Assets Manager **********/
.#{$am-prefix}assets {
height: 290px;
overflow: auto;
clear: both;
}
.#{$am-prefix}assets-header {
padding: 5px;
}
.#{$am-prefix}add-asset {
.#{$am-prefix}add-field {
width: 70%;
float: left;
}
button{
width: 25%;
float: right;
}
}
.#{$am-prefix}add-field input {
padding: 6px;
}
.#{$am-prefix}assets-cont {
background-color: $mainDklColor;
border-radius: 3px;
box-sizing: border-box;
padding: 10px;
width: 45%;
float:right;
height: 325px;
overflow: hidden;
##{$am-prefix}preview-cont{
position: relative;
height: 70px; width: 30%;
background-color: $mainColor;
border-radius: 2px;
float: left;
overflow: hidden;
}
##{$am-prefix}preview{
position: absolute;
background-position: center center;
background-size: cover;
background-repeat: no-repeat;
height: 100%;
width: 100%;
z-index: 1;
}
##{$am-prefix}preview-bg{
position: absolute;
height: 100%;
width: 100%;
@include opacity(0.5);
z-index: 0;
}
.#{$am-prefix}highlight {
background-color: $mainLhColor;
}
.#{$am-prefix}asset {
border-bottom: 1px solid darken($mainDkColor, 3%);
padding: 5px;
cursor:pointer;
position: relative;
&:hover ##{$am-prefix}close { display: block;}
}
##{$am-prefix}close {
@extend .btn-cl;
position: absolute;
right: 5px;
top: 0;
display: none;
}
##{$am-prefix}meta {
width: 70%;
float: left;
font-size: 12px;
padding: 5px 0 0 5px;
box-sizing: border-box;
> div { margin-bottom: 5px;}
##{$am-prefix}dimensions {
font-size: 10px;
@include opacity(0.5);
}
}
}
@import "gjs_assets";
/********* File uploader **********/

Loading…
Cancel
Save