tooltip.js 22.5 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
7
8
9
10

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

11
  module('tooltip', {
XhmikosR's avatar
XhmikosR committed
12
    setup: function () {
13
14
15
      // 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
16
    teardown: function () {
17
18
19
20
21
22
23
24
25
      $.fn.tooltip = $.fn.bootstrapTooltip
      delete $.fn.bootstrapTooltip
    }
  })

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

XhmikosR's avatar
XhmikosR committed
26
27
  test('should return element', function () {
    var div = $('<div></div>')
28
    ok(div.bootstrapTooltip() == div, 'document.body returned')
XhmikosR's avatar
XhmikosR committed
29
30
31
  })

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

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

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

XhmikosR's avatar
XhmikosR committed
45
  test('should add set set aria describedby to the element called on show', function () {
46
47
48
49
50
51
52
53
54
55
56
    var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>').bootstrapTooltip()
      .appendTo('#qunit-fixture')
      .bootstrapTooltip('show')
    ok(tooltip.attr('aria-describedby'), 'has the right attributes')
    var id = $('.tooltip').attr('id')

    ok($('#' + id).length == 1, 'has a unique id')
    ok($('.tooltip').attr('aria-describedby') === tooltip.attr('id'), 'they match!')
    ok(tooltip.attr('aria-describedby') !== undefined, 'has the right attributes')
  })

XhmikosR's avatar
XhmikosR committed
57
  test('should remove the aria-describedby attributes on hide', function () {
58
59
60
61
62
63
64
65
66
67
68
    var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>').bootstrapTooltip()
      .appendTo('#qunit-fixture')
      .bootstrapTooltip('show')
    ok(tooltip.attr('aria-describedby'), 'has the right attributes')
    tooltip.bootstrapTooltip('hide')
    ok(!tooltip.attr('aria-describedby'), 'removed the attributes on hide')
  })

  test('should assign a unique id tooltip element', function () {
    $('<a href="#" rel="tooltip" title="Another tooltip"></a>')
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
69
70
      .bootstrapTooltip('show')
    var id = $('.tooltip').attr('id')
71

XhmikosR's avatar
XhmikosR committed
72
    ok($('#' + id).length == 1 && id.indexOf('tooltip') === 0, 'generated prefixed and unique tooltip id')
73
74
  })

XhmikosR's avatar
XhmikosR committed
75
76
77
78
  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')
XhmikosR's avatar
XhmikosR committed
79
      .bootstrapTooltip({ placement: 'bottom' })
80
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
81
82

    ok($('.tooltip').is('.fade.bottom.in'), 'has correct classes applied')
83
    tooltip.bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
84
85
86
87
88
89
  })

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

    ok($('.tooltip b').length, 'b tag was inserted')
94
    tooltip.bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
95
96
97
98
99
100
    ok(!$('.tooltip').length, 'tooltip removed')
  })

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

    ok($('.tooltip').hasClass('some-class'), 'custom class is present')
105
    tooltip.bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
