Merge "Replace Linker::link() with LinkRenderer in includes directory"
[lhc/web/wiklou.git] / resources / src / mediawiki / mediawiki.storage.js
index e10b561..20f8efb 100644 (file)
@@ -1,69 +1,91 @@
 ( function ( mw ) {
        'use strict';
-       var storage;
+
+       // Catch exceptions to avoid fatal in Chrome's "Block data storage" mode
+       // which throws when accessing the localStorage property itself, as opposed
+       // to the standard behaviour of throwing on getItem/setItem. (T148998)
+       var
+               localStorage = ( function () {
+                       try {
+                               return window.localStorage;
+                       } catch ( e ) {}
+               }() ),
+               sessionStorage = ( function () {
+                       try {
+                               return window.sessionStorage;
+                       } catch ( e ) {}
+               }() );
 
        /**
-        * Library for storing device specific information. It should be used for storing simple
-        * strings and is not suitable for storing large chunks of data.
-        * @class mw.storage
-        * @singleton
+        * A wrapper for an HTML5 Storage interface (`localStorage` or `sessionStorage`)
+        * that is safe to call on all browsers.
+        *
+        * @class mw.SafeStorage
+        * @private
         */
-       storage = {
-               isLocalStorageSupported: false,
-               /**
-                * Retrieve value from device storage.
-                *
-                * @param {String} key of item to retrieve
-                * @returns {String|Boolean} false when localStorage not available, otherwise string
-                */
-               get: function ( key ) {
-                       if ( this.isLocalStorageSupported ) {
-                               return localStorage.getItem( key );
-                       } else {
-                               return false;
-                       }
-               },
 
-               /**
-                * Set a value in device storage.
-                *
-                * @param {String} key key name to store under.
-                * @param {String} value to be stored.
-                * @returns {Boolean} whether the save succeeded or not.
-                */
-               set: function ( key, value ) {
-                       try {
-                               localStorage.setItem( key, value );
-                               return true;
-                       } catch ( e ) {
-                               return false;
-                       }
-               },
+       /**
+        * @ignore
+        * @param {Object|undefined} store The Storage instance to wrap around
+        */
+       function SafeStorage( store ) {
+               this.store = store;
+       }
 
-               /**
-                * Remove a value from device storage.
-                *
-                * @param {String} key of item to remove.
-                * @returns {Boolean} whether the save succeeded or not.
-                */
-               remove: function ( key ) {
-                       if ( this.isLocalStorageSupported ) {
-                               localStorage.removeItem( key );
-                               return true;
-                       } else {
-                               return false;
-                       }
-               }
+       /**
+        * Retrieve value from device storage.
+        *
+        * @param {string} key Key of item to retrieve
+        * @return {string|boolean} False when localStorage not available, otherwise string
+        */
+       SafeStorage.prototype.get = function ( key ) {
+               try {
+                       return this.store.getItem( key );
+               } catch ( e ) {}
+               return false;
        };
 
-       mw.storage = storage;
-       // See if local storage is supported
-       try {
-               localStorage.setItem( 'localStorageTest', 'localStorageTest' );
-               localStorage.removeItem( 'localStorageTest' );
-               storage.isLocalStorageSupported = true;
-       } catch ( e ) {
-               // Already set. No body needed.
-       }
+       /**
+         * Set a value in device storage.
+         *
+         * @param {string} key Key name to store under
+         * @param {string} value Value to be stored
+         * @return {boolean} Whether the save succeeded or not
+         */
+       SafeStorage.prototype.set = function ( key, value ) {
+               try {
+                       this.store.setItem( key, value );
+                       return true;
+               } catch ( e ) {}
+               return false;
+       };
+
+       /**
+         * Remove a value from device storage.
+         *
+         * @param {string} key Key of item to remove
+         * @return {boolean} Whether the save succeeded or not
+         */
+       SafeStorage.prototype.remove = function ( key ) {
+               try {
+                       this.store.removeItem( key );
+                       return true;
+               } catch ( e ) {}
+               return false;
+       };
+
+       /**
+        * @class
+        * @singleton
+        * @extends mw.SafeStorage
+        */
+       mw.storage = new SafeStorage( localStorage );
+
+       /**
+        * @class
+        * @singleton
+        * @extends mw.SafeStorage
+        */
+       mw.storage.session = new SafeStorage( sessionStorage );
 
 }( mediaWiki ) );