tooltip.js 24 KB
Newer Older
Jacob Thornton's avatar
Jacob Thornton committed
1
$(function () {
XhmikosR's avatar
XhmikosR committed
2
  'use strict';
Jacob Thornton's avatar
Jacob Thornton committed
3

4
  module('tooltip plugin')
XhmikosR's avatar
XhmikosR committed
5
6

  test('should be defined on jquery object', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
7
    ok($(document.body).tooltip, 'popover method is defined')
XhmikosR's avatar
XhmikosR committed
8
9
  })

10
  module('tooltip', {
XhmikosR's avatar
XhmikosR committed
11
    setup: function () {
12
13
14
      // Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode
      $.fn.bootstrapTooltip = $.fn.tooltip.noConflict()
    },
XhmikosR's avatar
XhmikosR committed
15
    teardown: function () {
16
17
18
19
20
21
      $.fn.tooltip = $.fn.bootstrapTooltip
      delete $.fn.bootstrapTooltip
    }
  })

  test('should provide no conflict', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
22
    strictEqual($.fn.tooltip, undefined, 'tooltip was set back to undefined (org value)')
23
24
  })

Heinrich Fenkart's avatar
Heinrich Fenkart committed
25
26
27
28
29
  test('should return jquery collection containing the element', function () {
    var $el = $('<div/>')
    var $tooltip = $el.bootstrapTooltip()
    ok($tooltip instanceof $, 'returns jquery collection')
    strictEqual($tooltip[0], $el[0], 'collection contains element')
XhmikosR's avatar
XhmikosR committed
30
31
32
  })

  test('should expose default settings', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
33
    ok($.fn.bootstrapTooltip.Constructor.DEFAULTS, 'defaults is defined')
XhmikosR's avatar
XhmikosR committed
34
35
36
  })

  test('should empty title attribute', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
37
38
    var $trigger = $('<a href="#" rel="tooltip" title="Another tooltip"/>').bootstrapTooltip()
    strictEqual($trigger.attr('title'), '', 'title attribute was emptied')
XhmikosR's avatar
XhmikosR committed
39
40
41
  })

  test('should add data attribute for referencing original title', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
42
43
    var $trigger = $('<a href="#" rel="tooltip" title="Another tooltip"/>').bootstrapTooltip()
    strictEqual($trigger.attr('data-original-title'), 'Another tooltip', 'original title preserved in data attribute')
XhmikosR's avatar
XhmikosR committed
44
45
  })

Heinrich Fenkart's avatar
Heinrich Fenkart committed
46
47
48
  test('should add aria-describedby to the trigger on show', function () {
    var $trigger = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
      .bootstrapTooltip()
49
50
      .appendTo('#qunit-fixture')
      .bootstrapTooltip('show')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
51

52
53
    var id = $('.tooltip').attr('id')

Heinrich Fenkart's avatar
Heinrich Fenkart committed
54
55
56
    strictEqual($('#' + id).length, 1, 'has a unique id')
    strictEqual($('.tooltip').attr('aria-describedby'), $trigger.attr('id'), 'tooltip id and aria-describedby on trigger match')
    ok($trigger[0].hasAttribute('aria-describedby'), 'trigger has aria-describedby')
57
58
  })

Heinrich Fenkart's avatar
Heinrich Fenkart committed
59
60
61
  test('should remove aria-describedby from trigger on hide', function () {
    var $trigger = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
      .bootstrapTooltip()
62
      .appendTo('#qunit-fixture')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
63
64
65
66
67
68

    $trigger.bootstrapTooltip('show')
    ok($trigger[0].hasAttribute('aria-describedby'), 'trigger has aria-describedby')

    $trigger.bootstrapTooltip('hide')
    ok(!$trigger[0].hasAttribute('aria-describedby'), 'trigger does not have aria-describedby')
69
70
71
  })

  test('should assign a unique id tooltip element', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
72
    $('<a href="#" rel="tooltip" title="Another tooltip"/>')
73
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
74
      .bootstrapTooltip('show')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
75

XhmikosR's avatar
XhmikosR committed
76
    var id = $('.tooltip').attr('id')
77

Heinrich Fenkart's avatar
Heinrich Fenkart committed
78
79
    strictEqual($('#' + id).length, 1, 'tooltip has unique id')
    strictEqual(id.indexOf('tooltip'), 0, 'tooltip id has prefix')
80
81
  })

