diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index aabb829..20003ec 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -10,5 +10,13 @@ "appDescription": { "message": "Browser extension to bookmark fragments of audio files", "description": "The description of the application" + }, + "bookmarkSelectionContextMenuItemForFragment": { + "message": "Bookmark selected fragment", + "description": "The entry in the context ('right-click') menu when selecting an audio fragment" + }, + "bookmarkSelectionContextMenuItemForSingleMoment": { + "message": "Bookmark selected moment", + "description": "The entry in the context ('right-click') menu when selecting a single moment" } } diff --git a/app/assets/main.css b/app/assets/main.css index aec3371..a7edbda 100644 --- a/app/assets/main.css +++ b/app/assets/main.css @@ -85,3 +85,25 @@ input#volume:focus { filter: brightness(102%); outline: none; } + +.context-menu { + list-style: none; + margin: 0; + padding: 0; + position: absolute; + z-index: 9999999; + border: 1px solid #99999966; + border-radius: 2px; + box-shadow: 2px 2px 6px #99999966; + background: #fcfcfc; +} + +.context-menu button { + background: none; + border: none; + font-size: 1em; + padding: 4px 20px; +} +.context-menu button:hover { + background: #dddddd99; +} diff --git a/app/audio-player/contentscript.js b/app/audio-player/contentscript.js index 14da539..9498132 100644 --- a/app/audio-player/contentscript.js +++ b/app/audio-player/contentscript.js @@ -76,6 +76,11 @@ async function init() { // Start playing. A tiny delay seems needed in Firefox to show the cursor at the right place. requestAnimationFrame(() => eventEmitter.emit('play')); + + return playlist; } -init(); +init().then(playlist => { + // Store playlist as a shared global variable. + self.playlist = playlist; +}); diff --git a/app/create-bookmarks/background.js b/app/create-bookmarks/background.js new file mode 100644 index 0000000..094fc25 --- /dev/null +++ b/app/create-bookmarks/background.js @@ -0,0 +1,34 @@ +import { makeRemotelyCallable } from 'webextension-rpc'; + +// Format time as S, or M:SS, or H:MM:SS, depending on which would be needed to express maxSeconds. +// E.g. secondsToString(12) === '12', but secondsToString(12, 3600) === '0:00:12'. +function secondsToString(seconds, maxSeconds) { + let s = `${Math.round(seconds % 60)}`; + let m = ''; + let h = ''; + const minutes = Math.floor(seconds / 60); + if (minutes || maxSeconds >= 60) { + m = `${minutes % 60}:`; + if (!/^\d\d/.test(s)) s = '0' + s; + } + if (seconds >= 60 * 60 || maxSeconds >= 60 * 60) { + h = `${Math.floor(minutes / 60)}:`; + if (m.length <= 2) m = '0' + m; + } + return `${h}${m}${s}`; +} + +async function createBookmark({ url, start, end, trackDuration }) { + // Create a (hopefully) meaningful title; e.g. 'filename.mp3 0:30–1:10' + const filenameMatch = url.match(/.*\/([^\/#?]+)(?:\?.*)?(?:#.*)?/); + const filename = filenameMatch ? filenameMatch[1] : 'Audio fragment'; + const startString = secondsToString(start, trackDuration); + const endString = (end !== undefined) + ? '–' + secondsToString(end, trackDuration) + : ''; + const title = `${filename} ${startString}${endString}`; + + await browser.bookmarks.create({ url, title }); +} + +makeRemotelyCallable({ createBookmark }); diff --git a/app/create-bookmarks/contentscript.js b/app/create-bookmarks/contentscript.js new file mode 100644 index 0000000..9b4b1f4 --- /dev/null +++ b/app/create-bookmarks/contentscript.js @@ -0,0 +1,88 @@ +import html from 'nanohtml'; +import { remoteFunction } from 'webextension-rpc'; + +import { createMediaFragmentIdentifier } from '../util/media-fragment-identifier'; + +function createPreciseUrl(url, selector) { + const properUrl = url.split('#')[0]; + + let fragmentIdentifier; + if (selector.type === 'FragmentSelector') { + fragmentIdentifier = selector.value; + } else { + throw new Error('Unsupported selector type'); + } + + return properUrl + '#' + fragmentIdentifier; +} + +function describeMediaFragment({ start, end }) { + const fragmentIdentifier = createMediaFragmentIdentifier({ start, end }); + + const selector = { + type: 'FragmentSelector', + conformsTo: 'http://www.w3.org/TR/media-frags/', + value: fragmentIdentifier, + }; + return selector; +} + +async function init() { + let menuEl; + + function hideMenu() { + if (!menuEl) return; + menuEl.parentNode.removeChild(menuEl); + menuEl = undefined; + } + + function onContextMenu(event) { + event.preventDefault(); + const left = event.pageX; + const top = event.pageY; + + const playlist = self.playlist; + if (!playlist) { + throw new Error('Player has not been initialised.'); + } + const trackDuration = playlist.duration; + let { start, end } = playlist.getTimeSelection(); + if (start === undefined) return; + + // Waveform Playlist tells us end=start when the selection is just a single line. + if (end === start) end = undefined; + + // Round the numbers to two decimals. + // Also, as Waveform Playlist might report a slightly negative number, first cap it to zero. + start = Math.round(Math.max(0, start) * 100) / 100; + if (end !== undefined) end = Math.round(Math.max(0, end) * 100) / 100; + + async function createBookmark() { + const fileUrl = document.URL; + const selector = describeMediaFragment({ start, end }); + const bookmarkUrl = createPreciseUrl(fileUrl, selector); + await remoteFunction('createBookmark')({ url: bookmarkUrl, start, end, trackDuration }); + } + + hideMenu(); + menuEl = html` + + `; + document.body.appendChild(menuEl); + } + + document.addEventListener('contextmenu', onContextMenu, false); + + document.addEventListener('click', event => { hideMenu(); }); +} + +init(); diff --git a/app/manifest.json b/app/manifest.json index dcef13b..d11f6fe 100644 --- a/app/manifest.json +++ b/app/manifest.json @@ -10,6 +10,8 @@ }, "permissions": [ "", + "bookmarks", + "tabs", "webRequest" ] } diff --git a/app/scripts/background.js b/app/scripts/background.js index 8663d22..a5866e1 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -1 +1,2 @@ import '../audio-player/background.js' +import '../create-bookmarks/background.js' diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js index e33d912..ccccdce 100644 --- a/app/scripts/contentscript.js +++ b/app/scripts/contentscript.js @@ -1 +1,2 @@ import '../audio-player/contentscript.js' +import '../create-bookmarks/contentscript.js' diff --git a/package-lock.json b/package-lock.json index 8967650..8d94cd1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1306,6 +1306,28 @@ "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==", "dev": true }, + "acorn-node": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", + "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", + "requires": { + "acorn": "^7.0.0", + "acorn-walk": "^7.0.0", + "xtend": "^4.0.2" + }, + "dependencies": { + "acorn": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", + "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==" + } + } + }, + "acorn-walk": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.0.0.tgz", + "integrity": "sha512-7Bv1We7ZGuU79zZbb6rRqcpxo3OY+zrdtloZWoyD8fmGX+FeXRjE+iuGkZjSXLVovLzrsvMGMy0EkwA0E0umxg==" + }, "ajv": { "version": "6.10.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", @@ -2298,6 +2320,11 @@ "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", "dev": true }, + "browser-process-hrtime": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", + "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==" + }, "browser-split": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/browser-split/-/browser-split-0.0.1.tgz", @@ -2518,6 +2545,15 @@ "integrity": "sha1-qEq8glpV70yysCi9dOIFpluaSZY=", "dev": true }, + "camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, "camelcase": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", @@ -2942,7 +2978,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", - "dev": true, "requires": { "safe-buffer": "~5.1.1" } @@ -3016,8 +3051,7 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "create-ecdh": { "version": "4.0.3", @@ -3116,6 +3150,11 @@ "type": "^1.0.1" } }, + "dash-ast": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz", + "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==" + }, "date-now": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", @@ -3563,8 +3602,7 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "eslint-scope": { "version": "4.0.3", @@ -3624,6 +3662,11 @@ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, + "estree-is-member-expression": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/estree-is-member-expression/-/estree-is-member-expression-1.0.0.tgz", + "integrity": "sha512-Ec+X44CapIGExvSZN+pGkmr5p7HwUVQoPQSd458Lqwvaf4/61k/invHSh4BYK8OXnCkfEhWuIoG5hayKLQStIg==" + }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -4823,6 +4866,21 @@ "function-bind": "^1.1.1" } }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } + } + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -4946,6 +5004,19 @@ "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", "dev": true }, + "hyperscript-attribute-to-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hyperscript-attribute-to-property/-/hyperscript-attribute-to-property-1.0.2.tgz", + "integrity": "sha512-oerMul16jZCmrbNsUw8QgrtDzF8lKgFri1bKQjReLw1IhiiNkI59CWuzZjJDGT79UQ1YiWqXhJMv/tRMVqgtkA==" + }, + "hyperx": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/hyperx/-/hyperx-2.5.4.tgz", + "integrity": "sha512-iOkSh7Yse7lsN/B9y7OsevLWjeXPqGuHQ5SbwaiJM5xAhWFqhoN6erpK1dQsS12OFU36lyai1pnx1mmzWLQqcA==", + "requires": { + "hyperscript-attribute-to-property": "^1.0.0" + } + }, "ieee754": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", @@ -5082,8 +5153,7 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { "version": "1.3.5", @@ -5152,6 +5222,11 @@ "binary-extensions": "^1.0.0" } }, + "is-boolean-attribute": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/is-boolean-attribute/-/is-boolean-attribute-0.0.1.tgz", + "integrity": "sha1-JKtZt9y52jYSx3PmDGVlZeWgmAw=" + }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", @@ -5423,8 +5498,7 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "isemail": { "version": "3.2.0", @@ -5674,6 +5748,11 @@ "signal-exit": "^3.0.2" } }, + "lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=" + }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -5690,6 +5769,14 @@ "yallist": "^2.1.2" } }, + "magic-string": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.23.2.tgz", + "integrity": "sha512-oIUZaAxbcxYIp4AyLafV6OVKoB3YouZs0UTCJ8mOKBHNyJgGDaMJ4TgA+VylJh6fx7EQCC52XkbURxxG9IoJXA==", + "requires": { + "sourcemap-codec": "^1.4.1" + } + }, "make-dir": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", @@ -5808,6 +5895,14 @@ } } }, + "merge-source-map": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.0.4.tgz", + "integrity": "sha1-pd5GU42uhNQRTMXqArR3KmNGcB8=", + "requires": { + "source-map": "^0.5.6" + } + }, "merge2": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", @@ -5991,6 +6086,11 @@ "resolved": "https://registry.npmjs.org/mucss/-/mucss-1.1.5.tgz", "integrity": "sha1-fNbsWVWQ5gPkg6ENaajsfdJwplY=" }, + "mutexify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mutexify/-/mutexify-1.2.0.tgz", + "integrity": "sha512-oprzxd2zhfrJqEuB98qc1dRMMonClBQ57UPDjnbcrah4orEMTq1jq3+AcdFe5ePzdbJXI7zmdhfftIdMnhYFoQ==" + }, "nan": { "version": "2.14.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", @@ -5998,6 +6098,77 @@ "dev": true, "optional": true }, + "nanoassert": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-1.1.0.tgz", + "integrity": "sha1-TzFS4JVA/eKMdvRLGbvNHVpCR40=" + }, + "nanobench": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nanobench/-/nanobench-2.1.1.tgz", + "integrity": "sha512-z+Vv7zElcjN+OpzAxAquUayFLGK3JI/ubCl0Oh64YQqsTGG09CGqieJVQw4ui8huDnnAgrvTv93qi5UaOoNj8A==", + "requires": { + "browser-process-hrtime": "^0.1.2", + "chalk": "^1.1.3", + "mutexify": "^1.1.0", + "pretty-hrtime": "^1.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "nanohtml": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/nanohtml/-/nanohtml-1.8.1.tgz", + "integrity": "sha512-yoS1g5rikfacn4XA9dgr2GHO5oVUImFdnKjFrnLLZtmM+73CCM4yWK8NalD8HwTvK8a6d3vV2+GVzcoHrC83WQ==", + "requires": { + "acorn-node": "^1.8.2", + "camel-case": "^3.0.0", + "convert-source-map": "^1.5.1", + "estree-is-member-expression": "^1.0.0", + "hyperx": "^2.5.0", + "is-boolean-attribute": "0.0.1", + "nanoassert": "^1.1.0", + "nanobench": "^2.1.0", + "normalize-html-whitespace": "^0.2.0", + "through2": "^2.0.3", + "transform-ast": "^2.4.0" + } + }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -6028,6 +6199,14 @@ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" }, + "no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "requires": { + "lower-case": "^1.1.1" + } + }, "node-libs-browser": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", @@ -6090,6 +6269,11 @@ } } }, + "normalize-html-whitespace": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/normalize-html-whitespace/-/normalize-html-whitespace-0.2.0.tgz", + "integrity": "sha1-EBci9kI1Ucdc24+dEE/4UNrx4Q4=" + }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -6594,6 +6778,11 @@ "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", "dev": true }, + "pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=" + }, "pretty-ms": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-5.0.0.tgz", @@ -6623,8 +6812,7 @@ "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "promise-inflight": { "version": "1.0.1", @@ -6770,7 +6958,6 @@ "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -7046,8 +7233,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "safe-regex": { "version": "1.1.0", @@ -7302,8 +7488,7 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" }, "source-map-resolve": { "version": "0.5.2", @@ -7342,6 +7527,11 @@ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "dev": true }, + "sourcemap-codec": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.6.tgz", + "integrity": "sha512-1ZooVLYFxC448piVLBbtOxFcXwnymH9oUF8nRd3CuYDVvkRBxRl6pB4Mtas5a4drtL+E8LDgFkQNcgIw6tc8Hg==" + }, "spdx-correct": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", @@ -7522,7 +7712,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "requires": { "safe-buffer": "~5.1.0" } @@ -7799,7 +7988,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, "requires": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" @@ -7897,6 +8085,27 @@ } } }, + "transform-ast": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/transform-ast/-/transform-ast-2.4.4.tgz", + "integrity": "sha512-AxjeZAcIOUO2lev2GDe3/xZ1Q0cVGjIMk5IsriTy8zbWlsEnjeB025AhkhBJHoy997mXpLd4R+kRbvnnQVuQHQ==", + "requires": { + "acorn-node": "^1.3.0", + "convert-source-map": "^1.5.1", + "dash-ast": "^1.0.0", + "is-buffer": "^2.0.0", + "magic-string": "^0.23.2", + "merge-source-map": "1.0.4", + "nanobench": "^2.1.1" + }, + "dependencies": { + "is-buffer": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" + } + } + }, "trim-newlines": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", @@ -8120,6 +8329,11 @@ } } }, + "upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=" + }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", @@ -8188,8 +8402,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "util.promisify": { "version": "1.0.0", @@ -8293,6 +8506,29 @@ "integrity": "sha512-ISB42vlgMyM7xE1u6pREeCqmmXjLsYu/nqAR8Dl/gIAnylb+KpRpvKbVkUYNFePhhXn0Obkkc3jasOII9ztUtg==", "dev": true }, + "webextension-rpc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/webextension-rpc/-/webextension-rpc-0.1.0.tgz", + "integrity": "sha512-9JCBkXmeP7ossYauXgfvxqQurO5E0VK7uQnlIyirj1zzhGzV92TvOC4FhhqhYBphV9d0doUg+pCQtvRkGsk8+A==", + "requires": { + "@babel/runtime": "^7.6.2" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.3.tgz", + "integrity": "sha512-kq6anf9JGjW8Nt5rYfEuGRaEAaH1mkv3Bbu6rYvLOpPh/RusSJXuKPEAoZ7L7gybZkchE8+NV5g9vKF4AGAtsA==", + "requires": { + "regenerator-runtime": "^0.13.2" + } + }, + "regenerator-runtime": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==" + } + } + }, "webextension-toolbox": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/webextension-toolbox/-/webextension-toolbox-3.0.0.tgz", diff --git a/package.json b/package.json index 78dd204..4214d1c 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,9 @@ }, "dependencies": { "delay": "^4.3.0", - "waveform-playlist": "^3.0.4" + "nanohtml": "^1.8.1", + "waveform-playlist": "^3.0.4", + "webextension-rpc": "^0.1.0" }, "ava": { "require": [