mirror of
https://git.tt-rss.org/git/tt-rss.git
synced 2025-12-14 10:05:56 +00:00
build custom layer of Dojo to speed up loading of tt-rss (refs #293)
This commit is contained in:
@@ -5,126 +5,338 @@
|
||||
*/
|
||||
|
||||
|
||||
if(!dojo._hasResource["dojo._base.Deferred"]){
|
||||
dojo._hasResource["dojo._base.Deferred"]=true;
|
||||
if(!dojo._hasResource["dojo._base.Deferred"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
||||
dojo._hasResource["dojo._base.Deferred"] = true;
|
||||
dojo.provide("dojo._base.Deferred");
|
||||
dojo.require("dojo._base.lang");
|
||||
|
||||
(function(){
|
||||
var _1=function(){
|
||||
};
|
||||
var _2=Object.freeze||function(){
|
||||
};
|
||||
dojo.Deferred=function(_3){
|
||||
var _4,_5,_6,_7,_8;
|
||||
var _9=this.promise={};
|
||||
function _a(_b){
|
||||
if(_5){
|
||||
throw new Error("This deferred has already been resolved");
|
||||
}
|
||||
_4=_b;
|
||||
_5=true;
|
||||
_c();
|
||||
};
|
||||
function _c(){
|
||||
var _d;
|
||||
while(!_d&&_8){
|
||||
var _e=_8;
|
||||
_8=_8.next;
|
||||
if(_d=(_e.progress==_1)){
|
||||
_5=false;
|
||||
}
|
||||
var _f=(_6?_e.error:_e.resolved);
|
||||
if(_f){
|
||||
try{
|
||||
var _10=_f(_4);
|
||||
if(_10&&typeof _10.then==="function"){
|
||||
_10.then(dojo.hitch(_e.deferred,"resolve"),dojo.hitch(_e.deferred,"reject"));
|
||||
continue;
|
||||
}
|
||||
var _11=_d&&_10===undefined;
|
||||
_e.deferred[_11&&_6?"reject":"resolve"](_11?_4:_10);
|
||||
}
|
||||
catch(e){
|
||||
_e.deferred.reject(e);
|
||||
}
|
||||
}else{
|
||||
if(_6){
|
||||
_e.deferred.reject(_4);
|
||||
}else{
|
||||
_e.deferred.resolve(_4);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
this.resolve=this.callback=function(_12){
|
||||
this.fired=0;
|
||||
this.results=[_12,null];
|
||||
_a(_12);
|
||||
};
|
||||
this.reject=this.errback=function(_13){
|
||||
_6=true;
|
||||
this.fired=1;
|
||||
_a(_13);
|
||||
this.results=[null,_13];
|
||||
if(!_13||_13.log!==false){
|
||||
(dojo.config.deferredOnError||function(x){
|
||||
console.error(x);
|
||||
})(_13);
|
||||
}
|
||||
};
|
||||
this.progress=function(_14){
|
||||
var _15=_8;
|
||||
while(_15){
|
||||
var _16=_15.progress;
|
||||
_16&&_16(_14);
|
||||
_15=_15.next;
|
||||
}
|
||||
};
|
||||
this.addCallbacks=function(_17,_18){
|
||||
this.then(_17,_18,_1);
|
||||
return this;
|
||||
};
|
||||
this.then=_9.then=function(_19,_1a,_1b){
|
||||
var _1c=_1b==_1?this:new dojo.Deferred(_9.cancel);
|
||||
var _1d={resolved:_19,error:_1a,progress:_1b,deferred:_1c};
|
||||
if(_8){
|
||||
_7=_7.next=_1d;
|
||||
}else{
|
||||
_8=_7=_1d;
|
||||
}
|
||||
if(_5){
|
||||
_c();
|
||||
}
|
||||
return _1c.promise;
|
||||
};
|
||||
var _1e=this;
|
||||
this.cancel=_9.cancel=function(){
|
||||
if(!_5){
|
||||
var _1f=_3&&_3(_1e);
|
||||
if(!_5){
|
||||
if(!(_1f instanceof Error)){
|
||||
_1f=new Error(_1f);
|
||||
}
|
||||
_1f.log=false;
|
||||
_1e.reject(_1f);
|
||||
}
|
||||
}
|
||||
};
|
||||
_2(_9);
|
||||
};
|
||||
dojo.extend(dojo.Deferred,{addCallback:function(_20){
|
||||
return this.addCallbacks(dojo.hitch.apply(dojo,arguments));
|
||||
},addErrback:function(_21){
|
||||
return this.addCallbacks(null,dojo.hitch.apply(dojo,arguments));
|
||||
},addBoth:function(_22){
|
||||
var _23=dojo.hitch.apply(dojo,arguments);
|
||||
return this.addCallbacks(_23,_23);
|
||||
},fired:-1});
|
||||
var mutator = function(){};
|
||||
var freeze = Object.freeze || function(){};
|
||||
// A deferred provides an API for creating and resolving a promise.
|
||||
dojo.Deferred = function(/*Function?*/canceller){
|
||||
// summary:
|
||||
// Deferreds provide a generic means for encapsulating an asynchronous
|
||||
// operation and notifying users of the completion and result of the operation.
|
||||
// description:
|
||||
// The dojo.Deferred API is based on the concept of promises that provide a
|
||||
// generic interface into the eventual completion of an asynchronous action.
|
||||
// The motivation for promises fundamentally is about creating a
|
||||
// separation of concerns that allows one to achieve the same type of
|
||||
// call patterns and logical data flow in asynchronous code as can be
|
||||
// achieved in synchronous code. Promises allows one
|
||||
// to be able to call a function purely with arguments needed for
|
||||
// execution, without conflating the call with concerns of whether it is
|
||||
// sync or async. One shouldn't need to alter a call's arguments if the
|
||||
// implementation switches from sync to async (or vice versa). By having
|
||||
// async functions return promises, the concerns of making the call are
|
||||
// separated from the concerns of asynchronous interaction (which are
|
||||
// handled by the promise).
|
||||
//
|
||||
// The dojo.Deferred is a type of promise that provides methods for fulfilling the
|
||||
// promise with a successful result or an error. The most important method for
|
||||
// working with Dojo's promises is the then() method, which follows the
|
||||
// CommonJS proposed promise API. An example of using a Dojo promise:
|
||||
//
|
||||
// | var resultingPromise = someAsyncOperation.then(function(result){
|
||||
// | ... handle result ...
|
||||
// | },
|
||||
// | function(error){
|
||||
// | ... handle error ...
|
||||
// | });
|
||||
//
|
||||
// The .then() call returns a new promise that represents the result of the
|
||||
// execution of the callback. The callbacks will never affect the original promises value.
|
||||
//
|
||||
// The dojo.Deferred instances also provide the following functions for backwards compatibility:
|
||||
//
|
||||
// * addCallback(handler)
|
||||
// * addErrback(handler)
|
||||
// * callback(result)
|
||||
// * errback(result)
|
||||
//
|
||||
// Callbacks are allowed to return promisesthemselves, so
|
||||
// you can build complicated sequences of events with ease.
|
||||
//
|
||||
// The creator of the Deferred may specify a canceller. The canceller
|
||||
// is a function that will be called if Deferred.cancel is called
|
||||
// before the Deferred fires. You can use this to implement clean
|
||||
// aborting of an XMLHttpRequest, etc. Note that cancel will fire the
|
||||
// deferred with a CancelledError (unless your canceller returns
|
||||
// another kind of error), so the errbacks should be prepared to
|
||||
// handle that error for cancellable Deferreds.
|
||||
// example:
|
||||
// | var deferred = new dojo.Deferred();
|
||||
// | setTimeout(function(){ deferred.callback({success: true}); }, 1000);
|
||||
// | return deferred;
|
||||
// example:
|
||||
// Deferred objects are often used when making code asynchronous. It
|
||||
// may be easiest to write functions in a synchronous manner and then
|
||||
// split code using a deferred to trigger a response to a long-lived
|
||||
// operation. For example, instead of register a callback function to
|
||||
// denote when a rendering operation completes, the function can
|
||||
// simply return a deferred:
|
||||
//
|
||||
// | // callback style:
|
||||
// | function renderLotsOfData(data, callback){
|
||||
// | var success = false
|
||||
// | try{
|
||||
// | for(var x in data){
|
||||
// | renderDataitem(data[x]);
|
||||
// | }
|
||||
// | success = true;
|
||||
// | }catch(e){ }
|
||||
// | if(callback){
|
||||
// | callback(success);
|
||||
// | }
|
||||
// | }
|
||||
//
|
||||
// | // using callback style
|
||||
// | renderLotsOfData(someDataObj, function(success){
|
||||
// | // handles success or failure
|
||||
// | if(!success){
|
||||
// | promptUserToRecover();
|
||||
// | }
|
||||
// | });
|
||||
// | // NOTE: no way to add another callback here!!
|
||||
// example:
|
||||
// Using a Deferred doesn't simplify the sending code any, but it
|
||||
// provides a standard interface for callers and senders alike,
|
||||
// providing both with a simple way to service multiple callbacks for
|
||||
// an operation and freeing both sides from worrying about details
|
||||
// such as "did this get called already?". With Deferreds, new
|
||||
// callbacks can be added at any time.
|
||||
//
|
||||
// | // Deferred style:
|
||||
// | function renderLotsOfData(data){
|
||||
// | var d = new dojo.Deferred();
|
||||
// | try{
|
||||
// | for(var x in data){
|
||||
// | renderDataitem(data[x]);
|
||||
// | }
|
||||
// | d.callback(true);
|
||||
// | }catch(e){
|
||||
// | d.errback(new Error("rendering failed"));
|
||||
// | }
|
||||
// | return d;
|
||||
// | }
|
||||
//
|
||||
// | // using Deferred style
|
||||
// | renderLotsOfData(someDataObj).then(null, function(){
|
||||
// | promptUserToRecover();
|
||||
// | });
|
||||
// | // NOTE: addErrback and addCallback both return the Deferred
|
||||
// | // again, so we could chain adding callbacks or save the
|
||||
// | // deferred for later should we need to be notified again.
|
||||
// example:
|
||||
// In this example, renderLotsOfData is syncrhonous and so both
|
||||
// versions are pretty artificial. Putting the data display on a
|
||||
// timeout helps show why Deferreds rock:
|
||||
//
|
||||
// | // Deferred style and async func
|
||||
// | function renderLotsOfData(data){
|
||||
// | var d = new dojo.Deferred();
|
||||
// | setTimeout(function(){
|
||||
// | try{
|
||||
// | for(var x in data){
|
||||
// | renderDataitem(data[x]);
|
||||
// | }
|
||||
// | d.callback(true);
|
||||
// | }catch(e){
|
||||
// | d.errback(new Error("rendering failed"));
|
||||
// | }
|
||||
// | }, 100);
|
||||
// | return d;
|
||||
// | }
|
||||
//
|
||||
// | // using Deferred style
|
||||
// | renderLotsOfData(someDataObj).then(null, function(){
|
||||
// | promptUserToRecover();
|
||||
// | });
|
||||
//
|
||||
// Note that the caller doesn't have to change his code at all to
|
||||
// handle the asynchronous case.
|
||||
var result, finished, isError, head, nextListener;
|
||||
var promise = this.promise = {};
|
||||
|
||||
function complete(value){
|
||||
if(finished){
|
||||
throw new Error("This deferred has already been resolved");
|
||||
}
|
||||
result = value;
|
||||
finished = true;
|
||||
notify();
|
||||
}
|
||||
function notify(){
|
||||
var mutated;
|
||||
while(!mutated && nextListener){
|
||||
var listener = nextListener;
|
||||
nextListener = nextListener.next;
|
||||
if(mutated = (listener.progress == mutator)){ // assignment and check
|
||||
finished = false;
|
||||
}
|
||||
var func = (isError ? listener.error : listener.resolved);
|
||||
if (func) {
|
||||
try {
|
||||
var newResult = func(result);
|
||||
if (newResult && typeof newResult.then === "function") {
|
||||
newResult.then(dojo.hitch(listener.deferred, "resolve"), dojo.hitch(listener.deferred, "reject"));
|
||||
continue;
|
||||
}
|
||||
var unchanged = mutated && newResult === undefined;
|
||||
listener.deferred[unchanged && isError ? "reject" : "resolve"](unchanged ? result : newResult);
|
||||
}
|
||||
catch (e) {
|
||||
listener.deferred.reject(e);
|
||||
}
|
||||
}else {
|
||||
if(isError){
|
||||
listener.deferred.reject(result);
|
||||
}else{
|
||||
listener.deferred.resolve(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// calling resolve will resolve the promise
|
||||
this.resolve = this.callback = function(value){
|
||||
// summary:
|
||||
// Fulfills the Deferred instance successfully with the provide value
|
||||
this.fired = 0;
|
||||
this.results = [value, null];
|
||||
complete(value);
|
||||
};
|
||||
|
||||
|
||||
// calling error will indicate that the promise failed
|
||||
this.reject = this.errback = function(error){
|
||||
// summary:
|
||||
// Fulfills the Deferred instance as an error with the provided error
|
||||
isError = true;
|
||||
this.fired = 1;
|
||||
complete(error);
|
||||
this.results = [null, error];
|
||||
if(!error || error.log !== false){
|
||||
(dojo.config.deferredOnError || function(x){ console.error(x); })(error);
|
||||
}
|
||||
};
|
||||
// call progress to provide updates on the progress on the completion of the promise
|
||||
this.progress = function(update){
|
||||
// summary
|
||||
// Send progress events to all listeners
|
||||
var listener = nextListener;
|
||||
while(listener){
|
||||
var progress = listener.progress;
|
||||
progress && progress(update);
|
||||
listener = listener.next;
|
||||
}
|
||||
};
|
||||
this.addCallbacks = function(/*Function?*/callback, /*Function?*/errback){
|
||||
this.then(callback, errback, mutator);
|
||||
return this;
|
||||
};
|
||||
// provide the implementation of the promise
|
||||
this.then = promise.then = function(/*Function?*/resolvedCallback, /*Function?*/errorCallback, /*Function?*/progressCallback){
|
||||
// summary
|
||||
// Adds a fulfilledHandler, errorHandler, and progressHandler to be called for
|
||||
// completion of a promise. The fulfilledHandler is called when the promise
|
||||
// is fulfilled. The errorHandler is called when a promise fails. The
|
||||
// progressHandler is called for progress events. All arguments are optional
|
||||
// and non-function values are ignored. The progressHandler is not only an
|
||||
// optional argument, but progress events are purely optional. Promise
|
||||
// providers are not required to ever create progress events.
|
||||
//
|
||||
// This function will return a new promise that is fulfilled when the given
|
||||
// fulfilledHandler or errorHandler callback is finished. This allows promise
|
||||
// operations to be chained together. The value returned from the callback
|
||||
// handler is the fulfillment value for the returned promise. If the callback
|
||||
// throws an error, the returned promise will be moved to failed state.
|
||||
//
|
||||
// example:
|
||||
// An example of using a CommonJS compliant promise:
|
||||
// | asyncComputeTheAnswerToEverything().
|
||||
// | then(addTwo).
|
||||
// | then(printResult, onError);
|
||||
// | >44
|
||||
//
|
||||
var returnDeferred = progressCallback == mutator ? this : new dojo.Deferred(promise.cancel);
|
||||
var listener = {
|
||||
resolved: resolvedCallback,
|
||||
error: errorCallback,
|
||||
progress: progressCallback,
|
||||
deferred: returnDeferred
|
||||
};
|
||||
if(nextListener){
|
||||
head = head.next = listener;
|
||||
}
|
||||
else{
|
||||
nextListener = head = listener;
|
||||
}
|
||||
if(finished){
|
||||
notify();
|
||||
}
|
||||
return returnDeferred.promise;
|
||||
};
|
||||
var deferred = this;
|
||||
this.cancel = promise.cancel = function () {
|
||||
// summary:
|
||||
// Cancels the asynchronous operation
|
||||
if(!finished){
|
||||
var error = canceller && canceller(deferred);
|
||||
if(!finished){
|
||||
if (!(error instanceof Error)) {
|
||||
error = new Error(error);
|
||||
}
|
||||
error.log = false;
|
||||
deferred.reject(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
freeze(promise);
|
||||
};
|
||||
dojo.extend(dojo.Deferred, {
|
||||
addCallback: function (/*Function*/callback) {
|
||||
return this.addCallbacks(dojo.hitch.apply(dojo, arguments));
|
||||
},
|
||||
|
||||
addErrback: function (/*Function*/errback) {
|
||||
return this.addCallbacks(null, dojo.hitch.apply(dojo, arguments));
|
||||
},
|
||||
|
||||
addBoth: function (/*Function*/callback) {
|
||||
var enclosed = dojo.hitch.apply(dojo, arguments);
|
||||
return this.addCallbacks(enclosed, enclosed);
|
||||
},
|
||||
fired: -1
|
||||
});
|
||||
})();
|
||||
dojo.when=function(_24,_25,_26,_27){
|
||||
if(_24&&typeof _24.then==="function"){
|
||||
return _24.then(_25,_26,_27);
|
||||
}
|
||||
return _25(_24);
|
||||
dojo.when = function(promiseOrValue, /*Function?*/callback, /*Function?*/errback, /*Function?*/progressHandler){
|
||||
// summary:
|
||||
// This provides normalization between normal synchronous values and
|
||||
// asynchronous promises, so you can interact with them in a common way
|
||||
// example:
|
||||
// | function printFirstAndList(items){
|
||||
// | dojo.when(findFirst(items), console.log);
|
||||
// | dojo.when(findLast(items), console.log);
|
||||
// | }
|
||||
// | function findFirst(items){
|
||||
// | return dojo.when(items, function(items){
|
||||
// | return items[0];
|
||||
// | });
|
||||
// | }
|
||||
// | function findLast(items){
|
||||
// | return dojo.when(items, function(items){
|
||||
// | return items[items.length];
|
||||
// | });
|
||||
// | }
|
||||
// And now all three of his functions can be used sync or async.
|
||||
// | printFirstAndLast([1,2,3,4]) will work just as well as
|
||||
// | printFirstAndLast(dojo.xhrGet(...));
|
||||
|
||||
if(promiseOrValue && typeof promiseOrValue.then === "function"){
|
||||
return promiseOrValue.then(callback, errback, progressHandler);
|
||||
}
|
||||
return callback(promiseOrValue);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user