-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathcontent_script.js
More file actions
312 lines (285 loc) · 14.4 KB
/
content_script.js
File metadata and controls
312 lines (285 loc) · 14.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
(function(global) {
/* if (window.hasRunContentScriptOnce === true) return;
window.hasRunContentScriptOnce = true; */
const {
readFromClipboard, //library to read from clipboard to variable
} = global.es6lib_dom
const {
writeToClipboard, //library to write from variable to clipboard
} = global.es6lib_dom
var clickedElement = null;
document.addEventListener("mousedown", function(event) { //this one is needed for the plain text version
//right click
if (event.button == 2) {
clickedElement = event.target;
}
}, true);
document.removeEventListener("mousedown", function(event) {
//right click
if (event.button == 2) {
clickedElement = event.target;
}
}, true);
browser.runtime.onMessage.addListener(function(commandString) {
CommandParse(commandString)});
// });
browser.runtime.onMessage.removeListener(function(commandString) {
CommandParse(commandString);
});
// sanitize selections and clipboard contents so that they do not get executed as commands
// will put the string, "_~_~", in between each "{{", "}}", and "##" so they will not be parsed
function sanitize (sanitized) {
sanitized = sanitized.replace(/{{/g,"{_~_~{");
sanitized = sanitized.replace(/}}/g,"}_~_~}");
sanitized = sanitized.replace(/##/g,"#_~_~#");
return sanitized;
}
// return selections and clipboard contents back to original values.
function deSanitize (deSanitized) {
deSanitized = deSanitized.replace(/{_~_~{/g,"{{");
deSanitized = deSanitized.replace(/}_~_~}/g,"}}");
deSanitized = deSanitized.replace(/#_~_~#/g,"##");
deSanitized = deSanitized.replace(/~_~nl~_~/g,"\n"); //allows the use of ~_~nl~_~ to substitute for a new line used in custom tags
return deSanitized;
}
/*
Popup has the format of {{zzppopup,title,unique text string to change,text before, text after}}
text before and text after omitted if empty answer given. (use double quotes"" if not used)
Use unique text so that we can set order of dialogue boxes independent of the order of
Argument.
So, quote paste is: {{zzpopup,i18n.INS_AUTHOR,zzzquote,=","}}][quote]zzquote{{clipboard}}][/quote]
This will give [quote]CLIPBOARD[/QUOTE] if no author given and [quote="AUTHOR"] CLIPBOARD[/QUOTE]
if author given.
and url wizard is
{{zzpopup,i18n.URLCOMPOSTO_STEP1,zzTitle,"",""}}{{zzpopup,i18n.URLCOMPOSTO_STEP2,zzURL,"",""}}[url=zzURL]zzTitle[/url]
It will prompt for title, and then for url, and the result will be
[url=URL]TITLE[/url]
This will generate as many popup dialogues as you would want.
*/
async function colorPick (colorArg){ //read the color from the popup
let {pickColor: colorPicked} = await browser.storage.local.get("pickColor");
// console.log(colorPicked);
if (colorPicked == "nocolor"){ //No color selected, clear color agument
let colorStartStartIdx = colorArg.indexOf('{{zzGetColor');
let colorStartEndIdx = colorArg.indexOf("}}", colorStartStartIdx) + 2;
colorArg = colorArg.substring(0,colorStartStartIdx)+colorArg.substring(colorStartEndIdx);
let colorEndStartIdx = colorArg.indexOf("{{zzColorEnd");
let colorEndEndIdx = colorArg.indexOf("}}", colorEndStartIdx) + 2;
colorArg = colorArg.substring(0,colorEndStartIdx)+colorArg.substring(colorEndEndIdx);
// console.log(colorArg);
} else { //Color selected, process color argument
let colorStartStartIdx = colorArg.indexOf("{{zzpopup");
let colorStartEndIdx = colorArg.indexOf("}}", colorStartStartIdx) + 2;
let colorWork = colorArg.substring(colorStartStartIdx,colorStartEndIdx);
colorWork = colorWork.substring(colorWork.indexOf(",") + 1); //drop title from popWork
let startColorTag = colorWork.substring(1, colorWork.indexOf(",")-1);
colorWork = colorWork.substring(colorWork.indexOf(",")+2);
let endColorTag = colorWork.substring(0,colorWork.indexOf(",")-1);
colorWork = colorWork.substring(colorWork.indexOf(",")+2);
let finalColorTab = colorWork.substring(0,colorWork.indexOf("\""));;
colorArg = colorArg.substring(colorStartEndIdx);
colorArg = colorArg.substring(0,colorArg.indexOf("{{")),
colorArg = startColorTag+colorPicked+endColorTag+colorArg+finalColorTab;
// console.log(colorArg);
}
// console.log (colorArg);
colorArg = colorArg.replace(/~_~qt~_~/g,"\""); //the span statement uses quotes. This allows the
//use of the quote proxy (~_~qt~_~) in the argument
return colorArg ;
}
function popThisUp(popArg) {
while (popArg.includes("zzpopup")) { // cycle through multiple popups until done
let popStartIdx = popArg.indexOf("{{zzpopup"); // start of popup argument in commend string
let popEndIdx = popArg.indexOf("}}", popStartIdx) + 2; // end of popup argument in command string
let popWork = popArg.substring(popStartIdx, popEndIdx); // extract the portion of the argument that has to do with making the popup
popWork = popWork.substring(10, popWork.length - 2); //remove the "{{zzpopup," from the beginning of argument, and "}}" from the end.
let popTitle = popWork.substring(0, popWork.indexOf(",")); // popup title, possibly including i18n localization tag
if (popTitle.includes("i18n")) { //if there is a localization tag
popTitle = browser.i18n.getMessage(popTitle.substring(5)); // replace with i18n value
}
let popToReplaceStart = popWork.indexOf("##"); //start index of string to replace
let popToReplaceEnd = popWork.indexOf("##",popToReplaceStart + 1); //end index of string to replace.
var textToReplace = popWork.substring(popToReplaceStart,popToReplaceEnd +2);
popWork = popWork.substring(popWork.indexOf(",") + 1); //drop title from popWork
popWork = popWork.substring(popWork.indexOf(",") + 1); //drop string to be replaced from popWork
popupBefore = popWork.substring(0, popWork.indexOf(",")); //text to be added before entered text
popupAfter = popWork.substring(popWork.lastIndexOf(",")+1); //text to be added before entered text
let popupResp = prompt(popTitle);
if (popupResp === null || popupResp === "") { // if the prompt is left blank, produce empty response
popupResp = "";
popupBefore = "";
popupAfter = "";
}
let popUpHere = (popupBefore + popupResp + popupAfter);
// add stuff to allow '\n\' to creat new line from popup
popUpHere = popUpHere.replace(/\\\\n/g,'~_~_~n'); // use '\\n' to actually enter '\n\'
popUpHere = popUpHere.replace(/\\n/g,'\n');
popUpHere = popUpHere.replace(/~_~_~n/g,'\\n');
console.log("129",popArg);
popArg = popArg.substring(0, popStartIdx) + popArg.substring(popEndIdx); //string it together with popup removed
console.log("131",popArg);
popArg = popArg.replace(new RegExp(textToReplace,"g"),popUpHere); //replace hashtag with word prompt results
console.log("133",popArg);
}
//add in whatever you got from the dialog box
return popArg;
}
/*
List has the format of {{makeList,thing to make into list,type of list}}
*/
function listMake (listArg) {
let listStartIdx = listArg.indexOf("{{makeList"); // start of list argument in commend string
let listEndIdx = listArg.indexOf("}}", listStartIdx); // end of list argument in command string
let listWork = listArg.substring(listStartIdx, listEndIdx);; // extract the portion of the argument that has to do with making the list
listWork = listWork.substring(11, listWork.length -1 ); //remove the "{{makeList," from the beginning of the argument, and the "}}" from the end.
let listType = listWork.substring(listWork.lastIndexOf(",") +2, (listWork.length)) // the type of list is after the last comma
listWhat = listWork.substring(0, listWork.lastIndexOf(",")); // the text to which the list would be applied
// the replace will only apply to cases where line breaks are inserted through custom user scripts
let listResult = createList(listWhat, listType); //return the properly formatted list to put into the list argument
return listArg.substring(0, listStartIdx) + listResult + listArg.substring(listEndIdx +2); //send the parsed list in the back
}
async function CommandParse(argString) {
let txtcont = document.activeElement.value; //contents of edit box, textbox undef if content editable
let locProt = location.protocol;
// console.log("text box type: ",txtcont," Location Protocol: ",locProt);
if (clickedElement.selectionStart !== undefined) {// if this method works on this page, then
console.log("dialogue box case 1");
let selstart = clickedElement.selectionStart; // index of selection start
console.log("selection start ",selstart) //are we getting the start of the selection?
let selend = clickedElement.selectionEnd; //index of selection end
console.log("selection end ",selend) //are we getting the end of the selection?
let selcont = sanitize(txtcont.substring(selstart, selend)); // selected text content sanitized
console.log("selection content ",selcont) //are we getting the content of the selection?
let firsttext = txtcont.substring(0, selstart); //stuff before the selection
let lasttext = txtcont.substring(selend); // stuff after the selection
if (argString.includes("{{clipboard}}")) { // Replace clipboard tag with clipboard contents
const clipcont = sanitize(await readFromClipboard('text/plain')); //clipboard content sanitized
argString = argString.replace(/{{clipboard}}/g, clipcont);
}
if (argString.includes("{{selection}}")) { // Replace selection tag with selection value
argString = argString.replace(/{{selection}}/g, selcont);
}
if (argString.includes("{{zzpopup")) { // Invoke popup query function
console.log("before popup",argString);
argString = await popThisUp(argString);
console.log("after popup",argString);
}
if (argString.includes("{{makeList")) { // Invoke list creation function
argString = listMake(argString);
}
if (argString.includes("{{zzGetColor")) { // invoke color picker
argString = await colorPick(argString);
}
clickedElement.value = firsttext + deSanitize(argString) + lasttext; //desanitize and insert element
} else { // for rich text and iframe edit boxes only works on https pages
console.log("dialogue box case 2");
let currentClipBoard = await navigator.clipboard.readText();
let currentSelection = window.getSelection().toString().trim(); //store current selection contents
console.log("selection content https ",currentSelection); //are we getting the content?
if(currentSelection === null || currentSelection === undefined || currentSelection === ""){ //fix for Google breaking
currentSelection = String(txtcont); // HTML editor window in blogspot
currentSelection = currentSelection.replace(/\u200B/g,''); // yeah, somehow or other those morons at Google
}; //added a zero width space (8203 dec, 200B hex) seriously, they f%$# up everything!!!
// Seriously, Google sucks wet f@rts from dead pigeons
let selCont = sanitize(currentSelection); // selected text content sanitized
if (argString.includes("{{clipboard}}")) {// Replace clipboard tag with clipboard contents
argString = argString.replace(/{{clipboard}}/g, currentClipBoard);
}
if (argString.includes("{{selection}}")) { // Replace selection tag with selection value
argString = argString.replace(/{{selection}}/g, selCont);
}
if (argString.includes("{{zzpopup")) { // Invoke popup query function
argString = popThisUp(argString);
}
if (argString.includes("{{makeList")) { // Invoke list creation function
argString = listMake(argString);
}
if (argString.includes("{{zzGetColor")) { // invoke color picker
argString = await colorPick(argString);
}
await navigator.clipboard.writeText(deSanitize(argString));
console.log("moo");
document.execCommand('paste'); // paste to cursor location or selection
console.log("cclip",currentClipBoard);
await navigator.clipboard.writeText(currentClipBoard);
}}
})(this);
/* this is pretty much a copy of the function from bbCodeXtra by flod (Francesco Lodolo)
which is under an MIT free and open-source software (FOSS) license.
*/
function createList(originalText, listType) {
var startBlock, endBlock, startItem, endItem, formattedText;
// Make sure only \n is used as line ending
originalText = originalText.replace(/[\r|\n|\r\n]/g, '\n');
// Split lines based on \n
lines = originalText.split('\n');
// Ignore empty lines
lines = lines.filter(function(n) {
return n !== '';
});
switch (listType) {
case 'bbcode':
startBlock = '[list]\n';
startItem = '[*]';
endItem = '\n';
endBlock = '[/list]';
break;
case 'bbcodeord':
startBlock = '[list=1]\n';
startItem = '[*]';
endItem = '\n';
endBlock = '[/list]';
break;
case 'bbcodeordalf':
startBlock = '[list=a]\n';
startItem = '[*]';
endItem = '\n';
endBlock = '[/list]';
break;
case 'html':
startBlock = '<ul>\n';
startItem = '<li>';
endItem = '</li>\n';
endBlock = '</ul>';
break;
case 'htmlord':
startBlock = '<ol>\n';
startItem = '<li>';
endItem = '</li>\n';
endBlock = '</ol>';
break;
case 'htmlordalf':
startBlock = '<ol type=a>\n';
startItem = '<li>';
endItem = '</li>\n';
endBlock = '</ol>';
break;
case 'markdown':
startBlock = endBlock = '';
startItem = '- ';
endItem = '\n';
break;
case 'markdownord':
startBlock = endBlock = '';
startItem = '';
endItem = '\n';
break;
default:
startBlock = '';
startItem = '';
endItem = '\n';
endBlock = '';
break;
}
formattedText = startBlock;
for (var i = 0; i < lines.length; i++) {
if (listType == 'markdownord') {
var linenumber = i + 1;
formattedText += linenumber + '. ' + lines[i] + endItem;
} else {
formattedText += startItem + lines[i] + endItem;
}
}
formattedText += endBlock;
return formattedText;
}