mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-14 10:52:41 +01:00
41dcd7420b
Summary: Fixes T7054. Fixes T7049. - Stop scrolling Differential reticles when the page scrolls. - Make dialogs aware of multi-panel UI. Test Plan: - Dialogs pop up in the right place. - Inline + scroll now longer leaves the inline in a fixed position. Reviewers: btrahan, chad Reviewed By: chad Subscribers: epriestley Maniphest Tasks: T7049, T7054 Differential Revision: https://secure.phabricator.com/D11523
275 lines
6.9 KiB
JavaScript
275 lines
6.9 KiB
JavaScript
/**
|
|
* @provides javelin-behavior-differential-edit-inline-comments
|
|
* @requires javelin-behavior
|
|
* javelin-stratcom
|
|
* javelin-dom
|
|
* javelin-util
|
|
* javelin-vector
|
|
* differential-inline-comment-editor
|
|
*/
|
|
|
|
JX.behavior('differential-edit-inline-comments', function(config) {
|
|
|
|
var selecting = false;
|
|
var reticle = JX.$N('div', {className: 'differential-reticle'});
|
|
JX.DOM.hide(reticle);
|
|
|
|
var origin = null;
|
|
var target = null;
|
|
var root = null;
|
|
var changeset = null;
|
|
|
|
var editor = null;
|
|
|
|
function updateReticle() {
|
|
JX.DOM.getContentFrame().appendChild(reticle);
|
|
|
|
var top = origin;
|
|
var bot = target;
|
|
if (JX.$V(top).y > JX.$V(bot).y) {
|
|
var tmp = top;
|
|
top = bot;
|
|
bot = tmp;
|
|
}
|
|
var code = target.nextSibling;
|
|
|
|
var pos = JX.$V(top)
|
|
.add(JX.Vector.getAggregateScrollForNode(top))
|
|
.add(1 + JX.Vector.getDim(target).x, 0);
|
|
var dim = JX.Vector.getDim(code).add(-4, 0);
|
|
if (isOnRight(target)) {
|
|
dim.x += JX.Vector.getDim(code.nextSibling).x;
|
|
}
|
|
|
|
var bpos = JX.$V(bot)
|
|
.add(JX.Vector.getAggregateScrollForNode(bot));
|
|
dim.y = (bpos.y - pos.y) + JX.Vector.getDim(bot).y;
|
|
|
|
pos.setPos(reticle);
|
|
dim.setDim(reticle);
|
|
|
|
JX.DOM.show(reticle);
|
|
}
|
|
|
|
function hideReticle() {
|
|
JX.DOM.hide(reticle);
|
|
}
|
|
|
|
JX.DifferentialInlineCommentEditor.listen('done', function() {
|
|
selecting = false;
|
|
editor = false;
|
|
hideReticle();
|
|
set_link_state(false);
|
|
});
|
|
|
|
function isOnRight(node) {
|
|
return node.parentNode.firstChild != node;
|
|
}
|
|
|
|
function isNewFile(node) {
|
|
var data = JX.Stratcom.getData(root);
|
|
return isOnRight(node) || (data.left != data.right);
|
|
}
|
|
|
|
function getRowNumber(th_node) {
|
|
try {
|
|
return parseInt(th_node.id.match(/^C\d+[ON]L(\d+)$/)[1], 10);
|
|
} catch (x) {
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
var set_link_state = function(active) {
|
|
JX.DOM.alterClass(JX.$(config.stage), 'inline-editor-active', active);
|
|
};
|
|
|
|
JX.Stratcom.listen(
|
|
'mousedown',
|
|
['differential-changeset', 'tag:th'],
|
|
function(e) {
|
|
if (editor ||
|
|
selecting ||
|
|
e.isRightButton() ||
|
|
getRowNumber(e.getTarget()) === undefined) {
|
|
return;
|
|
}
|
|
|
|
selecting = true;
|
|
root = e.getNode('differential-changeset');
|
|
|
|
origin = target = e.getTarget();
|
|
|
|
var data = e.getNodeData('differential-changeset');
|
|
if (isOnRight(target)) {
|
|
changeset = data.right;
|
|
} else {
|
|
changeset = data.left;
|
|
}
|
|
|
|
updateReticle();
|
|
|
|
e.kill();
|
|
});
|
|
|
|
JX.Stratcom.listen(
|
|
'mouseover',
|
|
['differential-changeset', 'tag:th'],
|
|
function(e) {
|
|
if (!selecting ||
|
|
editor ||
|
|
(getRowNumber(e.getTarget()) === undefined) ||
|
|
(isOnRight(e.getTarget()) != isOnRight(origin)) ||
|
|
(e.getNode('differential-changeset') !== root)) {
|
|
return;
|
|
}
|
|
|
|
target = e.getTarget();
|
|
|
|
updateReticle();
|
|
});
|
|
|
|
JX.Stratcom.listen(
|
|
'mouseup',
|
|
null,
|
|
function(e) {
|
|
if (editor || !selecting) {
|
|
return;
|
|
}
|
|
|
|
var o = getRowNumber(origin);
|
|
var t = getRowNumber(target);
|
|
|
|
var insert;
|
|
var len;
|
|
if (t < o) {
|
|
len = (o - t);
|
|
o = t;
|
|
insert = origin.parentNode;
|
|
} else {
|
|
len = (t - o);
|
|
insert = target.parentNode;
|
|
}
|
|
|
|
editor = new JX.DifferentialInlineCommentEditor(config.uri)
|
|
.setTemplates(config.undo_templates)
|
|
.setOperation('new')
|
|
.setChangeset(changeset)
|
|
.setLineNumber(o)
|
|
.setLength(len)
|
|
.setIsNew(isNewFile(target) ? 1 : 0)
|
|
.setOnRight(isOnRight(target) ? 1 : 0)
|
|
.setRow(insert.nextSibling)
|
|
.setTable(insert.parentNode)
|
|
.start();
|
|
|
|
set_link_state(true);
|
|
|
|
e.kill();
|
|
});
|
|
|
|
JX.Stratcom.listen(
|
|
['mouseover', 'mouseout'],
|
|
'differential-inline-comment',
|
|
function(e) {
|
|
if (e.getType() == 'mouseout') {
|
|
hideReticle();
|
|
} else {
|
|
root = e.getNode('differential-changeset');
|
|
if (root) {
|
|
|
|
var data = e.getNodeData('differential-inline-comment');
|
|
var change = e.getNodeData('differential-changeset');
|
|
|
|
var id_part = data.on_right ? change.right : change.left;
|
|
|
|
// NOTE: We can't just look for 'tag:td' because the event might be
|
|
// inside a table which is inside an inline comment.
|
|
var comment = e.getNode('differential-inline-comment');
|
|
var td = JX.DOM.findAbove(comment, 'td');
|
|
var th = td.previousSibling;
|
|
|
|
var new_part = isNewFile(th) ? 'N' : 'O';
|
|
var prefix = 'C' + id_part + new_part + 'L';
|
|
|
|
origin = JX.$(prefix + data.number);
|
|
target = JX.$(prefix + (parseInt(data.number, 10) +
|
|
parseInt(data.length, 10)));
|
|
|
|
updateReticle();
|
|
}
|
|
}
|
|
});
|
|
|
|
var action_handler = function(op, e) {
|
|
e.kill();
|
|
|
|
if (editor) {
|
|
return;
|
|
}
|
|
|
|
var node = e.getNode('differential-inline-comment');
|
|
handle_inline_action(node, op);
|
|
};
|
|
|
|
var handle_inline_action = function(node, op) {
|
|
var data = JX.Stratcom.getData(node);
|
|
var row = node.parentNode.parentNode;
|
|
var other_rows = [];
|
|
if (JX.Stratcom.hasSigil(node, 'differential-inline-comment-preview')) {
|
|
// The DOM structure around the comment is different if it's part of the
|
|
// preview, so make sure not to pass the wrong container.
|
|
row = node;
|
|
if (op === 'delete') {
|
|
// Furthermore, deleting a comment in the preview does not automatically
|
|
// delete other occurrences of the same comment, so do that manually.
|
|
var nodes = JX.DOM.scry(
|
|
JX.DOM.getContentFrame(),
|
|
'div',
|
|
'differential-inline-comment');
|
|
for (var i = 0; i < nodes.length; ++i) {
|
|
if (JX.Stratcom.getData(nodes[i]).id === data.id) {
|
|
other_rows.push(nodes[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var original = data.original;
|
|
if (op == 'reply') {
|
|
// If the user hit "reply", the original text is empty (a new reply), not
|
|
// the text of the comment they're replying to.
|
|
original = '';
|
|
}
|
|
|
|
editor = new JX.DifferentialInlineCommentEditor(config.uri)
|
|
.setTemplates(config.undo_templates)
|
|
.setOperation(op)
|
|
.setID(data.id)
|
|
.setLineNumber(data.number)
|
|
.setLength(data.length)
|
|
.setOnRight(data.on_right)
|
|
.setOriginalText(original)
|
|
.setRow(row)
|
|
.setOtherRows(other_rows)
|
|
.setTable(row.parentNode)
|
|
.start();
|
|
|
|
set_link_state(true);
|
|
};
|
|
|
|
for (var op in {'edit' : 1, 'delete' : 1, 'reply' : 1}) {
|
|
JX.Stratcom.listen(
|
|
'click',
|
|
['differential-inline-comment', 'differential-inline-' + op],
|
|
JX.bind(null, action_handler, op));
|
|
}
|
|
|
|
JX.Stratcom.listen(
|
|
'differential-inline-action',
|
|
null,
|
|
function(e) {
|
|
var data = e.getData();
|
|
handle_inline_action(data.node, data.op);
|
|
});
|
|
|
|
});
|