Skip to content

Commit 9becb46

Browse files
committed
functional DOM inspector
1 parent 8305b89 commit 9becb46

6 files changed

Lines changed: 430 additions & 160 deletions

File tree

src/css/3p-filters.css

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ li.listEntry > a:nth-of-type(3) {
7575
}
7676
/* I designed the button with: http://charliepark.org/bootstrap_buttons/ */
7777
button.custom {
78-
padding: 5px;
78+
padding: 0.6em 1em;
7979
border: 1px solid transparent;
8080
border-color: #80b3ff #80b3ff hsl(216, 100%, 75%);
8181
border-radius: 3px;
@@ -98,7 +98,6 @@ button.custom:hover {
9898
#buttonApply {
9999
display: initial;
100100
margin: 1em 0;
101-
padding: 1em;
102101
position: fixed;
103102
right: 1em;
104103
top: 0;

src/css/common.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ body {
1818
font: 14px/1.3 sans-serif;
1919
}
2020
button.important {
21-
padding: 5px;
21+
padding: 0.6em 1em;
2222
border: 1px solid transparent;
2323
border-color: #ffcc7f #ffcc7f hsl(36, 100%, 73%);
2424
border-radius: 3px;

src/css/logger-ui-inspector.css

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#domInspector {
22
border-top: 1px solid #ccc;
33
display: none;
4-
max-height: 40%;
5-
min-height: 40%;
4+
max-height: 70%;
5+
min-height: 70%;
66
overflow: auto;
77
}
88
#domInspector.enabled {
@@ -83,6 +83,11 @@
8383
display: block;
8484
}
8585

86+
#cosmeticFilteringDialog .dialog {
87+
text-align: center;
88+
}
8689
#cosmeticFilteringDialog .dialog textarea {
8790
height: 40vh;
88-
}
91+
white-space: pre;
92+
word-wrap: normal;
93+
}

src/js/logger-ui-inspector.js

Lines changed: 122 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ var logger = self.logger;
4040
var messager = logger.messager;
4141

