Browse Source

Update move command using Sorter

pull/36/head
Artur Arseniev 10 years ago
parent
commit
4811e86b9b
  1. 18
      index.html
  2. 2
      src/commands/view/CommandAbstract.js
  3. 48
      src/commands/view/MoveComponent.js
  4. 1
      src/dom_components/view/ComponentView.js
  5. 1
      src/editor/model/Editor.js
  6. 87
      src/utils/Sorter.js
  7. 7
      styles/css/main.css
  8. 6
      styles/scss/main.scss
  9. 124
      test/specs/utils/Sorter.js

18
index.html

@ -29,7 +29,21 @@
<div class="lead-btn">Hover me</div>
</div>
</header>
<section class="flex-sect">
<div style="width:100px; height: 50px; float:left"></div>
<div style="width:150px; height: 75px; float:left"></div>
<div style="width:200px; height: 55px; float:left"></div>
<div style="width:100px; height: 50px; float:left"></div>
<div class="clearfix" style="width:350px; height: 50px;"></div>
<div class="clearfix" style="width:200px; height: 100px;"></div>
<div style="width:100px; height: 50px; float:left"></div>
<div style="width:150px; height: 75px; float:left"></div>
<div style="width:200px; height: 55px; float:left"></div>
<div style="width:100px; height: 50px; float:left"></div>
<div class="clearfix" style="width:350px; height: 50px;"></div>
<div class="clearfix" style="width:200px; height: 100px;"></div>
<div class="clearfix"></div>
</section>
<section class="flex-sect">
<div class="container-width">
<div class="flex-title">Flex is the new black</div>
@ -445,7 +459,7 @@
background-image:url("http://placehold.it/350x250/e868a2/fff/image6.jpg");
}
.card-body{
padding: 15px;
padding: 15px 15px 5px 15px;
color: #555;
}
.card-title{

2
src/commands/view/CommandAbstract.js

@ -17,9 +17,11 @@ define(['backbone'],
this.canvasId = this.config.canvasId || '';
this.wrapperId = this.config.wrapperId || 'wrapper';
this.pfx = this.config.stylePrefix;
this.ppfx = this.config.pStylePrefix;
this.hoverClass = this.pfx + 'hover';
this.badgeClass = this.pfx + 'badge';
this.plhClass = this.pfx + 'placeholder';
this.freezClass = this.ppfx + 'freezed';
if(this.editorModel.get)
this.setElement(this.editorModel.get('$editor').find('#'+this.canvasId));
this.$canvas = this.$el;

48
src/commands/view/MoveComponent.js

@ -8,7 +8,7 @@ define(['backbone', './SelectComponent','./SelectPosition'],
init: function(o){
SelectComponent.init.apply(this, arguments);
_.bindAll(this,'startMove','onMove','endMove','rollback','selectingPosition','itemLeft');
_.bindAll(this,'initSorter','startMove','onMove','endMove','rollback','selectingPosition','itemLeft', 'onEndMove');
this.opt = o;
this.hoverClass = this.pfx + 'hover-move';
this.badgeClass = this.pfx + 'badge-yellow';
@ -19,20 +19,38 @@ define(['backbone', './SelectComponent','./SelectPosition'],
this.canvasTop = this.$canvas.offset().top;
this.canvasLeft = this.$canvas.offset().left;
this.$el.css('cursor','move');
this.$el.on('mousedown', this.startMove);
//this.$el.on('mousedown', this.startMove);
this.$el.on('mousedown', this.initSorter);
this.startSelectComponent();
//Avoid strange moving behavior
this.$el.addClass(this.noSelClass);
},
/**
* Delegate sorting
* @param {Event} e
* */
initSorter: function(e){
if(this.sorter)
this.sorter.startSort(e.target);
this.stopSelectComponent(e);
this.$el.off('mousedown', this.initSorter);
},
/**
* Callback after sorting
*/
onEndMove: function(){
this.enable();
},
/**
* Hover command
* @param {Object} e
* @private
*/
onHover: function(e)
{
onHover: function(e) {
e.stopPropagation();
var $this = $(e.target);
@ -140,7 +158,7 @@ define(['backbone', './SelectComponent','./SelectPosition'],
* */
freezeComponent: function($component){
$component.css({'pointer-events':'none'});
$component.addClass('freezed');
$component.addClass(this.freezClass);
},
/** Make component touchable
@ -149,7 +167,7 @@ define(['backbone', './SelectComponent','./SelectPosition'],
* */
unfreezeComponent: function($component){
$component.css({'pointer-events':'auto'});
$component.removeClass('freezed');
$component.removeClass(this.freezClass);
},
/** Used to bring the previous situation before start moving the component
@ -179,7 +197,23 @@ define(['backbone', './SelectComponent','./SelectPosition'],
$(document).off('keypress', this.rollback);
},
run: function(){
run: function(editor, sender, opts){
this.editor = editor;
// Activate sorter, at any run? In layers, is called once at any stack
var utils = this.editor.Utils;
if(utils && utils.Sorter)
this.sorter = new utils.Sorter({
container: this.$el.get(0),
containerSel: '*',
itemSel: '*',
pfx: this.ppfx,
onEndMove: this.onEndMove,
direction: 'a',
nested: 1,
freezeClass: this.freezClass,
});
this.enable();
},

1
src/dom_components/view/ComponentView.js

@ -25,6 +25,7 @@ define(['backbone', './ComponentsView'],
this.listenTo(this.model.get('classes'), 'add remove change', this.updateClasses);
this.$el.data("model", this.model);
this.$el.data("model-comp", this.components);
this.$el.data("collection", this.components);
if(this.model.get('classes').length)
this.importClasses();

1
src/editor/model/Editor.js

@ -338,6 +338,7 @@ define([
initCommands: function() {
var cfg = this.config.commands,
pfx = cfg.stylePrefix || 'com-';
cfg.pStylePrefix = this.config.stylePrefix;
cfg.stylePrefix = this.config.stylePrefix + pfx;
cfg.em = this;
cfg.canvasId = this.config.idCanvas;

87
src/utils/Sorter.js

@ -18,6 +18,8 @@ define(['backbone'],
this.itemSel = o.itemSel || 'div';
this.nested = o.nested || 0;
this.pfx = o.pfx || '';
this.onEndMove = o.onEndMove || '';
this.direction = o.direction || 'v'; // v (vertical), h (horizontal), a (auto)
},
/**
@ -152,7 +154,16 @@ define(['backbone'],
if(!this.matches(el, this.itemSel))
continue;
var dim = this.getDim(el);
dim.push(true); //TODO check if in flow, now only for vertical elements
var dir = this.direction;
if(dir == 'v')
dir = true;
else if(dir == 'h')
dir = false;
else
dir = this.isInFlow(el, elem);
dim.push(dir);
dim.push(el);
dims.push(dim);
}
@ -169,6 +180,60 @@ define(['backbone'],
return [o.top - this.elT, o.left - this.elL, el.offsetHeight, el.offsetWidth];
},
/**
* Returns true if the elements is in flow, so is not in flow where
* for example the component is with float:left
* @param {HTMLElement} el
* @param {HTMLElement} parent
* @return {Boolean}
* @private
* */
isInFlow: function(el, parent) {
if(!el)
return false;
parent = parent || document.body;
var ch = -1, h;
var elem = el;
//while (elem !== document.body) {
h = elem.offsetHeight;
if (h < ch || !this.styleInFlow(elem, parent))
return false;
else
return true;
},
/**
* Check if el has style to be in flow
* @param {HTMLElement} el
* @param {HTMLElement} parent
* @return {Boolean}
* @private
*/
styleInFlow: function(el, parent) {
var style = el.style;
if (style.float && style.float !== 'none')
return;
if (style.overflow && style.overflow !== 'visible')
return;
if(parent && $(parent).css('display') == 'flex')
return;
switch (style.position) {
case 'static': case 'relative': case '':
break;
default:
return;
}
var disp = $(el).css('display');
switch (disp) {
case 'block':
case 'list-item':
case 'table':
return true;
}
return;
},
/**
* Get dimensions of nodes relative to the coordinates
* @param {HTMLElement} target
@ -315,9 +380,8 @@ define(['backbone'],
t = elDim[0] + marg;
l = (method == 'before') ? (elDim[1] - marg) : (elDim[1] + elDim[3] - marg);
}else{
//w = '100%';
w = elDim[3] + un;
//h = elDim[3] + un;
h = 'auto';
t = (method == 'before') ? (elDim[0] - marg) : (elDim[0] + elDim[2] - marg);
l = elDim[1];
}
@ -327,9 +391,10 @@ define(['backbone'],
return;
}
if(trgDim){
t = trgDim[0] + margI + 17;
l = trgDim[1] + margI * 7;
w = (parseInt(trgDim[3]) - margI * 14) + un;
t = trgDim[0] + margI;
l = trgDim[1] + margI;
w = (parseInt(trgDim[3]) - margI * 2) + un;
h = 'auto';
}
}
plh.style.top = t + un;
@ -355,6 +420,9 @@ define(['backbone'],
this.eV.className = this.eV.className.replace(clsReg, '');
if(this.moved)
this.move(this.target, this.eV, this.lastPos);
if(typeof this.onEndMove === 'function')
this.onEndMove();
},
/**
@ -367,9 +435,12 @@ define(['backbone'],
var index = pos.index;
var model = $(src).data('model');
var collection = model.collection;
var targetCollection = $(dst).data('collection');
var $dst = $(dst);
var targetCollection = $dst.data('collection');
var targetModel = $dst.data('model');
var droppable = targetModel ? targetModel.get('droppable') : 1;
if(targetCollection){// && targetModel.get('droppable')
if(targetCollection && droppable){ // TODO && targetModel.get('droppable')
index = pos.method === 'after' ? index + 1 : index;
var modelTemp = targetCollection.add({}, {at: index, noIncrement: 1});
var modelRemoved = model.collection.remove(model);

7
styles/css/main.css

@ -2602,6 +2602,11 @@ See http://bgrins.github.io/spectrum/themes/ for instructions.
height: 100%;
min-width: 1250px; }
.wte-freezed {
opacity: 0.5;
filter: alpha(opacity=50);
pointer-events: none; }
/************* CANVAS ****************/
.wte-cv-canvas {
position: absolute;
@ -2612,7 +2617,7 @@ See http://bgrins.github.io/spectrum/themes/ for instructions.
overflow: auto;
z-index: 1;
/* This simulate body behaviour */ }
.wte-cv-canvas > div {
.wte-cv-canvas > div:first-child {
background-color: #fff;
position: relative;
height: 100%;

6
styles/scss/main.scss

@ -87,6 +87,10 @@ $imageCompDim: 50px;
height: 100%;
min-width: 1250px;
}
.#{$app-prefix}freezed{
@include opacity(0.50);
pointer-events: none;
}
/************* CANVAS ****************/
.#{$cv-prefix}canvas {
position: absolute;
@ -97,7 +101,7 @@ $imageCompDim: 50px;
z-index:1;
/* This simulate body behaviour */
> div {
> div:first-child {
background-color: #fff;
position: relative;
height: 100%;

124
test/specs/utils/Sorter.js

@ -11,6 +11,7 @@ define([path + 'Sorter',],
var obj;
var parent;
var plh;
var html;
before(function () {
fixture = $('<div class="sorter-fixture"></div>').get(0);
@ -24,11 +25,38 @@ define([path + 'Sorter',],
obj = new Sorter({container: '.parent1'});
document.body.appendChild(fixture);
fixture.appendChild(parent);
html = '<div id="el1" style="overflow: hidden;">'+
'<div id="el2">ba' +
'<p id="baa">baa</p>' +
'<span id="elspan">bab</span>' +
'<span id="bac" style="display:block;">bac</span>'+
'<div id="eldiv">eldiv</div>'+
'</div>' +
'</div>' +
'<div id="a">' +
'<div id="aa">aa' +
'<p id="aaa">aaa</p>' +
'<span id="aab">aab</span>' +
'<span id="aac" style="display:block;">aac</span>' +
'</div>' +
'<div id="ab" style="float: left;">ab</div>' +
'<div id="ac" style="position: absolute;">ac' +
'<div id="aca" style="float: left;">aca</div>' +
'<div id="acb">acb</div>' +
'</div>' +
'<div id="ad" style="overflow: hidden;">ad' +
'<p id="ada">ada</p>' +
'<span id="adb">adb</span>' +
'<span id="adc" style="display:block;">adc</span>' +
'</div>' +
'</div>';
});
afterEach(function () {
document.body.removeChild(fixture);
delete obj;
delete parent;
delete html;
});
it('matches class', function() {
@ -61,6 +89,102 @@ define([path + 'Sorter',],
obj.createPlaceholder().className.should.equal('placeholder');
});
it('isInFlow to overflow hidden', function(){
parent.innerHTML = html;
var el = parent.querySelector('#el1');
obj.isInFlow(el).should.equal(false);
});
it('isInFlow inner to overflow', function(){
parent.innerHTML = html;
var el = parent.querySelector('#el2');
if(!el){
console.log('phantom issue');
return;
}
obj.isInFlow(el).should.equal(true);
});
it('isInFlow for span', function(){
parent.innerHTML = html;
var el = parent.querySelector('#elspan');
obj.isInFlow(el).should.equal(false);
});
it('isInFlow for div #a', function(){
parent.innerHTML = html;
var el = parent.querySelector('#a');
if(!el){
console.log('phantom issue');
return;
}
obj.isInFlow(el).should.equal(true);
});
it('isInFlow for div #aa', function(){
parent.innerHTML = html;
var el = parent.querySelector('#aa');
if(!el){
console.log('phantom issue');
return;
}
obj.isInFlow(el).should.equal(true);
});
it('isInFlow for p #aaa', function(){
parent.innerHTML = html;
var el = parent.querySelector('#aaa');
if(!el){
console.log('phantom issue');
return;
}
obj.isInFlow(el).should.equal(true);
});
it('isInFlow for span #aab', function(){
parent.innerHTML = html;
var el = parent.querySelector('#aab');
obj.isInFlow(el).should.equal(false);
});
it('isInFlow for span #aac with display block', function(){
parent.innerHTML = html;
var el = parent.querySelector('#aac');
if(!el) // in phantom doesnt work
return;
obj.isInFlow(el).should.equal(true);
});
it('isInFlow for div #ab with float left', function(){
parent.innerHTML = html;
var el = parent.querySelector('#ab');
obj.isInFlow(el).should.equal(false);
});
it('isInFlow for div #ac in absolute', function(){
parent.innerHTML = html;
var el = parent.querySelector('#ac');
obj.isInFlow(el).should.equal(false);
});
it('isInFlow for div #acb inside absolute', function(){
parent.innerHTML = html;
var el = parent.querySelector('#acb');
if(!el){
console.log('phantom issue');
return;
}
obj.isInFlow(el).should.equal(true);
});
it('isInFlow for div #ad overflow hidden', function(){
parent.innerHTML = html;
var el = parent.querySelector('#ad');
obj.isInFlow(el).should.equal(false);
});
describe('Closest method', function() {
var parent2;
var parent3;

Loading…
Cancel
Save