tooltip.js 18.7 KB
Newer Older
Jacob Thornton's avatar
Jacob Thornton committed
1
2
$(function () {

XhmikosR's avatar
XhmikosR committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
  module('tooltip')

  test('should provide no conflict', function () {
    var tooltip = $.fn.tooltip.noConflict()
    ok(!$.fn.tooltip, 'tooltip was set back to undefined (org value)')
    $.fn.tooltip = tooltip
  })

  test('should be defined on jquery object', function () {
    var div = $('<div></div>')
    ok(div.tooltip, 'popover method is defined')
  })

  test('should return element', function () {
    var div = $('<div></div>')
    ok(div.tooltip() == div, 'document.body returned')
  })

  test('should expose default settings', function () {
    ok(!!$.fn.tooltip.Constructor.DEFAULTS, 'defaults is defined')
  })

  test('should empty title attribute', function () {
    var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>').tooltip()
    ok(tooltip.attr('title') === '', 'title attribute was emptied')
  })

  test('should add data attribute for referencing original title', function () {
    var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>').tooltip()
    equal(tooltip.attr('data-original-title'), 'Another tooltip', 'original title preserved in data attribute')
  })

  test('should place tooltips relative to placement option', function () {
    $.support.transition = false
    var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>')
      .appendTo('#qunit-fixture')
      .tooltip({placement: 'bottom'})
      .tooltip('show')

    ok($('.tooltip').is('.fade.bottom.in'), 'has correct classes applied')
    tooltip.tooltip('hide')
  })

  test('should allow html entities', function () {
    $.support.transition = false
    var tooltip = $('<a href="#" rel="tooltip" title="<b>@fat</b>"></a>')
      .appendTo('#qunit-fixture')
      .tooltip({html: true})
      .tooltip('show')

    ok($('.tooltip b').length, 'b tag was inserted')
    tooltip.tooltip('hide')
    ok(!$('.tooltip').length, 'tooltip removed')
  })

  test('should respect custom classes', function () {
    var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>')
      .appendTo('#qunit-fixture')
      .tooltip({ template: '<div class="tooltip some-class"><div class="tooltip-arrow"/><div class="tooltip-inner"/></div>'})
      .tooltip('show')

    ok($('.tooltip').hasClass('some-class'), 'custom class is present')
    tooltip.tooltip('hide')
    ok(!$('.tooltip').length, 'tooltip removed')
  })

  test('should fire show event', function () {
    stop()
XhmikosR's avatar
XhmikosR committed
71
    $('<div title="tooltip title"></div>')
XhmikosR's avatar
XhmikosR committed
72
73
74
75
76
77
78
79
80
      .on('show.bs.tooltip', function () {
        ok(true, 'show was called')
        start()
      })
      .tooltip('show')
  })

  test('should fire shown event', function () {
    stop()
XhmikosR's avatar
XhmikosR committed
81
    $('<div title="tooltip title"></div>')
XhmikosR's avatar
XhmikosR committed
82
83
84
85
86
87
88
89
90
      .on('shown.bs.tooltip', function () {
        ok(true, 'shown was called')
        start()
      })
      .tooltip('show')
  })

  test('should not fire shown event when default prevented', function () {
    stop()
XhmikosR's avatar
XhmikosR committed
91
    $('<div title="tooltip title"></div>')
XhmikosR's avatar
XhmikosR committed
92
93
94
95
96
97
98
99
100
101
102
103
104
      .on('show.bs.tooltip', function (e) {
        e.preventDefault()
        ok(true, 'show was called')
        start()
      })
      .on('shown.bs.tooltip', function () {
        ok(false, 'shown was called')
      })
      .tooltip('show')
  })

  test('should fire hide event', function () {
    stop()
XhmikosR's avatar
XhmikosR committed
105
    $('<div title="tooltip title"></div>')
XhmikosR's avatar
XhmikosR committed
106
107
108
109
110
111
112
113
114
115
116
117
      .on('shown.bs.tooltip', function () {
        $(this).tooltip('hide')
      })
      .on('hide.bs.tooltip', function () {
        ok(true, 'hide was called')
        start()
      })
      .tooltip('show')
  })

  test('should fire hidden event', function () {
    stop()
XhmikosR's avatar
XhmikosR committed
118
    $('<div title="tooltip title"></div>')
XhmikosR's avatar
XhmikosR committed
119
120
121
122
123
124
125
126
127
128
129
130
      .on('shown.bs.tooltip', function () {
        $(this).tooltip('hide')
      })
      .on('hidden.bs.tooltip', function () {
        ok(true, 'hidden was called')
        start()
      })
      .tooltip('show')
  })

  test('should not fire hidden event when default prevented', function () {
    stop()
XhmikosR's avatar
XhmikosR committed
131
    $('<div title="tooltip title"></div>')
XhmikosR's avatar
XhmikosR committed
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
      .on('shown.bs.tooltip', function () {
        $(this).tooltip('hide')
      })
      .on('hide.bs.tooltip', function (e) {
        e.preventDefault()
        ok(true, 'hide was called')
        start()
      })
      .on('hidden.bs.tooltip', function () {
        ok(false, 'hidden was called')
      })
      .tooltip('show')
  })

  test('should not show tooltip if leave event occurs before delay expires', function () {
    var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>')
      .appendTo('#qunit-fixture')
      .tooltip({ delay: 200 })

    stop()

    tooltip.trigger('mouseenter')

    setTimeout(function () {
      ok(!$('.tooltip').is('.fade.in'), 'tooltip is not faded in')
      tooltip.trigger('mouseout')
      setTimeout(function () {
        ok(!$('.tooltip').is('.fade.in'), 'tooltip is not faded in')
        start()
      }, 200)
    }, 100)
  })

  test('should not show tooltip if leave event occurs before delay expires, even if hide delay is 0', function () {
    var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>')
      .appendTo('#qunit-fixture')
      .tooltip({ delay: { show: 200, hide: 0} })

    stop()

    tooltip.trigger('mouseenter')

    setTimeout(function () {
      ok(!$('.tooltip').is('.fade.in'), 'tooltip is not faded in')
      tooltip.trigger('mouseout')
      setTimeout(function () {
        ok(!$('.tooltip').is('.fade.in'), 'tooltip is not faded in')
        start()
      }, 200)
    }, 100)
  })

  test('should wait 200 ms before hiding the tooltip', 3, function () {
    var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>')
      .appendTo('#qunit-fixture')
      .tooltip({ delay: { show: 0, hide: 200} })

    stop()

    tooltip.trigger('mouseenter')

    setTimeout(function () {
      ok($('.tooltip').is('.fade.in'), 'tooltip is faded in')
      tooltip.trigger('mouseout')
      setTimeout(function () {
        ok($('.tooltip').is('.fade.in'), '100ms:tooltip is still faded in')
Jacob Thornton's avatar
Jacob Thornton committed
198
        setTimeout(function () {
XhmikosR's avatar
XhmikosR committed
199
200
201
202
203
204
          ok(!$('.tooltip').is('.in'), 'tooltip removed')
          start()
        }, 150)
      }, 100)
    }, 1)
  })
Jacob Thornton's avatar
Jacob Thornton committed
205

XhmikosR's avatar
XhmikosR committed
206
207
208
209
  test('should not hide tooltip if leave event occurs, then tooltip is show immediately again', function () {
    var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>')
      .appendTo('#qunit-fixture')
      .tooltip({ delay: { show: 0, hide: 200} })
Jacob Thornton's avatar
Jacob Thornton committed
210

XhmikosR's avatar
XhmikosR committed
211
    stop()
Jacob Thornton's avatar
Jacob Thornton committed
212

XhmikosR's avatar
XhmikosR committed
213
    tooltip.trigger('mouseenter')
Jacob Thornton's avatar
Jacob Thornton committed
214

XhmikosR's avatar
XhmikosR committed
215
216
217
218
219
    setTimeout(function () {
      ok($('.tooltip').is('.fade.in'), 'tooltip is faded in')
      tooltip.trigger('mouseout')
      setTimeout(function () {
        ok($('.tooltip').is('.fade.in'), '100ms:tooltip is still faded in')
220
221
        tooltip.trigger('mouseenter')
        setTimeout(function () {
XhmikosR's avatar
XhmikosR committed
222
          ok($('.tooltip').is('.in'), 'tooltip removed')
Jacob Thornton's avatar
Jacob Thornton committed
223
          start()
XhmikosR's avatar
XhmikosR committed
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
        }, 150)
      }, 100)
    }, 1)
  })

  test('should not show tooltip if leave event occurs before delay expires', function () {
    var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>')
      .appendTo('#qunit-fixture')
      .tooltip({ delay: 100 })
    stop()
    tooltip.trigger('mouseenter')
    setTimeout(function () {
      ok(!$('.tooltip').is('.fade.in'), 'tooltip is not faded in')
      tooltip.trigger('mouseout')
      setTimeout(function () {
        ok(!$('.tooltip').is('.fade.in'), 'tooltip is not faded in')
        start()
      }, 100)
    }, 50)
  })

  test('should show tooltip if leave event hasn\'t occured before delay expires', function () {
    var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>')
      .appendTo('#qunit-fixture')
      .tooltip({ delay: 150 })
    stop()
    tooltip.trigger('mouseenter')
    setTimeout(function () {
      ok(!$('.tooltip').is('.fade.in'), 'tooltip is not faded in')
    }, 100)
    setTimeout(function () {
      ok($('.tooltip').is('.fade.in'), 'tooltip has faded in')
      start()
    }, 200)
  })

  test('should destroy tooltip', function () {
    var tooltip = $('<div/>').tooltip().on('click.foo', function () {})
    ok(tooltip.data('bs.tooltip'), 'tooltip has data')
    ok($._data(tooltip[0], 'events').mouseover && $._data(tooltip[0], 'events').mouseout, 'tooltip has hover event')
    ok($._data(tooltip[0], 'events').click[0].namespace == 'foo', 'tooltip has extra click.foo event')
    tooltip.tooltip('show')
    tooltip.tooltip('destroy')
    ok(!tooltip.hasClass('in'), 'tooltip is hidden')
    ok(!$._data(tooltip[0], 'bs.tooltip'), 'tooltip does not have data')
    ok($._data(tooltip[0], 'events').click[0].namespace == 'foo', 'tooltip still has click.foo')
    ok(!$._data(tooltip[0], 'events').mouseover && !$._data(tooltip[0], 'events').mouseout, 'tooltip does not have any events')
  })

  test('should show tooltip with delegate selector on click', function () {
    var div = $('<div><a href="#" rel="tooltip" title="Another tooltip"></a></div>')
XhmikosR's avatar
XhmikosR committed
275
    div.appendTo('#qunit-fixture')
276
                     .tooltip({ selector: 'a[rel="tooltip"]', trigger: 'click' })
XhmikosR's avatar
XhmikosR committed
277
278
279
280
281
    div.find('a').trigger('click')
    ok($('.tooltip').is('.fade.in'), 'tooltip is faded in')
  })

  test('should show tooltip when toggle is called', function () {
XhmikosR's avatar
XhmikosR committed
282
    $('<a href="#" rel="tooltip" title="tooltip on toggle"></a>')
XhmikosR's avatar
XhmikosR committed
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
      .appendTo('#qunit-fixture')
      .tooltip({trigger: 'manual'})
      .tooltip('toggle')
    ok($('.tooltip').is('.fade.in'), 'tooltip should be toggled in')
  })

  test('should place tooltips inside the body', function () {
    var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>')
      .appendTo('#qunit-fixture')
      .tooltip({container: 'body'})
      .tooltip('show')
    ok($('body > .tooltip').length, 'inside the body')
    ok(!$('#qunit-fixture > .tooltip').length, 'not found in parent')
    tooltip.tooltip('hide')
  })

  test('should place tooltip inside window', function () {
    var container = $('<div />').appendTo('body')
XhmikosR's avatar
XhmikosR committed
301
302
        .css({position: 'absolute', width: 200, height: 200, bottom: 0, left: 0})
    $('<a href="#" title="Very very very very very very very very long tooltip">Hover me</a>')
XhmikosR's avatar
XhmikosR committed
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
      .css({position: 'absolute', top: 0, left: 0})
      .appendTo(container)
      .tooltip({placement: 'top', animate: false})
      .tooltip('show')

    stop()

    setTimeout(function () {
      ok($('.tooltip').offset().left >= 0)

      start()
      container.remove()
    }, 100)
  })

  test('should place tooltip on top of element', function () {
    var container = $('<div />').appendTo('body')
          .css({position: 'absolute', bottom: 0, left: 0, textAlign: 'right', width: 300, height: 300}),
          p = $('<p style="margin-top:200px" />').appendTo(container),
          tooltiped = $('<a href="#" title="very very very very very very very long tooltip">Hover me</a>')
            .css({marginTop: 200})
            .appendTo(p)
            .tooltip({placement: 'top', animate: false})
            .tooltip('show')

    stop()

    setTimeout(function () {
      var tooltip = container.find('.tooltip')

      start()
      ok(Math.round(tooltip.offset().top + tooltip.outerHeight()) <= Math.round(tooltiped.offset().top))
      container.remove()
    }, 100)
  })

  test('should add position class before positioning so that position-specific styles are taken into account', function () {
340
    $('head').append('<style id="test"> .tooltip.right { white-space: nowrap; } .tooltip.right .tooltip-inner { max-width: none; } </style>')
XhmikosR's avatar
XhmikosR committed
341
342
343

    var container = $('<div />').appendTo('body'),
        target = $('<a href="#" rel="tooltip" title="very very very very very very very very long tooltip in one line"></a>')
344
          .appendTo(container)
345
          .tooltip({placement: 'right', viewport: null})
XhmikosR's avatar
XhmikosR committed
346
347
348
349
350
351
352
353
354
          .tooltip('show'),
        tooltip = container.find('.tooltip')

    // this is some dumb hack shit because sub pixels in firefox
    var top = Math.round(target.offset().top + (target[0].offsetHeight / 2) - (tooltip[0].offsetHeight / 2))
    var top2 = Math.round(tooltip.offset().top)
    var topDiff =  top - top2
    ok(topDiff <= 1 && topDiff >= -1)
    target.tooltip('hide')
355
    $('head #test').remove()
XhmikosR's avatar
XhmikosR committed
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
  })

  test('tooltip title test #1', function () {
    var tooltip = $('<a href="#" rel="tooltip" title="Simple tooltip" style="display: inline-block; position: absolute; top: 0; left: 0;"></a>')
      .appendTo('#qunit-fixture')
      .tooltip({})
      .tooltip('show')
    equal($('.tooltip').children('.tooltip-inner').text(), 'Simple tooltip', 'title from title attribute is set')
    tooltip.tooltip('hide')
    ok(!$('.tooltip').length, 'tooltip removed')
  })

  test('tooltip title test #2', function () {
    var tooltip = $('<a href="#" rel="tooltip" title="Simple tooltip" style="display: inline-block; position: absolute; top: 0; left: 0;"></a>')
      .appendTo('#qunit-fixture')
      .tooltip({
        title: 'This is a tooltip with some content'
      })
      .tooltip('show')
    equal($('.tooltip').children('.tooltip-inner').text(), 'Simple tooltip', 'title is set from title attribute while prefered over title option')
    tooltip.tooltip('hide')
    ok(!$('.tooltip').length, 'tooltip removed')
  })

  test('tooltip title test #3', function () {
    var tooltip = $('<a href="#" rel="tooltip" style="display: inline-block; position: absolute; top: 0; left: 0;"></a>')
      .appendTo('#qunit-fixture')
      .tooltip({
        title: 'This is a tooltip with some content'
      })
      .tooltip('show')
    equal($('.tooltip').children('.tooltip-inner').text(), 'This is a tooltip with some content', 'title from title option is set')
    tooltip.tooltip('hide')
    ok(!$('.tooltip').length, 'tooltip removed')
  })

  test('tooltips should be placed dynamically, with the dynamic placement option', function () {
    $.support.transition = false
    var ttContainer = $('<div id="dynamic-tt-test"/>').css({
XhmikosR's avatar
XhmikosR committed
395
396
397
398
399
400
      height : 400,
      overflow : 'hidden',
      position : 'absolute',
      top : 0,
      left : 0,
      width : 600
401
402
    })
    .appendTo('body')
XhmikosR's avatar
XhmikosR committed
403
404
405
406
407
408

    var topTooltip = $('<div style="display: inline-block; position: absolute; left: 0; top: 0;" rel="tooltip" title="Top tooltip">Top Dynamic Tooltip</div>')
      .appendTo('#dynamic-tt-test')
      .tooltip({placement: 'auto'})
      .tooltip('show')

409
    ok($('.tooltip').is('.bottom'), 'top positioned tooltip is dynamically positioned bottom')
XhmikosR's avatar
XhmikosR committed
410
411
412
413
414
415
416
417

    topTooltip.tooltip('hide')

    var rightTooltip = $('<div style="display: inline-block; position: absolute; right: 0;" rel="tooltip" title="Right tooltip">Right Dynamic Tooltip</div>')
      .appendTo('#dynamic-tt-test')
      .tooltip({placement: 'right auto'})
      .tooltip('show')

418
    ok($('.tooltip').is('.left'), 'right positioned tooltip is dynamically positioned left')
XhmikosR's avatar
XhmikosR committed
419
420
421
422
423
424
425
    rightTooltip.tooltip('hide')

    var leftTooltip = $('<div style="display: inline-block; position: absolute; left: 0;" rel="tooltip" title="Left tooltip">Left Dynamic Tooltip</div>')
      .appendTo('#dynamic-tt-test')
      .tooltip({placement: 'auto left'})
      .tooltip('show')

426
    ok($('.tooltip').is('.right'), 'left positioned tooltip is dynamically positioned right')
XhmikosR's avatar
XhmikosR committed
427
428
429
430
    leftTooltip.tooltip('hide')

    ttContainer.remove()
  })
431

432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
  test('should adjust the tip\'s top when up against the top of the viewport', function () {
    $('head').append('<style id="test"> .tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; } </style>')

    var container = $('<div />').appendTo('body'),
      target = $('<a href="#" rel="tooltip" title="tip" style="position: fixed; top: 0px; left: 0px;"></a>')
          .appendTo(container)
          .tooltip({placement: 'right', viewport: {selector: 'body', padding: 12}})
          .tooltip('show'),
      tooltip = container.find('.tooltip')

    ok( Math.round(tooltip.offset().top) === 12 )
    target.tooltip('hide')
    $('head #test').remove()
  })

  test('should adjust the tip\'s top when up against the bottom of the viewport', function () {
    $('head').append('<style id="test"> .tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; } </style>')

    var container = $('<div />').appendTo('body'),
      target = $('<a href="#" rel="tooltip" title="tip" style="position: fixed; bottom: 0px; left: 0px;"></a>')
          .appendTo(container)
          .tooltip({placement: 'right', viewport: {selector: 'body', padding: 12}})
          .tooltip('show'),
      tooltip = container.find('.tooltip')

    ok( Math.round(tooltip.offset().top) === Math.round($(window).height() - 12 - tooltip[0].offsetHeight) )
    target.tooltip('hide')
    $('head #test').remove()
  })

  test('should adjust the tip\'s left when up against the left of the viewport', function () {
    $('head').append('<style id="test"> .tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; } </style>')

    var container = $('<div />').appendTo('body'),
      target = $('<a href="#" rel="tooltip" title="tip" style="position: fixed; top: 0px; left: 0px;"></a>')
          .appendTo(container)
          .tooltip({placement: 'bottom', viewport: {selector: 'body', padding: 12}})
          .tooltip('show'),
      tooltip = container.find('.tooltip')

    ok( Math.round(tooltip.offset().left) === 12 )
    target.tooltip('hide')
    $('head #test').remove()
  })

  test('should adjust the tip\'s left when up against the right of the viewport', function () {
    $('head').append('<style id="test"> .tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; } </style>')

    var container = $('<div />').appendTo('body'),
      target = $('<a href="#" rel="tooltip" title="tip" style="position: fixed; top: 0px; right: 0px;"></a>')
          .appendTo(container)
          .tooltip({placement: 'bottom', viewport: {selector: 'body', padding: 12}})
          .tooltip('show'),
      tooltip = container.find('.tooltip')

    ok( Math.round(tooltip.offset().left) === Math.round($(window).width() - 12 - tooltip[0].offsetWidth) )
    target.tooltip('hide')
    $('head #test').remove()
  })

  test('should adjust the tip when up against the right of an arbitrary viewport', function () {
    $('head').append('<style id="test"> .tooltip, .tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; } </style>')
    $('head').append('<style id="viewport-style"> .container-viewport { position: absolute; top: 50px; left: 60px; width: 300px; height: 300px; } </style>')

    var container = $('<div />', {class: 'container-viewport'}).appendTo('body'),
      target = $('<a href="#" rel="tooltip" title="tip" style="position: fixed; top: 50px; left: 350px;"></a>')
          .appendTo(container)
          .tooltip({placement: 'bottom', viewport: '.container-viewport'})
          .tooltip('show'),
      tooltip = container.find('.tooltip')

    ok( Math.round(tooltip.offset().left) === Math.round(60 + container.width() - tooltip[0].offsetWidth) )
    target.tooltip('hide')
    $('head #test').remove()
    $('head #viewport-style').remove()
  })
508
})