Skip to content
Snippets Groups Projects
Commit 214e2aa3 authored by Benoit Lavenier's avatar Benoit Lavenier
Browse files

- use xdLocalStorage for cross-domain storage

parent d2aa5aa8
No related branches found
No related tags found
No related merge requests found
......@@ -43,6 +43,8 @@
<script src="lib/ionic/js/angular/angular-bind-notifier.min.js"></script>
<script src="lib/ionic/js/angular/angular-image-crop.js"></script>
<script src="lib/ionic/js/angular/angular-file-saver.bundle.js"></script>
<script src="lib/ionic/js/angular/angular-xdLocalStorage.min.js"></script>
<script src="js/vendor/base58.js" async></script>
<!--removeIf(android)-->
<!--removeIf(ios)-->
......@@ -158,6 +160,6 @@
<!-- endbuild -->
</head>
<body ng-app="cesium" id="cesium" ng-strict-di ng-class="{'nobackdrop': $root.tour}">
<ion-nav-view></ion-nav-view>
<ion-nav-view></ion-nav-view>
</body>
</html>
......@@ -4,7 +4,7 @@
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
// 'starter.controllers' is found in controllers.js
angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht.translate',
angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht.translate', 'xdLocalStorage',
'ngApi', 'angular-cache', 'angular.screenmatch', 'angular.bind.notifier','ImageCropper', 'ngFileSaver',
// removeIf(no-device)
'ngCordova',
......@@ -302,7 +302,7 @@ angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht
$ionicConfigProvider.views.maxCache(5);
})
.run(function($rootScope, $translate, $state, $window, Device, UIUtils, $ionicConfig, PluginService, csWallet, csSettings, csConfig) {
.run(function($rootScope, $translate, $state, $window, xdLocalStorage, Device, UIUtils, $ionicConfig, PluginService, csWallet, csSettings, csConfig) {
'ngInject';
$rootScope.config = csConfig;
......@@ -377,6 +377,20 @@ angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht
});
}
if (csConfig.httpsMode === 'clever' && $window.location.protocol !== 'https:') {
var href = $window.location.href;
var hashIndex = href.indexOf('#');
var rootPath = (hashIndex != -1) ? href.substr(0, hashIndex) : href;
var httpsFrame = (csConfig.httpsModeDebug ? 'http' : 'https') + rootPath.substr(4) + 'sync-storage.html';
xdLocalStorage.init({iframeUrl: httpsFrame})
.then(function () {
//an option function to be called once the iframe was loaded and ready for action
console.debug('[app] Cross-domain local storage started');
csSettings.start();
});
}
// We use 'Device.ready()' instead of '$ionicPlatform.ready()', because this one is callable many times
Device.ready()
.then(function() {
......
......@@ -4,277 +4,270 @@ angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.confi
.factory('csSettings', function($rootScope, $q, Api, localStorage, $translate, csConfig, Device) {
'ngInject';
function CsSettings() {
// Define app locales
var locales = [
{id:'en', label:'English'},
{id:'en-GB', label:'English (UK)'},
{id:'fr-FR', label:'Français'},
{id:'nl-NL', label:'Nederlands'}
];
var fallbackLocale = csConfig.fallbackLanguage ? fixLocale(csConfig.fallbackLanguage) : 'en';
// Convert browser locale to app locale (fix #140)
function fixLocale (locale) {
if (!locale) return fallbackLocale;
// exists in app locales: use it
if (_.findWhere(locales, {id: locale})) return locale;
// not exists: reiterate with the root(e.g. 'fr-XX' -> 'fr')
var localeParts = locale.split('-');
if (localeParts.length > 1) {
return fixLocale(localeParts[0]);
}
// If another locale exists with the same root: use it
var similarLocale = _.find(locales, function(l) {
return String.prototype.startsWith.call(l.id, locale);
});
if (similarLocale) return similarLocale.id;
// Define app locales
var locales = [
{id:'en', label:'English'},
{id:'en-GB', label:'English (UK)'},
{id:'fr-FR', label:'Français'},
{id:'nl-NL', label:'Nederlands'}
];
var fallbackLocale = csConfig.fallbackLanguage ? fixLocale(csConfig.fallbackLanguage) : 'en';
// Convert browser locale to app locale (fix #140)
function fixLocale (locale) {
if (!locale) return fallbackLocale;
// exists in app locales: use it
if (_.findWhere(locales, {id: locale})) return locale;
// not exists: reiterate with the root(e.g. 'fr-XX' -> 'fr')
var localeParts = locale.split('-');
if (localeParts.length > 1) {
return fixLocale(localeParts[0]);
}
// If another locale exists with the same root: use it
var similarLocale = _.find(locales, function(l) {
return String.prototype.startsWith.call(l.id, locale);
});
if (similarLocale) return similarLocale.id;
return fallbackLocale;
}
return fallbackLocale;
}
// Convert browser locale to app locale (fix #140)
function fixLocaleWithLog (locale) {
var fixedLocale = fixLocale(locale);
if (locale != fixedLocale) {
console.debug('[settings] Fix locale [{0}] -> [{1}]'.format(locale, fixedLocale));
}
return fixedLocale;
}
// Convert browser locale to app locale (fix #140)
function fixLocaleWithLog (locale) {
var fixedLocale = fixLocale(locale);
if (locale != fixedLocale) {
console.debug('[settings] Fix locale [{0}] -> [{1}]'.format(locale, fixedLocale));
}
return fixedLocale;
}
var
constants = {
STORAGE_KEY: 'CESIUM_SETTINGS'
},
defaultSettings = angular.merge({
timeout : 4000,
cacheTimeMs: 60000, /*1 min*/
useRelative: false,
timeWarningExpireMembership: 2592000 * 2 /*=2 mois*/,
timeWarningExpire: 2592000 * 3 /*=3 mois*/,
useLocalStorage: Device.enable, // on mobile device, use local storage by default
walletHistoryTimeSecond: 30 * 24 * 60 * 60 /*30 days*/,
walletHistorySliceSecond: 5 * 24 * 60 * 60 /*download using 5 days slice*/,
rememberMe: Device.enable, // on mobile device, remember me by default
showUDHistory: true,
showLoginSalt: false,
initPhase: false, // For currency start (when block #0 not written)
httpsMode: false,
expertMode: false,
decimalCount: 4,
forceNetworkViewToHttp: false,
uiEffects: true,
minVersion: csConfig.compatProtocol_0_80 ? '0.80.0' : '0.90.0', // TODO update this if need
newIssueUrl: "https://github.com/duniter/cesium/issues/new?labels=bug",
helptip: {
enable: true,
installDocUrl: "https://github.com/duniter/duniter/blob/master/doc/install-a-node.md",
currency: 0,
wot: 0,
wotCerts: 0,
wallet: 0,
walletCerts: 0,
header: 0,
settings: 0
},
wallet: {
showPubkey: true,
alertIfUnusedWallet: true,
notificationReadTime: 0
},
locale: {
id: fixLocaleWithLog(csConfig.defaultLanguage || $translate.use()) // use config locale if set, or browser default
}
}, csConfig),
var
constants = {
STORAGE_KEY: 'CESIUM_SETTINGS'
},
defaultSettings = angular.merge({
timeout : 4000,
cacheTimeMs: 60000, /*1 min*/
useRelative: false,
timeWarningExpireMembership: 2592000 * 2 /*=2 mois*/,
timeWarningExpire: 2592000 * 3 /*=3 mois*/,
useLocalStorage: Device.enable, // on mobile device, use local storage by default
walletHistoryTimeSecond: 30 * 24 * 60 * 60 /*30 days*/,
walletHistorySliceSecond: 5 * 24 * 60 * 60 /*download using 5 days slice*/,
rememberMe: Device.enable, // on mobile device, remember me by default
showUDHistory: true,
showLoginSalt: false,
initPhase: false, // For currency start (when block #0 not written)
httpsMode: false,
expertMode: false,
decimalCount: 4,
forceNetworkViewToHttp: false,
uiEffects: true,
minVersion: csConfig.compatProtocol_0_80 ? '0.80.0' : '0.90.0', // TODO update this if need
newIssueUrl: "https://github.com/duniter/cesium/issues/new?labels=bug",
helptip: {
enable: true,
installDocUrl: "https://github.com/duniter/duniter/blob/master/doc/install-a-node.md",
currency: 0,
wot: 0,
wotCerts: 0,
wallet: 0,
walletCerts: 0,
header: 0,
settings: 0
},
wallet: {
showPubkey: true,
alertIfUnusedWallet: true,
notificationReadTime: 0
},
locale: {
id: fixLocaleWithLog(csConfig.defaultLanguage || $translate.use()) // use config locale if set, or browser default
}
}, csConfig),
data = {},
previousData,
api = new Api(this, "csSettings"),
reset = function() {
_.keys(data).forEach(function(key){
delete data[key];
});
data = {},
previousData,
applyData(defaultSettings);
api = new Api(this, "csSettings"),
return api.data.raisePromise.reset(data)
.then(store);
},
getByPath = function(path, defaultValue) {
var obj = data;
_.each(path.split('.'), function(key) {
obj = obj[key];
if (angular.isUndefined(obj)) {
obj = defaultValue;
return; // stop
}
});
reset = function() {
_.keys(data).forEach(function(key){
delete data[key];
});
return obj;
},
emitChangedEvent = function() {
var hasChanged = previousData && !angular.equals(previousData, data);
previousData = angular.copy(data);
if (hasChanged) {
api.data.raise.changed(data);
}
},
store = function() {
if (data.useLocalStorage) {
localStorage.setObject(constants.STORAGE_KEY, data);
}
else {
localStorage.setObject(constants.STORAGE_KEY, null);
}
// Emit event on store
return api.data.raisePromise.store(data)
.then(emitChangedEvent);
},
applyData = function(newData) {
var localeChanged = false;
if (newData.locale && newData.locale.id) {
// Fix previously stored locale (could use bad format)
newData.locale.id = fixLocale(newData.locale.id);
localeChanged = !data.locale || newData.locale.id !== data.locale.id || newData.locale.id !== $translate.use();
}
// Apply stored settings
angular.merge(data, newData);
// Always force the usage of deffault settings
// This is a workaround for DEV (TODO: implement edition in settings ?)
data.timeWarningExpire = defaultSettings.timeWarningExpire;
data.timeWarningExpireMembership = defaultSettings.timeWarningExpireMembership;
data.cacheTimeMs = defaultSettings.cacheTimeMs;
data.timeout = defaultSettings.timeout;
// Apply the new locale (only if need)
if (localeChanged) {
$translate.use(fixLocale(data.locale.id)); // will produce an event cached by onLocaleChange();
}
},
restore = function() {
var now = new Date().getTime();
return $q(function(resolve, reject){
console.debug("[settings] Loading from local storage...");
var storedData = localStorage.getObject(constants.STORAGE_KEY);
var finishRestore = function() {
emitChangedEvent();
resolve();
};
// No settings stored
if (!storedData) {
console.debug("[settings] No settings in local storage. Using defaults.");
applyData(defaultSettings);
finishRestore();
return;
}
return api.data.raisePromise.reset(data)
.then(store);
},
getByPath = function(path, defaultValue) {
var obj = data;
_.each(path.split('.'), function(key) {
obj = obj[key];
if (angular.isUndefined(obj)) {
obj = defaultValue;
return; // stop
}
});
return obj;
},
emitChangedEvent = function() {
var hasChanged = previousData && !angular.equals(previousData, data);
previousData = angular.copy(data);
if (hasChanged) {
api.data.raise.changed(data);
}
},
store = function() {
if (data.useLocalStorage) {
localStorage.setObject(constants.STORAGE_KEY, data);
}
else {
localStorage.setObject(constants.STORAGE_KEY, null);
}
// Emit event on store
return api.data.raisePromise.store(data)
.then(emitChangedEvent);
},
applyData = function(newData) {
var localeChanged = false;
if (newData.locale && newData.locale.id) {
// Fix previously stored locale (could use bad format)
newData.locale.id = fixLocale(newData.locale.id);
localeChanged = !data.locale || newData.locale.id !== data.locale.id || newData.locale.id !== $translate.use();
}
// Apply stored settings
angular.merge(data, newData);
// Always force the usage of deffault settings
// This is a workaround for DEV (TODO: implement edition in settings ?)
data.timeWarningExpire = defaultSettings.timeWarningExpire;
data.timeWarningExpireMembership = defaultSettings.timeWarningExpireMembership;
data.cacheTimeMs = defaultSettings.cacheTimeMs;
data.timeout = defaultSettings.timeout;
// Apply the new locale (only if need)
if (localeChanged) {
$translate.use(fixLocale(data.locale.id)); // will produce an event cached by onLocaleChange();
}
},
restore = function() {
var now = new Date().getTime();
return $q(function(resolve, reject){
console.debug("[settings] Loading from local storage...");
var storedData = localStorage.getObject(constants.STORAGE_KEY);
var finishRestore = function() {
emitChangedEvent();
resolve();
// Workaround to get node info from Cesium < 0.2.0
if (storedData.DUNITER_NODE) {
var nodePart = storedData.DUNITER_NODE.split(':');
if (nodePart.length == 1 || nodePart.length == 2) {
storedData.node = {
host: nodePart[0],
port: nodePart[1] // could be undefined, but that's fine
};
// No settings stored
if (!storedData) {
console.debug("[settings] No settings in local storage. Using defaults.");
applyData(defaultSettings);
finishRestore();
return;
}
// Workaround to get node info from Cesium < 0.2.0
if (storedData.DUNITER_NODE) {
var nodePart = storedData.DUNITER_NODE.split(':');
if (nodePart.length == 1 || nodePart.length == 2) {
storedData.node = {
host: nodePart[0],
port: nodePart[1] // could be undefined, but that's fine
};
}
delete storedData.DUNITER_NODE;
}
if (storedData.DUNITER_NODE_ES) {
var esNodePart = storedData.DUNITER_NODE_ES.split(':');
if (esNodePart.length == 1 || esNodePart.length == 2) {
storedData.plugins = {
es: {
enable: true,
host: esNodePart[0],
port: esNodePart[1] // could be undefined, but that's fine
}
};
}
delete storedData.DUNITER_NODE_ES;
}
// Apply stored data
applyData(storedData);
console.debug('[settings] Loaded from local storage in '+(new Date().getTime()-now)+'ms');
finishRestore();
});
},
// Detect locale sucessuf changes, then apply to vendor libs
onLocaleChange = function() {
var locale = $translate.use();
console.debug('[settings] Locale ['+locale+']');
// config moment lib
try {
moment.locale(locale.substr(0,2));
}
catch(err) {
moment.locale('en');
console.warn('[settings] Unknown local for moment lib. Using default [en]');
}
// config numeral lib
try {
numeral.language(locale.substr(0,2));
}
catch(err) {
numeral.language('en');
console.warn('[settings] Unknown local for numeral lib. Using default [en]');
delete storedData.DUNITER_NODE;
}
if (storedData.DUNITER_NODE_ES) {
var esNodePart = storedData.DUNITER_NODE_ES.split(':');
if (esNodePart.length == 1 || esNodePart.length == 2) {
storedData.plugins = {
es: {
enable: true,
host: esNodePart[0],
port: esNodePart[1] // could be undefined, but that's fine
}
};
}
delete storedData.DUNITER_NODE_ES;
}
// Emit event
api.locale.raise.changed(locale);
};
$rootScope.$on('$translateChangeSuccess', onLocaleChange);
api.registerEvent('data', 'reset');
api.registerEvent('data', 'changed');
api.registerEvent('data', 'store');
api.registerEvent('data', 'ready');
api.registerEvent('locale', 'changed');
// Apply default settings. This is required on some browser (web or mobile - see #361)
applyData(defaultSettings);
return {
data: data,
getByPath: getByPath,
reset: reset,
store: store,
restore: restore,
defaultSettings: defaultSettings,
// api extension
api: api,
locales: locales
};
}
var service = CsSettings();
// Apply stored data
applyData(storedData);
service.restore()
.then(function() {
service.api.data.raise.ready();
console.debug('[settings] Loaded from local storage in '+(new Date().getTime()-now)+'ms');
finishRestore();
});
return service;
},
// Detect locale sucessuf changes, then apply to vendor libs
onLocaleChange = function() {
var locale = $translate.use();
console.debug('[settings] Locale ['+locale+']');
// config moment lib
try {
moment.locale(locale.substr(0,2));
}
catch(err) {
moment.locale('en');
console.warn('[settings] Unknown local for moment lib. Using default [en]');
}
// config numeral lib
try {
numeral.language(locale.substr(0,2));
}
catch(err) {
numeral.language('en');
console.warn('[settings] Unknown local for numeral lib. Using default [en]');
}
// Emit event
api.locale.raise.changed(locale);
},
start = function() {
restore().then(api.data.raise.ready);
};
$rootScope.$on('$translateChangeSuccess', onLocaleChange);
api.registerEvent('data', 'reset');
api.registerEvent('data', 'changed');
api.registerEvent('data', 'store');
api.registerEvent('data', 'ready');
api.registerEvent('locale', 'changed');
// Apply default settings. This is required on some browser (web or mobile - see #361)
applyData(defaultSettings);
return {
start : start,
data: data,
getByPath: getByPath,
reset: reset,
store: store,
restore: restore,
defaultSettings: defaultSettings,
// api extension
api: api,
locales: locales
};
});
angular.module('cesium.storage.services', ['ngResource', 'cesium.device.services', 'cesium.config'])
angular.module('cesium.storage.services', ['ngResource', 'ngResource', 'xdLocalStorage',
'cesium.device.services', 'cesium.config'])
.factory('localStorage', function($window, $q, $rootScope, Device, csConfig) {
.factory('localStorage', function($window, $q, $rootScope, Device, csConfig, xdLocalStorage) {
'ngInject';
var
......@@ -9,16 +10,13 @@ angular.module('cesium.storage.services', ['ngResource', 'cesium.device.services
exports = {
useHttpsFrame: false,
unsecure: {},
https: {
frame: null,
domain: null
},
https: {},
secure: {
storage: null
}
};
/* -- default implementation (default browser storage) -- */
/* -- Use default default browser implementation -- */
exports.unsecure.put = function(key, value) {
localStorage[key] = value;
......@@ -37,14 +35,13 @@ angular.module('cesium.storage.services', ['ngResource', 'cesium.device.services
};
/* -- HTTPS frame -- */
/* -- Use of HTTPS frame -- */
exports.https.put = function(key, value) {
console.log('TODO: setting [{0}] into https frame'.format(key));
};
exports.https.get = function(key, defaultValue) {
exports.https.frame.postMessage(key, exports.https.domain);
console.log('TODO: getting [{0}] from https frame'.format(key));
return localStorage[key] || defaultValue;
};
......@@ -54,13 +51,12 @@ angular.module('cesium.storage.services', ['ngResource', 'cesium.device.services
};
exports.https.getObject = function(key) {
exports.https.frame.postMessage(key, exports.https.domain);
console.log('TODO: getting object [{0}] from https frame'.format(key));
return JSON.parse(localStorage[key] || '{}');
};
/* -- Secure storage (device only, using a cordova plugin) -- */
/* -- Use secure storage (using a cordova plugin) -- */
// Set a value to the secure storage (or remove if value is not defined)
exports.secure.put = function(key, value) {
......@@ -111,29 +107,15 @@ angular.module('cesium.storage.services', ['ngResource', 'cesium.device.services
});
};
// Create a HTTPS frame to get local storage from HTTPS domaine
// Copy HTTPS functions as default function
if (csConfig.httpsMode === 'clever' && $window.location.protocol !== 'https:') {
var href = $window.location.href;
var hashIndex = href.indexOf('#');
var rootPath = (hashIndex != -1) ? href.substr(0, hashIndex) : href;
var httpsFrame = (csConfig.httpsModeDebug ? 'http' : 'https') + rootPath.substr(4) + 'sync-storage.html';
console.debug('[storage] Adding HTTPS iframe [{0}]'.format(httpsFrame));
angular.element(document.body).append('<iframe name="httpsFrame" style="display:none" src="'+httpsFrame+'"></iframe>');
// Copy httpsFrame function as root exports function
_.forEach(_.keys(exports.https), function(key) {
exports[key] = exports.https[key];
});
exports.https.domain = 'https' + rootPath.substr(4);
exports.https.frame = frames['httpsFrame'];
}
else {
// Copy unsecure function as root exports function
// Copy unsecure function as default function
_.forEach(_.keys(exports.unsecure), function(key) {
exports[key] = exports.unsecure[key];
});
......@@ -162,8 +144,6 @@ angular.module('cesium.storage.services', ['ngResource', 'cesium.device.services
replaceSecureStorage();
}
});
return exports;
......
"use strict";window.XdUtils=window.XdUtils||function(){function a(a,b){var c,d=b||{};for(c in a)a.hasOwnProperty(c)&&(d[c]=a[c]);return d}return{extend:a}}(),window.xdLocalStorage=window.xdLocalStorage||function(){function a(a){j[a.id]&&(j[a.id](a),delete j[a.id])}function b(b){var c;try{c=JSON.parse(b.data)}catch(a){}c&&c.namespace===g&&("iframe-ready"===c.id?(l=!0,h.initCallback()):a(c))}function c(a,b,c,d){i++,j[i]=d;var e={namespace:g,id:i,action:a,key:b,value:c};f.contentWindow.postMessage(JSON.stringify(e),"*")}function d(a){h=XdUtils.extend(a,h);var c=document.createElement("div");window.addEventListener?window.addEventListener("message",b,!1):window.attachEvent("onmessage",b),c.innerHTML='<iframe id="'+h.iframeId+'" src='+h.iframeUrl+' style="display: none;"></iframe>',document.body.appendChild(c),f=document.getElementById(h.iframeId)}function e(){return k?!!l||(console.log("You must wait for iframe ready message before using the api."),!1):(console.log("You must call xdLocalStorage.init() before using it."),!1)}var f,g="cross-domain-local-message",h={iframeId:"cross-domain-iframe",iframeUrl:void 0,initCallback:function(){}},i=-1,j={},k=!1,l=!0;return{init:function(a){if(!a.iframeUrl)throw"You must specify iframeUrl";return k?void console.log("xdLocalStorage was already initialized!"):(k=!0,void("complete"===document.readyState?d(a):window.onload=function(){d(a)}))},setItem:function(a,b,d){e()&&c("set",a,b,d)},getItem:function(a,b){e()&&c("get",a,null,b)},removeItem:function(a,b){e()&&c("remove",a,null,b)},key:function(a,b){e()&&c("key",a,null,b)},getSize:function(a){e()&&c("size",null,null,a)},getLength:function(a){e()&&c("length",null,null,a)},clear:function(a){e()&&c("clear",null,null,a)},wasInit:function(){return k}}}(),angular.module("xdLocalStorage",[]).service("xdLocalStorage",["$q","$rootScope",function(a,b){function c(){if(!xdLocalStorage.wasInit())throw"You must init xdLocalStorage in app config before use";return f.promise}function d(d){var e=Array.prototype.slice.call(arguments,1);return c().then(function(){var c=a.defer();return xdLocalStorage[d].apply(this,e.concat(function(){var a=arguments[0];b.$apply(function(){c.resolve(a)})})),c.promise})}var e=!1,f=a.defer(),g=b.$watch(function(){return e},function(){f.resolve(!0),g()});return{init:function(c){var d=a.defer();return c.initCallback=function(){b.$apply(function(){e=!0,d.resolve()})},xdLocalStorage.init(c),d.promise},setItem:function(a,b){return d("setItem",a,b)},getItem:function(a){return d("getItem",a)},removeItem:function(a){return d("removeItem",a)},key:function(a){return d("key",a)},clear:function(){return d("clear")}}}]);
\ No newline at end of file
"use strict";window.XdUtils=window.XdUtils||function(){function a(a,b){var c,d=b||{};for(c in a)a.hasOwnProperty(c)&&(d[c]=a[c]);return d}return{extend:a}}(),function(){function a(a,b){var c=XdUtils.extend(b,l);c.id=a,parent.postMessage(JSON.stringify(c),"*")}function b(b,c){var d=localStorage.getItem(c),e={key:c,value:d};a(b,e)}function c(b,c,d){localStorage.setItem(c,d);var e=localStorage.getItem(c),f={success:e===d};a(b,f)}function d(b,c){localStorage.removeItem(c),a(b,{})}function e(b,c){var d=localStorage.key(c);a(b,{key:d})}function f(b){var c=JSON.stringify(localStorage).length;a(b,{size:c})}function g(b){var c=localStorage.length;a(b,{length:c})}function h(b){localStorage.clear(),a(b,{})}function i(a){var i;try{i=JSON.parse(a.data)}catch(a){}i&&i.namespace===k&&("set"===i.action?c(i.id,i.key,i.value):"get"===i.action?b(i.id,i.key):"remove"===i.action?d(i.id,i.key):"key"===i.action?e(i.id,i.key):"size"===i.action?f(i.id):"length"===i.action?g(i.id):"clear"===i.action&&h(i.id))}function j(){var a={namespace:k,id:"iframe-ready"};parent.postMessage(JSON.stringify(a),"*")}var k="cross-domain-local-message",l={namespace:k};window.addEventListener?window.addEventListener("message",i,!1):window.attachEvent("onmessage",i),j()}();
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="dist/dist_js/app/sync-storage.js"></script>
<script src="lib/ionic/js/angular/angular-xdLocalStoragePostMessageApi.min.js"></script>
</head>
<body >
<body>
This is the HTTPS Frame content
</body>
</html>
......@@ -173,6 +173,10 @@
<cs-extension-point name="menu-actions"></cs-extension-point>
</ion-list>
<iframe name="httpsFrame" style="display:none" ng-src="{{$root.detailFrame}}" >
</iframe>
</ion-content>
<!-- removeIf(device) -->
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment