From 175d7811b4ec228d878ffe294cdca26de9d30bc1 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 19 Nov 2014 18:57:08 -0700 Subject: [PATCH] Add TooltipManager Signed-off-by: Max Brunsfeld --- spec/tooltip-manager-spec.coffee | 54 ++++++++++++++++++++++++++++++++ src/tooltip-manager.coffee | 45 ++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 spec/tooltip-manager-spec.coffee create mode 100644 src/tooltip-manager.coffee diff --git a/spec/tooltip-manager-spec.coffee b/spec/tooltip-manager-spec.coffee new file mode 100644 index 000000000..40ac6d746 --- /dev/null +++ b/spec/tooltip-manager-spec.coffee @@ -0,0 +1,54 @@ +TooltipManager = require '../src/tooltip-manager' +{$} = require '../src/space-pen-extensions' + +describe "TooltipManager", -> + [manager, element] = [] + + beforeEach -> + manager = new TooltipManager + element = document.createElement('div') + element.classList.add('foo') + jasmine.attachToDOM(element) + + hover = (element, fn) -> + $(element).trigger 'mouseenter' + advanceClock(manager.defaults.delay.show) + fn() + $(element).trigger 'mouseleave' + advanceClock(manager.defaults.delay.hide) + + describe "::add(target, options)", -> + describe "when the target is an element", -> + it "creates a tooltip based on the given options when hovering over the target element", -> + manager.add element, title: "Title" + hover element, -> + expect(document.body.querySelector(".tooltip")).toHaveText("Title") + + describe "when the target is a selector", -> + it "creates a tooltip based on the given options when hovering over an element matching the target selector", -> + manager.add ".foo", title: "Title" + hover element, -> + expect(document.body.querySelector(".tooltip")).toHaveText("Title") + + describe "when a keyBindingCommand is specified", -> + describe "when a title is specified", -> + it "appends the key binding corresponding to the command to the title", -> + atom.keymaps.add 'test', + '.bar': 'ctrl-x ctrl-z': 'test-command' + '.foo': 'ctrl-x ctrl-y': 'test-command' + + manager.add element, title: "Title", keyBindingCommand: 'test-command' + + hover element, -> + tooltipElement = document.body.querySelector(".tooltip") + expect(tooltipElement).toHaveText "Title ⌃X ⌃Y" + + describe "when no title is specified", -> + it "shows the key binding corresponding to the command alone", -> + atom.keymaps.add 'test', '.foo': 'ctrl-x ctrl-y': 'test-command' + + manager.add element, keyBindingCommand: 'test-command' + + hover element, -> + tooltipElement = document.body.querySelector(".tooltip") + expect(tooltipElement).toHaveText "⌃X ⌃Y" diff --git a/src/tooltip-manager.coffee b/src/tooltip-manager.coffee new file mode 100644 index 000000000..ca7e81f05 --- /dev/null +++ b/src/tooltip-manager.coffee @@ -0,0 +1,45 @@ +_ = require 'underscore-plus' +{$} = require './space-pen-extensions' + +module.exports = +class TooltipManager + defaults: + delay: + show: 1000 + hide: 100 + container: 'body' + html: true + placement: 'auto top' + viewportPadding: 2 + + add: (target, options) -> + requireBootstrapTooltip() + + {keyBindingCommand} = options + + if keyBindingCommand? + keyBindingTarget = target unless typeof target is 'string' + bindings = atom.keymaps.findKeyBindings(command: keyBindingCommand, target: keyBindingTarget) + if options.title? + options.title += " " + getKeystroke(bindings) + else + options.title = getKeystroke(bindings) + + if typeof target is 'string' + options.selector = target + target = document.body + + $(target).tooltip(_.defaults(options, @defaults)) + +humanizeKeystrokes = (keystroke) -> + keystrokes = keystroke.split(' ') + keystrokes = (_.humanizeKeystroke(stroke) for stroke in keystrokes) + keystrokes.join(' ') + +getKeystroke = (bindings) -> + if bindings?.length + "#{humanizeKeystrokes(bindings[0].keystrokes)}" + else + +requireBootstrapTooltip = _.once -> + atom.requireWithGlobals('bootstrap/js/tooltip', {jQuery: $})