mw.util.addPortletLink: Check length before access array index
authorumherirrender <umherirrender_de.wp@web.de>
Sun, 10 Nov 2013 17:09:35 +0000 (18:09 +0100)
committerKrinkle <krinklemail@gmail.com>
Wed, 13 Nov 2013 17:45:13 +0000 (17:45 +0000)
This avoids "TypeError: Cannot read property 'parentNode' of undefined",
when the given nextNode is a jQuery object without elements.

Adding a test for this case and for the case of unknown id, which
internally results in a empty jQuery object.

Bug: 56770
Change-Id: I56de9e6bc15449e294b538743baf0f0c1cc0abb1

RELEASE-NOTES-1.22
resources/mediawiki/mediawiki.util.js
tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js

index 6826478..7ad29ab 100644 (file)
@@ -354,6 +354,7 @@ production.
 * (bug 55818) BREAKING CHANGE: Removed undocumented 'Debug' hook in wfDebug.
   This resolves an infinite loop when using $wgDebugFunctionEntry = true.
 * (bug 56707) Correct tooltip of "Next n results" on query special pages.
+* (bug 56770) mw.util.addPortletLink: Check length before access array index.
 
 === API changes in 1.22 ===
 * (bug 25553) The JSON output formatter now leaves forward slashes unescaped
index cfc717f..a057cce 100644 (file)
                                        // nextnode is a DOM element (was the only option before MW 1.17, in wikibits.js)
                                        // or nextnode is a CSS selector for jQuery
                                        nextnode = $ul.find( nextnode );
-                               } else if ( !nextnode.jquery || nextnode[0].parentNode !== $ul[0] ) {
+                               } else if ( !nextnode.jquery || ( nextnode.length && nextnode[0].parentNode !== $ul[0] ) ) {
                                        // Fallback
                                        $ul.append( $item );
                                        return $item[0];
index 2be8044..9216f0a 100644 (file)
         * Previously, test elements where invisible to the selector since only
         * one element can have a given id.
         */
-       QUnit.test( 'addPortletLink', 11, function ( assert ) {
-               var pTestTb, pCustom, vectorTabs, tbRL, cuQuux, $cuQuux, tbMW, $tbMW, tbRLDM, caFoo, addedAfter;
+       QUnit.test( 'addPortletLink', 13, function ( assert ) {
+               var pTestTb, pCustom, vectorTabs, tbRL, cuQuux, $cuQuux, tbMW, $tbMW, tbRLDM, caFoo,
+                       addedAfter, tbRLDMnonexistentid, tbRLDMemptyjquery;
 
                pTestTb = '\
                <div class="portlet" id="p-test-tb">\
 
                addedAfter = mw.util.addPortletLink( 'p-test-tb', '#', 'After foo', 'post-foo', 'After foo', null, $( tbRL ) );
                assert.strictEqual( $( addedAfter ).next()[0], tbRL, 'Link is in the correct position (by passing a jQuery object as nextnode)' );
+
+               // test case - nonexistent id as next node
+               tbRLDMnonexistentid = mw.util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/RL/DM',
+                       'Default modules', 't-rldm-nonexistent', 'List of all default modules ', 'd', '#t-rl-nonexistent' );
+
+               assert.equal( tbRLDMnonexistentid, $( '#p-test-tb li:last' )[0], 'Nonexistent id as nextnode adds the portlet at end' );
+
+               // test case - empty jquery object as next node
+               tbRLDMemptyjquery = mw.util.addPortletLink( 'p-test-tb', '//mediawiki.org/wiki/RL/DM',
+                       'Default modules', 't-rldm-empty-jquery', 'List of all default modules ', 'd', $( '#t-rl-nonexistent' ) );
+
+               assert.equal( tbRLDMemptyjquery, $( '#p-test-tb li:last' )[0], 'Empty jquery as nextnode adds the portlet at end' );
        } );
 
        QUnit.test( 'jsMessage', 1, function ( assert ) {