2011-04-22 14:44:23 +04:00
|
|
|
|
/**
|
2014-08-18 16:54:23 +04:00
|
|
|
|
* Code for drag&drop and/or editing of SCRUM-like cards from Bugzilla
|
|
|
|
|
* License: Dual-license GPL 3.0+ or MPL 1.1+
|
|
|
|
|
* Author: (c) Vitaliy Filippov 2010-2011
|
|
|
|
|
*/
|
2011-04-22 02:34:13 +04:00
|
|
|
|
var pressedButton;
|
|
|
|
|
var pasteMode = false;
|
|
|
|
|
var ctrl = false;
|
|
|
|
|
var highlitCard;
|
|
|
|
|
var selectedcards = {};
|
|
|
|
|
var cuttedcards = [];
|
|
|
|
|
var cuttedids = [];
|
2011-04-22 14:44:23 +04:00
|
|
|
|
// Добавить карточки для багов с ID'шниками из поля addbugs
|
2011-04-22 02:34:13 +04:00
|
|
|
|
function addNewCards()
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
for (var i = idlist.length-1; i >= 0; i--)
|
|
|
|
|
{
|
|
|
|
|
if (idlist[i] === '')
|
|
|
|
|
idlist.pop();
|
|
|
|
|
else
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
var val = document.getElementById('addbugs').value;
|
|
|
|
|
var re = /(\d+)/g;
|
|
|
|
|
var m;
|
|
|
|
|
while (m = re.exec(val))
|
|
|
|
|
idlist.push(m[1]);
|
|
|
|
|
document.getElementById('idlist_value').value = idlist.join(',');
|
|
|
|
|
document.getElementById('scrumform').submit();
|
2011-04-22 02:34:13 +04:00
|
|
|
|
}
|
2011-04-22 14:44:23 +04:00
|
|
|
|
// Добавить пустую страницу
|
2011-04-22 02:34:13 +04:00
|
|
|
|
function addEmptyPage()
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
for (var i = 0; i < nr*nc; i++)
|
|
|
|
|
idlist.push('');
|
|
|
|
|
document.getElementById('idlist_value').value = idlist.join(',');
|
|
|
|
|
document.getElementById('scrumform').submit();
|
2011-04-22 02:34:13 +04:00
|
|
|
|
}
|
2011-04-22 14:44:23 +04:00
|
|
|
|
// Обработчик нажатия Enter на поле addbugs
|
2011-04-22 02:34:13 +04:00
|
|
|
|
function addNewIfEnter(ev)
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
if (ev.keyCode == 10 || ev.keyCode == 13)
|
|
|
|
|
{
|
|
|
|
|
addNewCards();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
2011-04-22 02:34:13 +04:00
|
|
|
|
}
|
2011-04-22 14:44:23 +04:00
|
|
|
|
// Удалить все карточки
|
|
|
|
|
function deleteAllCards()
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
idlist = [];
|
|
|
|
|
document.getElementById('idlist_value').value = idlist.join(',');
|
|
|
|
|
document.getElementById('pages').innerHTML = '';
|
|
|
|
|
document.getElementById('scrumform').submit();
|
2011-04-22 14:44:23 +04:00
|
|
|
|
}
|
|
|
|
|
// Сбросить состояние кнопок, выделение карточек, режим вставки
|
2011-04-22 02:34:13 +04:00
|
|
|
|
function resetAll()
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
if (pressedButton)
|
|
|
|
|
{
|
|
|
|
|
buttonHandler(null, pressedButton);
|
|
|
|
|
pressedButton = null;
|
|
|
|
|
}
|
|
|
|
|
deselectAll();
|
|
|
|
|
stopPaste();
|
|
|
|
|
return true;
|
2011-04-22 02:34:13 +04:00
|
|
|
|
}
|
2011-04-22 14:44:23 +04:00
|
|
|
|
// Снять выделение
|
2011-04-22 02:34:13 +04:00
|
|
|
|
function deselectAll()
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
for (var i in selectedcards)
|
|
|
|
|
{
|
|
|
|
|
var e = document.getElementById('cardtd_'+i);
|
|
|
|
|
e.className = 'cardtd';
|
|
|
|
|
}
|
|
|
|
|
selectedcards = {};
|
2011-04-22 02:34:13 +04:00
|
|
|
|
}
|
2011-04-22 14:44:23 +04:00
|
|
|
|
// Обработчик, пытающийся по иерархии найти кнопку (id=btn_*),
|
|
|
|
|
// и вызвать на ней buttonHandler
|
2011-04-22 02:34:13 +04:00
|
|
|
|
function guessButton(ev)
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
ev = DragMaster.fixEvent(ev);
|
|
|
|
|
var t;
|
|
|
|
|
if (t = searchButtonTarget(ev))
|
|
|
|
|
return buttonHandler(ev, t);
|
|
|
|
|
return true;
|
2011-04-22 02:34:13 +04:00
|
|
|
|
}
|
2011-04-22 14:44:23 +04:00
|
|
|
|
// Обработчик mousedown и mouseup на кнопках (id=btn_*)
|
2011-04-22 02:34:13 +04:00
|
|
|
|
function buttonHandler(ev, target)
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
if (!pressedButton)
|
|
|
|
|
{
|
|
|
|
|
pressedButton = target;
|
|
|
|
|
target.style.borderStyle = 'inset';
|
|
|
|
|
target.style.padding = '4px 2px 2px 4px';
|
|
|
|
|
}
|
|
|
|
|
else if (pressedButton == target)
|
|
|
|
|
{
|
|
|
|
|
target.style.borderStyle = 'outset';
|
|
|
|
|
target.style.padding = '3px';
|
|
|
|
|
pressedButton = null;
|
|
|
|
|
if (target.id == 'btn_cut')
|
|
|
|
|
deleteSelectedCards(true);
|
|
|
|
|
else if (target.id == 'btn_delete')
|
|
|
|
|
deleteSelectedCards(false);
|
|
|
|
|
else if (target.id == 'btn_paste')
|
|
|
|
|
pasteCards();
|
|
|
|
|
else if (target.id == 'btn_paste_beg')
|
|
|
|
|
doPasteCards(0);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
2011-04-22 02:34:13 +04:00
|
|
|
|
}
|
2011-04-22 18:01:22 +04:00
|
|
|
|
// Обработчик клика-выделения по карточке
|
2011-04-22 14:04:03 +04:00
|
|
|
|
function selectCard(ev, target)
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
var empty = isEmptyHash(selectedcards, target.id.substr(7));
|
|
|
|
|
if (pasteMode)
|
|
|
|
|
{
|
|
|
|
|
doPasteCards(id_to_coord(target.id)+1);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else if (ctrl || !selectedcards[target.id.substr(7)])
|
|
|
|
|
{
|
|
|
|
|
if (!ctrl)
|
|
|
|
|
deselectAll();
|
|
|
|
|
var issel = target.className == 'cardtd selected';
|
|
|
|
|
target.className = issel ? 'cardtd' : 'cardtd selected';
|
|
|
|
|
if (issel)
|
|
|
|
|
delete selectedcards[target.id.substr(7)];
|
|
|
|
|
else
|
|
|
|
|
selectedcards[target.id.substr(7)] = true;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
2011-04-22 02:34:13 +04:00
|
|
|
|
}
|
2011-04-22 18:01:22 +04:00
|
|
|
|
// Подсветка карточки в режиме вставки
|
2011-04-22 02:34:13 +04:00
|
|
|
|
function highlightCard(ev)
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
if (pasteMode)
|
|
|
|
|
{
|
|
|
|
|
ev = DragMaster.fixEvent(ev);
|
|
|
|
|
var t = searchCardTarget(ev);
|
|
|
|
|
t.className = 'cardtd highlight';
|
|
|
|
|
highlitCard = t;
|
|
|
|
|
}
|
2011-04-22 02:34:13 +04:00
|
|
|
|
}
|
2011-04-22 18:01:22 +04:00
|
|
|
|
// Снятие подсветки карточки в режиме вставки
|
2011-04-22 02:34:13 +04:00
|
|
|
|
function unlightCard(ev)
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
if (pasteMode)
|
|
|
|
|
{
|
|
|
|
|
ev = DragMaster.fixEvent(ev);
|
|
|
|
|
var t = searchCardTarget(ev);
|
|
|
|
|
t.className = 'cardtd';
|
|
|
|
|
}
|
2011-04-22 02:34:13 +04:00
|
|
|
|
}
|
2011-04-22 18:01:22 +04:00
|
|
|
|
// Преобразование номера в координаты [лист, строка, столбец]
|
2011-04-22 02:34:13 +04:00
|
|
|
|
function to_coord(i)
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
var to_k = Math.floor(i / nr / nc);
|
|
|
|
|
var to_i = Math.floor((i / nc) % nr);
|
|
|
|
|
var to_j = Math.floor(i % nc);
|
|
|
|
|
return [to_k, to_i, to_j];
|
2011-04-22 02:34:13 +04:00
|
|
|
|
}
|
2011-04-22 18:20:38 +04:00
|
|
|
|
// Преобразование номера в строку с координатами лист_строка_столбец
|
|
|
|
|
function to_coord_id(i)
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
return to_coord(i).join('_');
|
2011-04-22 18:20:38 +04:00
|
|
|
|
}
|
2011-04-22 18:01:22 +04:00
|
|
|
|
// Преобразование id элемента (.*лист_строка_столбец.*) в номер
|
2011-04-22 02:34:13 +04:00
|
|
|
|
function id_to_coord(id)
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
var m = /(\d+)_(\d+)_(\d+)/.exec(id.substr(7));
|
|
|
|
|
return (parseInt(m[1])*nr+parseInt(m[2]))*nc+parseInt(m[3]);
|
2011-04-22 02:34:13 +04:00
|
|
|
|
}
|
2011-04-22 14:44:23 +04:00
|
|
|
|
// Удалить(cut=0)/вырезать(cut=1) выделенные карточки
|
2011-04-22 02:34:13 +04:00
|
|
|
|
function deleteSelectedCards(cut)
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
var shift = 0;
|
|
|
|
|
var coord = 0;
|
|
|
|
|
var n = nr * nc * np;
|
|
|
|
|
if (cut)
|
2011-04-22 02:34:13 +04:00
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
cuttedcards = [];
|
|
|
|
|
cuttedids = [];
|
|
|
|
|
}
|
|
|
|
|
for (var k = 0; k < np; k++)
|
|
|
|
|
{
|
|
|
|
|
for (var i = 0; i < nr; i++)
|
2011-04-22 02:34:13 +04:00
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
for (var j = 0; j < nc; j++, coord++)
|
|
|
|
|
{
|
|
|
|
|
var s = selectedcards[k+'_'+i+'_'+j];
|
|
|
|
|
var e = document.getElementById('cardtd_'+k+'_'+i+'_'+j);
|
|
|
|
|
if (!e)
|
|
|
|
|
continue;
|
|
|
|
|
if (s)
|
|
|
|
|
{
|
|
|
|
|
if (cut)
|
|
|
|
|
{
|
|
|
|
|
cuttedcards.push(e.innerHTML);
|
|
|
|
|
cuttedids.push(idlist[coord]);
|
|
|
|
|
}
|
|
|
|
|
shift++;
|
|
|
|
|
}
|
|
|
|
|
else if (shift > 0)
|
|
|
|
|
{
|
|
|
|
|
var to = to_coord_id(coord-shift);
|
|
|
|
|
document.getElementById('cardtd_'+to).innerHTML = e.innerHTML;
|
|
|
|
|
idlist[coord-shift] = idlist[coord];
|
|
|
|
|
}
|
|
|
|
|
else if (coord + shift < n)
|
|
|
|
|
continue;
|
|
|
|
|
// во всех трёх случаях - если выделена для
|
|
|
|
|
// удаления, если перемещена в другую, или
|
|
|
|
|
// если находится в конце - очищаем
|
|
|
|
|
e.innerHTML = emptycell;
|
|
|
|
|
idlist[coord] = '';
|
|
|
|
|
}
|
2011-04-22 02:34:13 +04:00
|
|
|
|
}
|
|
|
|
|
}
|
2014-10-13 20:33:51 +04:00
|
|
|
|
if (cut && cuttedids.length)
|
|
|
|
|
document.getElementById('cut_status').innerHTML = 'Вырезано '+cuttedids.length+' карточек.';
|
|
|
|
|
deselectAll();
|
|
|
|
|
document.getElementById('idlist_value').value = idlist.join(',');
|
2011-04-22 02:34:13 +04:00
|
|
|
|
}
|
2011-04-22 14:44:23 +04:00
|
|
|
|
// Перейти в режим выбора места вставки вырезанных карточек
|
2011-04-22 02:34:13 +04:00
|
|
|
|
function pasteCards()
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
if (!pasteMode)
|
2011-04-22 02:34:13 +04:00
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
if (!cuttedids.length)
|
|
|
|
|
{
|
|
|
|
|
alert('Сначала выделите и вырежьте какие-нибудь карточки!');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
alert('Кликните на карточку, после которой нужно вставить вырезанное, либо на кнопку "В начало".');
|
|
|
|
|
deselectAll();
|
|
|
|
|
pasteMode = true;
|
|
|
|
|
document.getElementById('btn_paste_beg').style.display = '';
|
2011-04-22 02:34:13 +04:00
|
|
|
|
}
|
|
|
|
|
}
|
2011-04-22 14:44:23 +04:00
|
|
|
|
// Вставить вырезанные карточки в позицию coord
|
2011-04-22 02:34:13 +04:00
|
|
|
|
function doPasteCards(coord)
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
stopPaste();
|
|
|
|
|
var nx = cuttedids.length;
|
|
|
|
|
if (nx <= 0)
|
|
|
|
|
return;
|
|
|
|
|
if (!document.getElementById('cardtd_'+to_coord_id(coord)))
|
|
|
|
|
{
|
|
|
|
|
alert('Некуда вставлять');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
var n = nr * nc * np;
|
|
|
|
|
var from, to;
|
|
|
|
|
for (var i = n-nx-1; i >= coord; i--)
|
|
|
|
|
{
|
|
|
|
|
from = to_coord_id(i);
|
|
|
|
|
to = to_coord_id(i+nx);
|
|
|
|
|
if (document.getElementById('cardtd_'+from) &&
|
|
|
|
|
document.getElementById('cardtd_'+to))
|
|
|
|
|
{
|
|
|
|
|
document.getElementById('cardtd_'+to).innerHTML =
|
|
|
|
|
document.getElementById('cardtd_'+from).innerHTML;
|
|
|
|
|
idlist[i+nx] = idlist[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (var i = 0; i < nx; i++)
|
2014-09-24 16:53:55 +04:00
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
to = to_coord_id(i+coord);
|
|
|
|
|
document.getElementById('cardtd_'+to).innerHTML = cuttedcards[i];
|
|
|
|
|
document.getElementById('cardtd_'+to).className = 'cardtd selected';
|
|
|
|
|
idlist[i+coord] = cuttedids[i];
|
|
|
|
|
selectedcards[to] = true;
|
2014-09-24 16:53:55 +04:00
|
|
|
|
}
|
2014-10-13 20:33:51 +04:00
|
|
|
|
cuttedids = [];
|
|
|
|
|
cuttedcards = [];
|
|
|
|
|
document.getElementById('cut_status').innerHTML = '';
|
|
|
|
|
document.getElementById('idlist_value').value = idlist.join(',');
|
2011-04-22 02:34:13 +04:00
|
|
|
|
}
|
2011-04-22 14:44:23 +04:00
|
|
|
|
// Выйти из режима вставки
|
2011-04-22 02:34:13 +04:00
|
|
|
|
function stopPaste()
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
if (highlitCard)
|
|
|
|
|
highlitCard.className = 'cardtd';
|
|
|
|
|
document.getElementById('btn_paste_beg').style.display = 'none';
|
|
|
|
|
pasteMode = false;
|
2011-04-22 02:34:13 +04:00
|
|
|
|
}
|
2011-04-22 14:44:23 +04:00
|
|
|
|
// Обработчик keydown/keyup, записывает состояние ctrl
|
2011-04-22 02:34:13 +04:00
|
|
|
|
function ctrlDown(ev)
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
if (ev.keyCode == 17)
|
|
|
|
|
{
|
|
|
|
|
ctrl = ev.type == 'keydown';
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
2011-04-22 02:34:13 +04:00
|
|
|
|
}
|
2011-04-22 14:44:23 +04:00
|
|
|
|
// Попробовать найти по иерархии карточку (id=cardtd_*)
|
2011-04-22 02:34:13 +04:00
|
|
|
|
function searchCardTarget(e)
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
var nt = e._target, i;
|
|
|
|
|
while (nt && (!nt.attributes ||
|
|
|
|
|
!(i = nt.attributes.getNamedItem('id')) ||
|
|
|
|
|
i.value.substr(0, 7) != 'cardtd_'))
|
|
|
|
|
nt = nt.parentNode;
|
|
|
|
|
return nt;
|
2011-04-22 02:34:13 +04:00
|
|
|
|
}
|
2011-04-22 14:44:23 +04:00
|
|
|
|
// Попробовать найти по иерархии кнопку (id=btn_*)
|
2011-04-22 02:34:13 +04:00
|
|
|
|
function searchButtonTarget(e)
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
var nt = e._target, i;
|
|
|
|
|
while (nt && (!nt.attributes ||
|
|
|
|
|
!(i = nt.attributes.getNamedItem('id')) ||
|
|
|
|
|
i.value.substr(0, 4) != 'btn_'))
|
|
|
|
|
nt = nt.parentNode;
|
|
|
|
|
return nt;
|
2011-04-22 02:34:13 +04:00
|
|
|
|
}
|
2011-04-22 18:01:22 +04:00
|
|
|
|
// Попробовать найти по иерархии что-нибудь кроме карточек и кнопок,
|
|
|
|
|
// по сути это только <input> и <textarea>, клик по чему не сбрасывает всё нахрен
|
2011-04-22 14:44:23 +04:00
|
|
|
|
function searchNonResetTarget(e)
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
var nt = e._target, i;
|
|
|
|
|
while (nt && (!(i = nt.nodeName.toLowerCase()) ||
|
|
|
|
|
!(i == 'input' || i == 'textarea')))
|
|
|
|
|
nt = nt.parentNode;
|
|
|
|
|
return nt;
|
2011-04-22 14:44:23 +04:00
|
|
|
|
}
|
|
|
|
|
// Глобальный обработчик события mouseup
|
2011-04-22 02:34:13 +04:00
|
|
|
|
function mouseUpHandler(e)
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
e = DragMaster.fixEvent(e);
|
|
|
|
|
var t;
|
|
|
|
|
if (searchNonResetTarget(e)) {}
|
|
|
|
|
else if (t = searchCardTarget(e))
|
|
|
|
|
selectCard(e, t);
|
|
|
|
|
else if (t = searchButtonTarget(e))
|
|
|
|
|
buttonHandler(e, t);
|
|
|
|
|
else
|
|
|
|
|
resetAll();
|
|
|
|
|
return true;
|
2011-04-22 02:34:13 +04:00
|
|
|
|
}
|
2011-04-22 14:44:23 +04:00
|
|
|
|
// Класс "Перетаскиваемая карточка", унаследованный от "Перетаскиваемого объекта"
|
|
|
|
|
// Логика - при начале перетаскивания удаляется из родительского элемента,
|
|
|
|
|
// который есть строка таблицы, и вместо себя вставляет пустую ячейку.
|
|
|
|
|
// При окончании перетаскивания сначала возвращается на место, а потом дёргает
|
|
|
|
|
// обработчики вырезания и вставки карточек.
|
2011-04-22 13:50:38 +04:00
|
|
|
|
var CardDragObject = function(e)
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
DragObject.call(this, e);
|
|
|
|
|
this.n = id_to_coord(e.id);
|
2011-04-22 13:50:38 +04:00
|
|
|
|
};
|
2011-04-22 02:34:13 +04:00
|
|
|
|
CardDragObject.prototype = new DragObject();
|
|
|
|
|
CardDragObject.prototype.onDragStart = function() {
|
2014-10-13 20:33:51 +04:00
|
|
|
|
this.tmp = document.createElement('td');
|
|
|
|
|
this.element.style.opacity = 0.5;
|
|
|
|
|
this.element.parentNode.insertBefore(this.tmp, this.element);
|
|
|
|
|
this.element.parentNode.parentNode.parentNode.appendChild(this.element);
|
2011-04-22 02:34:13 +04:00
|
|
|
|
};
|
|
|
|
|
CardDragObject.prototype.onDragSuccess = function(target, pos) {
|
2014-10-13 20:33:51 +04:00
|
|
|
|
this.tmp.parentNode.insertBefore(this.element, this.tmp);
|
|
|
|
|
this.tmp.parentNode.removeChild(this.tmp);
|
|
|
|
|
if (!selectedcards[this.element.id.substr(7)])
|
|
|
|
|
{
|
|
|
|
|
deselectAll();
|
|
|
|
|
selectedcards[this.element.id.substr(7)] = true;
|
|
|
|
|
}
|
|
|
|
|
var to = id_to_coord(target.element.id)+1;
|
|
|
|
|
var w = target.element.scrollWidth;
|
|
|
|
|
if (pos.x < w/2)
|
|
|
|
|
to--;
|
|
|
|
|
var decr = 0;
|
|
|
|
|
for (var i = 0; i < to; i++)
|
|
|
|
|
if (selectedcards[to_coord_id(i)])
|
|
|
|
|
decr++;
|
|
|
|
|
to -= decr;
|
|
|
|
|
deleteSelectedCards(true);
|
|
|
|
|
doPasteCards(to);
|
2011-04-22 02:34:13 +04:00
|
|
|
|
};
|
|
|
|
|
CardDragObject.prototype.onDragFail = function() {
|
2014-10-13 20:33:51 +04:00
|
|
|
|
this.tmp.parentNode.insertBefore(this.element, this.tmp);
|
|
|
|
|
this.tmp.parentNode.removeChild(this.tmp);
|
2011-04-22 02:34:13 +04:00
|
|
|
|
};
|
2011-04-22 14:44:23 +04:00
|
|
|
|
// Каждая карточка также является целью перетаскивания
|
|
|
|
|
// Тут вся логика - подсветить левый/правый край в зависимости
|
|
|
|
|
// от положения мышки
|
2011-04-22 02:34:13 +04:00
|
|
|
|
var CardDropTarget = function(e)
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
DropTarget.call(this, e);
|
|
|
|
|
this.n = id_to_coord(e.id);
|
2011-04-22 02:34:13 +04:00
|
|
|
|
};
|
|
|
|
|
CardDropTarget.prototype = new DropTarget();
|
|
|
|
|
CardDropTarget.prototype.onLeave = function()
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
this.element.style.border = '1px dashed black';
|
2011-04-22 02:34:13 +04:00
|
|
|
|
};
|
|
|
|
|
CardDropTarget.prototype.onMove = function(pos)
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
var w = this.element.scrollWidth;
|
|
|
|
|
this.element.style.border = '1px dashed black';
|
|
|
|
|
if (pos.x < w/2)
|
|
|
|
|
this.element.style.borderLeft = '5px solid red';
|
|
|
|
|
else
|
|
|
|
|
this.element.style.borderRight = '5px solid red';
|
2011-04-22 02:34:13 +04:00
|
|
|
|
};
|
2011-04-22 14:44:23 +04:00
|
|
|
|
// 2 если hash пуст
|
|
|
|
|
// 1 если в нём один ключ key
|
|
|
|
|
// 0 если в нём есть ключ, не равный key
|
|
|
|
|
function isEmptyHash(hash, key)
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
var empty = 2;
|
|
|
|
|
for (var i in hash)
|
2011-04-22 14:44:23 +04:00
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
if (key !== undefined && i == key)
|
|
|
|
|
empty = 1;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
empty = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2011-04-22 14:44:23 +04:00
|
|
|
|
}
|
2014-10-13 20:33:51 +04:00
|
|
|
|
return empty;
|
2011-04-22 14:44:23 +04:00
|
|
|
|
}
|
|
|
|
|
// Установка обработчиков событий:
|
2011-04-22 02:34:13 +04:00
|
|
|
|
for (var k = 0; k < np; k++)
|
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
for (var i = 0; i < nr; i++)
|
2011-04-22 02:34:13 +04:00
|
|
|
|
{
|
2014-10-13 20:33:51 +04:00
|
|
|
|
for (var j = 0; j < nc; j++)
|
|
|
|
|
{
|
|
|
|
|
var e = document.getElementById('cardtd_'+k+'_'+i+'_'+j);
|
|
|
|
|
if (e)
|
|
|
|
|
{
|
|
|
|
|
addListener(e, 'mouseover', highlightCard);
|
|
|
|
|
addListener(e, 'mouseout', unlightCard);
|
|
|
|
|
new CardDragObject(e);
|
|
|
|
|
new CardDropTarget(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-04-22 02:34:13 +04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
addListener(document, "mousedown", guessButton);
|
|
|
|
|
addListener(document, "mouseup", mouseUpHandler);
|
|
|
|
|
addListener(document, "keydown", ctrlDown);
|
|
|
|
|
addListener(document.getElementById('addbugs'), "keypress", addNewIfEnter);
|
2011-04-22 14:44:23 +04:00
|
|
|
|
addListener(document, "keyup", ctrlDown);
|