XhmikosR's avatar
XhmikosR committed
82
  test('should place tooltips relative to placement option', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
83
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
XhmikosR's avatar
XhmikosR committed
84
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
85
      .bootstrapTooltip({ placement: 'bottom' })
XhmikosR's avatar
XhmikosR committed
86

Heinrich Fenkart's avatar
Heinrich Fenkart committed
87
    $tooltip.bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
88
    ok($('.tooltip').is('.fade.bottom.in'), 'has correct classes applied')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
89
90
91

    $tooltip.bootstrapTooltip('hide')
    equal($('.tooltip').length, 0, 'tooltip removed')
XhmikosR's avatar
XhmikosR committed
92
93
94
  })

  test('should allow html entities', function () {
95
    var $tooltip = $('<a href="#" rel="tooltip" title="&lt;b&gt;@fat&lt;/b&gt;"/>')
XhmikosR's avatar
XhmikosR committed
96
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
97
      .bootstrapTooltip({ html: true })
XhmikosR's avatar
XhmikosR committed
98

Heinrich Fenkart's avatar
Heinrich Fenkart committed
99
100
101
102
103
    $tooltip.bootstrapTooltip('show')
    notEqual($('.tooltip b').length, 0, 'b tag was inserted')

    $tooltip.bootstrapTooltip('hide')
    equal($('.tooltip').length, 0, 'tooltip removed')
XhmikosR's avatar
XhmikosR committed
104
105
106
  })

  test('should respect custom classes', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
107
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
XhmikosR's avatar
XhmikosR committed
108
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
109
      .bootstrapTooltip({ template: '<div class="tooltip some-class"><div class="tooltip-arrow"/><div class="tooltip-inner"/></div>' })
XhmikosR's avatar
XhmikosR committed
110

Heinrich Fenkart's avatar
Heinrich Fenkart committed
111
    $tooltip.bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
112
    ok($('.tooltip').hasClass('some-class'), 'custom class is present')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
113
114
115

    $tooltip.bootstrapTooltip('hide')
    equal($('.tooltip').length, 0, 'tooltip removed')
XhmikosR's avatar
XhmikosR committed
116
117
118
119
  })

  test('should fire show event', function () {
    stop()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
120
121

    $('<div title="tooltip title"/>')
XhmikosR's avatar
XhmikosR committed
122
      .on('show.bs.tooltip', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
123
        ok(true, 'show event fired')
XhmikosR's avatar
XhmikosR committed
124
125
        start()
      })
126
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
127
128
129
130
  })

  test('should fire shown event', function () {
    stop()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
131
132
133

    $('<div title="tooltip title"></div>')
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
134
135
136
137
      .on('shown.bs.tooltip', function () {
        ok(true, 'shown was called')
        start()
      })
138
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
139
140
  })

Heinrich Fenkart's avatar
Heinrich Fenkart committed
141
  test('should not fire shown event when show was prevented', function () {
XhmikosR's avatar
XhmikosR committed
142
    stop()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
143
144

    $('<div title="tooltip title"/>')
XhmikosR's avatar
XhmikosR committed
145
146
      .on('show.bs.tooltip', function (e) {
        e.preventDefault()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
147
        ok(true, 'show event fired')
XhmikosR's avatar
XhmikosR committed
148
149
150
        start()
      })
      .on('shown.bs.tooltip', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
151
        ok(false, 'shown event fired')
XhmikosR's avatar
XhmikosR committed
152
      })
153
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
154
155
156
157
  })

  test('should fire hide event', function () {
    stop()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
158
159
160

    $('<div title="tooltip title"/>')
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
161
      .on('shown.bs.tooltip', function () {
162
        $(this).bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
163
164
      })
      .on('hide.bs.tooltip', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
165
        ok(true, 'hide event fired')
XhmikosR's avatar
XhmikosR committed
166
167
        start()
      })
168
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
169
170
171
172
  })

  test('should fire hidden event', function () {
    stop()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
173
174
175

    $('<div title="tooltip title"/>')
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
176
      .on('shown.bs.tooltip', function () {
177
        $(this).bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
178
179
      })
      .on('hidden.bs.tooltip', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
180
        ok(true, 'hidden event fired')
XhmikosR's avatar
XhmikosR committed
181
182
        start()
      })
183
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
184
185
  })

