Current Path : C:/xampp/htdocs/moodle/lib/yuilib/3.17.2/cache-base/ |
Current File : C:/xampp/htdocs/moodle/lib/yuilib/3.17.2/cache-base/cache-base.js |
/* YUI 3.17.2 (build 9c3c78e) Copyright 2014 Yahoo! Inc. All rights reserved. Licensed under the BSD License. http://yuilibrary.com/license/ */ 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 values this._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 array entries[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 that if(details && LANG.isValue(details.request)) { pos = this._position(details.request); if(LANG.isValue(pos)) { entries.splice(pos,1); } } //no item, flush everything else { 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 newest for(; i >= 0; i--) { // Execute matching function if(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 hit if(pos < length-1) { // Remove element from its original location entries.splice(pos,1); // Add as newest entries[entries.length] = entry; } return entry; } } return null; } }); Y.Cache = Cache; }, '3.17.2', {"requires": ["base"]});