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) })