mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-24 06:20:56 +01:00
Quicksand - provide some plumbing for fancier updates
Summary: Ref D12448. Ref T7573. This changes quicksand up a bit so rather than caching just rendered HTML we also cache the initial response from the server. We also fire off a quicksand-redraw event which will let things like the page objects for notifications update correctly while using Quicksand (see D12448). Test Plan: loaded up /p/btrahan/ Clicked the UI elements to navigate to various profile views up to maniphest. clicked back until back at /p/btrahan/ and it worked. clicked forward until all the way back to maniphest and it worked. clicked back 2x, then clicked new links, then back and it worked Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin, epriestley Maniphest Tasks: T7573 Differential Revision: https://secure.phabricator.com/D12449
This commit is contained in:
parent
bae0a85dbc
commit
4d5badeec0
5 changed files with 64 additions and 36 deletions
|
@ -205,7 +205,7 @@ return array(
|
||||||
'rsrc/externals/javelin/lib/JSON.js' => '69adf288',
|
'rsrc/externals/javelin/lib/JSON.js' => '69adf288',
|
||||||
'rsrc/externals/javelin/lib/Leader.js' => '331b1611',
|
'rsrc/externals/javelin/lib/Leader.js' => '331b1611',
|
||||||
'rsrc/externals/javelin/lib/Mask.js' => '8a41885b',
|
'rsrc/externals/javelin/lib/Mask.js' => '8a41885b',
|
||||||
'rsrc/externals/javelin/lib/Quicksand.js' => '2bb920b6',
|
'rsrc/externals/javelin/lib/Quicksand.js' => 'd15f0293',
|
||||||
'rsrc/externals/javelin/lib/Request.js' => '94b750d2',
|
'rsrc/externals/javelin/lib/Request.js' => '94b750d2',
|
||||||
'rsrc/externals/javelin/lib/Resource.js' => '44959b73',
|
'rsrc/externals/javelin/lib/Resource.js' => '44959b73',
|
||||||
'rsrc/externals/javelin/lib/Routable.js' => 'b3e7d692',
|
'rsrc/externals/javelin/lib/Routable.js' => 'b3e7d692',
|
||||||
|
@ -356,7 +356,7 @@ return array(
|
||||||
'rsrc/js/application/auth/behavior-persona-login.js' => '9414ff18',
|
'rsrc/js/application/auth/behavior-persona-login.js' => '9414ff18',
|
||||||
'rsrc/js/application/config/behavior-reorder-fields.js' => '14a827de',
|
'rsrc/js/application/config/behavior-reorder-fields.js' => '14a827de',
|
||||||
'rsrc/js/application/conpherence/ConpherenceThreadManager.js' => '0a5192c4',
|
'rsrc/js/application/conpherence/ConpherenceThreadManager.js' => '0a5192c4',
|
||||||
'rsrc/js/application/conpherence/behavior-durable-column.js' => '7ffa744f',
|
'rsrc/js/application/conpherence/behavior-durable-column.js' => '4de3bda8',
|
||||||
'rsrc/js/application/conpherence/behavior-menu.js' => '077a1dab',
|
'rsrc/js/application/conpherence/behavior-menu.js' => '077a1dab',
|
||||||
'rsrc/js/application/conpherence/behavior-pontificate.js' => '21ba5861',
|
'rsrc/js/application/conpherence/behavior-pontificate.js' => '21ba5861',
|
||||||
'rsrc/js/application/conpherence/behavior-quicksand-blacklist.js' => '7927a7d3',
|
'rsrc/js/application/conpherence/behavior-quicksand-blacklist.js' => '7927a7d3',
|
||||||
|
@ -590,7 +590,7 @@ return array(
|
||||||
'javelin-behavior-diffusion-locate-file' => '6d3e1947',
|
'javelin-behavior-diffusion-locate-file' => '6d3e1947',
|
||||||
'javelin-behavior-diffusion-pull-lastmodified' => '2b228192',
|
'javelin-behavior-diffusion-pull-lastmodified' => '2b228192',
|
||||||
'javelin-behavior-doorkeeper-tag' => 'e5822781',
|
'javelin-behavior-doorkeeper-tag' => 'e5822781',
|
||||||
'javelin-behavior-durable-column' => '7ffa744f',
|
'javelin-behavior-durable-column' => '4de3bda8',
|
||||||
'javelin-behavior-error-log' => '6882e80a',
|
'javelin-behavior-error-log' => '6882e80a',
|
||||||
'javelin-behavior-fancy-datepicker' => 'c51ae228',
|
'javelin-behavior-fancy-datepicker' => 'c51ae228',
|
||||||
'javelin-behavior-global-drag-and-drop' => 'bbdf75ca',
|
'javelin-behavior-global-drag-and-drop' => 'bbdf75ca',
|
||||||
|
@ -677,7 +677,7 @@ return array(
|
||||||
'javelin-leader' => '331b1611',
|
'javelin-leader' => '331b1611',
|
||||||
'javelin-magical-init' => '3010e992',
|
'javelin-magical-init' => '3010e992',
|
||||||
'javelin-mask' => '8a41885b',
|
'javelin-mask' => '8a41885b',
|
||||||
'javelin-quicksand' => '2bb920b6',
|
'javelin-quicksand' => 'd15f0293',
|
||||||
'javelin-reactor' => '2b8de964',
|
'javelin-reactor' => '2b8de964',
|
||||||
'javelin-reactor-dom' => 'c90a04fc',
|
'javelin-reactor-dom' => 'c90a04fc',
|
||||||
'javelin-reactor-node-calmer' => '76f4ebed',
|
'javelin-reactor-node-calmer' => '76f4ebed',
|
||||||
|
@ -1034,9 +1034,6 @@ return array(
|
||||||
'javelin-install',
|
'javelin-install',
|
||||||
'javelin-util',
|
'javelin-util',
|
||||||
),
|
),
|
||||||
'2bb920b6' => array(
|
|
||||||
'javelin-install',
|
|
||||||
),
|
|
||||||
'2be71d56' => array(
|
'2be71d56' => array(
|
||||||
'javelin-install',
|
'javelin-install',
|
||||||
'javelin-util',
|
'javelin-util',
|
||||||
|
@ -1164,6 +1161,16 @@ return array(
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
'phuix-dropdown-menu',
|
'phuix-dropdown-menu',
|
||||||
),
|
),
|
||||||
|
'4de3bda8' => array(
|
||||||
|
'javelin-behavior',
|
||||||
|
'javelin-dom',
|
||||||
|
'javelin-stratcom',
|
||||||
|
'javelin-behavior-device',
|
||||||
|
'javelin-scrollbar',
|
||||||
|
'javelin-quicksand',
|
||||||
|
'phabricator-keyboard-shortcut',
|
||||||
|
'conpherence-thread-manager',
|
||||||
|
),
|
||||||
'4e3e79a6' => array(
|
'4e3e79a6' => array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-stratcom',
|
'javelin-stratcom',
|
||||||
|
@ -1442,16 +1449,6 @@ return array(
|
||||||
'javelin-uri',
|
'javelin-uri',
|
||||||
'phabricator-file-upload',
|
'phabricator-file-upload',
|
||||||
),
|
),
|
||||||
'7ffa744f' => array(
|
|
||||||
'javelin-behavior',
|
|
||||||
'javelin-dom',
|
|
||||||
'javelin-stratcom',
|
|
||||||
'javelin-behavior-device',
|
|
||||||
'javelin-scrollbar',
|
|
||||||
'javelin-quicksand',
|
|
||||||
'phabricator-keyboard-shortcut',
|
|
||||||
'conpherence-thread-manager',
|
|
||||||
),
|
|
||||||
82439934 => array(
|
82439934 => array(
|
||||||
'javelin-behavior',
|
'javelin-behavior',
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
|
@ -1796,6 +1793,9 @@ return array(
|
||||||
'javelin-stratcom',
|
'javelin-stratcom',
|
||||||
'phabricator-phtize',
|
'phabricator-phtize',
|
||||||
),
|
),
|
||||||
|
'd15f0293' => array(
|
||||||
|
'javelin-install',
|
||||||
|
),
|
||||||
'd19198c8' => array(
|
'd19198c8' => array(
|
||||||
'javelin-install',
|
'javelin-install',
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
|
|
|
@ -9,6 +9,7 @@ final class ConpherenceDurableColumnView extends AphrontTagView {
|
||||||
private $visible;
|
private $visible;
|
||||||
private $initialLoad = false;
|
private $initialLoad = false;
|
||||||
private $policyObjects;
|
private $policyObjects;
|
||||||
|
private $quicksandConfig = array();
|
||||||
|
|
||||||
public function setConpherences(array $conpherences) {
|
public function setConpherences(array $conpherences) {
|
||||||
assert_instances_of($conpherences, 'ConpherenceThread');
|
assert_instances_of($conpherences, 'ConpherenceThread');
|
||||||
|
@ -78,6 +79,15 @@ final class ConpherenceDurableColumnView extends AphrontTagView {
|
||||||
return $this->policyObjects;
|
return $this->policyObjects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setQuicksandConfig(array $config) {
|
||||||
|
$this->quicksandConfig = $config;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getQuicksandConfig() {
|
||||||
|
return $this->quicksandConfig;
|
||||||
|
}
|
||||||
|
|
||||||
protected function getTagAttributes() {
|
protected function getTagAttributes() {
|
||||||
if ($this->getVisible()) {
|
if ($this->getVisible()) {
|
||||||
$style = null;
|
$style = null;
|
||||||
|
@ -106,6 +116,7 @@ final class ConpherenceDurableColumnView extends AphrontTagView {
|
||||||
array(
|
array(
|
||||||
'visible' => $this->getVisible(),
|
'visible' => $this->getVisible(),
|
||||||
'settingsURI' => '/settings/adjust/?key='.$column_key,
|
'settingsURI' => '/settings/adjust/?key='.$column_key,
|
||||||
|
'quicksandConfig' => $this->getQuicksandConfig(),
|
||||||
));
|
));
|
||||||
|
|
||||||
$policies = array();
|
$policies = array();
|
||||||
|
|
|
@ -410,6 +410,7 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView {
|
||||||
$durable_column = id(new ConpherenceDurableColumnView())
|
$durable_column = id(new ConpherenceDurableColumnView())
|
||||||
->setSelectedConpherence(null)
|
->setSelectedConpherence(null)
|
||||||
->setUser($user)
|
->setUser($user)
|
||||||
|
->setQuicksandConfig($this->buildQuicksandConfig())
|
||||||
->setVisible($is_visible)
|
->setVisible($is_visible)
|
||||||
->setInitialLoad(true);
|
->setInitialLoad(true);
|
||||||
}
|
}
|
||||||
|
@ -585,7 +586,11 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView {
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'content' => hsprintf('%s', $response),
|
'content' => hsprintf('%s', $response),
|
||||||
);
|
) + $this->buildQuicksandConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildQuicksandConfig() {
|
||||||
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getQuicksandURIPatternBlacklist() {
|
private function getQuicksandURIPatternBlacklist() {
|
||||||
|
|
43
webroot/rsrc/externals/javelin/lib/Quicksand.js
vendored
43
webroot/rsrc/externals/javelin/lib/Quicksand.js
vendored
|
@ -30,6 +30,7 @@ JX.install('Quicksand', {
|
||||||
_cursor: 0,
|
_cursor: 0,
|
||||||
_current: 0,
|
_current: 0,
|
||||||
_content: {},
|
_content: {},
|
||||||
|
_responses: {},
|
||||||
_history: [],
|
_history: [],
|
||||||
_started: false,
|
_started: false,
|
||||||
_frameNode: null,
|
_frameNode: null,
|
||||||
|
@ -39,7 +40,7 @@ JX.install('Quicksand', {
|
||||||
/**
|
/**
|
||||||
* Start Quicksand, accepting a fate of eternal torment.
|
* Start Quicksand, accepting a fate of eternal torment.
|
||||||
*/
|
*/
|
||||||
start: function() {
|
start: function(first_response) {
|
||||||
var self = JX.Quicksand;
|
var self = JX.Quicksand;
|
||||||
if (self._started) {
|
if (self._started) {
|
||||||
return;
|
return;
|
||||||
|
@ -49,10 +50,11 @@ JX.install('Quicksand', {
|
||||||
JX.Stratcom.listen('history:change', null, self._onchange);
|
JX.Stratcom.listen('history:change', null, self._onchange);
|
||||||
|
|
||||||
self._started = true;
|
self._started = true;
|
||||||
self._history.push({
|
var path = self._getRelativeURI(window.location);
|
||||||
id: 0,
|
var id = self._id;
|
||||||
path: self._getRelativeURI(window.location)
|
self._history.push({path: path, id: id});
|
||||||
});
|
|
||||||
|
self._responses[id] = first_response;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
@ -141,18 +143,18 @@ JX.install('Quicksand', {
|
||||||
var discard = (self._history.length - self._cursor) - 1;
|
var discard = (self._history.length - self._cursor) - 1;
|
||||||
for (var ii = 0; ii < discard; ii++) {
|
for (var ii = 0; ii < discard; ii++) {
|
||||||
var obsolete = self._history.pop();
|
var obsolete = self._history.pop();
|
||||||
self._content[obsolete.id] = false;
|
self._responses[obsolete.id] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up the new state and fire a request to fetch the page content.
|
// Set up the new state and fire a request to fetch the page data.
|
||||||
var path = self._getRelativeURI(uri);
|
var path = self._getRelativeURI(uri);
|
||||||
var id = ++self._id;
|
var id = ++self._id;
|
||||||
|
|
||||||
|
self._history.push({path: path, id: id});
|
||||||
JX.History.push(path, id);
|
JX.History.push(path, id);
|
||||||
|
|
||||||
self._history.push({path: path, id: id});
|
|
||||||
self._cursor = (self._history.length - 1);
|
self._cursor = (self._history.length - 1);
|
||||||
self._content[id] = null;
|
self._responses[id] = null;
|
||||||
self._current = id;
|
self._current = id;
|
||||||
|
|
||||||
new JX.Workflow(href, {__quicksand__: true})
|
new JX.Workflow(href, {__quicksand__: true})
|
||||||
|
@ -162,7 +164,7 @@ JX.install('Quicksand', {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receive a response from the server with page content.
|
* Receive a response from the server with page data e.g. content.
|
||||||
*
|
*
|
||||||
* Usually we'll dump it into the page, but if the user clicked very fast
|
* Usually we'll dump it into the page, but if the user clicked very fast
|
||||||
* it might already be out of date.
|
* it might already be out of date.
|
||||||
|
@ -173,10 +175,10 @@ JX.install('Quicksand', {
|
||||||
// Before possibly updating the document, check if this response is still
|
// Before possibly updating the document, check if this response is still
|
||||||
// relevant.
|
// relevant.
|
||||||
|
|
||||||
// We don't save the new content if the user has already destroyed
|
// We don't save the new response if the user has already destroyed
|
||||||
// the navigation. They can do this by pressing back, then clicking
|
// the navigation. They can do this by pressing back, then clicking
|
||||||
// another link before the content can load.
|
// another link before the response can load.
|
||||||
if (self._content[id] === false) {
|
if (self._responses[id] === false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,6 +187,7 @@ JX.install('Quicksand', {
|
||||||
// save it.
|
// save it.
|
||||||
var new_content = JX.$H(r.content).getFragment();
|
var new_content = JX.$H(r.content).getFragment();
|
||||||
self._content[id] = new_content;
|
self._content[id] = new_content;
|
||||||
|
self._responses[id] = r;
|
||||||
|
|
||||||
// If it's the current page, draw it into the browser. It might not be
|
// If it's the current page, draw it into the browser. It might not be
|
||||||
// the current page if the user already clicked another link.
|
// the current page if the user already clicked another link.
|
||||||
|
@ -208,7 +211,7 @@ JX.install('Quicksand', {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!self._content[self._current]) {
|
if (!self._responses[self._current]) {
|
||||||
// If we don't have this page yet, we can't draw it. We'll draw it
|
// If we don't have this page yet, we can't draw it. We'll draw it
|
||||||
// when it arrives.
|
// when it arrives.
|
||||||
return;
|
return;
|
||||||
|
@ -225,10 +228,18 @@ JX.install('Quicksand', {
|
||||||
|
|
||||||
// Now, replace it with the new content.
|
// Now, replace it with the new content.
|
||||||
JX.DOM.setContent(self._frameNode, self._content[self._current]);
|
JX.DOM.setContent(self._frameNode, self._content[self._current]);
|
||||||
|
// Let other things redraw, etc as necessary
|
||||||
|
JX.Stratcom.invoke(
|
||||||
|
'quicksand-redraw',
|
||||||
|
null,
|
||||||
|
{
|
||||||
|
newResponse: self._responses[self._current],
|
||||||
|
oldResponse: self._responses[self._onpage]
|
||||||
|
});
|
||||||
|
|
||||||
|
self._responses[self._onpage] = self._responses[self._current];
|
||||||
self._onpage = self._current;
|
self._onpage = self._current;
|
||||||
|
|
||||||
// Scroll to the top of the page and trigger any layout adjustments.
|
// Scroll to the top of the page and trigger any layout adjustments.
|
||||||
|
|
||||||
// TODO: Maybe store the scroll position?
|
// TODO: Maybe store the scroll position?
|
||||||
JX.DOM.scrollToPosition(0, 0);
|
JX.DOM.scrollToPosition(0, 0);
|
||||||
JX.Stratcom.invoke('resize');
|
JX.Stratcom.invoke('resize');
|
||||||
|
|
|
@ -61,7 +61,7 @@ JX.behavior('durable-column', function(config, statics) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _toggleColumn(explicit) {
|
function _toggleColumn() {
|
||||||
userVisible = !userVisible;
|
userVisible = !userVisible;
|
||||||
_updateColumnVisibility();
|
_updateColumnVisibility();
|
||||||
|
|
||||||
|
@ -100,7 +100,8 @@ JX.behavior('durable-column', function(config, statics) {
|
||||||
|
|
||||||
scrollbar = new JX.Scrollbar(_getColumnScrollNode());
|
scrollbar = new JX.Scrollbar(_getColumnScrollNode());
|
||||||
|
|
||||||
JX.Quicksand.start();
|
JX.Quicksand.setFrame(userVisible ? quick : null);
|
||||||
|
JX.Quicksand.start(config.quicksandConfig);
|
||||||
|
|
||||||
/* Conpherence Thread Manager configuration - lots of display
|
/* Conpherence Thread Manager configuration - lots of display
|
||||||
* callbacks.
|
* callbacks.
|
||||||
|
|
Loading…
Reference in a new issue