From 261548ff184926567a623e90df7954aeef842d59 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Wed, 30 Jun 2021 12:28:05 +0200 Subject: emply an sh-based build system; make some changes to blocking --- common/browser.js | 24 +- common/connection_types.js | 18 +- common/gen_unique.js | 42 +-- common/lock.js | 68 ++--- common/once.js | 50 ++-- common/sha256.js | 673 +++++++++++++++++++++++---------------------- common/storage_client.js | 360 ++++++++++++------------ common/stored_types.js | 46 ++-- common/url_item.js | 22 +- 9 files changed, 656 insertions(+), 647 deletions(-) (limited to 'common') diff --git a/common/browser.js b/common/browser.js index 0ff3510..e50a121 100644 --- a/common/browser.js +++ b/common/browser.js @@ -5,21 +5,19 @@ * Redistribution terms are gathered in the `copyright' file. */ -"use strict"; - /* * This module normalizes access to WebExtension apis between * chrome-based and firefox-based browsers. */ -(() => { - if (typeof browser === "object") { - window.browser = browser; - window.is_chrome = false; - window.is_mozilla = true; - } else { - window.browser = window.chrome; - window.is_chrome = true; - window.is_mozilla = false; - } -})(); +const is_mozilla = typeof window.browser === "object"; +const is_chrome = !is_mozilla; +const browser = window[is_chrome ? "chrome" : "browser"]; + +/* + * EXPORTS_START + * EXPORT browser + * EXPORT is_chrome + * EXPORT is_mozilla + * EXPORTS_END + */ diff --git a/common/connection_types.js b/common/connection_types.js index cc3c976..e227532 100644 --- a/common/connection_types.js +++ b/common/connection_types.js @@ -5,18 +5,18 @@ * Redistribution terms are gathered in the `copyright' file. */ -"use strict"; - /* * Those need to be strings so they can be used as 'name' parameter * to browser.runtime.connect() */ -(() => { - const CONNECTION_TYPE = { - REMOTE_STORAGE : "0", - PAGE_ACTIONS : "1" - }; +const CONNECTION_TYPE = { + REMOTE_STORAGE : "0", + PAGE_ACTIONS : "1" +}; - window.CONNECTION_TYPE = CONNECTION_TYPE; -})(); +/* + * EXPORTS_START + * EXPORT CONNECTION_TYPE + * EXPORTS_END + */ diff --git a/common/gen_unique.js b/common/gen_unique.js index 4bcfd67..7ec8b4a 100644 --- a/common/gen_unique.js +++ b/common/gen_unique.js @@ -5,25 +5,29 @@ * Redistribution terms are gathered in the `copyright' file. */ -"use strict"; - -(() => { - const sha256 = window.sha256; - const browser = window.browser; - const is_chrome = window.is_chrome; +/* + * IMPORTS_START + * IMPORT sha256 + * IMPORT browser + * IMPORT is_chrome + * IMPORTS_END + */ - function get_id() - { - if (is_chrome) - return browser.runtime.getManifest().key.substring(0, 50); - else - return browser.runtime.getURL("dummy"); - } +function get_id() +{ + if (is_chrome) + return browser.runtime.getManifest().key.substring(0, 50); + else + return browser.runtime.getURL("dummy"); +} - function gen_unique(url) - { - return "#" + sha256(get_id() + url); - } +function gen_unique(url) +{ + return "#" + sha256(get_id() + url); +} - window.gen_unique = gen_unique; -})(); +/* + * EXPORTS_START + * EXPORT gen_unique + * EXPORTS_END + */ diff --git a/common/lock.js b/common/lock.js index 3358393..1130762 100644 --- a/common/lock.js +++ b/common/lock.js @@ -19,40 +19,40 @@ * in a promise. */ -"use strict"; - -(() => { - function make_lock() { - return {free: true, queue: []}; +function make_lock() { + return {free: true, queue: []}; +} + +function _lock(lock, cb) { + if (lock.free) { + lock.free = false; + setTimeout(cb); + } else { + lock.queue.push(cb); } - - function _lock(lock, cb) { - if (lock.free) { - lock.free = false; - setTimeout(cb); - } else { - lock.queue.push(cb); - } +} + +function lock(lock) { + return new Promise((resolve, reject) => _lock(lock, resolve)); +} + +function unlock(lock) { + if (lock.free) + throw new Exception("Attempting to release a free lock"); + + if (lock.queue.length === 0) { + lock.free = true; + } else { + let cb = lock.queue[0]; + lock.queue.splice(0, 1); + setTimeout(cb); } +} - function lock(lock) { - return new Promise((resolve, reject) => _lock(lock, resolve)); - } - - function unlock(lock) { - if (lock.free) - throw new Exception("Attempting to release a free lock"); - - if (lock.queue.length === 0) { - lock.free = true; - } else { - let cb = lock.queue[0]; - lock.queue.splice(0, 1); - setTimeout(cb); - } - } - - window.make_lock = make_lock; - window.lock = lock; - window.unlock = unlock; -})(); +/* + * EXPORTS_START + * EXPORT make_lock + * EXPORT lock + * EXPORT unlock + * EXPORTS_END + */ diff --git a/common/once.js b/common/once.js index d56b3c8..e3e6dbe 100644 --- a/common/once.js +++ b/common/once.js @@ -5,37 +5,37 @@ * Redistribution terms are gathered in the `copyright' file. */ -"use strict"; - /* * This module provides an easy way to wrap an async function into a promise * so that it only gets executed once. */ -(() => { - async function assign_result(state, result_producer) - { - state.result = await result_producer(); - state.ready = true; - for (let cb of state.waiting) - setTimeout(cb, 0, state.result); - state.waiting = undefined; - } +async function assign_result(state, result_producer) +{ + state.result = await result_producer(); + state.ready = true; + for (let cb of state.waiting) + setTimeout(cb, 0, state.result); + state.waiting = undefined; +} - async function get_result(state) - { - if (state.ready) - return state.result; +async function get_result(state) +{ + if (state.ready) + return state.result; - return new Promise((resolve, reject) => state.waiting.push(resolve)); - } + return new Promise((resolve, reject) => state.waiting.push(resolve)); +} - function make_once(result_producer) - { - let state = {waiting : [], ready : false, result : undefined}; - assign_result(state, result_producer); - return () => get_result(state); - } +function make_once(result_producer) +{ + let state = {waiting : [], ready : false, result : undefined}; + assign_result(state, result_producer); + return () => get_result(state); +} - window.make_once = make_once; -})(); +/* + * EXPORTS_START + * EXPORT make_once + * EXPORTS_END + */ diff --git a/common/sha256.js b/common/sha256.js index 271ec87..4fa07b5 100644 --- a/common/sha256.js +++ b/common/sha256.js @@ -7,32 +7,28 @@ * @license MIT */ -"use strict"; +var fake_window = {}; -(() => { - var fake_window = {}; - - console.log('hello, crypto!'); - var ERROR = 'input is invalid type'; - var WINDOW = typeof window === 'object'; - var root = /*WINDOW ? window : {}*/ fake_window; - if (root.JS_SHA256_NO_WINDOW) { +var ERROR = 'input is invalid type'; +var WINDOW = typeof fake_window === 'object'; +var root = /*WINDOW ? window : {}*/ fake_window; +if (root.JS_SHA256_NO_WINDOW) { WINDOW = false; - } - var WEB_WORKER = !WINDOW && typeof self === 'object'; - var NODE_JS = !root.JS_SHA256_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node; - if (NODE_JS) { +} +var WEB_WORKER = !WINDOW && typeof self === 'object'; +var NODE_JS = !root.JS_SHA256_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node; +if (NODE_JS) { root = global; - } else if (WEB_WORKER) { +} else if (WEB_WORKER) { root = self; - } - var COMMON_JS = !root.JS_SHA256_NO_COMMON_JS && typeof module === 'object' && module.exports; - var AMD = typeof define === 'function' && define.amd; - var ARRAY_BUFFER = !root.JS_SHA256_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined'; - var HEX_CHARS = '0123456789abcdef'.split(''); - var EXTRA = [-2147483648, 8388608, 32768, 128]; - var SHIFT = [24, 16, 8, 0]; - var K = [ +} +var COMMON_JS = !root.JS_SHA256_NO_COMMON_JS && typeof module === 'object' && module.exports; +var AMD = typeof define === 'function' && define.amd; +var ARRAY_BUFFER = !root.JS_SHA256_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined'; +var HEX_CHARS = '0123456789abcdef'.split(''); +var EXTRA = [-2147483648, 8388608, 32768, 128]; +var SHIFT = [24, 16, 8, 0]; +var K = [ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, @@ -41,209 +37,209 @@ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 - ]; - var OUTPUT_TYPES = ['hex', 'array', 'digest', 'arrayBuffer']; +]; +var OUTPUT_TYPES = ['hex', 'array', 'digest', 'arrayBuffer']; - var blocks = []; +var blocks = []; - if (root.JS_SHA256_NO_NODE_JS || !Array.isArray) { +if (root.JS_SHA256_NO_NODE_JS || !Array.isArray) { Array.isArray = function (obj) { - return Object.prototype.toString.call(obj) === '[object Array]'; + return Object.prototype.toString.call(obj) === '[object Array]'; }; - } +} - if (ARRAY_BUFFER && (root.JS_SHA256_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) { +if (ARRAY_BUFFER && (root.JS_SHA256_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) { ArrayBuffer.isView = function (obj) { - return typeof obj === 'object' && obj.buffer && obj.buffer.constructor === ArrayBuffer; + return typeof obj === 'object' && obj.buffer && obj.buffer.constructor === ArrayBuffer; }; - } +} - var createOutputMethod = function (outputType, is224) { +var createOutputMethod = function (outputType, is224) { return function (message) { - return new Sha256(is224, true).update(message)[outputType](); + return new Sha256(is224, true).update(message)[outputType](); }; - }; +}; - var createMethod = function (is224) { +var createMethod = function (is224) { var method = createOutputMethod('hex', is224); if (NODE_JS) { - method = nodeWrap(method, is224); + method = nodeWrap(method, is224); } method.create = function () { - return new Sha256(is224); + return new Sha256(is224); }; method.update = function (message) { - return method.create().update(message); + return method.create().update(message); }; for (var i = 0; i < OUTPUT_TYPES.length; ++i) { - var type = OUTPUT_TYPES[i]; - method[type] = createOutputMethod(type, is224); + var type = OUTPUT_TYPES[i]; + method[type] = createOutputMethod(type, is224); } return method; - }; +}; - var nodeWrap = function (method, is224) { +var nodeWrap = function (method, is224) { var crypto = eval("require('crypto')"); var Buffer = eval("require('buffer').Buffer"); var algorithm = is224 ? 'sha224' : 'sha256'; var nodeMethod = function (message) { - if (typeof message === 'string') { - return crypto.createHash(algorithm).update(message, 'utf8').digest('hex'); - } else { - if (message === null || message === undefined) { - throw new Error(ERROR); - } else if (message.constructor === ArrayBuffer) { - message = new Uint8Array(message); - } - } - if (Array.isArray(message) || ArrayBuffer.isView(message) || - message.constructor === Buffer) { - return crypto.createHash(algorithm).update(new Buffer(message)).digest('hex'); - } else { - return method(message); - } + if (typeof message === 'string') { + return crypto.createHash(algorithm).update(message, 'utf8').digest('hex'); + } else { + if (message === null || message === undefined) { + throw new Error(ERROR); + } else if (message.constructor === ArrayBuffer) { + message = new Uint8Array(message); + } + } + if (Array.isArray(message) || ArrayBuffer.isView(message) || + message.constructor === Buffer) { + return crypto.createHash(algorithm).update(new Buffer(message)).digest('hex'); + } else { + return method(message); + } }; return nodeMethod; - }; +}; - var createHmacOutputMethod = function (outputType, is224) { +var createHmacOutputMethod = function (outputType, is224) { return function (key, message) { - return new HmacSha256(key, is224, true).update(message)[outputType](); + return new HmacSha256(key, is224, true).update(message)[outputType](); }; - }; +}; - var createHmacMethod = function (is224) { +var createHmacMethod = function (is224) { var method = createHmacOutputMethod('hex', is224); method.create = function (key) { - return new HmacSha256(key, is224); + return new HmacSha256(key, is224); }; method.update = function (key, message) { - return method.create(key).update(message); + return method.create(key).update(message); }; for (var i = 0; i < OUTPUT_TYPES.length; ++i) { - var type = OUTPUT_TYPES[i]; - method[type] = createHmacOutputMethod(type, is224); + var type = OUTPUT_TYPES[i]; + method[type] = createHmacOutputMethod(type, is224); } return method; - }; +}; - function Sha256(is224, sharedMemory) { +function Sha256(is224, sharedMemory) { if (sharedMemory) { - blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] = - blocks[4] = blocks[5] = blocks[6] = blocks[7] = - blocks[8] = blocks[9] = blocks[10] = blocks[11] = - blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; - this.blocks = blocks; + blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] = + blocks[4] = blocks[5] = blocks[6] = blocks[7] = + blocks[8] = blocks[9] = blocks[10] = blocks[11] = + blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; + this.blocks = blocks; } else { - this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; } if (is224) { - this.h0 = 0xc1059ed8; - this.h1 = 0x367cd507; - this.h2 = 0x3070dd17; - this.h3 = 0xf70e5939; - this.h4 = 0xffc00b31; - this.h5 = 0x68581511; - this.h6 = 0x64f98fa7; - this.h7 = 0xbefa4fa4; + this.h0 = 0xc1059ed8; + this.h1 = 0x367cd507; + this.h2 = 0x3070dd17; + this.h3 = 0xf70e5939; + this.h4 = 0xffc00b31; + this.h5 = 0x68581511; + this.h6 = 0x64f98fa7; + this.h7 = 0xbefa4fa4; } else { // 256 - this.h0 = 0x6a09e667; - this.h1 = 0xbb67ae85; - this.h2 = 0x3c6ef372; - this.h3 = 0xa54ff53a; - this.h4 = 0x510e527f; - this.h5 = 0x9b05688c; - this.h6 = 0x1f83d9ab; - this.h7 = 0x5be0cd19; + this.h0 = 0x6a09e667; + this.h1 = 0xbb67ae85; + this.h2 = 0x3c6ef372; + this.h3 = 0xa54ff53a; + this.h4 = 0x510e527f; + this.h5 = 0x9b05688c; + this.h6 = 0x1f83d9ab; + this.h7 = 0x5be0cd19; } this.block = this.start = this.bytes = this.hBytes = 0; this.finalized = this.hashed = false; this.first = true; this.is224 = is224; - } +} - Sha256.prototype.update = function (message) { +Sha256.prototype.update = function (message) { if (this.finalized) { - return; + return; } var notString, type = typeof message; if (type !== 'string') { - if (type === 'object') { - if (message === null) { - throw new Error(ERROR); - } else if (ARRAY_BUFFER && message.constructor === ArrayBuffer) { - message = new Uint8Array(message); - } else if (!Array.isArray(message)) { - if (!ARRAY_BUFFER || !ArrayBuffer.isView(message)) { + if (type === 'object') { + if (message === null) { + throw new Error(ERROR); + } else if (ARRAY_BUFFER && message.constructor === ArrayBuffer) { + message = new Uint8Array(message); + } else if (!Array.isArray(message)) { + if (!ARRAY_BUFFER || !ArrayBuffer.isView(message)) { + throw new Error(ERROR); + } + } + } else { throw new Error(ERROR); - } - } - } else { - throw new Error(ERROR); - } - notString = true; + } + notString = true; } var code, index = 0, i, length = message.length, blocks = this.blocks; while (index < length) { - if (this.hashed) { - this.hashed = false; - blocks[0] = this.block; - blocks[16] = blocks[1] = blocks[2] = blocks[3] = - blocks[4] = blocks[5] = blocks[6] = blocks[7] = - blocks[8] = blocks[9] = blocks[10] = blocks[11] = - blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; - } - - if (notString) { - for (i = this.start; index < length && i < 64; ++index) { - blocks[i >> 2] |= message[index] << SHIFT[i++ & 3]; - } - } else { - for (i = this.start; index < length && i < 64; ++index) { - code = message.charCodeAt(index); - if (code < 0x80) { - blocks[i >> 2] |= code << SHIFT[i++ & 3]; - } else if (code < 0x800) { - blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } else if (code < 0xd800 || code >= 0xe000) { - blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } else { - code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff)); - blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; - blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; - } - } - } - - this.lastByteIndex = i; - this.bytes += i - this.start; - if (i >= 64) { - this.block = blocks[16]; - this.start = i - 64; - this.hash(); - this.hashed = true; - } else { - this.start = i; - } + if (this.hashed) { + this.hashed = false; + blocks[0] = this.block; + blocks[16] = blocks[1] = blocks[2] = blocks[3] = + blocks[4] = blocks[5] = blocks[6] = blocks[7] = + blocks[8] = blocks[9] = blocks[10] = blocks[11] = + blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; + } + + if (notString) { + for (i = this.start; index < length && i < 64; ++index) { + blocks[i >> 2] |= message[index] << SHIFT[i++ & 3]; + } + } else { + for (i = this.start; index < length && i < 64; ++index) { + code = message.charCodeAt(index); + if (code < 0x80) { + blocks[i >> 2] |= code << SHIFT[i++ & 3]; + } else if (code < 0x800) { + blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } else if (code < 0xd800 || code >= 0xe000) { + blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } else { + code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff)); + blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } + } + } + + this.lastByteIndex = i; + this.bytes += i - this.start; + if (i >= 64) { + this.block = blocks[16]; + this.start = i - 64; + this.hash(); + this.hashed = true; + } else { + this.start = i; + } } if (this.bytes > 4294967295) { - this.hBytes += this.bytes / 4294967296 << 0; - this.bytes = this.bytes % 4294967296; + this.hBytes += this.bytes / 4294967296 << 0; + this.bytes = this.bytes % 4294967296; } return this; - }; +}; - Sha256.prototype.finalize = function () { +Sha256.prototype.finalize = function () { if (this.finalized) { - return; + return; } this.finalized = true; var blocks = this.blocks, i = this.lastByteIndex; @@ -251,86 +247,86 @@ blocks[i >> 2] |= EXTRA[i & 3]; this.block = blocks[16]; if (i >= 56) { - if (!this.hashed) { - this.hash(); - } - blocks[0] = this.block; - blocks[16] = blocks[1] = blocks[2] = blocks[3] = - blocks[4] = blocks[5] = blocks[6] = blocks[7] = - blocks[8] = blocks[9] = blocks[10] = blocks[11] = - blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; + if (!this.hashed) { + this.hash(); + } + blocks[0] = this.block; + blocks[16] = blocks[1] = blocks[2] = blocks[3] = + blocks[4] = blocks[5] = blocks[6] = blocks[7] = + blocks[8] = blocks[9] = blocks[10] = blocks[11] = + blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0; } blocks[14] = this.hBytes << 3 | this.bytes >>> 29; blocks[15] = this.bytes << 3; this.hash(); - }; +}; - Sha256.prototype.hash = function () { +Sha256.prototype.hash = function () { var a = this.h0, b = this.h1, c = this.h2, d = this.h3, e = this.h4, f = this.h5, g = this.h6, - h = this.h7, blocks = this.blocks, j, s0, s1, maj, t1, t2, ch, ab, da, cd, bc; + h = this.h7, blocks = this.blocks, j, s0, s1, maj, t1, t2, ch, ab, da, cd, bc; for (j = 16; j < 64; ++j) { - // rightrotate - t1 = blocks[j - 15]; - s0 = ((t1 >>> 7) | (t1 << 25)) ^ ((t1 >>> 18) | (t1 << 14)) ^ (t1 >>> 3); - t1 = blocks[j - 2]; - s1 = ((t1 >>> 17) | (t1 << 15)) ^ ((t1 >>> 19) | (t1 << 13)) ^ (t1 >>> 10); - blocks[j] = blocks[j - 16] + s0 + blocks[j - 7] + s1 << 0; + // rightrotate + t1 = blocks[j - 15]; + s0 = ((t1 >>> 7) | (t1 << 25)) ^ ((t1 >>> 18) | (t1 << 14)) ^ (t1 >>> 3); + t1 = blocks[j - 2]; + s1 = ((t1 >>> 17) | (t1 << 15)) ^ ((t1 >>> 19) | (t1 << 13)) ^ (t1 >>> 10); + blocks[j] = blocks[j - 16] + s0 + blocks[j - 7] + s1 << 0; } bc = b & c; for (j = 0; j < 64; j += 4) { - if (this.first) { - if (this.is224) { - ab = 300032; - t1 = blocks[0] - 1413257819; - h = t1 - 150054599 << 0; - d = t1 + 24177077 << 0; - } else { - ab = 704751109; - t1 = blocks[0] - 210244248; - h = t1 - 1521486534 << 0; - d = t1 + 143694565 << 0; - } - this.first = false; - } else { - s0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10)); - s1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7)); - ab = a & b; - maj = ab ^ (a & c) ^ bc; - ch = (e & f) ^ (~e & g); - t1 = h + s1 + ch + K[j] + blocks[j]; - t2 = s0 + maj; - h = d + t1 << 0; - d = t1 + t2 << 0; - } - s0 = ((d >>> 2) | (d << 30)) ^ ((d >>> 13) | (d << 19)) ^ ((d >>> 22) | (d << 10)); - s1 = ((h >>> 6) | (h << 26)) ^ ((h >>> 11) | (h << 21)) ^ ((h >>> 25) | (h << 7)); - da = d & a; - maj = da ^ (d & b) ^ ab; - ch = (h & e) ^ (~h & f); - t1 = g + s1 + ch + K[j + 1] + blocks[j + 1]; - t2 = s0 + maj; - g = c + t1 << 0; - c = t1 + t2 << 0; - s0 = ((c >>> 2) | (c << 30)) ^ ((c >>> 13) | (c << 19)) ^ ((c >>> 22) | (c << 10)); - s1 = ((g >>> 6) | (g << 26)) ^ ((g >>> 11) | (g << 21)) ^ ((g >>> 25) | (g << 7)); - cd = c & d; - maj = cd ^ (c & a) ^ da; - ch = (g & h) ^ (~g & e); - t1 = f + s1 + ch + K[j + 2] + blocks[j + 2]; - t2 = s0 + maj; - f = b + t1 << 0; - b = t1 + t2 << 0; - s0 = ((b >>> 2) | (b << 30)) ^ ((b >>> 13) | (b << 19)) ^ ((b >>> 22) | (b << 10)); - s1 = ((f >>> 6) | (f << 26)) ^ ((f >>> 11) | (f << 21)) ^ ((f >>> 25) | (f << 7)); - bc = b & c; - maj = bc ^ (b & d) ^ cd; - ch = (f & g) ^ (~f & h); - t1 = e + s1 + ch + K[j + 3] + blocks[j + 3]; - t2 = s0 + maj; - e = a + t1 << 0; - a = t1 + t2 << 0; + if (this.first) { + if (this.is224) { + ab = 300032; + t1 = blocks[0] - 1413257819; + h = t1 - 150054599 << 0; + d = t1 + 24177077 << 0; + } else { + ab = 704751109; + t1 = blocks[0] - 210244248; + h = t1 - 1521486534 << 0; + d = t1 + 143694565 << 0; + } + this.first = false; + } else { + s0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10)); + s1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7)); + ab = a & b; + maj = ab ^ (a & c) ^ bc; + ch = (e & f) ^ (~e & g); + t1 = h + s1 + ch + K[j] + blocks[j]; + t2 = s0 + maj; + h = d + t1 << 0; + d = t1 + t2 << 0; + } + s0 = ((d >>> 2) | (d << 30)) ^ ((d >>> 13) | (d << 19)) ^ ((d >>> 22) | (d << 10)); + s1 = ((h >>> 6) | (h << 26)) ^ ((h >>> 11) | (h << 21)) ^ ((h >>> 25) | (h << 7)); + da = d & a; + maj = da ^ (d & b) ^ ab; + ch = (h & e) ^ (~h & f); + t1 = g + s1 + ch + K[j + 1] + blocks[j + 1]; + t2 = s0 + maj; + g = c + t1 << 0; + c = t1 + t2 << 0; + s0 = ((c >>> 2) | (c << 30)) ^ ((c >>> 13) | (c << 19)) ^ ((c >>> 22) | (c << 10)); + s1 = ((g >>> 6) | (g << 26)) ^ ((g >>> 11) | (g << 21)) ^ ((g >>> 25) | (g << 7)); + cd = c & d; + maj = cd ^ (c & a) ^ da; + ch = (g & h) ^ (~g & e); + t1 = f + s1 + ch + K[j + 2] + blocks[j + 2]; + t2 = s0 + maj; + f = b + t1 << 0; + b = t1 + t2 << 0; + s0 = ((b >>> 2) | (b << 30)) ^ ((b >>> 13) | (b << 19)) ^ ((b >>> 22) | (b << 10)); + s1 = ((f >>> 6) | (f << 26)) ^ ((f >>> 11) | (f << 21)) ^ ((f >>> 25) | (f << 7)); + bc = b & c; + maj = bc ^ (b & d) ^ cd; + ch = (f & g) ^ (~f & h); + t1 = e + s1 + ch + K[j + 3] + blocks[j + 3]; + t2 = s0 + maj; + e = a + t1 << 0; + a = t1 + t2 << 0; } this.h0 = this.h0 + a << 0; @@ -341,77 +337,77 @@ this.h5 = this.h5 + f << 0; this.h6 = this.h6 + g << 0; this.h7 = this.h7 + h << 0; - }; +}; - Sha256.prototype.hex = function () { +Sha256.prototype.hex = function () { this.finalize(); var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5, - h6 = this.h6, h7 = this.h7; + h6 = this.h6, h7 = this.h7; var hex = HEX_CHARS[(h0 >> 28) & 0x0F] + HEX_CHARS[(h0 >> 24) & 0x0F] + - HEX_CHARS[(h0 >> 20) & 0x0F] + HEX_CHARS[(h0 >> 16) & 0x0F] + - HEX_CHARS[(h0 >> 12) & 0x0F] + HEX_CHARS[(h0 >> 8) & 0x0F] + - HEX_CHARS[(h0 >> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] + - HEX_CHARS[(h1 >> 28) & 0x0F] + HEX_CHARS[(h1 >> 24) & 0x0F] + - HEX_CHARS[(h1 >> 20) & 0x0F] + HEX_CHARS[(h1 >> 16) & 0x0F] + - HEX_CHARS[(h1 >> 12) & 0x0F] + HEX_CHARS[(h1 >> 8) & 0x0F] + - HEX_CHARS[(h1 >> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] + - HEX_CHARS[(h2 >> 28) & 0x0F] + HEX_CHARS[(h2 >> 24) & 0x0F] + - HEX_CHARS[(h2 >> 20) & 0x0F] + HEX_CHARS[(h2 >> 16) & 0x0F] + - HEX_CHARS[(h2 >> 12) & 0x0F] + HEX_CHARS[(h2 >> 8) & 0x0F] + - HEX_CHARS[(h2 >> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] + - HEX_CHARS[(h3 >> 28) & 0x0F] + HEX_CHARS[(h3 >> 24) & 0x0F] + - HEX_CHARS[(h3 >> 20) & 0x0F] + HEX_CHARS[(h3 >> 16) & 0x0F] + - HEX_CHARS[(h3 >> 12) & 0x0F] + HEX_CHARS[(h3 >> 8) & 0x0F] + - HEX_CHARS[(h3 >> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] + - HEX_CHARS[(h4 >> 28) & 0x0F] + HEX_CHARS[(h4 >> 24) & 0x0F] + - HEX_CHARS[(h4 >> 20) & 0x0F] + HEX_CHARS[(h4 >> 16) & 0x0F] + - HEX_CHARS[(h4 >> 12) & 0x0F] + HEX_CHARS[(h4 >> 8) & 0x0F] + - HEX_CHARS[(h4 >> 4) & 0x0F] + HEX_CHARS[h4 & 0x0F] + - HEX_CHARS[(h5 >> 28) & 0x0F] + HEX_CHARS[(h5 >> 24) & 0x0F] + - HEX_CHARS[(h5 >> 20) & 0x0F] + HEX_CHARS[(h5 >> 16) & 0x0F] + - HEX_CHARS[(h5 >> 12) & 0x0F] + HEX_CHARS[(h5 >> 8) & 0x0F] + - HEX_CHARS[(h5 >> 4) & 0x0F] + HEX_CHARS[h5 & 0x0F] + - HEX_CHARS[(h6 >> 28) & 0x0F] + HEX_CHARS[(h6 >> 24) & 0x0F] + - HEX_CHARS[(h6 >> 20) & 0x0F] + HEX_CHARS[(h6 >> 16) & 0x0F] + - HEX_CHARS[(h6 >> 12) & 0x0F] + HEX_CHARS[(h6 >> 8) & 0x0F] + - HEX_CHARS[(h6 >> 4) & 0x0F] + HEX_CHARS[h6 & 0x0F]; + HEX_CHARS[(h0 >> 20) & 0x0F] + HEX_CHARS[(h0 >> 16) & 0x0F] + + HEX_CHARS[(h0 >> 12) & 0x0F] + HEX_CHARS[(h0 >> 8) & 0x0F] + + HEX_CHARS[(h0 >> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] + + HEX_CHARS[(h1 >> 28) & 0x0F] + HEX_CHARS[(h1 >> 24) & 0x0F] + + HEX_CHARS[(h1 >> 20) & 0x0F] + HEX_CHARS[(h1 >> 16) & 0x0F] + + HEX_CHARS[(h1 >> 12) & 0x0F] + HEX_CHARS[(h1 >> 8) & 0x0F] + + HEX_CHARS[(h1 >> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] + + HEX_CHARS[(h2 >> 28) & 0x0F] + HEX_CHARS[(h2 >> 24) & 0x0F] + + HEX_CHARS[(h2 >> 20) & 0x0F] + HEX_CHARS[(h2 >> 16) & 0x0F] + + HEX_CHARS[(h2 >> 12) & 0x0F] + HEX_CHARS[(h2 >> 8) & 0x0F] + + HEX_CHARS[(h2 >> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] + + HEX_CHARS[(h3 >> 28) & 0x0F] + HEX_CHARS[(h3 >> 24) & 0x0F] + + HEX_CHARS[(h3 >> 20) & 0x0F] + HEX_CHARS[(h3 >> 16) & 0x0F] + + HEX_CHARS[(h3 >> 12) & 0x0F] + HEX_CHARS[(h3 >> 8) & 0x0F] + + HEX_CHARS[(h3 >> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] + + HEX_CHARS[(h4 >> 28) & 0x0F] + HEX_CHARS[(h4 >> 24) & 0x0F] + + HEX_CHARS[(h4 >> 20) & 0x0F] + HEX_CHARS[(h4 >> 16) & 0x0F] + + HEX_CHARS[(h4 >> 12) & 0x0F] + HEX_CHARS[(h4 >> 8) & 0x0F] + + HEX_CHARS[(h4 >> 4) & 0x0F] + HEX_CHARS[h4 & 0x0F] + + HEX_CHARS[(h5 >> 28) & 0x0F] + HEX_CHARS[(h5 >> 24) & 0x0F] + + HEX_CHARS[(h5 >> 20) & 0x0F] + HEX_CHARS[(h5 >> 16) & 0x0F] + + HEX_CHARS[(h5 >> 12) & 0x0F] + HEX_CHARS[(h5 >> 8) & 0x0F] + + HEX_CHARS[(h5 >> 4) & 0x0F] + HEX_CHARS[h5 & 0x0F] + + HEX_CHARS[(h6 >> 28) & 0x0F] + HEX_CHARS[(h6 >> 24) & 0x0F] + + HEX_CHARS[(h6 >> 20) & 0x0F] + HEX_CHARS[(h6 >> 16) & 0x0F] + + HEX_CHARS[(h6 >> 12) & 0x0F] + HEX_CHARS[(h6 >> 8) & 0x0F] + + HEX_CHARS[(h6 >> 4) & 0x0F] + HEX_CHARS[h6 & 0x0F]; if (!this.is224) { - hex += HEX_CHARS[(h7 >> 28) & 0x0F] + HEX_CHARS[(h7 >> 24) & 0x0F] + - HEX_CHARS[(h7 >> 20) & 0x0F] + HEX_CHARS[(h7 >> 16) & 0x0F] + - HEX_CHARS[(h7 >> 12) & 0x0F] + HEX_CHARS[(h7 >> 8) & 0x0F] + - HEX_CHARS[(h7 >> 4) & 0x0F] + HEX_CHARS[h7 & 0x0F]; + hex += HEX_CHARS[(h7 >> 28) & 0x0F] + HEX_CHARS[(h7 >> 24) & 0x0F] + + HEX_CHARS[(h7 >> 20) & 0x0F] + HEX_CHARS[(h7 >> 16) & 0x0F] + + HEX_CHARS[(h7 >> 12) & 0x0F] + HEX_CHARS[(h7 >> 8) & 0x0F] + + HEX_CHARS[(h7 >> 4) & 0x0F] + HEX_CHARS[h7 & 0x0F]; } return hex; - }; +}; - Sha256.prototype.toString = Sha256.prototype.hex; +Sha256.prototype.toString = Sha256.prototype.hex; - Sha256.prototype.digest = function () { +Sha256.prototype.digest = function () { this.finalize(); var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5, - h6 = this.h6, h7 = this.h7; + h6 = this.h6, h7 = this.h7; var arr = [ - (h0 >> 24) & 0xFF, (h0 >> 16) & 0xFF, (h0 >> 8) & 0xFF, h0 & 0xFF, - (h1 >> 24) & 0xFF, (h1 >> 16) & 0xFF, (h1 >> 8) & 0xFF, h1 & 0xFF, - (h2 >> 24) & 0xFF, (h2 >> 16) & 0xFF, (h2 >> 8) & 0xFF, h2 & 0xFF, - (h3 >> 24) & 0xFF, (h3 >> 16) & 0xFF, (h3 >> 8) & 0xFF, h3 & 0xFF, - (h4 >> 24) & 0xFF, (h4 >> 16) & 0xFF, (h4 >> 8) & 0xFF, h4 & 0xFF, - (h5 >> 24) & 0xFF, (h5 >> 16) & 0xFF, (h5 >> 8) & 0xFF, h5 & 0xFF, - (h6 >> 24) & 0xFF, (h6 >> 16) & 0xFF, (h6 >> 8) & 0xFF, h6 & 0xFF + (h0 >> 24) & 0xFF, (h0 >> 16) & 0xFF, (h0 >> 8) & 0xFF, h0 & 0xFF, + (h1 >> 24) & 0xFF, (h1 >> 16) & 0xFF, (h1 >> 8) & 0xFF, h1 & 0xFF, + (h2 >> 24) & 0xFF, (h2 >> 16) & 0xFF, (h2 >> 8) & 0xFF, h2 & 0xFF, + (h3 >> 24) & 0xFF, (h3 >> 16) & 0xFF, (h3 >> 8) & 0xFF, h3 & 0xFF, + (h4 >> 24) & 0xFF, (h4 >> 16) & 0xFF, (h4 >> 8) & 0xFF, h4 & 0xFF, + (h5 >> 24) & 0xFF, (h5 >> 16) & 0xFF, (h5 >> 8) & 0xFF, h5 & 0xFF, + (h6 >> 24) & 0xFF, (h6 >> 16) & 0xFF, (h6 >> 8) & 0xFF, h6 & 0xFF ]; if (!this.is224) { - arr.push((h7 >> 24) & 0xFF, (h7 >> 16) & 0xFF, (h7 >> 8) & 0xFF, h7 & 0xFF); + arr.push((h7 >> 24) & 0xFF, (h7 >> 16) & 0xFF, (h7 >> 8) & 0xFF, h7 & 0xFF); } return arr; - }; +}; - Sha256.prototype.array = Sha256.prototype.digest; +Sha256.prototype.array = Sha256.prototype.digest; - Sha256.prototype.arrayBuffer = function () { +Sha256.prototype.arrayBuffer = function () { this.finalize(); var buffer = new ArrayBuffer(this.is224 ? 28 : 32); @@ -424,60 +420,60 @@ dataView.setUint32(20, this.h5); dataView.setUint32(24, this.h6); if (!this.is224) { - dataView.setUint32(28, this.h7); + dataView.setUint32(28, this.h7); } return buffer; - }; +}; - function HmacSha256(key, is224, sharedMemory) { +function HmacSha256(key, is224, sharedMemory) { var i, type = typeof key; if (type === 'string') { - var bytes = [], length = key.length, index = 0, code; - for (i = 0; i < length; ++i) { - code = key.charCodeAt(i); - if (code < 0x80) { - bytes[index++] = code; - } else if (code < 0x800) { - bytes[index++] = (0xc0 | (code >> 6)); - bytes[index++] = (0x80 | (code & 0x3f)); - } else if (code < 0xd800 || code >= 0xe000) { - bytes[index++] = (0xe0 | (code >> 12)); - bytes[index++] = (0x80 | ((code >> 6) & 0x3f)); - bytes[index++] = (0x80 | (code & 0x3f)); - } else { - code = 0x10000 + (((code & 0x3ff) << 10) | (key.charCodeAt(++i) & 0x3ff)); - bytes[index++] = (0xf0 | (code >> 18)); - bytes[index++] = (0x80 | ((code >> 12) & 0x3f)); - bytes[index++] = (0x80 | ((code >> 6) & 0x3f)); - bytes[index++] = (0x80 | (code & 0x3f)); - } - } - key = bytes; + var bytes = [], length = key.length, index = 0, code; + for (i = 0; i < length; ++i) { + code = key.charCodeAt(i); + if (code < 0x80) { + bytes[index++] = code; + } else if (code < 0x800) { + bytes[index++] = (0xc0 | (code >> 6)); + bytes[index++] = (0x80 | (code & 0x3f)); + } else if (code < 0xd800 || code >= 0xe000) { + bytes[index++] = (0xe0 | (code >> 12)); + bytes[index++] = (0x80 | ((code >> 6) & 0x3f)); + bytes[index++] = (0x80 | (code & 0x3f)); + } else { + code = 0x10000 + (((code & 0x3ff) << 10) | (key.charCodeAt(++i) & 0x3ff)); + bytes[index++] = (0xf0 | (code >> 18)); + bytes[index++] = (0x80 | ((code >> 12) & 0x3f)); + bytes[index++] = (0x80 | ((code >> 6) & 0x3f)); + bytes[index++] = (0x80 | (code & 0x3f)); + } + } + key = bytes; } else { - if (type === 'object') { - if (key === null) { - throw new Error(ERROR); - } else if (ARRAY_BUFFER && key.constructor === ArrayBuffer) { - key = new Uint8Array(key); - } else if (!Array.isArray(key)) { - if (!ARRAY_BUFFER || !ArrayBuffer.isView(key)) { + if (type === 'object') { + if (key === null) { + throw new Error(ERROR); + } else if (ARRAY_BUFFER && key.constructor === ArrayBuffer) { + key = new Uint8Array(key); + } else if (!Array.isArray(key)) { + if (!ARRAY_BUFFER || !ArrayBuffer.isView(key)) { + throw new Error(ERROR); + } + } + } else { throw new Error(ERROR); - } - } - } else { - throw new Error(ERROR); - } + } } if (key.length > 64) { - key = (new Sha256(is224, true)).update(key).array(); + key = (new Sha256(is224, true)).update(key).array(); } var oKeyPad = [], iKeyPad = []; for (i = 0; i < 64; ++i) { - var b = key[i] || 0; - oKeyPad[i] = 0x5c ^ b; - iKeyPad[i] = 0x36 ^ b; + var b = key[i] || 0; + oKeyPad[i] = 0x5c ^ b; + iKeyPad[i] = 0x36 ^ b; } Sha256.call(this, is224, sharedMemory); @@ -486,38 +482,43 @@ this.oKeyPad = oKeyPad; this.inner = true; this.sharedMemory = sharedMemory; - } - HmacSha256.prototype = new Sha256(); +} +HmacSha256.prototype = new Sha256(); - HmacSha256.prototype.finalize = function () { +HmacSha256.prototype.finalize = function () { Sha256.prototype.finalize.call(this); if (this.inner) { - this.inner = false; - var innerHash = this.array(); - Sha256.call(this, this.is224, this.sharedMemory); - this.update(this.oKeyPad); - this.update(innerHash); - Sha256.prototype.finalize.call(this); + this.inner = false; + var innerHash = this.array(); + Sha256.call(this, this.is224, this.sharedMemory); + this.update(this.oKeyPad); + this.update(innerHash); + Sha256.prototype.finalize.call(this); } - }; +}; - var exports = createMethod(); - exports.sha256 = exports; - exports.sha224 = createMethod(true); - exports.sha256.hmac = createHmacMethod(); - exports.sha224.hmac = createHmacMethod(true); +var exports = createMethod(); +exports.sha256 = exports; +exports.sha224 = createMethod(true); +exports.sha256.hmac = createHmacMethod(); +exports.sha224.hmac = createHmacMethod(true); - if (COMMON_JS) { +if (COMMON_JS) { module.exports = exports; - } else { +} else { root.sha256 = exports.sha256; root.sha224 = exports.sha224; if (AMD) { - define(function () { - return exports; - }); + define(function () { + return exports; + }); } - } +} + +const sha256 = fake_window.sha256; - window.sha256 = fake_window.sha256; -})(); +/* + * EXPORTS_START + * EXPORT sha256 + * EXPORTS_END + */ diff --git a/common/storage_client.js b/common/storage_client.js index 1bc9a88..2bbddb6 100644 --- a/common/storage_client.js +++ b/common/storage_client.js @@ -5,182 +5,188 @@ * Redistribution terms are gathered in the `copyright' file. */ -"use strict"; - -(() => { - const CONNECTION_TYPE = window.CONNECTION_TYPE; - const TYPE_PREFIX = window.TYPE_PREFIX; - const list_prefixes = window.list_prefixes; - const make_once = window.make_once; - const browser = window.browser; - - var call_id = 0; - var port; - var calls_waiting = new Map(); - - function set_call_callback(resolve, reject, func, args) - { - port.postMessage([call_id, func, args]); - calls_waiting.set(call_id++, [resolve, reject]); - } - - async function remote_call(func, args) - { - return new Promise((resolve, reject) => - set_call_callback(resolve, reject, func, args)); - } - - function handle_message(message) - { - let callbacks = calls_waiting.get(message.call_id); - if (callbacks === undefined) { - handle_change(message); - return; - } - - let [resolve, reject] = callbacks; - calls_waiting.delete(message.call_id); - if (message.error !== undefined) - setTimeout(reject, 0, message.error); - else - setTimeout(resolve, 0, message.result); - } - - function list(name, prefix) - { - return {prefix, name, listeners : new Set()}; - } - - var scripts = list("scripts", TYPE_PREFIX.SCRIPT); - var bags = list("bags", TYPE_PREFIX.BAG); - var pages = list("pages", TYPE_PREFIX.PAGE); - - const list_by_prefix = { - [TYPE_PREFIX.SCRIPT] : scripts, - [TYPE_PREFIX.BAG] : bags, - [TYPE_PREFIX.PAGE] : pages - }; - - var resolve_init; - - function handle_first_message(message) - { - for (let prefix of Object.keys(message)) - list_by_prefix[prefix].map = new Map(message[prefix]); - - port.onMessage.removeListener(handle_first_message); - port.onMessage.addListener(handle_message); - - resolve_init(); - } - - function handle_change(change) - { - let list = list_by_prefix[change.prefix]; - - if (change.new_val === undefined) - list.map.delete(change.item); - else - list.map.set(change.item, change.new_val); - - for (let listener_callback of list.listeners) - listener_callback(change); - } - - var exports = {}; - - function start_connection(resolve) - { - resolve_init = resolve; - port = browser.runtime.connect({name : CONNECTION_TYPE.REMOTE_STORAGE}); - port.onMessage.addListener(handle_first_message); - } - - async function init() { - await new Promise((resolve, reject) => start_connection(resolve)); - return exports; - } - - for (let call_name of ["set", "remove", "replace", "clear"]) - exports [call_name] = (...args) => remote_call(call_name, args); - - // TODO: Much of the code below is copy-pasted from /background/storage.mjs. - // This should later be refactored into a separate module - // to avoid duplication. - - /* - * Facilitate listening to changes - */ - - exports.add_change_listener = function (cb, prefixes=list_prefixes) - { - if (typeof(prefixes) === "string") - prefixes = [prefixes]; - - for (let prefix of prefixes) - list_by_prefix[prefix].listeners.add(cb); - } - - exports.remove_change_listener = function (cb, prefixes=list_prefixes) - { - if (typeof(prefixes) === "string") - prefixes = [prefixes]; - - for (let prefix of prefixes) - list_by_prefix[prefix].listeners.delete(cb); - } - - /* Prepare some hepler functions to get elements of a list */ - - function list_items_it(list, with_values=false) - { - return with_values ? list.map.entries() : list.map.keys(); - } - - function list_entries_it(list) - { - return list_items_it(list, true); - } - - function list_items(list, with_values=false) - { - let array = []; - - for (let item of list_items_it(list, with_values)) - array.push(item); - - return array; - } - - function list_entries(list) - { - return list_items(list, true); - } - - exports.get = function (prefix, item) - { - return list_by_prefix[prefix].map.get(item); - } - - exports.get_all_names = function (prefix) - { - return list_items(list_by_prefix[prefix]); - } - - exports.get_all_names_it = function (prefix) - { - return list_items_it(list_by_prefix[prefix]); - } - - exports.get_all = function (prefix) - { - return list_entries(list_by_prefix[prefix]); - } +/* + * IMPORTS_START + * IMPORT CONNECTION_TYPE + * IMPORT TYPE_PREFIX + * IMPORT list_prefixes + * IMPORT make_once + * IMPORT browser + * IMPORTS_END + */ - exports.get_all_it = function (prefix) - { - return list_entries_it(list_by_prefix[prefix]); - } +var call_id = 0; +var port; +var calls_waiting = new Map(); + +function set_call_callback(resolve, reject, func, args) +{ + port.postMessage([call_id, func, args]); + calls_waiting.set(call_id++, [resolve, reject]); +} + +async function remote_call(func, args) +{ + return new Promise((resolve, reject) => + set_call_callback(resolve, reject, func, args)); +} + +function handle_message(message) +{ + let callbacks = calls_waiting.get(message.call_id); + if (callbacks === undefined) { + handle_change(message); + return; + } + + let [resolve, reject] = callbacks; + calls_waiting.delete(message.call_id); + if (message.error !== undefined) + setTimeout(reject, 0, message.error); + else + setTimeout(resolve, 0, message.result); +} + +function list(name, prefix) +{ + return {prefix, name, listeners : new Set()}; +} + +var scripts = list("scripts", TYPE_PREFIX.SCRIPT); +var bags = list("bags", TYPE_PREFIX.BAG); +var pages = list("pages", TYPE_PREFIX.PAGE); + +const list_by_prefix = { + [TYPE_PREFIX.SCRIPT] : scripts, + [TYPE_PREFIX.BAG] : bags, + [TYPE_PREFIX.PAGE] : pages +}; + +var resolve_init; + +function handle_first_message(message) +{ + for (let prefix of Object.keys(message)) + list_by_prefix[prefix].map = new Map(message[prefix]); + + port.onMessage.removeListener(handle_first_message); + port.onMessage.addListener(handle_message); + + resolve_init(); +} + +function handle_change(change) +{ + let list = list_by_prefix[change.prefix]; + + if (change.new_val === undefined) + list.map.delete(change.item); + else + list.map.set(change.item, change.new_val); + + for (let listener_callback of list.listeners) + listener_callback(change); +} + +var exports = {}; + +function start_connection(resolve) +{ + resolve_init = resolve; + port = browser.runtime.connect({name : CONNECTION_TYPE.REMOTE_STORAGE}); + port.onMessage.addListener(handle_first_message); +} + +async function init() { + await new Promise((resolve, reject) => start_connection(resolve)); + return exports; +} + +for (let call_name of ["set", "remove", "replace", "clear"]) + exports [call_name] = (...args) => remote_call(call_name, args); + +// TODO: Much of the code below is copy-pasted from /background/storage.mjs. +// This should later be refactored into a separate module +// to avoid duplication. + +/* + * Facilitate listening to changes + */ - window.get_storage = make_once(init); -})(); +exports.add_change_listener = function (cb, prefixes=list_prefixes) +{ + if (typeof(prefixes) === "string") + prefixes = [prefixes]; + + for (let prefix of prefixes) + list_by_prefix[prefix].listeners.add(cb); +} + +exports.remove_change_listener = function (cb, prefixes=list_prefixes) +{ + if (typeof(prefixes) === "string") + prefixes = [prefixes]; + + for (let prefix of prefixes) + list_by_prefix[prefix].listeners.delete(cb); +} + +/* Prepare some hepler functions to get elements of a list */ + +function list_items_it(list, with_values=false) +{ + return with_values ? list.map.entries() : list.map.keys(); +} + +function list_entries_it(list) +{ + return list_items_it(list, true); +} + +function list_items(list, with_values=false) +{ + let array = []; + + for (let item of list_items_it(list, with_values)) + array.push(item); + + return array; +} + +function list_entries(list) +{ + return list_items(list, true); +} + +exports.get = function (prefix, item) +{ + return list_by_prefix[prefix].map.get(item); +} + +exports.get_all_names = function (prefix) +{ + return list_items(list_by_prefix[prefix]); +} + +exports.get_all_names_it = function (prefix) +{ + return list_items_it(list_by_prefix[prefix]); +} + +exports.get_all = function (prefix) +{ + return list_entries(list_by_prefix[prefix]); +} + +exports.get_all_it = function (prefix) +{ + return list_entries_it(list_by_prefix[prefix]); +} + +const get_remote_storage = make_once(init); + +/* + * EXPORTS_START + * EXPORT get_remote_storage + * EXPORTS_END + */ diff --git a/common/stored_types.js b/common/stored_types.js index e043777..ef1339f 100644 --- a/common/stored_types.js +++ b/common/stored_types.js @@ -13,29 +13,29 @@ * an underscore. */ -"use strict"; +const TYPE_PREFIX = { + PAGE : "p", + BAG : "b", + SCRIPT : "s", + VAR : "_" +}; -(() => { - const TYPE_PREFIX = { - PAGE : "p", - BAG : "b", - SCRIPT : "s", - VAR : "_" - }; +const TYPE_NAME = { + [TYPE_PREFIX.PAGE] : "page", + [TYPE_PREFIX.BAG] : "bag", + [TYPE_PREFIX.SCRIPT] : "script" +} - const TYPE_NAME = { - [TYPE_PREFIX.PAGE] : "page", - [TYPE_PREFIX.BAG] : "bag", - [TYPE_PREFIX.SCRIPT] : "script" - } +const list_prefixes = [ + TYPE_PREFIX.PAGE, + TYPE_PREFIX.BAG, + TYPE_PREFIX.SCRIPT +]; - const list_prefixes = [ - TYPE_PREFIX.PAGE, - TYPE_PREFIX.BAG, - TYPE_PREFIX.SCRIPT - ]; - - window.TYPE_PREFIX = TYPE_PREFIX; - window.TYPE_NAME = TYPE_NAME; - window.list_prefixes = list_prefixes; -})(); +/* + * EXPORTS_START + * EXPORT TYPE_PREFIX + * EXPORT TYPE_NAME + * EXPORT list_prefixes + * EXPORTS_END + */ diff --git a/common/url_item.js b/common/url_item.js index 9f4b118..102f117 100644 --- a/common/url_item.js +++ b/common/url_item.js @@ -5,15 +5,15 @@ * Redistribution terms are gathered in the `copyright' file. */ -"use strict"; +function url_item(url) +{ + let url_re = /^([^?#]*).*$/; + let match = url_re.exec(url); + return match[1]; +} -(() => { - function url_item(url) - { - let url_re = /^([^?#]*).*$/; - let match = url_re.exec(url); - return match[1]; - } - - window.url_item = url_item; -})(); +/* + * EXPORTS_START + * EXPORT url_item + * EXPORTS_END + */ -- cgit v1.2.3