106
107
108
109
110
    ok(!$('.tooltip').length, 'tooltip removed')
  })

  test('should fire show event', function () {
    stop()
XhmikosR's avatar
XhmikosR committed
111
    $('<div title="tooltip title"></div>')
XhmikosR's avatar
XhmikosR committed
112
113
114
115
      .on('show.bs.tooltip', function () {
        ok(true, 'show was called')
        start()
      })
116
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
117
118
119
120
  })

  test('should fire shown event', function () {
    stop()
121
122
    var tooltip = $('<div title="tooltip title"></div>').appendTo('#qunit-fixture')
    tooltip
XhmikosR's avatar
XhmikosR committed
123
124
      .on('shown.bs.tooltip', function () {
        ok(true, 'shown was called')
125
        tooltip.remove()
XhmikosR's avatar
XhmikosR committed
126
127
        start()
      })
128
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
129
130
131
132
  })

  test('should not fire shown event when default prevented', function () {
    stop()
XhmikosR's avatar
XhmikosR committed
133
    $('<div title="tooltip title"></div>')
XhmikosR's avatar
XhmikosR committed
134
135
136
137
138
139
140
141
      .on('show.bs.tooltip', function (e) {
        e.preventDefault()
        ok(true, 'show was called')
        start()
      })
      .on('shown.bs.tooltip', function () {
        ok(false, 'shown was called')
      })
142
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
143
144
145
146
  })

  test('should fire hide event', function () {
    stop()
147
148
    var tooltip = $('<div title="tooltip title"></div>').appendTo('#qunit-fixture')
    tooltip
XhmikosR's avatar
XhmikosR committed
149
      .on('shown.bs.tooltip', function () {
150
        $(this).bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
151
152
153
      })
      .on('hide.bs.tooltip', function () {
        ok(true, 'hide was called')
154
        tooltip.remove()
XhmikosR's avatar
XhmikosR committed
155
156
        start()
      })
157
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
158
159
160
161
  })

  test('should fire hidden event', function () {
    stop()
162
163
    var tooltip = $('<div title="tooltip title"></div>').appendTo('#qunit-fixture')
    tooltip
XhmikosR's avatar
XhmikosR committed
164
      .on('shown.bs.tooltip', function () {
165
        $(this).bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
166
167
168
      })
      .on('hidden.bs.tooltip', function () {
        ok(true, 'hidden was called')
169
        tooltip.remove()
XhmikosR's avatar
XhmikosR committed
170
171
        start()
      })
172
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
173
174
175
176
  })

  test('should not fire hidden event when default prevented', function () {
    stop()
177
178
    var tooltip = $('<div title="tooltip title"></div>').appendTo('#qunit-fixture')
    tooltip
XhmikosR's avatar
XhmikosR committed
179
      .on('shown.bs.tooltip', function () {
180
        $(this).bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
181
182
183
184
      })
      .on('hide.bs.tooltip', function (e) {
        e.preventDefault()
        ok(true, 'hide was called')
185
        tooltip.remove()
XhmikosR's avatar
XhmikosR committed
186
187
188
189
190
        start()
      })
      .on('hidden.bs.tooltip', function () {
        ok(false, 'hidden was called')
      })
191
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
192
193
194
195
196
  })

  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')
197
      .bootstrapTooltip({ delay: 200 })
XhmikosR's avatar
XhmikosR committed
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215

    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')
XhmikosR's avatar
XhmikosR committed
216
      .bootstrapTooltip({ delay: { show: 200, hide: 0 }})
XhmikosR's avatar
XhmikosR committed
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234

    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')
XhmikosR's avatar
XhmikosR committed
235
      .bootstrapTooltip({ delay: { show: 0, hide: 200 }})
XhmikosR's avatar
XhmikosR committed
236
237
238
239
240
241
242
243
244
245

    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
246
        setTimeout(function () {
XhmikosR's avatar
XhmikosR committed
247
248
249
250
251
252
          ok(!$('.tooltip').is('.in'), 'tooltip removed')
          start()
        }, 150)
      }, 100)
    }, 1)
  })
Jacob Thornton's avatar
Jacob Thornton committed
253

XhmikosR's avatar
XhmikosR committed
254
255
256
  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')
XhmikosR's avatar
XhmikosR committed
257
      .bootstrapTooltip({ delay: { show: 0, hide: 200 }})
Jacob Thornton's avatar
Jacob Thornton committed
258

XhmikosR's avatar
XhmikosR committed
259
    stop()
Jacob Thornton's avatar
Jacob Thornton committed
260

XhmikosR's avatar
XhmikosR committed
261
    tooltip.trigger('mouseenter')
Jacob Thornton's avatar
Jacob Thornton committed
262

XhmikosR's avatar
XhmikosR committed
263
264
265
266
267
    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')
