Skip to content

Commit d63ea07

Browse files
committed
Add Bookmarklets
1 parent cdd45c6 commit d63ea07

File tree

1 file changed

+205
-0
lines changed

1 file changed

+205
-0
lines changed

bookmarklets/bookmarklets.md

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
# [Bookmarklets](https://en.wikipedia.org/wiki/Bookmarklet)
2+
This is a list of bookmarklets that are convenient for use with Charcoal.
3+
## WARNING
4+
Prior to copying and using any of the bookmarklets here:
5+
* Verify the history of this page and who edited it. If you don't trust the editors, don't trust the bookmarklets.
6+
* If you know JavaScript, it's a good idea to double-check the code.
7+
8+
Clicking on a bookmarklet runs JavaScript in the current page. That means it's possible for the bookmarklet to do anything that code in that page can do. Thus, there are significant security concerns for bookmarklets and you need to trust the bookmarklet code. As things are currently set up, changes to this page are **not secure**, so you need to verify that the code hasn't been nefariously changed.
9+
10+
## What are bookmarklets
11+
Bookmarklets are relatively small amounts of JavaScript code that are stored in a browser bookmark. When the bookmark is clicked, the JavaScript is run in the current page. The advantages of using a bookmarklet, rather than a userscript include:
12+
* Can be used in all browsers, even when the browser doesn't support browser extensions. Creating the bookmarklets may be inconvenient in some browsers.
13+
* Can, usually, be used in browsers/machines where installing browser extensions isn't permitted (e.g., some work environments). You should check the policies for where you are to be sure that having a bookmarklet doesn't violate the policy.
14+
* Can be used on almost all webpages, without the need to have a userscript or browser extension loaded into the page every time (i.e., They consume no resources and present no security issues, until activated by the user's click on the bookmark.).
15+
16+
## Searching on metasmoke
17+
18+
### Watchlist or blacklisted keyword entries
19+
20+
Select the regex text you desire to search for as a watchlist or blacklisted keyword entry and click the bookmarklet:
21+
```javascript
22+
javascript:(function(){
23+
/* The code to get the selected text on multiple platforms is from an [answer to "Get the Highlighted/Selected text"](https://stackoverflow.com/a/5379408) copyright by Tim Down and is under a [CC BY-SA 3.0 license](https://creativecommons.org/licenses/by-sa/3.0/legalcode). It has been modified to use let/const instead of var. */
24+
let text = "";
25+
const activeEl = document.activeElement;
26+
const activeElTagName = activeEl ? activeEl.tagName.toLowerCase() : null;
27+
if ((activeElTagName == "textarea" || activeElTagName == "input") && /^(?:text|textarea|search|password|tel|url)$/i.test(activeEl.type) && (typeof activeEl.selectionStart == "number")) {
28+
text = activeEl.value.slice(activeEl.selectionStart, activeEl.selectionEnd);
29+
} else if (window.getSelection) {
30+
text = window.getSelection().toString();
31+
}
32+
let searchTerm = encodeURIComponent(`(?s)(?:^|\\b)${text}(?:\\b|$)`);
33+
const textNoNoncaptureGroups = text.replace(/\(\?:/g, '(').replace(/\(\?-i:([^()]+)\)/, '$1');
34+
if (!/[+?*{}()|]/.test(textNoNoncaptureGroups)) {
35+
searchTerm = encodeURIComponent(`(?s)${text}(?<=(?:^|\\b)${text})(?:\\b|$)`);
36+
} else if (/^(?:\w+(?![?*+{])|\(\?-i:[^+?*{}()|]+\)\w*(?![?*+{]))/.test(text)) {
37+
searchTerm = encodeURIComponent(`(?s)${text.replace(/^(\w+(?![?*+{])|\(\?-i:[^+?*{}()|]+\)\w*(?![?*+{]))/, '$1(?<=(?:^|\\b)$1)')}(?:\\b|$)`);
38+
}
39+
const searchTitle = `&title_is_regex=1&title=${searchTerm}`;
40+
const searchBody = `&body_is_regex=1&body=${searchTerm}`;
41+
const searchUsername = `&username_is_regex=1&username=${searchTerm}`;
42+
const url = `https://metasmoke.erwaysoftware.com/search?utf8=%E2%9C%93${searchTitle}${searchBody}${searchUsername}&or_search=1`;
43+
window.open(url);
44+
})();
45+
```
46+
### Blacklisted website entries
47+
Select the regex text you desire to search for as a blacklisted website entry and click the bookmarklet:
48+
```javascript
49+
javascript:(function(){
50+
/* The code to get the selected text on multiple platforms is from an [answer to "Get the Highlighted/Selected text"](https://stackoverflow.com/a/5379408) copyright by Tim Down and is under a [CC BY-SA 3.0 license](https://creativecommons.org/licenses/by-sa/3.0/legalcode). It has been modified to use const instead of var. */
51+
var text = "";
52+
const activeEl = document.activeElement;
53+
const activeElTagName = activeEl ? activeEl.tagName.toLowerCase() : null;
54+
if ((activeElTagName == "textarea" || activeElTagName == "input") && /^(?:text|textarea|search|password|tel|url)$/i.test(activeEl.type) && (typeof activeEl.selectionStart == "number")) {
55+
text = activeEl.value.slice(activeEl.selectionStart, activeEl.selectionEnd);
56+
} else if (window.getSelection) {
57+
text = window.getSelection().toString();
58+
}
59+
const searchTerm = encodeURIComponent(`${text}`);
60+
const searchTitle = `&title_is_regex=1&title=${searchTerm}`;
61+
const searchBody = `&body_is_regex=1&body=${searchTerm}`;
62+
const searchUsername = `&username_is_regex=1&username=${searchTerm}`;
63+
const url = `https://metasmoke.erwaysoftware.com/search?utf8=%E2%9C%93${searchTitle}${searchBody}${searchUsername}&or_search=1`;
64+
window.open(url);
65+
})();
66+
```
67+
### Numbers
68+
Select the number text you desire to search for and click the bookmarklet:
69+
```javascript
70+
javascript:(function(){
71+
/* The code to get the selected text on multiple platforms is from an [answer to "Get the Highlighted/Selected text"](https://stackoverflow.com/a/5379408) copyright by Tim Down and is under a [CC BY-SA 3.0 license](https://creativecommons.org/licenses/by-sa/3.0/legalcode). It has been modified to use const instead of var. */
72+
var text = "";
73+
const activeEl = document.activeElement;
74+
const activeElTagName = activeEl ? activeEl.tagName.toLowerCase() : null;
75+
if ((activeElTagName == "textarea" || activeElTagName == "input") && /^(?:text|textarea|search|password|tel|url)$/i.test(activeEl.type) && (typeof activeEl.selectionStart == "number")) {
76+
text = activeEl.value.slice(activeEl.selectionStart, activeEl.selectionEnd);
77+
} else if (window.getSelection) {
78+
text = window.getSelection().toString();
79+
}
80+
const textOnlyNumbers = text.replace(/\D/g, '');
81+
if (textOnlyNumbers.length < 7 || textOnlyNumbers.length > 20) {
82+
if (!confirm('This text can never be detected by a number watch. Number watches must contain between 7 and 20 digits. Do you still wish to search for this on MS?')) {
83+
return;
84+
}
85+
}
86+
text = text.replace(/\D/g, '').replace(/(\d)/g, '$1[\\W_]*+').replace(/\[\\W_\]\*\+$/, '(?:\\D|$)').replace(/(\d)/, '$1(?:(?<=^\\d)|(?<=\\D\\d))');
87+
const searchTerm = encodeURIComponent(text);
88+
const searchTitle = `&title_is_regex=1&title=${searchTerm}`;
89+
const searchBody = `&body_is_regex=1&body=${searchTerm}`;
90+
const searchUsername = `&username_is_regex=1&username=${searchTerm}`;
91+
/*Why is also searched, as it may contain deobfuscated versions.*/
92+
const searchWhy = `&why_is_regex=1&why=${searchTerm}`;
93+
const url = `https://metasmoke.erwaysoftware.com/search?utf8=%E2%9C%93${searchTitle}${searchBody}${searchUsername}${searchWhy}&or_search=1`;
94+
window.open(url);
95+
})();
96+
```
97+
98+
### Loose number search
99+
Select the number text you desire to loosely search for and click the bookmarklet:
100+
```javascript
101+
javascript:(function(){
102+
/* The code to get the selected text on multiple platforms is from an [answer to "Get the Highlighted/Selected text"](https://stackoverflow.com/a/5379408) copyright by Tim Down and is under a [CC BY-SA 3.0 license](https://creativecommons.org/licenses/by-sa/3.0/legalcode). It has been modified to use const instead of var. */
103+
var text = "";
104+
const activeEl = document.activeElement;
105+
const activeElTagName = activeEl ? activeEl.tagName.toLowerCase() : null;
106+
if ((activeElTagName == "textarea" || activeElTagName == "input") && /^(?:text|textarea|search|password|tel|url)$/i.test(activeEl.type) && (typeof activeEl.selectionStart == "number")) {
107+
text = activeEl.value.slice(activeEl.selectionStart, activeEl.selectionEnd);
108+
} else if (window.getSelection) {
109+
text = window.getSelection().toString();
110+
}
111+
const textOnlyNumbers = text.replace(/\D/g, '');
112+
if (textOnlyNumbers.length < 7 || textOnlyNumbers.length > 20) {
113+
if (!confirm('This text can never be detected by a number watch. Number watches must contain between 7 and 20 digits. Do you still wish to search for this on MS?')) {
114+
return;
115+
}
116+
}
117+
text = text.replace(/\D/g, '').replace(/(\d)/g, '$1[\\W_]*+').replace(/\[\\W_\]\*\+$/, '');
118+
const searchTerm = encodeURIComponent(text);
119+
const searchTitle = `&title_is_regex=1&title=${searchTerm}`;
120+
const searchBody = `&body_is_regex=1&body=${searchTerm}`;
121+
const searchUsername = `&username_is_regex=1&username=${searchTerm}`;
122+
/*Why is also searched, as it may contain deobfuscated versions.*/
123+
const searchWhy = `&why_is_regex=1&why=${searchTerm}`;
124+
const url = `https://metasmoke.erwaysoftware.com/search?utf8=%E2%9C%93${searchTitle}${searchBody}${searchUsername}${searchWhy}&or_search=1`;
125+
window.open(url);
126+
})();
127+
```
128+
129+
### Blacklisted usernames
130+
Select the regex text you desire to search for as a blacklisted username entry and click the bookmarklet:
131+
```javascript
132+
javascript:(function(){
133+
/* The code to get the selected text on multiple platforms is from an [answer to "Get the Highlighted/Selected text"](https://stackoverflow.com/a/5379408) copyright by Tim Down and is under a [CC BY-SA 3.0 license](https://creativecommons.org/licenses/by-sa/3.0/legalcode). It has been modified to use const instead of var. */
134+
var text = "";
135+
const activeEl = document.activeElement;
136+
const activeElTagName = activeEl ? activeEl.tagName.toLowerCase() : null;
137+
if ((activeElTagName == "textarea" || activeElTagName == "input") && /^(?:text|textarea|search|password|tel|url)$/i.test(activeEl.type) && (typeof activeEl.selectionStart == "number")) {
138+
text = activeEl.value.slice(activeEl.selectionStart, activeEl.selectionEnd);
139+
} else if (window.getSelection) {
140+
text = window.getSelection().toString();
141+
}
142+
const searchTerm = encodeURIComponent(`${text}`);
143+
const searchUsername = `&username_is_regex=1&username=${searchTerm}`;
144+
const url = `https://metasmoke.erwaysoftware.com/search?utf8=%E2%9C%93${searchUsername}&or_search=1`;
145+
window.open(url);
146+
})();
147+
```
148+
149+
### Verbatim text
150+
Select the verbatim text you desire to search for as a blacklisted website entry and click the bookmarklet:
151+
```javascript
152+
javascript:(function(){
153+
/* The code to get the selected text on multiple platforms is from an [answer to "Get the Highlighted/Selected text"](https://stackoverflow.com/a/5379408) copyright by Tim Down and is under a [CC BY-SA 3.0 license](https://creativecommons.org/licenses/by-sa/3.0/legalcode). It has been modified to use const instead of var. */
154+
var text = "";
155+
const activeEl = document.activeElement;
156+
const activeElTagName = activeEl ? activeEl.tagName.toLowerCase() : null;
157+
if ((activeElTagName == "textarea" || activeElTagName == "input") && /^(?:text|textarea|search|password|tel|url)$/i.test(activeEl.type) && (typeof activeEl.selectionStart == "number")) {
158+
text = activeEl.value.slice(activeEl.selectionStart, activeEl.selectionEnd);
159+
} else if (window.getSelection) {
160+
text = window.getSelection().toString();
161+
}
162+
/*Escaping a regex is from [this SO answer](https://stackoverflow.com/a/3561711) by bobince.*/
163+
const searchTerm = encodeURIComponent(`${text.replace(/[/\-\\^$*+?.()|[\]{}]/g, '\\$&')}`);
164+
const searchTitle = `&title_is_regex=1&title=${searchTerm}`;
165+
const searchBody = `&body_is_regex=1&body=${searchTerm}`;
166+
const searchUsername = `&username_is_regex=1&username=${searchTerm}`;
167+
const url = `https://metasmoke.erwaysoftware.com/search?utf8=%E2%9C%93${searchTitle}${searchBody}${searchUsername}&or_search=1`;
168+
window.open(url);
169+
})();
170+
```
171+
172+
### Two searches for the difference between two watchlist/keyword blacklist entries
173+
The following bookmarklet will open two searches on MS to get the differences between two watchlist/keyword blacklist entries. The searches will be the relative complements of the hits for the two entries (i.e., one window showing what's caught by the first entry, but not caught by the second entry; and one window showing what's caught by the second entry, but not caught by the first entry).
174+
175+
The bookmarklet will prompt you for both a description for each entry and the entries (i.e., the prompts are in the order description 1, entry 1, description 2, entry 2). The descriptions are used in a regex comment, so it's easier to know which window is which. The descriptions are not permitted to be blank, nor to include "(" or ")".
176+
```javascript
177+
javascript:(function(){
178+
function openSearchForText(text) {
179+
const searchTerm = encodeURIComponent(text);
180+
const searchTitle = `&title_is_regex=1&title=${searchTerm}`;
181+
const searchBody = `&body_is_regex=1&body=${searchTerm}`;
182+
const searchUsername = `&username_is_regex=1&username=${searchTerm}`;
183+
const url = `https://metasmoke.erwaysoftware.com/search?utf8=%E2%9C%93${searchTitle}${searchBody}${searchUsername}&or_search=1`;
184+
window.open(url);
185+
}
186+
let description1 = '';
187+
while (!description1 || description1.includes('(') || description1.includes(')')) {
188+
description1 = window.prompt('Description for first entry (may not contain "(" or ")"):');
189+
}
190+
let entry1 = '';
191+
while (!entry1) {
192+
entry1 = window.prompt('First entry:');
193+
}
194+
let description2 = '';
195+
while (!description2 || description2.includes('(') || description2.includes(')')) {
196+
description2 = window.prompt('Description for second entry (may not contain "(" or ")"):');
197+
}
198+
let entry2 = '';
199+
while (!entry2) {
200+
entry2 = window.prompt('Second entry:');
201+
}
202+
openSearchForText(`(?#IN ${description1}, but NOT IN ${description2})(?s)^(?=[\\W\\w]*?(?:^|\\b)${entry1}(?:\\b|$))(?![\\W\\w]*?(?:^|\\b)${entry2}(?:\\b|$))`);
203+
openSearchForText(`(?#IN ${description2}, but NOT IN ${description1})(?s)^(?=[\\W\\w]*?(?:^|\\b)${entry2}(?:\\b|$))(?![\\W\\w]*?(?:^|\\b)${entry1}(?:\\b|$))`);
204+
})();
205+
```

0 commit comments

Comments
 (0)