1
0
Fork 0
mirror of https://github.com/gorhill/uMatrix.git synced 2024-06-17 09:44:59 +12:00

polish recipe-related code, user interface

This commit is contained in:
Raymond Hill 2018-03-24 08:01:25 -04:00
parent 707fd92307
commit 24289831c2
No known key found for this signature in database
GPG key ID: 25E1490B761470C2
7 changed files with 154 additions and 104 deletions

View file

@ -155,6 +155,14 @@
"message": "No web page found", "message": "No web page found",
"description": "Displays in place of matrix when no data is found for the current page" "description": "Displays in place of matrix when no data is found for the current page"
}, },
"matrixRecipeImportTip" : {
"message": "Import rules",
"description": "Used as a tooltip for the recipe import button"
},
"matrixRecipeSaveTip" : {
"message": "Save rules",
"description": "Used as a tooltip for the recipe padlock button"
},
"statsPageTitle" : { "statsPageTitle" : {
"message": "uMatrix – Statistics", "message": "uMatrix – Statistics",

View file

@ -159,7 +159,7 @@ body .toolbar button.fa {
} }
.dropdown-menu-capture { .dropdown-menu-capture {
background-color: transparent; background-color: rgba(0,0,0,0.2);
border: 0; border: 0;
bottom: 0; bottom: 0;
display: none; display: none;
@ -171,6 +171,10 @@ body .toolbar button.fa {
top: 0; top: 0;
z-index: 300; z-index: 300;
} }
.dropdown-menu-capture.dropdown-menu-centered > .dropdown-menu {
left: 4em;
right: 4em;
}
.dropdown-menu-capture.show { .dropdown-menu-capture.show {
display: block; display: block;
} }
@ -211,14 +215,15 @@ body .toolbar button.fa {
} }
button > span.badge { button > span.badge {
padding: 1px 1px; background-color: rgba(240,240,240,0.75);
display: inline-block;
font-size: 40%;
position: absolute;
right: 1px;
bottom: 1px; bottom: 1px;
color: #000; color: #000;
background-color: rgba(240,240,240,0.75) display: inline-block;
font-size: 40%;
padding: 1px 1px;
pointer-events: none;
position: absolute;
right: 1px;
} }
button.disabled > span.badge { button.disabled > span.badge {
display: none; display: none;
@ -238,7 +243,6 @@ button.disabled > span.badge {
padding: 0; padding: 0;
} }
.recipe { .recipe {
cursor: pointer;
list-style-type: none; list-style-type: none;
white-space: nowrap; white-space: nowrap;
} }
@ -266,15 +270,21 @@ button.disabled > span.badge {
} }
.recipe .name { .recipe .name {
color: #000; color: #000;
cursor: default;
flex-grow: 1; flex-grow: 1;
padding: 0.4em 0;
} }
.recipe .importer,
.recipe .committer { .recipe .committer {
cursor: pointer;
display: none; display: none;
font-size: 120%; font-size: 120%;
padding: 0.4em; padding: 0.4em;
width: 0.8em; text-align: center;
width: 1em;
} }
.recipe.mustCommit .committer { .recipe.mustImport .importer,
.recipe.mustCommit:not(.mustImport) .committer {
display: inline; display: inline;
} }
.recipe:hover { .recipe:hover {

View file

@ -21,7 +21,7 @@
<div class="assets"> <div class="assets">
<div data-i18n="assetsHostsSection"></div> <div data-i18n="assetsHostsSection"></div>
<div> <div>
<p data-i18n="hostsFilesPrompt"></p> <p><span data-i18n="hostsFilesPrompt"></span>&nbsp;<a class="fa info" href="https://github.com/gorhill/uMatrix/wiki/Preset-whitelisted-and-blacklisted-domains#preset-blacklist-rules" target="_blank">&#xf05a;</a></p>
<p id="listsOfBlockedHostsPrompt"></p> <p id="listsOfBlockedHostsPrompt"></p>
<ul id="hosts"> <ul id="hosts">
<li class="listEntry notAnAsset toImport"><input type="checkbox" id="importHosts"><label for="importHosts" data-i18n="assetsImportLabel"></label><!-- <li class="listEntry notAnAsset toImport"><input type="checkbox" id="importHosts"><label for="importHosts" data-i18n="assetsImportLabel"></label><!--
@ -33,7 +33,7 @@
<div class="assets"> <div class="assets">
<div data-i18n="assetsRecipesSection"></div> <div data-i18n="assetsRecipesSection"></div>
<div> <div>
<p data-i18n="assetsRecipesSummary"></p> <p><span data-i18n="assetsRecipesSummary"></span>&nbsp;<a class="fa info" href="https://github.com/gorhill/uMatrix/wiki/Ruleset-recipes" target="_blank">&#xf05a;</a></p>
<ul id="recipes"> <ul id="recipes">
<li class="listEntry notAnAsset toImport"><input type="checkbox" id="importRecipes"><label for="importRecipes" data-i18n="assetsImportLabel"></label><!-- <li class="listEntry notAnAsset toImport"><input type="checkbox" id="importRecipes"><label for="importRecipes" data-i18n="assetsImportLabel"></label><!--
--><textarea dir="ltr" spellcheck="false" placeholder="hostsFilesExternalListsHint"></textarea> --><textarea dir="ltr" spellcheck="false" placeholder="hostsFilesExternalListsHint"></textarea>

View file

@ -349,7 +349,7 @@ var onMessage = function(request, sender, callback) {
break; break;
case 'fetchRecipeCommitStatuses': case 'fetchRecipeCommitStatuses':
response = µm.recipeManager.commitStatuses(request); response = µm.recipeManager.statuses(request);
break; break;
case 'toggleMatrixSwitch': case 'toggleMatrixSwitch':

View file

@ -1310,10 +1310,19 @@ let recipeManager = (function() {
} }
function apply(ev) { function apply(ev) {
if ( ev.target.classList.contains('expander') ) { if (
ev.target.classList.contains('expander') ||
ev.target.classList.contains('name')
) {
ev.currentTarget.classList.toggle('expanded'); ev.currentTarget.classList.toggle('expanded');
return; return;
} }
if (
ev.target.classList.contains('importer') === false &&
ev.target.classList.contains('committer') === false
) {
return;
}
let root = ev.currentTarget; let root = ev.currentTarget;
let ruleset = root.querySelector('.ruleset'); let ruleset = root.querySelector('.ruleset');
let commit = ev.target.classList.contains('committer'); let commit = ev.target.classList.contains('committer');
@ -1326,6 +1335,7 @@ let recipeManager = (function() {
}, },
updateMatrixSnapshot updateMatrixSnapshot
); );
root.classList.remove('mustImport');
if ( commit ) { if ( commit ) {
root.classList.remove('mustCommit'); root.classList.remove('mustCommit');
} }
@ -1341,6 +1351,7 @@ let recipeManager = (function() {
recipe.ruleset.replace(reScopeAlias, '$1' + details.scope + '$2'), recipe.ruleset.replace(reScopeAlias, '$1' + details.scope + '$2'),
ul ul
); );
li.classList.toggle('mustImport', recipe.mustImport === true);
li.classList.toggle('mustCommit', recipe.mustCommit === true); li.classList.toggle('mustCommit', recipe.mustCommit === true);
li.addEventListener('click', apply); li.addEventListener('click', apply);
} }
@ -1448,8 +1459,10 @@ function dropDownMenuShow(button) {
var menu = menuOverlay.querySelector('.dropdown-menu'); var menu = menuOverlay.querySelector('.dropdown-menu');
var menuRect = menu.getBoundingClientRect(); var menuRect = menu.getBoundingClientRect();
var menuLeft = butnNormalLeft * (viewRect.width - menuRect.width); var menuLeft = butnNormalLeft * (viewRect.width - menuRect.width);
menu.style.left = menuLeft.toFixed(0) + 'px';
menu.style.top = butnRect.bottom + 'px'; menu.style.top = butnRect.bottom + 'px';
if ( menuOverlay.classList.contains('dropdown-menu-centered') === false ) {
menu.style.left = menuLeft.toFixed(0) + 'px';
}
} }
function dropDownMenuHide() { function dropDownMenuHide() {

View file

@ -148,99 +148,118 @@
rawRecipes = []; rawRecipes = [];
}; };
return { // true = blocked, false = not blocked
apply: function(details) { var evaluateRuleParts = function(matrix, scope, parts) {
let µm = µMatrix; if ( parts[0].endsWith(':') ) {
let tMatrix = µm.tMatrix; return matrix.evaluateSwitchZ(parts[0].slice(0, -1), scope);
let pMatrix = µm.pMatrix; }
let mustPersist = false; return matrix.evaluateCellZXY(scope, parts[1], parts[2]) === 1;
for ( let rule of details.ruleset.split('\n') ) { };
let parts = rule.split(/\s+/);
if ( parts.length < 2 ) { continue; } var api = {};
let f0 = parts[0];
let f1 = parts[1]; api.apply = function(details) {
// Switch let µm = µMatrix;
if ( f0.endsWith(':') ) { let tMatrix = µm.tMatrix;
f0 = f0.slice(0, -1); let pMatrix = µm.pMatrix;
if ( tMatrix.evaluateSwitchZ(f0, f1) !== false ) { let mustPersist = false;
tMatrix.setSwitchZ(f0, f1, false); for ( let rule of details.ruleset.split('\n') ) {
if ( details.commit ) { let parts = rule.split(/\s+/);
pMatrix.setSwitchZ(f0, f1, false); if ( parts.length < 2 ) { continue; }
mustPersist = true; let f0 = parts[0];
} let f1 = parts[1];
} // Switch
continue; if ( f0.endsWith(':') ) {
} f0 = f0.slice(0, -1);
// Rule if ( tMatrix.evaluateSwitchZ(f0, f1) !== false ) {
if ( parts.length < 3 ) { continue; } tMatrix.setSwitchZ(f0, f1, false);
let f2 = parts[2]; if ( details.commit ) {
let action = tMatrix.evaluateCellZXY(f0, f1, f2); pMatrix.setSwitchZ(f0, f1, false);
if ( (action & 3) === 1 ) { mustPersist = true;
tMatrix.whitelistCell(f0, f1, f2);
}
if ( details.commit !== true ) { continue; }
action = pMatrix.evaluateCellZXY(f0, f1, f2);
if ( (action & 3) === 1 ) {
pMatrix.whitelistCell(f0, f1, f2);
mustPersist = true;
}
}
if ( mustPersist ) {
µm.saveMatrix();
}
},
fetch: function(srcHostname, desHostnames, callback) {
fromPendingStrings();
let out = [];
let fetched = new Set();
let tokens = getTokens(srcHostname + ' ' + desHostnames.join(' '));
for ( let token of tokens ) {
let recipes = recipeBook.get(token);
if ( recipes === undefined ) { continue; }
for ( let recipe of recipes ) {
if ( fetched.has(recipe.id) ) { continue; }
if (
conditionMatch(
recipe.condition,
srcHostname,
desHostnames
)
) {
out.push(recipe);
fetched.add(recipe.id);
} }
} }
continue;
} }
callback(out); // Rule
}, if ( parts.length < 3 ) { continue; }
commitStatuses: function(details) { let f2 = parts[2];
let matrix = µMatrix.pMatrix; let action = tMatrix.evaluateCellZXY(f0, f1, f2);
for ( let recipe of details.recipes ) { if ( (action & 3) === 1 ) {
let ruleIter = new µMatrix.LineIterator(recipe.ruleset); tMatrix.whitelistCell(f0, f1, f2);
while ( ruleIter.eot() === false ) {
let parts = ruleIter.next().split(/\s+/);
if (
matrix.evaluateCellZXY(
details.scope,
parts[1],
parts[2]
) === 1
) {
recipe.mustCommit = true;
break;
}
}
} }
return details; if ( details.commit !== true ) { continue; }
}, action = pMatrix.evaluateCellZXY(f0, f1, f2);
fromString: function(raw) { if ( (action & 3) === 1 ) {
rawRecipes.push(raw); pMatrix.whitelistCell(f0, f1, f2);
}, mustPersist = true;
reset: function() { }
rawRecipes.length = 0; }
recipeBook.clear(); if ( mustPersist ) {
µm.saveMatrix();
} }
}; };
api.fetch = function(srcHostname, desHostnames, callback) {
fromPendingStrings();
let out = [];
let fetched = new Set();
let tokens = getTokens(srcHostname + ' ' + desHostnames.join(' '));
for ( let token of tokens ) {
let recipes = recipeBook.get(token);
if ( recipes === undefined ) { continue; }
for ( let recipe of recipes ) {
if ( fetched.has(recipe.id) ) { continue; }
if (
conditionMatch(
recipe.condition,
srcHostname,
desHostnames
)
) {
out.push(recipe);
fetched.add(recipe.id);
}
}
}
callback(out);
};
api.statuses = function(details) {
let pMatrix = µMatrix.pMatrix,
tMatrix = µMatrix.tMatrix;
for ( let recipe of details.recipes ) {
let ruleIter = new µMatrix.LineIterator(recipe.ruleset);
while ( ruleIter.eot() === false ) {
let parts = ruleIter.next().split(/\s+/);
if (
recipe.mustCommit !== true &&
evaluateRuleParts(pMatrix, details.scope, parts)
) {
recipe.mustCommit = true;
if ( recipe.mustImport ) { break; }
}
if (
recipe.mustImport !== true &&
evaluateRuleParts(tMatrix, details.scope, parts)
) {
recipe.mustImport = true;
if ( recipe.mustCommit ) { break; }
}
}
}
return details;
};
api.fromString = function(raw) {
rawRecipes.push(raw);
};
api.reset = function() {
rawRecipes.length = 0;
recipeBook.clear();
};
return api;
})(); })();
/******************************************************************************/ /******************************************************************************/

View file

@ -74,7 +74,7 @@
</div> </div>
</div> </div>
<div id="dropDownMenuRecipes" class="dropdown-menu-capture"> <div id="dropDownMenuRecipes" class="dropdown-menu-capture dropdown-menu-centered">
<div class="dropdown-menu"> <div class="dropdown-menu">
<ul></ul> <ul></ul>
</div> </div>
@ -111,7 +111,7 @@
</symbol> </symbol>
</svg> </svg>
--> -->
<li class="recipe"><div><span class="expander"></span><span class="name"></span><span class="fa committer">&#xf13e;</span></div><div class="ruleset"></div></li> <li class="recipe"><div><span class="expander"></span><span class="name"></span><span class="fa importer" title="matrixRecipeImportTip">&#xf019;</span><span class="fa committer" title="matrixRecipeSaveTip">&#xf13e;</span></div><div class="ruleset"></div></li>
</div> </div>
<script src="lib/punycode.js"></script> <script src="lib/punycode.js"></script>