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

3
  module('tooltip plugin')
XhmikosR's avatar
XhmikosR committed
4
5
6
7
8
9

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

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
  module('tooltip', {
    setup: function() {
      // 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()
    },
    teardown: function() {
      $.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
25
26
  test('should return element', function () {
    var div = $('<div></div>')
27
    ok(div.bootstrapTooltip() == div, 'document.body returned')
XhmikosR's avatar
XhmikosR committed
28
29
30
  })

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

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

  test('should add data attribute for referencing original title', function () {
40
    var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>').bootstrapTooltip()
XhmikosR's avatar
XhmikosR committed
41
42
43
44
45
46
47
    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')
48
49
      .bootstrapTooltip({placement: 'bottom'})
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
50
51

    ok($('.tooltip').is('.fade.bottom.in'), 'has correct classes applied')
52
    tooltip.bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
53
54
55
56
57
58
  })

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

    ok($('.tooltip b').length, 'b tag was inserted')
63
    tooltip.bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
64
65
66
67
68
69
    ok(!$('.tooltip').length, 'tooltip removed')
  })

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

    ok($('.tooltip').hasClass('some-class'), 'custom class is present')
74
    tooltip.bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
75
76
77
78
79
    ok(!$('.tooltip').length, 'tooltip removed')
  })

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

  test('should fire shown event', function () {
    stop()
XhmikosR's avatar
XhmikosR committed
90
    $('<div title="tooltip title"></div>')
XhmikosR's avatar
XhmikosR committed
91
92
93
94
      .on('shown.bs.tooltip', function () {
        ok(true, 'shown was called')
        start()
      })
95
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
96
97
98
99
  })

  test('should not fire shown event when default prevented', function () {
    stop()
XhmikosR's avatar
XhmikosR committed
100
    $('<div title="tooltip title"></div>')
XhmikosR's avatar
XhmikosR committed
101
102
103
104
105
106
107
108
      .on('show.bs.tooltip', function (e) {
        e.preventDefault()
        ok(true, 'show was called')
        start()
      })
      .on('shown.bs.tooltip', function () {
        ok(false, 'shown was called')
      })
109
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
110
111
112
113
  })

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

  test('should fire hidden event', function () {
    stop()
XhmikosR's avatar
XhmikosR committed
127
    $('<div title="tooltip title"></div>')
XhmikosR's avatar
XhmikosR committed
128
      .on('shown.bs.tooltip', function () {
129
        $(this).bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
130
131
132
133
134
      })
      .on('hidden.bs.tooltip', function () {
        ok(true, 'hidden was called')
        start()
      })
135
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
136
137
138
139
  })

  test('should not fire hidden event when default prevented', function () {
    stop()
XhmikosR's avatar
XhmikosR committed
140
    $('<div title="tooltip title"></div>')
XhmikosR's avatar
XhmikosR committed
141
      .on('shown.bs.tooltip', function () {
142
        $(this).bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
143
144
145
146
147
148
149
150
151
      })
      .on('hide.bs.tooltip', function (e) {
        e.preventDefault()
        ok(true, 'hide was called')
        start()
      })
      .on('hidden.bs.tooltip', function () {
        ok(false, 'hidden was called')
      })
152
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
153
154
155
156
157
  })

  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')
158
      .bootstrapTooltip({ delay: 200 })
XhmikosR's avatar
XhmikosR committed
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176

    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')
177
      .bootstrapTooltip({ delay: { show: 200, hide: 0} })
XhmikosR's avatar
XhmikosR committed
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195

    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')
196
      .bootstrapTooltip({ delay: { show: 0, hide: 200} })
XhmikosR's avatar
XhmikosR committed
197
198
199
200
201
202
203
204
205
206

    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
207
        setTimeout(function () {
XhmikosR's avatar
XhmikosR committed
208
209
210
211
212
213
          ok(!$('.tooltip').is('.in'), 'tooltip removed')
          start()
        }, 150)
      }, 100)
    }, 1)
  })
