From: Evad37 Date: Sat, 2 Feb 2019 05:42:00 +0000 (+0800) Subject: resourceloader: Add getScript() method for loading scripts with callback X-Git-Tag: 1.34.0-rc.0~2714^2 X-Git-Url: http://git.cyclocoop.org/data/%24oldEdit?a=commitdiff_plain;h=3b4a7cbd582ffb6d0fc7f9ec2781fe1cafb2c935;p=lhc%2Fweb%2Fwiklou.git resourceloader: Add getScript() method for loading scripts with callback Provides a friendly wrapper for loading scripts using $.ajax(). Returns a promise when the script dependency -- a single script url -- has been loaded. This matches how mw.loader.load is able to load a script url, and how mw.loader.using will return a promised that is resolved when dependecies are loaded, or rejected if there is an error. Added as a separate function mw.loader.getScript(), rather than adding this functionality to using(), as it is a separate use case, less confusing for users, and there is no shared or duplicated code between loading a script and loading one or more named modules. Bug: T27962 Change-Id: I13be426d03261a2d0c6a1631af94a9f9af58394b --- diff --git a/resources/src/mediawiki.base/mediawiki.base.js b/resources/src/mediawiki.base/mediawiki.base.js index 107ab33fb6..9016c7c274 100644 --- a/resources/src/mediawiki.base/mediawiki.base.js +++ b/resources/src/mediawiki.base/mediawiki.base.js @@ -644,7 +644,7 @@ var deferred = $.Deferred(); // Allow calling with a single dependency as a string - if ( typeof dependencies === 'string' ) { + if ( !Array.isArray( dependencies ) ) { dependencies = [ dependencies ]; } @@ -662,13 +662,42 @@ return deferred.reject( e ).promise(); } - mw.loader.enqueue( dependencies, function () { - deferred.resolve( mw.loader.require ); - }, deferred.reject ); + mw.loader.enqueue( + dependencies, + function () { deferred.resolve( mw.loader.require ); }, + deferred.reject + ); return deferred.promise(); }; + /** + * Load a script by URL. + * + * Example: + * + * mw.loader.getScript( + * 'https://example.org/x-1.0.0.js' + * ) + * .then( function () { + * // Script succeeded. You can use X now. + * }, function ( e ) { + * // Script failed. X is not avaiable + * mw.log.error( e.message ); // => "Failed to load script" + * } ); + * } ); + * + * @member mw.loader + * @param {string} url Script URL + * @return {jQuery.Promise} Resolved when the script is loaded + */ + mw.loader.getScript = function ( url ) { + return $.ajax( url, { dataType: 'script', cache: true } ) + .catch( function () { + throw new Error( 'Failed to load script' ); + } ); + }; + // Alias $j to jQuery for backwards compatibility // @deprecated since 1.23 Use $ or jQuery instead mw.log.deprecate( window, '$j', $, 'Use $ or jQuery instead.' ); diff --git a/tests/qunit/data/mediawiki.loader.getScript.example.js b/tests/qunit/data/mediawiki.loader.getScript.example.js new file mode 100644 index 0000000000..e5e4759d1c --- /dev/null +++ b/tests/qunit/data/mediawiki.loader.getScript.example.js @@ -0,0 +1 @@ +mw.getScriptExampleScriptLoaded = true; diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.loader.test.js b/tests/qunit/suites/resources/mediawiki/mediawiki.loader.test.js index cb028a93a1..8b06bd6e1f 100644 --- a/tests/qunit/suites/resources/mediawiki/mediawiki.loader.test.js +++ b/tests/qunit/suites/resources/mediawiki/mediawiki.loader.test.js @@ -24,6 +24,7 @@ // exposed for cross-file mocks. delete mw.loader.testCallback; delete mw.loader.testFail; + delete mw.getScriptExampleScriptLoaded; } } ) ); @@ -1097,4 +1098,24 @@ } ); } ); + QUnit.test( '.getScript() - success', function ( assert ) { + var scriptUrl = QUnit.fixurl( + mw.config.get( 'wgScriptPath' ) + '/tests/qunit/data/mediawiki.loader.getScript.example.js' + ); + + return mw.loader.getScript( scriptUrl ).then( + function () { + assert.strictEqual( mw.getScriptExampleScriptLoaded, true, 'Data attached to a global object is available' ); + } + ); + } ); + + QUnit.test( '.getScript() - failure', function ( assert ) { + assert.rejects( + mw.loader.getScript( 'https://example.test/not-found' ), + /Failed to load script/, + 'Descriptive error message' + ); + } ); + }() );