Skip to content

Commit

Permalink
show link hints for elements that have delegated onclick listener phi…
Browse files Browse the repository at this point in the history
  • Loading branch information
Maxim Baz committed Jan 2, 2015
1 parent 8bd8e13 commit 524d00d
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 2 deletions.
2 changes: 1 addition & 1 deletion content_scripts/inject_script.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ fetchFileContents = (extensionFileName) ->

eventName = "reset"
listenerName = "on#{eventName}"
injectScripts = ["pages/addEventListener_hook.js"]
injectScripts = ["pages/jQuery_delegatedEvents_hook.js", "pages/addEventListener_hook.js"]

# Store the original value of the event listener if one exists, or null otherwise.
oldValue =
Expand Down
25 changes: 24 additions & 1 deletion content_scripts/link_hints.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,22 @@ LinkHints =

marker

#
# Find children elements that have delegated onclick event listener assigned,
# and mark them with `vimium-has-delegated-onclick-listener` attribute.
# This will make sure those elements are discovered during `getVisibleClickableElements` call.
#
markChildrenThatHaveDelegatedOnClickListener: (element) ->
return unless element.hasAttribute "vimium-jquery-delegated-events-selectors"

selectorsStr = element.getAttribute "vimium-jquery-delegated-events-selectors"
selectors = selectorsStr.split("|").filter (x) -> !!x

for selector in selectors
for child in element.querySelectorAll(selector)
unless child.hasAttribute "vimium-has-delegated-onclick-listener"
child.setAttribute "vimium-has-delegated-onclick-listener", ""

#
# Determine whether the element is visible and clickable. If it is, find the rect bounding the element in
# the viewport. There may be more than one part of element which is clickable (for example, if it's an
Expand Down Expand Up @@ -156,9 +172,13 @@ LinkHints =
if (element.hasAttribute("onclick") or
element.getAttribute("role")?.toLowerCase() in ["button", "link"] or
element.getAttribute("contentEditable")?.toLowerCase() in ["", "contentEditable", "true"] or
element.hasAttribute("vimium-has-onclick-listener"))
element.hasAttribute("vimium-has-onclick-listener") or
element.hasAttribute("vimium-has-delegated-onclick-listener"))
isClickable = true

# Dispose the attribute so next time it is not included, in case listener has been removed
element.removeAttribute "vimium-has-delegated-onclick-listener"

# Check for jsaction event listeners on the element.
if element.hasAttribute "jsaction"
jsactionRules = element.getAttribute("jsaction").split(";")
Expand Down Expand Up @@ -198,6 +218,8 @@ LinkHints =
if clientRect != null
visibleElements.push {element: element, rect: clientRect, secondClassCitizen: onlyHasTabIndex}

@markChildrenThatHaveDelegatedOnClickListener element

visibleElements

#
Expand All @@ -208,6 +230,7 @@ LinkHints =
# element.
#
getVisibleClickableElements: ->
@markChildrenThatHaveDelegatedOnClickListener document.documentElement
elements = document.documentElement.getElementsByTagName "*"
visibleElements = []

Expand Down
1 change: 1 addition & 0 deletions manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
},
"web_accessible_resources": [
"pages/vomnibar.html",
"pages/jQuery_delegatedEvents_hook.js",
"pages/addEventListener_hook.js"
]
}
26 changes: 26 additions & 0 deletions pages/jQuery_delegatedEvents_hook.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
markHookSet = "vimium-hooked-delegated-onclick-listeners"
return if document.documentElement.hasAttribute(markHookSet)


Object.defineProperty window, "jQuery",
enumerable: yes
configurable: yes
set: (jQuery) ->
on_ = jQuery.fn.on

jQuery.fn.on = (evnt, selector, handlerFn) ->
if evnt is "click" and typeof selector is "string"
attrKey = "vimium-jquery-delegated-events-selectors"
sep = "|"

element = if @[0] is document then document.documentElement else @[0]
selectors = element.getAttribute(attrKey) || sep
if selectors.indexOf("#{sep}#{selector}#{sep}") < 0
element.setAttribute attrKey, selectors + selector + sep

return on_.apply @, arguments

return jQuery


document.documentElement.setAttribute markHookSet, ""
1 change: 1 addition & 0 deletions tests/dom_tests/dom_tests.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
<link rel="stylesheet" type="text/css" href="../../content_scripts/vimium.css" />

<!-- Simulate the load of injected hooks -->
<script type="text/javascript" src="../../pages/jQuery_delegatedEvents_hook.js"></script>
<script type="text/javascript" src="../../pages/addEventListener_hook.js"></script>

<script type="text/javascript" src="bind.js"></script>
Expand Down

0 comments on commit 524d00d

Please sign in to comment.