Merge pull request #13095 from atom/fb-vj-follow-through

Introduce follow through behavior for tooltips
This commit is contained in:
Nathan Sobo
2016-11-02 08:31:19 -06:00
committed by GitHub
3 changed files with 62 additions and 10 deletions

View File

@@ -82,7 +82,7 @@
"one-light-syntax": "1.6.0",
"solarized-dark-syntax": "1.1.1",
"solarized-light-syntax": "1.1.1",
"about": "1.7.0",
"about": "1.7.1",
"archive-view": "0.62.0",
"autocomplete-atom-api": "0.10.0",
"autocomplete-css": "0.14.1",

View File

@@ -1,4 +1,6 @@
{CompositeDisposable} = require 'atom'
TooltipManager = require '../src/tooltip-manager'
Tooltip = require '../src/tooltip'
_ = require 'underscore-plus'
describe "TooltipManager", ->
@@ -9,17 +11,27 @@ describe "TooltipManager", ->
beforeEach ->
manager = new TooltipManager(keymapManager: atom.keymaps, viewRegistry: atom.views)
element = document.createElement('div')
element.classList.add('foo')
jasmine.attachToDOM(element)
element = createElement 'foo'
hover = (element, fn) ->
createElement = (className) ->
el = document.createElement('div')
el.classList.add(className)
jasmine.attachToDOM(el)
el
mouseEnter = (element) ->
element.dispatchEvent(new CustomEvent('mouseenter', bubbles: false))
element.dispatchEvent(new CustomEvent('mouseover', bubbles: true))
advanceClock(manager.hoverDefaults.delay.show)
fn()
mouseLeave = (element) ->
element.dispatchEvent(new CustomEvent('mouseleave', bubbles: false))
element.dispatchEvent(new CustomEvent('mouseout', bubbles: true))
hover = (element, fn) ->
mouseEnter(element)
advanceClock(manager.hoverDefaults.delay.show)
fn()
mouseLeave(element)
advanceClock(manager.hoverDefaults.delay.hide)
describe "::add(target, options)", ->
@@ -29,6 +41,32 @@ describe "TooltipManager", ->
hover element, ->
expect(document.body.querySelector(".tooltip")).toHaveText("Title")
it "displays tooltips immediately when hovering over new elements once a tooltip has been displayed once", ->
disposables = new CompositeDisposable
element1 = createElement('foo')
disposables.add(manager.add element1, title: 'Title')
element2 = createElement('bar')
disposables.add(manager.add element2, title: 'Title')
element3 = createElement('baz')
disposables.add(manager.add element3, title: 'Title')
hover element1, ->
expect(document.body.querySelector(".tooltip")).toBeNull()
mouseEnter(element2)
expect(document.body.querySelector(".tooltip")).not.toBeNull()
mouseLeave(element2)
advanceClock(manager.hoverDefaults.delay.hide)
expect(document.body.querySelector(".tooltip")).toBeNull()
advanceClock(Tooltip.FOLLOW_THROUGH_DURATION)
mouseEnter(element3)
expect(document.body.querySelector(".tooltip")).toBeNull()
advanceClock(manager.hoverDefaults.delay.show)
expect(document.body.querySelector(".tooltip")).not.toBeNull()
disposables.dispose()
describe "when the trigger is 'manual'", ->
it "creates a tooltip immediately and only hides it on dispose", ->
disposable = manager.add element, title: "Title", trigger: "manual"
@@ -149,6 +187,6 @@ describe "TooltipManager", ->
it "hides the tooltips", ->
manager.add element, title: "Title"
hover element, ->
expect(document.body.querySelector(".tooltip")).toBeDefined()
expect(document.body.querySelector(".tooltip")).not.toBeNull()
window.dispatchEvent(new CustomEvent('resize'))
expect(document.body.querySelector(".tooltip")).toBeNull()

View File

@@ -7,6 +7,8 @@ const listen = require('./delegated-listener')
// This tooltip class is derived from Bootstrap 3, but modified to not require
// jQuery, which is an expensive dependency we want to eliminate.
var followThroughTimer = null
var Tooltip = function (element, options, viewRegistry) {
this.options = null
this.enabled = null
@@ -21,7 +23,7 @@ var Tooltip = function (element, options, viewRegistry) {
Tooltip.VERSION = '3.3.5'
Tooltip.TRANSITION_DURATION = 150
Tooltip.FOLLOW_THROUGH_DURATION = 300
Tooltip.DEFAULTS = {
animation: true,
@@ -151,7 +153,11 @@ Tooltip.prototype.enter = function (event) {
this.hoverState = 'in'
if (!this.options.delay || !this.options.delay.show) return this.show()
if (!this.options.delay ||
!this.options.delay.show ||
followThroughTimer) {
return this.show()
}
this.timeout = setTimeout(function () {
if (this.hoverState === 'in') this.show()
@@ -343,6 +349,14 @@ Tooltip.prototype.hide = function (callback) {
this.hoverState = null
clearTimeout(followThroughTimer)
followThroughTimer = setTimeout(
function () {
followThroughTimer = null
},
Tooltip.FOLLOW_THROUGH_DURATION
)
return this
}