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 }); 159 160 $$("script").each(function(script) { 161 var src = script.src; 162 if(src.match(/boot\.js/) && src.indexOf('?') != -1) { 163 var options = src.split('?')[1].split(','); 164 if (options.length >= 1) { rio.boot.appName = options[0]; } 165 if (options.length >= 2) { rio.boot.environment = options[1]; } 166 if (options.length >= 3) { rio.boot.bootCompressed = (options[2] == "compressed"); } 167 } 168 }); 169 170 Object.extend(rio.environment, rio.environments[rio.boot.environment]); 171 Object.extend(rio.boot, rio.environment.boot); 172 173 if (bootOptions.noConsole === undefined) { 174 rio.boot.noConsole = (rio.environment.console == undefined) ? false : !rio.environment.console; 175 } 176 177 rio.require = function(fileName, options) { 178 options = Object.extend({ 179 force: false, 180 track: true 181 }, options || {}); 182 183 if (!rio.boot.loadedFiles.include(fileName)) { 184 if (rio.boot.bootCompressed && options.force) { 185 if (options.track) { rio.boot.loadedFiles.push(fileName); } 186 document.write('<script type="text/javascript" src="' + (options.noPrefix ? "" : rio.assetPrefix) + rio.url(rio.boot.root + fileName + '.js') + '"></script>'); 187 } else if (!rio.boot.bootCompressed) { 188 if (rio.boot.loadFunctions[fileName]) { 189 rio.boot.loadFunctions[fileName](); 190 } else { 191 var path = rio.boot.root + fileName + ".js"; 192 new Ajax.Request(rio.url(path), { 193 asynchronous: false, 194 method: "get", 195 evalJSON: false, 196 evalJS: false, 197 onSuccess: function(response) { 198 try { 199 w.eval(response.responseText); 200 } catch(e) { 201 rio.error(e, "Failed parsing file: " + path); 202 203 if (!rio.app) { 204 if (fileName != "lib/rio_lint") { 205 rio.require("lib/rio_lint", { track: false }); 206 } 207 208 var lintIt = function(fileName) { 209 rio.RioLint.checkFileSyntax(fileName, { 210 onComplete: function(errors) { 211 rio.boot.errors.push({ lint: errors }); 212 } 213 }); 214 }; 215 if (fileName == "lib/rio_concat") { 216 new Ajax.Request(rio.url("/javascripts/lib/rio.build"), { 217 asynchronous: false, 218 method: "get", 219 evalJSON: false, 220 evalJS: false, 221 onSuccess: function(response) { 222 var files = response.responseText.split("\n"); 223 files.without("lib/swfobject").each(function(f) { 224 lintIt(f); 225 }); 226 } 227 }); 228 } else if (fileName == "apps/" + rio.boot.appName + "_concat") { 229 } else { 230 rio.boot.errors.push({ e: e, msg: "Failed parsing file: " + path }); 231 lintIt(fileName); 232 } 233 234 } 235 throw(e); 236 } 237 }, 238 onFailure: function() { 239 rio.log("Failed loading file: " + path); 240 } 241 }); 242 } 243 if (options.track) { rio.boot.loadedFiles.push(fileName); } 244 } 245 } 246 }; 247 248 if (rio.boot.bootCompressed) { 249 // rio.require(rio.boot.appRoot + "prototype/compressed/prototype", { force: true }); 250 rio.require(rio.boot.rioPath + "compressed/rio", { force: true }); 251 rio.require(rio.boot.appRoot + "apps/compressed/" + rio.boot.appName, { force: true }); 252 if (rio.boot.environment == "development") { 253 rio.require(rio.boot.rioPath + "rio_development_concat", { force: true }); 254 } 255 } else { 256 try { 257 rio.require(rio.boot.appRoot + "prototype/prototype_concat", { track: false }); 258 rio.require(rio.boot.rioPath + "rio_concat", { track: false }); 259 rio.require(rio.boot.appRoot + "apps/" + rio.boot.appName + "_concat", { track: false }); 260 rio.require(rio.boot.appRoot + "apps/" + rio.boot.appName); 261 } catch(e) { 262 // Let the errors print on load 263 } 264 } 265 if (rio.environment.autoConcatCss) { 266 if (rio.boot.bootCompressed) { 267 document.write('<script type="text/javascript">' + 'rio.Application.injectCss();' + '</script>') 268 } else { 269 rio.Application.injectCss(); 270 } 271 } 272 273 if (rio.environment.supportSelenium) { 274 rio.require(rio.boot.rioPath + "event.simulate", { force: true, noPrefix: true }); 275 rio.require(rio.boot.rioPath + "selenium_extensions", { force: true, noPrefix: true }); 276 } 277 278 document.observe('dom:loaded', function() { 279 if (rio.environment.push && !rio.push) { 280 rio.Push.boot(); 281 } 282 283 if (rio.preloadTemplates) { 284 rio.JsTemplate.preload("apps/" + (rio.boot.bootCompressed ? "compressed/" + rio.boot.appName : rio.boot.appName + "_concat")); 285 } 286 287 if (rio.environment.failOnBootError && rio.boot.errors.length > 0) { 288 rio.boot.failBoot(); 289 return; 290 } 291 try { 292 window.initialOptions = window.initialOptions || {}; 293 rio.app = new rio.apps[rio.boot.appName.camelize()](initialOptions); 294 rio.app.launch(); 295 } catch(e) { 296 rio.boot.errors.push({ e: e, msg: "Failed inititializing or launching application" }); 297 rio.boot.failBoot(); 298 } 299 }.bind(this)); 300 })(); 301