Skip to content

Commit

Permalink
Version 0.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
getvictor committed May 9, 2024
1 parent 2bcc3a9 commit 2133b60
Show file tree
Hide file tree
Showing 12 changed files with 2,425 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/.idea/
/dist/
/node_modules/
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
# open-blur
# OpenBlur Chrome extension

Automatically hide and blur sensitive information on any webpage, including emails and names.
2,128 changes: 2,128 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "openblur",
"version": "0.1.0",
"repository": "https://github.com/getvictor/openblur",
"author": "getvictor",
"license": "MIT",
"scripts": {
"build": "webpack --mode production"
},
"devDependencies": {
"@tsconfig/recommended": "^1.0.6",
"@types/chrome": "^0.0.266",
"copy-webpack-plugin": "^12.0.2",
"ts-loader": "^9.5.1",
"ts-node": "^10.9.2",
"typescript": "^5.4.5",
"webpack": "^5.91.0",
"webpack-cli": "^5.1.4"
}
}
11 changes: 11 additions & 0 deletions src/background.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { MODES } from "./constants"

let currentModeIndex = 1

chrome.storage.sync.get("mode", (data) => {
if (data.mode) {
currentModeIndex = data.mode.index
}
chrome.action.setBadgeText({text: MODES[currentModeIndex].text}).then(r => {})
chrome.action.setBadgeBackgroundColor({color: MODES[currentModeIndex].color}).then(r => {})
})
15 changes: 15 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export const MODES = [
{
index: 0,
id: "off",
text: "off",
color: "#AAAAAA",
},
{
index: 1,
id: "on",
text: "blur",
color: "#008C20",
},
]
export const NUMBER_OF_ITEMS = 10
70 changes: 70 additions & 0 deletions src/content.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { NUMBER_OF_ITEMS} from "./constants"

const contentToBlur: string[] = []
const blurFilter = "blur(6px)"

function processNode(node: Node) {
if (node.childNodes.length > 0) {
Array.from(node.childNodes).forEach(processNode)
}
if (node.nodeType === Node.TEXT_NODE && node.textContent !== null && node.textContent.trim().length > 0) {
const parent = node.parentElement
if (parent !== null && (parent.tagName === 'SCRIPT' || parent.style.filter === blurFilter)) {
// Already blurred
return
}
const text = node.textContent!
contentToBlur.some((content) => {
if (text.includes(content)) {
blurElement(parent!)
return true
}
return false
})

}
}

function blurElement(elem: HTMLElement) {
elem.style.filter = blurFilter
console.debug("blurred id:" + elem.id + " class:" + elem.className + " tag:" + elem.tagName + " text:" + elem.textContent)
}

const observer = new MutationObserver((mutations, observer) => {
mutations.forEach((mutation) => {
if (mutation.addedNodes.length > 0) {
mutation.addedNodes.forEach(processNode)
} else {
processNode(mutation.target)
}
})
})

let enabled = true
const keys = ["mode"]
for (let i = 0; i < NUMBER_OF_ITEMS; i++) {
keys.push(`item_${i}`)
}

chrome.storage.sync.get(keys, (data) => {
if (data.mode && data.mode.id === "off") {
enabled = false
}
for (let i = 0; i < NUMBER_OF_ITEMS; i++) {
const item = data[`item_${i}`]
if (item) {
contentToBlur.push(item)
}
}
if (enabled) {
observer.observe(document, {
attributes: false,
characterData: true,
childList: true,
subtree: true,
})

// Loop through all elements on the page.
processNode(document)
}
})
21 changes: 21 additions & 0 deletions src/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"manifest_version": 3,
"name": "OpenBlur",
"version": "0.1.0",
"description": "Automatically hide and blur sensitive information on any webpage, including emails and names.",
"action": {
"default_popup": "popup.html"
},
"permissions": [
"storage"
],
"background": {
"service_worker": "background.js"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"]
}
]
}
86 changes: 86 additions & 0 deletions src/popup.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<html lang="en">
<head>
<title>Water Popup</title>
<style>
/* The switch - the box around the slider */
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}

/* Hide default HTML checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}

/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
/*transition: .4s;*/ /* TODO: Bring back animation but disable on initial load. */
}

.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
/*transition: .4s;*/
}

input:checked + .slider {
background-color: #2196F3;
}

input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
}

input:checked + .slider:before {
transform: translateX(26px);
}

/* Rounded sliders */
.slider.round {
border-radius: 34px;
}

.slider.round:before {
border-radius: 50%;
}

.secret {
margin: 5px;
}
</style>
</head>
<body>
<label class="switch">
<input type="checkbox" id="enabled">
<span class="slider round"></span>
</label>
<input class="secret" type="password" id="item_0">
<input class="secret" type="password" id="item_1">
<input class="secret" type="password" id="item_2">
<input class="secret" type="password" id="item_3">
<input class="secret" type="password" id="item_4">
<input class="secret" type="password" id="item_5">
<input class="secret" type="password" id="item_6">
<input class="secret" type="password" id="item_7">
<input class="secret" type="password" id="item_8">
<input class="secret" type="password" id="item_9">
<script src="popup.js"></script>
</body>
</html>
33 changes: 33 additions & 0 deletions src/popup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { MODES, NUMBER_OF_ITEMS } from "./constants"

console.log("Hello, world from popup!")

const checkbox = document.getElementById("enabled") as HTMLInputElement
chrome.storage.sync.get("mode", (data) => {
checkbox.checked = !(data.mode && data.mode.id === "off");
const mode = data.mode || MODES[1]
chrome.action.setBadgeText({text: mode.text}).then(r => {})
chrome.action.setBadgeBackgroundColor({color: mode.color}).then(r => {})
})
checkbox.addEventListener("change", (event) => {
if (event.target instanceof HTMLInputElement) {
const mode = event.target.checked ? MODES[1] : MODES[0]
chrome.storage.sync.set({mode}, () => {})
chrome.action.setBadgeText({text: mode.text}).then(r => {})
chrome.action.setBadgeBackgroundColor({color: mode.color}).then(r => {})
}
})

// Loop over NUMBER_OF_ITEMS elements and listen to each one.
for (let i = 0; i < NUMBER_OF_ITEMS; i++) {
const input = document.getElementById(`item_${i}`) as HTMLInputElement
// TODO: optimize to get all stored items at once
chrome.storage.sync.get(`item_${i}`, (data) => {
input.value = data[`item_${i}`] || ""
})
input.addEventListener("change", (event) => {
if (event.target instanceof HTMLInputElement) {
chrome.storage.sync.set({[`item_${i}`]: event.target.value}, () => {})
}
})
}
3 changes: 3 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "@tsconfig/recommended/tsconfig.json",
}
32 changes: 32 additions & 0 deletions webpack.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import CopyWebpackPlugin from "copy-webpack-plugin";

module.exports = {
entry: {
background: './src/background.ts',
content: './src/content.ts',
popup: './src/popup.ts',
},
resolve: {
extensions: [".ts"],
},
module: {
rules: [
{
test: /\.ts$/,
loader: "ts-loader",
exclude: /node_modules/,
},
],
},
plugins: [
new CopyWebpackPlugin({
patterns: [
{ from: "./src/manifest.json" },
{ from: "./src/popup.html" },
],
}),
],
optimization: {
minimize: false,
},
}

0 comments on commit 2133b60

Please sign in to comment.