Heinrich Fenkart's avatar
Heinrich Fenkart committed
186
  test('should not fire hidden event when hide was prevented', function () {
XhmikosR's avatar
XhmikosR committed
187
    stop()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
188
189
190

    $('<div title="tooltip title"/>')
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
191
      .on('shown.bs.tooltip', function () {
192
        $(this).bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
193
194
195
      })
      .on('hide.bs.tooltip', function (e) {
        e.preventDefault()
Heinrich Fenkart's avatar
Heinrich Fenkart committed
196
        ok(true, 'hide event fired')
XhmikosR's avatar
XhmikosR committed
197
198
199
        start()
      })
      .on('hidden.bs.tooltip', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
200
        ok(false, 'hidden event fired')
XhmikosR's avatar
XhmikosR committed
201
      })
202
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
203
204
205
206
207
  })

  test('should not show tooltip if leave event occurs before delay expires', function () {
    stop()

Heinrich Fenkart's avatar
Heinrich Fenkart committed
208
209
210
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
      .appendTo('#qunit-fixture')
      .bootstrapTooltip({ delay: 200 })
XhmikosR's avatar
XhmikosR committed
211
212

    setTimeout(function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
213
214
      ok(!$('.tooltip').is('.fade.in'), '100ms: tooltip not faded in')
      $tooltip.trigger('mouseout')
XhmikosR's avatar
XhmikosR committed
215
    }, 100)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
216
217
218
219
220
221
222

    setTimeout(function () {
      ok(!$('.tooltip').is('.fade.in'), '300ms: tooltip not faded in')
      start()
    }, 300)

    $tooltip.trigger('mouseenter')
XhmikosR's avatar
XhmikosR committed
223
224
225
226
227
  })

  test('should not show tooltip if leave event occurs before delay expires, even if hide delay is 0', function () {
    stop()

Heinrich Fenkart's avatar
Heinrich Fenkart committed
228
229
230
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
      .appendTo('#qunit-fixture')
      .bootstrapTooltip({ delay: { show: 200, hide: 0 }})
XhmikosR's avatar
XhmikosR committed
231
232

    setTimeout(function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
233
234
      ok(!$('.tooltip').is('.fade.in'), '100ms: tooltip not faded in')
      $tooltip.trigger('mouseout')
XhmikosR's avatar
XhmikosR committed
235
    }, 100)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
236
237
238
239
240
241
242

    setTimeout(function () {
      ok(!$('.tooltip').is('.fade.in'), '300ms: tooltip not faded in')
      start()
    }, 300)

    $tooltip.trigger('mouseenter')
XhmikosR's avatar
XhmikosR committed
243
244
  })

Heinrich Fenkart's avatar
Heinrich Fenkart committed
245
246
247
248
  test('should wait 200 ms before hiding the tooltip', function () {
    stop()

    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
XhmikosR's avatar
XhmikosR committed
249
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
250
      .bootstrapTooltip({ delay: { show: 0, hide: 200 }})
XhmikosR's avatar
XhmikosR committed
251

Heinrich Fenkart's avatar
Heinrich Fenkart committed
252
253
254
255
    setTimeout(function () {
      ok($('.tooltip').is('.fade.in'), '1ms: tooltip faded in')
      $tooltip.trigger('mouseout')
    }, 1)
XhmikosR's avatar
XhmikosR committed
256

Heinrich Fenkart's avatar
Heinrich Fenkart committed
257
258
259
    setTimeout(function () {
      ok($('.tooltip').is('.fade.in'), '100ms: tooltip still faded in')
    }, 100)
XhmikosR's avatar
XhmikosR committed
260
261

    setTimeout(function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
262
263
264
265
266
      ok(!$('.tooltip').is('.in'), '250ms: tooltip removed')
      start()
    }, 250)

    $tooltip.trigger('mouseenter')
XhmikosR's avatar
XhmikosR committed
267
  })
Jacob Thornton's avatar
Jacob Thornton committed
268

