Favor key bindings with the most specific CSS selectors

Now if a keypress event bubbles to an element with bindings for
multiple matching selectors, the most specific selector is chosen. This
allows us to override a keybinding by using a more specific selector.
For example, say we have an editor instance inside of the file-finder
widget, so that the user can use all their normal bindings when they
type the name of the file. Except when they hit <esc> we want to close
the file finder, not do whatever they normally have it bound to. Now we
can just say:

```
.file-finder .editor {
  <esc>: close-file-finder
}
```

And we're assured that our binding will take precedence.
This commit is contained in:
Nathan Sobo
2012-01-09 21:31:49 -08:00
committed by Corey Johnson & Nathan Sobo
parent f5be55e000
commit 65605409b0
5 changed files with 296 additions and 8 deletions

View File

@@ -1,4 +1,5 @@
$ = require 'jquery'
Specificity = require 'specificity'
module.exports =
class BindingSet
@@ -13,6 +14,7 @@ class BindingSet
bindings: null
constructor: (@selector, @bindings) ->
@specificity = Specificity(@selector)
commandForEvent: (event) ->
for pattern, command of @bindings

View File

@@ -1,5 +1,6 @@
$ = require 'jquery'
BindingSet = require 'binding-set'
Specificity = require 'specificity'
module.exports =
class KeyEventHandler
@@ -12,12 +13,13 @@ class KeyEventHandler
@bindingSets.push(new BindingSet(selector, bindings))
handleKeypress: (event) ->
currentNode = event.target
currentNode = $(event.target)
while currentNode
for bindingSet in @bindingSets
if $(currentNode).is(bindingSet.selector)
if command = bindingSet.commandForEvent(event)
$(event.target).trigger(command)
return
currentNode = currentNode.parentNode
candidateBindingSets = @bindingSets.filter (set) -> currentNode.is(set.selector)
candidateBindingSets.sort (a, b) -> b.specificity - a.specificity
for bindingSet in candidateBindingSets
if command = bindingSet.commandForEvent(event)
$(event.target).trigger(command)
return
currentNode = currentNode.parent()