mirror of https://github.com/gorhill/uBlock.git
some more work re inspector
This commit is contained in:
parent
58b6552207
commit
39b0d719c0
|
@ -100,6 +100,10 @@ MessagingListeners.prototype.remove = function(callback) {
|
||||||
this.listeners.splice(this.listeners.indexOf(callback), 1);
|
this.listeners.splice(this.listeners.indexOf(callback), 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MessagingListeners.prototype.removeAll = function() {
|
||||||
|
this.listeners = [];
|
||||||
|
};
|
||||||
|
|
||||||
MessagingListeners.prototype.process = function(msg) {
|
MessagingListeners.prototype.process = function(msg) {
|
||||||
var listeners = this.listeners;
|
var listeners = this.listeners;
|
||||||
var n = listeners.length;
|
var n = listeners.length;
|
||||||
|
@ -209,6 +213,10 @@ MessagingChannel.prototype.removeListener = function(callback) {
|
||||||
this.listeners.remove(callback);
|
this.listeners.remove(callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MessagingChannel.prototype.removeAllListeners = function() {
|
||||||
|
this.listeners.removeAll();
|
||||||
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
vAPI.messaging = {
|
vAPI.messaging = {
|
||||||
|
|
|
@ -94,6 +94,10 @@ MessagingListeners.prototype.remove = function(callback) {
|
||||||
this.listeners.splice(this.listeners.indexOf(callback), 1);
|
this.listeners.splice(this.listeners.indexOf(callback), 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MessagingListeners.prototype.removeAll = function() {
|
||||||
|
this.listeners = [];
|
||||||
|
};
|
||||||
|
|
||||||
MessagingListeners.prototype.process = function(msg) {
|
MessagingListeners.prototype.process = function(msg) {
|
||||||
var listeners = this.listeners;
|
var listeners = this.listeners;
|
||||||
var n = listeners.length;
|
var n = listeners.length;
|
||||||
|
@ -199,6 +203,10 @@ MessagingChannel.prototype.removeListener = function(callback) {
|
||||||
this.listeners.remove(callback);
|
this.listeners.remove(callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MessagingChannel.prototype.removeAllListeners = function() {
|
||||||
|
this.listeners.removeAll();
|
||||||
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
vAPI.messaging = {
|
vAPI.messaging = {
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
#domInspector {
|
||||||
|
border-top: 1px solid #ccc;
|
||||||
|
display: none;
|
||||||
|
max-height: 40%;
|
||||||
|
min-height: 40%;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
#domInspector.enabled {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
#domInspector .permatoolbar {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
#domInspector .permatoolbar .highlightMode.invert {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
#domInspector > ul:first-of-type {
|
||||||
|
padding-left: 0.5em;
|
||||||
|
}
|
||||||
|
#domInspector ul {
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 1em;
|
||||||
|
}
|
||||||
|
#domInspector li {
|
||||||
|
list-style-type: none;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
#domInspector li.isCosmeticHide,
|
||||||
|
#domInspector li.isCosmeticHide ul,
|
||||||
|
#domInspector li.isCosmeticHide li {
|
||||||
|
background-color: #fee;
|
||||||
|
}
|
||||||
|
#domInspector li > * {
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
#domInspector li > span:first-child {
|
||||||
|
color: #000;
|
||||||
|
cursor: default;
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 0;
|
||||||
|
opacity: 0.5;
|
||||||
|
visibility: hidden;
|
||||||
|
width: 1em;
|
||||||
|
}
|
||||||
|
#domInspector li > span:first-child:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
#domInspector li > *:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
#domInspector li > span:first-child:before {
|
||||||
|
content: '\a0';
|
||||||
|
}
|
||||||
|
#domInspector li.branch > span:first-child:before {
|
||||||
|
content: '\25b8';
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
#domInspector li.branch.show > span:first-child:before {
|
||||||
|
content: '\25be';
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
#domInspector li.branch.hasCosmeticHide > span:first-child:before {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
#domInspector li > code {
|
||||||
|
cursor: pointer;
|
||||||
|
font: 12px/1.4 monospace;
|
||||||
|
}
|
||||||
|
#domInspector li > code.off {
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
|
#domInspector li > span {
|
||||||
|
color: #aaa;
|
||||||
|
}
|
||||||
|
#domInspector li > code.filter {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
#domInspector li > ul {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
#domInspector li.show > ul {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cosmeticFilteringDialog .dialog textarea {
|
||||||
|
height: 40vh;
|
||||||
|
}
|
|
@ -16,6 +16,12 @@ body {
|
||||||
input:focus {
|
input:focus {
|
||||||
background-color: #ffe;
|
background-color: #ffe;
|
||||||
}
|
}
|
||||||
|
textarea {
|
||||||
|
box-sizing: border-box;
|
||||||
|
direction: ltr;
|
||||||
|
resize: none;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
.permatoolbar {
|
.permatoolbar {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
border: 0;
|
border: 0;
|
||||||
|
@ -55,85 +61,6 @@ input:focus {
|
||||||
padding: 0.2em 0;
|
padding: 0.2em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#domInspector {
|
|
||||||
border-top: 1px solid #ccc;
|
|
||||||
display: none;
|
|
||||||
max-height: 40%;
|
|
||||||
min-height: 40%;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
#domInspector.enabled {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
#domInspector > ul:first-child {
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
|
||||||
#domInspector ul {
|
|
||||||
background-color: #fff;
|
|
||||||
margin: 0;
|
|
||||||
padding-left: 1em;
|
|
||||||
}
|
|
||||||
#domInspector li {
|
|
||||||
list-style-type: none;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
#domInspector li.isCosmeticHide,
|
|
||||||
#domInspector li.isCosmeticHide ul,
|
|
||||||
#domInspector li.isCosmeticHide li {
|
|
||||||
background-color: #fee;
|
|
||||||
}
|
|
||||||
#domInspector li > * {
|
|
||||||
margin-right: 1em;
|
|
||||||
}
|
|
||||||
#domInspector li > span:first-child {
|
|
||||||
color: #000;
|
|
||||||
cursor: default;
|
|
||||||
display: inline-block;
|
|
||||||
margin-right: 0;
|
|
||||||
opacity: 0.5;
|
|
||||||
visibility: hidden;
|
|
||||||
width: 1em;
|
|
||||||
}
|
|
||||||
#domInspector li > span:first-child:hover {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
#domInspector li > *:last-child {
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
#domInspector li > span:first-child:before {
|
|
||||||
content: '\a0';
|
|
||||||
}
|
|
||||||
#domInspector li.branch > span:first-child:before {
|
|
||||||
content: '\25b8';
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
#domInspector li.branch.show > span:first-child:before {
|
|
||||||
content: '\25be';
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
#domInspector li.branch.hasCosmeticHide > span:first-child:before {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
#domInspector li > code {
|
|
||||||
cursor: pointer;
|
|
||||||
font: 12px/1.4 monospace;
|
|
||||||
}
|
|
||||||
#domInspector li > code.off {
|
|
||||||
text-decoration: line-through;
|
|
||||||
}
|
|
||||||
#domInspector li > span {
|
|
||||||
color: #aaa;
|
|
||||||
}
|
|
||||||
#domInspector li > code.filter {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
#domInspector li > ul {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
#domInspector li.show > ul {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
#events {
|
#events {
|
||||||
border-top: 1px solid #ccc;
|
border-top: 1px solid #ccc;
|
||||||
font: 13px sans-serif;
|
font: 13px sans-serif;
|
||||||
|
@ -623,11 +550,7 @@ body.colorBlind #netFilteringDialog .dialog > div.containers > div.dynamic tr.e
|
||||||
margin: 0.75em 0;
|
margin: 0.75em 0;
|
||||||
}
|
}
|
||||||
#netFilteringDialog .dialog > div.containers > div.static textarea {
|
#netFilteringDialog .dialog > div.containers > div.static textarea {
|
||||||
box-sizing: border-box;
|
|
||||||
direction: ltr;
|
|
||||||
height: 6em;
|
height: 6em;
|
||||||
resize: none;
|
|
||||||
width: 100%;
|
|
||||||
}
|
}
|
||||||
#netFilteringDialog .dialog > div.containers > div.static > p:nth-of-type(2) {
|
#netFilteringDialog .dialog > div.containers > div.static > p:nth-of-type(2) {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
|
@ -0,0 +1,671 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
|
||||||
|
uBlock Origin - a browser extension to block requests.
|
||||||
|
Copyright (C) 2015 Raymond Hill
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program 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 this program. If not, see {http://www.gnu.org/licenses/}.
|
||||||
|
|
||||||
|
Home: https://github.com/gorhill/uBlock
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* global vAPI, uDom */
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
// Don't bother if the browser is not modern enough.
|
||||||
|
if ( typeof Map === undefined || typeof WeakMap === undefined ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var logger = self.logger;
|
||||||
|
var messager = logger.messager;
|
||||||
|
|
||||||
|
var inspectedTabId = '';
|
||||||
|
var inspectedHostname = '';
|
||||||
|
var pollTimer = null;
|
||||||
|
var fingerprint = null;
|
||||||
|
var showdomButton = uDom.nodeFromId('showdom');
|
||||||
|
var inspector = uDom.nodeFromId('domInspector');
|
||||||
|
var domTree = uDom.nodeFromId('domTree');
|
||||||
|
var tabSelector = uDom.nodeFromId('pageSelector');
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var nodeFromDomEntry = function(entry) {
|
||||||
|
var node, value;
|
||||||
|
var li = document.createElement('li');
|
||||||
|
li.setAttribute('id', entry.nid);
|
||||||
|
// expander/collapser
|
||||||
|
node = document.createElement('span');
|
||||||
|
li.appendChild(node);
|
||||||
|
// selector
|
||||||
|
node = document.createElement('code');
|
||||||
|
node.textContent = entry.sel;
|
||||||
|
li.appendChild(node);
|
||||||
|
// descendant count
|
||||||
|
value = entry.cnt || 0;
|
||||||
|
node = document.createElement('span');
|
||||||
|
node.textContent = value !== 0 ? value.toLocaleString() : '';
|
||||||
|
node.setAttribute('data-cnt', value);
|
||||||
|
li.appendChild(node);
|
||||||
|
// cosmetic filter
|
||||||
|
if ( entry.filter !== undefined ) {
|
||||||
|
node = document.createElement('code');
|
||||||
|
node.classList.add('filter');
|
||||||
|
node.textContent = entry.filter;
|
||||||
|
li.appendChild(node);
|
||||||
|
li.classList.add('isCosmeticHide');
|
||||||
|
}
|
||||||
|
return li;
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var appendListItem = function(ul, li) {
|
||||||
|
ul.appendChild(li);
|
||||||
|
// Ancestor nodes of a node which is affected by a cosmetic filter will
|
||||||
|
// be marked as "containing cosmetic filters", for user convenience.
|
||||||
|
if ( li.classList.contains('isCosmeticHide') === false ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (;;) {
|
||||||
|
li = li.parentElement.parentElement;
|
||||||
|
if ( li === null ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
li.classList.add('hasCosmeticHide');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var renderDOMFull = function(response) {
|
||||||
|
var ul = inspector.removeChild(domTree);
|
||||||
|
logger.removeAllChildren(domTree);
|
||||||
|
|
||||||
|
var lvl = 0;
|
||||||
|
var entries = response.layout;
|
||||||
|
var n = entries.length;
|
||||||
|
var li, entry;
|
||||||
|
for ( var i = 0; i < n; i++ ) {
|
||||||
|
entry = entries[i];
|
||||||
|
if ( entry.lvl === lvl ) {
|
||||||
|
li = nodeFromDomEntry(entry);
|
||||||
|
appendListItem(ul, li);
|
||||||
|
//expandIfBlockElement(li);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( entry.lvl > lvl ) {
|
||||||
|
ul = document.createElement('ul');
|
||||||
|
li.appendChild(ul);
|
||||||
|
li.classList.add('branch');
|
||||||
|
li = nodeFromDomEntry(entry);
|
||||||
|
appendListItem(ul, li);
|
||||||
|
//expandIfBlockElement(li);
|
||||||
|
lvl = entry.lvl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// entry.lvl < lvl
|
||||||
|
while ( entry.lvl < lvl ) {
|
||||||
|
ul = li.parentNode;
|
||||||
|
li = ul.parentNode;
|
||||||
|
ul = li.parentNode;
|
||||||
|
lvl -= 1;
|
||||||
|
}
|
||||||
|
li = nodeFromDomEntry(entry);
|
||||||
|
ul.appendChild(li);
|
||||||
|
}
|
||||||
|
while ( ul.parentNode !== null ) {
|
||||||
|
ul = ul.parentNode;
|
||||||
|
}
|
||||||
|
ul.firstElementChild.classList.add('show');
|
||||||
|
|
||||||
|
inspector.appendChild(domTree);
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var patchIncremental = function(from, delta) {
|
||||||
|
var span, cnt;
|
||||||
|
var li = from.parentElement.parentElement;
|
||||||
|
var patchCosmeticHide = delta >= 0 &&
|
||||||
|
from.classList.contains('isCosmeticFilter') &&
|
||||||
|
li.classList.contains('hasCosmeticFilter') === false;
|
||||||
|
// Include descendants count when removing a node
|
||||||
|
if ( delta < 0 ) {
|
||||||
|
delta -= countFromNode(from);
|
||||||
|
}
|
||||||
|
for ( ; li.localName === 'li'; li = li.parentElement.parentElement ) {
|
||||||
|
span = li.children[2];
|
||||||
|
if ( delta !== 0 ) {
|
||||||
|
cnt = countFromNode(li) + delta;
|
||||||
|
span.textContent = cnt !== 0 ? cnt.toLocaleString() : '';
|
||||||
|
span.setAttribute('data-cnt', cnt);
|
||||||
|
}
|
||||||
|
if ( patchCosmeticHide ) {
|
||||||
|
li.classList.add('hasCosmeticFilter');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var renderDOMIncremental = function(response) {
|
||||||
|
// Process each journal entry:
|
||||||
|
// 1 = node added
|
||||||
|
// -1 = node removed
|
||||||
|
var journal = response.journal;
|
||||||
|
var nodes = response.nodes;
|
||||||
|
var entry, previous, li, ul;
|
||||||
|
for ( var i = 0, n = journal.length; i < n; i++ ) {
|
||||||
|
entry = journal[i];
|
||||||
|
// Remove node
|
||||||
|
if ( entry.what === -1 ) {
|
||||||
|
li = document.getElementById(entry.nid);
|
||||||
|
if ( li === null ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
patchIncremental(li, -1);
|
||||||
|
li.parentNode.removeChild(li);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Modify node
|
||||||
|
if ( entry.what === 0 ) {
|
||||||
|
// TODO: update selector/filter
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Add node as sibling
|
||||||
|
if ( entry.what === 1 && entry.l ) {
|
||||||
|
previous = document.getElementById(entry.l);
|
||||||
|
// This should not happen
|
||||||
|
if ( previous === null ) {
|
||||||
|
// throw new Error('No left sibling!?');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ul = previous.parentElement;
|
||||||
|
li = nodeFromDomEntry(nodes[entry.nid]);
|
||||||
|
ul.insertBefore(li, previous.nextElementSibling);
|
||||||
|
patchIncremental(li, 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Add node as child
|
||||||
|
if ( entry.what === 1 && entry.u ) {
|
||||||
|
li = document.getElementById(entry.u);
|
||||||
|
// This should not happen
|
||||||
|
if ( li === null ) {
|
||||||
|
// throw new Error('No parent!?');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ul = li.querySelector('ul');
|
||||||
|
if ( ul === null ) {
|
||||||
|
ul = document.createElement('ul');
|
||||||
|
li.appendChild(ul);
|
||||||
|
li.classList.add('branch');
|
||||||
|
}
|
||||||
|
li = nodeFromDomEntry(nodes[entry.nid]);
|
||||||
|
ul.appendChild(li);
|
||||||
|
patchIncremental(li, 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var countFromNode = function(li) {
|
||||||
|
var span = li.children[2];
|
||||||
|
var cnt = parseInt(span.getAttribute('data-cnt'), 10);
|
||||||
|
return isNaN(cnt) ? cnt : 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var selectorFromNode = function(node, nth) {
|
||||||
|
var selector = '';
|
||||||
|
var code;
|
||||||
|
if ( nth === undefined ) {
|
||||||
|
nth = 1;
|
||||||
|
}
|
||||||
|
while ( node !== null ) {
|
||||||
|
if ( node.localName === 'li' ) {
|
||||||
|
code = node.querySelector('code:nth-of-type(' + nth + ')');
|
||||||
|
if ( code !== null ) {
|
||||||
|
selector = code.textContent + ' > ' + selector;
|
||||||
|
if ( selector.indexOf('#') !== -1 ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nth = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node = node.parentElement;
|
||||||
|
}
|
||||||
|
return selector.slice(0, -3);
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var nidFromNode = function(node) {
|
||||||
|
var li = node;
|
||||||
|
while ( li !== null ) {
|
||||||
|
if ( li.localName === 'li' ) {
|
||||||
|
return li.id || '';
|
||||||
|
}
|
||||||
|
li = li.parentElement;
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var startDialog = (function() {
|
||||||
|
var dialog = uDom.nodeFromId('cosmeticFilteringDialog');
|
||||||
|
var candidateFilters = [];
|
||||||
|
|
||||||
|
var onClick = function(ev) {
|
||||||
|
var target = ev.target;
|
||||||
|
|
||||||
|
// click outside the dialog proper
|
||||||
|
if ( target.classList.contains('modalDialog') ) {
|
||||||
|
return stop();
|
||||||
|
}
|
||||||
|
ev.stopPropagation();
|
||||||
|
};
|
||||||
|
|
||||||
|
var stop = function() {
|
||||||
|
dialog.removeEventListener('click', onClick, true);
|
||||||
|
document.body.removeChild(dialog);
|
||||||
|
};
|
||||||
|
|
||||||
|
var start = function() {
|
||||||
|
// Collect all selectors which are currently toggled
|
||||||
|
var node, filters = [];
|
||||||
|
var nodes = domTree.querySelectorAll('code.off');
|
||||||
|
for ( var i = 0; i < nodes.length; i++ ) {
|
||||||
|
node = nodes[i];
|
||||||
|
if ( node.classList.contains('filter') ) {
|
||||||
|
filters.push({
|
||||||
|
prefix: '#@#',
|
||||||
|
nid: '',
|
||||||
|
selector: node.textContent
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
filters.push({
|
||||||
|
prefix: '##',
|
||||||
|
nid: nidFromNode(node),
|
||||||
|
selector: node.textContent
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Send filters through dom-inspector.js for further processing.
|
||||||
|
|
||||||
|
candidateFilters = filters;
|
||||||
|
var taValue = [], filter;
|
||||||
|
for ( i = 0; i < filters.length; i++ ) {
|
||||||
|
filter = filters[i];
|
||||||
|
taValue.push(inspectedHostname + filter.prefix + filter.selector);
|
||||||
|
}
|
||||||
|
dialog.querySelector('textarea').value = taValue.join('\n');
|
||||||
|
document.body.appendChild(dialog);
|
||||||
|
dialog.addEventListener('click', onClick, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
return start;
|
||||||
|
})();
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var onClick = function(ev) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
|
||||||
|
if ( inspectedTabId === '' ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var target = ev.target;
|
||||||
|
var parent = target.parentElement;
|
||||||
|
|
||||||
|
// Expand/collapse branch
|
||||||
|
if (
|
||||||
|
target.localName === 'span' &&
|
||||||
|
parent instanceof HTMLLIElement &&
|
||||||
|
parent.classList.contains('branch') &&
|
||||||
|
target === parent.firstElementChild
|
||||||
|
) {
|
||||||
|
target.parentElement.classList.toggle('show');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle selector
|
||||||
|
if ( target.localName === 'code' ) {
|
||||||
|
var original = target.classList.contains('filter') === false;
|
||||||
|
messager.send({
|
||||||
|
what: 'postMessageTo',
|
||||||
|
senderTabId: null,
|
||||||
|
senderChannel: 'logger-ui.js',
|
||||||
|
receiverTabId: inspectedTabId,
|
||||||
|
receiverChannel: 'dom-inspector.js',
|
||||||
|
msg: {
|
||||||
|
what: 'toggleNodes',
|
||||||
|
original: original,
|
||||||
|
target: original !== target.classList.toggle('off'),
|
||||||
|
selector: selectorFromNode(target, original ? 1 : 2),
|
||||||
|
nid: original ? nidFromNode(target) : ''
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var cantCreate = inspector.querySelector('#domTree .off') === null;
|
||||||
|
inspector.querySelector('.permatoolbar .revert').classList.toggle('disabled', cantCreate);
|
||||||
|
inspector.querySelector('.permatoolbar .commit').classList.toggle('disabled', cantCreate);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var onMouseOver = (function() {
|
||||||
|
var mouseoverTarget = null;
|
||||||
|
var mouseoverTimer = null;
|
||||||
|
|
||||||
|
var timerHandler = function() {
|
||||||
|
mouseoverTimer = null;
|
||||||
|
messager.send({
|
||||||
|
what: 'postMessageTo',
|
||||||
|
senderTabId: null,
|
||||||
|
senderChannel: 'logger-ui.js',
|
||||||
|
receiverTabId: inspectedTabId,
|
||||||
|
receiverChannel: 'dom-inspector.js',
|
||||||
|
msg: {
|
||||||
|
what: 'highlightOne',
|
||||||
|
selector: selectorFromNode(mouseoverTarget),
|
||||||
|
nid: nidFromNode(mouseoverTarget),
|
||||||
|
scrollTo: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return function(ev) {
|
||||||
|
if ( inspectedTabId === '' ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find closest `li`
|
||||||
|
var target = ev.target;
|
||||||
|
while ( target !== null ) {
|
||||||
|
if ( target.localName === 'li' ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
target = target.parentElement;
|
||||||
|
}
|
||||||
|
if ( target === mouseoverTarget ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mouseoverTarget = target;
|
||||||
|
if ( mouseoverTimer === null ) {
|
||||||
|
mouseoverTimer = vAPI.setTimeout(timerHandler, 50);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var currentTabId = function() {
|
||||||
|
if ( showdomButton.classList.contains('active') === false ) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
var tabId = logger.tabIdFromClassName(tabSelector.value) || '';
|
||||||
|
return tabId !== 'bts' ? tabId : '';
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var cancelPollTimer = function() {
|
||||||
|
if ( pollTimer !== null ) {
|
||||||
|
clearTimeout(pollTimer);
|
||||||
|
pollTimer = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var onDOMFetched = function(response) {
|
||||||
|
if ( response === undefined || currentTabId() !== inspectedTabId ) {
|
||||||
|
shutdownInspector(inspectedTabId);
|
||||||
|
injectInspectorAsync(250);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ( response.status ) {
|
||||||
|
case 'full':
|
||||||
|
renderDOMFull(response);
|
||||||
|
fingerprint = response.fingerprint;
|
||||||
|
inspectedHostname = response.hostname;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'incremental':
|
||||||
|
renderDOMIncremental(response);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'nochange':
|
||||||
|
case 'busy':
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchDOMAsync();
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var fetchDOM = function() {
|
||||||
|
messager.send({
|
||||||
|
what: 'postMessageTo',
|
||||||
|
senderTabId: null,
|
||||||
|
senderChannel: 'logger-ui.js',
|
||||||
|
receiverTabId: inspectedTabId,
|
||||||
|
receiverChannel: 'dom-inspector.js',
|
||||||
|
msg: {
|
||||||
|
what: 'domLayout',
|
||||||
|
fingerprint: fingerprint
|
||||||
|
}
|
||||||
|
});
|
||||||
|
pollTimer = vAPI.setTimeout(function() {
|
||||||
|
pollTimer = null;
|
||||||
|
onDOMFetched();
|
||||||
|
}, 1001);
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var fetchDOMAsync = function(delay) {
|
||||||
|
if ( pollTimer !== null ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pollTimer = vAPI.setTimeout(function() {
|
||||||
|
pollTimer = null;
|
||||||
|
fetchDOM();
|
||||||
|
}, delay || 1001);
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var injectInspector = function() {
|
||||||
|
var tabId = currentTabId();
|
||||||
|
// No valid tab, go back
|
||||||
|
if ( tabId === '' ) {
|
||||||
|
injectInspectorAsync();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
inspectedTabId = tabId;
|
||||||
|
fingerprint = null;
|
||||||
|
messager.send({
|
||||||
|
what: 'scriptlet',
|
||||||
|
tabId: tabId,
|
||||||
|
scriptlet: 'dom-inspector'
|
||||||
|
});
|
||||||
|
fetchDOMAsync(250);
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var injectInspectorAsync = function(delay) {
|
||||||
|
if ( pollTimer !== null ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( showdomButton.classList.contains('active') === false ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pollTimer = vAPI.setTimeout(function() {
|
||||||
|
pollTimer = null;
|
||||||
|
injectInspector();
|
||||||
|
}, delay || 1001);
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var shutdownInspector = function(tabId) {
|
||||||
|
messager.send({
|
||||||
|
what: 'postMessageTo',
|
||||||
|
senderTabId: null,
|
||||||
|
senderChannel: 'logger-ui.js',
|
||||||
|
receiverTabId: tabId,
|
||||||
|
receiverChannel: 'dom-inspector.js',
|
||||||
|
msg: { what: 'shutdown', }
|
||||||
|
});
|
||||||
|
logger.removeAllChildren(domTree);
|
||||||
|
cancelPollTimer();
|
||||||
|
inspectedTabId = '';
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var onTabIdChanged = function() {
|
||||||
|
if ( inspectedTabId !== currentTabId() ) {
|
||||||
|
shutdownInspector();
|
||||||
|
injectInspectorAsync(250);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var toggleHighlightMode = function() {
|
||||||
|
messager.send({
|
||||||
|
what: 'postMessageTo',
|
||||||
|
senderTabId: null,
|
||||||
|
senderChannel: 'logger-ui.js',
|
||||||
|
receiverTabId: inspectedTabId,
|
||||||
|
receiverChannel: 'dom-inspector.js',
|
||||||
|
msg: {
|
||||||
|
what: 'highlightMode',
|
||||||
|
invert: uDom.nodeFromSelector('#domInspector .permatoolbar .highlightMode').classList.toggle('invert')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var revert = function() {
|
||||||
|
uDom('#domTree .off').removeClass('off');
|
||||||
|
messager.send({
|
||||||
|
what: 'postMessageTo',
|
||||||
|
senderTabId: null,
|
||||||
|
senderChannel: 'logger-ui.js',
|
||||||
|
receiverTabId: inspectedTabId,
|
||||||
|
receiverChannel: 'dom-inspector.js',
|
||||||
|
msg: { what: 'resetToggledNodes' }
|
||||||
|
});
|
||||||
|
inspector.querySelector('.permatoolbar .revert').classList.add('disabled');
|
||||||
|
inspector.querySelector('.permatoolbar .commit').classList.add('disabled');
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var onMessage = function(request) {
|
||||||
|
var msg = request.what === 'postMessageTo' ? request.msg : request;
|
||||||
|
switch ( msg.what ) {
|
||||||
|
case 'domLayout':
|
||||||
|
cancelPollTimer();
|
||||||
|
onDOMFetched(msg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var toggleOn = function() {
|
||||||
|
window.addEventListener('beforeunload', toggleOff);
|
||||||
|
tabSelector.addEventListener('change', onTabIdChanged);
|
||||||
|
domTree.addEventListener('click', onClick, true);
|
||||||
|
domTree.addEventListener('mouseover', onMouseOver, true);
|
||||||
|
uDom.nodeFromSelector('#domInspector .permatoolbar .highlightMode').addEventListener('click', toggleHighlightMode);
|
||||||
|
uDom.nodeFromSelector('#domInspector .permatoolbar .revert').addEventListener('click', revert);
|
||||||
|
uDom.nodeFromSelector('#domInspector .permatoolbar .commit').addEventListener('click', startDialog);
|
||||||
|
inspector.classList.add('enabled');
|
||||||
|
messager.addListener(onMessage);
|
||||||
|
injectInspector();
|
||||||
|
// Adjust tree view for toolbar height
|
||||||
|
domTree.style.setProperty(
|
||||||
|
'margin-top',
|
||||||
|
inspector.querySelector('.permatoolbar').clientHeight + 'px'
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var toggleOff = function() {
|
||||||
|
messager.removeListener(onMessage);
|
||||||
|
cancelPollTimer();
|
||||||
|
shutdownInspector();
|
||||||
|
window.removeEventListener('beforeunload', toggleOff);
|
||||||
|
tabSelector.removeEventListener('change', onTabIdChanged);
|
||||||
|
domTree.removeEventListener('click', onClick, true);
|
||||||
|
domTree.removeEventListener('mouseover', onMouseOver, true);
|
||||||
|
uDom.nodeFromSelector('#domInspector .permatoolbar .highlightMode').removeEventListener('click', toggleHighlightMode);
|
||||||
|
uDom.nodeFromSelector('#domInspector .permatoolbar .revert').removeEventListener('click', revert);
|
||||||
|
uDom.nodeFromSelector('#domInspector .permatoolbar .commit').removeEventListener('click', startDialog);
|
||||||
|
inspectedTabId = '';
|
||||||
|
inspector.classList.remove('enabled');
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var toggle = function() {
|
||||||
|
if ( showdomButton.classList.toggle('active') ) {
|
||||||
|
toggleOn();
|
||||||
|
} else {
|
||||||
|
toggleOff();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
showdomButton.addEventListener('click', toggle);
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,30 @@
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var logger = self.logger = {};
|
||||||
|
var messager = logger.messager = vAPI.messaging.channel('logger-ui.js');
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var removeAllChildren = logger.removeAllChildren = function(node) {
|
||||||
|
while ( node.firstChild ) {
|
||||||
|
node.removeChild(node.firstChild);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var tabIdFromClassName = logger.tabIdFromClassName = function(className) {
|
||||||
|
var matches = className.match(/(?:^| )tab_([^ ]+)(?: |$)/);
|
||||||
|
if ( matches === null ) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return matches[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
// Adjust top padding of content table, to match that of toolbar height.
|
// Adjust top padding of content table, to match that of toolbar height.
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
@ -47,8 +71,6 @@
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var messager = vAPI.messaging.channel('logger-ui.js');
|
|
||||||
|
|
||||||
var tbody = document.querySelector('#events tbody');
|
var tbody = document.querySelector('#events tbody');
|
||||||
var trJunkyard = [];
|
var trJunkyard = [];
|
||||||
var tdJunkyard = [];
|
var tdJunkyard = [];
|
||||||
|
@ -61,7 +83,6 @@ var allTabIdsToken;
|
||||||
var hiddenTemplate = document.querySelector('#hiddenTemplate > span');
|
var hiddenTemplate = document.querySelector('#hiddenTemplate > span');
|
||||||
var reRFC3986 = /^([^:\/?#]+:)?(\/\/[^\/?#]*)?([^?#]*)(\?[^#]*)?(#.*)?/;
|
var reRFC3986 = /^([^:\/?#]+:)?(\/\/[^\/?#]*)?([^?#]*)(\?[^#]*)?(#.*)?/;
|
||||||
var netFilteringDialog = uDom.nodeFromId('netFilteringDialog');
|
var netFilteringDialog = uDom.nodeFromId('netFilteringDialog');
|
||||||
var filterFinderDialog = uDom.nodeFromId('filterFinderDialog');
|
|
||||||
|
|
||||||
var prettyRequestTypes = {
|
var prettyRequestTypes = {
|
||||||
'main_frame': 'doc',
|
'main_frame': 'doc',
|
||||||
|
@ -98,14 +119,6 @@ var dateOptions = {
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var removeAllChildren = function(node) {
|
|
||||||
while ( node.firstChild ) {
|
|
||||||
node.removeChild(node.firstChild);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
var classNameFromTabId = function(tabId) {
|
var classNameFromTabId = function(tabId) {
|
||||||
if ( tabId === noTabId ) {
|
if ( tabId === noTabId ) {
|
||||||
return 'tab_bts';
|
return 'tab_bts';
|
||||||
|
@ -116,503 +129,6 @@ var classNameFromTabId = function(tabId) {
|
||||||
return '';
|
return '';
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
var tabIdFromClassName = function(className) {
|
|
||||||
var matches = className.match(/(?:^| )tab_([^ ]+)(?: |$)/);
|
|
||||||
if ( matches === null ) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
return matches[1];
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
// DOM inspector
|
|
||||||
|
|
||||||
(function domInspector() {
|
|
||||||
// Don't bother if the browser is not modern enough.
|
|
||||||
if ( typeof Map === undefined || typeof WeakMap === undefined ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var inspectedTabId = '';
|
|
||||||
var currentSelector = '';
|
|
||||||
var showdomButton = uDom.nodeFromId('showdom');
|
|
||||||
var inspector = uDom.nodeFromId('domInspector');
|
|
||||||
var tabSelector = uDom.nodeFromId('pageSelector');
|
|
||||||
|
|
||||||
var nodeFromDomEntry = function(entry) {
|
|
||||||
var node, value;
|
|
||||||
var li = document.createElement('li');
|
|
||||||
li.setAttribute('id', entry.nid);
|
|
||||||
// expander/collapser
|
|
||||||
node = document.createElement('span');
|
|
||||||
li.appendChild(node);
|
|
||||||
// selector
|
|
||||||
node = document.createElement('code');
|
|
||||||
node.textContent = entry.sel;
|
|
||||||
li.appendChild(node);
|
|
||||||
// descendant count
|
|
||||||
value = entry.cnt || 0;
|
|
||||||
node = document.createElement('span');
|
|
||||||
node.textContent = value !== 0 ? value.toLocaleString() : '';
|
|
||||||
node.setAttribute('data-cnt', value);
|
|
||||||
li.appendChild(node);
|
|
||||||
// cosmetic filter
|
|
||||||
if ( entry.filter !== undefined ) {
|
|
||||||
node = document.createElement('code');
|
|
||||||
node.classList.add('filter');
|
|
||||||
node.textContent = entry.filter;
|
|
||||||
li.appendChild(node);
|
|
||||||
li.classList.add('isCosmeticHide');
|
|
||||||
}
|
|
||||||
return li;
|
|
||||||
};
|
|
||||||
|
|
||||||
var appendListItem = function(ul, li) {
|
|
||||||
ul.appendChild(li);
|
|
||||||
// Ancestor nodes of a node which is affected by a cosmetic filter will
|
|
||||||
// be marked as "containing cosmetic filters", for user convenience.
|
|
||||||
if ( li.classList.contains('isCosmeticHide') === false ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (;;) {
|
|
||||||
li = li.parentElement.parentElement;
|
|
||||||
if ( li === null ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
li.classList.add('hasCosmeticHide');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var renderDOMFull = function(response) {
|
|
||||||
var ul = document.createElement('ul');
|
|
||||||
var lvl = 0;
|
|
||||||
var entries = response.layout;
|
|
||||||
var n = entries.length;
|
|
||||||
var li, entry;
|
|
||||||
for ( var i = 0; i < n; i++ ) {
|
|
||||||
entry = entries[i];
|
|
||||||
if ( entry.lvl === lvl ) {
|
|
||||||
li = nodeFromDomEntry(entry);
|
|
||||||
appendListItem(ul, li);
|
|
||||||
//expandIfBlockElement(li);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ( entry.lvl > lvl ) {
|
|
||||||
ul = document.createElement('ul');
|
|
||||||
li.appendChild(ul);
|
|
||||||
li.classList.add('branch');
|
|
||||||
li = nodeFromDomEntry(entry);
|
|
||||||
appendListItem(ul, li);
|
|
||||||
//expandIfBlockElement(li);
|
|
||||||
lvl = entry.lvl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// entry.lvl < lvl
|
|
||||||
while ( entry.lvl < lvl ) {
|
|
||||||
ul = li.parentNode;
|
|
||||||
li = ul.parentNode;
|
|
||||||
ul = li.parentNode;
|
|
||||||
lvl -= 1;
|
|
||||||
}
|
|
||||||
li = nodeFromDomEntry(entry);
|
|
||||||
ul.appendChild(li);
|
|
||||||
}
|
|
||||||
while ( ul.parentNode !== null ) {
|
|
||||||
ul = ul.parentNode;
|
|
||||||
}
|
|
||||||
ul.firstElementChild.classList.add('show');
|
|
||||||
|
|
||||||
removeAllChildren(inspector);
|
|
||||||
inspector.appendChild(ul);
|
|
||||||
};
|
|
||||||
|
|
||||||
var patchIncremental = function(from, delta) {
|
|
||||||
var span, cnt;
|
|
||||||
var li = from.parentElement.parentElement;
|
|
||||||
var patchCosmeticHide = delta >= 0 &&
|
|
||||||
from.classList.contains('isCosmeticFilter') &&
|
|
||||||
li.classList.contains('hasCosmeticFilter') === false;
|
|
||||||
// Include descendants count when removing a node
|
|
||||||
if ( delta < 0 ) {
|
|
||||||
delta -= countFromNode(from);
|
|
||||||
}
|
|
||||||
for ( ; li.localName === 'li'; li = li.parentElement.parentElement ) {
|
|
||||||
span = li.children[2];
|
|
||||||
if ( delta !== 0 ) {
|
|
||||||
cnt = countFromNode(li) + delta;
|
|
||||||
span.textContent = cnt !== 0 ? cnt.toLocaleString() : '';
|
|
||||||
span.setAttribute('data-cnt', cnt);
|
|
||||||
}
|
|
||||||
if ( patchCosmeticHide ) {
|
|
||||||
li.classList.add('hasCosmeticFilter');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var renderDOMIncremental = function(response) {
|
|
||||||
// Process each journal entry:
|
|
||||||
// 1 = node added
|
|
||||||
// -1 = node removed
|
|
||||||
var journal = response.journal;
|
|
||||||
var nodes = response.nodes;
|
|
||||||
var entry, previous, li, ul;
|
|
||||||
for ( var i = 0, n = journal.length; i < n; i++ ) {
|
|
||||||
entry = journal[i];
|
|
||||||
// Remove node
|
|
||||||
if ( entry.what === -1 ) {
|
|
||||||
li = document.getElementById(entry.nid);
|
|
||||||
if ( li === null ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
patchIncremental(li, -1);
|
|
||||||
li.parentNode.removeChild(li);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Modify node
|
|
||||||
if ( entry.what === 0 ) {
|
|
||||||
// TODO: update selector/filter
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Add node as sibling
|
|
||||||
if ( entry.what === 1 && entry.l ) {
|
|
||||||
previous = document.getElementById(entry.l);
|
|
||||||
// This should not happen
|
|
||||||
if ( previous === null ) {
|
|
||||||
// throw new Error('No left sibling!?');
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ul = previous.parentElement;
|
|
||||||
li = nodeFromDomEntry(nodes[entry.nid]);
|
|
||||||
ul.insertBefore(li, previous.nextElementSibling);
|
|
||||||
patchIncremental(li, 1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Add node as child
|
|
||||||
if ( entry.what === 1 && entry.u ) {
|
|
||||||
li = document.getElementById(entry.u);
|
|
||||||
// This should not happen
|
|
||||||
if ( li === null ) {
|
|
||||||
// throw new Error('No parent!?');
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ul = li.querySelector('ul');
|
|
||||||
if ( ul === null ) {
|
|
||||||
ul = document.createElement('ul');
|
|
||||||
li.appendChild(ul);
|
|
||||||
li.classList.add('branch');
|
|
||||||
}
|
|
||||||
li = nodeFromDomEntry(nodes[entry.nid]);
|
|
||||||
ul.appendChild(li);
|
|
||||||
patchIncremental(li, 1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var countFromNode = function(li) {
|
|
||||||
var span = li.children[2];
|
|
||||||
var cnt = parseInt(span.getAttribute('data-cnt'), 10);
|
|
||||||
return isNaN(cnt) ? cnt : 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
var selectorFromNode = function(node, nth) {
|
|
||||||
var selector = '';
|
|
||||||
var code;
|
|
||||||
if ( nth === undefined ) {
|
|
||||||
nth = 1;
|
|
||||||
}
|
|
||||||
while ( node !== null ) {
|
|
||||||
if ( node.localName === 'li' ) {
|
|
||||||
code = node.querySelector('code:nth-of-type(' + nth + ')');
|
|
||||||
if ( code !== null ) {
|
|
||||||
selector = code.textContent + ' > ' + selector;
|
|
||||||
if ( selector.indexOf('#') !== -1 ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
nth = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
node = node.parentElement;
|
|
||||||
}
|
|
||||||
return selector.slice(0, -3);
|
|
||||||
};
|
|
||||||
|
|
||||||
var onClick = function(ev) {
|
|
||||||
ev.stopPropagation();
|
|
||||||
|
|
||||||
if ( inspectedTabId === '' ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var target = ev.target;
|
|
||||||
var parent = target.parentElement;
|
|
||||||
|
|
||||||
// Expand/collapse branch
|
|
||||||
if (
|
|
||||||
target.localName === 'span' &&
|
|
||||||
parent instanceof HTMLLIElement &&
|
|
||||||
parent.classList.contains('branch') &&
|
|
||||||
target === parent.firstElementChild
|
|
||||||
) {
|
|
||||||
target.parentElement.classList.toggle('show');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Toggle selector
|
|
||||||
if ( target.localName === 'code' ) {
|
|
||||||
var original = target.classList.contains('filter') === false;
|
|
||||||
messager.send({
|
|
||||||
what: 'postMessageTo',
|
|
||||||
senderTabId: null,
|
|
||||||
senderChannel: 'logger-ui.js',
|
|
||||||
receiverTabId: inspectedTabId,
|
|
||||||
receiverChannel: 'dom-inspector.js',
|
|
||||||
msg: {
|
|
||||||
what: 'toggleNodes',
|
|
||||||
original: original,
|
|
||||||
target: original !== target.classList.toggle('off'),
|
|
||||||
selector: selectorFromNode(target, original ? 1 : 2)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Highlight and scrollto
|
|
||||||
if ( target.localName === 'code' ) {
|
|
||||||
messager.send({
|
|
||||||
what: 'postMessageTo',
|
|
||||||
senderTabId: null,
|
|
||||||
senderChannel: 'logger-ui.js',
|
|
||||||
receiverTabId: inspectedTabId,
|
|
||||||
receiverChannel: 'dom-inspector.js',
|
|
||||||
msg: {
|
|
||||||
what: 'highlight',
|
|
||||||
selector: selectorFromNode(target),
|
|
||||||
scrollTo: true
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var onMouseOver = (function() {
|
|
||||||
var mouseoverTarget = null;
|
|
||||||
var mouseoverTimer = null;
|
|
||||||
|
|
||||||
var timerHandler = function() {
|
|
||||||
mouseoverTimer = null;
|
|
||||||
messager.send({
|
|
||||||
what: 'postMessageTo',
|
|
||||||
senderTabId: null,
|
|
||||||
senderChannel: 'logger-ui.js',
|
|
||||||
receiverTabId: inspectedTabId,
|
|
||||||
receiverChannel: 'dom-inspector.js',
|
|
||||||
msg: {
|
|
||||||
what: 'highlight',
|
|
||||||
selector: selectorFromNode(mouseoverTarget),
|
|
||||||
scrollTo: true
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return function(ev) {
|
|
||||||
if ( inspectedTabId === '' ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find closest `li`
|
|
||||||
var target = ev.target;
|
|
||||||
while ( target !== null ) {
|
|
||||||
if ( target.localName === 'li' ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
target = target.parentElement;
|
|
||||||
}
|
|
||||||
if ( target === mouseoverTarget ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mouseoverTarget = target;
|
|
||||||
if ( mouseoverTimer === null ) {
|
|
||||||
mouseoverTimer = vAPI.setTimeout(timerHandler, 50);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|
||||||
var pollTimer = null;
|
|
||||||
var fingerprint = null;
|
|
||||||
|
|
||||||
var currentTabId = function() {
|
|
||||||
if ( showdomButton.classList.contains('active') === false ) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
var tabId = tabIdFromClassName(tabSelector.value) || '';
|
|
||||||
return tabId !== 'bts' ? tabId : '';
|
|
||||||
};
|
|
||||||
|
|
||||||
var cancelPollTimer = function() {
|
|
||||||
if ( pollTimer !== null ) {
|
|
||||||
clearTimeout(pollTimer);
|
|
||||||
pollTimer = null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var onDOMFetched = function(response) {
|
|
||||||
if ( response === undefined || currentTabId() !== inspectedTabId ) {
|
|
||||||
shutdownInspector(inspectedTabId);
|
|
||||||
injectInspectorAsync(250);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ( response.status ) {
|
|
||||||
case 'full':
|
|
||||||
renderDOMFull(response);
|
|
||||||
fingerprint = response.fingerprint;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'incremental':
|
|
||||||
renderDOMIncremental(response);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'nochange':
|
|
||||||
case 'busy':
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fetchDOMAsync();
|
|
||||||
};
|
|
||||||
|
|
||||||
var fetchDOM = function() {
|
|
||||||
messager.send({
|
|
||||||
what: 'postMessageTo',
|
|
||||||
senderTabId: null,
|
|
||||||
senderChannel: 'logger-ui.js',
|
|
||||||
receiverTabId: inspectedTabId,
|
|
||||||
receiverChannel: 'dom-inspector.js',
|
|
||||||
msg: {
|
|
||||||
what: 'domLayout',
|
|
||||||
fingerprint: fingerprint
|
|
||||||
}
|
|
||||||
});
|
|
||||||
pollTimer = vAPI.setTimeout(function() {
|
|
||||||
pollTimer = null;
|
|
||||||
onDOMFetched();
|
|
||||||
}, 1001);
|
|
||||||
};
|
|
||||||
|
|
||||||
var fetchDOMAsync = function(delay) {
|
|
||||||
if ( pollTimer !== null ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pollTimer = vAPI.setTimeout(function() {
|
|
||||||
pollTimer = null;
|
|
||||||
fetchDOM();
|
|
||||||
}, delay || 1001);
|
|
||||||
};
|
|
||||||
|
|
||||||
var injectInspector = function() {
|
|
||||||
var tabId = currentTabId();
|
|
||||||
// No valid tab, go back
|
|
||||||
if ( tabId === '' ) {
|
|
||||||
injectInspectorAsync();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
inspectedTabId = tabId;
|
|
||||||
fingerprint = null;
|
|
||||||
messager.send({
|
|
||||||
what: 'scriptlet',
|
|
||||||
tabId: tabId,
|
|
||||||
scriptlet: 'dom-inspector'
|
|
||||||
});
|
|
||||||
fetchDOMAsync(250);
|
|
||||||
};
|
|
||||||
|
|
||||||
var injectInspectorAsync = function(delay) {
|
|
||||||
if ( pollTimer !== null ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ( showdomButton.classList.contains('active') === false ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pollTimer = vAPI.setTimeout(function() {
|
|
||||||
pollTimer = null;
|
|
||||||
injectInspector();
|
|
||||||
}, delay || 1001);
|
|
||||||
};
|
|
||||||
|
|
||||||
var shutdownInspector = function(tabId) {
|
|
||||||
messager.send({
|
|
||||||
what: 'postMessageTo',
|
|
||||||
senderTabId: null,
|
|
||||||
senderChannel: 'logger-ui.js',
|
|
||||||
receiverTabId: tabId,
|
|
||||||
receiverChannel: 'dom-inspector.js',
|
|
||||||
msg: { what: 'shutdown', }
|
|
||||||
});
|
|
||||||
removeAllChildren(inspector);
|
|
||||||
cancelPollTimer();
|
|
||||||
inspectedTabId = '';
|
|
||||||
};
|
|
||||||
|
|
||||||
var onTabIdChanged = function() {
|
|
||||||
if ( inspectedTabId !== currentTabId() ) {
|
|
||||||
shutdownInspector();
|
|
||||||
injectInspectorAsync(250);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var onMessage = function(request) {
|
|
||||||
var msg = request.what === 'postMessageTo' ? request.msg : request;
|
|
||||||
switch ( msg.what ) {
|
|
||||||
case 'domLayout':
|
|
||||||
cancelPollTimer();
|
|
||||||
onDOMFetched(msg);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var toggleOn = function() {
|
|
||||||
window.addEventListener('beforeunload', toggleOff);
|
|
||||||
inspector.addEventListener('click', onClick, true);
|
|
||||||
inspector.addEventListener('mouseover', onMouseOver, true);
|
|
||||||
tabSelector.addEventListener('change', onTabIdChanged);
|
|
||||||
inspector.classList.add('enabled');
|
|
||||||
messager.addListener(onMessage);
|
|
||||||
injectInspector();
|
|
||||||
};
|
|
||||||
|
|
||||||
var toggleOff = function() {
|
|
||||||
messager.removeListener(onMessage);
|
|
||||||
cancelPollTimer();
|
|
||||||
shutdownInspector();
|
|
||||||
window.removeEventListener('beforeunload', toggleOff);
|
|
||||||
inspector.removeEventListener('click', onClick, true);
|
|
||||||
inspector.removeEventListener('mouseover', onMouseOver, true);
|
|
||||||
tabSelector.removeEventListener('change', onTabIdChanged);
|
|
||||||
currentSelector = inspectedTabId = '';
|
|
||||||
inspector.classList.remove('enabled');
|
|
||||||
};
|
|
||||||
|
|
||||||
var toggle = function() {
|
|
||||||
if ( showdomButton.classList.toggle('active') ) {
|
|
||||||
toggleOn();
|
|
||||||
} else {
|
|
||||||
toggleOff();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
showdomButton.addEventListener('click', toggle);
|
|
||||||
})();
|
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
@ -1776,6 +1292,7 @@ var netFilteringManager = (function() {
|
||||||
var reverseLookupManager = (function() {
|
var reverseLookupManager = (function() {
|
||||||
var reSentence1 = /\{\{filter\}\}/g;
|
var reSentence1 = /\{\{filter\}\}/g;
|
||||||
var sentence1Template = vAPI.i18n('loggerStaticFilteringFinderSentence1');
|
var sentence1Template = vAPI.i18n('loggerStaticFilteringFinderSentence1');
|
||||||
|
var filterFinderDialog = uDom.nodeFromId('filterFinderDialog');
|
||||||
|
|
||||||
var removeAllChildren = function(node) {
|
var removeAllChildren = function(node) {
|
||||||
while ( node.firstChild ) {
|
while ( node.firstChild ) {
|
||||||
|
|
|
@ -144,8 +144,9 @@ var svgOcean = null;
|
||||||
var svgIslands = null;
|
var svgIslands = null;
|
||||||
var svgRoot = null;
|
var svgRoot = null;
|
||||||
var pickerRoot = null;
|
var pickerRoot = null;
|
||||||
var currentSelector = '';
|
var highlightedElements = [];
|
||||||
|
|
||||||
|
var nodeToIdMap = new WeakMap(); // No need to iterate
|
||||||
var toggledNodes = new Map();
|
var toggledNodes = new Map();
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -175,7 +176,6 @@ var domLayout = (function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
var idGenerator = 0;
|
var idGenerator = 0;
|
||||||
var nodeToIdMap = new WeakMap(); // No need to iterate
|
|
||||||
|
|
||||||
// This will be used to uniquely identify nodes across process.
|
// This will be used to uniquely identify nodes across process.
|
||||||
|
|
||||||
|
@ -209,7 +209,7 @@ var domLayout = (function() {
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
})();
|
})();
|
||||||
|
/*
|
||||||
var matchesSelector = (function() {
|
var matchesSelector = (function() {
|
||||||
if ( typeof Element.prototype.matches === 'function' ) {
|
if ( typeof Element.prototype.matches === 'function' ) {
|
||||||
return 'matches';
|
return 'matches';
|
||||||
|
@ -222,26 +222,7 @@ var domLayout = (function() {
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
})();
|
})();
|
||||||
|
*/
|
||||||
var hasManyMatches = function(node, selector) {
|
|
||||||
var fnName = matchesSelector;
|
|
||||||
if ( fnName === '' ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
var child = node.firstElementChild;
|
|
||||||
var match = false;
|
|
||||||
while ( child !== null ) {
|
|
||||||
if ( child[fnName](selector) ) {
|
|
||||||
if ( match ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
match = true;
|
|
||||||
}
|
|
||||||
child = child.nextElementSibling;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
var selectorFromNode = function(node) {
|
var selectorFromNode = function(node) {
|
||||||
var str, attr, pos, sw, i;
|
var str, attr, pos, sw, i;
|
||||||
var tag = node.localName;
|
var tag = node.localName;
|
||||||
|
@ -276,18 +257,6 @@ var domLayout = (function() {
|
||||||
selector += '[' + attr + sw + '="' + cssEscape(str) + '"]';
|
selector += '[' + attr + sw + '="' + cssEscape(str) + '"]';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// The resulting selector must cause only one element to be selected. If
|
|
||||||
// it's not the case, further narrow using `nth-of-type` pseudo-class.
|
|
||||||
if ( hasManyMatches(node.parentElement, selector) ) {
|
|
||||||
i = 1;
|
|
||||||
while ( node.previousElementSibling ) {
|
|
||||||
node = node.previousElementSibling;
|
|
||||||
if ( node.localName === tag ) {
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
selector += ':nth-of-type(' + i + ')';
|
|
||||||
}
|
|
||||||
return selector;
|
return selector;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -543,7 +512,8 @@ var domLayout = (function() {
|
||||||
|
|
||||||
var response = {
|
var response = {
|
||||||
what: 'domLayout',
|
what: 'domLayout',
|
||||||
fingerprint: domFingerprint()
|
fingerprint: domFingerprint(),
|
||||||
|
hostname: window.location.hostname
|
||||||
};
|
};
|
||||||
|
|
||||||
// No mutation observer means we need to send full layout
|
// No mutation observer means we need to send full layout
|
||||||
|
@ -593,7 +563,8 @@ var domLayout = (function() {
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var highlightElements = function(elems, scrollTo) {
|
var highlightElements = function(scrollTo) {
|
||||||
|
var elems = highlightedElements;
|
||||||
var wv = pickerRoot.contentWindow.innerWidth;
|
var wv = pickerRoot.contentWindow.innerWidth;
|
||||||
var hv = pickerRoot.contentWindow.innerHeight;
|
var hv = pickerRoot.contentWindow.innerHeight;
|
||||||
var ocean = ['M0 0h' + wv + 'v' + hv + 'h-' + wv, 'z'];
|
var ocean = ['M0 0h' + wv + 'v' + hv + 'h-' + wv, 'z'];
|
||||||
|
@ -684,15 +655,31 @@ var elementsFromSelector = function(filter) {
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var highlight = function(scrollTo) {
|
var selectNodes = function(selector, nid) {
|
||||||
var elements = elementsFromSelector(currentSelector);
|
var nodes = elementsFromSelector(selector);
|
||||||
highlightElements(elements, scrollTo);
|
if ( nid === '' ) {
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
var i = nodes.length;
|
||||||
|
while ( i-- ) {
|
||||||
|
if ( nodeToIdMap.get(nodes[i]) === nid ) {
|
||||||
|
return [nodes[i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var hightlightNodes = function(selector, nid, scrollTo) {
|
||||||
|
highlightedElements = selectNodes(selector, nid);
|
||||||
|
highlightElements(scrollTo);
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var onScrolled = function() {
|
var onScrolled = function() {
|
||||||
highlight();
|
highlightElements();
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -703,8 +690,7 @@ var onScrolled = function() {
|
||||||
// hidden, any = remove display property, don't remember original state
|
// hidden, any = remove display property, don't remember original state
|
||||||
// hidden, hidden = set display to `none`
|
// hidden, hidden = set display to `none`
|
||||||
|
|
||||||
var toggleNodes = function(selector, originalState, targetState) {
|
var toggleNodes = function(nodes, originalState, targetState) {
|
||||||
var nodes = document.querySelectorAll(selector);
|
|
||||||
var i = nodes.length;
|
var i = nodes.length;
|
||||||
if ( i === 0 ) {
|
if ( i === 0 ) {
|
||||||
return;
|
return;
|
||||||
|
@ -759,13 +745,13 @@ var resetToggledNodes = function() {
|
||||||
var shutdown = function() {
|
var shutdown = function() {
|
||||||
resetToggledNodes();
|
resetToggledNodes();
|
||||||
domLayout.shutdown();
|
domLayout.shutdown();
|
||||||
localMessager.removeListener(onMessage);
|
localMessager.removeAllListeners();
|
||||||
localMessager.close();
|
localMessager.close();
|
||||||
localMessager = null;
|
localMessager = null;
|
||||||
window.removeEventListener('scroll', onScrolled, true);
|
window.removeEventListener('scroll', onScrolled, true);
|
||||||
document.documentElement.removeChild(pickerRoot);
|
document.documentElement.removeChild(pickerRoot);
|
||||||
pickerRoot = svgRoot = svgOcean = svgIslands = null;
|
pickerRoot = svgRoot = svgOcean = svgIslands = null;
|
||||||
currentSelector = '';
|
highlightedElements = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -779,15 +765,22 @@ var onMessage = function(request) {
|
||||||
response = domLayout.get(msg.fingerprint);
|
response = domLayout.get(msg.fingerprint);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'highlight':
|
case 'highlightMode':
|
||||||
currentSelector = msg.selector;
|
svgRoot.classList.toggle('invert', msg.invert);
|
||||||
highlight(msg.scrollTo);
|
break;
|
||||||
|
|
||||||
|
case 'highlightOne':
|
||||||
|
hightlightNodes(msg.selector, msg.nid, msg.scrollTo);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'resetToggledNodes':
|
||||||
|
resetToggledNodes();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'toggleNodes':
|
case 'toggleNodes':
|
||||||
toggleNodes(msg.selector, msg.original, msg.target);
|
highlightedElements = selectNodes(msg.selector, msg.nid);
|
||||||
currentSelector = msg.selector;
|
toggleNodes(highlightedElements, msg.original, msg.target);
|
||||||
highlight(true);
|
highlightElements(true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'shutdown':
|
case 'shutdown':
|
||||||
|
@ -863,6 +856,13 @@ pickerRoot.onload = function() {
|
||||||
'stroke: #FFF;',
|
'stroke: #FFF;',
|
||||||
'stroke-width: 0.5px;',
|
'stroke-width: 0.5px;',
|
||||||
'}',
|
'}',
|
||||||
|
'svg.invert > path:first-child {',
|
||||||
|
'fill: rgba(0,0,255,0.1);',
|
||||||
|
'}',
|
||||||
|
'svg.invert > path + path {',
|
||||||
|
'fill: rgba(0,0,0,0.75);',
|
||||||
|
'stroke: #000;',
|
||||||
|
'}',
|
||||||
''
|
''
|
||||||
].join('\n');
|
].join('\n');
|
||||||
pickerDoc.body.appendChild(style);
|
pickerDoc.body.appendChild(style);
|
||||||
|
@ -876,7 +876,7 @@ pickerRoot.onload = function() {
|
||||||
|
|
||||||
window.addEventListener('scroll', onScrolled, true);
|
window.addEventListener('scroll', onScrolled, true);
|
||||||
|
|
||||||
highlight();
|
highlightElements();
|
||||||
|
|
||||||
localMessager.addListener(onMessage);
|
localMessager.addListener(onMessage);
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link rel="stylesheet" type="text/css" href="css/common.css">
|
<link rel="stylesheet" type="text/css" href="css/common.css">
|
||||||
<link rel="stylesheet" type="text/css" href="css/logger-ui.css">
|
<link rel="stylesheet" type="text/css" href="css/logger-ui.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/logger-ui-inspector.css">
|
||||||
<title data-i18n="statsPageName"></title>
|
<title data-i18n="statsPageName"></title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -20,6 +21,14 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="domInspector">
|
<div id="domInspector">
|
||||||
|
<div class="permatoolbar">
|
||||||
|
<div>
|
||||||
|
<span class="button fa highlightMode"></span>
|
||||||
|
<span class="button fa revert disabled"></span>
|
||||||
|
<span class="button fa commit disabled"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ul id="domTree"></ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="events" class="compactView f">
|
<div id="events" class="compactView f">
|
||||||
|
@ -88,7 +97,9 @@
|
||||||
<div class="dialog"></div>
|
<div class="dialog"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="cosmeticFilteringDialog" class="modalDialog">
|
<div id="cosmeticFilteringDialog" class="modalDialog">
|
||||||
<div class="dialog"></div>
|
<div class="dialog">
|
||||||
|
<p><textarea class="cosmeticFilters" value=""></textarea>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="filterFinderDialogSentence1"><span><span></span><code></code><span></span></span></div>
|
<div id="filterFinderDialogSentence1"><span><span></span><code></code><span></span></span></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -98,6 +109,7 @@
|
||||||
<script src="js/udom.js"></script>
|
<script src="js/udom.js"></script>
|
||||||
<script src="js/i18n.js"></script>
|
<script src="js/i18n.js"></script>
|
||||||
<script src="js/logger-ui.js"></script>
|
<script src="js/logger-ui.js"></script>
|
||||||
|
<script src="js/logger-ui-inspector.js"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in New Issue