Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merge branch 'master' into selectmenu

  • Loading branch information...
commit b4d9eee966f1dec06f0772e38bba9e5c864374f9 2 parents 8c10c1e + 63215a6
Scott González scottgonzalez authored

Showing 95 changed files with 2,121 additions and 1,889 deletions. Show diff stats Hide diff stats

  1. +4 4 demos/accordion/collapsible.html
  2. +4 4 demos/accordion/custom-icons.html
  3. +4 4 demos/accordion/default.html
  4. +4 4 demos/accordion/fillspace.html
  5. +4 4 demos/accordion/hoverintent.html
  6. +0 1  demos/accordion/index.html
  7. +0 57 demos/accordion/mouseover.html
  8. +3 4 demos/accordion/no-auto-height.html
  9. +4 4 demos/accordion/sortable.html
  10. +15 12 demos/position/cycler.html
  11. +9 2 external/qunit.css
  12. +462 282 external/qunit.js
  13. +121 119 tests/jquery.simulate.js
  14. +6 6 tests/unit/accordion/accordion.html
  15. +0 7 tests/unit/accordion/accordion_core.js
  16. +6 6 tests/unit/accordion/accordion_deprecated.html
  17. +6 6 tests/unit/accordion/accordion_events.js
  18. +12 12 tests/unit/button/button_core.js
  19. +19 19 tests/unit/button/button_options.js
  20. +35 35 tests/unit/core/core.js
  21. +35 35 tests/unit/datepicker/datepicker_core.js
  22. +25 25 tests/unit/datepicker/datepicker_events.js
  23. +155 155 tests/unit/datepicker/datepicker_options.js
  24. +8 8 tests/unit/datepicker/datepicker_tickets.js
  25. +9 9 tests/unit/dialog/dialog_core.js
  26. +42 42 tests/unit/dialog/dialog_events.js
  27. +15 15 tests/unit/dialog/dialog_methods.js
  28. +77 77 tests/unit/dialog/dialog_options.js
  29. +8 8 tests/unit/dialog/dialog_tickets.js
  30. +1 1  tests/unit/draggable/draggable_core.js
  31. +9 9 tests/unit/draggable/draggable_events.js
  32. +9 9 tests/unit/draggable/draggable_methods.js
  33. +74 74 tests/unit/draggable/draggable_options.js
  34. +10 10 tests/unit/droppable/droppable_methods.js
  35. +2 2 tests/unit/droppable/droppable_options.js
  36. +6 6 tests/unit/menu/menu_core.js
  37. +4 1 tests/unit/menu/menu_defaults.js
  38. +58 58 tests/unit/menu/menu_events.js
  39. +4 4 tests/unit/menu/menu_methods.js
  40. +2 2 tests/unit/menu/menu_options.js
  41. +35 35 tests/unit/position/position_core.js
  42. +28 28 tests/unit/position/position_core_within.js
  43. +3 3 tests/unit/position/position_deprecated.js
  44. +7 7 tests/unit/progressbar/progressbar_core.js
  45. +5 5 tests/unit/progressbar/progressbar_events.js
  46. +5 5 tests/unit/progressbar/progressbar_methods.js
  47. +5 5 tests/unit/progressbar/progressbar_options.js
  48. +25 25 tests/unit/resizable/resizable_core.js
  49. +3 3 tests/unit/resizable/resizable_methods.js
  50. +52 52 tests/unit/resizable/resizable_options.js
  51. +2 2 tests/unit/selectable/selectable_events.js
  52. +9 9 tests/unit/selectable/selectable_methods.js
  53. +4 4 tests/unit/selectable/selectable_options.js
  54. +34 34 tests/unit/slider/slider_core.js
  55. +11 11 tests/unit/slider/slider_events.js
  56. +14 14 tests/unit/slider/slider_methods.js
  57. +13 13 tests/unit/slider/slider_options.js
  58. +9 9 tests/unit/sortable/sortable_methods.js
  59. +2 2 tests/unit/sortable/sortable_tickets.js
  60. +29 29 tests/unit/spinner/spinner_methods.js
  61. +18 18 tests/unit/spinner/spinner_options.js
  62. +3 3 tests/unit/tabs/tabs.html
  63. +4 4 tests/unit/tabs/tabs_core.js
  64. +3 3 tests/unit/tabs/tabs_deprecated.html
  65. +63 63 tests/unit/tabs/tabs_deprecated.js
  66. +59 59 tests/unit/tabs/tabs_events.js
  67. +14 14 tests/unit/tabs/tabs_methods.js
  68. +11 11 tests/unit/tabs/tabs_options.js
  69. +4 4 tests/unit/testsuite.js
  70. +7 7 tests/unit/tooltip/tooltip_events.js
  71. +2 2 tests/unit/tooltip/tooltip_methods.js
  72. +7 7 tests/unit/tooltip/tooltip_options.js
  73. +102 102 tests/unit/widget/widget_core.js
  74. +95 0 tests/visual/accordion/accordion.html
  75. +22 15 tests/visual/tooltip/tooltip.html
  76. +4 7 themes/base/jquery.ui.accordion.css
  77. +15 15 ui/i18n/jquery.ui.datepicker-bg.js
  78. +1 1  ui/i18n/jquery.ui.datepicker-cs.js
  79. +8 8 ui/i18n/jquery.ui.datepicker-da.js
  80. +1 1  ui/i18n/jquery.ui.datepicker-et.js
  81. +7 7 ui/i18n/jquery.ui.datepicker-fi.js
  82. +2 2 ui/i18n/jquery.ui.datepicker-fr.js
  83. +18 18 ui/i18n/jquery.ui.datepicker-no.js
  84. +8 8 ui/i18n/jquery.ui.datepicker-sv.js
  85. +1 1  ui/jquery.effects.blind.js
  86. +12 13 ui/jquery.ui.accordion.js
  87. +1 1  ui/jquery.ui.core.js
  88. +10 10 ui/jquery.ui.datepicker.js
  89. +13 13 ui/jquery.ui.draggable.js
  90. +6 1 ui/jquery.ui.menu.js
  91. +2 2 ui/jquery.ui.mouse.js
  92. +28 28 ui/jquery.ui.resizable.js
  93. +1 1  ui/jquery.ui.sortable.js
  94. +1 1  ui/jquery.ui.tabs.js
  95. +2 2 ui/jquery.ui.tooltip.js
8 demos/accordion/collapsible.html
@@ -22,15 +22,15 @@
22 22 <div class="demo">
23 23
24 24 <div id="accordion">
25   - <h3><a href="#">Section 1</a></h3>
  25 + <h3>Section 1</h3>
26 26 <div>
27 27 <p>Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.</p>
28 28 </div>
29   - <h3><a href="#">Section 2</a></h3>
  29 + <h3>Section 2</h3>
30 30 <div>
31 31 <p>Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In suscipit faucibus urna. </p>
32 32 </div>
33   - <h3><a href="#">Section 3</a></h3>
  33 + <h3>Section 3</h3>
34 34 <div>
35 35 <p>Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis. Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui. </p>
36 36 <ul>
@@ -39,7 +39,7 @@
39 39 <li>List item three</li>
40 40 </ul>
41 41 </div>
42   - <h3><a href="#">Section 4</a></h3>
  42 + <h3>Section 4</h3>
43 43 <div>
44 44 <p>Cras dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia mauris vel est. </p><p>Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. </p>
45 45 </div>
8 demos/accordion/custom-icons.html
@@ -32,15 +32,15 @@
32 32 <div class="demo">
33 33
34 34 <div id="accordion">
35   - <h3><a href="#">Section 1</a></h3>
  35 + <h3>Section 1</h3>
36 36 <div>
37 37 <p>Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.</p>
38 38 </div>
39   - <h3><a href="#">Section 2</a></h3>
  39 + <h3>Section 2</h3>
40 40 <div>
41 41 <p>Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In suscipit faucibus urna. </p>
42 42 </div>
43   - <h3><a href="#">Section 3</a></h3>
  43 + <h3>Section 3</h3>
44 44 <div>
45 45 <p>Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis. Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui. </p>
46 46 <ul>
@@ -49,7 +49,7 @@
49 49 <li>List item three</li>
50 50 </ul>
51 51 </div>
52   - <h3><a href="#">Section 4</a></h3>
  52 + <h3>Section 4</h3>
53 53 <div>
54 54 <p>Cras dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia mauris vel est. </p><p>Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. </p>
55 55 </div>
8 demos/accordion/default.html
@@ -20,7 +20,7 @@
20 20 <div class="demo">
21 21
22 22 <div id="accordion">
23   - <h3><a href="#">Section 1</a></h3>
  23 + <h3>Section 1</h3>
24 24 <div>
25 25 <p>
26 26 Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer
@@ -29,7 +29,7 @@
29 29 odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.
30 30 </p>
31 31 </div>
32   - <h3><a href="#">Section 2</a></h3>
  32 + <h3>Section 2</h3>
33 33 <div>
34 34 <p>
35 35 Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet
@@ -38,7 +38,7 @@
38 38 suscipit faucibus urna.
39 39 </p>
40 40 </div>
41   - <h3><a href="#">Section 3</a></h3>
  41 + <h3>Section 3</h3>
42 42 <div>
43 43 <p>
44 44 Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis.
@@ -52,7 +52,7 @@
52 52 <li>List item three</li>
53 53 </ul>
54 54 </div>
55   - <h3><a href="#">Section 4</a></h3>
  55 + <h3>Section 4</h3>
56 56 <div>
57 57 <p>
58 58 Cras dictum. Pellentesque habitant morbi tristique senectus et netus
8 demos/accordion/fillspace.html
@@ -37,15 +37,15 @@ <h3 class="docs">Resize the outer container:</h3>
37 37 <div id="accordionResizer" style="padding:10px; width:350px; height:220px;" class="ui-widget-content">
38 38
39 39 <div id="accordion">
40   - <h3><a href="#">Section 1</a></h3>
  40 + <h3>Section 1</h3>
41 41 <div>
42 42 <p>Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.</p>
43 43 </div>
44   - <h3><a href="#">Section 2</a></h3>
  44 + <h3>Section 2</h3>
45 45 <div>
46 46 <p>Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In suscipit faucibus urna. </p>
47 47 </div>
48   - <h3><a href="#">Section 3</a></h3>
  48 + <h3>Section 3</h3>
49 49 <div>
50 50 <p>Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis. Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui. </p>
51 51 <ul>
@@ -54,7 +54,7 @@ <h3 class="docs">Resize the outer container:</h3>
54 54 <li>List item three</li>
55 55 </ul>
56 56 </div>
57   - <h3><a href="#">Section 4</a></h3>
  57 + <h3>Section 4</h3>
58 58 <div>
59 59 <p>Cras dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia mauris vel est. </p><p>Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. </p>
60 60 </div>
8 demos/accordion/hoverintent.html
@@ -73,7 +73,7 @@
73 73 <div class="demo">
74 74
75 75 <div id="accordion">
76   - <h3><a href="#">Section 1</a></h3>
  76 + <h3>Section 1</h3>
77 77 <div>
78 78 <p>
79 79 Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer
@@ -82,7 +82,7 @@
82 82 odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.
83 83 </p>
84 84 </div>
85   - <h3><a href="#">Section 2</a></h3>
  85 + <h3>Section 2</h3>
86 86 <div>
87 87 <p>
88 88 Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet
@@ -91,7 +91,7 @@
91 91 suscipit faucibus urna.
92 92 </p>
93 93 </div>
94   - <h3><a href="#">Section 3</a></h3>
  94 + <h3>Section 3</h3>
95 95 <div>
96 96 <p>
97 97 Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis.
@@ -105,7 +105,7 @@
105 105 <li>List item three</li>
106 106 </ul>
107 107 </div>
108   - <h3><a href="#">Section 4</a></h3>
  108 + <h3>Section 4</h3>
109 109 <div>
110 110 <p>
111 111 Cras dictum. Pellentesque habitant morbi tristique senectus et netus
1  demos/accordion/index.html
@@ -14,7 +14,6 @@
14 14 <li><a href="fillspace.html">Fill space</a></li>
15 15 <li><a href="no-auto-height.html">No auto height</a></li>
16 16 <li><a href="collapsible.html">Collapse content</a></li>
17   - <li><a href="mouseover.html">Open on mouseover</a></li>
18 17 <li><a href="hoverintent.html">Open on hoverintent</a></li>
19 18 <li><a href="custom-icons.html">Customize icons</a></li>
20 19 <li><a href="sortable.html">Sortable</a></li>
57 demos/accordion/mouseover.html
... ... @@ -1,57 +0,0 @@
1   -<!DOCTYPE html>
2   -<html lang="en">
3   -<head>
4   - <meta charset="utf-8">
5   - <title>jQuery UI Accordion - Open on mouseover</title>
6   - <link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">
7   - <script src="../../jquery-1.7.1.js"></script>
8   - <script src="../../ui/jquery.ui.core.js"></script>
9   - <script src="../../ui/jquery.ui.widget.js"></script>
10   - <script src="../../ui/jquery.ui.accordion.js"></script>
11   - <link rel="stylesheet" href="../demos.css">
12   - <script>
13   - $(function() {
14   - $( "#accordion" ).accordion({
15   - event: "mouseover"
16   - });
17   - });
18   - </script>
19   -</head>
20   -<body>
21   -
22   -<div class="demo">
23   -
24   -<div id="accordion">
25   - <h3><a href="#">Section 1</a></h3>
26   - <div>
27   - <p>Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.</p>
28   - </div>
29   - <h3><a href="#">Section 2</a></h3>
30   - <div>
31   - <p>Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In suscipit faucibus urna. </p>
32   - </div>
33   - <h3><a href="#">Section 3</a></h3>
34   - <div>
35   - <p>Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis. Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui. </p>
36   - <ul>
37   - <li>List item one</li>
38   - <li>List item two</li>
39   - <li>List item three</li>
40   - </ul>
41   - </div>
42   - <h3><a href="#">Section 4</a></h3>
43   - <div>
44   - <p>Cras dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia mauris vel est. </p><p>Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. </p>
45   - </div>
46   -</div>
47   -
48   -</div><!-- End demo -->
49   -
50   -
51   -
52   -<div class="demo-description">
53   -<p>Toggle sections open/closed on mouseover with the <code>event</code> option. The default value for event is "click."</p>
54   -</div><!-- End demo-description -->
55   -
56   -</body>
57   -</html>
7 demos/accordion/no-auto-height.html
@@ -22,15 +22,15 @@
22 22 <div class="demo">
23 23
24 24 <div id="accordion">
25   - <h3><a href="#section1">Section 1</a></h3>
  25 + <h3>Section 1</h3>
26 26 <div>
27 27 <p>Mauris mauris ante, blandit et, ultrices a, susceros. Nam mi. Proin viverra leo ut odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.</p>
28 28 </div>
29   - <h3><a href="#section2">Section 2</a></h3>
  29 + <h3>Section 2</h3>
30 30 <div>
31 31 <p>Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In suscipit faucibus urna. </p>
32 32 </div>
33   - <h3><a href="#section3">Section 3</a></h3>
  33 + <h3>Section 3</h3>
34 34 <div>
35 35 <p>Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis. Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui. </p>
36 36 <ul>
@@ -42,7 +42,6 @@
42 42 <li>List item</li>
43 43 <li>List item</li>
44 44 </ul>
45   - <a href="#othercontent">Link to other content</a>
46 45 </div>
47 46 </div>
48 47
8 demos/accordion/sortable.html
@@ -39,19 +39,19 @@
39 39
40 40 <div id="accordion">
41 41 <div class="group">
42   - <h3><a href="#">Section 1</a></h3>
  42 + <h3>Section 1</h3>
43 43 <div>
44 44 <p>Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.</p>
45 45 </div>
46 46 </div>
47 47 <div class="group">
48   - <h3><a href="#">Section 2</a></h3>
  48 + <h3>Section 2</h3>
49 49 <div>
50 50 <p>Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In suscipit faucibus urna. </p>
51 51 </div>
52 52 </div>
53 53 <div class="group">
54   - <h3><a href="#">Section 3</a></h3>
  54 + <h3>Section 3</h3>
55 55 <div>
56 56 <p>Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis. Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui. </p>
57 57 <ul>
@@ -62,7 +62,7 @@
62 62 </div>
63 63 </div>
64 64 <div class="group">
65   - <h3><a href="#">Section 4</a></h3>
  65 + <h3>Section 4</h3>
66 66 <div>
67 67 <p>Cras dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia mauris vel est. </p><p>Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. </p>
68 68 </div>
27 demos/position/cycler.html
@@ -17,6 +17,7 @@
17 17 </style>
18 18 <script>
19 19 $(function() {
  20 + // TODO refactor into a widget and get rid of these plugin methods
20 21 $.fn.position2 = function( options ) {
21 22 return this.position( $.extend({
22 23 of: window,
@@ -52,10 +53,6 @@
52 53 });
53 54 };
54 55
55   - $( "img:eq(0)" ).left();
56   - $( "img:eq(1)" ).center();
57   - $( "img:eq(2)" ).right();
58   -
59 56 $( "body" ).css({
60 57 overflow: "hidden"
61 58 })
@@ -66,15 +63,21 @@
66 63 position: "absolute",
67 64 });
68 65
  66 + $( "img:eq(0)" ).left();
  67 + $( "img:eq(1)" ).center();
  68 + $( "img:eq(2)" ).right();
  69 +
69 70 function animate( to ) {
70   - $(this).animate( to );
  71 + $(this).stop( true, false ).animate( to );
71 72 }
72   - function next() {
  73 + function next( event ) {
  74 + event.preventDefault();
73 75 $( "img:eq(2)" ).center( animate );
74 76 $( "img:eq(1)" ).left( animate )
75 77 $( "img:eq(0)" ).right().appendTo( ".demo" );
76 78 }
77   - function previous() {
  79 + function previous( event ) {
  80 + event.preventDefault();
78 81 $( "img:eq(0)" ).center( animate );
79 82 $( "img:eq(1)" ).right( animate );
80 83 $( "img:eq(2)" ).left().prependTo( ".demo" );
@@ -82,8 +85,8 @@
82 85 $( "#previous" ).click( previous );
83 86 $( "#next" ).click( next );
84 87
85   - $( ".demo img" ).click(function() {
86   - $( ".demo img" ).index( this ) === 0 ? previous() : next();
  88 + $( ".demo img" ).click(function( event ) {
  89 + $( ".demo img" ).index( this ) === 0 ? previous( event ) : next( event );
87 90 });
88 91
89 92 $( window ).resize(function() {
@@ -98,9 +101,9 @@
98 101
99 102 <div class="demo">
100 103
101   -<img src="images/earth.jpg" />
102   -<img src="images/flight.jpg" />
103   -<img src="images/rocket.jpg" />
  104 +<img src="images/earth.jpg" width="458" height="308" />
  105 +<img src="images/flight.jpg" width="512" height="307" />
  106 +<img src="images/rocket.jpg" width="300" height="353" />
104 107
105 108 <a id="previous" href="#">Previous</a>
106 109 <a id="next" href="#">Next</a>
11 external/qunit.css
... ... @@ -1,9 +1,9 @@
1 1 /**
2   - * QUnit - A JavaScript Unit Testing Framework
  2 + * QUnit v1.4.0pre - A JavaScript Unit Testing Framework
3 3 *
4 4 * http://docs.jquery.com/QUnit
5 5 *
6   - * Copyright (c) 2011 John Resig, Jörn Zaefferer
  6 + * Copyright (c) 2012 John Resig, Jörn Zaefferer
7 7 * Dual licensed under the MIT (MIT-LICENSE.txt)
8 8 * or GPL (GPL-LICENSE.txt) licenses.
9 9 */
@@ -54,6 +54,10 @@
54 54 color: #fff;
55 55 }
56 56
  57 +#qunit-header label {
  58 + display: inline-block;
  59 +}
  60 +
57 61 #qunit-banner {
58 62 height: 5px;
59 63 }
@@ -186,6 +190,7 @@
186 190 color: #710909;
187 191 background-color: #fff;
188 192 border-left: 26px solid #EE5757;
  193 + white-space: pre;
189 194 }
190 195
191 196 #qunit-tests > li:last-child {
@@ -222,4 +227,6 @@
222 227 position: absolute;
223 228 top: -10000px;
224 229 left: -10000px;
  230 + width: 1000px;
  231 + height: 1000px;
225 232 }
744 external/qunit.js
... ... @@ -1,9 +1,9 @@
1 1 /**
2   - * QUnit - A JavaScript Unit Testing Framework
  2 + * QUnit v1.4.0pre - A JavaScript Unit Testing Framework
3 3 *
4 4 * http://docs.jquery.com/QUnit
5 5 *
6   - * Copyright (c) 2011 John Resig, Jörn Zaefferer
  6 + * Copyright (c) 2012 John Resig, Jörn Zaefferer
7 7 * Dual licensed under the MIT (MIT-LICENSE.txt)
8 8 * or GPL (GPL-LICENSE.txt) licenses.
9 9 */
@@ -13,21 +13,25 @@
13 13 var defined = {
14 14 setTimeout: typeof window.setTimeout !== "undefined",
15 15 sessionStorage: (function() {
  16 + var x = "qunit-test-string";
16 17 try {
17   - return !!sessionStorage.getItem;
18   - } catch(e){
  18 + sessionStorage.setItem(x, x);
  19 + sessionStorage.removeItem(x);
  20 + return true;
  21 + } catch(e) {
19 22 return false;
20 23 }
21   - })()
  24 + })()
22 25 };
23 26
24   -var testId = 0;
  27 +var testId = 0,
  28 + toString = Object.prototype.toString,
  29 + hasOwn = Object.prototype.hasOwnProperty;
25 30
26   -var Test = function(name, testName, expected, testEnvironmentArg, async, callback) {
  31 +var Test = function(name, testName, expected, async, callback) {
27 32 this.name = name;
28 33 this.testName = testName;
29 34 this.expected = expected;
30   - this.testEnvironmentArg = testEnvironmentArg;
31 35 this.async = async;
32 36 this.callback = callback;
33 37 this.assertions = [];
@@ -48,7 +52,7 @@ Test.prototype = {
48 52 setup: function() {
49 53 if (this.module != config.previousModule) {
50 54 if ( config.previousModule ) {
51   - QUnit.moduleDone( {
  55 + runLoggingCallbacks('moduleDone', QUnit, {
52 56 name: config.previousModule,
53 57 failed: config.moduleStats.bad,
54 58 passed: config.moduleStats.all - config.moduleStats.bad,
@@ -57,7 +61,11 @@ Test.prototype = {
57 61 }
58 62 config.previousModule = this.module;
59 63 config.moduleStats = { all: 0, bad: 0 };
60   - QUnit.moduleStart( {
  64 + runLoggingCallbacks( 'moduleStart', QUnit, {
  65 + name: this.module
  66 + } );
  67 + } else if (config.autorun) {
  68 + runLoggingCallbacks( 'moduleStart', QUnit, {
61 69 name: this.module
62 70 } );
63 71 }
@@ -67,13 +75,11 @@ Test.prototype = {
67 75 setup: function() {},
68 76 teardown: function() {}
69 77 }, this.moduleTestEnvironment);
70   - if (this.testEnvironmentArg) {
71   - extend(this.testEnvironment, this.testEnvironmentArg);
72   - }
73 78
74   - QUnit.testStart( {
75   - name: this.testName
76   - } );
  79 + runLoggingCallbacks( 'testStart', QUnit, {
  80 + name: this.testName,
  81 + module: this.module
  82 + });
77 83
78 84 // allow utility functions to access the current test environment
79 85 // TODO why??
@@ -90,6 +96,7 @@ Test.prototype = {
90 96 }
91 97 },
92 98 run: function() {
  99 + config.current = this;
93 100 if ( this.async ) {
94 101 QUnit.stop();
95 102 }
@@ -108,11 +115,12 @@ Test.prototype = {
108 115
109 116 // Restart the tests if they're blocking
110 117 if ( config.blocking ) {
111   - start();
  118 + QUnit.start();
112 119 }
113 120 }
114 121 },
115 122 teardown: function() {
  123 + config.current = this;
116 124 try {
117 125 this.testEnvironment.teardown.call(this.testEnvironment);
118 126 checkPollution();
@@ -121,7 +129,8 @@ Test.prototype = {
121 129 }
122 130 },
123 131 finish: function() {
124   - if ( this.expected && this.expected != this.assertions.length ) {
  132 + config.current = this;
  133 + if ( this.expected != null && this.expected != this.assertions.length ) {
125 134 QUnit.ok( false, "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run" );
126 135 }
127 136
@@ -132,7 +141,7 @@ Test.prototype = {
132 141 config.moduleStats.all += this.assertions.length;
133 142
134 143 if ( tests ) {
135   - var ol = document.createElement("ol");
  144 + var ol = document.createElement("ol");
136 145
137 146 for ( var i = 0; i < this.assertions.length; i++ ) {
138 147 var assertion = this.assertions[i];
@@ -210,8 +219,9 @@ Test.prototype = {
210 219 fail("reset() failed, following Test " + this.testName + ", exception and reset fn follows", e, QUnit.reset);
211 220 }
212 221
213   - QUnit.testDone( {
  222 + runLoggingCallbacks( 'testDone', QUnit, {
214 223 name: this.testName,
  224 + module: this.module,
215 225 failed: bad,
216 226 passed: this.assertions.length - bad,
217 227 total: this.assertions.length
@@ -243,7 +253,7 @@ Test.prototype = {
243 253 if (bad) {
244 254 run();
245 255 } else {
246   - synchronize(run);
  256 + synchronize(run, true);
247 257 };
248 258 }
249 259
@@ -260,24 +270,19 @@ var QUnit = {
260 270 asyncTest: function(testName, expected, callback) {
261 271 if ( arguments.length === 2 ) {
262 272 callback = expected;
263   - expected = 0;
  273 + expected = null;
264 274 }
265 275
266 276 QUnit.test(testName, expected, callback, true);
267 277 },
268 278
269 279 test: function(testName, expected, callback, async) {
270   - var name = '<span class="test-name">' + testName + '</span>', testEnvironmentArg;
  280 + var name = '<span class="test-name">' + escapeInnerText(testName) + '</span>';
271 281
272 282 if ( arguments.length === 2 ) {
273 283 callback = expected;
274 284 expected = null;
275 285 }
276   - // is 2nd argument a testEnvironment?
277   - if ( expected && typeof expected === 'object') {
278   - testEnvironmentArg = expected;
279   - expected = null;
280   - }
281 286
282 287 if ( config.currentModule ) {
283 288 name = '<span class="module-name">' + config.currentModule + "</span>: " + name;
@@ -287,7 +292,7 @@ var QUnit = {
287 292 return;
288 293 }
289 294
290   - var test = new Test(name, testName, expected, testEnvironmentArg, async, callback);
  295 + var test = new Test(name, testName, expected, async, callback);
291 296 test.module = config.currentModule;
292 297 test.moduleTestEnvironment = config.currentModuleTestEnviroment;
293 298 test.queue();
@@ -305,13 +310,16 @@ var QUnit = {
305 310 * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
306 311 */
307 312 ok: function(a, msg) {
  313 + if (!config.current) {
  314 + throw new Error("ok() assertion outside test context, was " + sourceFromStacktrace(2));
  315 + }
308 316 a = !!a;
309 317 var details = {
310 318 result: a,
311 319 message: msg
312 320 };
313   - msg = escapeHtml(msg);
314   - QUnit.log(details);
  321 + msg = escapeInnerText(msg);
  322 + runLoggingCallbacks( 'log', QUnit, details );
315 323 config.current.assertions.push({
316 324 result: a,
317 325 message: msg
@@ -387,8 +395,8 @@ var QUnit = {
387 395 QUnit.ok(ok, message);
388 396 },
389 397
390   - start: function() {
391   - config.semaphore--;
  398 + start: function(count) {
  399 + config.semaphore -= count || 1;
392 400 if (config.semaphore > 0) {
393 401 // don't start until equal number of stop-calls
394 402 return;
@@ -400,36 +408,54 @@ var QUnit = {
400 408 // A slight delay, to avoid any current callbacks
401 409 if ( defined.setTimeout ) {
402 410 window.setTimeout(function() {
  411 + if (config.semaphore > 0) {
  412 + return;
  413 + }
403 414 if ( config.timeout ) {
404 415 clearTimeout(config.timeout);
405 416 }
406 417
407 418 config.blocking = false;
408   - process();
  419 + process(true);
409 420 }, 13);
410 421 } else {
411 422 config.blocking = false;
412   - process();
  423 + process(true);
413 424 }
414 425 },
415 426
416   - stop: function(timeout) {
417   - config.semaphore++;
  427 + stop: function(count) {
  428 + config.semaphore += count || 1;
418 429 config.blocking = true;
419 430
420   - if ( timeout && defined.setTimeout ) {
  431 + if ( config.testTimeout && defined.setTimeout ) {
421 432 clearTimeout(config.timeout);
422 433 config.timeout = window.setTimeout(function() {
423 434 QUnit.ok( false, "Test timed out" );
  435 + config.semaphore = 1;
424 436 QUnit.start();
425   - }, timeout);
  437 + }, config.testTimeout);
426 438 }
427 439 }
428 440 };
429 441
430   -// Backwards compatibility, deprecated
431   -QUnit.equals = QUnit.equal;
432   -QUnit.same = QUnit.deepEqual;
  442 +//We want access to the constructor's prototype
  443 +(function() {
  444 + function F(){};
  445 + F.prototype = QUnit;
  446 + QUnit = new F();
  447 + //Make F QUnit's constructor so that we can add to the prototype later
  448 + QUnit.constructor = F;
  449 +})();
  450 +
  451 +// deprecated; still export them to window to provide clear error messages
  452 +// next step: remove entirely
  453 +QUnit.equals = function() {
  454 + throw new Error("QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead");
  455 +};
  456 +QUnit.same = function() {
  457 + throw new Error("QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead");
  458 +};
433 459
434 460 // Maintain internal state
435 461 var config = {
@@ -439,12 +465,27 @@ var config = {
439 465 // block until document ready
440 466 blocking: true,
441 467
  468 + // when enabled, show only failing tests
  469 + // gets persisted through sessionStorage and can be changed in UI via checkbox
  470 + hidepassed: false,
  471 +
442 472 // by default, run previously failed tests first
443 473 // very useful in combination with "Hide passed tests" checked
444 474 reorder: true,
445 475
446   - noglobals: false,
447   - notrycatch: false
  476 + // by default, modify document.title when suite is done
  477 + altertitle: true,
  478 +
  479 + urlConfig: ['noglobals', 'notrycatch'],
  480 +
  481 + //logging callback queues
  482 + begin: [],
  483 + done: [],
  484 + log: [],
  485 + testStart: [],
  486 + testDone: [],
  487 + moduleStart: [],
  488 + moduleDone: []
448 489 };
449 490
450 491 // Load paramaters
@@ -462,9 +503,6 @@ var config = {
462 503 // allow just a key to turn on a flag, e.g., test.html?noglobals
463 504 current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true;
464 505 urlParams[ current[ 0 ] ] = current[ 1 ];
465   - if ( current[ 0 ] in config ) {
466   - config[ current[ 0 ] ] = current[ 1 ];
467   - }
468 506 }
469 507 }
470 508
@@ -481,8 +519,7 @@ if ( typeof exports === "undefined" || typeof require === "undefined" ) {
481 519 extend(window, QUnit);
482 520 window.QUnit = QUnit;
483 521 } else {
484   - extend(exports, QUnit);
485   - exports.QUnit = QUnit;
  522 + module.exports = QUnit;
486 523 }
487 524
488 525 // define these after exposing globals to keep them in these QUnit namespace only
@@ -504,6 +541,16 @@ extend(QUnit, {
504 541 semaphore: 0
505 542 });
506 543
  544 + var qunit = id( "qunit" );
  545 + if ( qunit ) {
  546 + qunit.innerHTML =
  547 + '<h1 id="qunit-header">' + escapeInnerText( document.title ) + '</h1>' +
  548 + '<h2 id="qunit-banner"></h2>' +
  549 + '<div id="qunit-testrunner-toolbar"></div>' +
  550 + '<h2 id="qunit-userAgent"></h2>' +
  551 + '<ol id="qunit-tests"></ol>';
  552 + }
  553 +
507 554 var tests = id( "qunit-tests" ),
508 555 banner = id( "qunit-banner" ),
509 556 result = id( "qunit-testresult" );
@@ -580,8 +627,7 @@ extend(QUnit, {
580 627 return "null";
581 628 }
582 629
583   - var type = Object.prototype.toString.call( obj )
584   - .match(/^\[object\s(.*)\]$/)[1] || '';
  630 + var type = toString.call( obj ).match(/^\[object\s(.*)\]$/)[1] || '';
585 631
586 632 switch (type) {
587 633 case 'Number':
@@ -605,6 +651,9 @@ extend(QUnit, {
605 651 },
606 652
607 653 push: function(result, actual, expected, message) {
  654 + if (!config.current) {
  655 + throw new Error("assertion outside test context, was " + sourceFromStacktrace());
  656 + }
608 657 var details = {
609 658 result: result,
610 659 message: message,
@@ -612,25 +661,26 @@ extend(QUnit, {
612 661 expected: expected
613 662 };
614 663
615   - message = escapeHtml(message) || (result ? "okay" : "failed");
  664 + message = escapeInnerText(message) || (result ? "okay" : "failed");
616 665 message = '<span class="test-message">' + message + "</span>";
617   - expected = escapeHtml(QUnit.jsDump.parse(expected));
618   - actual = escapeHtml(QUnit.jsDump.parse(actual));
619   - var output = message + '<table><tr class="test-expected"><th>Expected: </th><td><pre>' + expected + '</pre></td></tr>';
620   - if (actual != expected) {
621   - output += '<tr class="test-actual"><th>Result: </th><td><pre>' + actual + '</pre></td></tr>';
622   - output += '<tr class="test-diff"><th>Diff: </th><td><pre>' + QUnit.diff(expected, actual) +'</pre></td></tr>';
623   - }
  666 + var output = message;
624 667 if (!result) {
  668 + expected = escapeInnerText(QUnit.jsDump.parse(expected));
  669 + actual = escapeInnerText(QUnit.jsDump.parse(actual));
  670 + output += '<table><tr class="test-expected"><th>Expected: </th><td><pre>' + expected + '</pre></td></tr>';
  671 + if (actual != expected) {
  672 + output += '<tr class="test-actual"><th>Result: </th><td><pre>' + actual + '</pre></td></tr>';
  673 + output += '<tr class="test-diff"><th>Diff: </th><td><pre>' + QUnit.diff(expected, actual) +'</pre></td></tr>';
  674 + }
625 675 var source = sourceFromStacktrace();
626 676 if (source) {
627 677 details.source = source;
628   - output += '<tr class="test-source"><th>Source: </th><td><pre>' + escapeHtml(source) + '</pre></td></tr>';
  678 + output += '<tr class="test-source"><th>Source: </th><td><pre>' + escapeInnerText(source) + '</pre></td></tr>';
629 679 }
  680 + output += "</table>";
630 681 }
631   - output += "</table>";
632 682
633   - QUnit.log(details);
  683 + runLoggingCallbacks( 'log', QUnit, details );
634 684
635 685 config.current.assertions.push({
636 686 result: !!result,
@@ -643,6 +693,9 @@ extend(QUnit, {
643 693 var querystring = "?",
644 694 key;
645 695 for ( key in params ) {
  696 + if ( !hasOwn.call( params, key ) ) {
  697 + continue;
  698 + }
646 699 querystring += encodeURIComponent( key ) + "=" +
647 700 encodeURIComponent( params[ key ] ) + "&";
648 701 }
@@ -651,31 +704,36 @@ extend(QUnit, {
651 704
652 705 extend: extend,
653 706 id: id,
654   - addEvent: addEvent,
  707 + addEvent: addEvent
  708 +});
655 709
  710 +//QUnit.constructor is set to the empty F() above so that we can add to it's prototype later
  711 +//Doing this allows us to tell if the following methods have been overwritten on the actual
  712 +//QUnit object, which is a deprecated way of using the callbacks.
  713 +extend(QUnit.constructor.prototype, {
656 714 // Logging callbacks; all receive a single argument with the listed properties
657 715 // run test/logs.html for any related changes
658   - begin: function() {},
  716 + begin: registerLoggingCallback('begin'),
659 717 // done: { failed, passed, total, runtime }
660   - done: function() {},
  718 + done: registerLoggingCallback('done'),
661 719 // log: { result, actual, expected, message }
662   - log: function() {},
  720 + log: registerLoggingCallback('log'),
663 721 // testStart: { name }
664   - testStart: function() {},
  722 + testStart: registerLoggingCallback('testStart'),
665 723 // testDone: { name, failed, passed, total }
666   - testDone: function() {},
  724 + testDone: registerLoggingCallback('testDone'),
667 725 // moduleStart: { name }
668   - moduleStart: function() {},
  726 + moduleStart: registerLoggingCallback('moduleStart'),
669 727 // moduleDone: { name, failed, passed, total }
670   - moduleDone: function() {}
  728 + moduleDone: registerLoggingCallback('moduleDone')
671 729 });
672 730
673 731 if ( typeof document === "undefined" || document.readyState === "complete" ) {
674 732 config.autorun = true;
675 733 }
676 734
677   -addEvent(window, "load", function() {
678   - QUnit.begin({});
  735 +QUnit.load = function() {
  736 + runLoggingCallbacks( 'begin', QUnit, {} );
679 737
680 738 // Initialize the config, saving the execution queue
681 739 var oldconfig = extend({}, config);
@@ -684,15 +742,19 @@ addEvent(window, "load", function() {
684 742
685 743 config.blocking = false;
686 744
  745 + var urlConfigHtml = '', len = config.urlConfig.length;
  746 + for ( var i = 0, val; i < len, val = config.urlConfig[i]; i++ ) {
  747 + config[val] = QUnit.urlParams[val];
  748 + urlConfigHtml += '<label><input name="' + val + '" type="checkbox"' + ( config[val] ? ' checked="checked"' : '' ) + '>' + val + '</label>';
  749 + }
  750 +
687 751 var userAgent = id("qunit-userAgent");
688 752 if ( userAgent ) {
689 753 userAgent.innerHTML = navigator.userAgent;
690 754 }
691 755 var banner = id("qunit-header");
692 756 if ( banner ) {
693   - banner.innerHTML = '<a href="' + QUnit.url({ filter: undefined }) + '"> ' + banner.innerHTML + '</a> ' +
694   - '<label><input name="noglobals" type="checkbox"' + ( config.noglobals ? ' checked="checked"' : '' ) + '>noglobals</label>' +
695   - '<label><input name="notrycatch" type="checkbox"' + ( config.notrycatch ? ' checked="checked"' : '' ) + '>notrycatch</label>';
  757 + banner.innerHTML = '<a href="' + QUnit.url({ filter: undefined }) + '"> ' + banner.innerHTML + '</a> ' + urlConfigHtml;
696 758 addEvent( banner, "change", function( event ) {
697 759 var params = {};
698 760 params[ event.target.name ] = event.target.checked ? true : undefined;
@@ -715,13 +777,13 @@ addEvent(window, "load", function() {
715 777 }
716 778 if ( defined.sessionStorage ) {
717 779 if (filter.checked) {
718   - sessionStorage.setItem("qunit-filter-passed-tests", "true");
  780 + sessionStorage.setItem("qunit-filter-passed-tests", "true");
719 781 } else {
720 782 sessionStorage.removeItem("qunit-filter-passed-tests");
721 783 }
722 784 }
723 785 });
724   - if ( defined.sessionStorage && sessionStorage.getItem("qunit-filter-passed-tests") ) {
  786 + if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem("qunit-filter-passed-tests") ) {
725 787 filter.checked = true;
726 788 var ol = document.getElementById("qunit-tests");
727 789 ol.className = ol.className + " hidepass";
@@ -742,14 +804,27 @@ addEvent(window, "load", function() {
742 804 if (config.autostart) {
743 805 QUnit.start();
744 806 }
745   -});
  807 +};
  808 +
  809 +addEvent(window, "load", QUnit.load);
  810 +
  811 +// addEvent(window, "error") gives us a useless event object
  812 +window.onerror = function( message, file, line ) {
  813 + if ( QUnit.config.current ) {
  814 + ok( false, message + ", " + file + ":" + line );
  815 + } else {
  816 + test( "global failure", function() {
  817 + ok( false, message + ", " + file + ":" + line );
  818 + });
  819 + }
  820 +};
746 821
747 822 function done() {
748 823 config.autorun = true;
749 824
750 825 // Log the last module results
751 826 if ( config.currentModule ) {
752   - QUnit.moduleDone( {
  827 + runLoggingCallbacks( 'moduleDone', QUnit, {
753 828 name: config.currentModule,
754 829 failed: config.moduleStats.bad,
755 830 passed: config.moduleStats.all - config.moduleStats.bad,
@@ -782,13 +857,25 @@ function done() {
782 857 id( "qunit-testresult" ).innerHTML = html;
783 858 }
784 859
785   - if ( typeof document !== "undefined" && document.title ) {
786   - // show ✖ for bad, ✔ for good suite result in title
  860 + if ( config.altertitle && typeof document !== "undefined" && document.title ) {
  861 + // show ✖ for good, ✔ for bad suite result in title
787 862 // use escape sequences in case file gets loaded with non-utf-8-charset
788   - document.title = (config.stats.bad ? "\u2716" : "\u2714") + " " + document.title;
  863 + document.title = [
  864 + (config.stats.bad ? "\u2716" : "\u2714"),
  865 + document.title.replace(/^[\u2714\u2716] /i, "")
  866 + ].join(" ");
  867 + }
  868 +
  869 + // clear own sessionStorage items if all tests passed
  870 + if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) {
  871 + for (var key in sessionStorage) {
  872 + if (sessionStorage.hasOwnProperty(key) && key.indexOf("qunit-") === 0 ) {
  873 + sessionStorage.removeItem(key);
  874 + }
  875 + }
789 876 }
790 877
791   - QUnit.done( {
  878 + runLoggingCallbacks( 'done', QUnit, {
792 879 failed: config.stats.bad,
793 880 passed: passed,
794 881 total: config.stats.all,
@@ -822,30 +909,37 @@ function validTest( name ) {
822 909
823 910 // so far supports only Firefox, Chrome and Opera (buggy)
824 911 // could be extended in the future to use something like https://github.com/csnover/TraceKit
825   -function sourceFromStacktrace() {
  912 +function sourceFromStacktrace(offset) {
  913 + offset = offset || 3;
826 914 try {
827 915 throw new Error();
828 916 } catch ( e ) {
829 917 if (e.stacktrace) {
830 918 // Opera
831   - return e.stacktrace.split("\n")[6];
  919 + return e.stacktrace.split("\n")[offset + 3];
832 920 } else if (e.stack) {
833 921 // Firefox, Chrome
834   - return e.stack.split("\n")[4];
  922 + var stack = e.stack.split("\n");
  923 + if (/^error$/i.test(stack[0])) {
  924 + stack.shift();
  925 + }
  926 + return stack[offset];
  927 + } else if (e.sourceURL) {
  928 + // Safari, PhantomJS
  929 + // TODO sourceURL points at the 'throw new Error' line above, useless
  930 + //return e.sourceURL + ":" + e.line;
835 931 }
836 932 }
837 933 }
838 934
839   -function escapeHtml(s) {
  935 +function escapeInnerText(s) {
840 936 if (!s) {
841 937 return "";
842 938 }
843 939 s = s + "";
844   - return s.replace(/[\&"<>\\]/g, function(s) {
  940 + return s.replace(/[\&<>]/g, function(s) {
845 941 switch(s) {
846 942 case "&": return "&amp;";
847   - case "\\": return "\\\\";
848   - case '"': return '\"';
849 943 case "<": return "&lt;";
850 944 case ">": return "&gt;";
851 945 default: return s;
@@ -853,28 +947,32 @@ function escapeHtml(s) {
853 947 });
854 948 }
855 949
856   -function synchronize( callback ) {
  950 +function synchronize( callback, last ) {
857 951 config.queue.push( callback );
858 952
859 953 if ( config.autorun && !config.blocking ) {
860   - process();
  954 + process(last);
861 955 }
862 956 }
863 957
864   -function process() {
865   - var start = (new Date()).getTime();
  958 +function process( last ) {
  959 + var start = new Date().getTime();
  960 + config.depth = config.depth ? config.depth + 1 : 1;
866 961
867 962 while ( config.queue.length && !config.blocking ) {
868   - if ( config.updateRate <= 0 || (((new Date()).getTime() - start) < config.updateRate) ) {
  963 + if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) {
869 964 config.queue.shift()();
870 965 } else {
871   - window.setTimeout( process, 13 );
  966 + window.setTimeout( function(){
  967 + process( last );
  968 + }, 13 );
872 969 break;
873 970 }
874 971 }
875   - if (!config.blocking && !config.queue.length) {
876   - done();
877   - }
  972 + config.depth--;
  973 + if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) {
  974 + done();
  975 + }
878 976 }
879 977
880 978 function saveGlobal() {
@@ -882,6 +980,9 @@ function saveGlobal() {
882 980
883 981 if ( config.noglobals ) {
884 982 for ( var key in window ) {
  983 + if ( !hasOwn.call( window, key ) ) {
  984 + continue;
  985 + }
885 986 config.pollution.push( key );
886 987 }
887 988 }
@@ -921,6 +1022,7 @@ function fail(message, exception, callback) {
921 1022 if ( typeof console !== "undefined" && console.error && console.warn ) {
922 1023 console.error(message);
923 1024 console.error(exception);
  1025 + console.error(exception.stack);
924 1026 console.warn(callback.toString());
925 1027
926 1028 } else if ( window.opera && opera.postError ) {
@@ -932,7 +1034,9 @@ function extend(a, b) {
932 1034 for ( var prop in b ) {
933 1035 if ( b[prop] === undefined ) {
934 1036 delete a[prop];
935   - } else {
  1037 +
  1038 + // Avoid "Member not found" error in IE8 caused by setting window.constructor
  1039 + } else if ( prop !== "constructor" || a !== window ) {
936 1040 a[prop] = b[prop];
937 1041 }
938 1042 }
@@ -955,176 +1059,216 @@ function id(name) {
955 1059 document.getElementById( name );
956 1060 }
957 1061
  1062 +function registerLoggingCallback(key){
  1063 + return function(callback){
  1064 + config[key].push( callback );
  1065 + };
  1066 +}
  1067 +
  1068 +// Supports deprecated method of completely overwriting logging callbacks
  1069 +function runLoggingCallbacks(key, scope, args) {
  1070 + //debugger;
  1071 + var callbacks;
  1072 + if ( QUnit.hasOwnProperty(key) ) {
  1073 + QUnit[key].call(scope, args);
  1074 + } else {
  1075 + callbacks = config[key];
  1076 + for( var i = 0; i < callbacks.length; i++ ) {
  1077 + callbacks[i].call( scope, args );
  1078 + }
  1079 + }
  1080 +}
  1081 +
958 1082 // Test for equality any JavaScript type.
959   -// Discussions and reference: http://philrathe.com/articles/equiv
960   -// Test suites: http://philrathe.com/tests/equiv
961 1083 // Author: Philippe Rathé <prathe@gmail.com>
962 1084 QUnit.equiv = function () {
963 1085
964   - var innerEquiv; // the real equiv function
965   - var callers = []; // stack to decide between skip/abort functions
966   - var parents = []; // stack to avoiding loops from circular referencing
967   -
968   - // Call the o related callback with the given arguments.
969