Template
This commit is contained in:
parent
f3adc8257b
commit
8252949ce9
3
.gitignore
vendored
3
.gitignore
vendored
@ -14,4 +14,5 @@ node_modules/
|
||||
/dist/
|
||||
/builds/*.gz
|
||||
/test/
|
||||
.vscode/launch.json
|
||||
.vscode/launch.json
|
||||
user-script-register
|
||||
29
README.md
29
README.md
@ -1,28 +1 @@
|
||||
# 4chx
|
||||
|
||||
A suckless 4chan X inspired user addon, for image boards. GPL V3.
|
||||
|
||||
## A minimal user addon for 4chan and other like minded imageboards
|
||||
|
||||
Making a minimal style addon for imageboards is a must, as developers come and go on the regular
|
||||
|
||||
No one will really maintain the addon if they either left the site or just don't have the time to maintain it anymore.
|
||||
|
||||
Therefore it's meant to be easily "hackable" for anons to make their own changes/fixes to it
|
||||
|
||||
So if a part breaks then it's not over for the whole project.
|
||||
|
||||
It also combats "bloatware" as each added feature will be made separately, hopefully be one who understands what he is doing so it can be bade as perfect as possible.
|
||||
|
||||
### What will 4chx serve as default?
|
||||
|
||||
These are core features that makes 4chanX, 4chanX
|
||||
|
||||
- Frontend. Header, settings menu, catalog
|
||||
|
||||
- JSON Index. Opens the door for support for future features
|
||||
|
||||
- Notifications. Default notification API for errors, information, etc is a valuable core feature.
|
||||
|
||||
- Drop down menu for post. Default will only have 1 or 2 clickable. Will have an API to add buttons to it.
|
||||
|
||||
# Hello!
|
||||
|
||||
27558
package-lock.json
generated
27558
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
86
package.json
86
package.json
@ -1,6 +1,88 @@
|
||||
{
|
||||
"name": "web-extension-starter",
|
||||
"version": "2.0.0",
|
||||
"description": "Web extension starter using react and typescript",
|
||||
"private": true,
|
||||
"repository": "https://github.com/abhijithvijayan/web-extension-starter.git",
|
||||
"author": {
|
||||
"name": "abhijithvijayan",
|
||||
"email": "goy@goyslop.xyz",
|
||||
"url": "https://goyslop.xyz"
|
||||
},
|
||||
"license": "GPLV3",
|
||||
"engines": {
|
||||
"node": ">=10.0.0",
|
||||
"yarn": ">= 1.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"dev:chrome": "cross-env NODE_ENV=development cross-env TARGET_BROWSER=chrome webpack --watch",
|
||||
"dev:firefox": "cross-env NODE_ENV=development cross-env TARGET_BROWSER=firefox webpack --watch",
|
||||
"dev:opera": "cross-env NODE_ENV=development cross-env TARGET_BROWSER=opera webpack --watch",
|
||||
"build:chrome": "cross-env NODE_ENV=production cross-env TARGET_BROWSER=chrome webpack",
|
||||
"build:firefox": "cross-env NODE_ENV=production cross-env TARGET_BROWSER=firefox webpack",
|
||||
"build:opera": "cross-env NODE_ENV=production cross-env TARGET_BROWSER=opera webpack",
|
||||
"build": "yarn run build:chrome && yarn run build:firefox && yarn run build:opera",
|
||||
"lint": "eslint . --ext .ts,.tsx",
|
||||
"lint:fix": "eslint . --ext .ts,.tsx --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.14.0",
|
||||
"advanced-css-reset": "^1.2.2",
|
||||
"emoji-log": "^1.0.2",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"webext-base-css": "^1.3.1",
|
||||
"webextension-polyfill-ts": "^0.25.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"react": "^18.2.0",
|
||||
"typescript": "^4.9.5"
|
||||
"@abhijithvijayan/eslint-config": "2.6.3",
|
||||
"@abhijithvijayan/eslint-config-airbnb": "^1.0.2",
|
||||
"@abhijithvijayan/tsconfig": "^1.3.0",
|
||||
"@babel/core": "^7.14.3",
|
||||
"@babel/eslint-parser": "^7.12.16",
|
||||
"@babel/plugin-proposal-class-properties": "^7.13.0",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.14.2",
|
||||
"@babel/plugin-transform-destructuring": "^7.13.17",
|
||||
"@babel/plugin-transform-runtime": "^7.14.3",
|
||||
"@babel/preset-env": "^7.14.2",
|
||||
"@babel/preset-react": "^7.13.13",
|
||||
"@babel/preset-typescript": "^7.13.0",
|
||||
"@types/react": "^17.0.6",
|
||||
"@types/react-dom": "^17.0.5",
|
||||
"@types/webpack": "^4.41.29",
|
||||
"@typescript-eslint/eslint-plugin": "^4.4.1",
|
||||
"@typescript-eslint/parser": "^4.4.1",
|
||||
"autoprefixer": "^10.2.5",
|
||||
"babel-loader": "^8.2.2",
|
||||
"clean-webpack-plugin": "^3.0.0",
|
||||
"copy-webpack-plugin": "^6.4.1",
|
||||
"cross-env": "^7.0.3",
|
||||
"css-loader": "^5.2.5",
|
||||
"eslint": "^7.27.0",
|
||||
"eslint-config-prettier": "^6.15.0",
|
||||
"eslint-plugin-import": "^2.23.3",
|
||||
"eslint-plugin-jsx-a11y": "^6.4.1",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-prettier": "^3.4.0",
|
||||
"eslint-plugin-react": "^7.23.2",
|
||||
"eslint-plugin-react-hooks": "^4.2.0",
|
||||
"filemanager-webpack-plugin": "^3.1.1",
|
||||
"fork-ts-checker-webpack-plugin": "^6.2.10",
|
||||
"html-webpack-plugin": "^4.5.2",
|
||||
"mini-css-extract-plugin": "^1.6.0",
|
||||
"optimize-css-assets-webpack-plugin": "^5.0.6",
|
||||
"postcss": "^8.3.0",
|
||||
"postcss-loader": "^4.3.0",
|
||||
"prettier": "^2.3.0",
|
||||
"resolve-url-loader": "^3.1.3",
|
||||
"sass": "^1.53.0",
|
||||
"sass-loader": "^10.2.0",
|
||||
"terser-webpack-plugin": "^4.2.3",
|
||||
"typescript": "4.1.5",
|
||||
"webpack": "^4.46.0",
|
||||
"webpack-cli": "^4.7.0",
|
||||
"webpack-extension-reloader": "^1.1.4",
|
||||
"wext-manifest-loader": "^2.3.0",
|
||||
"wext-manifest-webpack-plugin": "^1.2.1"
|
||||
}
|
||||
}
|
||||
|
||||
6
source/Background/index.ts
Normal file
6
source/Background/index.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import 'emoji-log';
|
||||
import {browser} from 'webextension-polyfill-ts';
|
||||
|
||||
browser.runtime.onInstalled.addListener((): void => {
|
||||
console.emoji('🦄', 'extension installed');
|
||||
});
|
||||
3
source/ContentScript/index.ts
Normal file
3
source/ContentScript/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
console.log('helloworld from content script');
|
||||
|
||||
export {};
|
||||
34
source/Options/Options.tsx
Normal file
34
source/Options/Options.tsx
Normal file
@ -0,0 +1,34 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import './styles.scss';
|
||||
|
||||
const Options: React.FC = () => {
|
||||
return (
|
||||
<div>
|
||||
<form>
|
||||
<p>
|
||||
<label htmlFor="username">Your Name</label>
|
||||
<br />
|
||||
<input
|
||||
type="text"
|
||||
id="username"
|
||||
name="username"
|
||||
spellCheck="false"
|
||||
autoComplete="off"
|
||||
required
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<label htmlFor="logging">
|
||||
<input type="checkbox" name="logging" /> Show the features enabled
|
||||
on each page in the console
|
||||
</label>
|
||||
|
||||
<p>cool cool cool</p>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Options;
|
||||
6
source/Options/index.tsx
Normal file
6
source/Options/index.tsx
Normal file
@ -0,0 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import Options from './Options';
|
||||
|
||||
ReactDOM.render(<Options />, document.getElementById('options-root'));
|
||||
10
source/Options/styles.scss
Normal file
10
source/Options/styles.scss
Normal file
@ -0,0 +1,10 @@
|
||||
@import "../styles/fonts";
|
||||
@import "../styles/reset";
|
||||
@import "../styles/variables";
|
||||
|
||||
@import "~webext-base-css/webext-base.css";
|
||||
|
||||
body {
|
||||
color: $black;
|
||||
background-color: $greyWhite;
|
||||
}
|
||||
55
source/Popup/Popup.tsx
Normal file
55
source/Popup/Popup.tsx
Normal file
@ -0,0 +1,55 @@
|
||||
import * as React from 'react';
|
||||
import {browser, Tabs} from 'webextension-polyfill-ts';
|
||||
|
||||
import './styles.scss';
|
||||
|
||||
function openWebPage(url: string): Promise<Tabs.Tab> {
|
||||
return browser.tabs.create({url});
|
||||
}
|
||||
|
||||
const Popup: React.FC = () => {
|
||||
return (
|
||||
<section id="popup">
|
||||
<h2>WEB-EXTENSION-STARTER</h2>
|
||||
<button
|
||||
id="options__button"
|
||||
type="button"
|
||||
onClick={(): Promise<Tabs.Tab> => {
|
||||
return openWebPage('options.html');
|
||||
}}
|
||||
>
|
||||
Options Page
|
||||
</button>
|
||||
<div className="links__holder">
|
||||
<ul>
|
||||
<li>
|
||||
<button
|
||||
type="button"
|
||||
onClick={(): Promise<Tabs.Tab> => {
|
||||
return openWebPage(
|
||||
'https://github.com/abhijithvijayan/web-extension-starter'
|
||||
);
|
||||
}}
|
||||
>
|
||||
GitHub
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button
|
||||
type="button"
|
||||
onClick={(): Promise<Tabs.Tab> => {
|
||||
return openWebPage(
|
||||
'https://www.buymeacoffee.com/abhijithvijayan'
|
||||
);
|
||||
}}
|
||||
>
|
||||
Buy Me A Coffee
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Popup;
|
||||
6
source/Popup/index.tsx
Normal file
6
source/Popup/index.tsx
Normal file
@ -0,0 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import Popup from './Popup';
|
||||
|
||||
ReactDOM.render(<Popup />, document.getElementById('popup-root'));
|
||||
53
source/Popup/styles.scss
Normal file
53
source/Popup/styles.scss
Normal file
@ -0,0 +1,53 @@
|
||||
@import "../styles/fonts";
|
||||
@import "../styles/reset";
|
||||
@import "../styles/variables";
|
||||
|
||||
body {
|
||||
color: $black;
|
||||
background-color: $greyWhite;
|
||||
}
|
||||
|
||||
|
||||
#popup {
|
||||
min-width: 350px;
|
||||
padding: 30px 20px;
|
||||
|
||||
h2 {
|
||||
font-size: 25px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#options__button {
|
||||
width: 50%;
|
||||
background: green;
|
||||
color: white;
|
||||
font-weight: 500;
|
||||
border-radius: 15px;
|
||||
padding: 5px 10px;
|
||||
justify-content: center;
|
||||
margin: 20px auto;
|
||||
cursor: pointer;
|
||||
opacity: 0.8;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.links__holder {
|
||||
ul {
|
||||
display: flex;
|
||||
margin-top: 1em;
|
||||
justify-content: space-around;
|
||||
|
||||
li {
|
||||
button {
|
||||
border-radius: 25px;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
padding: 10px 17px;
|
||||
background-color: rgba(0, 0, 255, 0.7);
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
source/assets/icons/favicon-128.png
Normal file
BIN
source/assets/icons/favicon-128.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
BIN
source/assets/icons/favicon-16.png
Normal file
BIN
source/assets/icons/favicon-16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
BIN
source/assets/icons/favicon-32.png
Normal file
BIN
source/assets/icons/favicon-32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
BIN
source/assets/icons/favicon-48.png
Normal file
BIN
source/assets/icons/favicon-48.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
79
source/manifest.json
Normal file
79
source/manifest.json
Normal file
@ -0,0 +1,79 @@
|
||||
{
|
||||
"manifest_version": 2,
|
||||
"name": "Sample WebExtension",
|
||||
"version": "0.0.0",
|
||||
|
||||
"icons": {
|
||||
"16": "assets/icons/favicon-16.png",
|
||||
"32": "assets/icons/favicon-32.png",
|
||||
"48": "assets/icons/favicon-48.png",
|
||||
"128": "assets/icons/favicon-128.png"
|
||||
},
|
||||
"description": "Sample description",
|
||||
"homepage_url": "https://github.com/abhijithvijayan/web-extension-starter",
|
||||
"short_name": "Sample Name",
|
||||
|
||||
"permissions": [
|
||||
"activeTab",
|
||||
"storage",
|
||||
"http://www.4chan.org/*",
|
||||
"https://www.4chan.org/*",
|
||||
"http://boards.4channel.org/*",
|
||||
"https://boards.4channel.org/*"
|
||||
],
|
||||
|
||||
"content_security_policy": "script-src 'self'; object-src 'self'",
|
||||
|
||||
"__chrome|firefox__author": "abhijithvijayan",
|
||||
"__opera__developer": {
|
||||
"name": "abhijithvijayan"
|
||||
},
|
||||
|
||||
"__firefox__applications": {
|
||||
"gecko": {
|
||||
"id": "{754FB1AD-CC3B-4856-B6A0-7786F8CA9D17}"
|
||||
}
|
||||
},
|
||||
|
||||
"__chrome__minimum_chrome_version": "49",
|
||||
"__opera__minimum_opera_version": "36",
|
||||
|
||||
"browser_action": {
|
||||
"default_popup": "popup.html",
|
||||
"default_icon": {
|
||||
"16": "assets/icons/favicon-16.png",
|
||||
"32": "assets/icons/favicon-32.png",
|
||||
"48": "assets/icons/favicon-48.png",
|
||||
"128": "assets/icons/favicon-128.png"
|
||||
},
|
||||
"default_title": "tiny title",
|
||||
"__chrome|opera__chrome_style": false,
|
||||
"__firefox__browser_style": false
|
||||
},
|
||||
|
||||
"__chrome|opera__options_page": "options.html",
|
||||
"options_ui": {
|
||||
"page": "options.html",
|
||||
"open_in_tab": true,
|
||||
"__chrome__chrome_style": false
|
||||
},
|
||||
|
||||
"background": {
|
||||
"scripts": [
|
||||
"js/background.bundle.js"
|
||||
],
|
||||
"__chrome|opera__persistent": false
|
||||
},
|
||||
|
||||
"content_scripts": [{
|
||||
"matches": [
|
||||
"http://www.4chan.org/*",
|
||||
"https://www.4chan.org/*",
|
||||
"http://boards.4channel.org/*",
|
||||
"https://boards.4channel.org/*"
|
||||
],
|
||||
"js": [
|
||||
"js/contentScript.bundle.js"
|
||||
]
|
||||
}]
|
||||
}
|
||||
1
source/styles/_fonts.scss
Normal file
1
source/styles/_fonts.scss
Normal file
@ -0,0 +1 @@
|
||||
@import url("https://fonts.googleapis.com/css?family=Nunito:400,600");
|
||||
10
source/styles/_reset.scss
Normal file
10
source/styles/_reset.scss
Normal file
@ -0,0 +1,10 @@
|
||||
@import '~advanced-css-reset/dist/reset.css';
|
||||
|
||||
// Add your custom reset rules here
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
}
|
||||
23
source/styles/_variables.scss
Normal file
23
source/styles/_variables.scss
Normal file
@ -0,0 +1,23 @@
|
||||
// colors
|
||||
$black: #0d0d0d;
|
||||
$greyWhite: #f3f3f3;
|
||||
$skyBlue: #8892b0;
|
||||
|
||||
// fonts
|
||||
$nunito: "Nunito", sans-serif;
|
||||
|
||||
// font weights
|
||||
$thin: 100;
|
||||
$exlight: 200;
|
||||
$light: 300;
|
||||
$regular: 400;
|
||||
$medium: 500;
|
||||
$semibold: 600;
|
||||
$bold: 700;
|
||||
$exbold: 800;
|
||||
$exblack: 900;
|
||||
|
||||
// other variables
|
||||
.d-none {
|
||||
display: none !important;
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
p {
|
||||
color: red;
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<link rel="stylesheet" type="text/css" href="../css/style.css">
|
||||
<html>
|
||||
<p>Penis</p>
|
||||
</html>
|
||||
@ -1,5 +0,0 @@
|
||||
const world = 'World';
|
||||
|
||||
export function hello(who: string = world): string {
|
||||
return `Hello ${who}! `;
|
||||
}
|
||||
120
tsconfig.json
120
tsconfig.json
@ -1,103 +1,21 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
/* Visit https://aka.ms/tsconfig to read more about this file */
|
||||
|
||||
/* Projects */
|
||||
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
|
||||
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
||||
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
|
||||
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
|
||||
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
||||
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
||||
|
||||
/* Language and Environment */
|
||||
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
||||
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
||||
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
||||
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
||||
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
|
||||
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
||||
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
|
||||
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
|
||||
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
||||
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
||||
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
|
||||
|
||||
/* Modules */
|
||||
"module": "commonjs", /* Specify what module code is generated. */
|
||||
// "rootDir": "./", /* Specify the root folder within your source files. */
|
||||
// "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
|
||||
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
||||
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
|
||||
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
|
||||
// "resolveJsonModule": true, /* Enable importing .json files. */
|
||||
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
|
||||
|
||||
/* JavaScript Support */
|
||||
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
|
||||
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
||||
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
|
||||
|
||||
/* Emit */
|
||||
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
||||
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
||||
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
||||
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
||||
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
|
||||
// "outDir": "./", /* Specify an output folder for all emitted files. */
|
||||
// "removeComments": true, /* Disable emitting comments. */
|
||||
// "noEmit": true, /* Disable emitting files from a compilation. */
|
||||
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
||||
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
|
||||
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
||||
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
||||
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
|
||||
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
|
||||
// "newLine": "crlf", /* Set the newline character for emitting files. */
|
||||
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
|
||||
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
|
||||
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
|
||||
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
|
||||
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
||||
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
|
||||
|
||||
/* Interop Constraints */
|
||||
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
|
||||
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
|
||||
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
||||
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
|
||||
|
||||
/* Type Checking */
|
||||
"strict": true, /* Enable all strict type-checking options. */
|
||||
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
|
||||
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
||||
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
|
||||
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
||||
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
|
||||
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
|
||||
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
|
||||
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
|
||||
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
||||
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
||||
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
|
||||
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
||||
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
|
||||
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
||||
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
||||
|
||||
/* Completeness */
|
||||
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
||||
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||
}
|
||||
"extends": "@abhijithvijayan/tsconfig",
|
||||
"compilerOptions": {
|
||||
"target": "es5", // ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'.
|
||||
"module": "esnext", // Module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'.
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"declaration": false,
|
||||
"isolatedModules": true,
|
||||
/* Additional Checks */
|
||||
"useDefineForClassFields": true,
|
||||
"skipLibCheck": true,
|
||||
},
|
||||
"include": [
|
||||
"source",
|
||||
"webpack.config.js"
|
||||
]
|
||||
}
|
||||
|
||||
11
views/options.html
Normal file
11
views/options.html
Normal file
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Options</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="options-root"></div>
|
||||
</body>
|
||||
</html>
|
||||
11
views/popup.html
Normal file
11
views/popup.html
Normal file
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=500" />
|
||||
<title>Popup</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="popup-root"></div>
|
||||
</body>
|
||||
</html>
|
||||
211
webpack.config.js
Normal file
211
webpack.config.js
Normal file
@ -0,0 +1,211 @@
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const FilemanagerPlugin = require('filemanager-webpack-plugin');
|
||||
const TerserPlugin = require('terser-webpack-plugin');
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
|
||||
const ExtensionReloader = require('webpack-extension-reloader');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const WextManifestWebpackPlugin = require('wext-manifest-webpack-plugin');
|
||||
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
|
||||
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
|
||||
|
||||
const viewsPath = path.join(__dirname, 'views');
|
||||
const sourcePath = path.join(__dirname, 'source');
|
||||
const destPath = path.join(__dirname, 'extension');
|
||||
const nodeEnv = process.env.NODE_ENV || 'development';
|
||||
const targetBrowser = process.env.TARGET_BROWSER;
|
||||
|
||||
const extensionReloaderPlugin =
|
||||
nodeEnv === 'development'
|
||||
? new ExtensionReloader({
|
||||
port: 9090,
|
||||
reloadPage: true,
|
||||
entries: {
|
||||
// TODO: reload manifest on update
|
||||
contentScript: 'contentScript',
|
||||
background: 'background',
|
||||
extensionPage: ['popup', 'options'],
|
||||
},
|
||||
})
|
||||
: () => {
|
||||
this.apply = () => {};
|
||||
};
|
||||
|
||||
const getExtensionFileType = (browser) => {
|
||||
if (browser === 'opera') {
|
||||
return 'crx';
|
||||
}
|
||||
|
||||
if (browser === 'firefox') {
|
||||
return 'xpi';
|
||||
}
|
||||
|
||||
return 'zip';
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
devtool: false, // https://github.com/webpack/webpack/issues/1194#issuecomment-560382342
|
||||
|
||||
stats: {
|
||||
all: false,
|
||||
builtAt: true,
|
||||
errors: true,
|
||||
hash: true,
|
||||
},
|
||||
|
||||
mode: nodeEnv,
|
||||
|
||||
entry: {
|
||||
manifest: path.join(sourcePath, 'manifest.json'),
|
||||
background: path.join(sourcePath, 'Background', 'index.ts'),
|
||||
contentScript: path.join(sourcePath, 'ContentScript', 'index.ts'),
|
||||
popup: path.join(sourcePath, 'Popup', 'index.tsx'),
|
||||
options: path.join(sourcePath, 'Options', 'index.tsx'),
|
||||
},
|
||||
|
||||
output: {
|
||||
path: path.join(destPath, targetBrowser),
|
||||
filename: 'js/[name].bundle.js',
|
||||
},
|
||||
|
||||
resolve: {
|
||||
extensions: ['.ts', '.tsx', '.js', '.json'],
|
||||
alias: {
|
||||
'webextension-polyfill-ts': path.resolve(
|
||||
path.join(__dirname, 'node_modules', 'webextension-polyfill-ts')
|
||||
),
|
||||
},
|
||||
},
|
||||
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
type: 'javascript/auto', // prevent webpack handling json with its own loaders,
|
||||
test: /manifest\.json$/,
|
||||
use: {
|
||||
loader: 'wext-manifest-loader',
|
||||
options: {
|
||||
usePackageJSONVersion: true, // set to false to not use package.json version for manifest
|
||||
},
|
||||
},
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
{
|
||||
test: /\.(js|ts)x?$/,
|
||||
loader: 'babel-loader',
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
{
|
||||
test: /\.(sa|sc|c)ss$/,
|
||||
use: [
|
||||
{
|
||||
loader: MiniCssExtractPlugin.loader, // It creates a CSS file per JS file which contains CSS
|
||||
},
|
||||
{
|
||||
loader: 'css-loader', // Takes the CSS files and returns the CSS with imports and url(...) for Webpack
|
||||
options: {
|
||||
sourceMap: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
[
|
||||
'autoprefixer',
|
||||
{
|
||||
// Options
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
'resolve-url-loader', // Rewrites relative paths in url() statements
|
||||
'sass-loader', // Takes the Sass/SCSS file and compiles to the CSS
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
plugins: [
|
||||
// Plugin to not generate js bundle for manifest entry
|
||||
new WextManifestWebpackPlugin(),
|
||||
// Generate sourcemaps
|
||||
new webpack.SourceMapDevToolPlugin({filename: false}),
|
||||
new ForkTsCheckerWebpackPlugin(),
|
||||
// environmental variables
|
||||
new webpack.EnvironmentPlugin(['NODE_ENV', 'TARGET_BROWSER']),
|
||||
// delete previous build files
|
||||
new CleanWebpackPlugin({
|
||||
cleanOnceBeforeBuildPatterns: [
|
||||
path.join(process.cwd(), `extension/${targetBrowser}`),
|
||||
path.join(
|
||||
process.cwd(),
|
||||
`extension/${targetBrowser}.${getExtensionFileType(targetBrowser)}`
|
||||
),
|
||||
],
|
||||
cleanStaleWebpackAssets: false,
|
||||
verbose: true,
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
template: path.join(viewsPath, 'popup.html'),
|
||||
inject: 'body',
|
||||
chunks: ['popup'],
|
||||
hash: true,
|
||||
filename: 'popup.html',
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
template: path.join(viewsPath, 'options.html'),
|
||||
inject: 'body',
|
||||
chunks: ['options'],
|
||||
hash: true,
|
||||
filename: 'options.html',
|
||||
}),
|
||||
// write css file(s) to build folder
|
||||
new MiniCssExtractPlugin({filename: 'css/[name].css'}),
|
||||
// copy static assets
|
||||
new CopyWebpackPlugin({
|
||||
patterns: [{from: 'source/assets', to: 'assets'}],
|
||||
}),
|
||||
// plugin to enable browser reloading in development mode
|
||||
extensionReloaderPlugin,
|
||||
],
|
||||
|
||||
optimization: {
|
||||
minimize: true,
|
||||
minimizer: [
|
||||
new TerserPlugin({
|
||||
parallel: true,
|
||||
terserOptions: {
|
||||
format: {
|
||||
comments: false,
|
||||
},
|
||||
},
|
||||
extractComments: false,
|
||||
}),
|
||||
new OptimizeCSSAssetsPlugin({
|
||||
cssProcessorPluginOptions: {
|
||||
preset: ['default', {discardComments: {removeAll: true}}],
|
||||
},
|
||||
}),
|
||||
new FilemanagerPlugin({
|
||||
events: {
|
||||
onEnd: {
|
||||
archive: [
|
||||
{
|
||||
format: 'zip',
|
||||
source: path.join(destPath, targetBrowser),
|
||||
destination: `${path.join(destPath, targetBrowser)}.${getExtensionFileType(targetBrowser)}`,
|
||||
options: {zlib: {level: 6}},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
}),
|
||||
],
|
||||
},
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user