Heinrich Fenkart's avatar
Heinrich Fenkart committed
269
270
271
272
  test('should not hide tooltip if leave event occurs and enter event occurs within the hide delay', function () {
    stop()

    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
XhmikosR's avatar
XhmikosR committed
273
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
274
      .bootstrapTooltip({ delay: { show: 0, hide: 200 }})
Jacob Thornton's avatar
Jacob Thornton committed
275

Heinrich Fenkart's avatar
Heinrich Fenkart committed
276
277
278
279
    setTimeout(function () {
      ok($('.tooltip').is('.fade.in'), '1ms: tooltip faded in')
      $tooltip.trigger('mouseout')
    }, 1)
Jacob Thornton's avatar
Jacob Thornton committed
280

Heinrich Fenkart's avatar
Heinrich Fenkart committed
281
282
283
284
    setTimeout(function () {
      ok($('.tooltip').is('.fade.in'), '100ms: tooltip still faded in')
      $tooltip.trigger('mouseenter')
    }, 100)
Jacob Thornton's avatar
Jacob Thornton committed
285

XhmikosR's avatar
XhmikosR committed
286
    setTimeout(function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
287
288
289
290
291
      ok($('.tooltip').is('.fade.in'), '250ms: tooltip still faded in')
      start()
    }, 250)

    $tooltip.trigger('mouseenter')
XhmikosR's avatar
XhmikosR committed
292
293
294
  })

  test('should not show tooltip if leave event occurs before delay expires', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
295
296
297
    stop()

    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
XhmikosR's avatar
XhmikosR committed
298
      .appendTo('#qunit-fixture')
299
      .bootstrapTooltip({ delay: 100 })
Heinrich Fenkart's avatar
Heinrich Fenkart committed
300

XhmikosR's avatar
XhmikosR committed
301
    setTimeout(function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
302
303
      ok(!$('.tooltip').is('.fade.in'), '50ms: tooltip not faded in')
      $tooltip.trigger('mouseout')
XhmikosR's avatar
XhmikosR committed
304
    }, 50)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
305
306
307
308
309
310
311

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

    $tooltip.trigger('mouseenter')
XhmikosR's avatar
XhmikosR committed
312
313
314
  })

  test('should show tooltip if leave event hasn\'t occured before delay expires', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
315
316
317
    stop()

    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
XhmikosR's avatar
XhmikosR committed
318
      .appendTo('#qunit-fixture')
319
      .bootstrapTooltip({ delay: 150 })
Heinrich Fenkart's avatar
Heinrich Fenkart committed
320

XhmikosR's avatar
XhmikosR committed
321
    setTimeout(function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
322
      ok(!$('.tooltip').is('.fade.in'), '100ms: tooltip is not faded in')
XhmikosR's avatar
XhmikosR committed
323
    }, 100)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
324

XhmikosR's avatar
XhmikosR committed
325
    setTimeout(function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
326
      ok($('.tooltip').is('.fade.in'), '200ms: tooltip is faded in')
XhmikosR's avatar
XhmikosR committed
327
328
      start()
    }, 200)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
329
330

    $tooltip.trigger('mouseenter')
XhmikosR's avatar
XhmikosR committed
331
332
333
  })

  test('should destroy tooltip', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
    var $tooltip = $('<div/>')
      .bootstrapTooltip()
      .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 events')
    equal($._data($tooltip[0], 'events').click[0].namespace, 'foo', 'tooltip has extra click.foo event')

    $tooltip.bootstrapTooltip('show')
    $tooltip.bootstrapTooltip('destroy')

    ok(!$tooltip.hasClass('in'), 'tooltip is hidden')
    ok(!$._data($tooltip[0], 'bs.tooltip'), 'tooltip does not have data')
    equal($._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 hover events')
XhmikosR's avatar
XhmikosR committed
349
350
351
  })

  test('should show tooltip with delegate selector on click', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
352
353
354
355
356
357
358
359
    var $div = $('<div><a href="#" rel="tooltip" title="Another tooltip"/></div>')
      .appendTo('#qunit-fixture')
      .bootstrapTooltip({
        selector: 'a[rel="tooltip"]',
        trigger: 'click'
      })

    $div.find('a').click()
XhmikosR's avatar
XhmikosR committed
360
    ok($('.tooltip').is('.fade.in'), 'tooltip is faded in')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
361
362
363

    $div.find('a').click()
    equal($('.tooltip').length, 0, 'tooltip was removed from dom')
XhmikosR's avatar
XhmikosR committed
364
365
366
  })

  test('should show tooltip when toggle is called', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
367
    $('<a href="#" rel="tooltip" title="tooltip on toggle"/>')
XhmikosR's avatar
XhmikosR committed
368
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
369
      .bootstrapTooltip({ trigger: 'manual' })
370
      .bootstrapTooltip('toggle')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
371
372

    ok($('.tooltip').is('.fade.in'), 'tooltip is faded in')
XhmikosR's avatar
XhmikosR committed
373
374
  })

