diff --git a/eustia/safeStorage.js b/eustia/safeStorage.js
new file mode 100644
index 0000000..ac7b31f
--- /dev/null
+++ b/eustia/safeStorage.js
@@ -0,0 +1,30 @@
+_('isUndef memStorage');
+
+function exports(type, memReplacement)
+{
+ if (isUndef(memReplacement)) memReplacement = true;
+
+ var ret;
+
+ switch (type)
+ {
+ case 'local': ret = window.localStorage; break;
+ case 'session': ret = window.sessionStorage; break;
+ }
+
+ try
+ {
+ // Safari private browsing
+ var x = 'test-localStorage-' + Date.now();
+ ret.setItem(x, x);
+ var y = ret.getItem(x);
+ ret.removeItem(x);
+ if (y !== x) throw new Error();
+ } catch (e)
+ {
+ if (memReplacement) return memStorage;
+ return;
+ }
+
+ return ret;
+}
\ No newline at end of file
diff --git a/src/DevTools/DevTools.es6 b/src/DevTools/DevTools.es6
index d96c97c..ceffc26 100644
--- a/src/DevTools/DevTools.es6
+++ b/src/DevTools/DevTools.es6
@@ -152,5 +152,7 @@ export default class DevTools extends util.Emitter
}
}
-var activeEruda = flag => window.localStorage.setItem('active-eruda', flag);
+var localStore = util.safeStorage('local');
+
+var activeEruda = flag => localStore.setItem('active-eruda', flag);
diff --git a/src/Info/Info.hbs b/src/Info/Info.hbs
index dfd01fd..6a64c23 100644
--- a/src/Info/Info.hbs
+++ b/src/Info/Info.hbs
@@ -2,7 +2,7 @@
{{#each messages}}
{{name}}
- {{val}}
+ {{{val}}}
{{/each}}
-
\ No newline at end of file
+
diff --git a/src/Resources/Resources.es6 b/src/Resources/Resources.es6
index 8ffc039..d4147cc 100644
--- a/src/Resources/Resources.es6
+++ b/src/Resources/Resources.es6
@@ -87,14 +87,21 @@ export default class Resources extends Tool
}
_refreshStorage(type)
{
+ var store = util.safeStorage(type, false);
+
+ if (!store) return;
+
var storeData = [];
// Mobile safari is not able to loop through localStorage directly.
- var store = JSON.parse(JSON.stringify(window[type + 'Storage']));
+ store = JSON.parse(JSON.stringify(store));
util.each(store, (val, key) =>
{
- if (this._hideErudaSetting && util.startWith(key, 'eruda')) return;
+ if (this._hideErudaSetting)
+ {
+ if (util.startWith(key, 'eruda') || key === 'active-eruda') return;
+ }
storeData.push({
key: key,
diff --git a/src/Sources/Sources.scss b/src/Sources/Sources.scss
index 2f8268c..de7528f 100644
--- a/src/Sources/Sources.scss
+++ b/src/Sources/Sources.scss
@@ -64,6 +64,7 @@
padding: $padding;
font-size: $font-size-s;
margin-bottom: 10px;
+ white-space: pre-wrap;
}
}
iframe {
diff --git a/src/lib/Storage.es6 b/src/lib/Storage.es6
index da5a16d..e2d457f 100644
--- a/src/lib/Storage.es6
+++ b/src/lib/Storage.es6
@@ -1,7 +1,7 @@
import util from './util';
var localStore = {
- _storage: window.localStorage,
+ _storage: util.safeStorage('local'),
get(key)
{
var val = this._storage.getItem(key);
diff --git a/src/lib/util.js b/src/lib/util.js
index b3e94d2..4f89741 100644
--- a/src/lib/util.js
+++ b/src/lib/util.js
@@ -389,7 +389,7 @@ module.exports = (function ()
var idxOf = _.idxOf = (function ()
{
- /* Get the index at which the first occurrence of value. TODO
+ /* Get the index at which the first occurrence of value.
*
* |Name |Type |Desc |
* |-----------|------|--------------------|
@@ -404,7 +404,7 @@ module.exports = (function ()
function exports(arr, val, fromIdx)
{
- return Array.prototype.indexOf.call(arr, val);
+ return Array.prototype.indexOf.call(arr, val, fromIdx);
}
return exports;
@@ -1577,6 +1577,92 @@ module.exports = (function ()
return exports;
})();
+ /* ------------------------------ memStorage ------------------------------ */
+
+ var memStorage = _.memStorage = (function (exports)
+ {
+ /* Memory-backed implementation of the Web Storage API.
+ *
+ * A replacement for environments where localStorage or sessionStorage is not available.
+ *
+ * ```javascript
+ * var localStorage = window.localStorage || memStorage;
+ * localStorage.setItem('test', 'eris');
+ * ```
+ */
+
+ exports = {
+ getItem: function (key)
+ {
+ return (API_KEYS[key] ? cloak[key] : this[key]) || null;
+ },
+ setItem: function (key, val)
+ {
+ API_KEYS[key] ? cloak[key] = val : this[key] = val;
+ },
+ removeItem: function (key)
+ {
+ API_KEYS[key] ? delete cloak[key] : delete this[key];
+ },
+ key: function (i)
+ {
+ var keys = enumerableKeys();
+
+ return i >= 0 && i < keys.length ? keys[i] : null;
+ },
+ clear: function ()
+ {
+ var keys = uncloakedKeys();
+
+ for (var i = 0, key; key = keys[i]; i++) delete this[key];
+
+ keys = cloakedKeys();
+
+ for (i = 0; key = keys[i]; i++) delete cloak[key];
+ }
+ };
+
+ Object.defineProperty(exports, 'length', {
+ enumerable: false,
+ configurable: true,
+ get: function ()
+ {
+ return enumerableKeys().length;
+ }
+ });
+
+ var cloak = {};
+
+ var API_KEYS = {
+ getItem: 1,
+ setItem: 1,
+ removeItem: 1,
+ key: 1,
+ clear: 1,
+ length: 1
+ };
+
+ function enumerableKeys()
+ {
+ return uncloakedKeys().concat(cloakedKeys());
+ }
+
+ function uncloakedKeys()
+ {
+ return keys(exports).filter(function (key)
+ {
+ return !API_KEYS[key];
+ });
+ }
+
+ function cloakedKeys()
+ {
+ return keys(cloak);
+ }
+
+ return exports;
+ })({});
+
/* ------------------------------ noop ------------------------------ */
var noop = _.noop = (function ()
@@ -1616,32 +1702,32 @@ module.exports = (function ()
var optimizeCb = _.optimizeCb = (function ()
{
- /* TODO
+ /* Used for function context binding.
*/
- function exports(func, ctx, argCount)
+ function exports(fn, ctx, argCount)
{
- if (isUndef(ctx)) return func;
+ if (isUndef(ctx)) return fn;
switch (argCount == null ? 3 : argCount)
{
case 1: return function (val)
{
- return func.call(ctx, val);
+ return fn.call(ctx, val);
};
case 3: return function (val, idx, collection)
{
- return func.call(ctx, val, idx, collection);
+ return fn.call(ctx, val, idx, collection);
};
case 4: return function (accumulator, val, idx, collection)
{
- return func.call(ctx, accumulator, val, idx, collection);
+ return fn.call(ctx, accumulator, val, idx, collection);
}
}
return function ()
{
- return func.apply(ctx, arguments);
+ return fn.apply(ctx, arguments);
};
}
@@ -1652,7 +1738,7 @@ module.exports = (function ()
var safeCb = _.safeCb = (function (exports)
{
- /* Create callback based on input value. TODO
+ /* Create callback based on input value.
*/
exports = function (val, ctx, argCount)
@@ -2473,7 +2559,32 @@ module.exports = (function ()
var delegate = _.delegate = (function (exports)
{
- /* TODO
+ /* Event delegation.
+ *
+ * ### add
+ *
+ * Add event delegation.
+ *
+ * |Name |Type |Desc |
+ * |--------|--------|--------------|
+ * |el |element |Parent element|
+ * |type |string |Event type |
+ * |selector|string |Match selector|
+ * |cb |function|Event callback|
+ *
+ * ### remove
+ *
+ * Remove event delegation.
+ *
+ * ```javascript
+ * var container = document.getElementById('container');
+ * function clickHandler()
+ * {
+ * // Do something...
+ * }
+ * delegate.add(container, 'click', '.children', clickHandler);
+ * delegate.remove(container, 'click', '.children', clickHandler);
+ * ```
*/
function retTrue() { return true }
@@ -2629,13 +2740,15 @@ module.exports = (function ()
var $event = _.$event = (function (exports)
{
- /* bind events to certain dom elements. TODO
+ /* bind events to certain dom elements.
*
* ```javascript
- * $event.on('#test', 'click', function ()
+ * function clickHandler()
* {
- * // ...
- * });
+ * // Do something...
+ * }
+ * $event.on('#test', 'click', clickHandler);
+ * $event.off('#test', 'click', clickHandler);
* ```
*/
@@ -3383,6 +3496,42 @@ module.exports = (function ()
return exports;
})();
+ /* ------------------------------ safeStorage ------------------------------ */
+
+ var safeStorage = _.safeStorage = (function ()
+ {
+ function exports(type, memReplacement)
+ {
+ if (isUndef(memReplacement)) memReplacement = true;
+
+ var ret;
+
+ switch (type)
+ {
+ case 'local': ret = window.localStorage; break;
+ case 'session': ret = window.sessionStorage; break;
+ }
+
+ try
+ {
+ // Safari private browsing
+ var x = 'test-localStorage-' + Date.now();
+ ret.setItem(x, x);
+ var y = ret.getItem(x);
+ ret.removeItem(x);
+ if (y !== x) throw new Error();
+ } catch (e)
+ {
+ if (memReplacement) return memStorage;
+ return;
+ }
+
+ return ret;
+ }
+
+ return exports;
+ })();
+
/* ------------------------------ stripHtmlTag ------------------------------ */
var stripHtmlTag = _.stripHtmlTag = (function ()
@@ -3547,7 +3696,7 @@ module.exports = (function ()
* |return|string|Converted string |
*
* ```javascript
- * upperFirst('red'); // -> RED
+ * upperFirst('red'); // -> Red
* ```
*/