-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathadblock-filter-analyzer.js
106 lines (90 loc) · 4.05 KB
/
adblock-filter-analyzer.js
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
// Copyright https://www.RedDragonWebDesign.com/ All rights reserved.
"use strict";
import { AdBlockSyntaxBlock } from './AdBlockSyntaxBlock.js';
import { Cursor } from './Cursor.js';
import { tooltips } from './tooltips.js';
// This line not optional. Content loads top to bottom. Need to wait until DOM is fully loaded.
window.addEventListener('DOMContentLoaded', (e) => {
let json = document.getElementById('json');
let richText = document.getElementById('rich-text');
let clear = document.getElementById('clear');
let lineCount = document.getElementById('line-count');
let definition = document.getElementById('definition');
let filterList = document.getElementById('filter-list');
/** Do some HTML escape, convert tabs to  , convert enters to <br>. Prevents bugs when pasting and importing from file into richTextBox. */
function processPastedText(text) {
text = text.replace(/</g, "<");
text = text.replace(/>/g, ">");
text = text.replace(/\t/g, " ");
text = text.replace(/\r\n/g, "<br>");
text = text.replace(/\n/g, "<br>");
return text;
}
richText.addEventListener('input', function(e) {
// In theory, we should need some escapeHTML's and unescapeHTML's around here. In actual testing, anything being written into the <textarea> by JS didn't need to be escaped.
let offset = Cursor.getCurrentCursorPosition(richText);
let block = new AdBlockSyntaxBlock();
block.parseRichText(richText.innerHTML);
json.value = block.getJSON();
richText.innerHTML = block.getRichText();
Cursor.setCurrentCursorPosition(offset, richText);
lineCount.innerHTML = block.getLineCount();
richText.focus(); // blinks the cursor
});
// When pasting into rich text editor, force plain text. Do not allow rich text or HTML. For example, the default copy/paste from VS Code is rich text. Foreign formatting messes up our syntax highlighting.
richText.addEventListener("paste", function(e) {
// cancel paste
e.preventDefault();
// get text representation of clipboard
var text = (e.originalEvent || e).clipboardData.getData('text/plain');
text = processPastedText(text);
// insert text manually
Cursor.setCurrentCursorPosition(0, richText);
document.execCommand("insertHTML", false, text);
richText.focus(); // shows the cursor
});
clear.addEventListener('click', function(e) {
richText.innerHTML = "";
lineCount.innerHTML = 0;
filterList.value = "";
});
/** Provides functionality for hovering over a highlight and getting the syntax description */
function addDescription(e) {
e = e || window.event;
var targetElem = e.target || e.srcElement;
// tags must be capitalized for some reason
if ( targetElem.nodeName === "SPAN" ) {
let myClasses = targetElem.className.split(" ");
for ( let myClass of myClasses ) {
let descriptionText = tooltips[myClass];
descriptionText = `<h2><span class="` + myClass + `">` + myClass + `</span></h2>` + descriptionText;
definition.innerHTML = descriptionText;
// make sure error overwrites everything else
if ( myClass === "error" ) break;
}
}
}
richText.addEventListener("mouseover", addDescription, false);
richText.addEventListener("mousewheel", addDescription, false);
// when picking a filter list to load from the combo box
filterList.addEventListener("change", function(e) {
if ( ! filterList.value ) {
richText.innerHTML = "";
return;
}
let text;
try {
let xmlhttp = new XMLHttpRequest();
xmlhttp.open('GET', filterList.value, false);
xmlhttp.send();
text = xmlhttp.responseText;
text = processPastedText(text);
richText.innerHTML = text;
Cursor.setCurrentCursorPosition(0, richText);
richText.dispatchEvent(new Event('input', { bubbles: true }));
} catch(DOMException) {
richText.innerHTML = "CORS policy error. The website we are trying to fetch these filters from is not allowing our script to access it.";
}
});
filterList.dispatchEvent(new Event('change', { bubbles: true }));
});