Heinrich Fenkart's avatar
Heinrich Fenkart committed
375
376
  test('should hide previously shown tooltip when toggle is called on tooltip', function () {
    $('<a href="#" rel="tooltip" title="tooltip on toggle">@ResentedHook</a>')
377
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
378
      .bootstrapTooltip({ trigger: 'manual' })
Heinrich Fenkart's avatar
Heinrich Fenkart committed
379
380
381
382
      .bootstrapTooltip('show')

    $('.tooltip').bootstrapTooltip('toggle')
    ok($('.tooltip').not('.fade.in'), 'tooltip was faded out')
383
384
  })

Heinrich Fenkart's avatar
Heinrich Fenkart committed
385
386
  test('should place tooltips inside body when container is body', function () {
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
XhmikosR's avatar
XhmikosR committed
387
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
388
      .bootstrapTooltip({ container: 'body' })
389
      .bootstrapTooltip('show')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
390
391
392
393
394
395

    notEqual($('body > .tooltip').length, 0, 'tooltip is direct descendant of body')
    equal($('#qunit-fixture > .tooltip').length, 0, 'tooltip is not in parent')

    $tooltip.bootstrapTooltip('hide')
    equal($('body > .tooltip').length, 0, 'tooltip was removed from dom')
XhmikosR's avatar
XhmikosR committed
396
397
  })

Heinrich Fenkart's avatar
Heinrich Fenkart committed
398
399
400
401
402
403
404
405
406
407
408
409
410
  test('should place tooltip inside viewport', function () {
    stop()

    var $container = $('<div/>')
      .css({
        position: 'absolute',
        width: 200,
        height: 200,
        bottom: 0,
        left: 0
      })
      .appendTo(document.body)

XhmikosR's avatar
XhmikosR committed
411
    $('<a href="#" title="Very very very very very very very very long tooltip">Hover me</a>')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
412
413
414
415
416
417
418
419
420
421
      .css({
        position: 'absolute',
        top: 0,
        left: 0
      })
      .appendTo($container)
      .bootstrapTooltip({
        placement: 'top',
        animate: false
      })
422
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
423
424
425

    setTimeout(function () {
      ok($('.tooltip').offset().left >= 0)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
426
      $container.remove()
XhmikosR's avatar
XhmikosR committed
427
428
429
430
431
432
433
      start()
    }, 100)
  })

  test('should place tooltip on top of element', function () {
    stop()

Heinrich Fenkart's avatar
Heinrich Fenkart committed
434
435
436
437
438
    var containerHTML = '<div>'
        + '<p style="margin-top: 200px">'
        + '<a href="#" title="very very very very very very very long tooltip">Hover me</a>'
        + '</p>'
        + '</div>'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
    var $container = $(containerHTML)
      .css({
        position: 'absolute',
        bottom: 0,
        left: 0,
        textAlign: 'right',
        width: 300,
        height: 300
      })
      .appendTo(document.body)

    var $trigger = $container
      .find('a')
      .css('margin-top', 200)
      .bootstrapTooltip({
        placement: 'top',
        animate: false
      })
      .bootstrapTooltip('show')

    var $tooltip = $container.find('.tooltip')
XhmikosR's avatar
XhmikosR committed
460

Heinrich Fenkart's avatar
Heinrich Fenkart committed
461
462
463
    setTimeout(function () {
      ok(Math.round($tooltip.offset().top + $tooltip.outerHeight()) <= Math.round($trigger.offset().top))
      $container.remove()
XhmikosR's avatar
XhmikosR committed
464
465
466
467
468
      start()
    }, 100)
  })

  test('should add position class before positioning so that position-specific styles are taken into account', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
469
470
471
472
    var styles = '<style>'
        + '.tooltip.right { white-space: nowrap; }'
        + '.tooltip.right .tooltip-inner { max-width: none; }'
        + '</style>'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
473
474
475
476
477
478
479
480
481
482
483
    var $styles = $(styles).appendTo(document.head)

    var $container = $('<div/>').appendTo(document.body)
    var $target = $('<a href="#" rel="tooltip" title="very very very very very very very very long tooltip in one line"/>')
      .appendTo($container)
      .bootstrapTooltip({
        placement: 'right',
        viewport: null
      })
      .bootstrapTooltip('show')
    var $tooltip = $container.find('.tooltip')
XhmikosR's avatar
XhmikosR committed
484
485

    // this is some dumb hack shit because sub pixels in firefox
Heinrich Fenkart's avatar
Heinrich Fenkart committed
486
487
    var top = Math.round($target.offset().top + ($target[0].offsetHeight / 2) - ($tooltip[0].offsetHeight / 2))
    var top2 = Math.round($tooltip.offset().top)
XhmikosR's avatar
XhmikosR committed
488
    var topDiff = top - top2
XhmikosR's avatar
XhmikosR committed
489
    ok(topDiff <= 1 && topDiff >= -1)
Heinrich Fenkart's avatar
Heinrich Fenkart committed
490
491
492
493
    $target.bootstrapTooltip('hide')

    $container.remove()
    $styles.remove()
XhmikosR's avatar
XhmikosR committed
494
495
  })

