Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v3.0.0.1の公開のためのPR #5

Merged
merged 18 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions .github/workflows/build-extension.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Build WXT Extension

on:
push:
branches:
- main
- develop
pull_request:
branches:
- main
- develop

jobs:
build:
runs-on: ubuntu-24.04

steps:
- name: Checkout code
uses: actions/checkout@v4

- uses: pnpm/action-setup@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version-file: .node-version
cache: 'pnpm'

- name: Install dependencies
run: pnpm install

- name: Build extension
run: pnpm run zip

- name: Build extension for firefox
run: pnpm run zip:firefox

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: extension-${{ github.sha }}
path: .output/*.zip
29 changes: 29 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
.output
stats.html
stats-*.json
.wxt
web-ext.config.ts

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

# FOR MIGRATION
example-wxt/
1 change: 1 addition & 0 deletions .node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v22.6.0
1 change: 0 additions & 1 deletion css/bootstrap-multiselect.css

This file was deleted.

22 changes: 0 additions & 22 deletions css/bootstrap-switch.min.css

This file was deleted.

5 changes: 0 additions & 5 deletions css/bootstrap.min.css

This file was deleted.

15 changes: 0 additions & 15 deletions css/global.css

This file was deleted.

40 changes: 0 additions & 40 deletions css/main.css

This file was deleted.

99 changes: 99 additions & 0 deletions entrypoints/content.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
export default defineContentScript({
matches: ["*://*/*"],
runAt: "document_end",
main() {
nyanize();
},
});

let nyanizeStatus = 1;

async function nyanize() {
await initConfigs();

if (nyanizeStatus === 0) {
return;
}

walk(document.body);

const observer = new MutationObserver((mutationRecords) => {
for (const record of mutationRecords) {
for (const node of record.addedNodes) {
walk(node);
}
}
});

observer.observe(document.body, {
childList: true,
subtree: true,
characterData: true
});
}

async function initConfigs() {
const data = await browser.storage.local.get(null);
if (typeof data.nyanizeStatus !== "undefined") {
nyanizeStatus = parseInt(data.nyanizeStatus);
}
}

function walk(node: Node) {
switch (node.nodeType) {
case 1: // Element
// ignore special node
if (
["SCRIPT", "CODE", "SVG", "NOSCRIPT", "STYLE"].includes(node.nodeName)
) {
break;
}
case 9: // Document
case 11: // Document fragment
let child = node.firstChild;
while (child) {
walk(child);
child = child.nextSibling;
}
break;

case 3: // Text node
handleText(node as Text);
break;

default:
console.log(node)
}
}

function handleText(textNode: Text) {
let v = textNode.nodeValue;
if (v === null) {
console.error("textNode.nodeValue is null");
return;
}
if (nyanizeStatus === 2) {
v = v.replace(/にゃ/g, "な"); // temporary reverse
v = v.replace(/[ぁ-ん]/g, "にゃ");
v = v.replace(/ニャ/g, "ナ"); // temporary reverse
v = v.replace(/[ァ-ン]/g, "ニャ");
v = v.replace(/ニャ/g, "ナ"); // temporary reverse
v = v.replace(/[ァ-ン゙゚]/g, "ニャ");
v = v.replace(/[一-龥]/g, "にゃ");
v = v.replace(/nya/g, "n"); // temporary reverse
v = v.replace(/[a-z]/g, "nya");
v = v.replace(/NYA/g, "N"); // temporary reverse
v = v.replace(/[A-Z]/g, "NYA");
} else {
v = v.replace(/な/g, "にゃ");
v = v.replace(/ナ/g, "ニャ");
v = v.replace(/ナ/g, "ニャ");
v = v.replace(/na/g, "nya");
v = v.replace(/Na/g, "Nya");
v = v.replace(/nA/g, "nyA");
v = v.replace(/NA/g, "NYA");
}
if (textNode.nodeValue !== v) {
textNode.nodeValue = v;
}
}
45 changes: 45 additions & 0 deletions entrypoints/popup/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<!doctype html>
<html lang="en" style="opacity: 0">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Nyanize Extension</title>
<meta name="manifest.type" content="browser_action" />
</head>
<body>
<div id="main-outer">
<div id="main-inner">
<h1 id="main-title">Nyanize</h1>
<p>
<label class="form-check form-switch">
<input
type="checkbox"
class="form-check-input"
id="nyanizeStatus"
name="nyanizeStatus"
data-size="mini"
role="switch"
/>
Enable nyanize
</label>
</p>
<p>
<label class="form-check form-switch">
<input
class="form-check-input"
type="checkbox"
id="ultimatenyanizeStatus"
name="ultimatenyanizeStatus"
data-size="mini"
role="switch"
/>
Ultimate Nyanize mode
</label>
</p>
<p>Settings are effective after reloading.</p>
</div>
</div>

<script type="module" src="./main.ts"></script>
</body>
</html>
77 changes: 77 additions & 0 deletions entrypoints/popup/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import "./style.scss";

async function init_main() {
let isEnyabled = 1;
//get the current enyabled state and rule list
const data = await browser.storage.local.get("nyanizeStatus");

console.log(data);
if (typeof data.nyanizeStatus !== "undefined") {
isEnyabled = parseInt(data.nyanizeStatus);
}
//make the switch reflect our current state
const nyanizeStatus = document.getElementById(
"nyanizeStatus",
) as HTMLInputElement;
const ultimatenyanizeStatus = document.getElementById(
"ultimatenyanizeStatus",
) as HTMLInputElement;

if (isEnyabled === 1) {
nyanizeStatus.checked = true;
ultimatenyanizeStatus.checked = false;
} else if (isEnyabled === 2) {
nyanizeStatus.checked = true;
ultimatenyanizeStatus.checked = true;
} else {
nyanizeStatus.checked = false;
ultimatenyanizeStatus.checked = false;
}

setupEventHandler();

//show the menu with fade-in effect
document.documentElement.style.transition = "opacity 1s";
setTimeout(() => {
document.documentElement.style.opacity = "1";
}, 0);
}

function setupEventHandler() {
const nyanizeStatus = document.getElementById(
"nyanizeStatus",
) as HTMLInputElement;
const ultimatenyanizeStatus = document.getElementById(
"ultimatenyanizeStatus",
) as HTMLInputElement;

//handle enyabling or disabling or the extension
nyanizeStatus.addEventListener("change", function (event) {
if (this.checked) {
browser.storage.local.set({
nyanizeStatus: 1,
});
} else {
ultimatenyanizeStatus.checked = false;
browser.storage.local.set({
nyanizeStatus: 0,
});
}
});

ultimatenyanizeStatus.addEventListener("change", function (event) {
if (this.checked) {
nyanizeStatus.checked = true;
browser.storage.local.set({
nyanizeStatus: 2,
});
} else {
browser.storage.local.set({
nyanizeStatus: 1,
});
}
});
}

//bind events to dom elements
document.addEventListener("DOMContentLoaded", init_main);
Loading