📄 core.js
字号:
* CAUTION: When adding and removing methods as listeners, note that two separately * constructed methods will not be treated as equal, even if their instance and method * properties are the same. Failing to heed this warning can result in a memory leak, * as listeners would never be removed. * * @param instance the object instance * @param {Function} method the method to be invoked on the instance * @return the return value provided by the method */ method: function(instance, method) { return function() { return method.apply(instance, arguments); }; }, /** * Add properties of mixin objects to destination object. * Mixins will be added in order, and any property which is already * present in the destination object will not be overridden. * * @param destination the destination object * @param {Array} mixins the mixin objects to add */ _processMixins: function(destination, mixins) { for (var i = 0; i < mixins.length; ++i) { for (var mixinProperty in mixins[i]) { if (destination.prototype[mixinProperty]) { // Ignore mixin properties that already exist. continue; } destination.prototype[mixinProperty] = mixins[i][mixinProperty]; } } }, /** * Sets a value in an object hierarchy. * * Examples: * Given the following object 'o': <code>{ a: { b: 4, c: 2 } }</code> * <ul> * <li><code>Core.set(o, ["a", "b"], 5)</code> will update the value of 'o' to be: <code>{ a: { b: 5, c: 2 } }</code></li> * <li><code>Core.set(o, ["a", "d"], 7)</code> will update the value of 'o' to be: * <code>{ a: { b: 4, c: 2, d: 7 } }</code></li> * <li><code>Core.set(o, ["e"], 9)</code> will update the value of 'o' to be: <code>{ a: { b: 4, c: 2 }, e: 9 }</code></li> * <li><code>Core.set(o, ["f", "g"], 8)</code> will update the value of 'o' to be: * <code>{ a: { b: 4, c: 2 }, f: { g: 8 } }</code></li> * <li><code>Core.set(o, ["a"], 10)</code> will update the value of 'o' to be: <code>{ a: 10 }</code></li> * </ul> * * @param object an arbitrary object from which the value should be retrieved * @param {Array} path an array of object property names describing the path to retrieve * @return the value, if found, or null if it does not exist */ set: function(object, path, value) { var parentObject = null; // Find or create container object. for (var i = 0; i < path.length - 1; ++i) { parentObject = object; object = object[path[i]]; if (!object) { object = {}; parentObject[path[i]] = object; } } // Assign value. object[path[path.length - 1]] = value; }, /** * Verifies that a concrete derivative of an abstract class implements * abstract properties present in the base class. * * @param constructorClass the class to verify */ _verifyAbstractImpl: function(constructorClass) { var baseClass = constructorClass.$super; if (!baseClass || !baseClass.$abstract || baseClass.$abstract === true) { return; } for (var x in baseClass.$abstract) { if (constructorClass.prototype[x] == null) { throw new Error("Concrete class does not provide implementation of abstract method \"" + x + "\"."); } } }};/** * Namespace for debugging related utilities. * @class */Core.Debug = { /** * The DOM element to which console output should be written. * @type HTMLElement */ consoleElement: null, /** * Flag indicating whether console output should be displayed as alerts. * Enabling is generally not recommended. * @type Boolean */ useAlertDialog: false, /** * Writes a message to the debug console. * * @param {String} text the message */ consoleWrite: function(text) { if (Core.Debug.consoleElement) { var entryElement = document.createElement("div"); entryElement.appendChild(document.createTextNode(text)); if (Core.Debug.consoleElement.childNodes.length === 0) { Core.Debug.consoleElement.appendChild(entryElement); } else { Core.Debug.consoleElement.insertBefore(entryElement, Core.Debug.consoleElement.firstChild); } } else if (Core.Debug.useAlertDialog) { alert("DEBUG:" + text); } }, /** * Creates a string representation of the state of an object's instance variables. * * @param object the object to convert to a string * @return the string * @type String */ toString: function(object) { var s = ""; for (var x in object) { if (typeof object[x] != "function") { s += x + ":" + object[x] + "\n"; } } return s; }};/** * Arrays namespace. */Core.Arrays = { /** * Returns <tt>true</tt> if the first array contains all of the elements * in the second array. * * @param {Array} array1 the array to be analyzed * @param {Array} array2 an array whose elements must all be present in <code>array1</code> * for this method to return <code>true</code> * @param {Boolean} unique optional flag indicating that all elements in array2 are unique * @return <tt>true</tt> if the first array contains all of the elements * in the second array * @type Boolean */ containsAll: function(array1, array2, unique) { if (unique && array1.length < array2.length) { return false; } if (array2.length === 0) { return true; } var found, item; for (var i = 0; i < array2.length; ++i) { found = false; item = array2[i]; for (var j = 0; j < array1.length; ++j) { if (item == array1[j]) { found = true; break; } } if (!found) { return false; } } return true; }, /** * Returns the index of the specified item within the array, or -1 if it * is not contained in the array. * * @param item the item * @return the index of the item, or -1 if it is not present in the array * @type Number */ indexOf: function(array, item) { for (var i = 0; i < array.length; ++i) { if (item == array[i]) { return i; } } return -1; }, /** * Removes the first instance of the specified item from an array. * If the item does not exist in the array, no action is taken. * Equality is determined using the '==' operator. * * @param array the array from which the item should be removed * @param item the item to remove */ remove: function(array, item) { for (var i = 0; i < array.length; ++i) { if (item == array[i]) { array.splice(i, 1); return; } } }, /** * Removes duplicate items from an array. * Items retained in the array may not appear in the previous order. * * @param array the array from which duplicates are to be removed. */ removeDuplicates: function(array) { array.sort(); var removeCount = 0; // Iterate from last element to second element. for (var i = array.length - 1; i > 0; --i) { // Determine if element is equivalent to previous element. if (array[i] == array[i - 1]) { // If duplicate, copy last element in array over current element. array[i] = array[array.length - 1 - removeCount]; // Increment removeCount (indicating how much the length of the array should be decremented) ++removeCount; } } if (removeCount > 0) { array.length = array.length - removeCount; } }};/** * Associative array wrapper which periodically recreates the associative array * in order to avoid memory leakage and performance problems on certain browser * platforms, i.e., Internet Explorer 6. * Null values are not permitted as keys. Setting a key to a null value * will result in the key being removed. */Core.Arrays.LargeMap = Core.extend({ $static: { /** * Flag indicating whether forced garbage collection should be enabled. * This flag should be manually set in environments where it is required. * (The web module does this automatically for IE6.) */ garbageCollectEnabled: false }, /** * Number of removes since last associative array re-creation. * @type Number */ _removeCount: 0, /** * Number (integer) of removes between associative array re-creation. * @type Number */ garbageCollectionInterval: 250, /** * Associative mapping. */ map: null, /** * Creates a new LargeMap. */ $construct: function() { this.map = {}; }, /** * Performs 'garbage-collection' operations, recreating the array. * This operation is necessary due to Internet Explorer memory leak * issues. */ _garbageCollect: function() { this._removeCount = 0; var newMap = {}; for (var key in this.map) { newMap[key] = this.map[key]; } this.map = newMap; }, /** * Removes the value referenced by the specified key. * * @param key the key */ remove: function(key) { delete this.map[key]; if (Core.Arrays.LargeMap.garbageCollectEnabled) { ++this._removeCount; if (this._removeCount >= this.garbageCollectionInterval) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -