redo Drag class

This commit is contained in:
Alex Pankratov
2021-04-01 19:12:43 +02:00
parent 4e4ad68843
commit d3bfc83fcb

View File

@@ -555,6 +555,7 @@
overflow: hidden; overflow: hidden;
line-height: 22px; line-height: 22px;
padding-top: 0; padding-top: 0;
padding-bottom: 11px;
} }
/***/ /***/
@@ -1055,7 +1056,7 @@
} }
.fsize-z1 .dragster.collapsed { .fsize-z1 .dragster.collapsed {
line-height: 24px; line-height: 25px;
} }
.fsize-z1 .board .note .ops { .fsize-z1 .board .note .ops {
@@ -1242,7 +1243,7 @@
{ {
this.type = '?'; this.type = '?';
this.conf = null; this.conf = new AppConfig();
this.boardIndex = new Map(); this.boardIndex = new Map();
} }
@@ -1501,8 +1502,6 @@
{ {
var conf = this.getJson('config'); var conf = this.getJson('config');
this.conf = new AppConfig();
if (conf && (conf.format != NB.confVersion)) if (conf && (conf.format != NB.confVersion))
{ {
if (! confirm('Preferences are stored in an unsupported format. Reset them?')) if (! confirm('Preferences are stored in an unsupported format. Reset them?'))
@@ -1633,21 +1632,6 @@
} }
} }
function _rollback()
{
localStorage.removeItem('nullboard.config');
var metas = [];
for (var i=0; i<localStorage.length; i++)
{
var m = localStorage.key(i).match(/^nullboard\.board\.(\d+)\.meta$/);
if (m) metas.push(m[0]);
}
for (var k of metas) localStorage.removeItem(k);
}
</script> </script>
<script type="text/javascript"> <script type="text/javascript">
@@ -1692,35 +1676,42 @@
<script type="text/javascript"> <script type="text/javascript">
function Drag() function Drag2()
{ {
this.item = null; // .text of .note // config
this.org_loc = 0; // original noteLocation(); this.listSel = null;
this.priming = null; this.itemSel = null;
this.primexy = { x: 0, y: 0 }; this.onDragging = function(started) { }
this.$drag = null; this.swapAnimMs = 200;
this.mouse = null;
this.delta = { x: 0, y: 0 };
this.in_swap = false;
// state
this.item = null;
this.priming = null;
this.primeXY = { x: 0, y: 0 };
this.$drag = null;
this.mouseEv = null;
this.delta = { x: 0, y: 0 };
this.inSwap = 0;
// api
this.prime = function(item, ev) this.prime = function(item, ev)
{ {
var self = this; var self = this;
this.item = item; this.item = item;
this.priming = setTimeout(function(){ self.onPrimed.call(self); }, ev.altKey ? 1 : 500); this.priming = setTimeout(function(){ self.onPrimed.call(self); }, ev.altKey ? 1 : 500);
this.primexy.x = ev.clientX; this.primeXY = { x: ev.clientX, y: ev.clientY };
this.primexy.y = ev.clientY; this.mouseEv = ev;
this.mouse = ev;
} }
this.cancelPriming = function() this.cancelPriming = function()
{ {
if (this.item && this.priming) if (! this.item || ! this.priming)
{ return;
clearTimeout(this.priming);
this.priming = null; clearTimeout(this.priming);
this.item = null; this.priming = null;
} this.item = null;
} }
this.end = function() this.end = function()
@@ -1736,36 +1727,34 @@
this.onPrimed = function() this.onPrimed = function()
{ {
console.log('onPrimed');
clearTimeout(this.priming); clearTimeout(this.priming);
this.priming = null; this.priming = null;
this.item.was_dragged = true;
var $text = $(this.item); removeTextSelection();
var $note = $text.parent();
$note.addClass('dragging');
this.org_loc = noteLocation($note); var $item = $(this.item);
$item.addClass('dragging');
$('body').append('<div class=dragster></div>'); $('body').append('<div class=dragster></div>');
var $drag = $('body .dragster').last(); var $drag = $('body .dragster').last();
if ($note.hasClass('collapsed')) $drag.innerWidth ( $item.innerWidth() );
$drag.addClass('collapsed'); $drag.innerHeight( $item.innerHeight() );
$drag.html( $text.html() );
$drag.innerWidth ( $note.innerWidth() );
$drag.innerHeight( $note.innerHeight() );
this.$drag = $drag; this.$drag = $drag;
if (this.onDragging)
this.onDragging.call(this, true); // started
var $win = $(window); var $win = $(window);
var scroll_x = $win.scrollLeft(); var scroll_x = $win.scrollLeft();
var scroll_y = $win.scrollTop(); var scroll_y = $win.scrollTop();
var pos = $note.offset(); var pos = $item.offset();
this.delta.x = pos.left - this.mouse.clientX - scroll_x; this.delta.x = pos.left - this.mouseEv.clientX - scroll_x;
this.delta.y = pos.top - this.mouse.clientY - scroll_y; this.delta.y = pos.top - this.mouseEv.clientY - scroll_y;
this.adjustDrag(); this.adjustDrag();
$drag.css({ opacity: 1 }); $drag.css({ opacity: 1 });
@@ -1778,163 +1767,194 @@
if (! this.$drag) if (! this.$drag)
return; return;
var drag = this;
var $drag = this.$drag;
var $win = $(window); var $win = $(window);
var scroll_x = $win.scrollLeft(); var scroll_x = $win.scrollLeft();
var scroll_y = $win.scrollTop(); var scroll_y = $win.scrollTop();
var drag_x = this.mouse.clientX + this.delta.x + scroll_x; var drag_x = drag.mouseEv.clientX + drag.delta.x + scroll_x;
var drag_y = this.mouse.clientY + this.delta.y + scroll_y; var drag_y = drag.mouseEv.clientY + drag.delta.y + scroll_y;
this.$drag.offset({ left: drag_x, top: drag_y }); $drag.offset({ left: drag_x, top: drag_y });
if (this.in_swap) if (drag.inSwap)
return; return;
/* /*
* see if a swap is in order * see if a swap is in order
*/ */
var pos = this.$drag.offset(); var pos = $drag.offset();
var x = pos.left + this.$drag.width()/2 - $win.scrollLeft(); var x = pos.left + $drag.width()/2 - $win.scrollLeft();
var y = pos.top + this.$drag.height()/2 - $win.scrollTop(); var y = pos.top + $drag.height()/2 - $win.scrollTop();
var drag = this;
var prepend = null; // if dropping on the list header
var target = null; // if over some item var target = null; // if over some item
var before = false; // if should go before that item var before = false; // if should go before that item
$(".board .list").each(function(){ $(this.listSel).each(function(){
var list = this; var list = this;
var rc = list.getBoundingClientRect(); var rcList = list.getBoundingClientRect();
var y_min = rc.bottom; var yTop, itemTop = null;
var n_min = null; var yBottom, itemBottom = null;
if (x <= rc.left || rc.right <= x || y <= rc.top || rc.bottom <= y) if (x <= rcList.left || rcList.right <= x)
return; return;
var $list = $(list); $(list).find(drag.itemSel).each(function(){
var rcItem = this.getBoundingClientRect();
$list.find('.note').each(function(){ if (! itemTop || rcItem.top < yTop)
var note = this;
var rc = note.getBoundingClientRect();
if (rc.top < y_min)
{ {
y_min = rc.top; itemTop = this;
n_min = note; yTop = rcItem.top;
} }
if (y <= rc.top || rc.bottom <= y) if (! itemBottom || yBottom < rcItem.bottom)
{
itemBottom = this;
yBottom = rcItem.bottom;
}
if (y <= rcItem.top || rcItem.bottom <= y)
return; return;
if (note == drag.item.parentNode) if (this == drag.item)
return; return;
target = note; target = this;
before = (y < (rc.top + rc.bottom)/2); before = (y < (rcItem.top + rcItem.bottom)/2);
}); });
/* if (y < rcList.top)
* dropping on the list header
*/
if (! target && y < y_min)
{ {
if (n_min) // non-empty list target = itemTop;
{ before = true;
target = n_min;
before = true;
}
else
{
prepend = list;
}
} }
else
if (y >= rcList.bottom)
{
target = itemBottom;
before = false;
}
}); });
if (! target && ! prepend) if (! target)
return; return;
if (target) if (target == drag.item)
{ return;
if (target == drag.item.parentNode)
return;
if (! before && target.nextSibling == drag.item.parentNode || if (! before && $(target).next()[0] == drag.item ||
before && target.previousSibling == drag.item.parentNode) before && $(target).prev()[0] == drag.item)
return; return;
}
else
{
if (prepend.firstChild == drag.item.parentNode)
return;
}
/* /*
* swap 'em * swap 'em
*/ */
var $have = $(this.item.parentNode); var $target = $(target);
var have = drag.item;
var $have = $(have);
var $want = $have.clone(); var $want = $have.clone();
$want.css({ display: 'none' }); $want.css({ display: 'none' });
if (target) if (before)
{ {
var $target = $(target); $want.insertBefore($target);
$want = $target.prev();
if (before)
{
$want.insertBefore($target);
$want = $target.prev();
}
else
{
$want.insertAfter($target);
$want = $target.next();
}
drag.item = $want.find('.text')[0];
} }
else else
{ {
var $notes = $(prepend).find('.notes'); $want.insertAfter($target);
$want = $target.next();
$notes.prepend($want);
drag.item = $notes.find('.note .text')[0];
} }
// drag.item = $want[0];
var h = $have.height();
drag.in_swap = true; if (! drag.swapAnimMs)
{
$have.remove();
$want.show();
return;
}
$want.css({ display: 'block', height: 0, marginTop: 0 }); /*
* see if it's a same-list move
*/
if (target.parentNode == have.parentNode)
{
var delta = $have.offset().top - $target.offset().top;
var d_bulk = 0;
var d_have = 0;
var $bulk = $();
if (delta < 0) // item is moving down
{
for (var $i = $have.next(); $i.length && $i[0] != $want[0]; $i = $i.next())
$bulk = $bulk.add($i);
}
else
{
for (var $i = $want.next(); $i.length && $i[0] != $have[0]; $i = $i.next())
$bulk = $bulk.add($i);
}
d_bulk = $have.outerHeight(true);
d_have = $bulk.last().offset().top + $bulk.last().outerHeight(true) - $bulk.first().offset().top;
if (delta < 0) d_bulk = -d_bulk;
else d_have = -d_have;
$have.parent().css({ position: 'relative' });
$have.css({ position: 'relative', 'z-index': 0 });
$bulk.css({ position: 'relative', 'z-index': 1 });
drag.inSwap = 1 + $bulk.length;
$have.animate({ top: d_have }, drag.swapAnimMs, function(){ if (! --drag.inSwap) swapCleanUp(); });
$bulk.animate({ top: d_bulk }, drag.swapAnimMs, function(){ if (! --drag.inSwap) swapCleanUp(); });
function swapCleanUp()
{
$have.parent().css({ position: '' });
$want.animate({ height: h }, {
duration: 'fast',
progress: function() {
$have.height( h - $(this).height() );
},
complete: function() {
$have.remove(); $have.remove();
$want.css({ marginTop: 5, opacity: '', height: '' }); $want.show();
drag.in_swap = false; $bulk.css({ position: '', 'z-index': '', top: '' });
drag.adjustDrag(); drag.adjustDrag();
} }
}); }
else
{
drag.inSwap = 1;
$want.slideDown(drag.swapAnimMs);
$have.slideUp(drag.swapAnimMs, function() {
$have.remove();
drag.inSwap = 0;
drag.adjustDrag();
});
}
} }
this.onMouseMove = function(ev) this.onMouseMove = function(ev)
{ {
this.mouse = ev; this.mouseEv = ev;
if (! this.item) if (! this.item)
return; return;
if (this.priming) if (this.priming)
{ {
var x = ev.clientX - this.primexy.x; var x = ev.clientX - this.primeXY.x;
var y = ev.clientY - this.primexy.y; var y = ev.clientY - this.primeXY.y;
if (x*x + y*y > 5*5) if (x*x + y*y > 5*5)
this.onPrimed(); this.onPrimed();
} }
@@ -1946,11 +1966,9 @@
this.stopDragging = function() this.stopDragging = function()
{ {
var $text = $(this.item); var $item = $(this.item);
var $note = $text.parent();
$note.addClass('dragging');
$note.removeClass('dragging'); $item.removeClass('dragging');
$('body').removeClass('dragging'); $('body').removeClass('dragging');
if (this.$drag) if (this.$drag)
@@ -1958,12 +1976,10 @@
this.$drag.remove(); this.$drag.remove();
this.$drag = null; this.$drag = null;
if (window.getSelection) { window.getSelection().removeAllRanges(); } removeTextSelection();
else if (document.selection) { document.selection.empty(); }
var loc_now = noteLocation($note); if (this.onDragging)
if (loc_now != this.org_loc) this.onDragging.call(this, false); // stopped
saveBoard();
} }
this.item = null; this.item = null;
@@ -2582,6 +2598,12 @@
return $note.attr('_text'); return $note.attr('_text');
} }
function removeTextSelection()
{
if (window.getSelection) { window.getSelection().removeAllRanges(); }
else if (document.selection) { document.selection.empty(); }
}
/* /*
* inline editing * inline editing
*/ */
@@ -2846,7 +2868,34 @@
}; };
NB.storage = new Storage_Local(); NB.storage = new Storage_Local();
NB.drag = new Drag(), NB.drag = new Drag2();
NB.drag.listSel = '.board .list';
NB.drag.itemSel = '.note';
NB.drag.onDragging = function(started)
{
var drag = this;
var $note = $(drag.item);
if (started)
{
var $drag = drag.$drag;
if ($note.hasClass('collapsed'))
$drag.addClass('collapsed');
$drag.html( $note.find('.text').html() );
drag.org_loc = noteLocation($note);
if ($note.hasClass('collapsed'))
drag.$drag.addClass('collapsed');
}
else
{
if (drag.org_log != noteLocation($note))
saveBoard();
}
}
/* /*
* event handlers * event handlers
@@ -3101,7 +3150,7 @@
// //
$('.wrap').on('mousedown', '.board .note .text', function(ev){ $('.wrap').on('mousedown', '.board .note .text', function(ev){
NB.drag.prime(this, ev); NB.drag.prime(this.parentNode, ev);
}); });
$(document).on('mouseup', function(ev){ $(document).on('mouseup', function(ev){