Skip to content

Commit

Permalink
You'll take care of her, I know it, you will do a better job
Browse files Browse the repository at this point in the history
  • Loading branch information
chee committed Jun 9, 2018
0 parents commit ae5a477
Show file tree
Hide file tree
Showing 9 changed files with 303 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
web-ext-artifacts/
3 changes: 3 additions & 0 deletions .web-extension-id
@@ -0,0 +1,3 @@
# This file was created by https://github.com/mozilla/web-ext
# Your auto-generated extension ID for addons.mozilla.org is:
anything_to_anything@snake.dog
33 changes: 33 additions & 0 deletions STYLE.css
@@ -0,0 +1,33 @@
body {
background: #ff2a50;
color: white;
font-size: 5vw;
display: flex;
justify-content: center;
align-items: center;
}

input {
border: none;
border-radius: 2px;
padding: .5em;
font-size: .4em;
}

input[type="text"] {
width: 9em;
}

input:focus {
outline: 5px solid #33ffcc;
border: 2px solid black;
box-shadow: 0 0 2px 5px rgba(40, 60, 120, 0.5);
}

th {
text-align: left;
}

th, td {
padding: .2em .4em;
}
97 changes: 97 additions & 0 deletions background.js
@@ -0,0 +1,97 @@
var escape = char => `\\${char}`

var special = new RegExp('[' +
'()}{[]|\\^$*+?.'.split``
.map(escape)
.join`|` +
']', 'g'
)

var escapeRegex = string => string.replace(special, '\\$&')

var wordStartRegex = /((?:^|\s|[-_])\w)/g

String.prototype.toTitleCase = function () {
return this.toLowerCase().replace(wordStartRegex, $1 => $1.toUpperCase())
}

function createInsensitiveReplacements ({from, to}) {
var replacements = []
replacements.push({from, to})

replacements.push({
from: from.toUpperCase(),
to: to.toUpperCase()
})

replacements.push({
from: from.toLowerCase(),
to: to.toLowerCase()
})

replacements.push({
from: from.toTitleCase(),
to: to.toTitleCase()
})

return replacements
}

var build = items => items.reduce((map, item) => {
var {
from = '',
to = '',
sensitive = false,
isRegex = false
} = item

if (!from) return map

var replacements = sensitive
? [{from, to}]
: createInsensitiveReplacements({from, to})

return replacements.reduce((map, {from, to}) => (
map[isRegex
? from
: escapeRegex(from)
] = to, map
), map)

}, {})

var currentData = {}

browser.storage.local.get('map').then(results => {
currentData = results
})

browser.tabs.onUpdated.addListener = (tabId, changeInfo, tab) => {
browsers.tabs.sendMessage(tabId, currentData)
}

function handleBrowserActionMessage ({type, value}) {
if (type === 'items:change') {
currentData.map = build(value)
browser.storage.local.set(currentData)
}
}

browser.runtime.onMessage.addListener((message, sender) => {
if (sender.tab && sender.url.endsWith('the-replacements.htm')) {
// we are getting messages from our special tab
handleBrowserActionMessage(message)
}
})

browser.browserAction.onClicked.addListener(() => {
browser.tabs.create({
active: true,
url: './the-replacements.htm'
}).then(() => {
setTimeout(() => {
browser.runtime.sendMessage('hello m8')
browser.runtime.sendMessage(['like this', '?'])
}, 4000)
})
})
70 changes: 70 additions & 0 deletions browser-action.js
@@ -0,0 +1,70 @@
var dom = 'tr td input'.split` `.reduce((dom, nodename) => {
dom[nodename] = (attrs = {}, children = '') => {
var node = document.createElement(nodename)

Object.entries(attrs).forEach(([key, value]) => {
value != null && value !== false && node.setAttribute(key, value)
})

if (typeof children === 'string') {
node.textContent = children
} else if (Array.isArray(children)) {
node.append(...children)
} else {
node.append(children)
}

return node
}
return dom
}, {})