Heinrich Fenkart's avatar
Heinrich Fenkart committed
496
497
  test('should use title attribute for tooltip text', function () {
    var $tooltip = $('<a href="#" rel="tooltip" title="Simple tooltip"/>')
XhmikosR's avatar
XhmikosR committed
498
      .appendTo('#qunit-fixture')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
499
500
501
      .bootstrapTooltip()

    $tooltip.bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
502
    equal($('.tooltip').children('.tooltip-inner').text(), 'Simple tooltip', 'title from title attribute is set')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
503
504
505

    $tooltip.bootstrapTooltip('hide')
    equal($('.tooltip').length, 0, 'tooltip removed from dom')
XhmikosR's avatar
XhmikosR committed
506
507
  })

Heinrich Fenkart's avatar
Heinrich Fenkart committed
508
509
  test('should prefer title attribute over title option', function () {
    var $tooltip = $('<a href="#" rel="tooltip" title="Simple tooltip"/>')
XhmikosR's avatar
XhmikosR committed
510
      .appendTo('#qunit-fixture')
511
      .bootstrapTooltip({
XhmikosR's avatar
XhmikosR committed
512
513
        title: 'This is a tooltip with some content'
      })
Heinrich Fenkart's avatar
Heinrich Fenkart committed
514
515

    $tooltip.bootstrapTooltip('show')
516
    equal($('.tooltip').children('.tooltip-inner').text(), 'Simple tooltip', 'title is set from title attribute while preferred over title option')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
517
518
519

    $tooltip.bootstrapTooltip('hide')
    equal($('.tooltip').length, 0, 'tooltip removed from dom')
XhmikosR's avatar
XhmikosR committed
520
521
  })

