-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathadblock-uiscripts-blacklisting-clickwatcher.js
195 lines (175 loc) · 5.76 KB
/
adblock-uiscripts-blacklisting-clickwatcher.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
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
/*
* This file is part of AdBlock <https://getadblock.com/>,
* Copyright (C) 2013-present Adblock, Inc.
*
* AdBlock is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* AdBlock is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AdBlock. If not, see <http://www.gnu.org/licenses/>.
*/
/* For ESLint: List any global identifiers used in this file below */
/* global Overlay */
// Requires overlay.js and jquery
// Highlight DOM elements with an overlayed box, similar to Webkit's inspector.
// Creates an absolute-positioned div that is translated & scaled following
// mousemove events. Holds a pointer to target DOM element.
function Highlighter() {
let target = null;
let enabled = false;
let then = Date.now();
let box = $("<div id='overlay-box' class='adblock-highlight-node'></div>");
box.css({
'background-color': 'rgba(130, 180, 230, 0.5)',
'box-sizing': 'border-box',
outline: 'solid 1px #0F4D9A',
position: 'absolute',
zIndex: 214748364,
});
box.appendTo($(document.body));
function handler(e) {
let el = e.target;
const now = Date.now();
if (now - then < 25) {
return;
}
then = now;
if (el === box[0]) {
box.hide();
el = document.elementFromPoint(e.clientX, e.clientY);
}
if (el === target) {
box.show();
return;
}
if (el === document.body || el.className === 'adblock-killme-overlay') {
box.hide();
return;
}
target = el;
const $el = $(el);
const offset = $el.offset();
box.css({
height: $el.outerHeight() || 0,
width: $el.outerWidth() || 0,
left: offset.left,
top: offset.top,
});
box.show();
}
this.getCurrentNode = function getCurrentNode(el) {
return el === box[0] ? target : el;
};
this.enable = function enable() {
if (box && !enabled) {
$(document.body).on('mousemove', handler);
}
enabled = true;
};
this.disable = function disable() {
if (box && enabled) {
box.hide();
$(document.body).off('mousemove', handler);
}
enabled = false;
};
this.destroy = function destroy() {
this.disable();
if (box) {
box.remove();
box = null;
}
};
}
// Class that watches the whole page for a click, including iframes and
// objects. Shows a modal while doing so.
function ClickWatcher() {
this.callbacks = { cancel: [], click: [] };
this.clickedElement = null;
this.highlighter = null;
}
ClickWatcher.prototype.cancel = function cancel(callback) {
this.callbacks.cancel.push(callback);
};
ClickWatcher.prototype.click = function click(callback) {
this.callbacks.click.push(callback);
};
ClickWatcher.prototype.fire = function fire(eventName, arg) {
const callbacks = this.callbacks[eventName];
for (let i = 0; i < callbacks.length; i++) {
callbacks[i](arg);
}
};
ClickWatcher.prototype.enable = function enable() {
const that = this;
that.highlighter = new Highlighter();
that.highlighter.enable();
that.eventsListener();
};
// Clean up / remove added DOM elements.
ClickWatcher.prototype.disable = function disable() {
$('body').off('click', '.adblock-killme-overlay, .adblock-highlight-node', this.clickHandler);
$('body').unbind();
Overlay.removeAll();
this.onClose();
};
// Called externally to close ClickWatcher. Doesn't cause any events to
// fire.
ClickWatcher.prototype.close = function close() {
// Delete our event listeners so we don't fire any cancel events
this.callbacks.cancel = [];
};
// The dialog is closing, either because the user clicked cancel, or the
// close button, or because they clicked an item.
ClickWatcher.prototype.onClose = function onClose() {
if (!this.clickedElement) {
// User clicked Cancel button or X
this.fire('cancel');
} else {
// User clicked a page item
this.fire('click', this.clickedElement);
}
this.highlighter.destroy();
};
ClickWatcher.prototype.clickHandler = function clickHandler(event) {
if (event && event.data && event.data.clickWatcherRef) {
const theClickWatcherRef = event.data.clickWatcherRef;
theClickWatcherRef.clickedElement = theClickWatcherRef.highlighter.getCurrentNode(this);
theClickWatcherRef.disable();
}
return false;
};
// Catches clicks on elements and mouse hover on the wizard
// when element is clicked we stored the element in clickedElement
// and close all ClickWatcher processes
ClickWatcher.prototype.eventsListener = function eventsListener() {
const that = this;
// Most things can be blacklisted with a simple click handler.
$('body').on('click', '.adblock-killme-overlay, .adblock-highlight-node', { clickWatcherRef: that }, that.clickHandler);
// Since iframes that will get clicked will almost always be an entire
// ad, and I *really* don't want to figure out inter-frame communication
// so that the blacklist UI's slider works between multiple layers of
// iframes... just overlay iframes and treat them as a giant object.
$('object,embed,iframe,[onclick]:empty')
.each((i, el) => {
// Don't add overlay's for hidden elements
if (el.style && el.style.display === 'none') {
return;
}
const killmeOverlay = new Overlay({
domElement: el,
clickHandler: that.clickHandler,
});
killmeOverlay.display();
});
};
// required return value for tabs.executeScript
/* eslint-disable-next-line no-unused-expressions */
'';
//# sourceURL=/uiscripts/blacklisting/clickwatcher.js