Jacob Thornton's avatar
Jacob Thornton committed
214

XhmikosR's avatar
XhmikosR committed
215
216
217
  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')
218
      .bootstrapTooltip({ delay: { show: 0, hide: 200} })
Jacob Thornton's avatar
Jacob Thornton committed
219

XhmikosR's avatar
XhmikosR committed
220
    stop()
Jacob Thornton's avatar
Jacob Thornton committed
221

XhmikosR's avatar
XhmikosR committed
222
    tooltip.trigger('mouseenter')
Jacob Thornton's avatar
Jacob Thornton committed
223

XhmikosR's avatar
XhmikosR committed
224
225
226
227
228
    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')
229
230
        tooltip.trigger('mouseenter')
        setTimeout(function () {
XhmikosR's avatar
XhmikosR committed
231
          ok($('.tooltip').is('.in'), 'tooltip removed')
Jacob Thornton's avatar
Jacob Thornton committed
232
          start()
XhmikosR's avatar
XhmikosR committed
233
234
235
236
237
238
239
240
        }, 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')
241
      .bootstrapTooltip({ delay: 100 })
XhmikosR's avatar
XhmikosR committed
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
    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')
257
      .bootstrapTooltip({ delay: 150 })
XhmikosR's avatar
XhmikosR committed
258
259
260
261
262
263
264
265
266
267
268
269
    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 () {
270
    var tooltip = $('<div/>').bootstrapTooltip().on('click.foo', function () {})
XhmikosR's avatar
XhmikosR committed
271
272
273
    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')
274
275
    tooltip.bootstrapTooltip('show')
    tooltip.bootstrapTooltip('destroy')
XhmikosR's avatar
XhmikosR committed
276
277
278
279
280
281
282
283
    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
284
    div.appendTo('#qunit-fixture')
285
                     .bootstrapTooltip({ selector: 'a[rel="tooltip"]', trigger: 'click' })
XhmikosR's avatar
XhmikosR committed
286
287
288
289
290
    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
291
    $('<a href="#" rel="tooltip" title="tooltip on toggle"></a>')
XhmikosR's avatar
XhmikosR committed
292
      .appendTo('#qunit-fixture')
293
294
      .bootstrapTooltip({trigger: 'manual'})
      .bootstrapTooltip('toggle')
XhmikosR's avatar
XhmikosR committed
295
296
297
    ok($('.tooltip').is('.fade.in'), 'tooltip should be toggled in')
  })

298
299
300
301
302
303
304
305
306
307
308
  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')
      .bootstrapTooltip({trigger: 'manual'})
      .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
309
310
311
  test('should place tooltips inside the body', function () {
    var tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"></a>')
      .appendTo('#qunit-fixture')
312
313
      .bootstrapTooltip({container: 'body'})
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
314
315
    ok($('body > .tooltip').length, 'inside the body')
    ok(!$('#qunit-fixture > .tooltip').length, 'not found in parent')
316
    tooltip.bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
317
318
319
320
  })

  test('should place tooltip inside window', function () {
    var container = $('<div />').appendTo('body')
XhmikosR's avatar
XhmikosR committed
321
322
        .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
323
324
      .css({position: 'absolute', top: 0, left: 0})
      .appendTo(container)
325
326
      .bootstrapTooltip({placement: 'top', animate: false})
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344

    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)
345
346
            .bootstrapTooltip({placement: 'top', animate: false})
            .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
347
348
349
350
351
352
353
354
355
356
357
358
359

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

    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>')
364
          .appendTo(container)
365
366
          .bootstrapTooltip({placement: 'right', viewport: null})
          .bootstrapTooltip('show'),
XhmikosR's avatar
XhmikosR committed
367
368
369
370
371
372
373
        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)
374
    target.bootstrapTooltip('hide')
