Browse Source

Clean select position command

pull/36/head
Artur Arseniev 10 years ago
parent
commit
70c43eabb2
  1. 2
      src/commands/view/CreateComponent.js
  2. 328
      src/commands/view/SelectPosition.js

2
src/commands/view/CreateComponent.js

@ -12,7 +12,6 @@ define(['backbone','./SelectPosition'],
tempComponent: { style:{} },
init: function(opt) {
SelectPosition.init.apply(this, arguments);
_.bindAll(this,'startDraw','draw','endDraw','rollback');
this.config = opt;
this.heightType = this.config.newFixedH ? 'height' : 'min-height';
@ -293,7 +292,6 @@ define(['backbone','./SelectPosition'],
},
stop: function(){
this.removePositionPlaceholder(); //Removes placeholder from eventSelectPosition
this.stopSelectPosition();
this.$el.css('cursor',''); //Changes back aspect of the cursor
this.$el.unbind(); //Removes all attached events

328
src/commands/view/SelectPosition.js

@ -1,37 +1,6 @@
define(function() {
/**
* @class SelectPosition
* @private
* */
return {
init: function(opt) {
_.bindAll(this,'selectingPosition','itemLeft');
this.config = opt;
},
/**
* Returns position placeholder
*
* @return {Object} Placeholder
* @private
* */
getPositionPlaceholder: function() {
return this.$plh;
},
/**
* Creates position placeholder
* @return {Object} Placeholder
* @private
* */
createPositionPlaceholder: function() {
this.$plh = $('<div>', { class: this.plhClass + " no-dots" })
.css({'pointer-events':'none'}).data('helper',1);
this.$plh.append( $('<div>', { class: this.plhClass + "-int no-dots" } ) );
this.$plh.appendTo( this.$wrapper );
return this.$plh;
},
return {
/**
* Start select position event
@ -49,7 +18,6 @@ define(function() {
pfx: this.ppfx,
direction: 'a',
nested: 1,
//onEndMove: this.onEndMove,
});
var offDim = this.getOffsetDim();
this.sorter.offTop = offDim.top;
@ -57,12 +25,17 @@ define(function() {
this.$wrapper.on('mousemove', this.selectingPosition);
},
getOffsetDim: function(){
/**
* Get frame position
* @return {Object}
* @private
*/
getOffsetDim: function() {
var frameOff = this.offset(this.canvas.getFrameEl());
var canvasOff = this.offset(this.canvas.getElement());
var bodyEl = this.getCanvasBody();
var top = frameOff.top - canvasOff.top; //- bodyEl.scrollTop
var left = frameOff.left - canvasOff.left;// - bodyEl.scrollLeft
var top = frameOff.top - canvasOff.top;
var left = frameOff.left - canvasOff.left;
return { top: top, left: left };
},
@ -88,280 +61,10 @@ define(function() {
},
/**
* During event
* @param {Object} e Event
* @private
* */
selectingPosition: function(e) {
this.isPointed = true;
if(!this.wp){
this.$wp = this.$wrapper;
this.wp = this.$wp[0];
}
var wpO = this.$wp.offset();
this.wpT = wpO.top;
this.wpL = wpO.left;
this.wpScT = this.$wp.scrollTop();
this.wpScL = this.$wp.scrollLeft();
if(!this.$plh)
this.createPositionPlaceholder();
this.rY = (e.pageY - this.wpT) + this.wpScT;
this.rX = (e.pageX - this.wpL) + this.wpScL;
this.entered(e);
this.updatePosition(this.rX, this.rY);
var actualPos = this.posIndex + ':' + this.posMethod; //save globally the new index
if(!this.lastPos || (this.lastPos != actualPos)){ //If there is a significant changes with mouse
this.updatePositionPlaceholder(this.posIndex, this.posMethod);
this.lastPos = actualPos;
}
},
/**
* Search where to put placeholder
* @param {Integer} posX X position of the mouse
* @param {Integer} posY Y position of the mouse
* @private
* */
updatePosition: function( posX, posY ){
this.posMethod = "before";
this.posIndex = 0;
var leftLimit = 0, xLimit = 0, dimRight = 0, yLimit = 0, xCenter = 0, yCenter = 0, dimDown = 0, dim = 0;
for(var i = 0; i < this.cDim.length; i++){
dim = this.cDim[i];
dimDown = dim[0] + dim[2];
yCenter = dim[0] + (dim[2] / 2); //Horizontal center
xCenter = dim[1] + (dim[3] / 2); //Vertical center
dimRight = dim[1] + dim[3];
if( (xLimit && dim[1] > xLimit) || (yLimit && yCenter > yLimit) ||
(leftLimit && dimRight < leftLimit)) //No need with this one if over the limit
continue;
if(!dim[4]){ //If it's not inFlow (like float element)
if( posY < dimDown)
yLimit = dimDown;
if( posX < xCenter){ //If mouse lefter than center
xLimit = xCenter;
this.posMethod = "before";
}else{
leftLimit = xCenter;
this.posMethod = "after";
}
this.posIndex = i;
}else{
this.posIndex = i;
if( posY < yCenter ){ //If mouse upper than center
this.posMethod = "before"; //Should place helper before
break; //No need to continue under inFlow element
}else
this.posMethod = "after";
}
}
if(this.posIndex == (this.cDim.length) && this.posMethod == 'after' ){
this.posIndex--;
}
},
/**
* Updates the position of the placeholder
* @param {Integer} index Index of the nearest child
* @param {String} method Before or after position
* @private
* */
updatePositionPlaceholder: function(index, method){
var t = 0, l = 0, w = 0, h = 0,
marg = 2,
un = 'px',
margI = 5,
plh = this.$plh[0];
if( this.cDim[index] ){
var elDim = this.cDim[index];
if(!elDim[4]){
w = 'auto';
t = elDim[0] + marg;
h = elDim[2] - (marg * 2) + un;
l = (method == 'before') ? (elDim[1] - marg) : (elDim[1] + elDim[3] - marg);
}else{
w = elDim[3] + un;
t = (method == 'before') ? (elDim[0] - marg) : (elDim[0] + elDim[2] - marg);
l = elDim[1];
h = 'auto';
}
//t -= this.wpScT;
//l -= this.wpScL;
}else{
if(this.$targetEl){
var trg = this.$targetEl[0],
$eO = this.$targetEl.offset();
t = $eO.top - this.wpT + this.wpScT + margI;
l = $eO.left - this.wpL + this.wpScL + margI;
w = (parseInt(trg.offsetWidth) - margI * 2) + un;
h = 'auto';
}
}
plh.style.top = t + un;
plh.style.left = l + un;
if(w)
plh.style.width = w;
if(h)
plh.style.height = h;
},
/**
* Track inside which element pointer entered
* @param {Object} e Event
* @private
* */
entered: function(e){
if( (!this.outsideElem || this.outsideElem != e.target) ){ //If I'm in the new element
this.outsideElem = e.target; //Set the element in which it's actually inside
this.$targetEl = $(e.target);
$(this.outsideElem).on('mouseleave',this.itemLeft);
this.cDim = this.getChildrenDim();
this.dimT = this.getTargetDim(e);
if( this.nearToBorders(e) && (e.target.parentNode!=this.wp.parentNode) ) //Avoid flickering
this.cDim = this.getChildrenDim(e.target.parentNode);
}else if( this.nearToBorders(e) && (e.target.parentNode!=this.wp.parentNode) ){ //Near to borders and parent is not the canvas
this.cDim = this.getChildrenDim(e.target.parentNode);
}else if( !(this.nearToBorders(e)) ){
this.cDim = this.getChildrenDim();
}
},
/**
* Check if pointer is near to the borders of the target
* @param {Object} e Event
* @return {Integer}
* @private
* */
nearToBorders: function(e){
var m = 7; //Limit in pixels for be near
if(!this.dimT)
return;
var dimT = this.dimT;
if(dimT[2] < 40)
m = 5;
if( ((dimT[0] + m) > this.rY) || (this.rY > (dimT[0] + dimT[2] - m)) ||
((dimT[1] + m) > this.rX) || (this.rX > (dimT[1] + dimT[3] - m)) ) //Check if the pointer is near
return 1;
else
return 0;
},
/**
* Check if pointer is near to the float component
* @return {Integer}
* @private
* */
nearToFloat: function() {
var index = this.posIndex;
var isLastEl = this.posIsLastEl;
if(this.cDim.length !== 0 && (
(!isLastEl && !this.cDim[index][4]) ||
(this.cDim[index-1] && !this.cDim[index-1][4]) ||
(isLastEl && !this.cDim[index-1][4]) ) )
return 1;
else
return 0;
},
/**
* Returns dimension of the taget
* @param {Object} e Event
* @return {Array}
* Enabel select position
* @private
* */
getTargetDim: function(e) {
var elT = e.target,
$el = $(elT);
return [ elT.offsetTop, elT.offsetLeft, $el.outerHeight(), $el.outerWidth() ];
},
/**
* Returns children and their dimensions of the target element,
* excluding text nodes and the move placeholder
* @param {Object} el Element
* @return {Array}
* @private
* */
getChildrenDim: function(el) {
var dim = [];
var elToPars = el || this.outsideElem;
var isInFlow = this.isInFlow; //Assign method for make it work inside $.each
var $this = this; //Store context
$(elToPars.childNodes).each(function(){
var $el = $(this);
if(this.nodeName != '#text' && !$el.data('helper') ){ //Ignore text nodes and helpers
dim.push( [ this.offsetTop, this.offsetLeft, $el.outerHeight(), $el.outerWidth(), isInFlow($this, this), this ] );
}
});
return dim;
},
/**
* Track when I go ouside of the element (basically when the target changes)
* @param {Object} e Event
* @private
* */
itemLeft: function(e) {
$(this.outsideElem).off('mouseleave',this.itemLeft);
this.outsideElem = null;
this.$targetEl = null;
this.lastPos = null;
},
/**
* Returns true if the elements is in flow, or better is not in flow where
* for example the component is with float:left
* @param {Object} $this Context
* @param {Object} elm Element
* @return {Boolean}
* @private
* */
isInFlow: function($this, elm) {
var $elm = $(elm), ch = -1;
if(!$elm.length)
return false;
if( ($elm.height() < ch) || !$this.okProps($elm) )
return false;
return true;
},
/**
* Returns true only if the element follow the standard flow
* @param {Object} $elm Element
* @return {Boolean}
* @private
* */
okProps: function($elm) {
if ($elm.css('float')!=='none')
return false;
switch($elm.css('position')) {
case 'static': case 'relative': break;
default: return false;
}
switch ($elm.css('display')) {
case 'block': case 'list-item': case 'table': return true;
}
return false;
},
/**
* Removes position placeholder
* @param void
* @private
* */
removePositionPlaceholder: function() {
if(this.$plh && this.$plh.length)
this.$plh.remove();
this.$plh = null;
},
enable: function(){
*/
enable: function() {
this.frameEl.contentWindow.onscroll = this.onFrameScroll.bind(this);
this.startSelectPosition();
},
@ -370,19 +73,18 @@ define(function() {
* On frame scroll callback
* @private
*/
onFrameScroll: function(e){
onFrameScroll: function(e) {
this.canvasTool.style.top = '-' + this.bodyEl.scrollTop + 'px';
this.canvasTool.style.left = '-' + this.bodyEl.scrollLeft + 'px';
},
run: function(){
run: function() {
this.enable();
},
stop: function(){
stop: function() {
this.frameEl.contentWindow.onscroll = null;
this.removePositionPlaceholder();
this.stopSelectPosition();
this.$wrapper.css('cursor','');//changes back aspect of the cursor
this.$wrapper.unbind();//removes all attached events

Loading…
Cancel
Save