diff --git a/src/epicker.html b/src/epicker.html
index d2b764349..33a402eb7 100644
--- a/src/epicker.html
+++ b/src/epicker.html
@@ -74,6 +74,7 @@ section > div:first-child > textarea {
height: 8em;
margin: 0;
overflow: hidden;
+ overflow-y: auto;
padding: 2px;
resize: none;
width: 100%;
@@ -165,10 +166,11 @@ aside {
border: 1px solid #aaa;
bottom: 4px;
box-sizing: border-box;
- visibility: hidden;
+ min-width: 24em;
padding: 4px;
position: fixed;
right: 4px;
+ visibility: hidden;
width: calc(40% - 4px);
}
body.paused > aside {
@@ -179,6 +181,12 @@ body.paused > aside {
body.paused > aside:hover {
opacity: 1;
}
+body.paused > aside.show {
+ opacity: 1;
+}
+body.paused > aside.hide {
+ opacity: 0.1;
+}
diff --git a/src/js/scriptlets/element-picker.js b/src/js/scriptlets/element-picker.js
index 9b7abaa2b..ca275f08c 100644
--- a/src/js/scriptlets/element-picker.js
+++ b/src/js/scriptlets/element-picker.js
@@ -1,7 +1,7 @@
/*******************************************************************************
uBlock Origin - a browser extension to block requests.
- Copyright (C) 2014-2016 Raymond Hill
+ Copyright (C) 2014-2017 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
@@ -1092,7 +1092,14 @@ var filterChoiceFromEvent = function(ev) {
/******************************************************************************/
var onDialogClicked = function(ev) {
- if ( ev.target === null ) {
+
+ // If the dialog is hidden, clicking on it force it to become visible.
+ if ( dialog.classList.contains('hide') ) {
+ dialog.classList.add('show');
+ dialog.classList.remove('hide');
+ }
+
+ else if ( ev.target === null ) {
/* do nothing */
}
@@ -1161,6 +1168,11 @@ var showDialog = function(options) {
options = options || {};
+ // Typically the dialog will be forced to be visible when using a
+ // touch-aware device.
+ dialog.classList.toggle('show', options.show === true);
+ dialog.classList.remove('hide');
+
// Create lists of candidate filters
var populate = function(src, des) {
var root = dialog.querySelector(des);
@@ -1262,7 +1274,17 @@ var onSvgHovered = (function() {
};
})();
-/******************************************************************************/
+/*******************************************************************************
+
+ Swipe right:
+ If picker not paused: quit picker
+ If picker paused and dialog visible: hide dialog
+ If picker paused and dialog not visible: quit picker
+
+ Swipe left:
+ If picker paused and dialog not visible: show dialog
+
+*/
var onSvgTouchStartStop = (function() {
var startX,
@@ -1277,22 +1299,43 @@ var onSvgTouchStartStop = (function() {
if ( startX === undefined ) { return; }
var stopX = ev.changedTouches[0].pageX,
stopY = ev.changedTouches[0].pageY,
+ angle = Math.abs(Math.atan2(stopY - startY, stopX - startX)),
distance = Math.sqrt(
Math.pow(stopX - startX, 2),
Math.pow(stopY - startY, 2)
);
- // Swipe = exit element zapper/picker.
- if ( distance > 32 ) {
- stopPicker();
+ var angleUpperBound = Math.PI * 0.25 * 0.5,
+ swipeRight = angle < angleUpperBound,
+ swipeInvalid = swipeRight === false &&
+ angle < Math.PI - angleUpperBound;
+ // Interpret touch events as a click events if swipe is not valid.
+ if ( distance < 64 || swipeInvalid ) {
+ onSvgClicked({
+ type: 'touch',
+ target: ev.target,
+ clientX: startX,
+ clientY: startY
+ });
return;
}
- // Interpret touch event as a click.
- onSvgClicked({
- type: 'click',
- target: ev.target,
- clientX: startX,
- clientY: startY
- });
+ // Swipe left.
+ if ( swipeRight === false ) {
+ if ( pickerBody.classList.contains('paused') ) {
+ dialog.classList.remove('hide');
+ dialog.classList.add('show');
+ }
+ return;
+ }
+ // Swipe right.
+ if (
+ pickerBody.classList.contains('paused') &&
+ dialog.classList.contains('show')
+ ) {
+ dialog.classList.remove('show');
+ dialog.classList.add('hide');
+ return;
+ }
+ stopPicker();
};
})();
@@ -1329,7 +1372,7 @@ var onSvgClicked = function(ev) {
if ( filtersFrom(ev.clientX, ev.clientY) === 0 ) {
return;
}
- showDialog();
+ showDialog({ show: ev.type === 'touch' });
};
/******************************************************************************/