diff --git a/js_tests/admin/DateTimeShortcuts.test.js b/js_tests/admin/DateTimeShortcuts.test.js
index e993090233..5d5b12ba60 100644
--- a/js_tests/admin/DateTimeShortcuts.test.js
+++ b/js_tests/admin/DateTimeShortcuts.test.js
@@ -1,10 +1,10 @@
-/* global module, test, DateTimeShortcuts */
+/* global QUnit, DateTimeShortcuts */
/* eslint global-strict: 0, strict: 0 */
'use strict';
-module('admin.DateTimeShortcuts');
+QUnit.module('admin.DateTimeShortcuts');
-test('init', function(assert) {
+QUnit.test('init', function(assert) {
var $ = django.jQuery;
var dateField = $('
');
diff --git a/js_tests/admin/RelatedObjectLookups.test.js b/js_tests/admin/RelatedObjectLookups.test.js
index 83071edd43..9ec1eed102 100644
--- a/js_tests/admin/RelatedObjectLookups.test.js
+++ b/js_tests/admin/RelatedObjectLookups.test.js
@@ -1,16 +1,16 @@
-/* global module, test, id_to_windowname,
+/* global QUnit, id_to_windowname,
windowname_to_id */
/* eslint global-strict: 0, strict: 0 */
'use strict';
-module('admin.RelatedObjectLookups');
+QUnit.module('admin.RelatedObjectLookups');
-test('id_to_windowname', function(assert) {
+QUnit.test('id_to_windowname', function(assert) {
assert.equal(id_to_windowname('.test'), '__dot__test');
assert.equal(id_to_windowname('misc-test'), 'misc__dash__test');
});
-test('windowname_to_id', function(assert) {
+QUnit.test('windowname_to_id', function(assert) {
assert.equal(windowname_to_id('__dot__test'), '.test');
assert.equal(windowname_to_id('misc__dash__test'), 'misc-test');
});
diff --git a/js_tests/admin/SelectBox.test.js b/js_tests/admin/SelectBox.test.js
index cb0259d12c..23c057c364 100644
--- a/js_tests/admin/SelectBox.test.js
+++ b/js_tests/admin/SelectBox.test.js
@@ -1,17 +1,17 @@
-/* global module, test, SelectBox */
+/* global QUnit, SelectBox */
/* eslint global-strict: 0, strict: 0 */
'use strict';
-module('admin.SelectBox');
+QUnit.module('admin.SelectBox');
-test('init: no options', function(assert) {
+QUnit.test('init: no options', function(assert) {
var $ = django.jQuery;
$('').appendTo('#qunit-fixture');
SelectBox.init('id');
assert.equal(SelectBox.cache.id.length, 0);
});
-test('filter', function(assert) {
+QUnit.test('filter', function(assert) {
var $ = django.jQuery;
$('').appendTo('#qunit-fixture');
$('').appendTo('#id');
diff --git a/js_tests/admin/SelectFilter2.test.js b/js_tests/admin/SelectFilter2.test.js
index 1aa97958cb..c000584f48 100644
--- a/js_tests/admin/SelectFilter2.test.js
+++ b/js_tests/admin/SelectFilter2.test.js
@@ -1,10 +1,10 @@
-/* global module, test, SelectFilter */
+/* global QUnit, SelectFilter */
/* eslint global-strict: 0, strict: 0 */
'use strict';
-module('admin.SelectFilter2');
+QUnit.module('admin.SelectFilter2');
-test('init', function(assert) {
+QUnit.test('init', function(assert) {
var $ = django.jQuery;
$('
').appendTo('#qunit-fixture');
$('').appendTo('#id');
diff --git a/js_tests/admin/actions.test.js b/js_tests/admin/actions.test.js
index d26d16328c..3ff8709ec6 100644
--- a/js_tests/admin/actions.test.js
+++ b/js_tests/admin/actions.test.js
@@ -1,8 +1,8 @@
-/* global module, test */
+/* global QUnit */
/* eslint global-strict: 0, strict: 0 */
'use strict';
-module('admin.actions', {
+QUnit.module('admin.actions', {
beforeEach: function() {
// Number of results shown on page
/* eslint-disable */
@@ -16,7 +16,7 @@ module('admin.actions', {
}
});
-test('check', function(assert) {
+QUnit.test('check', function(assert) {
var $ = django.jQuery;
assert.notOk($('.action-select').is(':checked'));
$('#action-toggle').click();
diff --git a/js_tests/admin/core.test.js b/js_tests/admin/core.test.js
index 7f0a4d6fda..eaf882dc4b 100644
--- a/js_tests/admin/core.test.js
+++ b/js_tests/admin/core.test.js
@@ -1,63 +1,63 @@
-/* global module, test */
+/* global QUnit */
/* eslint global-strict: 0, strict: 0 */
'use strict';
-module('admin.core');
+QUnit.module('admin.core');
-test('Date.getTwelveHours', function(assert) {
+QUnit.test('Date.getTwelveHours', function(assert) {
assert.equal(new Date(2011, 0, 1, 0, 0).getTwelveHours(), 12, '0:00');
assert.equal(new Date(2011, 0, 1, 11, 0).getTwelveHours(), 11, '11:00');
assert.equal(new Date(2011, 0, 1, 16, 0).getTwelveHours(), 4, '16:00');
});
-test('Date.getTwoDigitMonth', function(assert) {
+QUnit.test('Date.getTwoDigitMonth', function(assert) {
assert.equal(new Date(2011, 0, 1).getTwoDigitMonth(), '01', 'jan 1');
assert.equal(new Date(2011, 9, 1).getTwoDigitMonth(), '10', 'oct 1');
});
-test('Date.getTwoDigitDate', function(assert) {
+QUnit.test('Date.getTwoDigitDate', function(assert) {
assert.equal(new Date(2011, 0, 1).getTwoDigitDate(), '01', 'jan 1');
assert.equal(new Date(2011, 0, 15).getTwoDigitDate(), '15', 'jan 15');
});
-test('Date.getTwoDigitTwelveHour', function(assert) {
+QUnit.test('Date.getTwoDigitTwelveHour', function(assert) {
assert.equal(new Date(2011, 0, 1, 0, 0).getTwoDigitTwelveHour(), '12', '0:00');
assert.equal(new Date(2011, 0, 1, 4, 0).getTwoDigitTwelveHour(), '04', '4:00');
assert.equal(new Date(2011, 0, 1, 22, 0).getTwoDigitTwelveHour(), '10', '22:00');
});
-test('Date.getTwoDigitHour', function(assert) {
+QUnit.test('Date.getTwoDigitHour', function(assert) {
assert.equal(new Date(2014, 6, 1, 9, 0).getTwoDigitHour(), '09', '9:00 am is 09');
assert.equal(new Date(2014, 6, 1, 11, 0).getTwoDigitHour(), '11', '11:00 am is 11');
});
-test('Date.getTwoDigitMinute', function(assert) {
+QUnit.test('Date.getTwoDigitMinute', function(assert) {
assert.equal(new Date(2014, 6, 1, 0, 5).getTwoDigitMinute(), '05', '12:05 am is 05');
assert.equal(new Date(2014, 6, 1, 0, 15).getTwoDigitMinute(), '15', '12:15 am is 15');
});
-test('Date.getTwoDigitSecond', function(assert) {
+QUnit.test('Date.getTwoDigitSecond', function(assert) {
assert.equal(new Date(2014, 6, 1, 0, 0, 2).getTwoDigitSecond(), '02', '12:00:02 am is 02');
assert.equal(new Date(2014, 6, 1, 0, 0, 20).getTwoDigitSecond(), '20', '12:00:20 am is 20');
});
-test('Date.getHourMinute', function(assert) {
+QUnit.test('Date.getHourMinute', function(assert) {
assert.equal(new Date(2014, 6, 1, 11, 0).getHourMinute(), '11:00', '11:00 am is 11:00');
assert.equal(new Date(2014, 6, 1, 13, 25).getHourMinute(), '13:25', '1:25 pm is 13:25');
});
-test('Date.getHourMinuteSecond', function(assert) {
+QUnit.test('Date.getHourMinuteSecond', function(assert) {
assert.equal(new Date(2014, 6, 1, 11, 0, 0).getHourMinuteSecond(), '11:00:00', '11:00 am is 11:00:00');
assert.equal(new Date(2014, 6, 1, 17, 45, 30).getHourMinuteSecond(), '17:45:30', '5:45:30 pm is 17:45:30');
});
-test('Date.strftime', function(assert) {
+QUnit.test('Date.strftime', function(assert) {
var date = new Date(2014, 6, 1, 11, 0, 5);
assert.equal(date.strftime('%Y-%m-%d %H:%M:%S'), '2014-07-01 11:00:05');
assert.equal(date.strftime('%B %d, %Y'), 'July 01, 2014');
});
-test('String.strptime', function(assert) {
+QUnit.test('String.strptime', function(assert) {
// Use UTC functions for extracting dates since the calendar uses them as
// well. Month numbering starts with 0 (January).
var firstParsedDate = '1988-02-26'.strptime('%Y-%m-%d');
diff --git a/js_tests/admin/inlines.test.js b/js_tests/admin/inlines.test.js
index b18b266024..2ff6a14577 100644
--- a/js_tests/admin/inlines.test.js
+++ b/js_tests/admin/inlines.test.js
@@ -1,8 +1,8 @@
-/* global module, test */
+/* global QUnit */
/* eslint global-strict: 0, strict: 0 */
'use strict';
-module('admin.inlines: tabular formsets', {
+QUnit.module('admin.inlines: tabular formsets', {
beforeEach: function() {
var $ = django.jQuery;
var that = this;
@@ -19,19 +19,19 @@ module('admin.inlines: tabular formsets', {
}
});
-test('no forms', function(assert) {
+QUnit.test('no forms', function(assert) {
assert.ok(this.inlineRow.hasClass('dynamic-first'));
assert.equal(this.table.find('.add-row a').text(), this.addText);
});
-test('add form', function(assert) {
+QUnit.test('add form', function(assert) {
var addButton = this.table.find('.add-row a');
assert.equal(addButton.text(), this.addText);
addButton.click();
assert.ok(this.table.find('#first-1').hasClass('row2'));
});
-test('add/remove form events', function(assert) {
+QUnit.test('add/remove form events', function(assert) {
assert.expect(6);
var $ = django.jQuery;
var $document = $(document);
@@ -52,7 +52,7 @@ test('add/remove form events', function(assert) {
deleteLink.click();
});
-test('existing add button', function(assert) {
+QUnit.test('existing add button', function(assert) {
var $ = django.jQuery;
$('#qunit-fixture').empty(); // Clear the table added in beforeEach
$('#qunit-fixture').append($('#tabular-formset').text());
diff --git a/js_tests/admin/timeparse.test.js b/js_tests/admin/timeparse.test.js
index e5d1b2cf26..a162d6d36e 100644
--- a/js_tests/admin/timeparse.test.js
+++ b/js_tests/admin/timeparse.test.js
@@ -1,10 +1,10 @@
-/* global module, test, parseTimeString */
+/* global QUnit, parseTimeString */
/* eslint global-strict: 0, strict: 0 */
'use strict';
-module('admin.timeparse');
+QUnit.module('admin.timeparse');
-test('parseTimeString', function(assert) {
+QUnit.test('parseTimeString', function(assert) {
function time(then, expected) {
assert.equal(parseTimeString(then), expected);
}
diff --git a/js_tests/gis/mapwidget.test.js b/js_tests/gis/mapwidget.test.js
index 716e6eca8b..9d1daaaafd 100644
--- a/js_tests/gis/mapwidget.test.js
+++ b/js_tests/gis/mapwidget.test.js
@@ -1,10 +1,10 @@
-/* global module, test, MapWidget */
+/* global QUnit, MapWidget */
/* eslint global-strict: 0, strict: 0 */
'use strict';
-module('gis.OLMapWidget');
+QUnit.module('gis.OLMapWidget');
-test('MapWidget.featureAdded', function(assert) {
+QUnit.test('MapWidget.featureAdded', function(assert) {
var options = {id: 'id_point', map_id: 'id_point_map', geom_name: 'Point'};
var widget = new MapWidget(options);
assert.equal(widget.layers.vector.features.length, 1);
@@ -15,13 +15,13 @@ test('MapWidget.featureAdded', function(assert) {
);
});
-test('MapWidget.map_srid', function(assert) {
+QUnit.test('MapWidget.map_srid', function(assert) {
var options = {id: 'id_point', map_id: 'id_point_map', geom_name: 'Point'};
var widget = new MapWidget(options);
assert.equal(widget.options.map_srid, 4326, 'SRID 4326');
});
-test('MapWidget.defaultCenter', function(assert) {
+QUnit.test('MapWidget.defaultCenter', function(assert) {
var options = {id: 'id_point', map_id: 'id_point_map', geom_name: 'Point'};
var widget = new MapWidget(options);
assert.equal(widget.defaultCenter().toString(), 'lon=0,lat=0', 'Default center at 0, 0');
@@ -35,7 +35,7 @@ test('MapWidget.defaultCenter', function(assert) {
);
});
-test('MapWidget.getControls', function(assert) {
+QUnit.test('MapWidget.getControls', function(assert) {
var options = {id: 'id_point', map_id: 'id_point_map', geom_name: 'Point'};
var widget = new MapWidget(options);
widget.getControls(widget.layers.vector);
@@ -45,7 +45,7 @@ test('MapWidget.getControls', function(assert) {
assert.equal(widget.controls[2].displayClass, 'olControlModifyFeature', 'Modify control');
});
-test('MapWidget.IsCollection', function(assert) {
+QUnit.test('MapWidget.IsCollection', function(assert) {
var options = {id: 'id_point', map_id: 'id_point_map', geom_name: 'Point'};
var widget = new MapWidget(options);
assert.notOk(widget.options.is_collection);
diff --git a/js_tests/qunit/qunit.css b/js_tests/qunit/qunit.css
index ae68fc412e..5d19d74068 100644
--- a/js_tests/qunit/qunit.css
+++ b/js_tests/qunit/qunit.css
@@ -1,12 +1,12 @@
/*!
- * QUnit 1.23.1
+ * QUnit 2.0.1
* https://qunitjs.com/
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license
* https://jquery.org/license
*
- * Date: 2016-04-12T17:29Z
+ * Date: 2016-07-23T19:39Z
*/
/** Font Family and Sizes */
@@ -27,7 +27,7 @@
}
-/** Header */
+/** Header (excluding toolbar) */
#qunit-header {
padding: 0.5em 0 0.5em 1em;
@@ -52,51 +52,161 @@
color: #FFF;
}
-#qunit-testrunner-toolbar label {
- display: inline-block;
- padding: 0 0.5em 0 0.1em;
-}
-
#qunit-banner {
height: 5px;
}
+#qunit-filteredTest {
+ padding: 0.5em 1em 0.5em 1em;
+ color: #366097;
+ background-color: #F4FF77;
+}
+
+#qunit-userAgent {
+ padding: 0.5em 1em 0.5em 1em;
+ color: #FFF;
+ background-color: #2B81AF;
+ text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
+}
+
+
+/** Toolbar */
+
#qunit-testrunner-toolbar {
padding: 0.5em 1em 0.5em 1em;
color: #5E740B;
background-color: #EEE;
- overflow: hidden;
}
-#qunit-filteredTest {
- padding: 0.5em 1em 0.5em 1em;
- background-color: #F4FF77;
- color: #366097;
+#qunit-testrunner-toolbar .clearfix {
+ height: 0;
+ clear: both;
}
-#qunit-userAgent {
- padding: 0.5em 1em 0.5em 1em;
- background-color: #2B81AF;
- color: #FFF;
- text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
-}
-
-#qunit-modulefilter-container {
- float: right;
- padding: 0.2em;
-}
-
-.qunit-url-config {
+#qunit-testrunner-toolbar label {
display: inline-block;
- padding: 0.1em;
}
-.qunit-filter {
- display: block;
+#qunit-testrunner-toolbar input[type=checkbox],
+#qunit-testrunner-toolbar input[type=radio] {
+ margin: 3px;
+ vertical-align: -2px;
+}
+
+#qunit-testrunner-toolbar input[type=text] {
+ box-sizing: border-box;
+ height: 1.6em;
+}
+
+.qunit-url-config,
+.qunit-filter,
+#qunit-modulefilter {
+ display: inline-block;
+ line-height: 2.1em;
+}
+
+.qunit-filter,
+#qunit-modulefilter {
float: right;
+ position: relative;
margin-left: 1em;
}
+.qunit-url-config label {
+ margin-right: 0.5em;
+}
+
+#qunit-modulefilter-search {
+ box-sizing: border-box;
+ width: 400px;
+}
+
+#qunit-modulefilter-search-container:after {
+ position: absolute;
+ right: 0.3em;
+ content: "\25bc";
+ color: black;
+}
+
+#qunit-modulefilter-dropdown {
+ /* align with #qunit-modulefilter-search */
+ box-sizing: border-box;
+ width: 400px;
+ position: absolute;
+ right: 0;
+ top: 50%;
+ margin-top: 0.8em;
+
+ border: 1px solid #D3D3D3;
+ border-top: none;
+ border-radius: 0 0 .25em .25em;
+ color: #000;
+ background-color: #F5F5F5;
+ z-index: 99;
+}
+
+#qunit-modulefilter-dropdown a {
+ color: inherit;
+ text-decoration: none;
+}
+
+#qunit-modulefilter-dropdown .clickable.checked {
+ font-weight: bold;
+ color: #000;
+ background-color: #D2E0E6;
+}
+
+#qunit-modulefilter-dropdown .clickable:hover {
+ color: #FFF;
+ background-color: #0D3349;
+}
+
+#qunit-modulefilter-actions {
+ display: block;
+ overflow: auto;
+
+ /* align with #qunit-modulefilter-dropdown-list */
+ font: smaller/1.5em sans-serif;
+}
+
+#qunit-modulefilter-dropdown #qunit-modulefilter-actions > * {
+ box-sizing: border-box;
+ max-height: 2.8em;
+ display: block;
+ padding: 0.4em;
+}
+
+#qunit-modulefilter-dropdown #qunit-modulefilter-actions > button {
+ float: right;
+ font: inherit;
+}
+
+#qunit-modulefilter-dropdown #qunit-modulefilter-actions > :last-child {
+ /* insert padding to align with checkbox margins */
+ padding-left: 3px;
+}
+
+#qunit-modulefilter-dropdown-list {
+ max-height: 200px;
+ overflow-y: auto;
+ margin: 0;
+ border-top: 2px groove threedhighlight;
+ padding: 0.4em 0 0;
+ font: smaller/1.5em sans-serif;
+}
+
+#qunit-modulefilter-dropdown-list li {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+#qunit-modulefilter-dropdown-list .clickable {
+ display: block;
+ padding-left: 0.15em;
+}
+
+
/** Tests: Pass/Fail */
#qunit-tests {
@@ -202,14 +312,14 @@
}
#qunit-tests del {
- background-color: #E0F2BE;
color: #374E0C;
+ background-color: #E0F2BE;
text-decoration: none;
}
#qunit-tests ins {
- background-color: #FFCACA;
color: #500;
+ background-color: #FFCACA;
text-decoration: none;
}
diff --git a/js_tests/qunit/qunit.js b/js_tests/qunit/qunit.js
index 5df0822ea4..47c904cf32 100644
--- a/js_tests/qunit/qunit.js
+++ b/js_tests/qunit/qunit.js
@@ -1,12 +1,12 @@
/*!
- * QUnit 1.23.1
+ * QUnit 2.0.1
* https://qunitjs.com/
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license
* https://jquery.org/license
*
- * Date: 2016-04-12T17:29Z
+ * Date: 2016-07-23T19:39Z
*/
( function( global ) {
@@ -43,6 +43,8 @@ var fileName = ( sourceFromStacktrace( 0 ) || "" ).replace( /(:\d+)+\)?/, "" ).r
var globalStartCalled = false;
var runStarted = false;
+var autorun = false;
+
var toString = Object.prototype.toString,
hasOwn = Object.prototype.hasOwnProperty;
@@ -100,16 +102,10 @@ function objectValues ( obj ) {
function extend( a, b, undefOnly ) {
for ( var prop in b ) {
if ( hasOwn.call( b, prop ) ) {
-
- // Avoid "Member not found" error in IE8 caused by messing with window.constructor
- // This block runs on every environment, so `global` is being used instead of `window`
- // to avoid errors on node.
- if ( prop !== "constructor" || a !== global ) {
- if ( b[ prop ] === undefined ) {
- delete a[ prop ];
- } else if ( !( undefOnly && typeof a[ prop ] !== "undefined" ) ) {
- a[ prop ] = b[ prop ];
- }
+ if ( b[ prop ] === undefined ) {
+ delete a[ prop ];
+ } else if ( !( undefOnly && typeof a[ prop ] !== "undefined" ) ) {
+ a[ prop ] = b[ prop ];
}
}
}
@@ -157,7 +153,7 @@ function is( type, obj ) {
return QUnit.objectType( obj ) === type;
}
-// Doesn't support IE6 to IE9, it will return undefined on these browsers
+// Doesn't support IE9, it will return undefined on these browsers
// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack
function extractStacktrace( e, offset ) {
offset = offset === undefined ? 4 : offset;
@@ -182,17 +178,6 @@ function extractStacktrace( e, offset ) {
}
}
return stack[ offset ];
-
- // Support: Safari <=6 only
- } else if ( e.sourceURL ) {
-
- // Exclude useless self-reference for generated Error objects
- if ( /qunit.js$/.test( e.sourceURL ) ) {
- return;
- }
-
- // For actual exceptions, this is useful
- return e.sourceURL + ":" + e.line;
}
}
@@ -266,8 +251,6 @@ var config = {
// Push a loose unnamed module to the modules collection
config.modules.push( config.currentModule );
-var loggingCallbacks = {};
-
// Register logging callbacks
function registerLoggingCallbacks( obj ) {
var i, l, key,
@@ -285,11 +268,6 @@ function registerLoggingCallbacks( obj ) {
config.callbacks[ key ].push( callback );
};
- // DEPRECATED: This will be removed on QUnit 2.0.0+
- // Stores the registered functions allowing restoring
- // at verifyLoggingCallbacks() if modified
- loggingCallbacks[ key ] = loggingCallback;
-
return loggingCallback;
}
@@ -314,34 +292,6 @@ function runLoggingCallbacks( key, args ) {
}
}
-// DEPRECATED: This will be removed on 2.0.0+
-// This function verifies if the loggingCallbacks were modified by the user
-// If so, it will restore it, assign the given callback and print a console warning
-function verifyLoggingCallbacks() {
- var loggingCallback, userCallback;
-
- for ( loggingCallback in loggingCallbacks ) {
- if ( QUnit[ loggingCallback ] !== loggingCallbacks[ loggingCallback ] ) {
-
- userCallback = QUnit[ loggingCallback ];
-
- // Restore the callback function
- QUnit[ loggingCallback ] = loggingCallbacks[ loggingCallback ];
-
- // Assign the deprecated given callback
- QUnit[ loggingCallback ]( userCallback );
-
- if ( global.console && global.console.warn ) {
- global.console.warn(
- "QUnit." + loggingCallback + " was replaced with a new value.\n" +
- "Please, check out the documentation on how to apply logging callbacks.\n" +
- "Reference: https://api.qunitjs.com/category/callbacks/"
- );
- }
- }
- }
-}
-
( function() {
if ( !defined.document ) {
return;
@@ -384,7 +334,7 @@ function verifyLoggingCallbacks() {
QUnit.isLocal = !( defined.document && window.location.protocol !== "file:" );
// Expose the current QUnit version
-QUnit.version = "1.23.1";
+QUnit.version = "2.0.1";
extend( QUnit, {
@@ -400,22 +350,21 @@ extend( QUnit, {
}
}
- // DEPRECATED: handles setup/teardown functions,
- // beforeEach and afterEach should be used instead
- if ( testEnvironment && testEnvironment.setup ) {
- testEnvironment.beforeEach = testEnvironment.setup;
- delete testEnvironment.setup;
- }
- if ( testEnvironment && testEnvironment.teardown ) {
- testEnvironment.afterEach = testEnvironment.teardown;
- delete testEnvironment.teardown;
- }
-
module = createModule();
+ if ( testEnvironment && ( testEnvironment.setup || testEnvironment.teardown ) ) {
+ console.warn(
+ "Module's `setup` and `teardown` are not hooks anymore on QUnit 2.0, use " +
+ "`beforeEach` and `afterEach` instead\n" +
+ "Details in our upgrade guide at https://qunitjs.com/upgrade-guide-2.x/"
+ );
+ }
+
moduleFns = {
+ before: setHook( module, "before" ),
beforeEach: setHook( module, "beforeEach" ),
- afterEach: setHook( module, "afterEach" )
+ afterEach: setHook( module, "afterEach" ),
+ after: setHook( module, "after" )
};
if ( objectType( executeNow ) === "function" ) {
@@ -437,11 +386,13 @@ extend( QUnit, {
name: moduleName,
parentModule: parentModule,
tests: [],
- moduleId: generateHash( moduleName )
+ moduleId: generateHash( moduleName ),
+ testsRun: 0
};
var env = {};
if ( parentModule ) {
+ parentModule.childModule = module;
extend( env, parentModule.testEnvironment );
delete env.beforeEach;
delete env.afterEach;
@@ -459,17 +410,12 @@ extend( QUnit, {
},
- // DEPRECATED: QUnit.asyncTest() will be removed in QUnit 2.0.
- asyncTest: asyncTest,
-
test: test,
skip: skip,
only: only,
- // DEPRECATED: The functionality of QUnit.start() will be altered in QUnit 2.0.
- // In QUnit 2.0, invoking it will ONLY affect the `QUnit.config.autostart` blocking behavior.
start: function( count ) {
var globalStartAlreadyCalled = globalStartCalled;
@@ -477,7 +423,7 @@ extend( QUnit, {
globalStartCalled = true;
if ( runStarted ) {
- throw new Error( "Called start() outside of a test context while already started" );
+ throw new Error( "Called start() while test already started running" );
} else if ( globalStartAlreadyCalled || count > 1 ) {
throw new Error( "Called start() outside of a test context too many times" );
} else if ( config.autostart ) {
@@ -490,53 +436,14 @@ extend( QUnit, {
return;
}
} else {
-
- // If a test is running, adjust its semaphore
- config.current.semaphore -= count || 1;
-
- // If semaphore is non-numeric, throw error
- if ( isNaN( config.current.semaphore ) ) {
- config.current.semaphore = 0;
-
- QUnit.pushFailure(
- "Called start() with a non-numeric decrement.",
- sourceFromStacktrace( 2 )
- );
- return;
- }
-
- // Don't start until equal number of stop-calls
- if ( config.current.semaphore > 0 ) {
- return;
- }
-
- // Throw an Error if start is called more often than stop
- if ( config.current.semaphore < 0 ) {
- config.current.semaphore = 0;
-
- QUnit.pushFailure(
- "Called start() while already started (test's semaphore was 0 already)",
- sourceFromStacktrace( 2 )
- );
- return;
- }
+ throw new Error(
+ "QUnit.start cannot be called inside a test context. This feature is removed in " +
+ "QUnit 2.0. For async tests, use QUnit.test() with assert.async() instead.\n" +
+ "Details in our upgrade guide at https://qunitjs.com/upgrade-guide-2.x/"
+ );
}
- resumeProcessing();
- },
-
- // DEPRECATED: QUnit.stop() will be removed in QUnit 2.0.
- stop: function( count ) {
-
- // If there isn't a test running, don't allow QUnit.stop() to be called
- if ( !config.current ) {
- throw new Error( "Called stop() outside of a test context" );
- }
-
- // If a test is running, adjust its semaphore
- config.current.semaphore += count || 1;
-
- pauseProcessing();
+ scheduleBegin();
},
config: config,
@@ -560,10 +467,12 @@ extend( QUnit, {
filter: ""
}, true );
- config.blocking = false;
+ if ( !runStarted ) {
+ config.blocking = false;
- if ( config.autostart ) {
- resumeProcessing();
+ if ( config.autostart ) {
+ scheduleBegin();
+ }
}
},
@@ -575,6 +484,20 @@ extend( QUnit, {
registerLoggingCallbacks( QUnit );
+function scheduleBegin() {
+
+ runStarted = true;
+
+ // Add a slight delay to allow definition of more modules and tests.
+ if ( defined.setTimeout ) {
+ setTimeout( function() {
+ begin();
+ }, 13 );
+ } else {
+ begin();
+ }
+}
+
function begin() {
var i, l,
modulesLog = [];
@@ -585,8 +508,6 @@ function begin() {
// Record the time of the test run's beginning
config.started = now();
- verifyLoggingCallbacks();
-
// Delete the loose unnamed module if unused.
if ( config.modules[ 0 ].name === "" && config.modules[ 0 ].tests.length === 0 ) {
config.modules.shift();
@@ -638,47 +559,10 @@ function process( last ) {
}
}
-function pauseProcessing() {
- config.blocking = true;
-
- if ( config.testTimeout && defined.setTimeout ) {
- clearTimeout( config.timeout );
- config.timeout = setTimeout( function() {
- if ( config.current ) {
- config.current.semaphore = 0;
- QUnit.pushFailure( "Test timed out", sourceFromStacktrace( 2 ) );
- } else {
- throw new Error( "Test timed out" );
- }
- resumeProcessing();
- }, config.testTimeout );
- }
-}
-
-function resumeProcessing() {
- runStarted = true;
-
- // A slight delay to allow this iteration of the event loop to finish (more assertions, etc.)
- if ( defined.setTimeout ) {
- setTimeout( function() {
- if ( config.current && config.current.semaphore > 0 ) {
- return;
- }
- if ( config.timeout ) {
- clearTimeout( config.timeout );
- }
-
- begin();
- }, 13 );
- } else {
- begin();
- }
-}
-
function done() {
var runtime, passed;
- config.autorun = true;
+ autorun = true;
// Log the last module results
if ( config.previousModule ) {
@@ -714,15 +598,16 @@ function setHook( module, hookName ) {
};
}
-var focused = false;
-var priorityCount = 0;
-var unitSampler;
+var unitSampler,
+ focused = false,
+ priorityCount = 0;
function Test( settings ) {
var i, l;
++Test.count;
+ this.expected = null;
extend( this, settings );
this.assertions = [];
this.semaphore = 0;
@@ -791,8 +676,10 @@ Test.prototype = {
config.current = this;
if ( this.module.testEnvironment ) {
+ delete this.module.testEnvironment.before;
delete this.module.testEnvironment.beforeEach;
delete this.module.testEnvironment.afterEach;
+ delete this.module.testEnvironment.after;
}
this.testEnvironment = extend( {}, this.module.testEnvironment );
@@ -813,10 +700,6 @@ Test.prototype = {
config.current = this;
- if ( this.async ) {
- QUnit.stop();
- }
-
this.callbackStarted = now();
if ( config.notrycatch ) {
@@ -835,7 +718,7 @@ Test.prototype = {
// Restart the tests if they're blocking
if ( config.blocking ) {
- QUnit.start();
+ internalRecover( this );
}
}
@@ -849,10 +732,22 @@ Test.prototype = {
checkPollution();
},
- queueHook: function( hook, hookName ) {
+ queueHook: function( hook, hookName, hookOwner ) {
var promise,
test = this;
return function runHook() {
+ if ( hookName === "before" ) {
+ if ( hookOwner.testsRun !== 0 ) {
+ return;
+ }
+
+ test.preserveEnvironment = true;
+ }
+
+ if ( hookName === "after" && hookOwner.testsRun !== numberOfTests( hookOwner ) - 1 ) {
+ return;
+ }
+
config.current = test;
if ( config.notrycatch ) {
callHook();
@@ -882,7 +777,7 @@ Test.prototype = {
}
if ( module.testEnvironment &&
QUnit.objectType( module.testEnvironment[ handler ] ) === "function" ) {
- hooks.push( test.queueHook( module.testEnvironment[ handler ], handler ) );
+ hooks.push( test.queueHook( module.testEnvironment[ handler ], handler, module ) );
}
}
@@ -907,9 +802,11 @@ Test.prototype = {
}
var i,
+ skipped = !!this.skip,
bad = 0;
this.runtime = now() - this.started;
+
config.stats.all += this.assertions.length;
config.moduleStats.all += this.assertions.length;
@@ -921,34 +818,34 @@ Test.prototype = {
}
}
+ notifyTestsRan( this.module );
runLoggingCallbacks( "testDone", {
name: this.testName,
module: this.module.name,
- skipped: !!this.skip,
+ skipped: skipped,
failed: bad,
passed: this.assertions.length - bad,
total: this.assertions.length,
- runtime: this.runtime,
+ runtime: skipped ? 0 : this.runtime,
// HTML Reporter use
assertions: this.assertions,
testId: this.testId,
// Source of Test
- source: this.stack,
-
- // DEPRECATED: this property will be removed in 2.0.0, use runtime instead
- duration: this.runtime
+ source: this.stack
} );
- // QUnit.reset() is deprecated and will be replaced for a new
- // fixture reset function on QUnit 2.0/2.1.
- // It's still called here for backwards compatibility handling
- QUnit.reset();
-
config.current = undefined;
},
+ preserveTestEnvironment: function() {
+ if ( this.preserveEnvironment ) {
+ this.module.testEnvironment = this.testEnvironment;
+ this.testEnvironment = extend( {}, this.module.testEnvironment );
+ }
+ },
+
queue: function() {
var priority,
test = this;
@@ -965,16 +862,25 @@ Test.prototype = {
test.before();
},
+ test.hooks( "before" ),
+
+ function() {
+ test.preserveTestEnvironment();
+ },
+
test.hooks( "beforeEach" ),
+
function() {
test.run();
},
test.hooks( "afterEach" ).reverse(),
+ test.hooks( "after" ).reverse(),
function() {
test.after();
},
+
function() {
test.finish();
}
@@ -1049,15 +955,15 @@ Test.prototype = {
},
resolvePromise: function( promise, phase ) {
- var then, message,
+ var then, resume, message,
test = this;
if ( promise != null ) {
then = promise.then;
if ( QUnit.objectType( then ) === "function" ) {
- QUnit.stop();
+ resume = internalStop( test );
then.call(
promise,
- function() { QUnit.start(); },
+ function() { resume(); },
function( error ) {
message = "Promise rejected " +
( !phase ? "during" : phase.replace( /Each$/, "" ) ) +
@@ -1068,7 +974,7 @@ Test.prototype = {
saveGlobal();
// Unblock
- QUnit.start();
+ resume();
}
);
}
@@ -1153,28 +1059,6 @@ Test.prototype = {
}
};
-// Resets the test setup. Useful for tests that modify the DOM.
-/*
-DEPRECATED: Use multiple tests instead of resetting inside a test.
-Use testStart or testDone for custom cleanup.
-This method will throw an error in 2.0, and will be removed in 2.1
-*/
-QUnit.reset = function() {
-
- // Return on non-browser environments
- // This is necessary to not break on node tests
- if ( !defined.document ) {
- return;
- }
-
- var fixture = defined.document && document.getElementById &&
- document.getElementById( "qunit-fixture" );
-
- if ( fixture ) {
- fixture.innerHTML = config.fixture;
- }
-};
-
QUnit.pushFailure = function() {
if ( !QUnit.config.current ) {
throw new Error( "pushFailure() assertion outside test context, in " +
@@ -1236,7 +1120,7 @@ function synchronize( callback, priority, seed ) {
config.queue.push( callback );
}
- if ( config.autorun && !config.blocking ) {
+ if ( autorun && !config.blocking ) {
process( last );
}
}
@@ -1295,31 +1179,14 @@ function checkPollution() {
}
}
-// Will be exposed as QUnit.asyncTest
-function asyncTest( testName, expected, callback ) {
- if ( arguments.length === 2 ) {
- callback = expected;
- expected = null;
- }
-
- QUnit.test( testName, expected, callback, true );
-}
-
// Will be exposed as QUnit.test
-function test( testName, expected, callback, async ) {
+function test( testName, callback ) {
if ( focused ) { return; }
var newTest;
- if ( arguments.length === 2 ) {
- callback = expected;
- expected = null;
- }
-
newTest = new Test( {
testName: testName,
- expected: expected,
- async: async,
callback: callback
} );
@@ -1339,7 +1206,7 @@ function skip( testName ) {
}
// Will be exposed as QUnit.only
-function only( testName, expected, callback, async ) {
+function only( testName, callback ) {
var newTest;
if ( focused ) { return; }
@@ -1347,21 +1214,113 @@ function only( testName, expected, callback, async ) {
QUnit.config.queue.length = 0;
focused = true;
- if ( arguments.length === 2 ) {
- callback = expected;
- expected = null;
- }
-
newTest = new Test( {
testName: testName,
- expected: expected,
- async: async,
callback: callback
} );
newTest.queue();
}
+// Put a hold on processing and return a function that will release it.
+function internalStop( test ) {
+ var released = false;
+
+ test.semaphore += 1;
+ config.blocking = true;
+
+ // Set a recovery timeout, if so configured.
+ if ( config.testTimeout && defined.setTimeout ) {
+ clearTimeout( config.timeout );
+ config.timeout = setTimeout( function() {
+ QUnit.pushFailure( "Test timed out", sourceFromStacktrace( 2 ) );
+ internalRecover( test );
+ }, config.testTimeout );
+ }
+
+ return function resume() {
+ if ( released ) {
+ return;
+ }
+
+ released = true;
+ test.semaphore -= 1;
+ internalStart( test );
+ };
+}
+
+// Forcefully release all processing holds.
+function internalRecover( test ) {
+ test.semaphore = 0;
+ internalStart( test );
+}
+
+// Release a processing hold, scheduling a resumption attempt if no holds remain.
+function internalStart( test ) {
+
+ // If semaphore is non-numeric, throw error
+ if ( isNaN( test.semaphore ) ) {
+ test.semaphore = 0;
+
+ QUnit.pushFailure(
+ "Invalid value on test.semaphore",
+ sourceFromStacktrace( 2 )
+ );
+ return;
+ }
+
+ // Don't start until equal number of stop-calls
+ if ( test.semaphore > 0 ) {
+ return;
+ }
+
+ // Throw an Error if start is called more often than stop
+ if ( test.semaphore < 0 ) {
+ test.semaphore = 0;
+
+ QUnit.pushFailure(
+ "Tried to restart test while already started (test's semaphore was 0 already)",
+ sourceFromStacktrace( 2 )
+ );
+ return;
+ }
+
+ // Add a slight delay to allow more assertions etc.
+ if ( defined.setTimeout ) {
+ if ( config.timeout ) {
+ clearTimeout( config.timeout );
+ }
+ config.timeout = setTimeout( function() {
+ if ( test.semaphore > 0 ) {
+ return;
+ }
+
+ if ( config.timeout ) {
+ clearTimeout( config.timeout );
+ }
+
+ begin();
+ }, 13 );
+ } else {
+ begin();
+ }
+}
+
+function numberOfTests( module ) {
+ var count = module.tests.length;
+ while ( module = module.childModule ) {
+ count += module.tests.length;
+ }
+ return count;
+}
+
+function notifyTestsRan( module ) {
+ module.testsRun++;
+ while ( module = module.parentModule ) {
+ module.testsRun++;
+ }
+}
+
function Assert( testContext ) {
this.test = testContext;
}
@@ -1379,10 +1338,10 @@ QUnit.assert = Assert.prototype = {
}
},
- // Increment this Test's semaphore counter, then return a function that
- // decrements that counter a maximum of once.
+ // Put a hold on processing and return a function that will release it a maximum of once.
async: function( count ) {
- var test = this.test,
+ var resume,
+ test = this.test,
popped = false,
acceptCallCount = count;
@@ -1390,9 +1349,8 @@ QUnit.assert = Assert.prototype = {
acceptCallCount = 1;
}
- test.semaphore += 1;
test.usedAsync = true;
- pauseProcessing();
+ resume = internalStop( test );
return function done() {
@@ -1406,9 +1364,8 @@ QUnit.assert = Assert.prototype = {
return;
}
- test.semaphore -= 1;
popped = true;
- resumeProcessing();
+ resume();
};
},
@@ -1565,9 +1522,17 @@ QUnit.assert = Assert.prototype = {
currentTest = ( this instanceof Assert && this.test ) || QUnit.config.current;
// 'expected' is optional unless doing string comparison
- if ( message == null && typeof expected === "string" ) {
- message = expected;
- expected = null;
+ if ( QUnit.objectType( expected ) === "string" ) {
+ if ( message == null ) {
+ message = expected;
+ expected = null;
+ } else {
+ throw new Error(
+ "throws/raises does not accept a string value for the expected argument.\n" +
+ "Use a non-string object value (e.g. regExp) instead if it's necessary." +
+ "Details in our upgrade guide at https://qunitjs.com/upgrade-guide-2.x/"
+ );
+ }
}
currentTest.ignoreGlobalErrors = true;
@@ -1590,10 +1555,6 @@ QUnit.assert = Assert.prototype = {
} else if ( expectedType === "regexp" ) {
ok = expected.test( errorString( actual ) );
- // Expected is a string
- } else if ( expectedType === "string" ) {
- ok = expected === errorString( actual );
-
// Expected is a constructor, maybe an Error constructor
} else if ( expectedType === "function" && actual instanceof expected ) {
ok = true;
@@ -1947,6 +1908,21 @@ QUnit.dump = ( function() {
return join( "[", ret, "]" );
}
+ function isArray( obj ) {
+ return (
+
+ //Native Arrays
+ toString.call( obj ) === "[object Array]" ||
+
+ // NodeList objects
+ ( typeof obj.length === "number" && obj.item !== undefined ) &&
+ ( obj.length ?
+ obj.item( 0 ) === obj[ 0 ] :
+ ( obj.item( 0 ) === null && obj[ 0 ] === undefined )
+ )
+ );
+ }
+
var reName = /^function (\w+)/,
dump = {
@@ -1974,6 +1950,7 @@ QUnit.dump = ( function() {
},
typeOf: function( obj ) {
var type;
+
if ( obj === null ) {
type = "null";
} else if ( typeof obj === "undefined" ) {
@@ -1992,16 +1969,7 @@ QUnit.dump = ( function() {
type = "document";
} else if ( obj.nodeType ) {
type = "node";
- } else if (
-
- // Native arrays
- toString.call( obj ) === "[object Array]" ||
-
- // NodeList objects
- ( typeof obj.length === "number" && obj.item !== undefined &&
- ( obj.length ? obj.item( 0 ) === obj[ 0 ] : ( obj.item( 0 ) === null &&
- obj[ 0 ] === undefined ) ) )
- ) {
+ } else if ( isArray( obj ) ) {
type = "array";
} else if ( obj.constructor === Error.prototype.constructor ) {
type = "error";
@@ -2163,7 +2131,10 @@ QUnit.dump = ( function() {
date: quote,
regexp: literal,
number: literal,
- "boolean": literal
+ "boolean": literal,
+ symbol: function( sym ) {
+ return sym.toString();
+ }
},
// If true, entities are escaped ( <, >, \t, space and \n )
@@ -2182,54 +2153,72 @@ QUnit.dump = ( function() {
// Back compat
QUnit.jsDump = QUnit.dump;
-// Deprecated
-// Extend assert methods to QUnit for Backwards compatibility
-( function() {
- var i,
- assertions = Assert.prototype;
+function applyDeprecated( name ) {
+ return function() {
+ throw new Error(
+ name + " is removed in QUnit 2.0.\n" +
+ "Details in our upgrade guide at https://qunitjs.com/upgrade-guide-2.x/"
+ );
+ };
+}
- function applyCurrent( current ) {
- return function() {
- var assert = new Assert( QUnit.config.current );
- current.apply( assert, arguments );
- };
- }
+Object.keys( Assert.prototype ).forEach( function( key ) {
+ QUnit[ key ] = applyDeprecated( "`QUnit." + key + "`" );
+} );
- for ( i in assertions ) {
- QUnit[ i ] = applyCurrent( assertions[ i ] );
- }
-}() );
+QUnit.asyncTest = function() {
+ throw new Error(
+ "asyncTest is removed in QUnit 2.0, use QUnit.test() with assert.async() instead.\n" +
+ "Details in our upgrade guide at https://qunitjs.com/upgrade-guide-2.x/"
+ );
+};
+
+QUnit.stop = function() {
+ throw new Error(
+ "QUnit.stop is removed in QUnit 2.0, use QUnit.test() with assert.async() instead.\n" +
+ "Details in our upgrade guide at https://qunitjs.com/upgrade-guide-2.x/"
+ );
+};
+
+function resetThrower() {
+ throw new Error(
+ "QUnit.reset is removed in QUnit 2.0 without replacement.\n" +
+ "Details in our upgrade guide at https://qunitjs.com/upgrade-guide-2.x/"
+ );
+}
+
+Object.defineProperty( QUnit, "reset", {
+ get: function() {
+ return resetThrower;
+ },
+ set: resetThrower
+} );
-// For browser, export only select globals
if ( defined.document ) {
+ if ( window.QUnit ) {
+ throw new Error( "QUnit has already been defined." );
+ }
- ( function() {
- var i, l,
- keys = [
- "test",
- "module",
- "expect",
- "asyncTest",
- "start",
- "stop",
- "ok",
- "notOk",
- "equal",
- "notEqual",
- "propEqual",
- "notPropEqual",
- "deepEqual",
- "notDeepEqual",
- "strictEqual",
- "notStrictEqual",
- "throws",
- "raises"
- ];
-
- for ( i = 0, l = keys.length; i < l; i++ ) {
- window[ keys[ i ] ] = QUnit[ keys[ i ] ];
- }
- }() );
+ [
+ "test",
+ "module",
+ "expect",
+ "start",
+ "ok",
+ "notOk",
+ "equal",
+ "notEqual",
+ "propEqual",
+ "notPropEqual",
+ "deepEqual",
+ "notDeepEqual",
+ "strictEqual",
+ "notStrictEqual",
+ "throws",
+ "raises"
+ ].forEach( function( key ) {
+ window[ key ] = applyDeprecated( "The global `" + key + "`" );
+ } );
window.QUnit = QUnit;
}
@@ -2261,6 +2250,47 @@ if ( typeof define === "function" && define.amd ) {
( function() {
+if ( typeof window === "undefined" || !window.document ) {
+ return;
+}
+
+var config = QUnit.config,
+ hasOwn = Object.prototype.hasOwnProperty;
+
+// Stores fixture HTML for resetting later
+function storeFixture() {
+
+ // Avoid overwriting user-defined values
+ if ( hasOwn.call( config, "fixture" ) ) {
+ return;
+ }
+
+ var fixture = document.getElementById( "qunit-fixture" );
+ if ( fixture ) {
+ config.fixture = fixture.innerHTML;
+ }
+}
+
+QUnit.begin( storeFixture );
+
+// Resets the fixture DOM element if available.
+function resetFixture() {
+ if ( config.fixture == null ) {
+ return;
+ }
+
+ var fixture = document.getElementById( "qunit-fixture" );
+ if ( fixture ) {
+ fixture.innerHTML = config.fixture;
+ }
+}
+
+QUnit.testStart( resetFixture );
+
+}() );
+
+( function() {
+
// Only interact with URLs via window.location
var location = typeof window !== "undefined" && window.location;
if ( !location ) {
@@ -2338,11 +2368,11 @@ function getUrlParams() {
for ( i = 0; i < length; i++ ) {
if ( params[ i ] ) {
param = params[ i ].split( "=" );
- name = decodeURIComponent( param[ 0 ] );
+ name = decodeQueryParam( param[ 0 ] );
// Allow just a key to turn on a flag, e.g., test.html?noglobals
value = param.length === 1 ||
- decodeURIComponent( param.slice( 1 ).join( "=" ) ) ;
+ decodeQueryParam( param.slice( 1 ).join( "=" ) ) ;
if ( urlParams[ name ] ) {
urlParams[ name ] = [].concat( urlParams[ name ], value );
} else {
@@ -2354,27 +2384,20 @@ function getUrlParams() {
return urlParams;
}
+function decodeQueryParam( param ) {
+ return decodeURIComponent( param.replace( /\+/g, "%20" ) );
+}
+
// Don't load the HTML Reporter on non-browser environments
if ( typeof window === "undefined" || !window.document ) {
return;
}
-// Deprecated QUnit.init - Ref #530
-// Re-initialize the configuration options
QUnit.init = function() {
- var config = QUnit.config;
-
- config.stats = { all: 0, bad: 0 };
- config.moduleStats = { all: 0, bad: 0 };
- config.started = 0;
- config.updateRate = 1000;
- config.blocking = false;
- config.autostart = true;
- config.autorun = false;
- config.filter = "";
- config.queue = [];
-
- appendInterface();
+ throw new Error(
+ "QUnit.init is removed in QUnit 2.0, use QUnit.test() with assert.async() instead.\n" +
+ "Details in our upgrade guide at https://qunitjs.com/upgrade-guide-2.x/"
+ );
};
var config = QUnit.config,
@@ -2397,9 +2420,7 @@ var config = QUnit.config,
},
modulesList = [];
-/**
-* Escape text for attribute or text content.
-*/
+// Escape text for attribute or text content.
function escapeText( s ) {
if ( !s ) {
return "";
@@ -2423,35 +2444,14 @@ function escapeText( s ) {
} );
}
-/**
- * @param {HTMLElement} elem
- * @param {string} type
- * @param {Function} fn
- */
function addEvent( elem, type, fn ) {
- if ( elem.addEventListener ) {
-
- // Standards-based browsers
- elem.addEventListener( type, fn, false );
- } else if ( elem.attachEvent ) {
-
- // Support: IE <9
- elem.attachEvent( "on" + type, function() {
- var event = window.event;
- if ( !event.target ) {
- event.target = event.srcElement || document;
- }
-
- fn.call( elem, event );
- } );
- }
+ elem.addEventListener( type, fn, false );
+}
+
+function removeEvent( elem, type, fn ) {
+ elem.removeEventListener( type, fn, false );
}
-/**
- * @param {Array|NodeList} elems
- * @param {string} type
- * @param {Function} fn
- */
function addEvents( elems, type, fn ) {
var i = elems.length;
while ( i-- ) {
@@ -2493,6 +2493,16 @@ function id( name ) {
return document.getElementById && document.getElementById( name );
}
+function interceptNavigation( ev ) {
+ applyUrlParams();
+
+ if ( ev && ev.preventDefault ) {
+ ev.preventDefault();
+ }
+
+ return false;
+}
+
function getUrlConfigHtml() {
var i, j, val,
escaped, escapedTooltip,
@@ -2515,12 +2525,12 @@ function getUrlConfigHtml() {
escapedTooltip = escapeText( val.tooltip );
if ( !val.value || typeof val.value === "string" ) {
- urlConfigHtml += "";
+ " title='" + escapedTooltip + "' />" + escapeText( val.label ) + "";
} else {
urlConfigHtml += "