backing up
This commit is contained in:
commit
af881ecaec
24 changed files with 9449 additions and 0 deletions
30
.github/workflows/build.yml
vendored
Normal file
30
.github/workflows/build.yml
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
|
||||
|
||||
name: build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [16.x, 18.x]
|
||||
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: npm ci
|
||||
- run: npm run build --if-present
|
||||
- run: npm test
|
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
npm-debug.log
|
||||
node_modules/
|
||||
dist/
|
||||
tmp/
|
14
.vscode/settings.json
vendored
Normal file
14
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"copyrighter.author": "R3BL LLC",
|
||||
"copyrighter.license": "MIT",
|
||||
"typescript.tsdk": "./node_modules/typescript/lib",
|
||||
"files.eol": "\n",
|
||||
"json.schemas": [
|
||||
{
|
||||
"fileMatch": [
|
||||
"/manifest.json"
|
||||
],
|
||||
"url": "http://json.schemastore.org/chrome-manifest"
|
||||
}
|
||||
]
|
||||
}
|
33
.vscode/tasks.json
vendored
Normal file
33
.vscode/tasks.json
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"command": "npm",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "install",
|
||||
"type": "shell",
|
||||
"command": "npm",
|
||||
"args": ["install"]
|
||||
},
|
||||
{
|
||||
"label": "update",
|
||||
"type": "shell",
|
||||
"command": "npm",
|
||||
"args": ["update"]
|
||||
},
|
||||
{
|
||||
"label": "test",
|
||||
"type": "shell",
|
||||
"command": "npm",
|
||||
"args": ["run", "test"]
|
||||
},
|
||||
{
|
||||
"label": "build",
|
||||
"type": "shell",
|
||||
"group": "build",
|
||||
"command": "npm",
|
||||
"args": ["run", "watch"]
|
||||
}
|
||||
]
|
||||
}
|
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2018 Tomofumi Chiba
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
84
README.md
Normal file
84
README.md
Normal file
|
@ -0,0 +1,84 @@
|
|||
# Chrome extension template repo written in Typescript and React.
|
||||
|
||||
Table of contents:
|
||||
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Option](#option)
|
||||
- [Includes the following](#includes-the-following)
|
||||
- [Project Structure](#project-structure)
|
||||
- [Setup](#setup)
|
||||
- [Open in Visual Studio Code](#open-in-visual-studio-code)
|
||||
- [Build](#build)
|
||||
- [Build in watch mode](#build-in-watch-mode)
|
||||
- [terminal](#terminal)
|
||||
- [Visual Studio Code](#visual-studio-code)
|
||||
- [Load extension to chrome](#load-extension-to-chrome)
|
||||
- [Test](#test)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [node + npm](https://nodejs.org/) (Current Version)
|
||||
|
||||
## Option
|
||||
|
||||
- [Visual Studio Code](https://code.visualstudio.com/)
|
||||
|
||||
## Includes the following
|
||||
|
||||
- TypeScript
|
||||
- Webpack
|
||||
- React
|
||||
- Jest
|
||||
- Code
|
||||
- Chrome Storage
|
||||
- Badge number
|
||||
- Background script
|
||||
|
||||
## Project Structure
|
||||
|
||||
| Folder | Description |
|
||||
| ------------ | -------------------------- |
|
||||
| `src/` | TypeScript source files |
|
||||
| `public/` | static files |
|
||||
| `dist` | Chrome Extension directory |
|
||||
| `dist/js` | Generated JavaScript files |
|
||||
|
||||
|
||||
## Setup
|
||||
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
## Build
|
||||
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
## Build in watch mode
|
||||
|
||||
### terminal
|
||||
|
||||
```
|
||||
npm run watch
|
||||
```
|
||||
|
||||
### Visual Studio Code
|
||||
|
||||
Run watch mode.
|
||||
|
||||
type `Ctrl + Shift + B`
|
||||
|
||||
## Load extension to chrome
|
||||
|
||||
Load `dist` directory.
|
||||
|
||||
## Test
|
||||
|
||||
Run `npx jest` or `npm run test`.
|
8001
package-lock.json
generated
Normal file
8001
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
47
package.json
Normal file
47
package.json
Normal file
|
@ -0,0 +1,47 @@
|
|||
{
|
||||
"name": "faex",
|
||||
"version": "1.0.0",
|
||||
"description": "FurAFfinity Gallery Exporter",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build:watch": "webpack --config webpack/webpack.dev.js --watch",
|
||||
"tailwind:watch": "npx tailwindcss -i ./src/styles/tailwind.css -o ./public/styles.css --watch",
|
||||
"build": "webpack --config webpack/webpack.prod.js",
|
||||
"tailwind": "npx tailwindcss -i ./src/styles/tailwind.css -o ./public/styles.css",
|
||||
"clean": "rimraf dist",
|
||||
"test": "npx jest",
|
||||
"style": "prettier --write \"src/**/*.{ts,tsx}\"",
|
||||
"update-all-deps": "npm update --save"
|
||||
},
|
||||
"author": "R3BL LLC",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/chibat/chrome-extension-typescript-starter.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/chrome": "^0.0.240",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.5.2",
|
||||
"@types/react": "^18.2.14",
|
||||
"@types/react-dom": "^18.2.6",
|
||||
"copy-webpack-plugin": "^9.1.0",
|
||||
"css-loader": "^7.1.2",
|
||||
"glob": "^7.2.3",
|
||||
"jest": "^29.6.1",
|
||||
"prettier": "^2.8.8",
|
||||
"rimraf": "^3.0.2",
|
||||
"style-loader": "^4.0.0",
|
||||
"tailwindcss": "^3.4.8",
|
||||
"ts-jest": "^29.1.1",
|
||||
"ts-loader": "^8.4.0",
|
||||
"typescript": "^5.1.6",
|
||||
"webpack": "^5.93.0",
|
||||
"webpack-cli": "^4.10.0",
|
||||
"webpack-dev-server": "^5.0.4",
|
||||
"webpack-merge": "^5.9.0"
|
||||
}
|
||||
}
|
BIN
public/icon.png
Normal file
BIN
public/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
36
public/manifest.json
Normal file
36
public/manifest.json
Normal file
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"manifest_version": 3,
|
||||
"name": "FAEX",
|
||||
"description": "FurAFfinity Gallery Exporter",
|
||||
"version": "1.0",
|
||||
"options_ui": {
|
||||
"page": "options.html",
|
||||
"open_in_tab": true
|
||||
},
|
||||
"action": {
|
||||
"default_icon": {
|
||||
"16": "icon.png"
|
||||
},
|
||||
"default_popup": "popup.html"
|
||||
},
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": [
|
||||
"*://*.furaffinity.net/*"
|
||||
],
|
||||
"js": [
|
||||
"js/vendor.js",
|
||||
"js/content_script.js"
|
||||
]
|
||||
}
|
||||
],
|
||||
"background": {
|
||||
"service_worker": "js/background.js"
|
||||
},
|
||||
"permissions": [
|
||||
"storage", "cookies"
|
||||
],
|
||||
"host_permissions": [
|
||||
"*://*.furaffinity.net/*"
|
||||
]
|
||||
}
|
14
public/options.html
Normal file
14
public/options.html
Normal file
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>FAEX Options</title>
|
||||
<script src="js/vendor.js"></script>
|
||||
<link id="js-style" type="text/css" href="styles.css" rel="stylesheet">
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script src="js/options.js"></script>
|
||||
</body>
|
||||
</html>
|
14
public/popup.html
Normal file
14
public/popup.html
Normal file
|
@ -0,0 +1,14 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Getting Started Extension's Popup</title>
|
||||
<script src="js/vendor.js"></script>
|
||||
<link href="./styles.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script src="js/popup.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
803
public/styles.css
Normal file
803
public/styles.css
Normal file
|
@ -0,0 +1,803 @@
|
|||
/*
|
||||
! tailwindcss v3.4.8 | MIT License | https://tailwindcss.com
|
||||
*/
|
||||
|
||||
/*
|
||||
1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
|
||||
2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
|
||||
*/
|
||||
|
||||
*,
|
||||
::before,
|
||||
::after {
|
||||
box-sizing: border-box;
|
||||
/* 1 */
|
||||
border-width: 0;
|
||||
/* 2 */
|
||||
border-style: solid;
|
||||
/* 2 */
|
||||
border-color: #e5e7eb;
|
||||
/* 2 */
|
||||
}
|
||||
|
||||
::before,
|
||||
::after {
|
||||
--tw-content: '';
|
||||
}
|
||||
|
||||
/*
|
||||
1. Use a consistent sensible line-height in all browsers.
|
||||
2. Prevent adjustments of font size after orientation changes in iOS.
|
||||
3. Use a more readable tab size.
|
||||
4. Use the user's configured `sans` font-family by default.
|
||||
5. Use the user's configured `sans` font-feature-settings by default.
|
||||
6. Use the user's configured `sans` font-variation-settings by default.
|
||||
7. Disable tap highlights on iOS
|
||||
*/
|
||||
|
||||
html,
|
||||
:host {
|
||||
line-height: 1.5;
|
||||
/* 1 */
|
||||
-webkit-text-size-adjust: 100%;
|
||||
/* 2 */
|
||||
-moz-tab-size: 4;
|
||||
/* 3 */
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
/* 3 */
|
||||
font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
/* 4 */
|
||||
font-feature-settings: normal;
|
||||
/* 5 */
|
||||
font-variation-settings: normal;
|
||||
/* 6 */
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
/* 7 */
|
||||
}
|
||||
|
||||
/*
|
||||
1. Remove the margin in all browsers.
|
||||
2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
|
||||
*/
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
/* 1 */
|
||||
line-height: inherit;
|
||||
/* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
1. Add the correct height in Firefox.
|
||||
2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
|
||||
3. Ensure horizontal rules are visible by default.
|
||||
*/
|
||||
|
||||
hr {
|
||||
height: 0;
|
||||
/* 1 */
|
||||
color: inherit;
|
||||
/* 2 */
|
||||
border-top-width: 1px;
|
||||
/* 3 */
|
||||
}
|
||||
|
||||
/*
|
||||
Add the correct text decoration in Chrome, Edge, and Safari.
|
||||
*/
|
||||
|
||||
abbr:where([title]) {
|
||||
-webkit-text-decoration: underline dotted;
|
||||
text-decoration: underline dotted;
|
||||
}
|
||||
|
||||
/*
|
||||
Remove the default font size and weight for headings.
|
||||
*/
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-size: inherit;
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
/*
|
||||
Reset links to optimize for opt-in styling instead of opt-out.
|
||||
*/
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
|
||||
/*
|
||||
Add the correct font weight in Edge and Safari.
|
||||
*/
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Use the user's configured `mono` font-family by default.
|
||||
2. Use the user's configured `mono` font-feature-settings by default.
|
||||
3. Use the user's configured `mono` font-variation-settings by default.
|
||||
4. Correct the odd `em` font sizing in all browsers.
|
||||
*/
|
||||
|
||||
code,
|
||||
kbd,
|
||||
samp,
|
||||
pre {
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
/* 1 */
|
||||
font-feature-settings: normal;
|
||||
/* 2 */
|
||||
font-variation-settings: normal;
|
||||
/* 3 */
|
||||
font-size: 1em;
|
||||
/* 4 */
|
||||
}
|
||||
|
||||
/*
|
||||
Add the correct font size in all browsers.
|
||||
*/
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
/*
|
||||
Prevent `sub` and `sup` elements from affecting the line height in all browsers.
|
||||
*/
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
|
||||
2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
|
||||
3. Remove gaps between table borders by default.
|
||||
*/
|
||||
|
||||
table {
|
||||
text-indent: 0;
|
||||
/* 1 */
|
||||
border-color: inherit;
|
||||
/* 2 */
|
||||
border-collapse: collapse;
|
||||
/* 3 */
|
||||
}
|
||||
|
||||
/*
|
||||
1. Change the font styles in all browsers.
|
||||
2. Remove the margin in Firefox and Safari.
|
||||
3. Remove default padding in all browsers.
|
||||
*/
|
||||
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
font-family: inherit;
|
||||
/* 1 */
|
||||
font-feature-settings: inherit;
|
||||
/* 1 */
|
||||
font-variation-settings: inherit;
|
||||
/* 1 */
|
||||
font-size: 100%;
|
||||
/* 1 */
|
||||
font-weight: inherit;
|
||||
/* 1 */
|
||||
line-height: inherit;
|
||||
/* 1 */
|
||||
letter-spacing: inherit;
|
||||
/* 1 */
|
||||
color: inherit;
|
||||
/* 1 */
|
||||
margin: 0;
|
||||
/* 2 */
|
||||
padding: 0;
|
||||
/* 3 */
|
||||
}
|
||||
|
||||
/*
|
||||
Remove the inheritance of text transform in Edge and Firefox.
|
||||
*/
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Correct the inability to style clickable types in iOS and Safari.
|
||||
2. Remove default button styles.
|
||||
*/
|
||||
|
||||
button,
|
||||
input:where([type='button']),
|
||||
input:where([type='reset']),
|
||||
input:where([type='submit']) {
|
||||
-webkit-appearance: button;
|
||||
/* 1 */
|
||||
background-color: transparent;
|
||||
/* 2 */
|
||||
background-image: none;
|
||||
/* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
Use the modern Firefox focus style for all focusable elements.
|
||||
*/
|
||||
|
||||
:-moz-focusring {
|
||||
outline: auto;
|
||||
}
|
||||
|
||||
/*
|
||||
Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
|
||||
*/
|
||||
|
||||
:-moz-ui-invalid {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/*
|
||||
Add the correct vertical alignment in Chrome and Firefox.
|
||||
*/
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
/*
|
||||
Correct the cursor style of increment and decrement buttons in Safari.
|
||||
*/
|
||||
|
||||
::-webkit-inner-spin-button,
|
||||
::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Correct the odd appearance in Chrome and Safari.
|
||||
2. Correct the outline style in Safari.
|
||||
*/
|
||||
|
||||
[type='search'] {
|
||||
-webkit-appearance: textfield;
|
||||
/* 1 */
|
||||
outline-offset: -2px;
|
||||
/* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
Remove the inner padding in Chrome and Safari on macOS.
|
||||
*/
|
||||
|
||||
::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Correct the inability to style clickable types in iOS and Safari.
|
||||
2. Change font properties to `inherit` in Safari.
|
||||
*/
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
-webkit-appearance: button;
|
||||
/* 1 */
|
||||
font: inherit;
|
||||
/* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
Add the correct display in Chrome and Safari.
|
||||
*/
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
/*
|
||||
Removes the default spacing and border for appropriate elements.
|
||||
*/
|
||||
|
||||
blockquote,
|
||||
dl,
|
||||
dd,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
hr,
|
||||
figure,
|
||||
p,
|
||||
pre {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
legend {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul,
|
||||
menu {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Reset default styling for dialogs.
|
||||
*/
|
||||
|
||||
dialog {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Prevent resizing textareas horizontally by default.
|
||||
*/
|
||||
|
||||
textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
|
||||
2. Set the default placeholder color to the user's configured gray 400 color.
|
||||
*/
|
||||
|
||||
input::-moz-placeholder, textarea::-moz-placeholder {
|
||||
opacity: 1;
|
||||
/* 1 */
|
||||
color: #9ca3af;
|
||||
/* 2 */
|
||||
}
|
||||
|
||||
input::placeholder,
|
||||
textarea::placeholder {
|
||||
opacity: 1;
|
||||
/* 1 */
|
||||
color: #9ca3af;
|
||||
/* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
Set the default cursor for buttons.
|
||||
*/
|
||||
|
||||
button,
|
||||
[role="button"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/*
|
||||
Make sure disabled buttons don't get the pointer cursor.
|
||||
*/
|
||||
|
||||
:disabled {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
|
||||
2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
|
||||
This can trigger a poorly considered lint error in some tools but is included by design.
|
||||
*/
|
||||
|
||||
img,
|
||||
svg,
|
||||
video,
|
||||
canvas,
|
||||
audio,
|
||||
iframe,
|
||||
embed,
|
||||
object {
|
||||
display: block;
|
||||
/* 1 */
|
||||
vertical-align: middle;
|
||||
/* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
|
||||
*/
|
||||
|
||||
img,
|
||||
video {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/* Make elements with the HTML hidden attribute stay hidden by default */
|
||||
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
*, ::before, ::after {
|
||||
--tw-border-spacing-x: 0;
|
||||
--tw-border-spacing-y: 0;
|
||||
--tw-translate-x: 0;
|
||||
--tw-translate-y: 0;
|
||||
--tw-rotate: 0;
|
||||
--tw-skew-x: 0;
|
||||
--tw-skew-y: 0;
|
||||
--tw-scale-x: 1;
|
||||
--tw-scale-y: 1;
|
||||
--tw-pan-x: ;
|
||||
--tw-pan-y: ;
|
||||
--tw-pinch-zoom: ;
|
||||
--tw-scroll-snap-strictness: proximity;
|
||||
--tw-gradient-from-position: ;
|
||||
--tw-gradient-via-position: ;
|
||||
--tw-gradient-to-position: ;
|
||||
--tw-ordinal: ;
|
||||
--tw-slashed-zero: ;
|
||||
--tw-numeric-figure: ;
|
||||
--tw-numeric-spacing: ;
|
||||
--tw-numeric-fraction: ;
|
||||
--tw-ring-inset: ;
|
||||
--tw-ring-offset-width: 0px;
|
||||
--tw-ring-offset-color: #fff;
|
||||
--tw-ring-color: rgb(59 130 246 / 0.5);
|
||||
--tw-ring-offset-shadow: 0 0 #0000;
|
||||
--tw-ring-shadow: 0 0 #0000;
|
||||
--tw-shadow: 0 0 #0000;
|
||||
--tw-shadow-colored: 0 0 #0000;
|
||||
--tw-blur: ;
|
||||
--tw-brightness: ;
|
||||
--tw-contrast: ;
|
||||
--tw-grayscale: ;
|
||||
--tw-hue-rotate: ;
|
||||
--tw-invert: ;
|
||||
--tw-saturate: ;
|
||||
--tw-sepia: ;
|
||||
--tw-drop-shadow: ;
|
||||
--tw-backdrop-blur: ;
|
||||
--tw-backdrop-brightness: ;
|
||||
--tw-backdrop-contrast: ;
|
||||
--tw-backdrop-grayscale: ;
|
||||
--tw-backdrop-hue-rotate: ;
|
||||
--tw-backdrop-invert: ;
|
||||
--tw-backdrop-opacity: ;
|
||||
--tw-backdrop-saturate: ;
|
||||
--tw-backdrop-sepia: ;
|
||||
--tw-contain-size: ;
|
||||
--tw-contain-layout: ;
|
||||
--tw-contain-paint: ;
|
||||
--tw-contain-style: ;
|
||||
}
|
||||
|
||||
::backdrop {
|
||||
--tw-border-spacing-x: 0;
|
||||
--tw-border-spacing-y: 0;
|
||||
--tw-translate-x: 0;
|
||||
--tw-translate-y: 0;
|
||||
--tw-rotate: 0;
|
||||
--tw-skew-x: 0;
|
||||
--tw-skew-y: 0;
|
||||
--tw-scale-x: 1;
|
||||
--tw-scale-y: 1;
|
||||
--tw-pan-x: ;
|
||||
--tw-pan-y: ;
|
||||
--tw-pinch-zoom: ;
|
||||
--tw-scroll-snap-strictness: proximity;
|
||||
--tw-gradient-from-position: ;
|
||||
--tw-gradient-via-position: ;
|
||||
--tw-gradient-to-position: ;
|
||||
--tw-ordinal: ;
|
||||
--tw-slashed-zero: ;
|
||||
--tw-numeric-figure: ;
|
||||
--tw-numeric-spacing: ;
|
||||
--tw-numeric-fraction: ;
|
||||
--tw-ring-inset: ;
|
||||
--tw-ring-offset-width: 0px;
|
||||
--tw-ring-offset-color: #fff;
|
||||
--tw-ring-color: rgb(59 130 246 / 0.5);
|
||||
--tw-ring-offset-shadow: 0 0 #0000;
|
||||
--tw-ring-shadow: 0 0 #0000;
|
||||
--tw-shadow: 0 0 #0000;
|
||||
--tw-shadow-colored: 0 0 #0000;
|
||||
--tw-blur: ;
|
||||
--tw-brightness: ;
|
||||
--tw-contrast: ;
|
||||
--tw-grayscale: ;
|
||||
--tw-hue-rotate: ;
|
||||
--tw-invert: ;
|
||||
--tw-saturate: ;
|
||||
--tw-sepia: ;
|
||||
--tw-drop-shadow: ;
|
||||
--tw-backdrop-blur: ;
|
||||
--tw-backdrop-brightness: ;
|
||||
--tw-backdrop-contrast: ;
|
||||
--tw-backdrop-grayscale: ;
|
||||
--tw-backdrop-hue-rotate: ;
|
||||
--tw-backdrop-invert: ;
|
||||
--tw-backdrop-opacity: ;
|
||||
--tw-backdrop-saturate: ;
|
||||
--tw-backdrop-sepia: ;
|
||||
--tw-contain-size: ;
|
||||
--tw-contain-layout: ;
|
||||
--tw-contain-paint: ;
|
||||
--tw-contain-style: ;
|
||||
}
|
||||
|
||||
.m-auto {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.m-0 {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.m-1 {
|
||||
margin: 0.25rem;
|
||||
}
|
||||
|
||||
.m-3 {
|
||||
margin: 0.75rem;
|
||||
}
|
||||
|
||||
.m-2 {
|
||||
margin: 0.5rem;
|
||||
}
|
||||
|
||||
.mt-3 {
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
|
||||
.mb-1 {
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.mt-1 {
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
|
||||
.mb-3 {
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.mt-4 {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.mr-1 {
|
||||
margin-right: 0.25rem;
|
||||
}
|
||||
|
||||
.box-border {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.h-\[2px\] {
|
||||
height: 2px;
|
||||
}
|
||||
|
||||
.h-\[5px\] {
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
.h-\[3px\] {
|
||||
height: 3px;
|
||||
}
|
||||
|
||||
.w-\[95\%\] {
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
.w-\[100\%\] {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.max-w-3xl {
|
||||
max-width: 48rem;
|
||||
}
|
||||
|
||||
.flex-col {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.gap-4 {
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.rounded {
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
.border-2 {
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.border-hidden {
|
||||
border-style: hidden;
|
||||
}
|
||||
|
||||
.border-red-400 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(248 113 113 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.border-red-300 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(252 165 165 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.border-yellow-300 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(253 224 71 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.border-gray-300 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(209 213 219 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.bg-gray-200 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(229 231 235 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-yellow-50 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(254 252 232 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-red-200 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(254 202 202 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-red-300 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(252 165 165 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-red-400 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(248 113 113 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-red-100 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(254 226 226 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-yellow-300 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(253 224 71 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-gray-300 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(209 213 219 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-gray-100 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(243 244 246 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-gray-800 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(31 41 55 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.p-2 {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.p-20 {
|
||||
padding: 5rem;
|
||||
}
|
||||
|
||||
.p-3 {
|
||||
padding: 0.75rem;
|
||||
}
|
||||
|
||||
.p-5 {
|
||||
padding: 1.25rem;
|
||||
}
|
||||
|
||||
.p-1 {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.text-2xl {
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
}
|
||||
|
||||
.text-xl {
|
||||
font-size: 1.25rem;
|
||||
line-height: 1.75rem;
|
||||
}
|
||||
|
||||
.text-lg {
|
||||
font-size: 1.125rem;
|
||||
line-height: 1.75rem;
|
||||
}
|
||||
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.font-semibold {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.text-red-400 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(248 113 113 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-blue-700 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(29 78 216 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-black {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(0 0 0 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-gray-950 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(3 7 18 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-gray-50 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(249 250 251 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.placeholder-gray-600::-moz-placeholder {
|
||||
--tw-placeholder-opacity: 1;
|
||||
color: rgb(75 85 99 / var(--tw-placeholder-opacity));
|
||||
}
|
||||
|
||||
.placeholder-gray-600::placeholder {
|
||||
--tw-placeholder-opacity: 1;
|
||||
color: rgb(75 85 99 / var(--tw-placeholder-opacity));
|
||||
}
|
29
src/background.ts
Normal file
29
src/background.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2023 R3BL LLC
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
function polling() {
|
||||
// console.log("polling");
|
||||
setTimeout(polling, 1000 * 30)
|
||||
}
|
||||
|
||||
polling()
|
3
src/content_script.tsx
Normal file
3
src/content_script.tsx
Normal file
|
@ -0,0 +1,3 @@
|
|||
// import { changeBackgroundListener } from "./message_passing"
|
||||
|
||||
// chrome.runtime.onMessage.addListener(changeBackgroundListener)
|
130
src/options.tsx
Normal file
130
src/options.tsx
Normal file
|
@ -0,0 +1,130 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
|
||||
const Options = () => {
|
||||
const [cookieA, setCookieA] = useState<string>("");
|
||||
const [cookieB, setCookieB] = useState<string>("");
|
||||
const [status, setStatus] = useState<string>("");
|
||||
const [grabbedCookies, setGrabbedCookies] = useState<{
|
||||
a?: string;
|
||||
b?: string;
|
||||
}>({ a: undefined, b: undefined });
|
||||
|
||||
const fetchCookies = () => {
|
||||
console.log('fetching cookies')
|
||||
chrome.cookies.getAllCookieStores().then((stores) => {
|
||||
stores.forEach((store) => {
|
||||
chrome.cookies.getAll({ storeId: store.id }, (cookies) => {
|
||||
cookies.forEach((cookie) => {
|
||||
if (cookie.name === "a") {
|
||||
setCookieA(cookie.value);
|
||||
setGrabbedCookies({ ...grabbedCookies, a: cookie.value });
|
||||
}
|
||||
if (cookie.name === "b") {
|
||||
setCookieB(cookie.value);
|
||||
setGrabbedCookies({ ...grabbedCookies, b: cookie.value });
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
const saveCookies = () => {
|
||||
// Saves options to chrome.storage.sync.
|
||||
chrome.storage.sync.set(
|
||||
{
|
||||
FAEX_a: cookieA,
|
||||
FAEX_b: cookieB,
|
||||
},
|
||||
() => {
|
||||
// Update status to let user know options were saved.
|
||||
setStatus("Options saved.");
|
||||
const id = setTimeout(() => {
|
||||
setStatus("");
|
||||
}, 1000);
|
||||
return () => clearTimeout(id);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="p-20 w-[95%] max-w-3xl m-auto">
|
||||
<div className="logo text-center">
|
||||
<ruby className="text-xl">
|
||||
FurAffinity Exporter <rt className="text-2xl">FAEX</rt>
|
||||
</ruby>
|
||||
</div>
|
||||
<div id="settings" className="mt-3 bg-gray-100 p-5 rounded">
|
||||
<h1 className="text-xl">Extension Settings</h1>
|
||||
<p>
|
||||
To use the Extension, you need to provide it with your FurAffinity
|
||||
Cookies.
|
||||
</p>
|
||||
<p>
|
||||
<a className="text-blue-700" href="http://">
|
||||
Click here
|
||||
</a>{" "}
|
||||
to find out how they're used
|
||||
</p>
|
||||
<br />
|
||||
<p>
|
||||
Follow{" "}
|
||||
<a className="text-blue-700" href="http://">
|
||||
this guide
|
||||
</a>
|
||||
, if you want to get them manually.
|
||||
</p>
|
||||
<p>
|
||||
You can also click on the <kbd className="p-1 bg-gray-300">Fetch Cookies</kbd> Button below to
|
||||
fill them automatically.
|
||||
</p>
|
||||
<br />
|
||||
<p>Once they're in the Fields, press the <kbd className="p-1 bg-gray-300">Save Cookies</kbd> Button to save them for the future.</p>
|
||||
<hr className="mt-3 mb-3 h-[3px] m-0 w-[100%] border-hidden bg-gray-200" />
|
||||
<div id="inputs" className="flex flex-col gap-4">
|
||||
<div className="field">
|
||||
<label className="text-md font-semibold" htmlFor="cookie_A">Cookie A</label>
|
||||
<input
|
||||
className="p-3 bg-gray-300 text-gray-950 placeholder-gray-600 rounded border-2 border-gray-300 w-[100%] box-border"
|
||||
type="text"
|
||||
name="cookieA"
|
||||
id="cookie_A"
|
||||
placeholder="Put your 'a' Cookie here."
|
||||
/>
|
||||
</div>
|
||||
<div className="field">
|
||||
<label className="text-md font-semibold" htmlFor="cookie_B">Cookie B</label>
|
||||
<input
|
||||
className="p-3 bg-gray-300 text-gray-950 placeholder-gray-600 rounded border-2 border-gray-300 w-[100%] box-border"
|
||||
type="text"
|
||||
name="cookieB"
|
||||
id="cookie_B"
|
||||
placeholder="Put your 'b' Cookie here."
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div id="actions" className="mt-4">
|
||||
<button className="text-gray-50 bg-gray-800 p-2 rounded box-border mr-1" onSubmit={saveCookies}>
|
||||
Save Cookies
|
||||
</button>
|
||||
<button className="text-gray-50 bg-gray-800 p-2 rounded box-border mr-1" onSubmit={fetchCookies}>
|
||||
Fetch Cookies
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const root = createRoot(document.getElementById("root")!);
|
||||
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<Options />
|
||||
</React.StrictMode>
|
||||
);
|
61
src/popup.tsx
Normal file
61
src/popup.tsx
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2023 R3BL LLC
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
import React, { useEffect, useState } from "react"
|
||||
import { createRoot } from "react-dom/client"
|
||||
|
||||
const Popup = () => {
|
||||
const [count, setCount] = useState(0)
|
||||
const [currentURL, setCurrentURL] = useState<string>()
|
||||
|
||||
useEffect(() => {
|
||||
chrome.action.setBadgeText({ text: count.toString() })
|
||||
}, [count])
|
||||
|
||||
useEffect(() => {
|
||||
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
|
||||
setCurrentURL(tabs[0].url)
|
||||
})
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
<ul style={{ minWidth: "700px" }}>
|
||||
<li>Current URL: {currentURL}</li>
|
||||
<li>Current Time: {new Date().toLocaleTimeString()}</li>
|
||||
</ul>
|
||||
<button onClick={() => setCount(count + 1)} style={{ marginRight: "5px" }}>
|
||||
count up
|
||||
</button>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
const root = createRoot(document.getElementById("root")!)
|
||||
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<Popup />
|
||||
</React.StrictMode>
|
||||
)
|
3
src/styles/tailwind.css
Normal file
3
src/styles/tailwind.css
Normal file
|
@ -0,0 +1,3 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
8
tailwind.config.js
Normal file
8
tailwind.config.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ["./src/**/*.{html,tsx,js}"],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
24
tsconfig.json
Normal file
24
tsconfig.json
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"target": "es6",
|
||||
"moduleResolution": "bundler",
|
||||
"module": "ES6",
|
||||
"esModuleInterop": true,
|
||||
"sourceMap": false,
|
||||
"rootDir": "src",
|
||||
"outDir": "dist/js",
|
||||
"noEmitOnError": true,
|
||||
"jsx": "react",
|
||||
"typeRoots": [ "node_modules/@types" ],
|
||||
"types": [
|
||||
// Support for: https://www.npmjs.com/package/@types/chrome
|
||||
// Run: `npm install --save @types/chrome`
|
||||
// More info: https://stackoverflow.com/a/40826789/2085356
|
||||
"chrome",
|
||||
// Support for Jest
|
||||
// Run: `npm i --save-dev @types/jest`
|
||||
"jest",
|
||||
]
|
||||
}
|
||||
}
|
7
tsconfig.test.json
Normal file
7
tsconfig.test.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
}
|
||||
}
|
50
webpack/webpack.common.js
Normal file
50
webpack/webpack.common.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
const webpack = require("webpack");
|
||||
const path = require("path");
|
||||
const CopyPlugin = require("copy-webpack-plugin");
|
||||
const srcDir = path.join(__dirname, "..", "src");
|
||||
const pubDir = path.join(__dirname, "..", "public");
|
||||
|
||||
module.exports = {
|
||||
entry: {
|
||||
popup: path.join(srcDir, 'popup.tsx'),
|
||||
options: path.join(srcDir, 'options.tsx'),
|
||||
background: path.join(srcDir, 'background.ts'),
|
||||
content_script: path.join(srcDir, 'content_script.tsx'),
|
||||
// styles: path.join(pubDir, 'styles.css'),
|
||||
},
|
||||
output: {
|
||||
path: path.join(__dirname, "../dist/js"),
|
||||
filename: "[name].js",
|
||||
},
|
||||
optimization: {
|
||||
splitChunks: {
|
||||
name: "vendor",
|
||||
chunks(chunk) {
|
||||
return chunk.name !== 'background';
|
||||
}
|
||||
},
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: "ts-loader",
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
{
|
||||
test: /\.css?$/,
|
||||
use: ["css-loader"],
|
||||
},
|
||||
],
|
||||
},
|
||||
resolve: {
|
||||
extensions: [".ts", ".tsx", ".js"],
|
||||
},
|
||||
plugins: [
|
||||
new CopyPlugin({
|
||||
patterns: [{ from: ".", to: "../", context: "public" }],
|
||||
options: {},
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
27
webpack/webpack.dev.js
Normal file
27
webpack/webpack.dev.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
const { merge } = require('webpack-merge');
|
||||
const common = require('./webpack.common.js');
|
||||
const CopyPlugin = require("copy-webpack-plugin");
|
||||
const { HotModuleReplacementPlugin } = require('webpack');
|
||||
|
||||
module.exports = merge(common, {
|
||||
devtool: 'inline-source-map',
|
||||
mode: 'development',
|
||||
devServer: {
|
||||
static: './dist',
|
||||
hot: true
|
||||
},
|
||||
plugins: [
|
||||
new CopyPlugin({
|
||||
patterns: [{ from: ".", to: "../", context: "public" }],
|
||||
options: {},
|
||||
}),
|
||||
new HotModuleReplacementPlugin()
|
||||
]
|
||||
});
|
||||
|
||||
if (module.hot) {
|
||||
module.hot.accept('styles.css', () => {
|
||||
const baseStyle = window.document.getElementById('js-style')
|
||||
baseStyle.setAttribute('href', 'styles.css?v=' + new Date().valueOf)
|
||||
})
|
||||
}
|
6
webpack/webpack.prod.js
Normal file
6
webpack/webpack.prod.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
const { merge } = require('webpack-merge');
|
||||
const common = require('./webpack.common.js');
|
||||
|
||||
module.exports = merge(common, {
|
||||
mode: 'production'
|
||||
});
|
Loading…
Add table
Reference in a new issue