AutorÃa | Ultima modificación | Ver Log |
YUI.add('cache-base', function (Y, NAME) {/*** The Cache utility provides a common configurable interface for components to* cache and retrieve data from a local JavaScript struct.** @module cache* @main*//*** Provides the base class for the YUI Cache utility.** @submodule cache-base*/var LANG = Y.Lang,isDate = Y.Lang.isDate,/*** Base class for the YUI Cache utility.* @class Cache* @extends Base* @constructor*/Cache = function() {Cache.superclass.constructor.apply(this, arguments);};///////////////////////////////////////////////////////////////////////////////// Cache static properties///////////////////////////////////////////////////////////////////////////////Y.mix(Cache, {/*** Class name.** @property NAME* @type String* @static* @final* @value "cache"*/NAME: "cache",ATTRS: {///////////////////////////////////////////////////////////////////////////////// Cache Attributes////////////////////////////////////////////////////////////////////////////////*** @attribute max* @description Maximum number of entries the Cache can hold.* Set to 0 to turn off caching.* @type Number* @default 0*/max: {value: 0,setter: "_setMax"},/*** @attribute size* @description Number of entries currently cached.* @type Number*/size: {readOnly: true,getter: "_getSize"},/*** @attribute uniqueKeys* @description Validate uniqueness of stored keys. Default is false and* is more performant.* @type Boolean*/uniqueKeys: {value: false},/*** @attribute expires* @description Absolute Date when data expires or* relative number of milliseconds. Zero disables expiration.* @type Date | Number* @default 0*/expires: {value: 0,validator: function(v) {return Y.Lang.isDate(v) || (Y.Lang.isNumber(v) && v >= 0);}},/*** @attribute entries* @description Cached entries.* @type Array*/entries: {readOnly: true,getter: "_getEntries"}}});Y.extend(Cache, Y.Base, {///////////////////////////////////////////////////////////////////////////////// Cache private properties////////////////////////////////////////////////////////////////////////////////*** Array of request/response objects indexed chronologically.** @property _entries* @type Object[]* @private*/_entries: null,///////////////////////////////////////////////////////////////////////////////// Cache private methods////////////////////////////////////////////////////////////////////////////////*** @method initializer* @description Internal init() handler.* @param config {Object} Config object.* @private*/initializer: function(config) {/*** @event add* @description Fired when an entry is added.* @param e {EventFacade} Event Facade with the following properties:* <dl>* <dt>entry (Object)</dt> <dd>The cached entry.</dd>* </dl>* @preventable _defAddFn*/this.publish("add", {defaultFn: this._defAddFn});/*** @event flush* @description Fired when the cache is flushed.* @param e {EventFacade} Event Facade object.* @preventable _defFlushFn*/this.publish("flush", {defaultFn: this._defFlushFn});/*** @event request* @description Fired when an entry is requested from the cache.* @param e {EventFacade} Event Facade with the following properties:* <dl>* <dt>request (Object)</dt> <dd>The request object.</dd>* </dl>*//*** @event retrieve* @description Fired when an entry is retrieved from the cache.* @param e {EventFacade} Event Facade with the following properties:* <dl>* <dt>entry (Object)</dt> <dd>The retrieved entry.</dd>* </dl>*/// Initialize internal valuesthis._entries = [];},/*** @method destructor* @description Internal destroy() handler.* @private*/destructor: function() {this._entries = [];},///////////////////////////////////////////////////////////////////////////////// Cache protected methods////////////////////////////////////////////////////////////////////////////////*** Sets max.** @method _setMax* @protected*/_setMax: function(value) {// If the cache is full, make room by removing stalest element (index=0)var entries = this._entries;if(value > 0) {if(entries) {while(entries.length > value) {entries.shift();}}}else {value = 0;this._entries = [];}return value;},/*** Gets size.** @method _getSize* @protected*/_getSize: function() {return this._entries.length;},/*** Gets all entries.** @method _getEntries* @protected*/_getEntries: function() {return this._entries;},/*** Adds entry to cache.** @method _defAddFn* @param e {EventFacade} Event Facade with the following properties:* <dl>* <dt>entry (Object)</dt> <dd>The cached entry.</dd>* </dl>* @protected*/_defAddFn: function(e) {var entries = this._entries,entry = e.entry,max = this.get("max"),pos;// If uniqueKeys is true and item exists with this key, then remove it.if (this.get("uniqueKeys")) {pos = this._position(e.entry.request);if (LANG.isValue(pos)) {entries.splice(pos, 1);}}// If the cache at or over capacity, make room by removing stalest// element(s) starting at index-0.while (max && entries.length >= max) {entries.shift();}// Add entry to cache in the newest position, at the end of the arrayentries[entries.length] = entry;},/*** Flushes cache.** @method _defFlushFn* @param e {EventFacade} Event Facade object.* @protected*/_defFlushFn: function(e) {var entries = this._entries,details = e.details[0],pos;//passed an item, flush only thatif(details && LANG.isValue(details.request)) {pos = this._position(details.request);if(LANG.isValue(pos)) {entries.splice(pos,1);}}//no item, flush everythingelse {this._entries = [];}},/*** Default overridable method compares current request with given cache entry.* Returns true if current request matches the cached request, otherwise* false. Implementers should override this method to customize the* cache-matching algorithm.** @method _isMatch* @param request {Object} Request object.* @param entry {Object} Cached entry.* @return {Boolean} True if current request matches given cached request, false otherwise.* @protected*/_isMatch: function(request, entry) {if(!entry.expires || new Date() < entry.expires) {return (request === entry.request);}return false;},/*** Returns position of a request in the entries array, otherwise null.** @method _position* @param request {Object} Request object.* @return {Number} Array position if found, null otherwise.* @protected*/_position: function(request) {// If cache is enabled...var entries = this._entries,length = entries.length,i = length-1;if((this.get("max") === null) || this.get("max") > 0) {// Loop through each cached entry starting from the newestfor(; i >= 0; i--) {// Execute matching functionif(this._isMatch(request, entries[i])) {return i;}}}return null;},///////////////////////////////////////////////////////////////////////////////// Cache public methods////////////////////////////////////////////////////////////////////////////////*** Adds a new entry to the cache of the format* {request:request, response:response, cached:cached, expires:expires}.* If cache is full, evicts the stalest entry before adding the new one.** @method add* @param request {Object} Request value.* @param response {Object} Response value.*/add: function(request, response) {var expires = this.get("expires");if(this.get("initialized") && ((this.get("max") === null) || this.get("max") > 0) &&(LANG.isValue(request) || LANG.isNull(request) || LANG.isUndefined(request))) {this.fire("add", {entry: {request:request,response:response,cached: new Date(),expires: isDate(expires) ? expires :(expires ? new Date(new Date().getTime() + this.get("expires")) : null)}});}else {}},/*** Flushes cache.** @method flush*/flush: function(request) {this.fire("flush", { request: (LANG.isValue(request) ? request : null) });},/*** Retrieves cached object for given request, if available, and refreshes* entry in the cache. Returns null if there is no cache match.** @method retrieve* @param request {Object} Request object.* @return {Object} Cached object with the properties request and response, or null.*/retrieve: function(request) {// If cache is enabled...var entries = this._entries,length = entries.length,entry = null,pos;if((length > 0) && ((this.get("max") === null) || (this.get("max") > 0))) {this.fire("request", {request: request});pos = this._position(request);if(LANG.isValue(pos)) {entry = entries[pos];this.fire("retrieve", {entry: entry});// Refresh the position of the cache hitif(pos < length-1) {// Remove element from its original locationentries.splice(pos,1);// Add as newestentries[entries.length] = entry;}return entry;}}return null;}});Y.Cache = Cache;}, '3.18.1', {"requires": ["base"]});