mirror of
https://git.tt-rss.org/git/tt-rss.git
synced 2025-12-15 04:15:57 +00:00
build custom layer of Dojo to speed up loading of tt-rss (refs #293)
This commit is contained in:
@@ -5,171 +5,334 @@
|
||||
*/
|
||||
|
||||
|
||||
if(typeof window!="undefined"){
|
||||
dojo.isBrowser=true;
|
||||
dojo._name="browser";
|
||||
// a host environment specifically built for Mozilla extensions, but derived
|
||||
// from the browser host environment
|
||||
if(typeof window != 'undefined'){
|
||||
dojo.isBrowser = true;
|
||||
dojo._name = "browser";
|
||||
|
||||
|
||||
// FIXME: PORTME
|
||||
// http://developer.mozilla.org/en/mozIJSSubScriptLoader
|
||||
|
||||
|
||||
// attempt to figure out the path to dojo if it isn't set in the config
|
||||
(function(){
|
||||
var d = dojo;
|
||||
// this is a scope protection closure. We set browser versions and grab
|
||||
// the URL we were loaded from here.
|
||||
|
||||
// FIXME: need to probably use a different reference to "document" to get the hosting XUL environment
|
||||
|
||||
d.baseUrl = d.config.baseUrl;
|
||||
|
||||
// fill in the rendering support information in dojo.render.*
|
||||
var n = navigator;
|
||||
var dua = n.userAgent;
|
||||
var dav = n.appVersion;
|
||||
var tv = parseFloat(dav);
|
||||
|
||||
d.isMozilla = d.isMoz = tv;
|
||||
if(d.isMoz){
|
||||
d.isFF = parseFloat(dua.split("Firefox/")[1]) || undefined;
|
||||
}
|
||||
|
||||
// FIXME
|
||||
d.isQuirks = document.compatMode == "BackCompat";
|
||||
|
||||
// FIXME
|
||||
// TODO: is the HTML LANG attribute relevant?
|
||||
d.locale = dojo.config.locale || n.language.toLowerCase();
|
||||
|
||||
d._xhrObj = function(){
|
||||
return new XMLHttpRequest();
|
||||
}
|
||||
|
||||
// monkey-patch _loadUri to handle file://, chrome://, and resource:// url's
|
||||
var oldLoadUri = d._loadUri;
|
||||
d._loadUri = function(uri, cb){
|
||||
var handleLocal = ["file:", "chrome:", "resource:"].some(function(prefix){
|
||||
return String(uri).indexOf(prefix) == 0;
|
||||
});
|
||||
if(handleLocal){
|
||||
// see:
|
||||
// http://developer.mozilla.org/en/mozIJSSubScriptLoader
|
||||
var l = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
|
||||
.getService(Components.interfaces.mozIJSSubScriptLoader);
|
||||
var value = l.loadSubScript(uri, d.global)
|
||||
if(cb){ cb(value); }
|
||||
return true;
|
||||
}else{
|
||||
// otherwise, call the pre-existing version
|
||||
return oldLoadUri.apply(d, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: PORTME
|
||||
d._isDocumentOk = function(http){
|
||||
var stat = http.status || 0;
|
||||
return (stat >= 200 && stat < 300) || // Boolean
|
||||
stat == 304 || // allow any 2XX response code
|
||||
stat == 1223 || // get it out of the cache
|
||||
(!stat && (location.protocol=="file:" || location.protocol=="chrome:") );
|
||||
}
|
||||
|
||||
// FIXME: PORTME
|
||||
// var owloc = window.location+"";
|
||||
// var base = document.getElementsByTagName("base");
|
||||
// var hasBase = (base && base.length > 0);
|
||||
var hasBase = false;
|
||||
|
||||
d._getText = function(/*URI*/ uri, /*Boolean*/ fail_ok){
|
||||
// summary: Read the contents of the specified uri and return those contents.
|
||||
// uri:
|
||||
// A relative or absolute uri. If absolute, it still must be in
|
||||
// the same "domain" as we are.
|
||||
// fail_ok:
|
||||
// Default false. If fail_ok and loading fails, return null
|
||||
// instead of throwing.
|
||||
// returns: The response text. null is returned when there is a
|
||||
// failure and failure is okay (an exception otherwise)
|
||||
|
||||
// alert("_getText: " + uri);
|
||||
|
||||
// NOTE: must be declared before scope switches ie. this._xhrObj()
|
||||
var http = d._xhrObj();
|
||||
|
||||
if(!hasBase && dojo._Url){
|
||||
uri = (new dojo._Url(uri)).toString();
|
||||
}
|
||||
if(d.config.cacheBust){
|
||||
//Make sure we have a string before string methods are used on uri
|
||||
uri += "";
|
||||
uri += (uri.indexOf("?") == -1 ? "?" : "&") + String(d.config.cacheBust).replace(/\W+/g,"");
|
||||
}
|
||||
var handleLocal = ["file:", "chrome:", "resource:"].some(function(prefix){
|
||||
return String(uri).indexOf(prefix) == 0;
|
||||
});
|
||||
if(handleLocal){
|
||||
// see:
|
||||
// http://forums.mozillazine.org/viewtopic.php?p=921150#921150
|
||||
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.interfaces.nsIIOService);
|
||||
var scriptableStream=Components
|
||||
.classes["@mozilla.org/scriptableinputstream;1"]
|
||||
.getService(Components.interfaces.nsIScriptableInputStream);
|
||||
|
||||
var channel = ioService.newChannel(uri, null, null);
|
||||
var input = channel.open();
|
||||
scriptableStream.init(input);
|
||||
var str = scriptableStream.read(input.available());
|
||||
scriptableStream.close();
|
||||
input.close();
|
||||
return str;
|
||||
}else{
|
||||
http.open('GET', uri, false);
|
||||
try{
|
||||
http.send(null);
|
||||
// alert(http);
|
||||
if(!d._isDocumentOk(http)){
|
||||
var err = Error("Unable to load "+uri+" status:"+ http.status);
|
||||
err.status = http.status;
|
||||
err.responseText = http.responseText;
|
||||
throw err;
|
||||
}
|
||||
}catch(e){
|
||||
if(fail_ok){ return null; } // null
|
||||
// rethrow the exception
|
||||
throw e;
|
||||
}
|
||||
return http.responseText; // String
|
||||
}
|
||||
}
|
||||
|
||||
d._windowUnloaders = [];
|
||||
|
||||
// FIXME: PORTME
|
||||
d.windowUnloaded = function(){
|
||||
// summary:
|
||||
// signal fired by impending window destruction. You may use
|
||||
// dojo.addOnWIndowUnload() or dojo.connect() to this method to perform
|
||||
// page/application cleanup methods. See dojo.addOnWindowUnload for more info.
|
||||
var mll = d._windowUnloaders;
|
||||
while(mll.length){
|
||||
(mll.pop())();
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: PORTME
|
||||
d.addOnWindowUnload = function(/*Object?*/obj, /*String|Function?*/functionName){
|
||||
// summary:
|
||||
// registers a function to be triggered when window.onunload fires.
|
||||
// Be careful trying to modify the DOM or access JavaScript properties
|
||||
// during this phase of page unloading: they may not always be available.
|
||||
// Consider dojo.addOnUnload() if you need to modify the DOM or do heavy
|
||||
// JavaScript work.
|
||||
// example:
|
||||
// | dojo.addOnWindowUnload(functionPointer)
|
||||
// | dojo.addOnWindowUnload(object, "functionName")
|
||||
// | dojo.addOnWindowUnload(object, function(){ /* ... */});
|
||||
|
||||
d._onto(d._windowUnloaders, obj, functionName);
|
||||
}
|
||||
|
||||
// XUL specific APIs
|
||||
var contexts = [];
|
||||
var current = null;
|
||||
dojo._defaultContext = [ window, document ];
|
||||
|
||||
dojo.pushContext = function(/*Object|String?*/g, /*MDocumentElement?*/d){
|
||||
// summary:
|
||||
// causes subsequent calls to Dojo methods to assume the
|
||||
// passed object and, optionally, document as the default
|
||||
// scopes to use. A 2-element array of the previous global and
|
||||
// document are returned.
|
||||
// description:
|
||||
// dojo.pushContext treats contexts as a stack. The
|
||||
// auto-detected contexts which are initially provided using
|
||||
// dojo.setContext() require authors to keep state in order to
|
||||
// "return" to a previous context, whereas the
|
||||
// dojo.pushContext and dojo.popContext methods provide a more
|
||||
// natural way to augment blocks of code to ensure that they
|
||||
// execute in a different window or frame without issue. If
|
||||
// called without any arguments, the default context (the
|
||||
// context when Dojo is first loaded) is instead pushed into
|
||||
// the stack. If only a single string is passed, a node in the
|
||||
// intitial context's document is looked up and its
|
||||
// contextWindow and contextDocument properties are used as
|
||||
// the context to push. This means that iframes can be given
|
||||
// an ID and code can be executed in the scope of the iframe's
|
||||
// document in subsequent calls easily.
|
||||
// g:
|
||||
// The global context. If a string, the id of the frame to
|
||||
// search for a context and document.
|
||||
// d:
|
||||
// The document element to execute subsequent code with.
|
||||
var old = [dojo.global, dojo.doc];
|
||||
contexts.push(old);
|
||||
var n;
|
||||
if(!g && !d){
|
||||
n = dojo._defaultContext;
|
||||
}else{
|
||||
n = [ g, d ];
|
||||
if(!d && dojo.isString(g)){
|
||||
var t = document.getElementById(g);
|
||||
if(t.contentDocument){
|
||||
n = [t.contentWindow, t.contentDocument];
|
||||
}
|
||||
}
|
||||
}
|
||||
current = n;
|
||||
dojo.setContext.apply(dojo, n);
|
||||
return old; // Array
|
||||
};
|
||||
|
||||
dojo.popContext = function(){
|
||||
// summary:
|
||||
// If the context stack contains elements, ensure that
|
||||
// subsequent code executes in the *previous* context to the
|
||||
// current context. The current context set ([global,
|
||||
// document]) is returned.
|
||||
var oc = current;
|
||||
if(!contexts.length){
|
||||
return oc;
|
||||
}
|
||||
dojo.setContext.apply(dojo, contexts.pop());
|
||||
return oc;
|
||||
};
|
||||
|
||||
// FIXME:
|
||||
// don't really like the current arguments and order to
|
||||
// _inContext, so don't make it public until it's right!
|
||||
dojo._inContext = function(g, d, f){
|
||||
var a = dojo._toArray(arguments);
|
||||
f = a.pop();
|
||||
if(a.length == 1){
|
||||
d = null;
|
||||
}
|
||||
dojo.pushContext(g, d);
|
||||
var r = f();
|
||||
dojo.popContext();
|
||||
return r;
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
dojo._initFired = false;
|
||||
// BEGIN DOMContentLoaded, from Dean Edwards (http://dean.edwards.name/weblog/2006/06/again/)
|
||||
dojo._loadInit = function(e){
|
||||
dojo._initFired = true;
|
||||
// allow multiple calls, only first one will take effect
|
||||
// A bug in khtml calls events callbacks for document for event which isnt supported
|
||||
// for example a created contextmenu event calls DOMContentLoaded, workaround
|
||||
var type = (e && e.type) ? e.type.toLowerCase() : "load";
|
||||
if(arguments.callee.initialized || (type != "domcontentloaded" && type != "load")){ return; }
|
||||
arguments.callee.initialized = true;
|
||||
if(dojo._inFlightCount == 0){
|
||||
dojo._modulesLoaded();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
(function(){
|
||||
var _w = window;
|
||||
var _handleNodeEvent = function(evtName, fp){
|
||||
// summary:
|
||||
// non-destructively adds the specified function to the node's
|
||||
// evtName handler.
|
||||
// evtName: should be in the form "onclick" for "onclick" handlers.
|
||||
// Make sure you pass in the "on" part.
|
||||
var oldHandler = _w[evtName] || function(){};
|
||||
_w[evtName] = function(){
|
||||
fp.apply(_w, arguments);
|
||||
oldHandler.apply(_w, arguments);
|
||||
};
|
||||
};
|
||||
// FIXME: PORT
|
||||
// FIXME: dojo.unloaded requires dojo scope, so using anon function wrapper.
|
||||
_handleNodeEvent("onbeforeunload", function() { dojo.unloaded(); });
|
||||
_handleNodeEvent("onunload", function() { dojo.windowUnloaded(); });
|
||||
})();
|
||||
*/
|
||||
|
||||
|
||||
// FIXME: PORTME
|
||||
// this event fires a lot, namely for all plugin XUL overlays and for
|
||||
// all iframes (in addition to window navigations). We only want
|
||||
// Dojo's to fire once..but we might care if pages navigate. We'll
|
||||
// probably need an extension-specific API
|
||||
if(!dojo.config.afterOnLoad){
|
||||
window.addEventListener("DOMContentLoaded",function(e){
|
||||
dojo._loadInit(e);
|
||||
// console.log("DOM content loaded", e);
|
||||
}, false);
|
||||
}
|
||||
|
||||
} //if (typeof window != 'undefined')
|
||||
|
||||
//Register any module paths set up in djConfig. Need to do this
|
||||
//in the hostenvs since hostenv_browser can read djConfig from a
|
||||
//script tag's attribute.
|
||||
(function(){
|
||||
var d=dojo;
|
||||
d.baseUrl=d.config.baseUrl;
|
||||
var n=navigator;
|
||||
var _1=n.userAgent;
|
||||
var _2=n.appVersion;
|
||||
var tv=parseFloat(_2);
|
||||
d.isMozilla=d.isMoz=tv;
|
||||
if(d.isMoz){
|
||||
d.isFF=parseFloat(_1.split("Firefox/")[1])||undefined;
|
||||
}
|
||||
d.isQuirks=document.compatMode=="BackCompat";
|
||||
d.locale=dojo.config.locale||n.language.toLowerCase();
|
||||
d._xhrObj=function(){
|
||||
return new XMLHttpRequest();
|
||||
};
|
||||
var _3=d._loadUri;
|
||||
d._loadUri=function(_4,cb){
|
||||
var _5=["file:","chrome:","resource:"].some(function(_6){
|
||||
return String(_4).indexOf(_6)==0;
|
||||
});
|
||||
if(_5){
|
||||
var l=Components.classes["@mozilla.org/moz/jssubscript-loader;1"].getService(Components.interfaces.mozIJSSubScriptLoader);
|
||||
var _7=l.loadSubScript(_4,d.global);
|
||||
if(cb){
|
||||
cb(_7);
|
||||
}
|
||||
return true;
|
||||
}else{
|
||||
return _3.apply(d,arguments);
|
||||
}
|
||||
};
|
||||
d._isDocumentOk=function(_8){
|
||||
var _9=_8.status||0;
|
||||
return (_9>=200&&_9<300)||_9==304||_9==1223||(!_9&&(location.protocol=="file:"||location.protocol=="chrome:"));
|
||||
};
|
||||
var _a=false;
|
||||
d._getText=function(_b,_c){
|
||||
var _d=d._xhrObj();
|
||||
if(!_a&&dojo._Url){
|
||||
_b=(new dojo._Url(_b)).toString();
|
||||
}
|
||||
if(d.config.cacheBust){
|
||||
_b+="";
|
||||
_b+=(_b.indexOf("?")==-1?"?":"&")+String(d.config.cacheBust).replace(/\W+/g,"");
|
||||
}
|
||||
var _e=["file:","chrome:","resource:"].some(function(_f){
|
||||
return String(_b).indexOf(_f)==0;
|
||||
});
|
||||
if(_e){
|
||||
var _10=Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
|
||||
var _11=Components.classes["@mozilla.org/scriptableinputstream;1"].getService(Components.interfaces.nsIScriptableInputStream);
|
||||
var _12=_10.newChannel(_b,null,null);
|
||||
var _13=_12.open();
|
||||
_11.init(_13);
|
||||
var str=_11.read(_13.available());
|
||||
_11.close();
|
||||
_13.close();
|
||||
return str;
|
||||
}else{
|
||||
_d.open("GET",_b,false);
|
||||
try{
|
||||
_d.send(null);
|
||||
if(!d._isDocumentOk(_d)){
|
||||
var err=Error("Unable to load "+_b+" status:"+_d.status);
|
||||
err.status=_d.status;
|
||||
err.responseText=_d.responseText;
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
catch(e){
|
||||
if(_c){
|
||||
return null;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
return _d.responseText;
|
||||
}
|
||||
};
|
||||
d._windowUnloaders=[];
|
||||
d.windowUnloaded=function(){
|
||||
var mll=d._windowUnloaders;
|
||||
while(mll.length){
|
||||
(mll.pop())();
|
||||
}
|
||||
};
|
||||
d.addOnWindowUnload=function(obj,_14){
|
||||
d._onto(d._windowUnloaders,obj,_14);
|
||||
};
|
||||
var _15=[];
|
||||
var _16=null;
|
||||
dojo._defaultContext=[window,document];
|
||||
dojo.pushContext=function(g,d){
|
||||
var old=[dojo.global,dojo.doc];
|
||||
_15.push(old);
|
||||
var n;
|
||||
if(!g&&!d){
|
||||
n=dojo._defaultContext;
|
||||
}else{
|
||||
n=[g,d];
|
||||
if(!d&&dojo.isString(g)){
|
||||
var t=document.getElementById(g);
|
||||
if(t.contentDocument){
|
||||
n=[t.contentWindow,t.contentDocument];
|
||||
}
|
||||
}
|
||||
}
|
||||
_16=n;
|
||||
dojo.setContext.apply(dojo,n);
|
||||
return old;
|
||||
};
|
||||
dojo.popContext=function(){
|
||||
var oc=_16;
|
||||
if(!_15.length){
|
||||
return oc;
|
||||
}
|
||||
dojo.setContext.apply(dojo,_15.pop());
|
||||
return oc;
|
||||
};
|
||||
dojo._inContext=function(g,d,f){
|
||||
var a=dojo._toArray(arguments);
|
||||
f=a.pop();
|
||||
if(a.length==1){
|
||||
d=null;
|
||||
}
|
||||
dojo.pushContext(g,d);
|
||||
var r=f();
|
||||
dojo.popContext();
|
||||
return r;
|
||||
};
|
||||
})();
|
||||
dojo._initFired=false;
|
||||
dojo._loadInit=function(e){
|
||||
dojo._initFired=true;
|
||||
var _17=(e&&e.type)?e.type.toLowerCase():"load";
|
||||
if(arguments.callee.initialized||(_17!="domcontentloaded"&&_17!="load")){
|
||||
return;
|
||||
}
|
||||
arguments.callee.initialized=true;
|
||||
if(dojo._inFlightCount==0){
|
||||
dojo._modulesLoaded();
|
||||
}
|
||||
};
|
||||
if(!dojo.config.afterOnLoad){
|
||||
window.addEventListener("DOMContentLoaded",function(e){
|
||||
dojo._loadInit(e);
|
||||
},false);
|
||||
}
|
||||
}
|
||||
(function(){
|
||||
var mp=dojo.config["modulePaths"];
|
||||
if(mp){
|
||||
for(var _18 in mp){
|
||||
dojo.registerModulePath(_18,mp[_18]);
|
||||
}
|
||||
}
|
||||
var mp = dojo.config["modulePaths"];
|
||||
if(mp){
|
||||
for(var param in mp){
|
||||
dojo.registerModulePath(param, mp[param]);
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
//Load debug code if necessary.
|
||||
if(dojo.config.isDebug){
|
||||
console.log=function(m){
|
||||
var s=Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);
|
||||
s.logStringMessage(m);
|
||||
};
|
||||
console.debug=function(){
|
||||
};
|
||||
// logging stub for extension logging
|
||||
console.log = function(m){
|
||||
var s = Components.classes["@mozilla.org/consoleservice;1"].getService(
|
||||
Components.interfaces.nsIConsoleService
|
||||
);
|
||||
s.logStringMessage(m);
|
||||
}
|
||||
console.debug = function(){
|
||||
console.log(dojo._toArray(arguments).join(" "));
|
||||
}
|
||||
// FIXME: what about the rest of the console.* methods? And is there any way to reach into firebug and log into it directly?
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user