268
269
        tooltip.trigger('mouseenter')
        setTimeout(function () {
XhmikosR's avatar
XhmikosR committed
270
          ok($('.tooltip').is('.in'), 'tooltip removed')
Jacob Thornton's avatar
Jacob Thornton committed
271
          start()
XhmikosR's avatar
XhmikosR committed
272
273
274
275
276
277
278
279
        }, 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')
280
      .bootstrapTooltip({ delay: 100 })
XhmikosR's avatar
XhmikosR committed
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
    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')
296
      .bootstrapTooltip({ delay: 150 })
XhmikosR's avatar
XhmikosR committed
297
298
299
300
301
302
303
304
305
306
307
308
    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 () {
309
    var tooltip = $('<div/>').bootstrapTooltip().on('click.foo', function () {})
XhmikosR's avatar
XhmikosR committed
310
311
312
    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')
313
314
    tooltip.bootstrapTooltip('show')
    tooltip.bootstrapTooltip('destroy')
XhmikosR's avatar
XhmikosR committed
315
316
317
318
319
320
321
322
    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
323
324
325
    div.appendTo('#qunit-fixture').bootstrapTooltip({
      selector: 'a[rel="tooltip"]', trigger: 'click'
    })
XhmikosR's avatar
XhmikosR committed
326
327
328
329
330
    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
331
    $('<a href="#" rel="tooltip" title="tooltip on toggle"></a>')
XhmikosR's avatar
XhmikosR committed
332
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
333
      .bootstrapTooltip({ trigger: 'manual' })
334
      .bootstrapTooltip('toggle')
XhmikosR's avatar
XhmikosR committed
335
336
337
    ok($('.tooltip').is('.fade.in'), 'tooltip should be toggled in')
  })

338
339
340
  test('should hide shown tooltip when toggle is called on tooltip', function () {
    var tooltip = $('<a href="#" rel="tooltip" title="tooltip on toggle">@ResentedHook</a>')
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
341
      .bootstrapTooltip({ trigger: 'manual' })
342
343
344
345
346
347
348
      .bootstrapTooltip('toggle')
    $('.tooltip', '#qunit-fixture').bootstrapTooltip('toggle')
    ok($('.tooltip').not('.fade.in'), 'tooltip should be toggled out')
    tooltip.bootstrapTooltip('hide')
    $('#qunit-fixture').empty()
  })