function createRow ({from = '', to = '', sensitive = false, isRegex = false} = {}) {
return dom.tr({class: 'js-row'}, [
dom.td({}, dom.input({class: 'js-from', type: 'text', value: from})),
dom.td({}, dom.input({class: 'js-to', type: 'text', value: to})),
dom.td({}, dom.input({class: 'js-sensitive', type: 'checkbox', checked: sensitive})),
dom.td({}, dom.input({class: 'js-isRegex', type: 'checkbox', checked: isRegex}))
])
}

var table = document.getElementById('table')
var body = document.getElementById('body')

function serialise () {
return [].reduce.call(table.querySelectorAll('.js-row'), (items, row) => items.concat({
from: row.querySelector('.js-from').value || '',
to: row.querySelector('.js-to').value || '',
sensitive: !!row.querySelector('.js-sensitive').checked,
isRegex: !!row.querySelector('.js-isRegex').checked
}), [])
}

Array.prototype.last = function () {
return this[Math.max(this.length - 1, 0)]
}

function appendRow ({from, to, sensitive, isRegex} = {}) {
return body.append(createRow({from, to, sensitive, isRegex}))
}

function handleKeyDown () {
var items = serialise()

browser.storage.local.set({items}).then(() => browser.runtime.sendMessage({
type: 'items:change',
value: items
}))

var last = items.last()

if (last.from && last.to) appendRow()
}

document.addEventListener('keydown', handleKeyDown)

browser.storage.local.get('items').then(({items}) => {
if (!Array.isArray(items) || !items.length) return
body.textContent = ''
items.forEach(appendRow)
})
44 changes: 44 additions & 0 deletions content.js
@@ -0,0 +1,44 @@
var escape = char => `\\${char}`

var special = new RegExp('[' +
'()}{[]|\\^$*+?.'.split``
.map(escape)
.join`|` +
']', 'g'
)

var escapeRegex = string => string.replace(special, '\\$&')

var createReplace = replacements => match => {
var straightMatch = replacements[match]
if (straightMatch) return straightMatch

// else find gay match
var demiMatch = replacements[escapeRegex(match)]
if (demiMatch) return demiMatch

var [, okcupidMatch] = (Object.entries(replacements).find(([from]) =>
RegExp(escapeRegex(from)).test(match)
) || [])
if (okcupidMatch) return okcupidMatch

var [, tinderFuck] = (Object.entries(replacements).find(([from]) =>
RegExp(from).test(match)
) || [])
if (tinderFuck) return tinderFuck
}

var walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT)

browser.storage.local.get('map').then(results => {
var {map} = results
var keys = Object.keys(map)
if (!keys.length) return
var regex = RegExp(`\\b(${keys.join('|')})\\b`, 'g')
var replace = createReplace(map)
var text
while (text = walker.nextNode()) {
text.textContent = text.textContent.replace(regex, replace)
}
})

Binary file added icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 35 additions & 0 deletions manifest.json
@@ -0,0 +1,35 @@
{
"manifest_version": 2,
"name": "anything-to-anything",
"version": "0.0.17",
"description": "replace any term with anything, everywhere. cloud->butt millenial->snake peopel, blockchain->slow database",
"background": {
"scripts": ["background.js"]
},
"content_scripts": [
{
"matches": [
"*://*/*"
],
"js": [
"content.js"
]
}
],
"permissions": ["storage"],
"icons": {
"64": "icon.png"
},
"browser_action": {
"browser_style": true,
"default_title": "Anything to Anything",
"default_icon": {
"64": "icon.png"
}
},
"applications": {
"gecko": {
"id": "anything_to_anything@snake.dog"
}
}
}
20 changes: 20 additions & 0 deletions the-replacements.htm
@@ -0,0 +1,20 @@
<!doctype html>
<meta charset="utf-8">
<title>the replacements</title>
<link rel="stylesheet" href="./STYLE.css">
<table id="table">
<thead>
<tr>
<th title="fetching this one">from
<th title="turn this b*tch into what exactly">to
<th title="match case exactly, do not create smart lower upper and title versions">sensitive
<th title="this is a regex">regex
</thead>
<tbody id="body">
<tr class="js-row">
<td><input class="js-from" type="text">
<td><input class="js-to" type="text">
<td><input class="js-sensitive" type="checkbox">
<td><input class="js-isRegex" type="checkbox">
</table>
<script src="./browser-action.js"></script>

0 comments on commit ae5a477

Please sign in to comment.