Page MenuHomePhorge

No OneTemporary

diff --git a/webroot/rsrc/js/application/core/ShapedRequest.js b/webroot/rsrc/js/application/core/ShapedRequest.js
index dd03b30def..0f0e0d68d1 100644
--- a/webroot/rsrc/js/application/core/ShapedRequest.js
+++ b/webroot/rsrc/js/application/core/ShapedRequest.js
@@ -1,93 +1,94 @@
/**
* @requires javelin-install
* javelin-util
* javelin-request
* @provides phabricator-shaped-request
* @javelin
*/
/**
* Send requests with rate limiting and retries, in response to some application
* trigger. This is used to implement comment previews in Differential and
* Maniphest.
*/
JX.install('PhabricatorShapedRequest', {
construct : function(uri, callback, data_callback) {
this._uri = uri;
this._callback = callback;
this._dataCallback = data_callback;
},
members : {
_callback : null,
_dataCallback : null,
_request : null,
_min : null,
_defer : null,
_last : null,
start : function() {
this.trigger();
},
trigger : function() {
if (this._request) {
// Waiting on a request, rate-limit.
return;
}
if (this._min && (new Date().getTime() < this._min)) {
// Just got a request back, rate-limit.
return;
}
- this._defer && this._defer.stop();
-
+ clearTimeout(this._defer);
var data = this._dataCallback();
if (this.shouldSendRequest(this._last, data)) {
this._last = data;
var request = new JX.Request(this._uri, JX.bind(this, function(r) {
this._callback(r);
this._min = new Date().getTime() + this.getRateLimit();
- this._defer && this._defer.stop();
- this._defer = JX.defer(
+ clearTimeout(this._defer);
+ this._defer = setTimeout(
JX.bind(this, this.trigger),
- this.getRateLimit());
+ this.getRateLimit()
+ );
}));
request.listen('finally', JX.bind(this, function() {
this._request = null;
}));
request.setData(data);
request.setTimeout(this.getRequestTimeout());
request.send();
} else {
- this._defer = JX.defer(
+ this._defer = setTimeout(
JX.bind(this, this.trigger),
- this.getFrequency());
+ this.getFrequency()
+ );
}
},
shouldSendRequest : function(last, data) {
if (last === null) {
return true;
}
for (var k in last) {
if (data[k] !== last[k]) {
return true;
}
}
return false;
}
},
properties : {
rateLimit : 500,
frequency : 1000,
requestTimeout : 20000
}
});
diff --git a/webroot/rsrc/js/application/core/behavior-drag-and-drop.js b/webroot/rsrc/js/application/core/behavior-drag-and-drop.js
index 623fa92cbc..280a62292a 100644
--- a/webroot/rsrc/js/application/core/behavior-drag-and-drop.js
+++ b/webroot/rsrc/js/application/core/behavior-drag-and-drop.js
@@ -1,92 +1,92 @@
/**
* @provides javelin-behavior-aphront-drag-and-drop
* @requires javelin-behavior
* javelin-dom
* javelin-util
* phabricator-drag-and-drop-file-upload
*/
JX.behavior('aphront-drag-and-drop', function(config) {
// The control renders hidden by default; if we don't have support for
// drag-and-drop just leave it hidden.
if (!JX.PhabricatorDragAndDropFileUpload.isSupported()) {
return;
}
// Show the control, since we have browser support.
JX.$(config.control).style.display = '';
var files = config.value || {};
var pending = 0;
var list = JX.$(config.list);
var drop = new JX.PhabricatorDragAndDropFileUpload(JX.$(config.target))
.setActivatedClass(config.activatedClass)
.setURI(config.uri);
drop.listen('willUpload', function(f) {
pending++;
redraw();
});
drop.listen('didUpload', function(f) {
files[f.phid] = f;
// This redraws "Upload complete!"
pending--;
redraw(true);
// This redraws the instructions.
- JX.defer(redraw, 1000);
+ setTimeout(redraw, 1000);
});
drop.start();
redraw();
JX.DOM.listen(
list,
'click',
'aphront-attached-file-view-remove',
function(e) {
e.kill();
delete files[e.getTarget().getAttribute('ref')];
redraw();
});
function redraw(completed) {
var items = [];
for (var k in files) {
var file = files[k];
items.push(JX.$N('div', {}, JX.$H(file.html)));
items.push(JX.$N(
'input',
{
type: "hidden",
name: config.name + "[" + file.phid + "]",
value: file.phid
}));
}
var status;
if (!pending) {
if (completed) {
status = JX.$H('<strong>Upload complete!</strong>');
} else {
arrow = String.fromCharCode(0x21EA);
status = JX.$H(
arrow + ' <strong>Drag and Drop</strong> files here to upload them.');
}
} else {
status = JX.$H(
'Uploading <strong>' + parseInt(pending, 10) + '<strong> files...');
}
status = JX.$N('div', {className: 'drag-and-drop-instructions'}, status);
items.push(status);
JX.DOM.setContent(list, items);
}
});
diff --git a/webroot/rsrc/js/application/core/behavior-object-selector.js b/webroot/rsrc/js/application/core/behavior-object-selector.js
index 034fa579b1..9864a329e5 100644
--- a/webroot/rsrc/js/application/core/behavior-object-selector.js
+++ b/webroot/rsrc/js/application/core/behavior-object-selector.js
@@ -1,185 +1,183 @@
/**
* @provides javelin-behavior-phabricator-object-selector
* @requires javelin-behavior
* javelin-dom
* javelin-request
* javelin-util
* javelin-stratcom
*/
JX.behavior('phabricator-object-selector', function(config) {
var n = 0;
var phids = {};
var handles = config.handles;
for (var k in handles) {
phids[k] = true;
}
var attach_list = {};
var query_timer = null;
var query_delay = 50;
var phid_input = JX.DOM.find(
JX.$(config.form),
'input',
'aphront-dialog-application-input');
var last_value = JX.$(config.query).value;
function onreceive(seq, r) {
if (seq != n) {
return;
}
var display = [];
attach_list = {};
for (var k in r) {
handles[r[k].phid] = r[k];
display.push(renderHandle(r[k], true));
}
if (!display.length) {
display = renderNote('No results.');
}
JX.DOM.setContent(JX.$(config.results), display);
}
function redrawAttached() {
var display = [];
for (var k in phids) {
display.push(renderHandle(handles[k], false));
}
if (!display.length) {
display = renderNote('Nothing attached.');
}
JX.DOM.setContent(JX.$(config.current), display);
phid_input.value = JX.keys(phids).join(';');
}
function renderHandle(h, attach) {
var link = JX.$N(
'a',
{href : h.uri, target : '_blank'},
h.name);
var td = JX.$N('td');
var table = JX.$N(
'table',
{className: 'phabricator-object-selector-handle'},
JX.$N(
'tbody',
{},
[JX.$N('th', {}, link), td]));
var btn = JX.$N(
'a',
{className: 'button small grey'},
attach ? 'Select' : 'Remove');
JX.Stratcom.addSigil(btn, 'object-attach-button');
JX.Stratcom.addData(btn, {handle : h, table : table});
if (attach) {
attach_list[h.phid] = btn;
if (h.phid in phids) {
JX.DOM.alterClass(btn, 'disabled', true);
btn.disabled = true;
}
}
JX.DOM.setContent(td, btn);
return table;
}
function renderNote(note) {
return JX.$N('div', {className : 'object-selector-nothing'}, note);
}
function sendQuery() {
query_timer = null;
JX.DOM.setContent(JX.$(config.results), renderNote('Loading...'))
new JX.Request(config.uri, JX.bind(null, onreceive, ++n))
.setData({
filter: JX.$(config.filter).value,
query: JX.$(config.query).value
})
.send();
}
JX.DOM.listen(
JX.$(config.results),
'click',
'object-attach-button',
function(e) {
e.kill();
var button = e.getNode('object-attach-button');
if (button.disabled) {
return;
}
var data = e.getNodeData('object-attach-button');
phids[data.handle.phid] = true;
JX.DOM.alterClass(button, 'disabled', true);
button.disabled = true;
redrawAttached();
});
JX.DOM.listen(
JX.$(config.current),
'click',
'object-attach-button',
function(e) {
e.kill();
var button = e.getNode('object-attach-button');
if (button.disabled) {
return;
}
var data = e.getNodeData('object-attach-button');
delete phids[data.handle.phid];
if (attach_list[data.handle.phid]) {
JX.DOM.alterClass(attach_list[data.handle.phid], 'disabled', false);
attach_list[data.handle.phid].disabled = false;
}
redrawAttached();
});
JX.DOM.listen(
JX.$(config.filter),
'change',
null,
function(e) {
e.kill();
sendQuery();
});
JX.DOM.listen(
JX.$(config.query),
['change', 'keydown', 'keyup', 'keypress'],
null,
function(e) {
var cur_value = JX.$(config.query).value;
if (last_value == cur_value) {
return;
}
last_value = cur_value;
- if (query_timer) {
- query_timer.stop();
- }
- query_timer = JX.defer(sendQuery, query_delay);
+ clearTimeout(query_timer);
+ query_timer = setTimeout(sendQuery, query_delay);
});
sendQuery();
redrawAttached();
});
diff --git a/webroot/rsrc/js/application/core/behavior-watch-anchor.js b/webroot/rsrc/js/application/core/behavior-watch-anchor.js
index 0fc429b04a..8d8c0e5ca1 100644
--- a/webroot/rsrc/js/application/core/behavior-watch-anchor.js
+++ b/webroot/rsrc/js/application/core/behavior-watch-anchor.js
@@ -1,34 +1,33 @@
/**
* @provides javelin-behavior-phabricator-watch-anchor
* @requires javelin-behavior
* javelin-stratcom
* javelin-util
* javelin-dom
*/
JX.behavior('phabricator-watch-anchor', function() {
var highlighted;
function highlight() {
highlighted && JX.DOM.alterClass(highlighted, 'anchor-target', false);
try {
highlighted = JX.$('anchor-' + window.location.hash.replace('#', ''));
JX.DOM.alterClass(highlighted, 'anchor-target', true);
} catch (ex) {
if (ex === JX.$.NotFound) {
highlighted = null;
} else {
throw ex;
}
}
}
- JX.Stratcom.listen(
- 'hashchange',
- null,
- // Defer invocation so other listeners can update the document.
- function() { JX.defer(highlight); });
-
- JX.defer(highlight);
+ // Defer invocation so other listeners can update the document.
+ var fn = function() {
+ setTimeout(highlight, 0);
+ };
+ JX.Stratcom.listen('hashchange', null, fn);
+ fn();
});
diff --git a/webroot/rsrc/js/application/countdown/timer.js b/webroot/rsrc/js/application/countdown/timer.js
index ef944e6cd0..c7de7b7582 100644
--- a/webroot/rsrc/js/application/countdown/timer.js
+++ b/webroot/rsrc/js/application/countdown/timer.js
@@ -1,48 +1,48 @@
/**
* @provides javelin-behavior-countdown-timer
* @requires javelin-behavior
* javelin-dom
* javelin-util
*/
JX.behavior('countdown-timer', function(config) {
calculateTimeLeft();
function calculateTimeLeft() {
var days = 0;
var hours = 0;
var minutes = 0;
var seconds = 0;
var current_timestamp = Math.round(new Date() / 1000);
var delta = config.timestamp - current_timestamp;
if (delta <= 0) {
JX.DOM.setContent(JX.$('phabricator-timer-days'), days);
JX.DOM.setContent(JX.$('phabricator-timer-hours'), hours);
JX.DOM.setContent(JX.$('phabricator-timer-minutes'), minutes);
JX.DOM.setContent(JX.$('phabricator-timer-seconds'), seconds);
return;
}
days = Math.floor(delta/86400);
delta -= days * 86400;
hours = Math.floor(delta/3600);
delta -= hours * 3600;
minutes = Math.floor(delta / 60);
delta -= minutes * 60;
seconds = delta;
JX.DOM.setContent(JX.$('phabricator-timer-days'), days);
JX.DOM.setContent(JX.$('phabricator-timer-hours'), hours);
JX.DOM.setContent(JX.$('phabricator-timer-minutes'), minutes);
JX.DOM.setContent(JX.$('phabricator-timer-seconds'), seconds);
- JX.defer(calculateTimeLeft, 1000);
+ setTimeout(calculateTimeLeft, 1000);
}
});
diff --git a/webroot/rsrc/js/application/diffusion/behavior-jump-to.js b/webroot/rsrc/js/application/diffusion/behavior-jump-to.js
index 46604a4d66..6c51dc814a 100644
--- a/webroot/rsrc/js/application/diffusion/behavior-jump-to.js
+++ b/webroot/rsrc/js/application/diffusion/behavior-jump-to.js
@@ -1,17 +1,15 @@
/**
* @provides javelin-behavior-diffusion-jump-to
* @requires javelin-behavior
* javelin-util
* javelin-vector
* javelin-dom
*/
JX.behavior('diffusion-jump-to', function(config) {
- JX.defer(
- function() {
- window.scrollTo(0, JX.$V(JX.$(config.target)).y - 100);
- });
+ setTimeout(function() {
+ window.scrollTo(0, JX.$V(JX.$(config.target)).y - 100);
+ }, 0);
});
-
diff --git a/webroot/rsrc/js/application/herald/PathTypeahead.js b/webroot/rsrc/js/application/herald/PathTypeahead.js
index 7ef3a9b094..988d728ced 100644
--- a/webroot/rsrc/js/application/herald/PathTypeahead.js
+++ b/webroot/rsrc/js/application/herald/PathTypeahead.js
@@ -1,206 +1,205 @@
/**
* @requires javelin-install
* javelin-typeahead
* javelin-dom
* javelin-request
* javelin-typeahead-ondemand-source
* javelin-util
* @provides path-typeahead
* @javelin
*/
JX.install('PathTypeahead', {
construct : function(config) {
this._repositorySelect = config.repo_select;
this._hardpoint = config.hardpoint;
this._input = config.path_input;
this._completeURI = config.completeURI;
this._validateURI = config.validateURI;
this._errorDisplay = config.error_display;
/*
* Default values to preload the typeahead with, for extremely common
* cases.
*/
this._textInputValues = config.repositoryDefaultPaths;
this._initializeDatasource();
this._initializeTypeahead(this._input);
},
members : {
/*
* DOM <select> elem for choosing the repository of a path.
*/
_repositorySelect : null,
/*
* DOM parent div "hardpoint" to be passed to the JX.Typeahead.
*/
_hardpoint : null,
/*
* DOM element to display errors.
*/
_errorDisplay : null,
/*
* URI to query for typeahead results, to be passed to the
* TypeaheadOnDemandSource.
*/
_completeURI : null,
/*
* Underlying JX.TypeaheadOnDemandSource instance
*/
_datasource : null,
/*
* Underlying JX.Typeahead instance
*/
_typeahead : null,
/*
* Underlying input
*/
_input : null,
/*
* Whenever the user changes the typeahead value, we track the change
* here, keyed by the selected repository ID. That way, we can restore
* typed values if they change the repository choice and then change back.
*/
_textInputValues : null,
/*
* Configurable endpoint for server-side path validation
*/
_validateURI : null,
/*
* Keep the validation AJAX request so we don't send several.
*/
_validationInflight : null,
/*
* Installs path-specific behaviors and then starts the underlying
* typeahead.
*/
start : function() {
if (this._typeahead.getValue()) {
this._textInputValues[this._repositorySelect.value] =
this._typeahead.getValue();
}
this._typeahead.listen(
'change',
JX.bind(this, function(value) {
this._textInputValues[this._repositorySelect.value] = value;
this._validate();
}));
this._typeahead.listen(
'choose',
JX.bind(this, function() {
- JX.defer(
- JX.bind(this._typeahead, this._typeahead.refresh));
+ setTimeout(JX.bind(this._typeahead, this._typeahead.refresh), 0);
}));
var repo_set_input = JX.bind(this, this._onrepochange);
this._typeahead.listen('start', repo_set_input);
JX.DOM.listen(
this._repositorySelect,
'change',
null,
repo_set_input);
this._typeahead.start();
this._validate();
},
_onrepochange : function() {
this._setPathInputBasedOnRepository(
this._typeahead,
this._textInputValues);
this._datasource.setAuxiliaryData(
{repositoryPHID : this._repositorySelect.value}
);
},
_setPathInputBasedOnRepository : function(typeahead, lookup) {
if (lookup[this._repositorySelect.value]) {
typeahead.setValue(lookup[this._repositorySelect.value]);
} else {
typeahead.setValue('/');
}
},
_initializeDatasource : function() {
this._datasource = new JX.TypeaheadOnDemandSource(this._completeURI);
this._datasource.setNormalizer(this._datasourceNormalizer);
this._datasource.setQueryDelay(40);
},
/*
* Construct and initialize the Typeahead.
* Must be called after initializing the datasource.
*/
_initializeTypeahead : function(path_input) {
this._typeahead = new JX.Typeahead(this._hardpoint, path_input);
this._datasource.setMaximumResultCount(15);
this._typeahead.setDatasource(this._datasource);
},
_datasourceNormalizer : function(str) {
return ('' + str).replace(/[\/]+/g, '\/');
},
_validate : function() {
var input = this._input;
var repo_id = this._repositorySelect.value;
var input_value = input.value;
var error_display = this._errorDisplay;
if (!input_value.length) {
input.value = '/';
input_value = '/';
}
if (this._validationInflight) {
this._validationInflight.abort();
this._validationInflight = null;
}
var validation_request = new JX.Request(
this._validateURI,
function(payload) {
// Don't change validation display state if the input has been
// changed since we started validation
if (input.value === input_value) {
if (payload.valid) {
JX.DOM.alterClass(error_display, 'invalid', false);
JX.DOM.alterClass(error_display, 'valid', true);
} else {
JX.DOM.alterClass(error_display, 'invalid', true);
JX.DOM.alterClass(error_display, 'valid', false);
}
JX.DOM.setContent(error_display, payload.message);
}
});
validation_request.listen('finally', function() {
JX.DOM.alterClass(error_display, 'validating', false);
this._validationInflight = null;
});
validation_request.setData(
{
repositoryPHID : repo_id,
path : input_value
});
this._validationInflight = validation_request;
validation_request.setTimeout(750);
validation_request.send();
}
}
});

File Metadata

Mime Type
text/x-diff
Expires
Sun, Jan 19, 17:47 (1 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1127120
Default Alt Text
(19 KB)

Event Timeline