4242
var inspectedTabId = '';
43+
var inspectedURL = '';
4344
var inspectedHostname = '';
4445
var pollTimer = null;
4546
var fingerprint = null;
@@ -282,7 +283,48 @@ var nidFromNode = function(node) {
282283

283284
var startDialog = (function() {
284285
var dialog = uDom.nodeFromId('cosmeticFilteringDialog');
285-
var candidateFilters = [];
286+
var textarea = dialog.querySelector('textarea');
287+
var hideSelectors = [];
288+
var unhideSelectors = [];
289+
var inputTimer = null;
290+
291+
var onInputChanged = (function() {
292+
var parse = function() {
293+
inputTimer = null;
294+
hideSelectors = [];
295+
unhideSelectors = [];
296+
297+
var line, matches;
298+
var re = /^([^#]*)(#@?#)(.+)$/;
299+
var lines = textarea.value.split(/\s*\n\s*/);
300+
for ( var i = 0; i < lines.length; i++ ) {
301+
line = lines[i].trim();
302+
if ( line === '' || line.charAt(0) === '!' ) {
303+
continue;
304+
}
305+
matches = re.exec(line);
306+
if ( matches === null || matches.length !== 4 ) {
307+
continue;
308+
}
309+
if ( inspectedHostname.lastIndexOf(matches[1]) === -1 ) {
310+
continue;
311+
}
312+
if ( matches[2] === '##' ) {
313+
hideSelectors.push(matches[3]);
314+
} else {
315+
unhideSelectors.push(matches[3]);
316+
}
317+
}
318+
319+
showCommitted();
320+
};
321+
322+
return function parseAsync() {
323+
if ( inputTimer === null ) {
324+
inputTimer = vAPI.setTimeout(parse, 743);
325+
}
326+
};
327+
})();
286328

287329
var onClick = function(ev) {
288330
var target = ev.target;
@@ -292,45 +334,94 @@ var startDialog = (function() {
292334
return stop();
293335
}
294336
ev.stopPropagation();
337+
338+
if ( target.id === 'createCosmeticFilters' ) {
339+
messager.send({ what: 'createUserFilter', filters: textarea.value });
340+
// Force a reload for the new cosmetic filter(s) to take effect
341+
messager.send({ what: 'reloadTab', tabId: inspectedTabId });
342+
return stop();
343+
}
295344
};
296345

297-
var stop = function() {
298-
dialog.removeEventListener('click', onClick, true);
299-
document.body.removeChild(dialog);
346+
var onCooked = function(entries) {
347+
if ( Array.isArray(entries) === false ) {
348+
return;
349+
}
350+
hideSelectors = entries;
351+
var taValue = [], i, node;
352+
var d = new Date();
353+
taValue.push('! ' + d.toLocaleString() + ' ' + inspectedURL);
354+
for ( i = 0; i < entries.length; i++ ) {
355+
taValue.push(inspectedHostname + '##' + entries[i]);
356+
}
357+
var nodes = domTree.querySelectorAll('code.filter.off');
358+
for ( i = 0; i < nodes.length; i++ ) {
359+
node = nodes[i];
360+
unhideSelectors.push(node.textContent);
361+
taValue.push(inspectedHostname + '#@#' + node.textContent);
362+
}
363+
textarea.value = taValue.join('\n');
364+
document.body.appendChild(dialog);
365+
dialog.addEventListener('click', onClick, true);
366+
showCommitted();
367+
};
368+
369+
var showCommitted = function() {
370+
messager.sendTo(
371+
{
372+
what: 'showCommitted',
373+
hide: hideSelectors.join(',\n'),
374+
unhide: unhideSelectors.join(',\n')
375+
},
376+
inspectedTabId,
377+
'dom-inspector.js'
378+
);
379+
};
380+
381+
var showInteractive = function() {
382+
messager.sendTo(
383+
{
384+
what: 'showInteractive',
385+
hide: hideSelectors.join(',\n'),
386+
unhide: unhideSelectors.join(',\n')
387+
},
388+
inspectedTabId,
389+
'dom-inspector.js'
390+
);
300391
};
301392

302393
var start = function() {
303-
// Collect all selectors which are currently toggled
304-
var node, filters = [];
394+
textarea.addEventListener('input', onInputChanged);
395+
var node, entries = [];
305396
var nodes = domTree.querySelectorAll('code.off');
306397
for ( var i = 0; i < nodes.length; i++ ) {
307398
node = nodes[i];
308-
if ( node.classList.contains('filter') ) {
309-
filters.push({
310-
prefix: '#@#',
311-
nid: '',
312-
selector: node.textContent
313-
});
314-
} else {
315-
filters.push({
316-
prefix: '##',
399+
if ( node.classList.contains('filter') === false ) {
400+
entries.push({
317401
nid: nidFromNode(node),
318-
selector: node.textContent
402+
selector: selectorFromNode(node)
319403
});
320404
}
321405
}
406+
messager.sendTo(
407+
{ what: 'cookFilters', entries: entries },
408+
inspectedTabId,
409+
'dom-inspector.js',
410+
onCooked
411+
);
412+
};
322413

323-
// TODO: Send filters through dom-inspector.js for further processing.
324-
325-
candidateFilters = filters;
326-
var taValue = [], filter;
327-
for ( i = 0; i < filters.length; i++ ) {
328-
filter = filters[i];
329-
taValue.push(inspectedHostname + filter.prefix + filter.selector);
414+
var stop = function() {
415+
if ( inputTimer !== null ) {
416+
clearTimeout(inputTimer);
417+
inputTimer = null;
330418
}
331-
dialog.querySelector('textarea').value = taValue.join('\n');
332-
document.body.appendChild(dialog);
333-
dialog.addEventListener('click', onClick, true);
419+
showInteractive();
420+
hideSelectors = [];
421+
unhideSelectors = [];
422+
textarea.removeEventListener('input', onInputChanged);
423+
dialog.removeEventListener('click', onClick, true);
424+
document.body.removeChild(dialog);
334425
};
335426

336427
return start;
@@ -404,7 +495,10 @@ var onMouseOver = (function() {
404495
if ( inspectedTabId === '' ) {
405496
return;
406497
}
407-
498+
// Convenience: skip real-time highlighting if shift key is pressed.
499+
if ( ev.shiftKey ) {
500+
return;
501+
}
408502
// Find closest `li`
409503
var target = ev.target;
410504
while ( target !== null ) {
@@ -447,6 +541,7 @@ var fetchDOMAsync = (function() {
447541
case 'full':
448542
renderDOMFull(response);
449543
fingerprint = response.fingerprint;
544+
inspectedURL = response.url;
450545
inspectedHostname = response.hostname;
451546
break;
452547

0 commit comments

Comments
 (0)