Bikarhêner:Balyozxane/Gadget-StorageUtils.js

Ji Wîkîferhengê

Zanibe: Piştî weşandinê, ji bo dîtina guhartinan dibe ku hewce be "cache"ya geroka xwe paqij bikî.

  • Firefox / Safari: Pê li Shift û Reload bike an jî Ctrl-F5 an Ctrl-R bike (ji bo Mac: ⌘-R)
  • Google Chrome: Pê li Ctrl-Shift-R (ji bo Mac: ⌘-Shift-R) bike
  • Internet Explorer / Edge: Pê li Ctrl û Refresh bike, an jî Ctrl-F5 bike
  • Opera: Pê li Ctrl-F5 bike.
// {{documentation}}
// implicit dependencies : mediawiki.cookie,mw.storage
/* jshint maxerr:1048576, strict:true, undef:true, latedef:true, es5:true, sub:true */

/* global mw, $ */

//lowest level wrapper. wraps localstorage and cookie
var StorageWrapper = window.StorageWrapper = function(){
	this.localStorageAvailable = mw.storage.get("localStorageTest") !== false;
	this.storageAvailable = this.localStorageAvailable || navigator.cookieEnabled;
	this.cookiePreferences = {
		expires: 30, path: '/'
	};
	
	this.set = function(name, value){
		if (this.localStorageAvailable) {
			localStorage[name] = value;
		} else {
			mw.cookie.set(name, value, {});
		}
	};
	this.get = function(name) {
		if (this.localStorageAvailable){
			return localStorage[name];
		} else {
			return mw.cookie.get(name);
		}
	};
};

// expirable, lazy object storage. ideally should inherit(?) from ObjectStorage
window.CacheableStorage = function(productName, getProductCallback, expireInDays, version){
	this.storageWrapper = new StorageWrapper();
	this.StorageAvailable = this.storageWrapper.storageAvailable;
	this.expireInDays = expireInDays;
	this.version = version || 1;
	this.productName = productName;
	this.getProductCallback = getProductCallback;
	this._cachedData = null;
	
	this.itemAddressPrefix = "enwikt/CacheableStorage/" + this.productName + "?v=" + this.version;
	this.itemDataAddress = this.itemAddressPrefix + "&Type=Data";
	this.itemTypeAddress = this.itemAddressPrefix + "&Type=Type";
	this.itemExpirationAddress = this.itemAddressPrefix + "&Type=Expiration";
	
	this.refreshData = function() {
		var this1 = this;
		this.getProductCallback().then(function(d) {
			this1.storageWrapper.set(this1.itemTypeAddress, typeof(d));
			this1.storageWrapper.set(this1.itemExpirationAddress, new Date().toISOString());
			
			if (typeof(d) != "string") d = JSON.stringify(d);
			this1.storageWrapper.set(this1.itemDataAddress, d);
		});
	};
	this.GetItem = function(){
		if (this._cachedData)
			return this._cachedData;
		
		var data = this.storageWrapper.get(this.itemDataAddress);
		var type = this.storageWrapper.get(this.itemTypeAddress);
		var expiration = this.storageWrapper.get(this.itemExpirationAddress);
		if (data)
		{
			if (type != "string") data = JSON.parse(data);
			if ((new Date() - new Date(expiration))/1000 > this.expireInDays*24*3600){
				this.refreshData();
				return data;
			}
			else{
				this._cachedData=data;
				return this._cachedData;
			}
		}
		else
		{
			this.refreshData();
		}
		return null;
	};
};


//not expirable
window.ObjectStorage = function(contextName, version){
	this.storageWrapper = new StorageWrapper();
	this.StorageAvailable = this.storageWrapper.storageAvailable;
	this.version = version || 1;
	this.contextName = contextName;
	this._cachedData = null;
	
	this.itemAddressPrefix = "enwikt/ObjectStorage/" + this.contextName + "?v=" + this.version;
	this.itemDataAddress = this.itemAddressPrefix + "&Type=Data";
	this.itemTypeAddress = this.itemAddressPrefix + "&Type=Type";
	
	this.Set = function(obj) {
		var s = typeof(obj) == "string" ? obj : JSON.stringify(obj);
		this.storageWrapper.set(this.itemDataAddress, s);
		this.storageWrapper.set(this.itemTypeAddress, typeof(obj));
		this._cachedData = obj;
	};
	this.Get = function(){
		if (this._cachedData)
			return this._cachedData;
		
		var data = this.storageWrapper.get(this.itemDataAddress);
		var type = this.storageWrapper.get(this.itemTypeAddress);
		if (data)
		{
			if (type != "string") data = JSON.parse(data);
			this._cachedData=data;
			return this._cachedData;
		}
		return null;
	};
};