Browse Source

Improve dragger/sorter

pull/187/head
Artur Arseniev 9 years ago
parent
commit
5e4c4c6253
  1. 4
      dist/grapes.min.js
  2. 4
      index.html
  3. 2
      package.json
  4. 1
      src/dom_components/model/Component.js
  5. 4
      src/navigator/view/ItemsView.js
  6. 132
      src/utils/Sorter.js

4
dist/grapes.min.js

File diff suppressed because one or more lines are too long

4
index.html

@ -14,7 +14,7 @@
<body> <body>
<div id="gjs" style="height:0px; overflow:hidden;"> <div id="gjs" style="height:0px; overflow:hidden;">
<header class="header-banner"> <header class="header-banner">
<div class="container-width"> <div class="container-width" data-gjs-droppable=".blk-row">
<div class="logo-container"> <div class="logo-container">
<div class="logo">GrapesJS</div> <div class="logo">GrapesJS</div>
</div> </div>
@ -806,7 +806,7 @@
clearOnRender: 0, clearOnRender: 0,
storageManager:{ storageManager:{
autoload: 1, autoload: 0,
storeComponents: 1, storeComponents: 1,
storeStyles: 1, storeStyles: 1,
}, },

2
package.json

@ -1,7 +1,7 @@
{ {
"name": "grapesjs", "name": "grapesjs",
"description": "Free and Open Source Web Builder Framework", "description": "Free and Open Source Web Builder Framework",
"version": "0.8.19", "version": "0.8.21",
"author": "Artur Arseniev", "author": "Artur Arseniev",
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"homepage": "http://grapesjs.com", "homepage": "http://grapesjs.com",

1
src/dom_components/model/Component.js

@ -329,6 +329,7 @@ module.exports = Backbone.Model.extend({
toJSON(...args) { toJSON(...args) {
var obj = Backbone.Model.prototype.toJSON.apply(this, args); var obj = Backbone.Model.prototype.toJSON.apply(this, args);
var scriptStr = this.getScriptString(); var scriptStr = this.getScriptString();
delete obj.toolbar;
if (scriptStr) { if (scriptStr) {
obj.script = scriptStr; obj.script = scriptStr;

4
src/navigator/view/ItemsView.js

@ -34,6 +34,10 @@ module.exports = Backbone.View.extend({
// For the sorter // For the sorter
this.$el.data('collection', this.collection); this.$el.data('collection', this.collection);
if (this.parent) {
this.$el.data('model', this.parent);
}
}, },
/** /**

132
src/utils/Sorter.js

@ -134,10 +134,12 @@ module.exports = Backbone.View.extend({
* @param {Event} e * @param {Event} e
*/ */
moveDragHelper(e) { moveDragHelper(e) {
if(!this.dragHelper) { var doc = e.target.ownerDocument;
if(!this.dragHelper || !doc) {
return; return;
} }
var doc = e.target.ownerDocument;
var win = doc.defaultView || doc.parentWindow; var win = doc.defaultView || doc.parentWindow;
var addTop = 0; var addTop = 0;
var addLeft = 0; var addLeft = 0;
@ -221,11 +223,13 @@ module.exports = Backbone.View.extend({
* @param {HTMLElement} trg * @param {HTMLElement} trg
* */ * */
startSort(trg) { startSort(trg) {
this.dropModel = null;
this.moved = 0; this.moved = 0;
this.eV = trg;
if(trg && !this.matches(trg, this.itemSel + ',' + this.containerSel)) if(trg && !this.matches(trg, this.itemSel + ',' + this.containerSel))
this.eV = this.closest(trg, this.itemSel); trg = this.closest(trg, this.itemSel);
this.eV = trg;
// Create placeholder if not exists // Create placeholder if not exists
if(!this.plh) { if(!this.plh) {
@ -258,11 +262,36 @@ module.exports = Backbone.View.extend({
* Get the model from HTMLElement target * Get the model from HTMLElement target
* @return {Model|null} * @return {Model|null}
*/ */
getModelFromTarget(el) { getTargetModel(el) {
let elem = el || this.target; let elem = el || this.target;
return $(elem).data('model'); return $(elem).data('model');
}, },
/**
* Get the model of the current source element (element to drag)
* @return {Model}
*/
getSourceModel() {
var src = this.eV;
let dropContent = this.dropContent;
let dropModel = this.dropModel;
const em = this.em;
if (dropContent && em) {
if (!dropModel) {
let comps = em.get('DomComponents').getComponents();
let tempModel = comps.add(dropContent);
dropModel = comps.remove(tempModel);
this.dropModel = dropModel;
}
return dropModel;
}
if (src) {
return $(src).data('model');
}
},
/** /**
* Highlight target * Highlight target
* @param {Model|null} model * @param {Model|null} model
@ -307,7 +336,7 @@ module.exports = Backbone.View.extend({
var dims = this.dimsFromTarget(e.target, rX, rY); var dims = this.dimsFromTarget(e.target, rX, rY);
let targetModel = this.getModelFromTarget(this.target); let targetModel = this.getTargetModel(this.target);
this.selectTargetModel(targetModel); this.selectTargetModel(targetModel);
this.lastDims = dims; this.lastDims = dims;
@ -393,6 +422,37 @@ module.exports = Backbone.View.extend({
return; return;
}, },
/**
* Check if the target is valid with the actual source
* @param {HTMLElement} trg
* @return {Boolean}
*/
validTarget(trg) {
let srcModel = this.getSourceModel();
let src = srcModel.view.el;
let trgModel = this.getTargetModel(trg);
trg = trgModel.view.el;
console.log('Sorce', src, 'Target', trgModel, trg);
// Check if the target could accept the source
let droppable = trgModel.get('droppable');
droppable = droppable instanceof Array ? droppable.join(', ') : droppable;
droppable = typeof droppable === 'string' ? src.matches(droppable) : droppable;
console.log('Target droppable', droppable);
// check if the source is draggable in target
let draggable = srcModel.get('draggable');
draggable = draggable instanceof Array ? draggable.join(', ') : draggable;
draggable = typeof draggable === 'string' ? trg.matches(draggable) : draggable;
console.log('Source draggable', draggable);
if (!droppable || !draggable) {
return false;
}
return true;
},
/** /**
* Get dimensions of nodes relative to the coordinates * Get dimensions of nodes relative to the coordinates
* @param {HTMLElement} target * @param {HTMLElement} target
@ -404,29 +464,33 @@ module.exports = Backbone.View.extend({
var dims = []; var dims = [];
// Select the first valuable target // Select the first valuable target
// TODO: avoid this check for every standard component, if (!target.matches(`${this.itemSel}, ${this.containerSel}`)) {
// which generally is ok
if(!this.matches(target, this.itemSel + ',' + this.containerSel))
target = this.closest(target, this.itemSel); target = this.closest(target, this.itemSel);
}
// If draggable is an array the target will be one of those // If draggable is an array the target will be one of those
if(this.draggable instanceof Array){ if (this.draggable instanceof Array) {
target = this.closest(target, this.draggable.join(',')); target = this.closest(target, this.draggable.join(','));
} }
if(!target) if (!target) {
return dims; return dims;
}
// Check if the target is different from the previous one // Check if the target is different from the previous one
if(this.prevTarget){ if (this.prevTarget && this.prevTarget != target) {
if(this.prevTarget != target){
this.prevTarget = null; this.prevTarget = null;
}
} }
// New target encountered // New target found
if(!this.prevTarget){ if (!this.prevTarget) {
this.targetP = this.closest(target, this.containerSel); this.targetP = this.closest(target, this.containerSel);
// Check if the source is valid with the target
if (!this.validTarget(target)) {
return this.dimsFromTarget(this.targetP, rX, rY);
}
this.prevTarget = target; this.prevTarget = target;
this.prevTargetDim = this.getDim(target); this.prevTargetDim = this.getDim(target);
this.cacheDimsP = this.getChildrenDim(this.targetP); this.cacheDimsP = this.getChildrenDim(this.targetP);
@ -442,7 +506,7 @@ module.exports = Backbone.View.extend({
// Generally also on every new target the poiner enters near // Generally also on every new target the poiner enters near
// to borders, so have to to check always // to borders, so have to to check always
if(this.nearBorders(this.prevTargetDim, rX, rY) || if(this.nearBorders(this.prevTargetDim, rX, rY) ||
(!this.nested && !this.cacheDims.length)){ (!this.nested && !this.cacheDims.length)) {
dims = this.cacheDimsP; dims = this.cacheDimsP;
this.target = this.targetP; this.target = this.targetP;
} }
@ -714,21 +778,24 @@ module.exports = Backbone.View.extend({
var draggable = typeof drag !== 'undefined' ? drag : 1; var draggable = typeof drag !== 'undefined' ? drag : 1;
var toDrag = draggable; var toDrag = draggable;
if (this.dropContent instanceof Object) { // dropContent is for example the one used inside Blocks content
draggable = this.dropContent.draggable; var dropContent = this.dropContent;
if (dropContent instanceof Object) {
draggable = dropContent.draggable;
draggable = typeof draggable !== 'undefined' ? draggable : 1; draggable = typeof draggable !== 'undefined' ? draggable : 1;
} else if (typeof this.dropContent === 'string' && targetCollection) { } else if (typeof dropContent === 'string' && targetCollection) {
var sandboxOpts = {silent: true}; var sandboxModel = targetCollection.add(dropContent);
var sandboxModel = targetCollection.add(this.dropContent, sandboxOpts); src = sandboxModel.view ? sandboxModel.view.el : src;
draggable = sandboxModel.get && sandboxModel.get('draggable'); draggable = sandboxModel.get && sandboxModel.get('draggable');
draggable = typeof draggable !== 'undefined' ? draggable : 1; draggable = typeof draggable !== 'undefined' ? draggable : 1;
targetCollection.remove(sandboxModel, sandboxOpts); targetCollection.remove(sandboxModel);
} }
if(draggable instanceof Array) { if (draggable instanceof Array) {
toDrag = draggable.join(', '); toDrag = draggable.join(', ');
draggable = this.matches(dst, toDrag); draggable = this.matches(dst, toDrag);
}else if(typeof draggable === 'string') { } else if (typeof draggable === 'string') {
toDrag = draggable; toDrag = draggable;
draggable = this.matches(dst, toDrag, 1); draggable = this.matches(dst, toDrag, 1);
} }
@ -737,29 +804,30 @@ module.exports = Backbone.View.extend({
var accepted = 1; var accepted = 1;
var droppable = targetModel && targetModel.get ? targetModel.get('droppable') : 1; var droppable = targetModel && targetModel.get ? targetModel.get('droppable') : 1;
var toDrop = draggable; var toDrop = draggable;
if(droppable instanceof Array) {
if (droppable instanceof Array) {
// When I drag blocks src is the HTMLElement of the block // When I drag blocks src is the HTMLElement of the block
toDrop = droppable.join(', '); toDrop = droppable.join(', ');
accepted = this.matches(src, toDrop); accepted = this.matches(src, toDrop);
}else if(typeof droppable === 'string') { } else if (typeof droppable === 'string') {
toDrop = droppable; toDrop = droppable;
accepted = this.matches(src, toDrop); accepted = src.matches(toDrop);
} }
if(targetCollection && droppable && accepted && draggable) { if(targetCollection && droppable && accepted && draggable) {
index = pos.method === 'after' ? index + 1 : index; index = pos.method === 'after' ? index + 1 : index;
var opts = {at: index, noIncrement: 1}; var opts = {at: index, noIncrement: 1};
if(!this.dropContent){ if(!dropContent){
modelTemp = targetCollection.add({}, opts); modelTemp = targetCollection.add({}, opts);
if(model) if(model)
modelToDrop = model.collection.remove(model); modelToDrop = model.collection.remove(model);
}else{ }else{
modelToDrop = this.dropContent; modelToDrop = dropContent;
opts.silent = false; opts.silent = false;
} }
created = targetCollection.add(modelToDrop, opts); created = targetCollection.add(modelToDrop, opts);
if(!this.dropContent){ if (!dropContent) {
targetCollection.remove(modelTemp); targetCollection.remove(modelTemp);
}else{ }else{
this.dropContent = null; this.dropContent = null;

Loading…
Cancel
Save