Browse Source

Add textable in Sorter

pull/2031/head
Artur Arseniev 8 years ago
parent
commit
e468a172b9
  1. 156
      src/utils/Sorter.js

156
src/utils/Sorter.js

@ -1,6 +1,6 @@
import Backbone from 'backbone'; import Backbone from 'backbone';
import { isString, isFunction, isArray, result } from 'underscore'; import { isString, isFunction, isArray, result } from 'underscore';
import { on, off, matches, getElement } from 'utils/mixins'; import { on, off, matches, getElement, getPointerEvent } from 'utils/mixins';
const $ = Backbone.$; const $ = Backbone.$;
module.exports = Backbone.View.extend({ module.exports = Backbone.View.extend({
@ -51,6 +51,7 @@ module.exports = Backbone.View.extend({
this.canvasRelative = o.canvasRelative || 0; this.canvasRelative = o.canvasRelative || 0;
this.selectOnEnd = !o.avoidSelectOnEnd; this.selectOnEnd = !o.avoidSelectOnEnd;
this.scale = o.scale; this.scale = o.scale;
this.activeTextModel = null;
if (this.em && this.em.on) { if (this.em && this.em.on) {
this.em.on('change:canvasOffset', this.udpateOffset); this.em.on('change:canvasOffset', this.udpateOffset);
@ -96,6 +97,39 @@ module.exports = Backbone.View.extend({
this.dropContent = content; this.dropContent = content;
}, },
updateTextViewCursorPosition(e) {
const { em } = this;
const Canvas = em.get('Canvas');
const targetDoc = Canvas.getDocument();
const poiner = getPointerEvent(e);
let range = null;
if (targetDoc.caretRangeFromPoint) {
// Chrome
range = targetDoc.caretRangeFromPoint(poiner.clientX, poiner.clientY);
} else if (e.rangeParent) {
// Firefox
range = targetDoc.createRange();
range.setStart(e.rangeParent, e.rangeOffset);
}
const sel = Canvas.getWindow().getSelection();
Canvas.getFrameEl().focus();
sel.removeAllRanges();
sel.addRange(range);
},
disableEditingOn(model) {
model && model.getView().disableEditing();
},
setContentEditable(model, mode) {
if (model) {
const el = model.getEl();
if (el.contentEditable != mode) el.contentEditable = mode;
}
},
/** /**
* Toggle cursor while sorting * Toggle cursor while sorting
* @param {Boolean} active * @param {Boolean} active
@ -359,7 +393,8 @@ module.exports = Backbone.View.extend({
* @param {Event} e * @param {Event} e
* */ * */
onMove(e) { onMove(e) {
const em = this.em; const ev = e;
const { em, onMoveClb, activeTextModel } = this;
this.moved = 1; this.moved = 1;
// Turn placeholder visibile // Turn placeholder visibile
@ -385,6 +420,7 @@ module.exports = Backbone.View.extend({
this.eventMove = e; this.eventMove = e;
//var targetNew = this.getTargetFromEl(e.target); //var targetNew = this.getTargetFromEl(e.target);
const sourceModel = this.getSourceModel();
const dims = this.dimsFromTarget(e.target, rX, rY); const dims = this.dimsFromTarget(e.target, rX, rY);
const target = this.target; const target = this.target;
const targetModel = this.getTargetModel(target); const targetModel = this.getTargetModel(target);
@ -392,26 +428,39 @@ module.exports = Backbone.View.extend({
if (!targetModel) plh.style.display = 'none'; if (!targetModel) plh.style.display = 'none';
this.lastDims = dims; this.lastDims = dims;
var pos = this.findPosition(dims, rX, rY); const pos = this.findPosition(dims, rX, rY);
// If there is a significant changes with the pointer
if ( if (this.isTextableActive(sourceModel, targetModel)) {
!this.lastPos || this.activeTextModel = targetModel;
(this.lastPos.index != pos.index || this.lastPos.method != pos.method) this.setContentEditable(targetModel, true);
) {
this.movePlaceholder(this.plh, dims, pos, this.prevTargetDim);
if (!this.$plh) this.$plh = $(this.plh);
// With canvasRelative the offset is calculated automatically for
// each element
if (!this.canvasRelative) {
if (this.offTop) this.$plh.css('top', '+=' + this.offTop + 'px');
if (this.offLeft) this.$plh.css('left', '+=' + this.offLeft + 'px');
}
plh.style.display = 'none';
this.lastPos = pos; this.lastPos = pos;
this.updateTextViewCursorPosition(ev);
} else {
this.disableTextable();
this.activeTextModel = null;
// If there is a significant changes with the pointer
if (
!this.lastPos ||
(this.lastPos.index != pos.index || this.lastPos.method != pos.method)
) {
this.movePlaceholder(this.plh, dims, pos, this.prevTargetDim);
if (!this.$plh) this.$plh = $(this.plh);
// With canvasRelative the offset is calculated automatically for
// each element
if (!this.canvasRelative) {
if (this.offTop) this.$plh.css('top', '+=' + this.offTop + 'px');
if (this.offLeft) this.$plh.css('left', '+=' + this.offLeft + 'px');
}
this.lastPos = pos;
}
} }
if (typeof this.onMoveClb === 'function') this.onMoveClb(e); isFunction(onMoveClb) && onMoveClb(e);
em && em &&
em.trigger('sorter:drag', { em.trigger('sorter:drag', {
@ -424,6 +473,15 @@ module.exports = Backbone.View.extend({
}); });
}, },
isTextableActive(src, trg) {
return src && src.get('textable') && trg && trg.is('text');
},
disableTextable() {
const { activeTextModel } = this;
activeTextModel && this.setContentEditable(activeTextModel, false);
},
/** /**
* Returns true if the elements is in flow, so is not in flow where * Returns true if the elements is in flow, so is not in flow where
* for example the component is with float:left * for example the component is with float:left
@ -512,20 +570,35 @@ module.exports = Backbone.View.extend({
return result; return result;
} }
// check if the source is draggable in target
let draggable = srcModel.get('draggable');
draggable = draggable instanceof Array ? draggable.join(', ') : draggable;
result.dragInfo = draggable;
draggable = isString(draggable) ? this.matches(trg, draggable) : draggable;
result.draggable = draggable;
// Check if the target could accept the source // Check if the target could accept the source
let droppable = trgModel.get('droppable'); let droppable = trgModel.get('droppable');
droppable = droppable instanceof Backbone.Collection ? 1 : droppable; droppable = droppable instanceof Backbone.Collection ? 1 : droppable;
droppable = droppable instanceof Array ? droppable.join(', ') : droppable; droppable = droppable instanceof Array ? droppable.join(', ') : droppable;
result.dropInfo = droppable; result.dropInfo = droppable;
droppable = isString(droppable) ? this.matches(src, droppable) : droppable; droppable = isString(droppable) ? this.matches(src, droppable) : droppable;
droppable =
trgModel.is('text') && draggable && srcModel.get('textable')
? 1
: droppable;
result.droppable = droppable; result.droppable = droppable;
// check if the source is draggable in target console.log(
let draggable = srcModel.get('draggable'); `trgModel.is('text')`,
draggable = draggable instanceof Array ? draggable.join(', ') : draggable; trgModel.is('text'),
result.dragInfo = draggable; `srcModel.get('textable')`,
draggable = isString(draggable) ? this.matches(trg, draggable) : draggable; srcModel.get('textable'),
result.draggable = draggable; 'droppable',
droppable,
'draggable',
draggable
);
if (!droppable || !draggable) { if (!droppable || !draggable) {
result.valid = false; result.valid = false;
@ -953,6 +1026,7 @@ module.exports = Backbone.View.extend({
this.dragHelper = null; this.dragHelper = null;
} }
this.disableTextable();
this.selectTargetModel(); this.selectTargetModel();
this.toggleSortCursor(); this.toggleSortCursor();
@ -967,7 +1041,7 @@ module.exports = Backbone.View.extend({
* @param {Object} pos Object with position coordinates * @param {Object} pos Object with position coordinates
* */ * */
move(dst, src, pos) { move(dst, src, pos) {
var em = this.em; const { em, activeTextModel } = this;
const srcEl = getElement(src); const srcEl = getElement(src);
em && em.trigger('component:dragEnd:before', dst, srcEl, pos); // @depricated em && em.trigger('component:dragEnd:before', dst, srcEl, pos); // @depricated
var warns = []; var warns = [];
@ -981,8 +1055,21 @@ module.exports = Backbone.View.extend({
var dropInfo = validResult.dropInfo; var dropInfo = validResult.dropInfo;
var dragInfo = validResult.dragInfo; var dragInfo = validResult.dragInfo;
var dropContent = this.dropContent; var dropContent = this.dropContent;
droppable = const { trgModel } = validResult;
validResult.trgModel instanceof Backbone.Collection ? 1 : droppable; droppable = trgModel instanceof Backbone.Collection ? 1 : droppable;
const modelIsTextable = model.get('textable');
const targetIsTextView = trgModel && trgModel.is('text');
console.log(
'droppable',
droppable,
'draggable',
draggable,
'modelIsTextable',
modelIsTextable,
'targetIsTextView',
targetIsTextView
);
if (targetCollection && droppable && draggable) { if (targetCollection && droppable && draggable) {
index = pos.method === 'after' ? index + 1 : index; index = pos.method === 'after' ? index + 1 : index;
@ -993,7 +1080,7 @@ module.exports = Backbone.View.extend({
opts.temporary = 1; opts.temporary = 1;
modelTemp = targetCollection.add({}, { ...opts }); modelTemp = targetCollection.add({}, { ...opts });
if (model) { if (model.collection) {
modelToDrop = model.collection.remove(model, { temporary: 1 }); modelToDrop = model.collection.remove(model, { temporary: 1 });
} }
} else { } else {
@ -1002,7 +1089,14 @@ module.exports = Backbone.View.extend({
opts.avoidUpdateStyle = 1; opts.avoidUpdateStyle = 1;
} }
created = targetCollection.add(modelToDrop, opts); if (targetIsTextView && modelIsTextable) {
const viewActive = activeTextModel.getView();
activeTextModel.trigger('active');
const { activeRte } = viewActive;
activeRte.insertHTML && activeRte.insertHTML(model.toHTML());
} else {
created = targetCollection.add(modelToDrop, opts);
}
if (!dropContent) { if (!dropContent) {
targetCollection.remove(modelTemp); targetCollection.remove(modelTemp);
@ -1010,6 +1104,10 @@ module.exports = Backbone.View.extend({
this.dropContent = null; this.dropContent = null;
} }
if (targetIsTextView && modelIsTextable) {
this.disableEditingOn(activeTextModel); // TODO disableEditingOn is used only here
}
// This will cause to recalculate children dimensions // This will cause to recalculate children dimensions
this.prevTarget = null; this.prevTarget = null;
} else { } else {

Loading…
Cancel
Save