feat: add boilerplate
This commit is contained in:
18
manifest.json
Normal file
18
manifest.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"manifest_version": 3,
|
||||
"name": "Live Text Replacer",
|
||||
"version": "1.0",
|
||||
"description": "Replace words and phrases on web pages using a custom dictionary.",
|
||||
"permissions": ["storage", "activeTab", "scripting"],
|
||||
"host_permissions": ["<all_urls>"],
|
||||
"action": {
|
||||
"default_popup": "popup.html"
|
||||
},
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": ["<all_urls>"],
|
||||
"js": ["content.js"],
|
||||
"run_at": "document_idle"
|
||||
}
|
||||
]
|
||||
}
|
||||
25
popup.html
Normal file
25
popup.html
Normal file
@@ -0,0 +1,25 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Text Replacer</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h2>Text Replacer</h2>
|
||||
|
||||
<textarea id="dictionary" spellcheck="false"></textarea>
|
||||
|
||||
<button id="saveBtn">Save Dictionary</button>
|
||||
|
||||
<p class="hint">
|
||||
Format:
|
||||
consultant=conslutant
|
||||
AI process engineer=algorithm inventor
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<script src="popup.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
48
popup.js
Normal file
48
popup.js
Normal file
@@ -0,0 +1,48 @@
|
||||
const textarea = document.getElementById("dictionary");
|
||||
const saveBtn = document.getElementById("saveBtn");
|
||||
|
||||
const DEFAULT_TEXT = `consultant=conslutant
|
||||
AI process engineer=algorithm inventor`;
|
||||
|
||||
function parseDictionary(text) {
|
||||
const lines = text.split("\n");
|
||||
const result = {};
|
||||
|
||||
for (const line of lines) {
|
||||
if (!line.includes("=")) continue;
|
||||
|
||||
const [key, ...rest] = line.split("=");
|
||||
result[key.trim()] = rest.join("=").trim();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function serializeDictionary(obj) {
|
||||
return Object.entries(obj)
|
||||
.map(([k, v]) => `${k}=${v}`)
|
||||
.join("\n");
|
||||
}
|
||||
|
||||
chrome.storage.sync.get(["replacements"], (result) => {
|
||||
const replacements = result.replacements;
|
||||
|
||||
if (!replacements) {
|
||||
textarea.value = DEFAULT_TEXT;
|
||||
return;
|
||||
}
|
||||
|
||||
textarea.value = serializeDictionary(replacements);
|
||||
});
|
||||
|
||||
saveBtn.addEventListener("click", () => {
|
||||
const parsed = parseDictionary(textarea.value);
|
||||
|
||||
chrome.storage.sync.set({ replacements: parsed }, () => {
|
||||
saveBtn.innerText = "Saved!";
|
||||
|
||||
setTimeout(() => {
|
||||
saveBtn.innerText = "Save Dictionary";
|
||||
}, 1200);
|
||||
});
|
||||
});
|
||||
87
readme.md
Normal file
87
readme.md
Normal file
@@ -0,0 +1,87 @@
|
||||
\# Buzzword Killer - Chrome Extension
|
||||
|
||||
|
||||
|
||||
\## How To Install
|
||||
|
||||
|
||||
|
||||
Create a folder called: `text-replacer-extension`
|
||||
|
||||
|
||||
|
||||
Copy each file above into the folder.
|
||||
|
||||
|
||||
|
||||
Open Chrome and go to:
|
||||
|
||||
|
||||
|
||||
`chrome://extensions`
|
||||
|
||||
|
||||
|
||||
Enable:
|
||||
|
||||
* Developer mode
|
||||
|
||||
|
||||
|
||||
Click:
|
||||
|
||||
* Load unpacked
|
||||
|
||||
|
||||
|
||||
Select your extension folder.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
\## How It Works
|
||||
|
||||
|
||||
|
||||
The extension:
|
||||
|
||||
|
||||
|
||||
* Reads your replacement dictionary
|
||||
* Scans all visible text nodes in the page
|
||||
* Replaces matching phrases
|
||||
* Watches for dynamically added content using MutationObserver
|
||||
|
||||
|
||||
|
||||
So if a website loads new content later, the replacements still happen automatically.
|
||||
|
||||
|
||||
|
||||
\## Improvements You Can Add
|
||||
|
||||
|
||||
|
||||
Possible upgrades:
|
||||
|
||||
|
||||
|
||||
Regex support
|
||||
|
||||
Case-sensitive matching
|
||||
|
||||
Import/export dictionary
|
||||
|
||||
Enable/disable per site
|
||||
|
||||
Ignore specific domains
|
||||
|
||||
Highlight replaced words
|
||||
|
||||
AI-generated replacement rules
|
||||
|
||||
Toolbar toggle
|
||||
|
||||
Context menu integration
|
||||
|
||||
50
styles.css
Normal file
50
styles.css
Normal file
@@ -0,0 +1,50 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 340px;
|
||||
font-family: Arial, sans-serif;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 100%;
|
||||
height: 180px;
|
||||
resize: vertical;
|
||||
font-family: monospace;
|
||||
font-size: 13px;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
margin-top: 12px;
|
||||
padding: 10px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
background: black;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.hint {
|
||||
margin-top: 10px;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
white-space: pre-line;
|
||||
}
|
||||
Reference in New Issue
Block a user