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 |