mirror of https://github.com/gorhill/uBlock.git
This commit is contained in:
parent
9099c09ea8
commit
e475e1ece8
|
@ -42,7 +42,15 @@ button:not(:disabled):hover {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
#create:not(:disabled) {
|
#create:not(:disabled) {
|
||||||
background-color: #ffdca8;
|
background-color: hsl(36, 100%, 83%);
|
||||||
|
border-color: hsl(36, 50%, 60%);
|
||||||
|
}
|
||||||
|
#preview {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
body.preview #preview {
|
||||||
|
background-color: hsl(204, 100%, 83%);
|
||||||
|
border-color: hsl(204, 50%, 60%);
|
||||||
}
|
}
|
||||||
section {
|
section {
|
||||||
border: 0;
|
border: 0;
|
||||||
|
@ -78,7 +86,7 @@ ul {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
aside > ul {
|
aside > ul {
|
||||||
height: 16em;
|
max-height: 16em;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
aside > ul > li:first-of-type {
|
aside > ul > li:first-of-type {
|
||||||
|
@ -124,14 +132,19 @@ svg > path:first-child {
|
||||||
svg > path + path {
|
svg > path + path {
|
||||||
stroke: #F00;
|
stroke: #F00;
|
||||||
stroke-width: 0.5px;
|
stroke-width: 0.5px;
|
||||||
fill: rgba(255,31,31,0.25);
|
fill: rgba(255,63,63,0.20);
|
||||||
|
}
|
||||||
|
body.preview svg > path:first-child {
|
||||||
|
fill: rgba(0,0,0,0.10);
|
||||||
|
}
|
||||||
|
body.preview svg > path + path {
|
||||||
|
fill: rgba(0,0,0,0.10);
|
||||||
}
|
}
|
||||||
aside {
|
aside {
|
||||||
background-color: #eee;
|
background-color: #eee;
|
||||||
bottom: 4px;
|
bottom: 4px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
height: calc(40% - 4px);
|
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
right: 4px;
|
right: 4px;
|
||||||
|
@ -154,7 +167,8 @@ body.paused > aside:hover {
|
||||||
<section>
|
<section>
|
||||||
<textarea lang="en" dir="ltr" spellcheck="false"></textarea>
|
<textarea lang="en" dir="ltr" spellcheck="false"></textarea>
|
||||||
<div><!--
|
<div><!--
|
||||||
--><button id="create" type="button" disabled="disabled">{{create}}</button><!--
|
--><button id="preview" type="button">{{preview}}</button><!--
|
||||||
|
--><button id="create" type="button" disabled>{{create}}</button><!--
|
||||||
--><button id="pick" type="button">{{pick}}</button><!--
|
--><button id="pick" type="button">{{pick}}</button><!--
|
||||||
--><button id="quit" type="button">{{quit}}</button><!--
|
--><button id="quit" type="button">{{quit}}</button><!--
|
||||||
--></div>
|
--></div>
|
||||||
|
|
|
@ -19,8 +19,6 @@
|
||||||
Home: https://github.com/gorhill/uBlock
|
Home: https://github.com/gorhill/uBlock
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* global µBlock, vAPI */
|
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
@ -603,6 +601,7 @@ var onMessage = function(request, sender, callback) {
|
||||||
create: vAPI.i18n('pickerCreate'),
|
create: vAPI.i18n('pickerCreate'),
|
||||||
pick: vAPI.i18n('pickerPick'),
|
pick: vAPI.i18n('pickerPick'),
|
||||||
quit: vAPI.i18n('pickerQuit'),
|
quit: vAPI.i18n('pickerQuit'),
|
||||||
|
preview: vAPI.i18n('pickerPreview'),
|
||||||
netFilters: vAPI.i18n('pickerNetFilters'),
|
netFilters: vAPI.i18n('pickerNetFilters'),
|
||||||
cosmeticFilters: vAPI.i18n('pickerCosmeticFilters'),
|
cosmeticFilters: vAPI.i18n('pickerCosmeticFilters'),
|
||||||
cosmeticFiltersHint: vAPI.i18n('pickerCosmeticFiltersHint')
|
cosmeticFiltersHint: vAPI.i18n('pickerCosmeticFiltersHint')
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
Home: https://github.com/gorhill/uBlock
|
Home: https://github.com/gorhill/uBlock
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* global CSS, CSSImportRule, CSSStyleRule */
|
/* global CSS */
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -133,7 +133,7 @@ var pickerRoot = document.getElementById(vAPI.sessionId);
|
||||||
if ( pickerRoot ) {
|
if ( pickerRoot ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
var pickerBody = null;
|
||||||
var pickerStyle = null;
|
var pickerStyle = null;
|
||||||
var svgOcean = null;
|
var svgOcean = null;
|
||||||
var svgIslands = null;
|
var svgIslands = null;
|
||||||
|
@ -145,6 +145,9 @@ var netFilterCandidates = [];
|
||||||
var cosmeticFilterCandidates = [];
|
var cosmeticFilterCandidates = [];
|
||||||
|
|
||||||
var targetElements = [];
|
var targetElements = [];
|
||||||
|
var candidateElements = [];
|
||||||
|
var bestCandidateFilter = null;
|
||||||
|
var previewedElements = [];
|
||||||
|
|
||||||
var lastNetFilterSession = window.location.host + window.location.pathname;
|
var lastNetFilterSession = window.location.host + window.location.pathname;
|
||||||
var lastNetFilterHostname = '';
|
var lastNetFilterHostname = '';
|
||||||
|
@ -267,26 +270,51 @@ var highlightElements = function(elems, force) {
|
||||||
|
|
||||||
var filterElements = function(filter) {
|
var filterElements = function(filter) {
|
||||||
var items = elementsFromFilter(filter);
|
var items = elementsFromFilter(filter);
|
||||||
var i = items.length, item;
|
var i = items.length, item, elem, style;
|
||||||
while ( i-- ) {
|
while ( i-- ) {
|
||||||
item = items[i];
|
item = items[i];
|
||||||
|
elem = item.elem;
|
||||||
|
style = elem.style;
|
||||||
if (
|
if (
|
||||||
item.type === 'cosmetic' ||
|
item.type === 'cosmetic' ||
|
||||||
item.type === 'network' && item.src !== undefined
|
item.type === 'network' && item.src !== undefined
|
||||||
) {
|
) {
|
||||||
item.elem.style.setProperty('display', 'none', 'important');
|
previewedElements.push({
|
||||||
|
elem: elem,
|
||||||
|
prop: 'display',
|
||||||
|
value: style.display
|
||||||
|
});
|
||||||
|
style.display = 'none';
|
||||||
}
|
}
|
||||||
if ( item.type === 'network' && item.style === 'background-image' ) {
|
if ( item.type === 'network' && item.style === 'background-image' ) {
|
||||||
item.elem.style.setProperty('background-image', 'none', 'important');
|
previewedElements.push({
|
||||||
|
elem: elem,
|
||||||
|
prop: 'background-image',
|
||||||
|
value: style.backgroundImage
|
||||||
|
});
|
||||||
|
style.backgroundImage = 'none';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var urlFromCSSPropertyValue = function(value) {
|
var preview = function(filter) {
|
||||||
var matches = /^url\((["']?)([^"']+)\1\)$/.exec(value);
|
filterElements(filter);
|
||||||
return matches !== null && matches.length === 3 ? matches[2] : '';
|
pickerBody.classList.add('preview');
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
var unpreview = function() {
|
||||||
|
var items = previewedElements;
|
||||||
|
var i = items.length, item;
|
||||||
|
while ( i-- ) {
|
||||||
|
item = items[i];
|
||||||
|
item.elem.style[item.prop] = item.value;
|
||||||
|
}
|
||||||
|
previewedElements.length = 0;
|
||||||
|
pickerBody.classList.remove('preview');
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -294,7 +322,8 @@ var urlFromCSSPropertyValue = function(value) {
|
||||||
var backgroundImageURLFromElement = function(elem) {
|
var backgroundImageURLFromElement = function(elem) {
|
||||||
var style = window.getComputedStyle(elem);
|
var style = window.getComputedStyle(elem);
|
||||||
var bgImg = style.backgroundImage || '';
|
var bgImg = style.backgroundImage || '';
|
||||||
return bgImg !== '' ? urlFromCSSPropertyValue(bgImg) : '';
|
var matches = /^url\((["']?)([^"']+)\1\)$/.exec(bgImg);
|
||||||
|
return matches !== null && matches.length === 3 ? matches[2] : '';
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -399,18 +428,25 @@ var netFilterFromUnion = (function() {
|
||||||
|
|
||||||
// Extract the best possible net filter, i.e. as specific as possible.
|
// Extract the best possible net filter, i.e. as specific as possible.
|
||||||
|
|
||||||
var netFilterFromElement = function(elem, out) {
|
var netFilterFromElement = function(elem) {
|
||||||
if ( elem === null ) {
|
if ( elem === null ) {
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
if ( elem.nodeType !== 1 ) {
|
if ( elem.nodeType !== 1 ) {
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
var src = resourceURLFromElement(elem);
|
var src = resourceURLFromElement(elem);
|
||||||
if ( src === '' ) {
|
if ( src === '' ) {
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( candidateElements.indexOf(elem) === -1 ) {
|
||||||
|
candidateElements.push(elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
var candidates = netFilterCandidates;
|
||||||
|
var len = candidates.length;
|
||||||
|
|
||||||
// Remove fragment
|
// Remove fragment
|
||||||
var pos = src.indexOf('#');
|
var pos = src.indexOf('#');
|
||||||
if ( pos !== -1 ) {
|
if ( pos !== -1 ) {
|
||||||
|
@ -419,17 +455,25 @@ var netFilterFromElement = function(elem, out) {
|
||||||
|
|
||||||
var filter = src.replace(/^https?:\/\//, '||');
|
var filter = src.replace(/^https?:\/\//, '||');
|
||||||
|
|
||||||
// Anchor absolute filter to hostname
|
if ( bestCandidateFilter === null ) {
|
||||||
out.push(filter);
|
bestCandidateFilter = {
|
||||||
|
filters: candidates,
|
||||||
|
slot: candidates.length
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
candidates.push(filter);
|
||||||
|
|
||||||
// Suggest a less narrow filter if possible
|
// Suggest a less narrow filter if possible
|
||||||
pos = filter.indexOf('?');
|
pos = filter.indexOf('?');
|
||||||
if ( pos !== -1 ) {
|
if ( pos !== -1 ) {
|
||||||
out.push(filter.slice(0, pos));
|
candidates.push(filter.slice(0, pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Suggest a filter which is a result of combining more than one URL.
|
// Suggest a filter which is a result of combining more than one URL.
|
||||||
netFilterFromUnion(src, out);
|
netFilterFromUnion(src, candidates);
|
||||||
|
|
||||||
|
return candidates.length - len;
|
||||||
};
|
};
|
||||||
|
|
||||||
var netFilter1stSources = {
|
var netFilter1stSources = {
|
||||||
|
@ -458,13 +502,18 @@ var filterTypes = {
|
||||||
|
|
||||||
// Extract the best possible cosmetic filter, i.e. as specific as possible.
|
// Extract the best possible cosmetic filter, i.e. as specific as possible.
|
||||||
|
|
||||||
var cosmeticFilterFromElement = function(elem, out) {
|
var cosmeticFilterFromElement = function(elem) {
|
||||||
if ( elem === null ) {
|
if ( elem === null ) {
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
if ( elem.nodeType !== 1 ) {
|
if ( elem.nodeType !== 1 ) {
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( candidateElements.indexOf(elem) === -1 ) {
|
||||||
|
candidateElements.push(elem);
|
||||||
|
}
|
||||||
|
|
||||||
var tagName = elem.tagName.toLowerCase();
|
var tagName = elem.tagName.toLowerCase();
|
||||||
var prefix = '';
|
var prefix = '';
|
||||||
var suffix = [];
|
var suffix = [];
|
||||||
|
@ -549,22 +598,25 @@ var cosmeticFilterFromElement = function(elem, out) {
|
||||||
selector += ':nth-of-type(' + i + ')';
|
selector += ':nth-of-type(' + i + ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
out.push('##' + selector);
|
if ( bestCandidateFilter === null ) {
|
||||||
|
bestCandidateFilter = {
|
||||||
|
filters: cosmeticFilterCandidates,
|
||||||
|
slot: cosmeticFilterCandidates.length
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
cosmeticFilterCandidates.push('##' + selector);
|
||||||
|
|
||||||
|
return 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var filtersFrom = function(x, y) {
|
var filtersFrom = function(x, y) {
|
||||||
|
bestCandidateFilter = null;
|
||||||
netFilterCandidates.length = 0;
|
netFilterCandidates.length = 0;
|
||||||
cosmeticFilterCandidates.length = 0;
|
cosmeticFilterCandidates.length = 0;
|
||||||
|
candidateElements.length = 0;
|
||||||
// This is to prevent revisiting the same element more than once.
|
|
||||||
var visited = typeof Set === 'function' ?
|
|
||||||
new Set() :
|
|
||||||
{
|
|
||||||
add: function() {},
|
|
||||||
has: function() { return true; }
|
|
||||||
};
|
|
||||||
|
|
||||||
// We need at least one element.
|
// We need at least one element.
|
||||||
var first = null;
|
var first = null;
|
||||||
|
@ -574,16 +626,16 @@ var filtersFrom = function(x, y) {
|
||||||
first = x;
|
first = x;
|
||||||
x = undefined;
|
x = undefined;
|
||||||
}
|
}
|
||||||
if ( first === null ) {
|
|
||||||
return 0;
|
// Network filter from element which was clicked.
|
||||||
|
if ( first !== null ) {
|
||||||
|
netFilterFromElement(first);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract filter candidates from self and all ancestors.
|
// Cosmetic filter candidates from ancestors.
|
||||||
var elem = first;
|
var elem = first;
|
||||||
while ( elem && elem !== document.body ) {
|
while ( elem && elem !== document.body ) {
|
||||||
netFilterFromElement(elem, netFilterCandidates);
|
cosmeticFilterFromElement(elem);
|
||||||
cosmeticFilterFromElement(elem, cosmeticFilterCandidates);
|
|
||||||
visited.add(elem);
|
|
||||||
elem = elem.parentNode;
|
elem = elem.parentNode;
|
||||||
}
|
}
|
||||||
// The body tag is needed as anchor only when the immediate child
|
// The body tag is needed as anchor only when the immediate child
|
||||||
|
@ -594,28 +646,27 @@ var filtersFrom = function(x, y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/gorhill/uBlock/issues/1545
|
// https://github.com/gorhill/uBlock/issues/1545
|
||||||
// Extract filter candidates from all elements found at point (x, y).
|
// Network filter candidates from all other elements found at point (x, y).
|
||||||
if ( typeof x === 'number' ) {
|
if ( typeof x === 'number' ) {
|
||||||
var attrName = vAPI.sessionId + '-clickblind';
|
var attrName = vAPI.sessionId + '-clickblind';
|
||||||
var previous;
|
var previous;
|
||||||
elem = first;
|
elem = first;
|
||||||
for (;;) {
|
while ( elem !== null ) {
|
||||||
previous = elem;
|
previous = elem;
|
||||||
elem.setAttribute(attrName, '');
|
elem.setAttribute(attrName, '');
|
||||||
elem = elementFromPoint(x, y, true);
|
elem = elementFromPoint(x, y);
|
||||||
if ( elem === null || elem === previous ) {
|
if ( elem === null || elem === previous ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( visited.has(elem) === false ) {
|
netFilterFromElement(elem);
|
||||||
netFilterFromElement(elem, netFilterCandidates);
|
|
||||||
visited.add(elem);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
var elems = document.querySelectorAll('[' + attrName + ']');
|
var elems = document.querySelectorAll('[' + attrName + ']');
|
||||||
i = elems.length;
|
i = elems.length;
|
||||||
while ( i-- ) {
|
while ( i-- ) {
|
||||||
elems[i].removeAttribute(attrName);
|
elems[i].removeAttribute(attrName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
netFilterFromElement(document.body);
|
||||||
}
|
}
|
||||||
|
|
||||||
return netFilterCandidates.length + cosmeticFilterCandidates.length;
|
return netFilterCandidates.length + cosmeticFilterCandidates.length;
|
||||||
|
@ -623,45 +674,6 @@ var filtersFrom = function(x, y) {
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var elementsFromStylesheet = function(sheet, reURL, out) {
|
|
||||||
var rules = sheet.rules;
|
|
||||||
if ( !rules ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var iRule = rules.length;
|
|
||||||
var rule, value, src, elems, iElem;
|
|
||||||
while ( iRule-- ) {
|
|
||||||
rule = rules[iRule];
|
|
||||||
if ( rule instanceof CSSImportRule ) {
|
|
||||||
elementsFromStylesheet(rule.styleSheet, reURL, out);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ( rule instanceof CSSStyleRule === false ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
value = rule.style.backgroundImage;
|
|
||||||
if ( value.lastIndexOf('url(', 0) !== 0 ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
src = urlFromCSSPropertyValue(value);
|
|
||||||
if ( reURL.test(src) === false ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
elems = document.querySelectorAll(rule.selectorText);
|
|
||||||
iElem = elems.length;
|
|
||||||
while ( iElem-- ) {
|
|
||||||
out.push({
|
|
||||||
type: 'network',
|
|
||||||
elem: elems[iElem],
|
|
||||||
style: 'background-image',
|
|
||||||
opts: 'image'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
var elementsFromFilter = function(filter) {
|
var elementsFromFilter = function(filter) {
|
||||||
var out = [];
|
var out = [];
|
||||||
|
|
||||||
|
@ -754,8 +766,8 @@ var elementsFromFilter = function(filter) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lookup by inline-styled background image.
|
// Find matching background image in current set of candidate elements.
|
||||||
elems = document.querySelectorAll('[style*="background-image"]');
|
elems = candidateElements;
|
||||||
iElem = elems.length;
|
iElem = elems.length;
|
||||||
while ( iElem-- ) {
|
while ( iElem-- ) {
|
||||||
elem = elems[iElem];
|
elem = elems[iElem];
|
||||||
|
@ -769,13 +781,6 @@ var elementsFromFilter = function(filter) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lookup by stylesheet-styled background image.
|
|
||||||
var sheets = document.styleSheets;
|
|
||||||
var iSheet = sheets.length;
|
|
||||||
while ( iSheet-- ) {
|
|
||||||
elementsFromStylesheet(sheets[iSheet], reFilter, out);
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -825,13 +830,15 @@ var userFilterFromCandidate = function() {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var onCandidateChanged = function() {
|
var onCandidateChanged = function() {
|
||||||
|
unpreview();
|
||||||
|
|
||||||
var elems = [];
|
var elems = [];
|
||||||
var items = elementsFromFilter(taCandidate.value);
|
var items = elementsFromFilter(taCandidate.value);
|
||||||
for ( var i = 0; i < items.length; i++ ) {
|
for ( var i = 0; i < items.length; i++ ) {
|
||||||
elems.push(items[i].elem);
|
elems.push(items[i].elem);
|
||||||
}
|
}
|
||||||
dialog.querySelector('#create').disabled = elems.length === 0;
|
dialog.querySelector('#create').disabled = elems.length === 0;
|
||||||
highlightElements(elems);
|
highlightElements(elems, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -846,7 +853,7 @@ var candidateFromFilterChoice = function(filterChoice) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// For net filters there no such thing as a path
|
// For net filters there no such thing as a path
|
||||||
if ( filterChoice.type === 'net' || filterChoice.modifier ) {
|
if ( filter.lastIndexOf('##', 0) !== 0 || filterChoice.modifier ) {
|
||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -869,7 +876,6 @@ var filterChoiceFromEvent = function(ev) {
|
||||||
var li = ev.target;
|
var li = ev.target;
|
||||||
var isNetFilter = li.textContent.slice(0, 2) !== '##';
|
var isNetFilter = li.textContent.slice(0, 2) !== '##';
|
||||||
var r = {
|
var r = {
|
||||||
type: isNetFilter ? 'net' : 'cosmetic',
|
|
||||||
filters: isNetFilter ? netFilterCandidates : cosmeticFilterCandidates,
|
filters: isNetFilter ? netFilterCandidates : cosmeticFilterCandidates,
|
||||||
slot: 0,
|
slot: 0,
|
||||||
modifier: ev.ctrlKey || ev.metaKey
|
modifier: ev.ctrlKey || ev.metaKey
|
||||||
|
@ -889,6 +895,10 @@ var onDialogClicked = function(ev) {
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ( ev.target.id === 'create' ) {
|
else if ( ev.target.id === 'create' ) {
|
||||||
|
// We have to exit from preview mode: this guarantees matching elements
|
||||||
|
// will be found for the candidate filter.
|
||||||
|
unpreview();
|
||||||
|
|
||||||
var filter = userFilterFromCandidate();
|
var filter = userFilterFromCandidate();
|
||||||
if ( filter ) {
|
if ( filter ) {
|
||||||
var d = new Date();
|
var d = new Date();
|
||||||
|
@ -909,9 +919,19 @@ var onDialogClicked = function(ev) {
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ( ev.target.id === 'quit' ) {
|
else if ( ev.target.id === 'quit' ) {
|
||||||
|
unpreview();
|
||||||
stopPicker();
|
stopPicker();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if ( ev.target.id === 'preview' ) {
|
||||||
|
if ( pickerBody.classList.contains('preview') ) {
|
||||||
|
unpreview();
|
||||||
|
} else {
|
||||||
|
preview(taCandidate.value);
|
||||||
|
}
|
||||||
|
highlightElements(targetElements, true);
|
||||||
|
}
|
||||||
|
|
||||||
else if ( ev.target.parentNode.classList.contains('changeFilter') ) {
|
else if ( ev.target.parentNode.classList.contains('changeFilter') ) {
|
||||||
taCandidate.value = candidateFromFilterChoice(filterChoiceFromEvent(ev));
|
taCandidate.value = candidateFromFilterChoice(filterChoiceFromEvent(ev));
|
||||||
onCandidateChanged();
|
onCandidateChanged();
|
||||||
|
@ -960,39 +980,31 @@ var showDialog = function(options) {
|
||||||
dialog.querySelector('#create').disabled = true;
|
dialog.querySelector('#create').disabled = true;
|
||||||
|
|
||||||
// Auto-select a candidate filter
|
// Auto-select a candidate filter
|
||||||
var filterChoice = {
|
|
||||||
type: '',
|
if ( bestCandidateFilter === null ) {
|
||||||
filters: [],
|
taCandidate.value = '';
|
||||||
slot: 0,
|
return;
|
||||||
modifier: options.modifier || false
|
|
||||||
};
|
|
||||||
if ( netFilterCandidates.length ) {
|
|
||||||
filterChoice.type = 'net';
|
|
||||||
filterChoice.filters = netFilterCandidates;
|
|
||||||
} else if ( cosmeticFilterCandidates.length ) {
|
|
||||||
filterChoice.type = 'cosmetic';
|
|
||||||
filterChoice.filters = cosmeticFilterCandidates;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
taCandidate.value = '';
|
var filterChoice = {
|
||||||
if ( filterChoice.type !== '' ) {
|
filters: bestCandidateFilter.filters,
|
||||||
taCandidate.value = candidateFromFilterChoice(filterChoice);
|
slot: bestCandidateFilter.slot,
|
||||||
onCandidateChanged();
|
modifier: options.modifier || false
|
||||||
}
|
};
|
||||||
|
|
||||||
|
taCandidate.value = candidateFromFilterChoice(filterChoice);
|
||||||
|
onCandidateChanged();
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var elementFromPoint = function(x, y, includeBody) {
|
var elementFromPoint = function(x, y) {
|
||||||
if ( !pickerRoot ) {
|
if ( !pickerRoot ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
pickerRoot.style.pointerEvents = 'none';
|
pickerRoot.style.pointerEvents = 'none';
|
||||||
var elem = document.elementFromPoint(x, y);
|
var elem = document.elementFromPoint(x, y);
|
||||||
if (
|
if ( elem === document.body || elem === document.documentElement ) {
|
||||||
elem === document.body && !includeBody ||
|
|
||||||
elem === document.documentElement
|
|
||||||
) {
|
|
||||||
elem = null;
|
elem = null;
|
||||||
}
|
}
|
||||||
pickerRoot.style.pointerEvents = '';
|
pickerRoot.style.pointerEvents = '';
|
||||||
|
@ -1027,7 +1039,7 @@ var onSvgHovered = (function() {
|
||||||
var onSvgClicked = function(ev) {
|
var onSvgClicked = function(ev) {
|
||||||
// https://github.com/chrisaljoudi/uBlock/issues/810#issuecomment-74600694
|
// https://github.com/chrisaljoudi/uBlock/issues/810#issuecomment-74600694
|
||||||
// Unpause picker if user click outside dialog
|
// Unpause picker if user click outside dialog
|
||||||
if ( dialog.parentNode.classList.contains('paused') ) {
|
if ( pickerBody.classList.contains('paused') ) {
|
||||||
unpausePicker();
|
unpausePicker();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1067,14 +1079,15 @@ var onScrolled = function() {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var pausePicker = function() {
|
var pausePicker = function() {
|
||||||
dialog.parentNode.classList.add('paused');
|
pickerBody.classList.add('paused');
|
||||||
svgListening(false);
|
svgListening(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var unpausePicker = function() {
|
var unpausePicker = function() {
|
||||||
dialog.parentNode.classList.remove('paused');
|
unpreview();
|
||||||
|
pickerBody.classList.remove('paused');
|
||||||
svgListening(true);
|
svgListening(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1085,6 +1098,9 @@ var unpausePicker = function() {
|
||||||
|
|
||||||
var stopPicker = function() {
|
var stopPicker = function() {
|
||||||
targetElements = [];
|
targetElements = [];
|
||||||
|
candidateElements = [];
|
||||||
|
bestCandidateFilter = null;
|
||||||
|
previewedElements = [];
|
||||||
|
|
||||||
if ( pickerRoot === null ) {
|
if ( pickerRoot === null ) {
|
||||||
return;
|
return;
|
||||||
|
@ -1100,6 +1116,7 @@ var stopPicker = function() {
|
||||||
pickerRoot.parentNode.removeChild(pickerRoot);
|
pickerRoot.parentNode.removeChild(pickerRoot);
|
||||||
pickerRoot.onload = null;
|
pickerRoot.onload = null;
|
||||||
pickerRoot =
|
pickerRoot =
|
||||||
|
pickerBody =
|
||||||
dialog =
|
dialog =
|
||||||
svgRoot = svgOcean = svgIslands =
|
svgRoot = svgOcean = svgIslands =
|
||||||
taCandidate = null;
|
taCandidate = null;
|
||||||
|
@ -1127,15 +1144,16 @@ var startPicker = function(details) {
|
||||||
frameDoc.documentElement
|
frameDoc.documentElement
|
||||||
);
|
);
|
||||||
|
|
||||||
frameDoc.body.setAttribute('lang', navigator.language);
|
pickerBody = frameDoc.body;
|
||||||
|
pickerBody.setAttribute('lang', navigator.language);
|
||||||
|
|
||||||
dialog = frameDoc.body.querySelector('aside');
|
dialog = pickerBody.querySelector('aside');
|
||||||
dialog.addEventListener('click', onDialogClicked);
|
dialog.addEventListener('click', onDialogClicked);
|
||||||
|
|
||||||
taCandidate = dialog.querySelector('textarea');
|
taCandidate = dialog.querySelector('textarea');
|
||||||
taCandidate.addEventListener('input', onCandidateChanged);
|
taCandidate.addEventListener('input', onCandidateChanged);
|
||||||
|
|
||||||
svgRoot = frameDoc.body.querySelector('svg');
|
svgRoot = pickerBody.querySelector('svg');
|
||||||
svgOcean = svgRoot.firstChild;
|
svgOcean = svgRoot.firstChild;
|
||||||
svgIslands = svgRoot.lastChild;
|
svgIslands = svgRoot.lastChild;
|
||||||
svgRoot.addEventListener('click', onSvgClicked);
|
svgRoot.addEventListener('click', onSvgClicked);
|
||||||
|
|
Loading…
Reference in New Issue