1function WebCom_Util_TemplateUtil() { 2 3 /** 4 * Expands the <code>values</code> keys until a primitive value is found. The 5 * keys will have the following syntax 6 * 7 * Object properties: 8 * topKey.subKey.subSubKey 9 * 10 * Array properties: 11 * topKey.length 12 * topKey[index].subKey 13 * topKey[index].subKey.subSubKey 14 * topKey[index].subKey.length 15 * topKey[index].subKey[index2].subSubKey 16 * topKey[index].subKey.subSubKey.length 17 * topKey[index].subKey.subSubKey[index2] 18 * 19 * @param value 20 * @return expanded values hash 21 */ 22 this.expandKeys = function(/*hash*/ values) { 23 var hash = {}; 24 25 for (var paramName in values) { 26 var value = values[paramName]; 27 var valueType = typeof(value); 28 if ( value instanceof Array) { 29 hash[paramName + ".length"] = value.length; 30 for (var i=0; i < value.length; i++) { 31 var subHash = this.expandKeys(value[i]); 32 for (var pName in subHash) { 33 hash[paramName + "[" + i + "]." + pName] = subHash[pName]; 34 } 35 } 36 } else if (valueType == 'object' && value != null) { 37 var subHash = this.expandKeys(value); 38 for (var pName in subHash) { 39 hash[paramName + "." + pName] = subHash[pName]; 40 } 41 } else if (valueType != 'function') { 42 hash[paramName] = value; 43 } 44 } 45 46 return hash; 47 } 48 49 /** 50 * Formats <code>template</code> by replacing ${name} with the values from 51 * <code>formattingValues</code>. If no corresponding value is found for 52 * <i>name</i> then the original ${name} is preserved in the final output 53 * 54 * @param template the template source 55 * @param formattingValues hash holding value for ${name} occurences 56 * @param 57 * @return formatted templated 58 **/ 59 this.format = function (/*string*/ template, /*hash*/ formattingValues, /*boolean*/ preserveKeys) { 60 if (template == null) return null; 61 if (formattingValues == null) return template; 62 63 if (!preserveKeys) { 64 formattingValues = this.expandKeys(formattingValues); 65 } 66 67 for (var paramName in formattingValues) { 68 var escapedName = paramName.replace(/\./g, "\\."); 69 escapedName = escapedName.replace(/\[/g, "\\["); 70 escapedName = escapedName.replace(/\]/g, "\]"); 71 72 var pattern = new RegExp('\\${' + escapedName + '}', "g"); 73 template = template.replace(pattern, formattingValues[paramName]); 74 } 75 76 // take care of escape sequences 77 template = template.replace(/\\{/, "{"); 78 79 return template; 80 } 81} 82 83WebCom.ResourceLoader.makeNameSpace("WebCom.Util"); 84WebCom.Util.TemplateUtil = new WebCom_Util_TemplateUtil(); 85 86function Alpha_WebCom_Util_QueryString() { 87 this.build = function(params) { 88 var str = ""; 89 for (var param in params) { 90 str += param + "=" + params[param] + "&"; 91 } 92 93 return str; 94 } 95} 96// do not expose yet. not ready ... 97//WebCom.Util.QueryString = new WebCom_Util_QueryString(); 98 99function WebCom_Observable() { 100 101 this.webcomEvents = {}; 102 103 this.on = function(/*String*/event, /*Function*/handler, /*Object*/scope) { 104 this.webcomEvents[event] = this.webcomEvents[event] || []; 105 var registeredHandlers = this.webcomEvents[event]; 106 var alreadyRegistered = false; 107 for (var i=0; i < registeredHandlers.length; i++) { 108 var listener = registeredHandlers[i]; 109 if (listener.handler == handler) { 110 alreadyRegistered = true; 111 break; 112 } 113 } 114 115 if (!alreadyRegistered) { 116 this.webcomEvents[event].push({"handler": handler, "scope" : scope}); 117 } 118 }; 119 120 this.un = function(/*String*/event, /*Function*/handler) { 121 var registeredHandlers = this.webcomEvents[event]; 122 if (!registeredHandlers) return; 123 for (var i=0; i < registeredHandlers.length; i++) { 124 var listener = registeredHandlers[i]; 125 if (listener.handler == handler) { 126 registeredHandlers.splice(i,1); 127 break; 128 } 129 } 130 }; 131 132 this.fireEvent = function(/*String*/ event, /*Array*/ args) { 133 var registeredHandlers = this.webcomEvents[event]; 134 if (!registeredHandlers) return; 135 for (var i=0; i < registeredHandlers.length; i++) { 136 var listener = registeredHandlers[i]; 137 if (listener.scope) { 138 listener.handler.apply(listener.scope, args); 139 } else { 140 listener.handler(args); 141 } 142 } 143 }; 144 145 this.removeAllListeners = function() { 146 if (!registeredHandlers) return; 147 for (var i=0; i < registeredHandlers.length; i++) { 148 var listener = registeredHandlers[i]; 149 listener.handler = null 150 listener.scope = null; 151 listener = null; 152 registeredHandlers[i] = null; 153 } 154 155 registeredHandlers = new Array(); 156 }; 157} 158 159WebCom.Observable = WebCom_Observable; 160 161/* 162 * Abstraction for for (mostly) headless components. Basic services are provided 163 * to load a resources or build a resource URL. 164 * 165 * @inherits Observable 166 */ 167function WebCom_Components_BasicComponent(/*Library*/ _libraryHandle) { 168 WebCom.Observable.apply(this, arguments); 169 var libraryHandle = _libraryHandle; 170 171 this.loadResource = function (/*String*/ resourcePath) { 172 libraryHandle.loadResource(resourcePath); 173 }; 174 175 this.getResourceURL = function (/*String*/ resourcePath, /*String*/ resourceType) { 176 return libraryHandle.getResourceURL(resourcePath); 177 }; 178 179 this.getRuntimeName = function () { 180 return libraryHandle.getRuntimeName(); 181 }; 182 183 this.destroy = function () { 184 this.removeAllListeners(); 185 }; 186} 187 188WebCom.ResourceLoader.makeNameSpace("WebCom.Components"); 189WebCom.Components.BasicComponent = WebCom_Components_BasicComponent; 190WebCom.Components.BasicComponent.prototype = new WebCom.Observable(); 191 192 193/* 194 * Abstraction for Widget type components that require rendering on page, 195 * templating, localization etc. 196 * 197 * @inherits BasicComponent 198 */ 199function WebCom_Components_Component(/*Library*/ library) { 200 WebCom.Components.BasicComponent.apply(this, arguments); 201 202 this.getId = function () { 203 return this.id; 204 }; 205 206 207 this.toHTML = function (/*RenderMode*/ mode) { 208 this.WebCom_CC_MasterTemplate = this.getMasterTemplate(mode); 209 var tpl = this.WebCom_CC_MasterTemplate.getMarkupText(this); 210 return WebCom.Util.TemplateUtil.format(tpl, this.getFormattingValues()); //where format is implement 211 }; 212 213 this.render = function (/*RenderMode*/ mode, /*Element*/ _target) { 214 var str = this.toHTML(mode); 215 216 var target = _target || document.getElementById(this.id); 217 if (target != null) { 218 target.innerHTML = str; 219 if (this.WebCom_CC_MasterTemplate && 220 typeof(this.WebCom_CC_MasterTemplate.postRender) == 'function') {
221 this.WebCom_CC_MasterTemplate.postRender(this.id); 222 } 223 224 this.fireEvent("renderComplete", [this]); 225 } 226 }; 227 228 // Each component will return their master template 229 this.getMasterTemplate = function (/*RenderMode*/ mode) { 230 throw new Error("Abstract method called. needs to be overriden !"); 231 } 232 233 /** Each component will return the formatting template associated with master 234 * template. It might include sub-template values 235 */ 236 this.getFormattingValues = function (/*RenderMode*/ mode) { 237 throw new Error("Abstract method called. needs to be overriden !"); 238 }; 239 240 /** 241 * Returns a Template reference if a match is found. The match order is: 242 * 243 * name, layout, mode 244 * name, mode 245 * name, layout 246 * name 247 * 248 * <code>mode</code> is more specific then <code>layoutName</code> 249 * 250 * @throws Error if no match is found 251 * @return Template reference 252 * 253 */ 254 this.getTemplate = function(/*String*/name, /*RenderMode*/ mode, /*String*/ layoutName){ 255 var template = null; 256 257 try { template = this._getTemplate(name + "_" + layoutName + "_" + mode); } 258 catch (e1) { 259 try { template = this._getTemplate(name + "_" + mode); } 260 catch (e2) { 261 try { template = this._getTemplate(name + "_" + layoutName); } 262 catch (e3) { 263 template = this._getTemplate(name); 264 } 265 } 266 } 267 return template; 268 }; 269 270 this._getTemplate = function (/*String*/ name) { 271 var templateInstanceName = this.getRuntimeName().split(".").join("_") + "_Template_" + name; 272 273 var templateLoaded; 274 eval ("templateLoaded = typeof " + templateInstanceName + " == 'object';"); 275 /* TODO: this is not really supported yes as ResourceLoader assumes the document 276 * is not closed for writing yet. Will need to make it so it can inject script 277 * tags into the DOM in case the document is closed and monitor for updates 278 */ 279 if (!templateLoaded) { 280 throw new Error("Sorry " + templateInstanceName + " template needs to be pre-loaded. Dynamic loading not implemented yet!"); 281 //sample this.loadResource("templates/" + name + ".js"); 282 } 283 284 var template; 285 eval ("template = " + templateInstanceName + ";"); 286 287 return template; 288 }; 289 290 this.getLocalization = function (/*String*/ locale, /*Object*/ hash) { 291 if (locale == null) { 292 locale = "enus"; 293 } 294 var localeInstanceName = this.getRuntimeName().split(".").join("_") + "_Locale_" + locale; 295 296 var localeLoaded; 297 eval ("localeLoaded = typeof " + localeInstanceName + " == 'object';"); 298 /* TODO: this is not really supported yes as ResourceLoader assumes the document 299 * is not closed for writing yet. Will need to make it so it can inject script 300 * tags into the DOM in case the document is closed and monitor for updates 301 */ 302 if (!localeInstanceName) { 303 throw new Error("Sorry " + localeInstanceName + " locale needs to be pre-loaded. Dynamic loading not implemented yet!"); 304 //sample this.loadResource("js/resources_" + locale + ".js"); 305 } 306 307 var resources; 308 eval ("resources = " + localeInstanceName + ";"); 309 310 if (hash != null) { 311 for (var key in resources) { 312 hash[key] = resources[key]; 313 } 314 } else { 315 return resources; 316 } 317 }; 318 319 // Optional parts to be filled in ... 320 this.show = function () { 321 322 }; 323 324 this.hide = function() { 325 326 }; 327} 328 329WebCom.ResourceLoader.makeNameSpace("WebCom.Components"); 330WebCom.Components.Component = WebCom_Components_Component; 331WebCom.Components.Component.prototype = new WebCom.Components.BasicComponent(); 332 333function WebCom_Browser() { 334 var ua = navigator.userAgent.toLowerCase(); 335 this.check = function(r){ 336 return r.test(ua); 337 }; 338 this.isOpera = this.check(/opera/); 339 this.isChrome = this.check(/chrome/); 340 this.isWebKit = this.check(/webkit/); 341 this.isSafari = !this.isChrome && this.check(/safari/); 342 this.isIE = !this.isOpera && this.check(/msie/); 343 this.isIE7 = this.isIE && this.check(/msie 7/); 344 this.isIE8 = this.isIE && this.check(/msie 8/); 345 this.isIE6 = this.isIE && !this.isIE7 && !this.isIE8; 346 this.isGecko = !this.isWebKit && this.check(/gecko/); 347 this.isWindows = this.check(/windows|win32/); 348 this.isMac = this.check(/macintosh|mac os x/); 349 this.isLinux = this.check(/linux/); 350 this.isSecure = /^https/i.test(window.location.protocol); 351} 352 353WebCom.Browser = new WebCom_Browser();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.