diff --git a/package-lock.json b/package-lock.json index f3aef3d..0a1a95a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,9 +1,15 @@ { "name": "peertubeify", - "version": "0.2.1", + "version": "0.2.2", "lockfileVersion": 1, "requires": true, "dependencies": { + "@types/lodash": { + "version": "4.14.116", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.116.tgz", + "integrity": "sha512-lRnAtKnxMXcYYXqOiotTmJd74uawNWuPnsnPrrO7HiFuE3npE2iQhfABatbYDyxTNqZNuXzcKGhw37R7RjBFLg==", + "dev": true + }, "@webassemblyjs/ast": { "version": "1.5.13", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.5.13.tgz", @@ -3847,6 +3853,19 @@ "repeat-string": "^1.6.1" } }, + "ts-loader": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-4.4.2.tgz", + "integrity": "sha512-Z3Y1a7A0KZZ1s/mAZkt74l1NAF7Y5xUhD1V9VB8/1eUlUOk8Qa/oo46tO2Uu5kQ3wXypOlbv77lLQySjXEDcdw==", + "dev": true, + "requires": { + "chalk": "^2.3.0", + "enhanced-resolve": "^4.0.0", + "loader-utils": "^1.0.2", + "micromatch": "^3.1.4", + "semver": "^5.0.1" + } + }, "tslib": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", @@ -3865,6 +3884,12 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, + "typescript": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.0.1.tgz", + "integrity": "sha512-zQIMOmC+372pC/CCVLqnQ0zSBiY7HHodU7mpQdjiZddek4GMj31I3dUJ7gAs9o65X7mnRma6OokOkc6f9jjfBg==", + "dev": true + }, "uglify-es": { "version": "3.3.9", "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", @@ -4092,6 +4117,12 @@ "neo-async": "^2.5.0" } }, + "web-ext-types": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/web-ext-types/-/web-ext-types-2.1.0.tgz", + "integrity": "sha1-MdDb9RdimM2AYnSsxDgzhbgai7Y=", + "dev": true + }, "webpack": { "version": "4.16.5", "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.16.5.tgz", diff --git a/package.json b/package.json index 22bc0c7..89eea78 100644 --- a/package.json +++ b/package.json @@ -5,10 +5,14 @@ "main": "webpack.config.js", "dependencies": {}, "devDependencies": { + "@types/lodash": "^4.14.116", "extract-loader": "^2.0.1", "file-loader": "^1.1.11", "html-loader": "^0.5.5", "lodash": "^4.17.10", + "ts-loader": "^4.4.2", + "typescript": "^3.0.1", + "web-ext-types": "^2.1.0", "webpack": "^4.16.5", "webpack-cli": "^3.1.0" }, diff --git a/src/background.js b/src/background.ts similarity index 83% rename from src/background.js rename to src/background.ts index d77b4e0..a02f5c6 100644 --- a/src/background.js +++ b/src/background.ts @@ -14,12 +14,12 @@ * PeerTubeify. If not, see . */ -import _ from 'lodash/fp'; +import * as _ from 'lodash/fp'; -const buildSearchURL = (instance, query) => `https://${instance}/api/v1/search/videos?search=${encodeURIComponent(query)}`; +const buildSearchURL = (instance: string, query: string): string => `https://${instance}/api/v1/search/videos?search=${encodeURIComponent(query)}`; const search = query => new Promise(async (resolve, reject) => { - const instance = _.getOr('framatube.org', 'searchInstance', await browser.storage.local.get()); + const instance = _.getOr('framatube.org', 'searchInstance', await browser.storage.local.get()).toString(); fetch(buildSearchURL(instance, query)) .then(res => res.json()) diff --git a/src/options.js b/src/options.js deleted file mode 100644 index 6227e03..0000000 --- a/src/options.js +++ /dev/null @@ -1,25 +0,0 @@ -import _ from 'lodash/fp'; - -function id(id) { return document.getElementById(id); } - -function saveOptions(e) { - e.preventDefault(); - browser.storage.local.set({ - searchInstance: _.defaultTo('framatube.org', stripProtocol(id('search-instance').value)), - openInOriginalInstance: _.defaultTo(true, id('open-in-original-instance').checked), - }); -} - -function stripProtocol(url) { - return url.replace(/^https?:\/\//, ''); -} - -function restoreOptions() { - browser.storage.local.get().then(result => { - id('search-instance').value = _.defaultTo('framatube.org', result.searchInstance); - id('open-in-original-instance').checked = _.defaultTo(true, result.openInOriginalInstance); - }) -} - -document.addEventListener('DOMContentLoaded', restoreOptions); -document.querySelector('form').addEventListener('submit', saveOptions); diff --git a/src/options.ts b/src/options.ts new file mode 100644 index 0000000..4b80705 --- /dev/null +++ b/src/options.ts @@ -0,0 +1,26 @@ +import * as _ from 'lodash/fp'; + +function id(id: string): Element { return document.getElementById(id); } + +const searchInstanceInput = () => id('search-instance') as HTMLInputElement; +const openInOriginalInstanceInput = () => id('open-in-original-instance') as HTMLInputElement; + +function saveOptions(e) { + e.preventDefault(); + browser.storage.local.set({ + searchInstance: _.defaultTo('framatube.org', stripProtocol(searchInstanceInput().value)), + openInOriginalInstance: _.defaultTo(true, openInOriginalInstanceInput().checked), + }); +} + +const stripProtocol = _.replace(/^https?:\/\//, ''); + +function restoreOptions() { + browser.storage.local.get().then(result => { + searchInstanceInput().value = _.defaultTo('framatube.org', result.searchInstance as string); + openInOriginalInstanceInput().checked = _.defaultTo(true, result.openInOriginalInstance as boolean); + }) +} + +document.addEventListener('DOMContentLoaded', restoreOptions); +document.querySelector('form').addEventListener('submit', saveOptions); diff --git a/src/youtube.js b/src/youtube.ts similarity index 93% rename from src/youtube.js rename to src/youtube.ts index 7b1aff4..a59c2b5 100644 --- a/src/youtube.js +++ b/src/youtube.ts @@ -14,14 +14,14 @@ * PeerTubeify. If not, see . */ -import _ from 'lodash/fp'; +import * as _ from 'lodash/fp'; const watchURL = (host, uuid) => `https://${host}/videos/watch/${uuid}`; const thumbnailURL = (host, path) => `https://${host}${path}`; const LINK_ID = 'peertube-link'; -function peertubeify(query) { +function peertubeify(query: string) { browser.runtime.sendMessage({ query }).then(async video => { @@ -40,7 +40,7 @@ function peertubeify(query) { const throttledPeertubify = _.throttle(1000, peertubeify); const observer = new MutationObserver(function(mutationsList) { for (const mutation of mutationsList) { - if (mutation.target.classList.contains('ytp-title-link')) { + if ((mutation.target as Element).classList.contains('ytp-title-link')) { for (const node of mutation.addedNodes) { if (node.nodeType == Node.TEXT_NODE) { throttledPeertubify(node.textContent); @@ -55,10 +55,10 @@ observer.observe(document.body, { subtree: true, }) -function htmlToElement(html) { +function htmlToElement(html: string) : Element { const template = document.createElement('template'); template.innerHTML = html.trim(); - return template.content.firstChild; + return template.content.firstElementChild; } const videoLink = (url, video) => htmlToElement(` diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..b8533fd --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "outDir": "./built", + "allowJs": true, + "target": "es6", + "typeRoots": [ + "node_modules/@types", + "node_modules/web-ext-types" + ] + }, + "include": [ + "./src/**/*" + ] +} diff --git a/webpack.config.js b/webpack.config.js index a8d4f02..c084da2 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -3,9 +3,9 @@ const webpack = require('webpack'); module.exports = { entry: { - background: 'background.js', - youtube: 'youtube.js', - options: [ 'options.js', 'options.html' ], + background: 'background.ts', + youtube: 'youtube.ts', + options: ['options.ts', 'options.html'], }, output: { path: path.join(__dirname, 'extension', 'dist'), @@ -13,8 +13,7 @@ module.exports = { publicPath: '/', }, resolve: { - // This allows you to import modules just like you would in a NodeJS app. - extensions: ['.js'], + extensions: ['.js', '.ts', '.tsx'], modules: [ path.join(__dirname, 'src'), 'node_modules', @@ -22,19 +21,26 @@ module.exports = { }, module: { rules: [{ - test: /\.html$/, - use: [{ - loader: 'file-loader', - options: { - context: 'src', - name: '[path][name].[ext]', + test: /\.html$/, + use: [{ + loader: 'file-loader', + options: { + context: 'src', + name: '[path][name].[ext]', + }, + }, + 'extract-loader', + 'html-loader', + ], + }, + { + test: /\.tsx?$/, + exclude: /node_modules/, + use: { + loader: 'ts-loader', }, - }, { - loader: 'extract-loader' - }, { - loader: 'html-loader', - },], - }] + }, + ], }, plugins: [ // Since some NodeJS modules expect to be running in Node, it is helpful