| Index: trunk/phase3/includes/OutputPage.php |
| — | — | @@ -2695,9 +2695,7 @@ |
| 2696 | 2696 | if ( $modules ) { |
| 2697 | 2697 | $scripts .= Html::inlineScript( |
| 2698 | 2698 | ResourceLoader::makeLoaderConditionalScript( |
| 2699 | | - "mw.loader.setBlocking( true );\n" . |
| 2700 | | - Xml::encodeJsCall( 'mw.loader.load', array( $modules ) ) . |
| 2701 | | - "\nmw.loader.setBlocking( false );" |
| | 2699 | + Xml::encodeJsCall( 'mw.loader.load', array( $modules, null, true ) ) |
| 2702 | 2700 | ) |
| 2703 | 2701 | ); |
| 2704 | 2702 | } |
| Index: trunk/phase3/resources/mediawiki/mediawiki.js |
| — | — | @@ -364,9 +364,6 @@ |
| 365 | 365 | jobs = [], |
| 366 | 366 | // Flag indicating that document ready has occured |
| 367 | 367 | ready = false, |
| 368 | | - // Whether we should try to load scripts in a blocking way |
| 369 | | - // Set with setBlocking() |
| 370 | | - blocking = false, |
| 371 | 368 | // Selector cache for the marker element. Use getMarker() to get/use the marker! |
| 372 | 369 | $marker = null; |
| 373 | 370 | |
| — | — | @@ -549,7 +546,7 @@ |
| 550 | 547 | var j, r; |
| 551 | 548 | |
| 552 | 549 | try { |
| 553 | | - // Run jobs who's dependencies have just been met |
| | 550 | + // Run jobs whose dependencies have just been met |
| 554 | 551 | for ( j = 0; j < jobs.length; j += 1 ) { |
| 555 | 552 | if ( compare( |
| 556 | 553 | filter( 'ready', jobs[j].dependencies ), |
| — | — | @@ -562,7 +559,7 @@ |
| 563 | 560 | j -= 1; |
| 564 | 561 | } |
| 565 | 562 | } |
| 566 | | - // Execute modules who's dependencies have just been met |
| | 563 | + // Execute modules whose dependencies have just been met |
| 567 | 564 | for ( r in registry ) { |
| 568 | 565 | if ( registry[r].state === 'loaded' ) { |
| 569 | 566 | if ( compare( |
| — | — | @@ -594,7 +591,7 @@ |
| 595 | 592 | * @param src String: URL to script, will be used as the src attribute in the script tag |
| 596 | 593 | * @param callback Function: Optional callback which will be run when the script is done |
| 597 | 594 | */ |
| 598 | | - function addScript( src, callback ) { |
| | 595 | + function addScript( src, callback, blocking ) { |
| 599 | 596 | var done = false, script, head; |
| 600 | 597 | if ( ready || !blocking ) { |
| 601 | 598 | // jQuery's getScript method is NOT better than doing this the old-fashioned way |
| — | — | @@ -710,7 +707,7 @@ |
| 711 | 708 | callback(); |
| 712 | 709 | } |
| 713 | 710 | }; |
| 714 | | - nestedAddScript = function ( arr, callback, i ) { |
| | 711 | + nestedAddScript = function ( arr, callback, blocking, i ) { |
| 715 | 712 | // Recursively call addScript() in its own callback |
| 716 | 713 | // for each element of arr. |
| 717 | 714 | if ( i >= arr.length ) { |
| — | — | @@ -720,13 +717,13 @@ |
| 721 | 718 | } |
| 722 | 719 | |
| 723 | 720 | addScript( arr[i], function() { |
| 724 | | - nestedAddScript( arr, callback, i + 1 ); |
| 725 | | - } ); |
| | 721 | + nestedAddScript( arr, callback, blocking, i + 1 ); |
| | 722 | + }, blocking ); |
| 726 | 723 | }; |
| 727 | 724 | |
| 728 | 725 | if ( $.isArray( script ) ) { |
| 729 | 726 | registry[module].state = 'loading'; |
| 730 | | - nestedAddScript( script, markModuleReady, 0 ); |
| | 727 | + nestedAddScript( script, markModuleReady, registry[module].blocking, 0 ); |
| 731 | 728 | } else if ( $.isFunction( script ) ) { |
| 732 | 729 | script( $ ); |
| 733 | 730 | markModuleReady(); |
| — | — | @@ -749,8 +746,10 @@ |
| 750 | 747 | * @param dependencies string module name or array of string module names |
| 751 | 748 | * @param ready function callback to execute when all dependencies are ready |
| 752 | 749 | * @param error function callback to execute when any dependency fails |
| | 750 | + * @param blocking (optional) If true, load modules in a blocking fashion if |
| | 751 | + * document ready has not yet occurred |
| 753 | 752 | */ |
| 754 | | - function request( dependencies, ready, error ) { |
| | 753 | + function request( dependencies, ready, error, blocking ) { |
| 755 | 754 | var regItemDeps, regItemDepLen, n; |
| 756 | 755 | |
| 757 | 756 | // Allow calling by single module name |
| — | — | @@ -782,6 +781,10 @@ |
| 783 | 782 | for ( n = 0; n < dependencies.length; n += 1 ) { |
| 784 | 783 | if ( $.inArray( dependencies[n], queue ) === -1 ) { |
| 785 | 784 | queue[queue.length] = dependencies[n]; |
| | 785 | + if ( blocking ) { |
| | 786 | + // Mark this module as blocking in the registry |
| | 787 | + registry[dependencies[n]].blocking = true; |
| | 788 | + } |
| 786 | 789 | } |
| 787 | 790 | } |
| 788 | 791 | // Work the queue |
| — | — | @@ -821,8 +824,9 @@ |
| 822 | 825 | * @param moduleMap {Object}: Module map, see buildModulesString() |
| 823 | 826 | * @param currReqBase {Object}: Object with other parameters (other than 'modules') to use in the request |
| 824 | 827 | * @param sourceLoadScript {String}: URL of load.php |
| | 828 | + * @param blocking {Boolean}: If true, use a blocking request if document ready has not yet occurred |
| 825 | 829 | */ |
| 826 | | - function doRequest( moduleMap, currReqBase, sourceLoadScript ) { |
| | 830 | + function doRequest( moduleMap, currReqBase, sourceLoadScript, blocking ) { |
| 827 | 831 | var request = $.extend( |
| 828 | 832 | { 'modules': buildModulesString( moduleMap ) }, |
| 829 | 833 | currReqBase |
| — | — | @@ -830,7 +834,7 @@ |
| 831 | 835 | request = sortQuery( request ); |
| 832 | 836 | // Asynchronously append a script tag to the end of the body |
| 833 | 837 | // Append &* to avoid triggering the IE6 extension check |
| 834 | | - addScript( sourceLoadScript + '?' + $.param( request ) + '&*' ); |
| | 838 | + addScript( sourceLoadScript + '?' + $.param( request ) + '&*', null, blocking ); |
| 835 | 839 | } |
| 836 | 840 | |
| 837 | 841 | /* Public Methods */ |
| — | — | @@ -842,7 +846,7 @@ |
| 843 | 847 | var reqBase, splits, maxQueryLength, q, b, bSource, bGroup, bSourceGroup, |
| 844 | 848 | source, group, g, i, modules, maxVersion, sourceLoadScript, |
| 845 | 849 | currReqBase, currReqBaseLength, moduleMap, l, |
| 846 | | - lastDotIndex, prefix, suffix, bytesAdded; |
| | 850 | + lastDotIndex, prefix, suffix, bytesAdded, blocking; |
| 847 | 851 | |
| 848 | 852 | // Build a list of request parameters common to all requests. |
| 849 | 853 | reqBase = { |
| — | — | @@ -919,7 +923,7 @@ |
| 920 | 924 | |
| 921 | 925 | currReqBase = $.extend( { 'version': formatVersionNumber( maxVersion ) }, reqBase ); |
| 922 | 926 | currReqBaseLength = $.param( currReqBase ).length; |
| 923 | | - moduleMap = {}; |
| | 927 | + blocking = false; |
| 924 | 928 | // We may need to split up the request to honor the query string length limit, |
| 925 | 929 | // so build it piece by piece. |
| 926 | 930 | l = currReqBaseLength + 9; // '&modules='.length == 9 |
| — | — | @@ -941,19 +945,26 @@ |
| 942 | 946 | if ( maxQueryLength > 0 && !$.isEmptyObject( moduleMap ) && l + bytesAdded > maxQueryLength ) { |
| 943 | 947 | // This request would become too long, create a new one |
| 944 | 948 | // and fire off the old one |
| 945 | | - doRequest( moduleMap, currReqBase, sourceLoadScript ); |
| | 949 | + doRequest( moduleMap, currReqBase, sourceLoadScript, blocking ); |
| 946 | 950 | moduleMap = {}; |
| | 951 | + blocking = false; |
| 947 | 952 | l = currReqBaseLength + 9; |
| 948 | 953 | } |
| 949 | 954 | if ( moduleMap[prefix] === undefined ) { |
| 950 | 955 | moduleMap[prefix] = []; |
| 951 | 956 | } |
| 952 | 957 | moduleMap[prefix].push( suffix ); |
| | 958 | + if ( registry[modules[i]].blocking ) { |
| | 959 | + // If this module is blocking, make the entire request blocking |
| | 960 | + // This is slightly suboptimal, but in practice mixing of blocking |
| | 961 | + // and non-blocking modules will only occur in debug mode. |
| | 962 | + blocking = true; |
| | 963 | + } |
| 953 | 964 | l += bytesAdded; |
| 954 | 965 | } |
| 955 | 966 | // If there's anything left in moduleMap, request that too |
| 956 | 967 | if ( !$.isEmptyObject( moduleMap ) ) { |
| 957 | | - doRequest( moduleMap, currReqBase, sourceLoadScript ); |
| | 968 | + doRequest( moduleMap, currReqBase, sourceLoadScript, blocking ); |
| 958 | 969 | } |
| 959 | 970 | } |
| 960 | 971 | } |
| — | — | @@ -1135,8 +1146,10 @@ |
| 1136 | 1147 | * @param type {String} mime-type to use if calling with a URL of an |
| 1137 | 1148 | * external script or style; acceptable values are "text/css" and |
| 1138 | 1149 | * "text/javascript"; if no type is provided, text/javascript is assumed. |
| | 1150 | + * @param blocking {Boolean} (optional) If true, load modules in a blocking |
| | 1151 | + * fashion if document ready has not yet occurred |
| 1139 | 1152 | */ |
| 1140 | | - load: function ( modules, type ) { |
| | 1153 | + load: function ( modules, type, blocking ) { |
| 1141 | 1154 | var filtered, m; |
| 1142 | 1155 | |
| 1143 | 1156 | // Validate input |
| — | — | @@ -1155,7 +1168,7 @@ |
| 1156 | 1169 | } ) ); |
| 1157 | 1170 | return; |
| 1158 | 1171 | } else if ( type === 'text/javascript' || type === undefined ) { |
| 1159 | | - addScript( modules ); |
| | 1172 | + addScript( modules, null, blocking ); |
| 1160 | 1173 | return; |
| 1161 | 1174 | } |
| 1162 | 1175 | // Unknown type |
| — | — | @@ -1188,7 +1201,7 @@ |
| 1189 | 1202 | } |
| 1190 | 1203 | // Since some modules are not yet ready, queue up a request |
| 1191 | 1204 | else { |
| 1192 | | - request( filtered ); |
| | 1205 | + request( filtered, null, null, blocking ); |
| 1193 | 1206 | return; |
| 1194 | 1207 | } |
| 1195 | 1208 | }, |
| — | — | @@ -1254,18 +1267,6 @@ |
| 1255 | 1268 | return key; |
| 1256 | 1269 | } ); |
| 1257 | 1270 | }, |
| 1258 | | - |
| 1259 | | - /** |
| 1260 | | - * Enable or disable blocking. If blocking is enabled and |
| 1261 | | - * document ready has not yet occurred, scripts will be loaded |
| 1262 | | - * in a blocking way (using document.write) rather than |
| 1263 | | - * asynchronously using DOM manipulation |
| 1264 | | - * |
| 1265 | | - * @param b {Boolean} True to enable blocking, false to disable it |
| 1266 | | - */ |
| 1267 | | - setBlocking: function( b ) { |
| 1268 | | - blocking = b; |
| 1269 | | - }, |
| 1270 | 1271 | |
| 1271 | 1272 | /** |
| 1272 | 1273 | * For backwards-compatibility with Squid-cached pages. Loads mw.user |