1 /** 2 iiii jjjj 3 i::::i j::::j 4 iiii jjjj 5 6 rrrrr rrrrrrrrr iiiiiii ooooooooooo jjjjjjj ssssssssss 7 r::::rrr:::::::::r i:::::i oo:::::::::::oo :::::: j:::::j ss::::::::::s 8 r:::::::::::::::::r i::::i o:::::::::::::::o :::::: j::::jss:::::::::::::s 9 rr::::::rrrrr::::::ri::::i o:::::ooooo:::::o :::::: j::::js::::::ssss:::::s 10 r:::::r r:::::ri::::i o::::o o::::o j::::j s:::::s ssssss 11 r:::::r rrrrrrri::::i o::::o o::::o j::::j s::::::s 12 r:::::r i::::i o::::o o::::o j::::j s::::::s 13 r:::::r i::::i o::::o o::::o :::::: j::::jssssss s:::::s 14 r:::::r i::::::io:::::ooooo:::::o :::::: j::::js:::::ssss::::::s 15 r:::::r i::::::io:::::::::::::::o :::::: j::::js::::::::::::::s 16 r:::::r i::::::i oo:::::::::::oo j::::j s:::::::::::ss 17 rrrrrrr iiiiiiii ooooooooooo j::::j sssssssssss 18 j::::j 19 jjjj j::::j 20 j::::jj j:::::j 21 j::::::jjj::::::j 22 jj::::::::::::j 23 jjj::::::jjj 24 jjjjjj 25 26 27 @name rio 28 @namespace 29 30 The rio namespace is the root of the entire framework, through which you can access all of the classes and 31 namespaces. 32 33 <br /> 34 35 <h2>Namespaces</h2> 36 37 <ul> 38 <li>apps - contains instances of rio.Application</li> 39 <li>components - contains instances of rio.Component</li> 40 <li>models - contains instances of rio.Model</li> 41 <li>pages - contains instances of rio.Page</li> 42 <li>environment - configuration for the current environment</li> 43 <li>environments - configurations varying by environment</li> 44 <li>console - stuff related to the development console</li> 45 <li>boot - configuration related to the application boot process</li> 46 </ul> 47 48 <h2>Classes</h2> 49 50 <ul> 51 <li>AIM - manages AJAX file uploads</li> 52 <li>Application - root of application instances</li> 53 <li>Attr - root of most rio classes (Application, Component, Model, Page)</li> 54 <li>Binding - represents a bindable attribute</li> 55 <li>Tag - a collection of methods for building HTML tags</li> 56 <li>Utils - a collection of random helper methods</li> 57 </ul> 58 59 <h2>Methods</h2> 60 <ul> 61 <li>log - adds a log message to the rio console</li> 62 </ul> 63 64 <h2>Fields</h2> 65 <ul> 66 <li>app - the currently running application instance</li> 67 </ul> 68 69 @author Jason Tillery 70 @copyright 2008-2009 Thinklink LLC 71 */ 72 var w = window; 73 (function() { 74 if (!window.console) { window.console = { log: Prototype.emptyFunction }; } 75 76 var initialWindowKeys = Object.keys(window); 77 78 var bootOptions = window.bootOptions || {}; 79 80 Object.extend(rio, { 81 url: function(url) { 82 return url + "?" + rio.cacheKey; 83 }, 84 components: {}, 85 models: {}, 86 apps: {}, 87 pages: {}, 88 console: {}, 89 log: Prototype.emptyFunction, 90 warn: Prototype.emptyFunction, 91 error: Prototype.emptyFunction, 92 boot: { 93 errors: [], 94 isMac: navigator.appVersion.toLowerCase().indexOf("mac") != -1, 95 root: "/javascripts/", 96 appRoot: bootOptions.appRoot || "", 97 rioPath: bootOptions.rioPath || "lib/", 98 prototypePath: bootOptions.prototypePath || "prototype/", 99 prototypePollution: [ 100 "$", "$$", "$A", "$F", "$H", "$R", "$break", "$continue", "$w", "_eventID", "Abstract", "Ajax", "Autocompleter", "Builder", "Class", "Draggable", "Draggables", "Droppables", "Effect", "Element", "Enumerable", "Field", "Form", "Hash", "Insertion", "ObjectRange", "PeriodicalExecuter", "Position", "Prototype", "Selector", "Sortable", "SortableObserver", "Template", "Toggle", "Try" 101 ], 102 googleAnalyticsPollution: ["gaGlobal", "gaJsHost", "_gat", "pageTracker"], 103 noConsole: bootOptions.noConsole, 104 initialWindowKeys: initialWindowKeys, 105 prototypeScripts: [], 106 rioScripts: [], 107 rioScriptsDigest: {}, 108 appScriptsDigest: {}, 109 prototypeScriptsDigest: {}, 110 loadedFiles: [], 111 loadedStylesheets: [], 112 loadedTemplates: [], 113 loadFunctions: {}, 114 115 appScripts: function() { 116 return rio.boot.loadedFiles.reject(function(f) { 117 return rio.boot.prototypeScripts.include(f) || rio.boot.rioScripts.include(f); 118 }); 119 }, 120 121 pollution: function() { 122 return Object.keys(window).reject(function(key) { 123 return rio.boot.initialWindowKeys.include(key) || 124 rio.boot.prototypePollution.include(key) || 125 rio.boot.googleAnalyticsPollution.include(key); 126 }.bind(this)); 127 }, 128 129 failBoot: function() { 130 if (rio.environment.bootFailedUrl) { 131 document.location.href = rio.environment.bootFailedUrl; 132 } else { 133 rio.boot.printErrors(); 134 } 135 }, 136 137 printErrors: function() { 138 $$("body")[0].update(); 139 140 var msg = "<h1 style='font-size: 24px; color: #670800;'>Boot failed</h1>"; 141 msg += "<style>.errorLine{font-size:16px; padding:0px 2px; background-color:yellow}</style>"; 142 143 rio.boot.errors.each(function(e) { 144 if (e.e) { 145 msg += "<br /><br />"; 146 msg += "<p style='font-weight: 700'>" + e.msg + "<br /><br />" + e.e + "</p>"; 147 msg += "<br />"; 148 } else if (e.lint) { 149 e.lint.each(function(err) { 150 msg += err.toHtml() + "<br />"; 151 }); 152 } 153 }); 154 155 $$("body")[0].insert("<div style='padding: 20px'>" + msg + "</div>"); 156 }, 157 158 abort: function() { 159 rio.boot.abortBoot = true; 160 } 161 } 162 }); 163 164 $$("script").each(function(script) { 165 var src = script.src; 166 if(src.match(/boot\.js/) && src.indexOf('?') != -1) { 167 var options = src.split('?')[1].split(','); 168 if (options.length >= 1) { rio.boot.appName = options[0]; } 169 if (options.length >= 2) { rio.boot.environment = options[1]; } 170 if (options.length >= 3) { rio.boot.bootCompressed = (options[2] == "compressed"); } 171 } 172 }); 173 174 Object.extend(rio.environment, rio.environments[rio.boot.environment]); 175 Object.extend(rio.boot, rio.environment.boot); 176 177 if (bootOptions.noConsole === undefined) { 178 rio.boot.noConsole = (rio.environment.console == undefined) ? false : !rio.environment.console; 179 } 180 181 rio.require = function(fileName, options) { 182 options = Object.extend({ 183 force: false, 184 track: true 185 }, options || {}); 186 187 if (!rio.boot.loadedFiles.include(fileName)) { 188 if (rio.boot.bootCompressed && options.force) { 189 if (options.track) { rio.boot.loadedFiles.push(fileName); } 190 document.write('<script type="text/javascript" src="' + (options.noPrefix ? "" : rio.assetPrefix) + rio.url(rio.boot.root + fileName + '.js') + '"></script>'); 191 } else if (!rio.boot.bootCompressed) { 192 if (rio.boot.loadFunctions[fileName]) { 193 rio.boot.loadFunctions[fileName](); 194 } else { 195 rio.require.ajax(fileName); 196 } 197 if (options.track) { rio.boot.loadedFiles.push(fileName); } 198 } 199 } 200 }; 201 202 rio.require.ajax = function(fileName) { 203 var path = rio.boot.root + fileName + ".js"; 204 new Ajax.Request(rio.url(path), { 205 asynchronous: false, 206 method: "get", 207 evalJSON: false, 208 evalJS: false, 209 onSuccess: function(response) { 210 try { 211 w.eval(response.responseText); 212 } catch(e) { 213 rio.error(e, "Failed parsing file: " + path); 214 215 if (!rio.app) { 216 if (fileName != "lib/rio_lint") { 217 rio.require("lib/rio_lint", { track: false }); 218 } 219 220 var lintIt = function(fileName) { 221 rio.RioLint.checkFileSyntax(fileName, { 222 onComplete: function(errors) { 223 rio.boot.errors.push({ lint: errors }); 224 } 225 }); 226 }; 227 if (fileName == "lib/rio_concat") { 228 new Ajax.Request(rio.url("/javascripts/lib/rio.build"), { 229 asynchronous: false, 230 method: "get", 231 evalJSON: false, 232 evalJS: false, 233 onSuccess: function(response) { 234 var files = response.responseText.split("\n"); 235 files.without("lib/swfobject").each(function(f) { 236 lintIt(f); 237 }); 238 } 239 }); 240 } else if (fileName == "apps/" + rio.boot.appName + "_concat") { 241 } else { 242 rio.boot.errors.push({ e: e, msg: "Failed parsing file: " + path }); 243 lintIt(fileName); 244 } 245 246 } 247 throw(e); 248 } 249 }, 250 onFailure: function() { 251 rio.log("Failed loading file: " + path); 252 } 253 }); 254 }; 255 256 if (rio.boot.bootCompressed) { 257 // rio.require(rio.boot.appRoot + "prototype/compressed/prototype", { force: true }); 258 rio.require(rio.boot.rioPath + "compressed/rio", { force: true }); 259 rio.require(rio.boot.appRoot + "apps/compressed/" + rio.boot.appName, { force: true }); 260 if (rio.environment.developmentTools) { 261 rio.require(rio.boot.rioPath + "rio_development_concat", { force: true }); 262 } 263 } else { 264 try { 265 rio.require(rio.boot.appRoot + "prototype/prototype_concat", { track: false }); 266 rio.require(rio.boot.rioPath + "rio_concat", { track: false }); 267 rio.require(rio.boot.appRoot + "apps/" + rio.boot.appName + "_concat", { track: false }); 268 rio.require(rio.boot.appRoot + "apps/" + rio.boot.appName); 269 } catch(e) { 270 // Let the errors print on load 271 } 272 } 273 if (rio.environment.autoConcatCss) { 274 if (rio.boot.bootCompressed) { 275 document.write('<script type="text/javascript">' + 'rio.Application.injectCss();' + '</script>') 276 } else { 277 rio.Application.injectCss(); 278 } 279 } 280 281 if (rio.environment.supportSelenium) { 282 rio.require(rio.boot.rioPath + "event.simulate", { force: true, noPrefix: true }); 283 rio.require(rio.boot.rioPath + "selenium_extensions", { force: true, noPrefix: true }); 284 } 285 286 document.observe('dom:loaded', function() { 287 var app = rio.apps[rio.boot.appName.camelize()]; 288 var pushOverride = app.environment().push == undefined ? true : app.environment().push; 289 if ((rio.environment.push && pushOverride) && !rio.push) { 290 try { 291 rio.Push.boot(); 292 } catch(e) { 293 rio.boot.errors.push({ e: e, msg: "Failed booting push client" }); 294 } 295 } 296 297 if (rio.preloadTemplates) { 298 rio.JsTemplate.preload("apps/" + (rio.boot.bootCompressed ? "compressed/" + rio.boot.appName : rio.boot.appName + "_concat")); 299 } 300 301 if (rio.environment.failOnBootError && rio.boot.errors.length > 0) { 302 rio.boot.failBoot(); 303 return; 304 } 305 try { 306 window.initialOptions = window.initialOptions || {}; 307 rio.app = new app(initialOptions); 308 if (rio.boot.abortBoot) { return; } 309 rio.app.launch(); 310 } catch(e) { 311 rio.boot.errors.push({ e: e, msg: "Failed inititializing or launching application" }); 312 rio.boot.failBoot(); 313 } 314 }.bind(this)); 315 })(); 316