diff --git a/addons/web/static/src/js/core/abstract_storage_service.js b/addons/web/static/src/js/core/abstract_storage_service.js
new file mode 100644
index 00000000000..6a96036f5f5
--- /dev/null
+++ b/addons/web/static/src/js/core/abstract_storage_service.js
@@ -0,0 +1,56 @@
+odoo.define('web.AbstractStorageService', function (require) {
+'use strict';
+
+/**
+ * This module defines an abstraction for services that write into Storage
+ * objects (e.g. localStorage or sessionStorage).
+ */
+
+var AbstractService = require('web.AbstractService');
+
+var AbstractStorageService = AbstractService.extend({
+ // the 'storage' attribute must be set by actual StorageServices extending
+ // this abstraction
+ storage: null,
+
+ //--------------------------------------------------------------------------
+ // Public
+ //--------------------------------------------------------------------------
+
+ /**
+ * Removes all data from the storage
+ */
+ clear: function() {
+ this.storage.clear();
+ },
+ /**
+ * Returns the value associated with a given key in the storage
+ *
+ * @param {string} key
+ * @returns {string}
+ */
+ getItem: function(key) {
+ return this.storage.getItem(key);
+ },
+ /**
+ * Removes the given key from the storage
+ *
+ * @param {string} key
+ */
+ removeItem: function(key) {
+ this.storage.removeItem(key);
+ },
+ /**
+ * Sets the value of a given key in the storage
+ *
+ * @param {string} key
+ * @param {string} value
+ */
+ setItem: function(key, value) {
+ this.storage.setItem(key,value);
+ },
+});
+
+return AbstractStorageService;
+
+});
diff --git a/addons/web/static/src/js/core/local_storage.js b/addons/web/static/src/js/core/local_storage.js
index 6cf82e87752..da8e6714cb3 100644
--- a/addons/web/static/src/js/core/local_storage.js
+++ b/addons/web/static/src/js/core/local_storage.js
@@ -1,31 +1,16 @@
odoo.define('web.local_storage', function (require) {
'use strict';
-var Class = require('web.Class');
+var RamStorage = require('web.RamStorage');
-// Compatibility with private browsing in Safari
-// Use dict in case of local storage is disabled
+// use a fake localStorage in RAM if the native localStorage is unavailable
+// (e.g. private browsing in Safari)
var localStorage = window.localStorage;
try {
var uid = new Date();
localStorage.setItem(uid, uid);
localStorage.removeItem(uid);
} catch (exception) {
- var storage = {};
- var RamStorage = Class.extend({
- setItem: function(key, value) {
- storage[key] = value;
- },
- getItem: function(key) {
- return storage[key];
- },
- removeItem: function(key) {
- delete storage[key];
- },
- clear: function() {
- storage = {};
- },
- });
localStorage = new RamStorage();
}
diff --git a/addons/web/static/src/js/core/ram_storage.js b/addons/web/static/src/js/core/ram_storage.js
new file mode 100644
index 00000000000..cea66a10dfa
--- /dev/null
+++ b/addons/web/static/src/js/core/ram_storage.js
@@ -0,0 +1,61 @@
+odoo.define('web.RamStorage', function (require) {
+'use strict';
+
+/**
+ * This module defines an alternative of the Storage objects (localStorage,
+ * sessionStorage), stored in RAM. It is used when those native Storage objects
+ * are unavailable (e.g. in private browsing on Safari).
+ */
+
+var Class = require('web.Class');
+
+var RamStorage = Class.extend({
+ /**
+ * @constructor
+ */
+ init: function () {
+ this.storage = Object.create(null);
+ },
+
+ //--------------------------------------------------------------------------
+ // Public
+ //--------------------------------------------------------------------------
+
+ /**
+ * Removes all data from the storage
+ */
+ clear: function () {
+ this.init();
+ },
+ /**
+ * Returns the value associated with a given key in the storage
+ *
+ * @param {string} key
+ * @returns {string}
+ */
+ getItem: function (key) {
+ return this.storage[key];
+ },
+ /**
+ * Removes the given key from the storage
+ *
+ * @param {string} key
+ */
+ removeItem: function (key) {
+ delete this.storage[key];
+ },
+ /**
+ * Adds a given key-value pair to the storage, or update the value of the
+ * given key if it already exists
+ *
+ * @param {string} key
+ * @param {string} value
+ */
+ setItem: function (key, value) {
+ this.storage[key] = value;
+ },
+});
+
+return RamStorage;
+
+});
diff --git a/addons/web/static/src/js/core/session_storage.js b/addons/web/static/src/js/core/session_storage.js
new file mode 100644
index 00000000000..f648cee084a
--- /dev/null
+++ b/addons/web/static/src/js/core/session_storage.js
@@ -0,0 +1,19 @@
+odoo.define('web.sessionStorage', function (require) {
+'use strict';
+
+var RamStorage = require('web.RamStorage');
+
+// use a fake sessionStorage in RAM if the native sessionStorage is unavailable
+// (e.g. private browsing in Safari)
+var sessionStorage = window.sessionStorage;
+try {
+ var uid = new Date();
+ sessionStorage.setItem(uid, uid);
+ sessionStorage.removeItem(uid);
+} catch (exception) {
+ sessionStorage = new RamStorage();
+}
+
+return sessionStorage;
+
+});
diff --git a/addons/web/static/src/js/services/local_storage_service.js b/addons/web/static/src/js/services/local_storage_service.js
index 7a8c803a0f9..016ed08f2b7 100644
--- a/addons/web/static/src/js/services/local_storage_service.js
+++ b/addons/web/static/src/js/services/local_storage_service.js
@@ -1,24 +1,17 @@
odoo.define('web.LocalStorageService', function (require) {
'use strict';
-var AbstractService = require('web.AbstractService');
+/**
+ * This module defines a service to access the localStorage object.
+ */
+
+var AbstractStorageService = require('web.AbstractStorageService');
var core = require('web.core');
var localStorage = require('web.local_storage');
-var LocalStorageService = AbstractService.extend({
+var LocalStorageService = AbstractStorageService.extend({
name: 'local_storage',
- setItem: function(key, value) {
- localStorage.setItem(key,value);
- },
- getItem: function(key) {
- return localStorage.getItem(key);
- },
- removeItem: function(key) {
- localStorage.removeItem(key);
- },
- clear: function() {
- localStorage.clear();
- }
+ storage: localStorage,
});
core.serviceRegistry.add('local_storage', LocalStorageService);
diff --git a/addons/web/static/src/js/services/session_storage_service.js b/addons/web/static/src/js/services/session_storage_service.js
new file mode 100644
index 00000000000..b9441f2e173
--- /dev/null
+++ b/addons/web/static/src/js/services/session_storage_service.js
@@ -0,0 +1,21 @@
+odoo.define('web.SessionStorageService', function (require) {
+'use strict';
+
+/**
+ * This module defines a service to access the sessionStorage object.
+ */
+
+var AbstractStorageService = require('web.AbstractStorageService');
+var core = require('web.core');
+var sessionStorage = require('web.sessionStorage');
+
+var SessionStorageService = AbstractStorageService.extend({
+ name: 'session_storage',
+ storage: sessionStorage,
+});
+
+core.serviceRegistry.add('session_storage', SessionStorageService);
+
+return SessionStorageService;
+
+});
diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml
index 03b0b17542c..8400288fee2 100644
--- a/addons/web/views/webclient_templates.xml
+++ b/addons/web/views/webclient_templates.xml
@@ -69,6 +69,7 @@
+
@@ -90,6 +91,9 @@
+
+
+