| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * The global object. | 6 * The global object. |
| 7 * @type {!Object} | 7 * @type {!Object} |
| 8 * @const | 8 * @const |
| 9 */ | 9 */ |
| 10 var global = this; | 10 var global = this; |
| 11 | 11 |
| 12 /** Platform, package, object property, and Event support. **/ | 12 /** Platform, package, object property, and Event support. **/ |
| 13 this.cr = (function() { | 13 var cr = function() { |
| 14 'use strict'; | 14 'use strict'; |
| 15 | 15 |
| 16 /** | 16 /** |
| 17 * Builds an object structure for the provided namespace path, | 17 * Builds an object structure for the provided namespace path, |
| 18 * ensuring that names that already exist are not overwritten. For | 18 * ensuring that names that already exist are not overwritten. For |
| 19 * example: | 19 * example: |
| 20 * "a.b.c" -> a = {};a.b={};a.b.c={}; | 20 * "a.b.c" -> a = {};a.b={};a.b.c={}; |
| 21 * @param {string} name Name of the object that this file defines. | 21 * @param {string} name Name of the object that this file defines. |
| 22 * @param {*=} opt_object The object to expose at the end of the path. | 22 * @param {*=} opt_object The object to expose at the end of the path. |
| 23 * @param {Object=} opt_objectToExportTo The object to add the path to; | 23 * @param {Object=} opt_objectToExportTo The object to add the path to; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 * attribute name. | 61 * attribute name. |
| 62 * @param {string} jsName The javascript camelCase property name. | 62 * @param {string} jsName The javascript camelCase property name. |
| 63 * @return {string} The equivalent hyphenated-lower-case attribute name. | 63 * @return {string} The equivalent hyphenated-lower-case attribute name. |
| 64 */ | 64 */ |
| 65 function getAttributeName(jsName) { | 65 function getAttributeName(jsName) { |
| 66 return jsName.replace(/([A-Z])/g, '-$1').toLowerCase(); | 66 return jsName.replace(/([A-Z])/g, '-$1').toLowerCase(); |
| 67 } | 67 } |
| 68 | 68 |
| 69 /** | 69 /** |
| 70 * The kind of property to define in {@code defineProperty}. | 70 * The kind of property to define in {@code defineProperty}. |
| 71 * @enum {number} | 71 * @enum {string} |
| 72 * @const | 72 * @const |
| 73 */ | 73 */ |
| 74 var PropertyKind = { | 74 var PropertyKind = { |
| 75 /** | 75 /** |
| 76 * Plain old JS property where the backing data is stored as a "private" | 76 * Plain old JS property where the backing data is stored as a "private" |
| 77 * field on the object. | 77 * field on the object. |
| 78 */ | 78 */ |
| 79 JS: 'js', | 79 JS: 'js', |
| 80 | 80 |
| 81 /** | 81 /** |
| 82 * The property backing data is stored as an attribute on an element. | 82 * The property backing data is stored as an attribute on an element. |
| 83 */ | 83 */ |
| 84 ATTR: 'attr', | 84 ATTR: 'attr', |
| 85 | 85 |
| 86 /** | 86 /** |
| 87 * The property backing data is stored as an attribute on an element. If the | 87 * The property backing data is stored as an attribute on an element. If the |
| 88 * element has the attribute then the value is true. | 88 * element has the attribute then the value is true. |
| 89 */ | 89 */ |
| 90 BOOL_ATTR: 'boolAttr' | 90 BOOL_ATTR: 'boolAttr' |
| 91 }; | 91 }; |
| 92 | 92 |
| 93 /** | 93 /** |
| 94 * Helper function for defineProperty that returns the getter to use for the | 94 * Helper function for defineProperty that returns the getter to use for the |
| 95 * property. | 95 * property. |
| 96 * @param {string} name The name of the property. | 96 * @param {string} name The name of the property. |
| 97 * @param {cr.PropertyKind} kind The kind of the property. | 97 * @param {PropertyKind} kind The kind of the property. |
| 98 * @return {function():*} The getter for the property. | 98 * @return {function():*} The getter for the property. |
| 99 */ | 99 */ |
| 100 function getGetter(name, kind) { | 100 function getGetter(name, kind) { |
| 101 switch (kind) { | 101 switch (kind) { |
| 102 case PropertyKind.JS: | 102 case PropertyKind.JS: |
| 103 var privateName = name + '_'; | 103 var privateName = name + '_'; |
| 104 return function() { | 104 return function() { |
| 105 return this[privateName]; | 105 return this[privateName]; |
| 106 }; | 106 }; |
| 107 case PropertyKind.ATTR: | 107 case PropertyKind.ATTR: |
| 108 var attributeName = getAttributeName(name); | 108 var attributeName = getAttributeName(name); |
| 109 return function() { | 109 return function() { |
| 110 return this.getAttribute(attributeName); | 110 return this.getAttribute(attributeName); |
| 111 }; | 111 }; |
| 112 case PropertyKind.BOOL_ATTR: | 112 case PropertyKind.BOOL_ATTR: |
| 113 var attributeName = getAttributeName(name); | 113 var attributeName = getAttributeName(name); |
| 114 return function() { | 114 return function() { |
| 115 return this.hasAttribute(attributeName); | 115 return this.hasAttribute(attributeName); |
| 116 }; | 116 }; |
| 117 } | 117 } |
| 118 |
| 119 // TODO(dbeam): replace with assertNotReached() in assert.js when I can coax |
| 120 // the browser/unit tests to preprocess this file through grit. |
| 121 throw 'not reached'; |
| 118 } | 122 } |
| 119 | 123 |
| 120 /** | 124 /** |
| 121 * Helper function for defineProperty that returns the setter of the right | 125 * Helper function for defineProperty that returns the setter of the right |
| 122 * kind. | 126 * kind. |
| 123 * @param {string} name The name of the property we are defining the setter | 127 * @param {string} name The name of the property we are defining the setter |
| 124 * for. | 128 * for. |
| 125 * @param {cr.PropertyKind} kind The kind of property we are getting the | 129 * @param {PropertyKind} kind The kind of property we are getting the |
| 126 * setter for. | 130 * setter for. |
| 127 * @param {function(*):void} opt_setHook A function to run after the property | 131 * @param {function(*, *):void=} opt_setHook A function to run after the |
| 128 * is set, but before the propertyChange event is fired. | 132 * property is set, but before the propertyChange event is fired. |
| 129 * @return {function(*):void} The function to use as a setter. | 133 * @return {function(*):void} The function to use as a setter. |
| 130 */ | 134 */ |
| 131 function getSetter(name, kind, opt_setHook) { | 135 function getSetter(name, kind, opt_setHook) { |
| 132 switch (kind) { | 136 switch (kind) { |
| 133 case PropertyKind.JS: | 137 case PropertyKind.JS: |
| 134 var privateName = name + '_'; | 138 var privateName = name + '_'; |
| 135 return function(value) { | 139 return function(value) { |
| 136 var oldValue = this[name]; | 140 var oldValue = this[name]; |
| 137 if (value !== oldValue) { | 141 if (value !== oldValue) { |
| 138 this[privateName] = value; | 142 this[privateName] = value; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 165 if (value) | 169 if (value) |
| 166 this.setAttribute(attributeName, name); | 170 this.setAttribute(attributeName, name); |
| 167 else | 171 else |
| 168 this.removeAttribute(attributeName); | 172 this.removeAttribute(attributeName); |
| 169 if (opt_setHook) | 173 if (opt_setHook) |
| 170 opt_setHook.call(this, value, oldValue); | 174 opt_setHook.call(this, value, oldValue); |
| 171 dispatchPropertyChange(this, name, value, oldValue); | 175 dispatchPropertyChange(this, name, value, oldValue); |
| 172 } | 176 } |
| 173 }; | 177 }; |
| 174 } | 178 } |
| 179 |
| 180 // TODO(dbeam): replace with assertNotReached() in assert.js when I can coax |
| 181 // the browser/unit tests to preprocess this file through grit. |
| 182 throw 'not reached'; |
| 175 } | 183 } |
| 176 | 184 |
| 177 /** | 185 /** |
| 178 * Defines a property on an object. When the setter changes the value a | 186 * Defines a property on an object. When the setter changes the value a |
| 179 * property change event with the type {@code name + 'Change'} is fired. | 187 * property change event with the type {@code name + 'Change'} is fired. |
| 180 * @param {!Object} obj The object to define the property for. | 188 * @param {!Object} obj The object to define the property for. |
| 181 * @param {string} name The name of the property. | 189 * @param {string} name The name of the property. |
| 182 * @param {cr.PropertyKind=} opt_kind What kind of underlying storage to use. | 190 * @param {PropertyKind=} opt_kind What kind of underlying storage to use. |
| 183 * @param {function(*):void} opt_setHook A function to run after the | 191 * @param {function(*, *):void=} opt_setHook A function to run after the |
| 184 * property is set, but before the propertyChange event is fired. | 192 * property is set, but before the propertyChange event is fired. |
| 185 */ | 193 */ |
| 186 function defineProperty(obj, name, opt_kind, opt_setHook) { | 194 function defineProperty(obj, name, opt_kind, opt_setHook) { |
| 187 if (typeof obj == 'function') | 195 if (typeof obj == 'function') |
| 188 obj = obj.prototype; | 196 obj = obj.prototype; |
| 189 | 197 |
| 190 var kind = opt_kind || PropertyKind.JS; | 198 var kind = /** @type {PropertyKind} */ (opt_kind || PropertyKind.JS); |
| 191 | 199 |
| 192 if (!obj.__lookupGetter__(name)) | 200 if (!obj.__lookupGetter__(name)) |
| 193 obj.__defineGetter__(name, getGetter(name, kind)); | 201 obj.__defineGetter__(name, getGetter(name, kind)); |
| 194 | 202 |
| 195 if (!obj.__lookupSetter__(name)) | 203 if (!obj.__lookupSetter__(name)) |
| 196 obj.__defineSetter__(name, getSetter(name, kind, opt_setHook)); | 204 obj.__defineSetter__(name, getSetter(name, kind, opt_setHook)); |
| 197 } | 205 } |
| 198 | 206 |
| 199 /** | 207 /** |
| 200 * Counter for use with createUid | 208 * Counter for use with createUid |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 * instance object. | 284 * instance object. |
| 277 * @param {!Function} ctor The constructor for the class to add the static | 285 * @param {!Function} ctor The constructor for the class to add the static |
| 278 * method to. | 286 * method to. |
| 279 */ | 287 */ |
| 280 function addSingletonGetter(ctor) { | 288 function addSingletonGetter(ctor) { |
| 281 ctor.getInstance = function() { | 289 ctor.getInstance = function() { |
| 282 return ctor.instance_ || (ctor.instance_ = new ctor()); | 290 return ctor.instance_ || (ctor.instance_ = new ctor()); |
| 283 }; | 291 }; |
| 284 } | 292 } |
| 285 | 293 |
| 286 /** | |
| 287 * Initialization which must be deferred until run-time. | |
| 288 */ | |
| 289 function initialize() { | |
| 290 // If 'document' isn't defined, then we must be being pre-compiled, | |
| 291 // so set a trap so that we're initialized on first access at run-time. | |
| 292 if (!global.document) { | |
| 293 var originalCr = cr; | |
| 294 | |
| 295 Object.defineProperty(global, 'cr', { | |
| 296 get: function() { | |
| 297 Object.defineProperty(global, 'cr', {value: originalCr}); | |
| 298 originalCr.initialize(); | |
| 299 return originalCr; | |
| 300 }, | |
| 301 configurable: true | |
| 302 }); | |
| 303 | |
| 304 return; | |
| 305 } | |
| 306 | |
| 307 cr.doc = document; | |
| 308 | |
| 309 /** | |
| 310 * Whether we are using a Mac or not. | |
| 311 */ | |
| 312 cr.isMac = /Mac/.test(navigator.platform); | |
| 313 | |
| 314 /** | |
| 315 * Whether this is on the Windows platform or not. | |
| 316 */ | |
| 317 cr.isWindows = /Win/.test(navigator.platform); | |
| 318 | |
| 319 /** | |
| 320 * Whether this is on chromeOS or not. | |
| 321 */ | |
| 322 cr.isChromeOS = /CrOS/.test(navigator.userAgent); | |
| 323 | |
| 324 /** | |
| 325 * Whether this is on vanilla Linux (not chromeOS). | |
| 326 */ | |
| 327 cr.isLinux = /Linux/.test(navigator.userAgent); | |
| 328 | |
| 329 /** | |
| 330 * Whether this uses the views toolkit or not. | |
| 331 */ | |
| 332 cr.isViews = typeof chrome.getVariableValue == 'function' && | |
| 333 /views/.test(chrome.getVariableValue('toolkit')); | |
| 334 } | |
| 335 | |
| 336 return { | 294 return { |
| 337 addSingletonGetter: addSingletonGetter, | 295 addSingletonGetter: addSingletonGetter, |
| 338 createUid: createUid, | 296 createUid: createUid, |
| 339 define: define, | 297 define: define, |
| 340 defineProperty: defineProperty, | 298 defineProperty: defineProperty, |
| 341 dispatchPropertyChange: dispatchPropertyChange, | 299 dispatchPropertyChange: dispatchPropertyChange, |
| 342 dispatchSimpleEvent: dispatchSimpleEvent, | 300 dispatchSimpleEvent: dispatchSimpleEvent, |
| 343 getUid: getUid, | 301 getUid: getUid, |
| 344 initialize: initialize, | 302 PropertyKind: PropertyKind, |
| 345 PropertyKind: PropertyKind | 303 |
| 304 get doc() { |
| 305 return document; |
| 306 }, |
| 307 |
| 308 /** Whether we are using a Mac or not. */ |
| 309 get isMac() { |
| 310 return /Mac/.test(navigator.platform); |
| 311 }, |
| 312 |
| 313 /** Whether this is on the Windows platform or not. */ |
| 314 get isWindows() { |
| 315 return /Win/.test(navigator.platform); |
| 316 }, |
| 317 |
| 318 /** Whether this is on chromeOS or not. */ |
| 319 get isChromeOS() { |
| 320 return /CrOS/.test(navigator.userAgent); |
| 321 }, |
| 322 |
| 323 /** Whether this is on vanilla Linux (not chromeOS). */ |
| 324 get isLinux() { |
| 325 return /Linux/.test(navigator.userAgent); |
| 326 }, |
| 327 |
| 328 /** Whether this uses the views toolkit or not. */ |
| 329 get isViews() { |
| 330 return typeof chrome.getVariableValue == 'function' && |
| 331 /views/.test(chrome.getVariableValue('toolkit')); |
| 332 }, |
| 346 }; | 333 }; |
| 347 })(); | 334 }(); |
| 348 | |
| 349 | |
| 350 /** | |
| 351 * TODO(kgr): Move this to another file which is to be loaded last. | |
| 352 * This will be done as part of future work to make this code pre-compilable. | |
| 353 */ | |
| 354 cr.initialize(); | |
| OLD | NEW |