XhmikosR's avatar
XhmikosR committed
349
350
351
  test('should place tooltips inside the body', function () {
    var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>')
      .appendTo('#qunit-fixture')
XhmikosR's avatar
XhmikosR committed
352
      .bootstrapTooltip({ container: 'body' })
353
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
354
355
    ok($('body > .tooltip').length, 'inside the body')
    ok(!$('#qunit-fixture > .tooltip').length, 'not found in parent')
356
    tooltip.bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
357
358
359
360
  })

  test('should place tooltip inside window', function () {
    var container = $('<div />').appendTo('body')
XhmikosR's avatar
XhmikosR committed
361
        .css({ position: 'absolute', width: 200, height: 200, bottom: 0, left: 0 })
XhmikosR's avatar
XhmikosR committed
362
    $('<a href="#" title="Very very very very very very very very long tooltip">Hover me</a>')
XhmikosR's avatar
XhmikosR committed
363
      .css({ position: 'absolute', top: 0, left: 0 })
XhmikosR's avatar
XhmikosR committed
364
      .appendTo(container)
XhmikosR's avatar
XhmikosR committed
365
      .bootstrapTooltip({ placement: 'top', animate: false })
366
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
367
368
369
370
371
372
373
374
375
376
377
378
379

    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')
XhmikosR's avatar
XhmikosR committed
380
381
382
383
          .css({ position: 'absolute', bottom: 0, left: 0, textAlign: 'right', width: 300, height: 300 })
    var p = $('<p style="margin-top:200px" />').appendTo(container)
    var tooltiped = $('<a href="#" title="very very very very very very very long tooltip">Hover me</a>')
            .css({ marginTop: 200 })
XhmikosR's avatar
XhmikosR committed
384
            .appendTo(p)
XhmikosR's avatar
XhmikosR committed
385
            .bootstrapTooltip({ placement: 'top', animate: false })
386
            .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
387
388
389
390
391
392
393
394
395
396
397
398
399

    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 () {
400
    $('head').append('<style id="test"> .tooltip.right { white-space: nowrap; } .tooltip.right .tooltip-inner { max-width: none; } </style>')
XhmikosR's avatar
XhmikosR committed
401

XhmikosR's avatar
XhmikosR committed
402
403
    var container = $('<div />').appendTo('body')
    var target = $('<a href="#" rel="tooltip" title="very very very very very very very very long tooltip in one line"></a>')
404
          .appendTo(container)
XhmikosR's avatar
XhmikosR committed
405
406
407
          .bootstrapTooltip({ placement: 'right', viewport: null })
          .bootstrapTooltip('show')
    var tooltip = container.find('.tooltip')
XhmikosR's avatar
XhmikosR committed
408
409
410
411

    // 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)
XhmikosR's avatar
XhmikosR committed
412
    var topDiff = top - top2
XhmikosR's avatar
XhmikosR committed
413
    ok(topDiff <= 1 && topDiff >= -1)
414
    target.bootstrapTooltip('hide')
415
    $('head #test').remove()
XhmikosR's avatar
XhmikosR committed
416
417
418
419
420
  })

  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')
421
422
      .bootstrapTooltip({})
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
423
    equal($('.tooltip').children('.tooltip-inner').text(), 'Simple tooltip', 'title from title attribute is set')
424
    tooltip.bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
425
426
427
428
429
430
    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')
431
      .bootstrapTooltip({
XhmikosR's avatar
XhmikosR committed
432
433
        title: 'This is a tooltip with some content'
      })
434
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
435
    equal($('.tooltip').children('.tooltip-inner').text(), 'Simple tooltip', 'title is set from title attribute while prefered over title option')
436
    tooltip.bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
437
438
439
440
441
442
    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')
443
      .bootstrapTooltip({
XhmikosR's avatar
XhmikosR committed
444
445
        title: 'This is a tooltip with some content'
      })
446
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
447
    equal($('.tooltip').children('.tooltip-inner').text(), 'This is a tooltip with some content', 'title from title option is set')
448
    tooltip.bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
449
450
451
452
453
454
    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
455
456
457
458
459
460
      height: 400,
      overflow: 'hidden',
      position: 'absolute',
      top: 0,
      left: 0,
      width: 600
461
462
    })
    .appendTo('body')
XhmikosR's avatar
XhmikosR committed
463
464
465

    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')
XhmikosR's avatar
XhmikosR committed
466
      .bootstrapTooltip({ placement: 'auto' })
467
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
468

469
    ok($('.tooltip').is('.bottom'), 'top positioned tooltip is dynamically positioned bottom')
XhmikosR's avatar
XhmikosR committed
470

471
    topTooltip.bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
472
473
474

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

478
    ok($('.tooltip').is('.left'), 'right positioned tooltip is dynamically positioned left')
479
    rightTooltip.bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
480
481
482

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

486
    ok($('.tooltip').is('.right'), 'left positioned tooltip is dynamically positioned right')
487
    leftTooltip.bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
488
489
490

    ttContainer.remove()
  })
491

492
493
494
  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>')

XhmikosR's avatar
XhmikosR committed
495
496
    var container = $('<div />').appendTo('body')
    var target = $('<a href="#" rel="tooltip" title="tip" style="position: fixed; top: 0px; left: 0px;"></a>')
497
          .appendTo(container)
XhmikosR's avatar
XhmikosR committed
498
499
500
          .bootstrapTooltip({ placement: 'right', viewport: { selector: 'body', padding: 12 }})
          .bootstrapTooltip('show')
    var tooltip = container.find('.tooltip')
501

XhmikosR's avatar
XhmikosR committed
502
    ok(Math.round(tooltip.offset().top) === 12)
503
    target.bootstrapTooltip('hide')
