Allow element picker dialog to be moved around

Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/615

There is a grab area under the text area, to be used
to move the dialog around.
This commit is contained in:
Raymond Hill 2019-11-05 12:03:48 -05:00
parent 1026eb4d6c
commit d1995778ff
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
2 changed files with 87 additions and 37 deletions

View File

@ -20,6 +20,14 @@ html#ublock0-epicker,
#ublock0-epicker div {
display: block !important;
}
#ublock0-epicker #toolbar {
cursor: grab;
display: flex !important;
justify-content: space-between;
}
#ublock0-epicker aside.moving #toolbar {
cursor: grabbing;
}
#ublock0-epicker ul {
margin: 0.25em 0 0 0 !important;
}
@ -31,13 +39,9 @@ html#ublock0-epicker,
box-shadow: none !important;
color: #000 !important;
cursor: pointer !important;
margin: 0 0 0 2px !important;
opacity: 0.7 !important;
padding: 4px 6px !important;
}
#ublock0-epicker button:first-of-type {
margin-left: 0 !important;
}
#ublock0-epicker button:disabled {
color: #999 !important;
background-color: #ccc !important;
@ -218,12 +222,16 @@ html#ublock0-epicker,
<textarea lang="en" dir="ltr" spellcheck="false"></textarea>
<div id="resultsetCount"></div>
</div>
<div><!--
--><button id="preview" type="button">{{preview}}</button><!--
--><button id="create" type="button" disabled>{{create}}</button><!--
--><button id="pick" type="button">{{pick}}</button><!--
--><button id="quit" type="button">{{quit}}</button><!--
--></div>
<div id="toolbar">
<div>
<button id="preview" type="button">{{preview}}</button>
</div>
<div>
<button id="create" type="button" disabled>{{create}}</button>
<button id="pick" type="button">{{pick}}</button>
<button id="quit" type="button">{{quit}}</button>
</div>
</div>
</section>
<ul>
<li id="netFilters">

View File

@ -126,26 +126,26 @@ if (
return;
}
var pickerRoot = document.getElementById(vAPI.sessionId);
let pickerRoot = document.getElementById(vAPI.sessionId);
if ( pickerRoot ) { return; }
var pickerBody = null;
var svgOcean = null;
var svgIslands = null;
var svgRoot = null;
var dialog = null;
var taCandidate = null;
let pickerBody = null;
let svgOcean = null;
let svgIslands = null;
let svgRoot = null;
let dialog = null;
let taCandidate = null;
var netFilterCandidates = [];
var cosmeticFilterCandidates = [];
const netFilterCandidates = [];
const cosmeticFilterCandidates = [];
var targetElements = [];
var candidateElements = [];
var bestCandidateFilter = null;
let targetElements = [];
let candidateElements = [];
let bestCandidateFilter = null;
var lastNetFilterSession = window.location.host + window.location.pathname;
var lastNetFilterHostname = '';
var lastNetFilterUnion = '';
const lastNetFilterSession = window.location.host + window.location.pathname;
let lastNetFilterHostname = '';
let lastNetFilterUnion = '';
/******************************************************************************/
@ -1517,6 +1517,55 @@ const onScrolled = function() {
/******************************************************************************/
const onStartMoving = (( ) => {
let mx0 = 0, my0 = 0;
let r0 = 0, b0 = 0;
let rMax = 0, bMax = 0;
const move = ev => {
if ( ev.isTrusted === false ) { return; }
let r1 = Math.min(Math.max(r0 - ev.pageX + mx0, 4), rMax);
let b1 = Math.min(Math.max(b0 - ev.pageY + my0, 4), bMax);
dialog.style.setProperty('right', `${r1}px`, 'important');
dialog.style.setProperty('bottom', `${b1}px`, 'important');
ev.preventDefault();
ev.stopPropagation();
};
const stop = ev => {
if ( ev.isTrusted === false ) { return; }
if ( dialog.classList.contains('moving') === false ) { return; }
dialog.classList.remove('moving');
const pickerWin = pickerRoot.contentWindow;
pickerWin.removeEventListener('mousemove', move, { capture: true });
pickerWin.removeEventListener('mouseup', stop, { capture: true, once: true });
ev.preventDefault();
ev.stopPropagation();
};
return function(ev) {
if ( ev.isTrusted === false ) { return; }
const target = dialog.querySelector('#toolbar');
if ( ev.target !== target ) { return; }
if ( dialog.classList.contains('moving') ) { return; }
mx0 = ev.pageX; my0 = ev.pageY;
const pickerWin = pickerRoot.contentWindow;
const style = pickerWin.getComputedStyle(dialog);
r0 = parseInt(style.right, 10);
b0 = parseInt(style.bottom, 10);
const rect = dialog.getBoundingClientRect();
rMax = pickerBody.clientWidth - 4 - rect.width ;
bMax = pickerBody.clientHeight - 4 - rect.height;
dialog.classList.add('moving');
pickerWin.addEventListener('mousemove', move, { capture: true });
pickerWin.addEventListener('mouseup', stop, { capture: true, once: true });
ev.preventDefault();
ev.stopPropagation();
};
})();
/******************************************************************************/
const pausePicker = function() {
pickerBody.classList.add('paused');
svgListening(false);
@ -1553,20 +1602,11 @@ const stopPicker = function() {
vAPI.domFilterer.unexcludeNode(pickerRoot);
window.removeEventListener('scroll', onScrolled, true);
pickerRoot.contentWindow.removeEventListener('keydown', onKeyPressed, true);
taCandidate.removeEventListener('input', onCandidateChanged);
dialog.removeEventListener('click', onDialogClicked);
svgListening(false);
svgRoot.removeEventListener('click', onSvgClicked);
svgRoot.removeEventListener('touchstart', onSvgTouchStartStop);
svgRoot.removeEventListener('touchend', onSvgTouchStartStop);
pickerRoot.parentNode.removeChild(pickerRoot);
pickerRoot.removeEventListener('load', stopPicker);
pickerRoot =
pickerBody =
dialog =
svgRoot = svgOcean = svgIslands =
taCandidate = null;
pickerRoot = pickerBody =
svgRoot = svgOcean = svgIslands =
dialog = taCandidate = null;
window.focus();
};
@ -1612,6 +1652,8 @@ const startPicker = function(details) {
taCandidate = dialog.querySelector('textarea');
taCandidate.addEventListener('input', onCandidateChanged);
dialog.querySelector('#toolbar').addEventListener('mousedown', onStartMoving);
svgRoot = pickerBody.querySelector('svg');
svgOcean = svgRoot.firstChild;
svgIslands = svgRoot.lastChild;