diff --git a/.gitignore b/.gitignore
index 45381b4..0efd56d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,4 @@ build/*
/build
.settings
node_modules/
-todo.md
\ No newline at end of file
+todo.md
diff --git a/src/background.js b/src/background.js
index 43b5dfb..119691d 100644
--- a/src/background.js
+++ b/src/background.js
@@ -8,6 +8,11 @@ defaultOptions = { "button": 2,
"friction": 10,
"cursor": true,
"notext": false,
+ "nolinks": false,
+ "nobuttons": false,
+ "nolabels": false,
+ "noimages": false,
+ "noembeds": false,
"grab_and_drag": false,
"debug": false,
"blacklist": "",
diff --git a/src/content.js b/src/content.js
index 30262e1..1871290 100644
--- a/src/content.js
+++ b/src/content.js
@@ -11,6 +11,11 @@ ScrollbarAnywhere = (function() {
options = msg.saveOptions
options.cursor = (options.cursor == "true")
options.notext = (options.notext == "true")
+ options.nolinks = (options.nolinks == "true")
+ options.nobuttons = (options.nobuttons == "true")
+ options.nolabels = (options.nolabels == "true")
+ options.noimages = (options.noimages == "true")
+ options.noembeds = (options.noembeds == "true")
options.grab_and_drag = (options.grab_and_drag == "true")
options.debug = (options.debug == "true")
options.enabled = isEnabled(options.blacklist)
@@ -82,7 +87,6 @@ ScrollbarAnywhere = (function() {
function vmag(v) { return Math.sqrt(v[0]*v[0] + v[1]*v[1]) }
function vunit(v) { return vdiv(vmag(v),v) }
-
// Test if the given point is directly over text
var isOverText = (function() {
var bonet = document.createElement("SPAN")
@@ -176,23 +180,26 @@ ScrollbarAnywhere = (function() {
}
}
- // Don't drag when left-clicking on these elements
- const LBUTTON_OVERRIDE_TAGS = ['A','INPUT','SELECT','TEXTAREA','BUTTON','LABEL','OBJECT','EMBED']
- const MBUTTON_OVERRIDE_TAGS = ['A']
- const RBUTTON_OVERRIDE_TAGS = ['A','INPUT','TEXTAREA','OBJECT','EMBED']
- function hasOverrideAncestor(e) {
+ // Don't drag when clicking on these elements
+ const MANDATORY_OVERRIDE_TAGS = ['INPUT', 'TEXTAREA', 'SELECT']
+ function hasMandatoryOverrideAncestor(e) {
if (e == null) return false
- if (options.button == LBUTTON && shouldOverrideLeftButton(e)) return true;
- if (options.button == MBUTTON && MBUTTON_OVERRIDE_TAGS.some(function(tag) { return tag == e.tagName })) return true
- if (options.button == RBUTTON && RBUTTON_OVERRIDE_TAGS.some(function(tag) { return tag == e.tagName })) return true
+ if (MANDATORY_OVERRIDE_TAGS.some(function(tag) { return tag == e.tagName })) return true
return arguments.callee(e.parentNode)
}
- function shouldOverrideLeftButton(e) {
- return LBUTTON_OVERRIDE_TAGS.some(function(tag) { return tag == e.tagName; }) || hasRoleButtonAttribute(e);
+ function hasOptionalOverrideAncestor(e) {
+ if (e == null) return false
+ if (options.nolinks && e.tagName == 'A') return true
+ if (options.nobuttons && (e.tagName == 'BUTTON' || hasRoleButtonAttribute(e))) return true
+ if (options.nolabels && e.tagName == 'LABEL') return true
+ if (options.noimages && e.tagName == 'IMG') return true
+ if (options.noembeds && (e.tagName == 'OBJECT' || e.tagName == 'EMBED')) return true
+ return arguments.callee(e.parentNode)
}
function hasRoleButtonAttribute(e) {
+ // FIXME: github has a lot of links that look like buttons...
if (e.attributes && e.attributes.role) {
return e.attributes.role.value === 'button';
}
@@ -605,11 +612,21 @@ ScrollbarAnywhere = (function() {
break
}
- if (hasOverrideAncestor(ev.target)) {
+ if (hasMandatoryOverrideAncestor(ev.target)) {
debug("forbidden target element, ignoring",ev)
break
}
+ if (hasOptionalOverrideAncestor(ev.target)) {
+ debug("optional target element disabled, ignoring",ev)
+ break
+ }
+
+ if (options.notext && isOverText(ev)) {
+ debug("detected text node, ignoring")
+ break
+ }
+
if (isOverScrollbar(ev)) {
debug("detected scrollbar click, ignoring",ev)
break
@@ -621,11 +638,6 @@ ScrollbarAnywhere = (function() {
break
}
- if (options.notext && isOverText(ev)) {
- debug("detected text node, ignoring")
- break
- }
-
debug("click MouseEvent=",ev," dragElement=",dragElement)
activity = CLICK
mouseOrigin = [ev.clientX,ev.clientY]
diff --git a/src/options.html b/src/options.html
index 16c122c..b62760d 100644
--- a/src/options.html
+++ b/src/options.html
@@ -86,12 +86,12 @@
Keys
Tip: any unchecked keys will disable dragging when held down
@@ -99,17 +99,42 @@ Keys
- |
+
+ Disabled Elements
+ Which elements will you disable dragging on?
+ |
-
+
|
- |
+
+ Cursor
+ Cursor appearance while dragging.
+ |
-
- Try unchecking this if you notice any delays
+
+ Tip: try unchecking this if you notice any delays
|
@@ -119,7 +144,7 @@ Grab and drag
Grab-and-drag style scrolling will be enabled instead of the scrollbar anywhere style.
-
+
|
@@ -166,8 +191,13 @@ Blacklist
- |
- |
+
+ Developer
+ Development options.
+ |
+
+
+ |
diff --git a/src/options.js b/src/options.js
index 8a156dc..03644c8 100644
--- a/src/options.js
+++ b/src/options.js
@@ -52,6 +52,11 @@ function save() {
o.cursor = $('cursor').checked
o.notext = $('notext').checked
+ o.nolinks = $('nolinks').checked
+ o.nobuttons = $('nobuttons').checked
+ o.nolabels = $('nolabels').checked
+ o.noimages = $('noimages').checked
+ o.noembeds = $('noembeds').checked
o.grab_and_drag = $('grab_and_drag').checked
o.debug = $('debug').checked
@@ -74,13 +79,36 @@ function load() {
$('cursor').checked = (o.cursor == "true")
$('notext').checked = (o.notext == "true")
+ $('nolinks').checked = (o.nolinks == "true")
+ $('nobuttons').checked = (o.nobuttons == "true")
+ $('nolabels').checked = (o.nolabels == "true")
+ $('noimages').checked = (o.noimages == "true")
+ $('noembeds').checked = (o.noembeds == "true")
$('grab_and_drag').checked = (o.grab_and_drag == "true")
$('debug').checked = (o.debug == "true")
+
+ // Should only need to make sure we disable these on page [re]load.
+ $('nolinks').disabled = (o.notext == "true")
+ $('nobuttons').disabled = (o.notext == "true")
+ $('nolabels').disabled = (o.notext == "true")
+ $('noembeds').disabled = (o.noimages == "true")
}
var updateTimeoutId
function onUpdate(ev) {
+ if (ev.target == $('notext')) {
+ ['nolinks', 'nobuttons', 'nolabels'].forEach(function(id) {
+ $(id).checked = ($('notext').checked === true)
+ $(id).disabled = ($('notext').checked === true)
+ })
+ }
+
+ if (ev.target == $('noimages')) {
+ $('noembeds').checked = ($('noimages').checked === true)
+ $('noembeds').disabled = ($('noimages').checked === true)
+ }
+
if (updateTimeoutId != null) clearTimeout(updateTimeoutId)
updateTimeoutId = setTimeout(save,200)
@@ -92,7 +120,16 @@ function onUpdate(ev) {
document.addEventListener('DOMContentLoaded', function(ev) {
load();
- ['button','cursor','notext','debug', 'grab_and_drag'].forEach(function(id) {
+ ['button',
+ 'cursor',
+ 'notext',
+ 'nolinks',
+ 'nobuttons',
+ 'nolabels',
+ 'noimages',
+ 'noembeds',
+ 'debug',
+ 'grab_and_drag'].forEach(function(id) {
$(id).addEventListener('change',onUpdate,false)
})