504
505
506
507
508
509
    $('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>')

XhmikosR's avatar
XhmikosR committed
510
511
    var container = $('<div />').appendTo('body')
    var target = $('<a href="#" rel="tooltip" title="tip" style="position: fixed; bottom: 0px; left: 0px;"></a>')
512
          .appendTo(container)
XhmikosR's avatar
XhmikosR committed
513
514
515
          .bootstrapTooltip({ placement: 'right', viewport: { selector: 'body', padding: 12 }})
          .bootstrapTooltip('show')
    var tooltip = container.find('.tooltip')
516

XhmikosR's avatar
XhmikosR committed
517
    ok(Math.round(tooltip.offset().top) === Math.round($(window).height() - 12 - tooltip[0].offsetHeight))
518
    target.bootstrapTooltip('hide')
519
520
521
522
523
524
    $('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>')

XhmikosR's avatar
XhmikosR committed
525
526
    var container = $('<div />').appendTo('body')
    var target = $('<a href="#" rel="tooltip" title="tip" style="position: fixed; top: 0px; left: 0px;"></a>')
527
          .appendTo(container)
XhmikosR's avatar
XhmikosR committed
528
529
530
          .bootstrapTooltip({ placement: 'bottom', viewport: { selector: 'body', padding: 12 }})
          .bootstrapTooltip('show')
    var tooltip = container.find('.tooltip')
531

XhmikosR's avatar
XhmikosR committed
532
    ok(Math.round(tooltip.offset().left) === 12)
533
    target.bootstrapTooltip('hide')
534
535
536
537
538
539
    $('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>')

XhmikosR's avatar
XhmikosR committed
540
541
    var container = $('<div />').appendTo('body')
    var target = $('<a href="#" rel="tooltip" title="tip" style="position: fixed; top: 0px; right: 0px;"></a>')
542
          .appendTo(container)
XhmikosR's avatar
XhmikosR committed
543
544
545
          .bootstrapTooltip({ placement: 'bottom', viewport: { selector: 'body', padding: 12 }})
          .bootstrapTooltip('show')
    var tooltip = container.find('.tooltip')
546

XhmikosR's avatar
XhmikosR committed
547
    ok(Math.round(tooltip.offset().left) === Math.round($(window).width() - 12 - tooltip[0].offsetWidth))
548
    target.bootstrapTooltip('hide')
549
550
551
552
553
554
555
    $('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>')

XhmikosR's avatar
XhmikosR committed
556
557
    var container = $('<div />', { 'class': 'container-viewport' }).appendTo('body')
    var target = $('<a href="#" rel="tooltip" title="tip" style="position: fixed; top: 50px; left: 350px;"></a>')
558
          .appendTo(container)
XhmikosR's avatar
XhmikosR committed
559
560
561
          .bootstrapTooltip({ placement: 'bottom', viewport: '.container-viewport' })
          .bootstrapTooltip('show')
    var tooltip = container.find('.tooltip')
562

XhmikosR's avatar
XhmikosR committed
563
    ok(Math.round(tooltip.offset().left) === Math.round(60 + container.width() - tooltip[0].offsetWidth))
564
    target.bootstrapTooltip('hide')
565
566
567
    $('head #test').remove()
    $('head #viewport-style').remove()
  })
Chris Rebert's avatar
Chris Rebert committed
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594

  test('should not error when trying to show an auto-placed tooltip that has been removed from the dom', function () {
    var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>').appendTo('#qunit-fixture')

    tooltip
      .one('show.bs.tooltip', function () {
        tooltip.remove()
      })
      .bootstrapTooltip({ placement: 'auto' })

    var passed = true
    try {
      tooltip.bootstrapTooltip('show')
    }
    catch (err) {
      passed = false
      console.log(err)
    }
    ok(passed, '.tooltip(\'show\') should not throw an error in this case')

    try {
      tooltip.remove()
    }
    catch (err) {
      // tooltip may have already been removed
    }
  })
595
})