2011-01-25 20:57:47 +01:00
|
|
|
/**
|
|
|
|
* @provides javelin-behavior-differential-populate
|
Bring Javelin into Phabricator via git submodule, not copy-and-paste
Summary:
Javelin is currently embedded in Phabricator via copy-and-paste of prebuilt
packages. This is not so great.
Pull it in as a submodule instead and make all the Phabriator resources declare
proper dependency trees. Add Javelin linting.
Test Plan:
I tried to run through pretty much all the JS functionality on the site. This is
still a high-risk change, but I did a pretty thorough test
Differential: inline comments, revealing diffs, list tokenizers, comment
preview, editing/deleting comments, add review action.
Maniphest: list tokenizer, comment actions
Herald: rule editing, tokenizers, add/remove rows
Reviewed By: tomo
Reviewers: aran, tomo, mroch, jungejason, tuomaspelkonen
CC: aran, tomo, epriestley
Differential Revision: 223
2011-05-04 00:11:55 +02:00
|
|
|
* @requires javelin-behavior
|
2011-07-16 16:09:19 +02:00
|
|
|
* javelin-workflow
|
Bring Javelin into Phabricator via git submodule, not copy-and-paste
Summary:
Javelin is currently embedded in Phabricator via copy-and-paste of prebuilt
packages. This is not so great.
Pull it in as a submodule instead and make all the Phabriator resources declare
proper dependency trees. Add Javelin linting.
Test Plan:
I tried to run through pretty much all the JS functionality on the site. This is
still a high-risk change, but I did a pretty thorough test
Differential: inline comments, revealing diffs, list tokenizers, comment
preview, editing/deleting comments, add review action.
Maniphest: list tokenizer, comment actions
Herald: rule editing, tokenizers, add/remove rows
Reviewed By: tomo
Reviewers: aran, tomo, mroch, jungejason, tuomaspelkonen
CC: aran, tomo, epriestley
Differential Revision: 223
2011-05-04 00:11:55 +02:00
|
|
|
* javelin-util
|
|
|
|
* javelin-dom
|
2012-03-13 04:04:12 +01:00
|
|
|
* javelin-stratcom
|
2013-01-14 23:20:35 +01:00
|
|
|
* javelin-behavior-device
|
Stabilize scroll position as diffs load
Summary:
Try to lock the screen to whatever the user is looking at as we load changesets.
Notably, this improves the use case of taking a known action on a diff. Currently, you have to wait for everything to load or the comments keep getting scrolled down. After this change, the comments stay in the same place on screen.
Test Plan:
Raised the autoload changeset limit from 100 to 1000, looked at a 220 changeset diff.
- Reloaded it while scrolled at the top; normal behavior (no scrolling).
- Reloaded it, scrolled to the bottom. Comment area now stable.
- Reloaded it, kind of scrolled around the middle? Behavior seemed stable/reasonable. This one is kind of heursitic so it's hard to say I'm getting it totally right or not, but it's less important than the "bottom" case.
Reviewers: vrana, btrahan, chad, dctrwatson
Reviewed By: btrahan
CC: aran
Differential Revision: https://secure.phabricator.com/D4774
2013-02-01 19:52:07 +01:00
|
|
|
* javelin-vector
|
Provide a global router for Ajax requests
Summary:
Fixes T430. Fixes T4834. Obsoletes D7641. Currently, we do some things less-well than we could:
- We just let the browser queue and prioritize requests, so if you load a revision with 50 changes and then click "Award Token", the action blocks until the changes load in most/all browsers. It would be better to prioritize this action and queue it immediately.
- Similarly, changes tend to load in order, even if the user has clicked to a specific file. When the user expresses a preference for a specific file, we should prioritize it.
- We show a spinning GIF when waiting on requests. This is appropriate for some types of reuqests, but distracting for others.
To fix this:
- Queue all (or, at least, most) requests into a new queue in JX.Router.
- JX.Router handles prioritizing the requests. Principally:
- You can submit a request with a specific priority (500 = general content loading, 1000 = default, 2000 = explicit user action) and JX.Router will get the higher stuff fired off sooner.
- You can name requests and then adjust their prorities later, if the user expresses an interest in specific results.
- Only use the spinner gif for "workflow" requests, which is bascially when the user clicked something and we're waiting on the server. I think it's useful and not-annoying in this case.
- Don't show any status for draft requests.
- For content requests, show a subtle hipster-style top loading bar.
Test Plan:
- Viewed a diff with 93 changes, and clicked award token.
- Prior to this patch, the action took many many seconds to resolve.
- After this patch, it resolves quickly.
- Viewed a diff with 93 changes and saw a pleasant subtle hipster-style loading bar.
- Viewed a diff with 93 changes and typed some draft text. Previews populated fairly quickly and there was no spinner.
- Viewed a diff with 93 changes and clicked something with workflow, saw a spinner after a moment.
- Viewed a diff with 93 changes and clicked a file in the table of contents near the end of the list.
- Prior to this patch, it took a long time to show up.
- After this patch, it loads directly.
Reviewers: chad, btrahan
Reviewed By: btrahan
Subscribers: epriestley
Maniphest Tasks: T430, T4834
Differential Revision: https://secure.phabricator.com/D8979
2014-05-05 19:57:42 +02:00
|
|
|
* javelin-router
|
2012-03-13 04:04:12 +01:00
|
|
|
* phabricator-tooltip
|
2011-01-25 20:57:47 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
JX.behavior('differential-populate', function(config) {
|
|
|
|
|
Stabilize scroll position as diffs load
Summary:
Try to lock the screen to whatever the user is looking at as we load changesets.
Notably, this improves the use case of taking a known action on a diff. Currently, you have to wait for everything to load or the comments keep getting scrolled down. After this change, the comments stay in the same place on screen.
Test Plan:
Raised the autoload changeset limit from 100 to 1000, looked at a 220 changeset diff.
- Reloaded it while scrolled at the top; normal behavior (no scrolling).
- Reloaded it, scrolled to the bottom. Comment area now stable.
- Reloaded it, kind of scrolled around the middle? Behavior seemed stable/reasonable. This one is kind of heursitic so it's hard to say I'm getting it totally right or not, but it's less important than the "bottom" case.
Reviewers: vrana, btrahan, chad, dctrwatson
Reviewed By: btrahan
CC: aran
Differential Revision: https://secure.phabricator.com/D4774
2013-02-01 19:52:07 +01:00
|
|
|
function onresponse(target_id, response) {
|
|
|
|
// As we populate the diff, we try to hold the document scroll position
|
|
|
|
// steady, so that, e.g., users who want to leave a comment on a diff with a
|
|
|
|
// large number of changes don't constantly have the text area scrolled off
|
|
|
|
// the bottom of the screen until the entire diff loads.
|
|
|
|
//
|
|
|
|
// There are two three major cases here:
|
|
|
|
//
|
|
|
|
// - If we're near the top of the document, never scroll.
|
|
|
|
// - If we're near the bottom of the document, always scroll.
|
|
|
|
// - Otherwise, scroll if the changes were above the midline of the
|
|
|
|
// viewport.
|
|
|
|
var target = JX.$(target_id);
|
|
|
|
|
|
|
|
var old_pos = JX.Vector.getScroll();
|
|
|
|
var old_view = JX.Vector.getViewport();
|
|
|
|
var old_dim = JX.Vector.getDocument();
|
|
|
|
|
|
|
|
// Number of pixels away from the top or bottom of the document which
|
|
|
|
// count as "nearby".
|
|
|
|
var sticky = 480;
|
|
|
|
|
|
|
|
var near_top = (old_pos.y <= sticky);
|
|
|
|
var near_bot = ((old_pos.y + old_view.y) >= (old_dim.y - sticky));
|
|
|
|
|
|
|
|
var target_pos = JX.Vector.getPos(target);
|
|
|
|
var target_dim = JX.Vector.getDim(target);
|
|
|
|
var target_mid = (target_pos.y + (target_dim.y / 2));
|
|
|
|
|
|
|
|
var view_mid = (old_pos.y + (old_view.y / 2));
|
|
|
|
var above_mid = (target_mid < view_mid);
|
|
|
|
|
|
|
|
JX.DOM.replace(target, JX.$H(response.changeset));
|
|
|
|
|
|
|
|
if (!near_top) {
|
|
|
|
if (near_bot || above_mid) {
|
|
|
|
// Figure out how much taller the document got.
|
|
|
|
var delta = (JX.Vector.getDocument().y - old_dim.y);
|
|
|
|
|
|
|
|
window.scrollTo(old_pos.x, old_pos.y + delta);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-13 01:06:55 +01:00
|
|
|
if (response.coverage) {
|
|
|
|
for (var k in response.coverage) {
|
|
|
|
try {
|
|
|
|
JX.DOM.replace(JX.$(k), JX.$H(response.coverage[k]));
|
|
|
|
} catch (ignored) {
|
|
|
|
// Not terribly important.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-01-25 20:57:47 +01:00
|
|
|
}
|
|
|
|
|
2013-01-14 23:20:35 +01:00
|
|
|
// NOTE: If you load the page at one device resolution and then resize to
|
|
|
|
// a different one we don't re-render the diffs, because it's a complicated
|
|
|
|
// mess and you could lose inline comments, cursor positions, etc.
|
|
|
|
var renderer = (JX.Device.getDevice() == 'desktop') ? '2up' : '1up';
|
|
|
|
|
2013-01-18 00:04:44 +01:00
|
|
|
// TODO: Once 1up works better, figure out when to show it.
|
|
|
|
renderer = '2up';
|
|
|
|
|
Provide a global router for Ajax requests
Summary:
Fixes T430. Fixes T4834. Obsoletes D7641. Currently, we do some things less-well than we could:
- We just let the browser queue and prioritize requests, so if you load a revision with 50 changes and then click "Award Token", the action blocks until the changes load in most/all browsers. It would be better to prioritize this action and queue it immediately.
- Similarly, changes tend to load in order, even if the user has clicked to a specific file. When the user expresses a preference for a specific file, we should prioritize it.
- We show a spinning GIF when waiting on requests. This is appropriate for some types of reuqests, but distracting for others.
To fix this:
- Queue all (or, at least, most) requests into a new queue in JX.Router.
- JX.Router handles prioritizing the requests. Principally:
- You can submit a request with a specific priority (500 = general content loading, 1000 = default, 2000 = explicit user action) and JX.Router will get the higher stuff fired off sooner.
- You can name requests and then adjust their prorities later, if the user expresses an interest in specific results.
- Only use the spinner gif for "workflow" requests, which is bascially when the user clicked something and we're waiting on the server. I think it's useful and not-annoying in this case.
- Don't show any status for draft requests.
- For content requests, show a subtle hipster-style top loading bar.
Test Plan:
- Viewed a diff with 93 changes, and clicked award token.
- Prior to this patch, the action took many many seconds to resolve.
- After this patch, it resolves quickly.
- Viewed a diff with 93 changes and saw a pleasant subtle hipster-style loading bar.
- Viewed a diff with 93 changes and typed some draft text. Previews populated fairly quickly and there was no spinner.
- Viewed a diff with 93 changes and clicked something with workflow, saw a spinner after a moment.
- Viewed a diff with 93 changes and clicked a file in the table of contents near the end of the list.
- Prior to this patch, it took a long time to show up.
- After this patch, it loads directly.
Reviewers: chad, btrahan
Reviewed By: btrahan
Subscribers: epriestley
Maniphest Tasks: T430, T4834
Differential Revision: https://secure.phabricator.com/D8979
2014-05-05 19:57:42 +02:00
|
|
|
var get_key = function(id) {
|
|
|
|
return 'differential-populate.' + id;
|
|
|
|
};
|
|
|
|
|
|
|
|
var load = function(id, data) {
|
|
|
|
var routable = new JX.Workflow(config.uri, data)
|
|
|
|
.setHandler(JX.bind(null, onresponse, id))
|
|
|
|
.getRoutable();
|
|
|
|
|
|
|
|
routable
|
|
|
|
.setPriority(500)
|
|
|
|
.setType('content')
|
|
|
|
.setKey(get_key(id));
|
|
|
|
|
|
|
|
JX.Router.getInstance().queue(routable);
|
|
|
|
|
|
|
|
return routable;
|
|
|
|
};
|
|
|
|
|
2011-01-25 20:57:47 +01:00
|
|
|
for (var k in config.registry) {
|
2011-07-16 16:09:19 +02:00
|
|
|
var data = {
|
|
|
|
ref : config.registry[k],
|
2013-01-14 23:20:35 +01:00
|
|
|
whitespace: config.whitespace,
|
|
|
|
renderer: renderer
|
2011-07-16 16:09:19 +02:00
|
|
|
};
|
|
|
|
|
Provide a global router for Ajax requests
Summary:
Fixes T430. Fixes T4834. Obsoletes D7641. Currently, we do some things less-well than we could:
- We just let the browser queue and prioritize requests, so if you load a revision with 50 changes and then click "Award Token", the action blocks until the changes load in most/all browsers. It would be better to prioritize this action and queue it immediately.
- Similarly, changes tend to load in order, even if the user has clicked to a specific file. When the user expresses a preference for a specific file, we should prioritize it.
- We show a spinning GIF when waiting on requests. This is appropriate for some types of reuqests, but distracting for others.
To fix this:
- Queue all (or, at least, most) requests into a new queue in JX.Router.
- JX.Router handles prioritizing the requests. Principally:
- You can submit a request with a specific priority (500 = general content loading, 1000 = default, 2000 = explicit user action) and JX.Router will get the higher stuff fired off sooner.
- You can name requests and then adjust their prorities later, if the user expresses an interest in specific results.
- Only use the spinner gif for "workflow" requests, which is bascially when the user clicked something and we're waiting on the server. I think it's useful and not-annoying in this case.
- Don't show any status for draft requests.
- For content requests, show a subtle hipster-style top loading bar.
Test Plan:
- Viewed a diff with 93 changes, and clicked award token.
- Prior to this patch, the action took many many seconds to resolve.
- After this patch, it resolves quickly.
- Viewed a diff with 93 changes and saw a pleasant subtle hipster-style loading bar.
- Viewed a diff with 93 changes and typed some draft text. Previews populated fairly quickly and there was no spinner.
- Viewed a diff with 93 changes and clicked something with workflow, saw a spinner after a moment.
- Viewed a diff with 93 changes and clicked a file in the table of contents near the end of the list.
- Prior to this patch, it took a long time to show up.
- After this patch, it loads directly.
Reviewers: chad, btrahan
Reviewed By: btrahan
Subscribers: epriestley
Maniphest Tasks: T430, T4834
Differential Revision: https://secure.phabricator.com/D8979
2014-05-05 19:57:42 +02:00
|
|
|
load(k, data);
|
2011-01-25 20:57:47 +01:00
|
|
|
}
|
|
|
|
|
2012-03-13 04:04:12 +01:00
|
|
|
var highlighted = null;
|
|
|
|
var highlight_class = null;
|
|
|
|
|
2012-05-01 21:09:50 +02:00
|
|
|
JX.Stratcom.listen(
|
|
|
|
'click',
|
|
|
|
'differential-load',
|
|
|
|
function(e) {
|
|
|
|
var meta = e.getNodeData('differential-load');
|
2012-08-07 08:01:23 +02:00
|
|
|
var diff;
|
|
|
|
try {
|
|
|
|
diff = JX.$(meta.id);
|
2013-05-19 02:04:22 +02:00
|
|
|
} catch (ex) {
|
2012-08-07 08:01:23 +02:00
|
|
|
// Already loaded.
|
|
|
|
}
|
|
|
|
if (diff) {
|
|
|
|
JX.DOM.setContent(
|
|
|
|
diff,
|
|
|
|
JX.$H('<div class="differential-loading">Loading...</div>'));
|
Provide a global router for Ajax requests
Summary:
Fixes T430. Fixes T4834. Obsoletes D7641. Currently, we do some things less-well than we could:
- We just let the browser queue and prioritize requests, so if you load a revision with 50 changes and then click "Award Token", the action blocks until the changes load in most/all browsers. It would be better to prioritize this action and queue it immediately.
- Similarly, changes tend to load in order, even if the user has clicked to a specific file. When the user expresses a preference for a specific file, we should prioritize it.
- We show a spinning GIF when waiting on requests. This is appropriate for some types of reuqests, but distracting for others.
To fix this:
- Queue all (or, at least, most) requests into a new queue in JX.Router.
- JX.Router handles prioritizing the requests. Principally:
- You can submit a request with a specific priority (500 = general content loading, 1000 = default, 2000 = explicit user action) and JX.Router will get the higher stuff fired off sooner.
- You can name requests and then adjust their prorities later, if the user expresses an interest in specific results.
- Only use the spinner gif for "workflow" requests, which is bascially when the user clicked something and we're waiting on the server. I think it's useful and not-annoying in this case.
- Don't show any status for draft requests.
- For content requests, show a subtle hipster-style top loading bar.
Test Plan:
- Viewed a diff with 93 changes, and clicked award token.
- Prior to this patch, the action took many many seconds to resolve.
- After this patch, it resolves quickly.
- Viewed a diff with 93 changes and saw a pleasant subtle hipster-style loading bar.
- Viewed a diff with 93 changes and typed some draft text. Previews populated fairly quickly and there was no spinner.
- Viewed a diff with 93 changes and clicked something with workflow, saw a spinner after a moment.
- Viewed a diff with 93 changes and clicked a file in the table of contents near the end of the list.
- Prior to this patch, it took a long time to show up.
- After this patch, it loads directly.
Reviewers: chad, btrahan
Reviewed By: btrahan
Subscribers: epriestley
Maniphest Tasks: T430, T4834
Differential Revision: https://secure.phabricator.com/D8979
2014-05-05 19:57:42 +02:00
|
|
|
|
|
|
|
// When a user explicitly clicks "Load" (or clicks a link in the table
|
|
|
|
// of contents) prioritize this request if it already exists. If it
|
|
|
|
// doesn't, make a new high-priority request.
|
|
|
|
|
|
|
|
var key = get_key(meta.id);
|
|
|
|
var routable = JX.Router.getInstance().getRoutableByKey(key);
|
|
|
|
|
|
|
|
if (!routable) {
|
|
|
|
var data = {
|
|
|
|
ref : meta.ref,
|
|
|
|
whitespace : config.whitespace
|
|
|
|
};
|
|
|
|
|
|
|
|
routable = load(meta.id, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
routable.setPriority(2000);
|
2012-08-07 08:01:23 +02:00
|
|
|
}
|
2012-05-01 21:09:50 +02:00
|
|
|
if (meta.kill) {
|
|
|
|
e.kill();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2012-03-13 04:04:12 +01:00
|
|
|
JX.Stratcom.listen(
|
|
|
|
['mouseover', 'mouseout'],
|
|
|
|
['differential-changeset', 'tag:td'],
|
|
|
|
function(e) {
|
|
|
|
var t = e.getTarget();
|
|
|
|
|
|
|
|
// NOTE: Using className is not best practice, but the diff UI is perf
|
|
|
|
// sensitive.
|
2012-05-05 02:41:06 +02:00
|
|
|
if (!t.className.match(/cov|copy/)) {
|
2012-03-13 04:04:12 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (e.getType() == 'mouseout') {
|
|
|
|
JX.Tooltip.hide();
|
|
|
|
if (highlighted) {
|
|
|
|
JX.DOM.alterClass(highlighted, highlight_class, false);
|
|
|
|
highlighted = null;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
highlight_class = null;
|
|
|
|
var msg;
|
2012-12-21 03:23:35 +01:00
|
|
|
var align = 'W';
|
2012-05-05 02:41:06 +02:00
|
|
|
var sibling = 'previousSibling';
|
2012-08-07 02:17:38 +02:00
|
|
|
var width = 120;
|
2012-03-13 04:04:12 +01:00
|
|
|
if (t.className.match(/cov-C/)) {
|
|
|
|
msg = 'Covered';
|
|
|
|
highlight_class = 'source-cov-C';
|
|
|
|
} else if (t.className.match(/cov-U/)) {
|
|
|
|
msg = 'Not Covered';
|
|
|
|
highlight_class = 'source-cov-U';
|
|
|
|
} else if (t.className.match(/cov-N/)) {
|
|
|
|
msg = 'Not Executable';
|
|
|
|
highlight_class = 'source-cov-N';
|
2012-05-05 02:41:06 +02:00
|
|
|
} else {
|
|
|
|
var match = /new-copy|new-move/.exec(t.className);
|
|
|
|
if (match) {
|
|
|
|
sibling = 'nextSibling';
|
2012-08-07 02:17:38 +02:00
|
|
|
width = 500;
|
2012-05-05 02:41:06 +02:00
|
|
|
msg = JX.Stratcom.getData(t).msg;
|
|
|
|
highlight_class = match[0];
|
|
|
|
}
|
2012-03-13 04:04:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (msg) {
|
2012-08-07 02:17:38 +02:00
|
|
|
JX.Tooltip.show(t, width, align, msg);
|
2012-03-13 04:04:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (highlight_class) {
|
2012-05-05 02:41:06 +02:00
|
|
|
highlighted = t[sibling];
|
2012-03-13 04:04:12 +01:00
|
|
|
JX.DOM.alterClass(highlighted, highlight_class, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-01-25 20:57:47 +01:00
|
|
|
});
|