375
    $('head #test').remove()
XhmikosR's avatar
XhmikosR committed
376
377
378
379
380
  })

  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')
381
382
      .bootstrapTooltip({})
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
383
    equal($('.tooltip').children('.tooltip-inner').text(), 'Simple tooltip', 'title from title attribute is set')
384
    tooltip.bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
385
386
387
388
389
390
    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')
391
      .bootstrapTooltip({
XhmikosR's avatar
XhmikosR committed
392
393
        title: 'This is a tooltip with some content'
      })
394
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
395
    equal($('.tooltip').children('.tooltip-inner').text(), 'Simple tooltip', 'title is set from title attribute while prefered over title option')
396
    tooltip.bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
397
398
399
400
401
402
    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')
403
      .bootstrapTooltip({
XhmikosR's avatar
XhmikosR committed
404
405
        title: 'This is a tooltip with some content'
      })
406
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
407
    equal($('.tooltip').children('.tooltip-inner').text(), 'This is a tooltip with some content', 'title from title option is set')
408
    tooltip.bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
409
410
411
412
413
414
    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
415
416
417
418
419
420
      height : 400,
      overflow : 'hidden',
      position : 'absolute',
      top : 0,
      left : 0,
      width : 600
421
422
    })
    .appendTo('body')
XhmikosR's avatar
XhmikosR committed
423
424
425

    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')
426
427
      .bootstrapTooltip({placement: 'auto'})
      .bootstrapTooltip('show')
XhmikosR's avatar
XhmikosR committed
428

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

431
    topTooltip.bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
432
433
434

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

438
    ok($('.tooltip').is('.left'), 'right positioned tooltip is dynamically positioned left')
439
    rightTooltip.bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
440
441
442

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

446
    ok($('.tooltip').is('.right'), 'left positioned tooltip is dynamically positioned right')
447
    leftTooltip.bootstrapTooltip('hide')
XhmikosR's avatar
XhmikosR committed
448
449
450

    ttContainer.remove()
  })
451

452
453
454
455
456
457
  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)
458
459
          .bootstrapTooltip({placement: 'right', viewport: {selector: 'body', padding: 12}})
          .bootstrapTooltip('show'),
460
461
462
      tooltip = container.find('.tooltip')

    ok( Math.round(tooltip.offset().top) === 12 )
463
    target.bootstrapTooltip('hide')
464
465
466
467
468
469
470
471
472
    $('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)
473
474
          .bootstrapTooltip({placement: 'right', viewport: {selector: 'body', padding: 12}})
          .bootstrapTooltip('show'),
475
476
477
      tooltip = container.find('.tooltip')

    ok( Math.round(tooltip.offset().top) === Math.round($(window).height() - 12 - tooltip[0].offsetHeight) )
478
    target.bootstrapTooltip('hide')
479
480
481
482
483
484
485
486
487
    $('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)
488
489
          .bootstrapTooltip({placement: 'bottom', viewport: {selector: 'body', padding: 12}})
          .bootstrapTooltip('show'),
490
491
492
      tooltip = container.find('.tooltip')

    ok( Math.round(tooltip.offset().left) === 12 )
493
    target.bootstrapTooltip('hide')
494
495
496
497
498
499
500
501
502
    $('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)
503
504
          .bootstrapTooltip({placement: 'bottom', viewport: {selector: 'body', padding: 12}})
          .bootstrapTooltip('show'),
505
506
507
      tooltip = container.find('.tooltip')

    ok( Math.round(tooltip.offset().left) === Math.round($(window).width() - 12 - tooltip[0].offsetWidth) )
508
    target.bootstrapTooltip('hide')
509
510
511
512
513
514
515
516
517
518
    $('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)
519
520
          .bootstrapTooltip({placement: 'bottom', viewport: '.container-viewport'})
          .bootstrapTooltip('show'),
521
522
523
      tooltip = container.find('.tooltip')

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