From d25c6009e5264a945d56698791bf8b2b47dcffb2 Mon Sep 17 00:00:00 2001 From: Joscha Feth Date: Thu, 4 Oct 2012 23:51:53 +0700 Subject: [PATCH 01/95] use yepnope.js instead of the discontinued LABjs --- .gitmodules | 3 + chrome/lib/bootstrap.js | 49 ++---- chrome/lib/init.js | 27 --- chrome/lib/lab.js | 371 ---------------------------------------- chrome/lib/yepnope.js | 1 + chrome/main.js | 2 +- chrome/manifest.json | 24 ++- 7 files changed, 34 insertions(+), 443 deletions(-) create mode 100644 .gitmodules delete mode 100644 chrome/lib/init.js delete mode 100644 chrome/lib/lab.js create mode 160000 chrome/lib/yepnope.js diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..02a6a7d --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "chrome/lib/yepnope.js"] + path = chrome/lib/yepnope.js + url = git://github.com/SlexAxton/yepnope.js.git diff --git a/chrome/lib/bootstrap.js b/chrome/lib/bootstrap.js index 8a74e3b..d15c26e 100644 --- a/chrome/lib/bootstrap.js +++ b/chrome/lib/bootstrap.js @@ -1,42 +1,15 @@ /** This is the bootstrapping code that sets up the scripts to be used in the - Gmailr example Chrome plugin. It does the following: - - 1) Sets up data DOM elements that allow strings to be shared to injected scripts. - 2) Injects the scripts necessary to load the Gmailr API into the Gmail script environment. + Gmailr example Chrome plugin. */ -// Only run this script in the top-most frame (there are multiple frames in Gmail) -if(top.document == document) { - - // Adds a data DOM element that simply holds a string in an attribute, to be read - // by the injected scripts. - var addData = function(id, val) { - var body = document.getElementsByTagName("body")[0]; - var div = document.createElement('div'); - div.setAttribute('data-val', val); - div.id = id + "_gmailr_data"; - div.setAttribute('style', "display:none"); - body.appendChild(div); - }; - - // Loads a script - var loadScript = function(path) { - var headID = document.getElementsByTagName("head")[0]; - var newScript = document.createElement('script'); - newScript.type = 'text/javascript'; - newScript.src = path; - headID.appendChild(newScript); - }; - - // Pass data to inserted scripts via DOM elements - addData("css_path", chrome.extension.getURL("main.css")); - addData("jquery_path", chrome.extension.getURL("lib/jquery.1.4.2.js")); - addData("jquery_bbq_path", chrome.extension.getURL("lib/jquery.ba-bbq.js")); - addData("gmailr_path", chrome.extension.getURL("lib/gmailr.js")); - addData("main_path", chrome.extension.getURL("main.js")); - - // Load the initialization scripts - loadScript(chrome.extension.getURL("lib/lab.js")); - loadScript(chrome.extension.getURL("lib/init.js")); -}; +yepnope({ + test: top.document === document, + yep: [ + chrome.extension.getURL("main.css"), + chrome.extension.getURL("lib/jquery.1.4.2.js"), + chrome.extension.getURL("lib/jquery.ba-bbq.js"), + chrome.extension.getURL("lib/gmailr.js"), + chrome.extension.getURL("main.js") + ] +}); \ No newline at end of file diff --git a/chrome/lib/init.js b/chrome/lib/init.js deleted file mode 100644 index 1f56ab1..0000000 --- a/chrome/lib/init.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - This is the first script (along with lab.js) that is injected into the top frame of the - Gmail DOM. - - It loads the dependencies needed for Gmailr (via LAB), and then runs main.js, - which is the app code that uses Gmailr. - - If you want to get started writing an extension using Gmailr, edit main.js. - - If you want to add more files, or change how files are loaded, simply extend the load - paths after the LAB call to getData('gmailr_path'). - */ - -// Grabs the data that is injected using addData in bootstrap.js -var getData = function(id) { - return document.getElementById(id + "_gmailr_data").getAttribute('data-val'); -}; - -// Load all dependencies and run main.js -$LAB -.script(getData('jquery_path')) -.wait() -.script(getData('jquery_bbq_path')) -.wait() -.script(getData('gmailr_path')) -.wait() -.script(getData('main_path')); diff --git a/chrome/lib/lab.js b/chrome/lib/lab.js deleted file mode 100644 index a64f497..0000000 --- a/chrome/lib/lab.js +++ /dev/null @@ -1,371 +0,0 @@ -/*! LAB.js (LABjs :: Loading And Blocking JavaScript) - v1.2.0 (c) Kyle Simpson - MIT License -*/ - -(function(global){ - var sSTRING = "string", // constants used for compression optimization - sHEAD = "head", - sBODY = "body", - sSCRIPT = "script", - sREADYSTATE = "readyState", - sPRELOADDONE = "preloaddone", - sLOADTRIGGER = "loadtrigger", - sSRCURI = "srcuri", - sPRELOAD = "preload", - sCOMPLETE = "complete", - sDONE = "done", - sWHICH = "which", - sPRESERVE = "preserve", - sONREADYSTATECHANGE = "onreadystatechange", - sONLOAD = "onload", - sHASOWNPROPERTY = "hasOwnProperty", - sSCRIPTCACHE = "script/cache", - sTYPEOBJ = "[object ", - sTYPEFUNC = sTYPEOBJ+"Function]", - sTYPEARRAY = sTYPEOBJ+"Array]", - nNULL = null, - bTRUE = true, - bFALSE = false, - oDOC = global.document, - oWINLOC = global.location, - oACTIVEX = global.ActiveXObject, - fSETTIMEOUT = global.setTimeout, - fCLEARTIMEOUT = global.clearTimeout, - fGETELEMENTSBYTAGNAME = function(tn){return oDOC.getElementsByTagName(tn);}, - fOBJTOSTRING = Object.prototype.toString, - fNOOP = function(){}, - append_to = {}, - all_scripts = {}, - PAGEROOT = /^[^?#]*\//.exec(oWINLOC.href)[0], // these ROOTs do not support file:/// usage, only http:// type usage - DOCROOT = /^\w+\:\/\/\/?[^\/]+/.exec(PAGEROOT)[0], // optional third / in the protocol portion of this regex so that LABjs doesn't blow up when used in file:/// usage - docScripts = fGETELEMENTSBYTAGNAME(sSCRIPT), - - // Ah-ha hush that fuss, feature inference is used to detect specific browsers - // because the techniques used in LABjs have no known feature detection. If - // you know of a feature test please contact me ASAP. Feature inference is used - // instead of user agent sniffing because the UA string can be easily - // spoofed and is not adequate for such a mission critical part of the code. - is_opera = global.opera && fOBJTOSTRING.call(global.opera) == sTYPEOBJ+"Opera]", - is_gecko = ("MozAppearance" in oDOC.documentElement.style), - - // the following is a feature sniff for the ability to set async=false on dynamically created script elements, as proposed to the W3C - // RE: http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order - is_script_async = (oDOC.createElement(sSCRIPT).async === true), - - global_defs = { - cache:!(is_gecko||is_opera), // browsers like IE/Safari/Chrome can use the "cache" trick to preload - order:is_gecko||is_opera||is_script_async, // FF(prior to FF4) & Opera preserve execution order with script tags automatically, - // so just add all scripts as fast as possible. FF4 has async=false to do the same - xhr:bTRUE, // use XHR trick to preload local scripts - dupe:bTRUE, // allow duplicate scripts? defaults to true now 'cause is slightly more performant that way (less checks) - base:"", // base path to prepend to all non-absolute-path scripts - which:sHEAD // which DOM object ("head" or "body") to append scripts to - } - ; - global_defs[sPRESERVE] = bFALSE; // force preserve execution order of all loaded scripts (regardless of preloading) - global_defs[sPRELOAD] = bTRUE; // use various tricks for "preloading" scripts - - append_to[sHEAD] = oDOC.head || fGETELEMENTSBYTAGNAME(sHEAD); - append_to[sBODY] = fGETELEMENTSBYTAGNAME(sBODY); - - function isFunc(func) { return fOBJTOSTRING.call(func) === sTYPEFUNC; } - function canonicalScriptURI(src,base_path) { - var regex = /^\w+\:\/\//, ret; - if (typeof src != sSTRING) src = ""; - if (typeof base_path != sSTRING) base_path = ""; - ret = ((/^\/\//.test(src)) ? oWINLOC.protocol : "") + src; - ret = (regex.test(ret) ? "" : base_path) + ret; - - // Edit this just to make it a NOOP, because it can't handle chrome:// urls correctly - return src; - //return ((regex.test(ret) ? "" : (ret.charAt(0) === "/" ? DOCROOT : PAGEROOT)) + ret); - } - function sameDomain(src) { return (canonicalScriptURI(src).indexOf(DOCROOT) === 0); } - function scriptTagExists(uri) { // checks if a script uri has ever been loaded into this page's DOM - var script, idx=-1; - while (script = docScripts[++idx]) { - if (typeof script.src == sSTRING && uri === canonicalScriptURI(script.src) && script.type !== sSCRIPTCACHE) return bTRUE; - } - return bFALSE; - } - function engine(queueExec,opts) { - queueExec = !(!queueExec); - if (opts == nNULL) opts = global_defs; - - var ready = bFALSE, - _use_preload = queueExec && opts[sPRELOAD], - _use_cache_preload = _use_preload && opts.cache, - _use_script_order = _use_preload && opts.order, - _use_xhr_preload = _use_preload && opts.xhr, - _auto_wait = opts[sPRESERVE], - _which = opts.which, - _base_path = opts.base, - waitFunc = fNOOP, - scripts_loading = bFALSE, - publicAPI, - - first_pass = bTRUE, - scripts = {}, - exec = [], - end_of_chain_check_interval = nNULL - ; - - _use_preload = _use_cache_preload || _use_xhr_preload || _use_script_order; // if all flags are turned off, preload is moot so disable it - - function isScriptLoaded(elem,scriptentry) { - if ((elem[sREADYSTATE] && elem[sREADYSTATE]!==sCOMPLETE && elem[sREADYSTATE]!=="loaded") || scriptentry[sDONE]) { return bFALSE; } - elem[sONLOAD] = elem[sONREADYSTATECHANGE] = nNULL; // prevent memory leak - return bTRUE; - } - function handleScriptLoad(elem,scriptentry,skipReadyCheck) { - skipReadyCheck = !(!skipReadyCheck); // used to override ready check when script text was injected from XHR preload - if (!skipReadyCheck && !(isScriptLoaded(elem,scriptentry))) return; - scriptentry[sDONE] = bTRUE; - - for (var key in scripts) { - if (scripts[sHASOWNPROPERTY](key) && !(scripts[key][sDONE])) return; - } - ready = bTRUE; - waitFunc(); - } - function loadTriggerExecute(scriptentry) { - if (isFunc(scriptentry[sLOADTRIGGER])) { - scriptentry[sLOADTRIGGER](); - scriptentry[sLOADTRIGGER] = nNULL; // prevent memory leak - } - } - function handleScriptPreload(elem,scriptentry) { - if (!isScriptLoaded(elem,scriptentry)) return; - scriptentry[sPRELOADDONE] = bTRUE; - fSETTIMEOUT(function(){ - append_to[scriptentry[sWHICH]].removeChild(elem); // remove preload script node - loadTriggerExecute(scriptentry); - },0); - } - function handleXHRPreload(xhr,scriptentry) { - if (xhr[sREADYSTATE] === 4) { - xhr[sONREADYSTATECHANGE] = fNOOP; // fix a memory leak in IE - scriptentry[sPRELOADDONE] = bTRUE; - fSETTIMEOUT(function(){ loadTriggerExecute(scriptentry); },0); - } - } - function createScriptTag(scriptentry,src,type,charset,onload,scriptText) { - var _script_which = scriptentry[sWHICH]; - fSETTIMEOUT(function() { // this setTimeout waiting "hack" prevents a nasty race condition browser hang (IE) when the document.write("