Heinrich Fenkart's avatar
Heinrich Fenkart committed
522
523
  test('should use title option', function () {
    var $tooltip = $('<a href="#" rel="tooltip"/>')
XhmikosR's avatar
XhmikosR committed
524
      .appendTo('#qunit-fixture')
525
      .bootstrapTooltip({
XhmikosR's avatar
XhmikosR committed
526
527
        title: 'This is a tooltip with some content'
      })
Heinrich Fenkart's avatar
Heinrich Fenkart committed
528
529

    $tooltip.bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
530
    equal($('.tooltip').children('.tooltip-inner').text(), 'This is a tooltip with some content', 'title from title option is set')
Heinrich Fenkart's avatar
Heinrich Fenkart committed
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550

    $tooltip.bootstrapTooltip('hide')
    equal($('.tooltip').length, 0, 'tooltip removed from dom')
  })

  test('should be placed dynamically with the dynamic placement option', function () {
    var $style = $('<style> a[rel="tooltip"] { display: inline-block; position: absolute; } </style>')
    var $container = $('<div/>')
      .css({
        position: 'absolute',
        overflow: 'hidden',
        width: 600,
        height: 400,
        top: 0,
        left: 0
      })
      .appendTo(document.body)

    var $topTooltip = $('<div style="left: 0; top: 0;" rel="tooltip" title="Top tooltip">Top Dynamic Tooltip</div>')
      .appendTo($container)
XhmikosR's avatar
XhmikosR committed
551
      .bootstrapTooltip({ placement: 'auto' })
XhmikosR's avatar
XhmikosR committed
552

Heinrich Fenkart's avatar
Heinrich Fenkart committed
553
554
    $topTooltip.bootstrapTooltip('show')
    ok($('.tooltip').is('.bottom'), 'top positioned tooltip is dynamically positioned to bottom')
XhmikosR's avatar
XhmikosR committed
555

Heinrich Fenkart's avatar
Heinrich Fenkart committed
556
557
    $topTooltip.bootstrapTooltip('hide')
    equal($('.tooltip').length, 0, 'top positioned tooltip removed from dom')
XhmikosR's avatar
XhmikosR committed
558

Heinrich Fenkart's avatar
Heinrich Fenkart committed
559
560
    var $rightTooltip = $('<div style="right: 0;" rel="tooltip" title="Right tooltip">Right Dynamic Tooltip</div>')
      .appendTo($container)
XhmikosR's avatar
XhmikosR committed
561
      .bootstrapTooltip({ placement: 'right auto' })
XhmikosR's avatar
XhmikosR committed
562

Heinrich Fenkart's avatar
Heinrich Fenkart committed
563
    $rightTooltip.bootstrapTooltip('show')
564
    ok($('.tooltip').is('.left'), 'right positioned tooltip is dynamically positioned left')
XhmikosR's avatar
XhmikosR committed
565

Heinrich Fenkart's avatar
Heinrich Fenkart committed
566
567
568
569
570
    $rightTooltip.bootstrapTooltip('hide')
    equal($('.tooltip').length, 0, 'right positioned tooltip removed from dom')

    var $leftTooltip = $('<div style="left: 0;" rel="tooltip" title="Left tooltip">Left Dynamic Tooltip</div>')
      .appendTo($container)
XhmikosR's avatar
XhmikosR committed
571
      .bootstrapTooltip({ placement: 'auto left' })
XhmikosR's avatar
XhmikosR committed
572

Heinrich Fenkart's avatar
Heinrich Fenkart committed
573
    $leftTooltip.bootstrapTooltip('show')
574
    ok($('.tooltip').is('.right'), 'left positioned tooltip is dynamically positioned right')
XhmikosR's avatar
XhmikosR committed
575

Heinrich Fenkart's avatar
Heinrich Fenkart committed
576
577
578
579
580
    $leftTooltip.bootstrapTooltip('hide')
    equal($('.tooltip').length, 0, 'left positioned tooltip removed from dom')

    $container.remove()
    $style.remove()
XhmikosR's avatar
XhmikosR committed
581
  })
582

Heinrich Fenkart's avatar
Heinrich Fenkart committed
583
  test('should adjust the tip\'s top position when up against the top of the viewport', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
584
585
586
587
    var styles = '<style>'
        + '.tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; }'
        + 'a[rel="tooltip"] { position: fixed; }'
        + '</style>'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
    var $styles = $(styles).appendTo(document.head)

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

    $target.bootstrapTooltip('show')
    equal(Math.round($container.find('.tooltip').offset().top), 12)
603

Heinrich Fenkart's avatar
Heinrich Fenkart committed
604
605
    $target.bootstrapTooltip('hide')
    equal($('.tooltip').length, 0, 'tooltip removed from dom')
606

Heinrich Fenkart's avatar
Heinrich Fenkart committed
607
608
    $container.remove()
    $styles.remove()
609
610
  })

Heinrich Fenkart's avatar
Heinrich Fenkart committed
611
  test('should adjust the tip\'s top position when up against the bottom of the viewport', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
612
613
614
615
    var styles = '<style>'
        + '.tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; }'
        + 'a[rel="tooltip"] { position: fixed; }'
        + '</style>'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
616
617
618
619
620
621
622
623
624
625
626
627
    var $styles = $(styles).appendTo(document.head)

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

Heinrich Fenkart's avatar
Heinrich Fenkart committed
629
630
631
    $target.bootstrapTooltip('show')
    var $tooltip = $container.find('.tooltip')
    strictEqual(Math.round($tooltip.offset().top), Math.round($(window).height() - 12 - $tooltip[0].offsetHeight))
632

Heinrich Fenkart's avatar
Heinrich Fenkart committed
633
634
635
636
637
    $target.bootstrapTooltip('hide')
    equal($('.tooltip').length, 0, 'tooltip removed from dom')

    $container.remove()
    $styles.remove()
638
639
  })

