]>
Commit | Line | Data |
---|---|---|
91e44d91 S |
1 | $(function () { |
2 | 'use strict' | |
3 | ||
4 | QUnit.module('tooltip plugin') | |
5 | ||
6 | QUnit.test('should be defined on jquery object', function (assert) { | |
7 | assert.expect(1) | |
8 | assert.ok($(document.body).tooltip, 'tooltip method is defined') | |
9 | }) | |
10 | ||
11 | QUnit.module('tooltip', { | |
12 | beforeEach: function () { | |
13 | // Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode | |
14 | $.fn.bootstrapTooltip = $.fn.tooltip.noConflict() | |
15 | }, | |
16 | afterEach: function () { | |
17 | $.fn.tooltip = $.fn.bootstrapTooltip | |
18 | delete $.fn.bootstrapTooltip | |
19 | $('.tooltip').remove() | |
20 | } | |
21 | }) | |
22 | ||
23 | QUnit.test('should provide no conflict', function (assert) { | |
24 | assert.expect(1) | |
25 | assert.strictEqual($.fn.tooltip, undefined, 'tooltip was set back to undefined (org value)') | |
26 | }) | |
27 | ||
28 | QUnit.test('should throw explicit error on undefined method', function (assert) { | |
29 | assert.expect(1) | |
30 | var $el = $('<div/>') | |
31 | $el.bootstrapTooltip() | |
32 | try { | |
33 | $el.bootstrapTooltip('noMethod') | |
34 | } | |
35 | catch (err) { | |
36 | assert.strictEqual(err.message, 'No method named "noMethod"') | |
37 | } | |
38 | }) | |
39 | ||
40 | QUnit.test('should return jquery collection containing the element', function (assert) { | |
41 | assert.expect(2) | |
42 | var $el = $('<div/>') | |
43 | var $tooltip = $el.bootstrapTooltip() | |
44 | assert.ok($tooltip instanceof $, 'returns jquery collection') | |
45 | assert.strictEqual($tooltip[0], $el[0], 'collection contains element') | |
46 | }) | |
47 | ||
48 | QUnit.test('should expose default settings', function (assert) { | |
49 | assert.expect(1) | |
50 | assert.ok($.fn.bootstrapTooltip.Constructor.Default, 'defaults is defined') | |
51 | }) | |
52 | ||
53 | QUnit.test('should empty title attribute', function (assert) { | |
54 | assert.expect(1) | |
55 | var $trigger = $('<a href="#" rel="tooltip" title="Another tooltip"/>').bootstrapTooltip() | |
56 | assert.strictEqual($trigger.attr('title'), '', 'title attribute was emptied') | |
57 | }) | |
58 | ||
59 | QUnit.test('should add data attribute for referencing original title', function (assert) { | |
60 | assert.expect(1) | |
61 | var $trigger = $('<a href="#" rel="tooltip" title="Another tooltip"/>').bootstrapTooltip() | |
62 | assert.strictEqual($trigger.attr('data-original-title'), 'Another tooltip', 'original title preserved in data attribute') | |
63 | }) | |
64 | ||
65 | QUnit.test('should add aria-describedby to the trigger on show', function (assert) { | |
66 | assert.expect(3) | |
67 | var $trigger = $('<a href="#" rel="tooltip" title="Another tooltip"/>') | |
68 | .bootstrapTooltip() | |
69 | .appendTo('#qunit-fixture') | |
70 | .bootstrapTooltip('show') | |
71 | ||
72 | var id = $('.tooltip').attr('id') | |
73 | ||
74 | assert.strictEqual($('#' + id).length, 1, 'has a unique id') | |
75 | assert.strictEqual($('.tooltip').attr('aria-describedby'), $trigger.attr('id'), 'tooltip id and aria-describedby on trigger match') | |
76 | assert.ok($trigger[0].hasAttribute('aria-describedby'), 'trigger has aria-describedby') | |
77 | }) | |
78 | ||
79 | QUnit.test('should remove aria-describedby from trigger on hide', function (assert) { | |
80 | assert.expect(2) | |
81 | var $trigger = $('<a href="#" rel="tooltip" title="Another tooltip"/>') | |
82 | .bootstrapTooltip() | |
83 | .appendTo('#qunit-fixture') | |
84 | ||
85 | $trigger.bootstrapTooltip('show') | |
86 | assert.ok($trigger[0].hasAttribute('aria-describedby'), 'trigger has aria-describedby') | |
87 | ||
88 | $trigger.bootstrapTooltip('hide') | |
89 | assert.ok(!$trigger[0].hasAttribute('aria-describedby'), 'trigger does not have aria-describedby') | |
90 | }) | |
91 | ||
92 | QUnit.test('should assign a unique id tooltip element', function (assert) { | |
93 | assert.expect(2) | |
94 | $('<a href="#" rel="tooltip" title="Another tooltip"/>') | |
95 | .appendTo('#qunit-fixture') | |
96 | .bootstrapTooltip('show') | |
97 | ||
98 | var id = $('.tooltip').attr('id') | |
99 | ||
100 | assert.strictEqual($('#' + id).length, 1, 'tooltip has unique id') | |
101 | assert.strictEqual(id.indexOf('tooltip'), 0, 'tooltip id has prefix') | |
102 | }) | |
103 | ||
104 | QUnit.test('should place tooltips relative to placement option', function (assert) { | |
105 | assert.expect(2) | |
106 | var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>') | |
107 | .appendTo('#qunit-fixture') | |
108 | .bootstrapTooltip({ placement: 'bottom' }) | |
109 | ||
110 | $tooltip.bootstrapTooltip('show') | |
111 | ||
112 | assert | |
113 | .ok($('.tooltip') | |
114 | .is('.fade.bs-tether-element-attached-top.bs-tether-element-attached-center.show'), 'has correct classes applied') | |
115 | ||
116 | $tooltip.bootstrapTooltip('hide') | |
117 | ||
118 | assert.strictEqual($tooltip.data('bs.tooltip').tip.parentNode, null, 'tooltip removed') | |
119 | }) | |
120 | ||
121 | QUnit.test('should allow html entities', function (assert) { | |
122 | assert.expect(2) | |
123 | var $tooltip = $('<a href="#" rel="tooltip" title="<b>@fat</b>"/>') | |
124 | .appendTo('#qunit-fixture') | |
125 | .bootstrapTooltip({ html: true }) | |
126 | ||
127 | $tooltip.bootstrapTooltip('show') | |
128 | assert.notEqual($('.tooltip b').length, 0, 'b tag was inserted') | |
129 | ||
130 | $tooltip.bootstrapTooltip('hide') | |
131 | assert.strictEqual($tooltip.data('bs.tooltip').tip.parentNode, null, 'tooltip removed') | |
132 | }) | |
133 | ||
134 | QUnit.test('should allow DOMElement title (html: false)', function (assert) { | |
135 | assert.expect(3) | |
136 | var title = document.createTextNode('<3 writing tests') | |
137 | var $tooltip = $('<a href="#" rel="tooltip"/>') | |
138 | .appendTo('#qunit-fixture') | |
139 | .bootstrapTooltip({ title: title }) | |
140 | ||
141 | $tooltip.bootstrapTooltip('show') | |
142 | ||
143 | assert.notEqual($('.tooltip').length, 0, 'tooltip inserted') | |
144 | assert.strictEqual($('.tooltip').text(), '<3 writing tests', 'title inserted') | |
145 | assert.ok(!$.contains($('.tooltip').get(0), title), 'title node copied, not moved') | |
146 | }) | |
147 | ||
148 | QUnit.test('should allow DOMElement title (html: true)', function (assert) { | |
149 | assert.expect(3) | |
150 | var title = document.createTextNode('<3 writing tests') | |
151 | var $tooltip = $('<a href="#" rel="tooltip"/>') | |
152 | .appendTo('#qunit-fixture') | |
153 | .bootstrapTooltip({ html: true, title: title }) | |
154 | ||
155 | $tooltip.bootstrapTooltip('show') | |
156 | ||
157 | assert.notEqual($('.tooltip').length, 0, 'tooltip inserted') | |
158 | assert.strictEqual($('.tooltip').text(), '<3 writing tests', 'title inserted') | |
159 | assert.ok($.contains($('.tooltip').get(0), title), 'title node moved, not copied') | |
160 | }) | |
161 | ||
162 | ||
163 | QUnit.test('should respect custom classes', function (assert) { | |
164 | assert.expect(2) | |
165 | var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>') | |
166 | .appendTo('#qunit-fixture') | |
167 | .bootstrapTooltip({ template: '<div class="tooltip some-class"><div class="tooltip-arrow"/><div class="tooltip-inner"/></div>' }) | |
168 | ||
169 | $tooltip.bootstrapTooltip('show') | |
170 | assert.ok($('.tooltip').hasClass('some-class'), 'custom class is present') | |
171 | ||
172 | $tooltip.bootstrapTooltip('hide') | |
173 | assert.strictEqual($tooltip.data('bs.tooltip').tip.parentNode, null, 'tooltip removed') | |
174 | }) | |
175 | ||
176 | QUnit.test('should fire show event', function (assert) { | |
177 | assert.expect(1) | |
178 | var done = assert.async() | |
179 | ||
180 | $('<div title="tooltip title"/>') | |
181 | .on('show.bs.tooltip', function () { | |
182 | assert.ok(true, 'show event fired') | |
183 | done() | |
184 | }) | |
185 | .bootstrapTooltip('show') | |
186 | }) | |
187 | ||
188 | QUnit.test('should throw an error when show is called on hidden elements', function (assert) { | |
189 | assert.expect(1) | |
190 | var done = assert.async() | |
191 | ||
192 | try { | |
193 | $('<div title="tooltip title" style="display: none"/>').bootstrapTooltip('show') | |
194 | } | |
195 | catch (err) { | |
196 | assert.strictEqual(err.message, 'Please use show on visible elements') | |
197 | done() | |
198 | } | |
199 | }) | |
200 | ||
201 | QUnit.test('should fire inserted event', function (assert) { | |
202 | assert.expect(2) | |
203 | var done = assert.async() | |
204 | ||
205 | $('<div title="tooltip title"/>') | |
206 | .appendTo('#qunit-fixture') | |
207 | .on('inserted.bs.tooltip', function () { | |
208 | assert.notEqual($('.tooltip').length, 0, 'tooltip was inserted') | |
209 | assert.ok(true, 'inserted event fired') | |
210 | done() | |
211 | }) | |
212 | .bootstrapTooltip('show') | |
213 | }) | |
214 | ||
215 | QUnit.test('should fire shown event', function (assert) { | |
216 | assert.expect(1) | |
217 | var done = assert.async() | |
218 | ||
219 | $('<div title="tooltip title"></div>') | |
220 | .appendTo('#qunit-fixture') | |
221 | .on('shown.bs.tooltip', function () { | |
222 | assert.ok(true, 'shown was called') | |
223 | done() | |
224 | }) | |
225 | .bootstrapTooltip('show') | |
226 | }) | |
227 | ||
228 | QUnit.test('should not fire shown event when show was prevented', function (assert) { | |
229 | assert.expect(1) | |
230 | var done = assert.async() | |
231 | ||
232 | $('<div title="tooltip title"/>') | |
233 | .on('show.bs.tooltip', function (e) { | |
234 | e.preventDefault() | |
235 | assert.ok(true, 'show event fired') | |
236 | done() | |
237 | }) | |
238 | .on('shown.bs.tooltip', function () { | |
239 | assert.ok(false, 'shown event fired') | |
240 | }) | |
241 | .bootstrapTooltip('show') | |
242 | }) | |
243 | ||
244 | QUnit.test('should fire hide event', function (assert) { | |
245 | assert.expect(1) | |
246 | var done = assert.async() | |
247 | ||
248 | $('<div title="tooltip title"/>') | |
249 | .appendTo('#qunit-fixture') | |
250 | .on('shown.bs.tooltip', function () { | |
251 | $(this).bootstrapTooltip('hide') | |
252 | }) | |
253 | .on('hide.bs.tooltip', function () { | |
254 | assert.ok(true, 'hide event fired') | |
255 | done() | |
256 | }) | |
257 | .bootstrapTooltip('show') | |
258 | }) | |
259 | ||
260 | QUnit.test('should fire hidden event', function (assert) { | |
261 | assert.expect(1) | |
262 | var done = assert.async() | |
263 | ||
264 | $('<div title="tooltip title"/>') | |
265 | .appendTo('#qunit-fixture') | |
266 | .on('shown.bs.tooltip', function () { | |
267 | $(this).bootstrapTooltip('hide') | |
268 | }) | |
269 | .on('hidden.bs.tooltip', function () { | |
270 | assert.ok(true, 'hidden event fired') | |
271 | done() | |
272 | }) | |
273 | .bootstrapTooltip('show') | |
274 | }) | |
275 | ||
276 | QUnit.test('should not fire hidden event when hide was prevented', function (assert) { | |
277 | assert.expect(1) | |
278 | var done = assert.async() | |
279 | ||
280 | $('<div title="tooltip title"/>') | |
281 | .appendTo('#qunit-fixture') | |
282 | .on('shown.bs.tooltip', function () { | |
283 | $(this).bootstrapTooltip('hide') | |
284 | }) | |
285 | .on('hide.bs.tooltip', function (e) { | |
286 | e.preventDefault() | |
287 | assert.ok(true, 'hide event fired') | |
288 | done() | |
289 | }) | |
290 | .on('hidden.bs.tooltip', function () { | |
291 | assert.ok(false, 'hidden event fired') | |
292 | }) | |
293 | .bootstrapTooltip('show') | |
294 | }) | |
295 | ||
296 | QUnit.test('should destroy tooltip', function (assert) { | |
297 | assert.expect(7) | |
298 | var $tooltip = $('<div/>') | |
299 | .bootstrapTooltip() | |
300 | .on('click.foo', function () {}) | |
301 | ||
302 | assert.ok($tooltip.data('bs.tooltip'), 'tooltip has data') | |
303 | assert.ok($._data($tooltip[0], 'events').mouseover && $._data($tooltip[0], 'events').mouseout, 'tooltip has hover events') | |
304 | assert.strictEqual($._data($tooltip[0], 'events').click[0].namespace, 'foo', 'tooltip has extra click.foo event') | |
305 | ||
306 | $tooltip.bootstrapTooltip('show') | |
307 | $tooltip.bootstrapTooltip('dispose') | |
308 | ||
309 | assert.ok(!$tooltip.hasClass('show'), 'tooltip is hidden') | |
310 | assert.ok(!$._data($tooltip[0], 'bs.tooltip'), 'tooltip does not have data') | |
311 | assert.strictEqual($._data($tooltip[0], 'events').click[0].namespace, 'foo', 'tooltip still has click.foo') | |
312 | assert.ok(!$._data($tooltip[0], 'events').mouseover && !$._data($tooltip[0], 'events').mouseout, 'tooltip does not have hover events') | |
313 | }) | |
314 | ||
315 | // QUnit.test('should show tooltip with delegate selector on click', function (assert) { | |
316 | // assert.expect(2) | |
317 | // var $div = $('<div><a href="#" rel="tooltip" title="Another tooltip"/></div>') | |
318 | // .appendTo('#qunit-fixture') | |
319 | // .bootstrapTooltip({ | |
320 | // selector: 'a[rel="tooltip"]', | |
321 | // trigger: 'click' | |
322 | // }) | |
323 | ||
324 | // $div.find('a').trigger('click') | |
325 | // assert.ok($('.tooltip').is('.fade.in'), 'tooltip is faded in') | |
326 | ||
327 | // $div.find('a').trigger('click') | |
328 | // assert.strictEqual($div.data('bs.tooltip').tip.parentNode, null, 'tooltip removed') | |
329 | // }) | |
330 | ||
331 | QUnit.test('should show tooltip when toggle is called', function (assert) { | |
332 | assert.expect(1) | |
333 | $('<a href="#" rel="tooltip" title="tooltip on toggle"/>') | |
334 | .appendTo('#qunit-fixture') | |
335 | .bootstrapTooltip({ trigger: 'manual' }) | |
336 | .bootstrapTooltip('toggle') | |
337 | ||
338 | assert.ok($('.tooltip').is('.fade.show'), 'tooltip is faded active') | |
339 | }) | |
340 | ||
341 | QUnit.test('should hide previously shown tooltip when toggle is called on tooltip', function (assert) { | |
342 | assert.expect(1) | |
343 | $('<a href="#" rel="tooltip" title="tooltip on toggle">@ResentedHook</a>') | |
344 | .appendTo('#qunit-fixture') | |
345 | .bootstrapTooltip({ trigger: 'manual' }) | |
346 | .bootstrapTooltip('show') | |
347 | ||
348 | $('.tooltip').bootstrapTooltip('toggle') | |
349 | assert.ok($('.tooltip').not('.fade.show'), 'tooltip was faded out') | |
350 | }) | |
351 | ||
352 | QUnit.test('should place tooltips inside body when container is body', function (assert) { | |
353 | assert.expect(3) | |
354 | var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>') | |
355 | .appendTo('#qunit-fixture') | |
356 | .bootstrapTooltip({ container: 'body' }) | |
357 | .bootstrapTooltip('show') | |
358 | ||
359 | assert.notEqual($('body > .tooltip').length, 0, 'tooltip is direct descendant of body') | |
360 | assert.strictEqual($('#qunit-fixture > .tooltip').length, 0, 'tooltip is not in parent') | |
361 | ||
362 | $tooltip.bootstrapTooltip('hide') | |
363 | assert.strictEqual($('body > .tooltip').length, 0, 'tooltip was removed from dom') | |
364 | }) | |
365 | ||
366 | QUnit.test('should add position class before positioning so that position-specific styles are taken into account', function (assert) { | |
367 | assert.expect(1) | |
368 | var styles = '<style>' | |
369 | + '.tooltip.right { white-space: nowrap; }' | |
370 | + '.tooltip.right .tooltip-inner { max-width: none; }' | |
371 | + '</style>' | |
372 | var $styles = $(styles).appendTo('head') | |
373 | ||
374 | var $container = $('<div/>').appendTo('#qunit-fixture') | |
375 | var $target = $('<a href="#" rel="tooltip" title="very very very very very very very very long tooltip in one line"/>') | |
376 | .appendTo($container) | |
377 | .bootstrapTooltip({ | |
378 | placement: 'right' | |
379 | }) | |
380 | .bootstrapTooltip('show') | |
381 | ||
382 | var $tooltip = $($target.data('bs.tooltip').tip) | |
383 | ||
384 | // this is some dumb hack stuff because sub pixels in firefox | |
385 | var top = Math.round($target.offset().top + $target[0].offsetHeight / 2 - $tooltip[0].offsetHeight / 2) | |
386 | var top2 = Math.round($tooltip.offset().top) | |
387 | var topDiff = top - top2 | |
388 | assert.ok(topDiff <= 1 && topDiff >= -1) | |
389 | $target.bootstrapTooltip('hide') | |
390 | ||
391 | $container.remove() | |
392 | $styles.remove() | |
393 | }) | |
394 | ||
395 | QUnit.test('should use title attribute for tooltip text', function (assert) { | |
396 | assert.expect(2) | |
397 | var $tooltip = $('<a href="#" rel="tooltip" title="Simple tooltip"/>') | |
398 | .appendTo('#qunit-fixture') | |
399 | .bootstrapTooltip() | |
400 | ||
401 | $tooltip.bootstrapTooltip('show') | |
402 | assert.strictEqual($('.tooltip').children('.tooltip-inner').text(), 'Simple tooltip', 'title from title attribute is set') | |
403 | ||
404 | $tooltip.bootstrapTooltip('hide') | |
405 | assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom') | |
406 | }) | |
407 | ||
408 | QUnit.test('should prefer title attribute over title option', function (assert) { | |
409 | assert.expect(2) | |
410 | var $tooltip = $('<a href="#" rel="tooltip" title="Simple tooltip"/>') | |
411 | .appendTo('#qunit-fixture') | |
412 | .bootstrapTooltip({ | |
413 | title: 'This is a tooltip with some content' | |
414 | }) | |
415 | ||
416 | $tooltip.bootstrapTooltip('show') | |
417 | assert.strictEqual($('.tooltip').children('.tooltip-inner').text(), 'Simple tooltip', 'title is set from title attribute while preferred over title option') | |
418 | ||
419 | $tooltip.bootstrapTooltip('hide') | |
420 | assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom') | |
421 | }) | |
422 | ||
423 | QUnit.test('should use title option', function (assert) { | |
424 | assert.expect(2) | |
425 | var $tooltip = $('<a href="#" rel="tooltip"/>') | |
426 | .appendTo('#qunit-fixture') | |
427 | .bootstrapTooltip({ | |
428 | title: 'This is a tooltip with some content' | |
429 | }) | |
430 | ||
431 | $tooltip.bootstrapTooltip('show') | |
432 | assert.strictEqual($('.tooltip').children('.tooltip-inner').text(), 'This is a tooltip with some content', 'title from title option is set') | |
433 | ||
434 | $tooltip.bootstrapTooltip('hide') | |
435 | assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom') | |
436 | }) | |
437 | ||
438 | QUnit.test('should not error when trying to show an top-placed tooltip that has been removed from the dom', function (assert) { | |
439 | assert.expect(1) | |
440 | var passed = true | |
441 | var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>') | |
442 | .appendTo('#qunit-fixture') | |
443 | .one('show.bs.tooltip', function () { | |
444 | $(this).remove() | |
445 | }) | |
446 | .bootstrapTooltip({ placement: 'top' }) | |
447 | ||
448 | try { | |
449 | $tooltip.bootstrapTooltip('show') | |
450 | } catch (err) { | |
451 | passed = false | |
452 | console.log(err) | |
453 | } | |
454 | ||
455 | assert.ok(passed, '.tooltip(\'show\') should not throw an error if element no longer is in dom') | |
456 | }) | |
457 | ||
458 | QUnit.test('should place tooltip on top of element', function (assert) { | |
459 | assert.expect(1) | |
460 | var done = assert.async() | |
461 | ||
462 | var containerHTML = '<div>' | |
463 | + '<p style="margin-top: 200px">' | |
464 | + '<a href="#" title="very very very very very very very long tooltip">Hover me</a>' | |
465 | + '</p>' | |
466 | + '</div>' | |
467 | ||
468 | var $container = $(containerHTML) | |
469 | .css({ | |
470 | position: 'absolute', | |
471 | bottom: 0, | |
472 | left: 0, | |
473 | textAlign: 'right', | |
474 | width: 300, | |
475 | height: 300 | |
476 | }) | |
477 | .appendTo('#qunit-fixture') | |
478 | ||
479 | var $trigger = $container | |
480 | .find('a') | |
481 | .css('margin-top', 200) | |
482 | .bootstrapTooltip({ | |
483 | placement: 'top', | |
484 | animate: false | |
485 | }) | |
486 | .bootstrapTooltip('show') | |
487 | ||
488 | var $tooltip = $($trigger.data('bs.tooltip').tip) | |
489 | ||
490 | setTimeout(function () { | |
491 | assert.ok(Math.round($tooltip.offset().top + $tooltip.outerHeight()) <= Math.round($trigger.offset().top)) | |
492 | done() | |
493 | }, 0) | |
494 | }) | |
495 | ||
496 | QUnit.test('should show tooltip if leave event hasn\'t occurred before delay expires', function (assert) { | |
497 | assert.expect(2) | |
498 | var done = assert.async() | |
499 | ||
500 | var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>') | |
501 | .appendTo('#qunit-fixture') | |
502 | .bootstrapTooltip({ delay: 150 }) | |
503 | ||
504 | setTimeout(function () { | |
505 | assert.ok(!$('.tooltip').is('.fade.show'), '100ms: tooltip is not faded active') | |
506 | }, 100) | |
507 | ||
508 | setTimeout(function () { | |
509 | assert.ok($('.tooltip').is('.fade.show'), '200ms: tooltip is faded active') | |
510 | done() | |
511 | }, 200) | |
512 | ||
513 | $tooltip.trigger('mouseenter') | |
514 | }) | |
515 | ||
516 | QUnit.test('should not show tooltip if leave event occurs before delay expires', function (assert) { | |
517 | assert.expect(2) | |
518 | var done = assert.async() | |
519 | ||
520 | var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>') | |
521 | .appendTo('#qunit-fixture') | |
522 | .bootstrapTooltip({ delay: 150 }) | |
523 | ||
524 | setTimeout(function () { | |
525 | assert.ok(!$('.tooltip').is('.fade.show'), '100ms: tooltip not faded active') | |
526 | $tooltip.trigger('mouseout') | |
527 | }, 100) | |
528 | ||
529 | setTimeout(function () { | |
530 | assert.ok(!$('.tooltip').is('.fade.show'), '200ms: tooltip not faded active') | |
531 | done() | |
532 | }, 200) | |
533 | ||
534 | $tooltip.trigger('mouseenter') | |
535 | }) | |
536 | ||
537 | QUnit.test('should not hide tooltip if leave event occurs and enter event occurs within the hide delay', function (assert) { | |
538 | assert.expect(3) | |
539 | var done = assert.async() | |
540 | ||
541 | var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>') | |
542 | .appendTo('#qunit-fixture') | |
543 | .bootstrapTooltip({ delay: { show: 0, hide: 150 } }) | |
544 | ||
545 | setTimeout(function () { | |
546 | assert.ok($('.tooltip').is('.fade.show'), '1ms: tooltip faded active') | |
547 | $tooltip.trigger('mouseout') | |
548 | ||
549 | setTimeout(function () { | |
550 | assert.ok($('.tooltip').is('.fade.show'), '100ms: tooltip still faded active') | |
551 | $tooltip.trigger('mouseenter') | |
552 | }, 100) | |
553 | ||
554 | setTimeout(function () { | |
555 | assert.ok($('.tooltip').is('.fade.show'), '200ms: tooltip still faded active') | |
556 | done() | |
557 | }, 200) | |
558 | }, 0) | |
559 | ||
560 | $tooltip.trigger('mouseenter') | |
561 | }) | |
562 | ||
563 | QUnit.test('should not show tooltip if leave event occurs before delay expires', function (assert) { | |
564 | assert.expect(2) | |
565 | var done = assert.async() | |
566 | ||
567 | var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>') | |
568 | .appendTo('#qunit-fixture') | |
569 | .bootstrapTooltip({ delay: 150 }) | |
570 | ||
571 | setTimeout(function () { | |
572 | assert.ok(!$('.tooltip').is('.fade.show'), '100ms: tooltip not faded active') | |
573 | $tooltip.trigger('mouseout') | |
574 | }, 100) | |
575 | ||
576 | setTimeout(function () { | |
577 | assert.ok(!$('.tooltip').is('.fade.show'), '200ms: tooltip not faded active') | |
578 | done() | |
579 | }, 200) | |
580 | ||
581 | $tooltip.trigger('mouseenter') | |
582 | }) | |
583 | ||
584 | QUnit.test('should not show tooltip if leave event occurs before delay expires, even if hide delay is 0', function (assert) { | |
585 | assert.expect(2) | |
586 | var done = assert.async() | |
587 | ||
588 | var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>') | |
589 | .appendTo('#qunit-fixture') | |
590 | .bootstrapTooltip({ delay: { show: 150, hide: 0 } }) | |
591 | ||
592 | setTimeout(function () { | |
593 | assert.ok(!$('.tooltip').is('.fade.show'), '100ms: tooltip not faded active') | |
594 | $tooltip.trigger('mouseout') | |
595 | }, 100) | |
596 | ||
597 | setTimeout(function () { | |
598 | assert.ok(!$('.tooltip').is('.fade.show'), '250ms: tooltip not faded active') | |
599 | done() | |
600 | }, 250) | |
601 | ||
602 | $tooltip.trigger('mouseenter') | |
603 | }) | |
604 | ||
605 | QUnit.test('should wait 200ms before hiding the tooltip', function (assert) { | |
606 | assert.expect(3) | |
607 | var done = assert.async() | |
608 | ||
609 | var $tooltip = $('<a href="#" rel="tooltip" title="Another tooltip"/>') | |
610 | .appendTo('#qunit-fixture') | |
611 | .bootstrapTooltip({ delay: { show: 0, hide: 150 } }) | |
612 | ||
613 | setTimeout(function () { | |
614 | assert.ok($($tooltip.data('bs.tooltip').tip).is('.fade.show'), '1ms: tooltip faded active') | |
615 | ||
616 | $tooltip.trigger('mouseout') | |
617 | ||
618 | setTimeout(function () { | |
619 | assert.ok($($tooltip.data('bs.tooltip').tip).is('.fade.show'), '100ms: tooltip still faded active') | |
620 | }, 100) | |
621 | ||
622 | setTimeout(function () { | |
623 | assert.ok(!$($tooltip.data('bs.tooltip').tip).is('.show'), '200ms: tooltip removed') | |
624 | done() | |
625 | }, 200) | |
626 | ||
627 | }, 0) | |
628 | ||
629 | $tooltip.trigger('mouseenter') | |
630 | }) | |
631 | ||
632 | QUnit.test('should correctly position tooltips on SVG elements', function (assert) { | |
633 | if (!window.SVGElement) { | |
634 | // Skip IE8 since it doesn't support SVG | |
635 | assert.expect(0) | |
636 | return | |
637 | } | |
638 | assert.expect(2) | |
639 | ||
640 | var done = assert.async() | |
641 | ||
642 | var styles = '<style>' | |
643 | + '.tooltip, .tooltip *, .tooltip *:before, .tooltip *:after { box-sizing: border-box; }' | |
644 | + '.tooltip { position: absolute; }' | |
645 | + '.tooltip .tooltip-inner { width: 24px; height: 24px; font-family: Helvetica; }' | |
646 | + '</style>' | |
647 | var $styles = $(styles).appendTo('head') | |
648 | ||
649 | $('#qunit-fixture').append( | |
650 | '<div style="position: fixed; top: 0; left: 0;">' | |
651 | + ' <svg width="200" height="200">' | |
652 | + ' <circle cx="100" cy="100" r="10" title="m" id="theCircle" />' | |
653 | + ' </svg>' | |
654 | + '</div>') | |
655 | var $circle = $('#theCircle') | |
656 | ||
657 | $circle | |
658 | .on('shown.bs.tooltip', function () { | |
659 | var offset = $('.tooltip').offset() | |
660 | $styles.remove() | |
661 | assert.ok(Math.abs(offset.left - 88) <= 1, 'tooltip has correct horizontal location') | |
662 | $circle.bootstrapTooltip('hide') | |
663 | assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom') | |
664 | done() | |
665 | }) | |
666 | .bootstrapTooltip({ placement: 'top', trigger: 'manual' }) | |
667 | ||
668 | $circle.bootstrapTooltip('show') | |
669 | }) | |
670 | ||
671 | QUnit.test('should not reload the tooltip on subsequent mouseenter events', function (assert) { | |
672 | assert.expect(1) | |
673 | var titleHtml = function () { | |
674 | var uid = Util.getUID('tooltip') | |
675 | return '<p id="tt-content">' + uid + '</p><p>' + uid + '</p><p>' + uid + '</p>' | |
676 | } | |
677 | ||
678 | var $tooltip = $('<span id="tt-outer" rel="tooltip" data-trigger="hover" data-placement="top">some text</span>') | |
679 | .appendTo('#qunit-fixture') | |
680 | ||
681 | $tooltip.bootstrapTooltip({ | |
682 | html: true, | |
683 | animation: false, | |
684 | trigger: 'hover', | |
685 | delay: { show: 0, hide: 500 }, | |
686 | container: $tooltip, | |
687 | title: titleHtml | |
688 | }) | |
689 | ||
690 | $('#tt-outer').trigger('mouseenter') | |
691 | ||
692 | var currentUid = $('#tt-content').text() | |
693 | ||
694 | $('#tt-content').trigger('mouseenter') | |
695 | assert.strictEqual(currentUid, $('#tt-content').text()) | |
696 | }) | |
697 | ||
698 | QUnit.test('should not reload the tooltip if the mouse leaves and re-enters before hiding', function (assert) { | |
699 | assert.expect(4) | |
700 | ||
701 | var titleHtml = function () { | |
702 | var uid = Util.getUID('tooltip') | |
703 | return '<p id="tt-content">' + uid + '</p><p>' + uid + '</p><p>' + uid + '</p>' | |
704 | } | |
705 | ||
706 | var $tooltip = $('<span id="tt-outer" rel="tooltip" data-trigger="hover" data-placement="top">some text</span>') | |
707 | .appendTo('#qunit-fixture') | |
708 | ||
709 | $tooltip.bootstrapTooltip({ | |
710 | html: true, | |
711 | animation: false, | |
712 | trigger: 'hover', | |
713 | delay: { show: 0, hide: 500 }, | |
714 | title: titleHtml | |
715 | }) | |
716 | ||
717 | var obj = $tooltip.data('bs.tooltip') | |
718 | ||
719 | $('#tt-outer').trigger('mouseenter') | |
720 | ||
721 | var currentUid = $('#tt-content').text() | |
722 | ||
723 | $('#tt-outer').trigger('mouseleave') | |
724 | assert.strictEqual(currentUid, $('#tt-content').text()) | |
725 | ||
726 | assert.ok(obj._hoverState === 'out', 'the tooltip hoverState should be set to "out"') | |
727 | ||
728 | $('#tt-outer').trigger('mouseenter') | |
729 | assert.ok(obj._hoverState === 'show', 'the tooltip hoverState should be set to "show"') | |
730 | ||
731 | assert.strictEqual(currentUid, $('#tt-content').text()) | |
732 | }) | |
733 | ||
734 | QUnit.test('should correctly position tooltips on transformed elements', function (assert) { | |
735 | var styleProps = document.documentElement.style | |
736 | if (!('transform' in styleProps) && !('webkitTransform' in styleProps) && !('msTransform' in styleProps)) { | |
737 | assert.expect(0) | |
738 | return | |
739 | } | |
740 | assert.expect(2) | |
741 | ||
742 | var done = assert.async() | |
743 | ||
744 | var styles = '<style>' | |
745 | + '#qunit-fixture { top: 0; left: 0; }' | |
746 | + '.tooltip, .tooltip *, .tooltip *:before, .tooltip *:after { box-sizing: border-box; }' | |
747 | + '.tooltip { position: absolute; }' | |
748 | + '.tooltip .tooltip-inner { width: 24px; height: 24px; font-family: Helvetica; }' | |
749 | + '#target { position: absolute; top: 100px; left: 50px; width: 100px; height: 200px; -webkit-transform: rotate(270deg); -ms-transform: rotate(270deg); transform: rotate(270deg); }' | |
750 | + '</style>' | |
751 | var $styles = $(styles).appendTo('head') | |
752 | ||
753 | var $element = $('<div id="target" title="1"/>').appendTo('#qunit-fixture') | |
754 | ||
755 | $element | |
756 | .on('shown.bs.tooltip', function () { | |
757 | var offset = $('.tooltip').offset() | |
758 | $styles.remove() | |
759 | assert.ok(Math.abs(offset.left - 88) <= 1, 'tooltip has correct horizontal location') | |
760 | assert.ok(Math.abs(offset.top - 126) <= 1, 'tooltip has correct vertical location') | |
761 | $element.bootstrapTooltip('hide') | |
762 | done() | |
763 | }) | |
764 | .bootstrapTooltip({ | |
765 | trigger: 'manual' | |
766 | }) | |
767 | ||
768 | $element.bootstrapTooltip('show') | |
769 | }) | |
770 | ||
771 | QUnit.test('should do nothing when an attempt is made to hide an uninitialized tooltip', function (assert) { | |
772 | assert.expect(1) | |
773 | ||
774 | var $tooltip = $('<span data-toggle="tooltip" title="some tip">some text</span>') | |
775 | .appendTo('#qunit-fixture') | |
776 | .on('hidden.bs.tooltip shown.bs.tooltip', function () { | |
777 | assert.ok(false, 'should not fire any tooltip events') | |
778 | }) | |
779 | .bootstrapTooltip('hide') | |
780 | assert.strictEqual($tooltip.data('bs.tooltip'), undefined, 'should not initialize the tooltip') | |
781 | }) | |
782 | ||
783 | QUnit.test('should not remove tooltip if multiple triggers are set and one is still active', function (assert) { | |
784 | assert.expect(41) | |
785 | var $el = $('<button>Trigger</button>') | |
786 | .appendTo('#qunit-fixture') | |
787 | .bootstrapTooltip({ trigger: 'click hover focus', animation: false }) | |
788 | var tooltip = $el.data('bs.tooltip') | |
789 | var $tooltip = $(tooltip.getTipElement()) | |
790 | ||
791 | function showingTooltip() { return $tooltip.hasClass('show') || tooltip._hoverState === 'show' } | |
792 | ||
793 | var tests = [ | |
794 | ['mouseenter', 'mouseleave'], | |
795 | ||
796 | ['focusin', 'focusout'], | |
797 | ||
798 | ['click', 'click'], | |
799 | ||
800 | ['mouseenter', 'focusin', 'focusout', 'mouseleave'], | |
801 | ['mouseenter', 'focusin', 'mouseleave', 'focusout'], | |
802 | ||
803 | ['focusin', 'mouseenter', 'mouseleave', 'focusout'], | |
804 | ['focusin', 'mouseenter', 'focusout', 'mouseleave'], | |
805 | ||
806 | ['click', 'focusin', 'mouseenter', 'focusout', 'mouseleave', 'click'], | |
807 | ['mouseenter', 'click', 'focusin', 'focusout', 'mouseleave', 'click'], | |
808 | ['mouseenter', 'focusin', 'click', 'click', 'mouseleave', 'focusout'] | |
809 | ] | |
810 | ||
811 | assert.ok(!showingTooltip()) | |
812 | ||
813 | $.each(tests, function (idx, triggers) { | |
814 | for (var i = 0, len = triggers.length; i < len; i++) { | |
815 | $el.trigger(triggers[i]) | |
816 | assert.equal(i < len - 1, showingTooltip()) | |
817 | } | |
818 | }) | |
819 | }) | |
820 | ||
821 | QUnit.test('should show on first trigger after hide', function (assert) { | |
822 | assert.expect(3) | |
823 | var $el = $('<a href="#" rel="tooltip" title="Test tooltip"/>') | |
824 | .appendTo('#qunit-fixture') | |
825 | .bootstrapTooltip({ trigger: 'click hover focus', animation: false }) | |
826 | ||
827 | var tooltip = $el.data('bs.tooltip') | |
828 | var $tooltip = $(tooltip.getTipElement()) | |
829 | ||
830 | function showingTooltip() { return $tooltip.hasClass('show') || tooltip._hoverState === 'show' } | |
831 | ||
832 | $el.trigger('click') | |
833 | assert.ok(showingTooltip(), 'tooltip is faded in') | |
834 | ||
835 | $el.bootstrapTooltip('hide') | |
836 | assert.ok(!showingTooltip(), 'tooltip was faded out') | |
837 | ||
838 | $el.trigger('click') | |
839 | assert.ok(showingTooltip(), 'tooltip is faded in again') | |
840 | }) | |
841 | ||
842 | QUnit.test('should hide tooltip when their containing modal is closed', function (assert) { | |
843 | assert.expect(1) | |
844 | var done = assert.async() | |
845 | var templateHTML = '<div id="modal-test" class="modal">' + | |
846 | '<div class="modal-dialog" role="document">' + | |
847 | '<div class="modal-content">' + | |
848 | '<div class="modal-body">' + | |
849 | '<a id="tooltipTest" href="#" data-toggle="tooltip" title="Some tooltip text!">Tooltip</a>' + | |
850 | '</div>' + | |
851 | '</div>' + | |
852 | '</div>' + | |
853 | '</div>' | |
854 | ||
855 | $(templateHTML).appendTo('#qunit-fixture') | |
856 | $('#tooltipTest') | |
857 | .bootstrapTooltip({ trigger: 'manuel' }) | |
858 | .on('shown.bs.tooltip', function () { | |
859 | $('#modal-test').modal('hide') | |
860 | }) | |
861 | .on('hide.bs.tooltip', function () { | |
862 | assert.ok(true, 'tooltip hide') | |
863 | done() | |
864 | }) | |
865 | ||
866 | $('#modal-test') | |
867 | .on('shown.bs.modal', function () { | |
868 | $('#tooltipTest').bootstrapTooltip('show') | |
869 | }) | |
870 | .modal('show') | |
871 | }) | |
872 | }) |