Heinrich Fenkart's avatar
Heinrich Fenkart committed
640
  test('should adjust the tip\'s left position when up against the left of the viewport', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
641
642
643
644
    var styles = '<style>'
        + '.tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; }'
        + 'a[rel="tooltip"] { position: fixed; }'
        + '</style>'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
    var $styles = $(styles).appendTo(document.head)

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

    $target.bootstrapTooltip('show')
    strictEqual(Math.round($container.find('.tooltip').offset().left), 12)
660

Heinrich Fenkart's avatar
Heinrich Fenkart committed
661
662
    $target.bootstrapTooltip('hide')
    equal($('.tooltip').length, 0, 'tooltip removed from dom')
663

Heinrich Fenkart's avatar
Heinrich Fenkart committed
664
665
    $container.remove()
    $styles.remove()
666
667
  })

Heinrich Fenkart's avatar
Heinrich Fenkart committed
668
  test('should adjust the tip\'s left position when up against the right of the viewport', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
669
670
671
672
    var styles = '<style>'
        + '.tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; }'
        + 'a[rel="tooltip"] { position: fixed; }'
        + '</style>'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
673
    var $styles = $(styles).appendTo(document.head)
674

Heinrich Fenkart's avatar
Heinrich Fenkart committed
675
676
677
678
679
680
681
682
683
684
685
686
687
688
    var $container = $('<div/>').appendTo('body')
    var $target = $('<a href="#" rel="tooltip" title="tip" style="top: 0px; right: 0px;"/>')
      .appendTo($container)
      .bootstrapTooltip({
        placement: 'bottom',
        viewport: {
          selector: 'body',
          padding: 12
        }
      })

    $target.bootstrapTooltip('show')
    var $tooltip = $container.find('.tooltip')
    strictEqual(Math.round($tooltip.offset().left), Math.round($(window).width() - 12 - $tooltip[0].offsetWidth))
689

Heinrich Fenkart's avatar
Heinrich Fenkart committed
690
691
692
693
694
    $target.bootstrapTooltip('hide')
    equal($('.tooltip').length, 0, 'tooltip removed from dom')

    $container.remove()
    $styles.remove()
695
696
697
  })

  test('should adjust the tip when up against the right of an arbitrary viewport', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
698
699
700
701
702
    var styles = '<style>'
        + '.tooltip, .tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; }'
        + '.container-viewport { position: absolute; top: 50px; left: 60px; width: 300px; height: 300px; }'
        + 'a[rel="tooltip"] { position: fixed; }'
        + '</style>'
Heinrich Fenkart's avatar
Heinrich Fenkart committed
703
704
705
706
707
708
709
710
711
712
713
714
715
    var $styles = $(styles).appendTo(document.head)

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

    $target.bootstrapTooltip('show')
    var $tooltip = $container.find('.tooltip')
    strictEqual(Math.round($tooltip.offset().left), Math.round(60 + $container.width() - $tooltip[0].offsetWidth))
716

Heinrich Fenkart's avatar
Heinrich Fenkart committed
717
718
    $target.bootstrapTooltip('hide')
    equal($('.tooltip').length, 0, 'tooltip removed from dom')
719

Heinrich Fenkart's avatar
Heinrich Fenkart committed
720
721
    $container.remove()
    $styles.remove()
722
  })
Chris Rebert's avatar
Chris Rebert committed
723
724

  test('should not error when trying to show an auto-placed tooltip that has been removed from the dom', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
725
726
727
    var passed = true
    var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>')
      .appendTo('#qunit-fixture')
Chris Rebert's avatar
Chris Rebert committed
728
      .one('show.bs.tooltip', function () {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
729
        $(this).remove()
Chris Rebert's avatar
Chris Rebert committed
730
731
732
733
      })
      .bootstrapTooltip({ placement: 'auto' })

    try {
Heinrich Fenkart's avatar
Heinrich Fenkart committed
734
735
      $tooltip.bootstrapTooltip('show')
    } catch (err) {
Chris Rebert's avatar
Chris Rebert committed
736
737
738
739
      passed = false
      console.log(err)
    }

Heinrich Fenkart's avatar
Heinrich Fenkart committed
740
    ok(passed, '.tooltip(\'show\') should not throw an error if element no longer is in dom')
Chris Rebert's avatar
Chris Rebert committed
741
  })
742
})