MediaWiki fundraising/REL1_35
ResourceLoaderStartUpModule.php
Go to the documentation of this file.
1<?php
44 protected $targets = [ 'desktop', 'mobile' ];
45
46 private $groupIds = [
47 // These reserved numbers MUST start at 0 and not skip any. These are preset
48 // for forward compatibility so that they can be safely referenced by mediawiki.js,
49 // even when the code is cached and the order of registrations (and implicit
50 // group ids) changes between versions of the software.
51 'user' => 0,
52 'private' => 1,
53 ];
54
64 protected static function getImplicitDependencies(
65 array $registryData,
66 string $moduleName,
67 array $handled = []
68 ) : array {
69 static $dependencyCache = [];
70
71 // No modules will be added or changed server-side after this point,
72 // so we can safely cache parts of the tree for re-use.
73 if ( !isset( $dependencyCache[$moduleName] ) ) {
74 if ( !isset( $registryData[$moduleName] ) ) {
75 // Unknown module names are allowed here, this is only an optimisation.
76 // Checks for illegal and unknown dependencies happen as PHPUnit structure tests,
77 // and also client-side at run-time.
78 $flat = [];
79 } else {
80 $data = $registryData[$moduleName];
81 $flat = $data['dependencies'];
82
83 // Prevent recursion
84 $handled[] = $moduleName;
85 foreach ( $data['dependencies'] as $dependency ) {
86 if ( in_array( $dependency, $handled, true ) ) {
87 // If we encounter a circular dependency, then stop the optimiser and leave the
88 // original dependencies array unmodified. Circular dependencies are not
89 // supported in ResourceLoader. Awareness of them exists here so that we can
90 // optimise the registry when it isn't broken, and otherwise transport the
91 // registry unchanged. The client will handle this further.
93 } else {
94 // Recursively add the dependencies of the dependencies
95 $flat = array_merge(
96 $flat,
97 self::getImplicitDependencies( $registryData, $dependency, $handled )
98 );
99 }
100 }
101 }
102
103 $dependencyCache[$moduleName] = $flat;
104 }
105
106 return $dependencyCache[$moduleName];
107 }
108
130 public static function compileUnresolvedDependencies( array &$registryData ) : void {
131 foreach ( $registryData as $name => &$data ) {
132 $dependencies = $data['dependencies'];
133 try {
134 foreach ( $data['dependencies'] as $dependency ) {
135 $implicitDependencies = self::getImplicitDependencies( $registryData, $dependency );
136 $dependencies = array_diff( $dependencies, $implicitDependencies );
137 }
139 // Leave unchanged
140 $dependencies = $data['dependencies'];
141 }
142
143 // Rebuild keys
144 $data['dependencies'] = array_values( $dependencies );
145 }
146 }
147
154 public function getModuleRegistrations( ResourceLoaderContext $context ) : string {
155 $resourceLoader = $context->getResourceLoader();
156 // Future developers: Use WebRequest::getRawVal() instead getVal().
157 // The getVal() method performs slow Language+UTF logic. (f303bb9360)
158 $target = $context->getRequest()->getRawVal( 'target', 'desktop' );
159 $safemode = $context->getRequest()->getRawVal( 'safemode' ) === '1';
160 // Bypass target filter if this request is Special:JavaScriptTest.
161 // To prevent misuse in production, this is only allowed if testing is enabled server-side.
162 $byPassTargetFilter = $this->getConfig()->get( 'EnableJavaScriptTest' ) && $target === 'test';
163
164 $out = '';
165 $states = [];
166 $registryData = [];
167 $moduleNames = $resourceLoader->getModuleNames();
168
169 // Preload with a batch so that the below calls to getVersionHash() for each module
170 // don't require on-demand loading of more information.
171 try {
172 $resourceLoader->preloadModuleInfo( $moduleNames, $context );
173 } catch ( Exception $e ) {
174 // Don't fail the request (T152266)
175 // Also print the error in the main output
176 $resourceLoader->outputErrorAndLog( $e,
177 'Preloading module info from startup failed: {exception}',
178 [ 'exception' => $e ]
179 );
180 }
181
182 // Get registry data
183 foreach ( $moduleNames as $name ) {
184 $module = $resourceLoader->getModule( $name );
185 $moduleTargets = $module->getTargets();
186 if (
187 ( !$byPassTargetFilter && !in_array( $target, $moduleTargets ) )
188 || ( $safemode && $module->getOrigin() > ResourceLoaderModule::ORIGIN_CORE_INDIVIDUAL )
189 ) {
190 continue;
191 }
192
193 if ( $module instanceof ResourceLoaderStartUpModule ) {
194 // Don't register 'startup' to the client because loading it lazily or depending
195 // on it doesn't make sense, because the startup module *is* the client.
196 // Registering would be a waste of bandwidth and memory and risks somehow causing
197 // it to load a second time.
198
199 // ATTENTION: Because of the line below, this is not going to cause infinite recursion.
200 // Think carefully before making changes to this code!
201 // The below code is going to call ResourceLoaderModule::getVersionHash() for every module.
202 // For StartUpModule (this module) the hash is computed based on the manifest content,
203 // which is the very thing we are computing right here. As such, this must skip iterating
204 // over 'startup' itself.
205 continue;
206 }
207
208 try {
209 $versionHash = $module->getVersionHash( $context );
210 } catch ( Exception $e ) {
211 // Don't fail the request (T152266)
212 // Also print the error in the main output
213 $resourceLoader->outputErrorAndLog( $e,
214 'Calculating version for "{module}" failed: {exception}',
215 [
216 'module' => $name,
217 'exception' => $e,
218 ]
219 );
220 $versionHash = '';
221 $states[$name] = 'error';
222 }
223
224 if ( $versionHash !== '' && strlen( $versionHash ) !== ResourceLoader::HASH_LENGTH ) {
225 $e = new RuntimeException( "Badly formatted module version hash" );
226 $resourceLoader->outputErrorAndLog( $e,
227 "Module '{module}' produced an invalid version hash: '{version}'.",
228 [
229 'module' => $name,
230 'version' => $versionHash,
231 ]
232 );
233 // Module implementation either broken or deviated from ResourceLoader::makeHash
234 // Asserted by tests/phpunit/structure/ResourcesTest.
235 $versionHash = ResourceLoader::makeHash( $versionHash );
236 }
237
238 $skipFunction = $module->getSkipFunction();
239 if ( $skipFunction !== null && !$context->getDebug() ) {
240 $skipFunction = ResourceLoader::filter( 'minify-js', $skipFunction );
241 }
242
243 $registryData[$name] = [
244 'version' => $versionHash,
245 'dependencies' => $module->getDependencies( $context ),
246 'group' => $this->getGroupId( $module->getGroup() ),
247 'source' => $module->getSource(),
248 'skip' => $skipFunction,
249 ];
250 }
251
252 self::compileUnresolvedDependencies( $registryData );
253
254 // Register sources
255 $out .= ResourceLoader::makeLoaderSourcesScript( $context, $resourceLoader->getSources() );
256
257 // Figure out the different call signatures for mw.loader.register
258 $registrations = [];
259 foreach ( $registryData as $name => $data ) {
260 // Call mw.loader.register(name, version, dependencies, group, source, skip)
261 $registrations[] = [
262 $name,
263 $data['version'],
264 $data['dependencies'],
265 $data['group'],
266 // Swap default (local) for null
267 $data['source'] === 'local' ? null : $data['source'],
268 $data['skip']
269 ];
270 }
271
272 // Register modules
273 $out .= "\n" . ResourceLoader::makeLoaderRegisterScript( $context, $registrations );
274
275 if ( $states ) {
276 $out .= "\n" . ResourceLoader::makeLoaderStateScript( $context, $states );
277 }
278
279 return $out;
280 }
281
282 private function getGroupId( $groupName ) : ?int {
283 if ( $groupName === null ) {
284 return null;
285 }
286
287 if ( !array_key_exists( $groupName, $this->groupIds ) ) {
288 $this->groupIds[$groupName] = count( $this->groupIds );
289 }
290
291 return $this->groupIds[$groupName];
292 }
293
299 private function getBaseModules() : array {
300 return [ 'jquery', 'mediawiki.base' ];
301 }
302
309 private function getStoreKey() : string {
310 return 'MediaWikiModuleStore:' . $this->getConfig()->get( 'DBname' );
311 }
312
317 private function getMaxQueryLength() : int {
318 $len = $this->getConfig()->get( 'ResourceLoaderMaxQueryLength' );
319 // - Ignore -1, which in MW 1.34 and earlier was used to mean "unlimited".
320 // - Ignore invalid values, e.g. non-int or other negative values.
321 if ( $len === false || $len < 0 ) {
322 // Default
323 $len = 2000;
324 }
325 return $len;
326 }
327
334 private function getStoreVary( ResourceLoaderContext $context ) : string {
335 return implode( ':', [
336 $context->getSkin(),
337 $this->getConfig()->get( 'ResourceLoaderStorageVersion' ),
338 $context->getLanguage(),
339 ] );
340 }
341
346 public function getScript( ResourceLoaderContext $context ) : string {
347 global $IP;
348 $conf = $this->getConfig();
349
350 if ( $context->getOnly() !== 'scripts' ) {
351 return '/* Requires only=scripts */';
352 }
353
354 $startupCode = file_get_contents( "$IP/resources/src/startup/startup.js" );
355
356 // The files read here MUST be kept in sync with maintenance/jsduck/eg-iframe.html,
357 // and MUST be considered by 'fileHashes' in StartUpModule::getDefinitionSummary().
358 $mwLoaderCode = file_get_contents( "$IP/resources/src/startup/mediawiki.js" ) .
359 file_get_contents( "$IP/resources/src/startup/mediawiki.requestIdleCallback.js" );
360 if ( $context->getDebug() ) {
361 $mwLoaderCode .= file_get_contents( "$IP/resources/src/startup/mediawiki.log.js" );
362 }
363 if ( $conf->get( 'ResourceLoaderEnableJSProfiler' ) ) {
364 $mwLoaderCode .= file_get_contents( "$IP/resources/src/startup/profiler.js" );
365 }
366
367 // Perform replacements for mediawiki.js
368 $mwLoaderPairs = [
369 // This should always be an object, even if the base vars are empty
370 // (such as when using the default lang/skin).
371 '$VARS.reqBase' => $context->encodeJson( (object)$context->getReqBase() ),
372 '$VARS.baseModules' => $context->encodeJson( $this->getBaseModules() ),
373 '$VARS.maxQueryLength' => $context->encodeJson( $this->getMaxQueryLength() ),
374 // The client-side module cache can be disabled by site configuration.
375 // It is also always disabled in debug mode.
376 '$VARS.storeEnabled' => $context->encodeJson(
377 $conf->get( 'ResourceLoaderStorageEnabled' ) && !$context->getDebug()
378 ),
379 '$VARS.wgLegacyJavaScriptGlobals' => $context->encodeJson(
380 $conf->get( 'LegacyJavaScriptGlobals' )
381 ),
382 '$VARS.storeKey' => $context->encodeJson( $this->getStoreKey() ),
383 '$VARS.storeVary' => $context->encodeJson( $this->getStoreVary( $context ) ),
384 '$VARS.groupUser' => $context->encodeJson( $this->getGroupId( 'user' ) ),
385 '$VARS.groupPrivate' => $context->encodeJson( $this->getGroupId( 'private' ) ),
386 ];
387 $profilerStubs = [
388 '$CODE.profileExecuteStart();' => 'mw.loader.profiler.onExecuteStart( module );',
389 '$CODE.profileExecuteEnd();' => 'mw.loader.profiler.onExecuteEnd( module );',
390 '$CODE.profileScriptStart();' => 'mw.loader.profiler.onScriptStart( module );',
391 '$CODE.profileScriptEnd();' => 'mw.loader.profiler.onScriptEnd( module );',
392 ];
393 if ( $conf->get( 'ResourceLoaderEnableJSProfiler' ) ) {
394 // When profiling is enabled, insert the calls.
395 $mwLoaderPairs += $profilerStubs;
396 } else {
397 // When disabled (by default), insert nothing.
398 $mwLoaderPairs += array_fill_keys( array_keys( $profilerStubs ), '' );
399 }
400 $mwLoaderCode = strtr( $mwLoaderCode, $mwLoaderPairs );
401
402 // Perform string replacements for startup.js
403 $pairs = [
404 // Raw JavaScript code (not JSON)
405 '$CODE.registrations();' => trim( $this->getModuleRegistrations( $context ) ),
406 '$CODE.defineLoader();' => $mwLoaderCode,
407 ];
408 $startupCode = strtr( $startupCode, $pairs );
409
410 return $startupCode;
411 }
412
416 public function supportsURLLoading() : bool {
417 return false;
418 }
419
423 public function enableModuleContentVersion() : bool {
424 // Enabling this means that ResourceLoader::getVersionHash will simply call getScript()
425 // and hash it to determine the version (as used by E-Tag HTTP response header).
426 return true;
427 }
428}
return[ 'abap'=> true, 'abl'=> true, 'abnf'=> true, 'aconf'=> true, 'actionscript'=> true, 'actionscript3'=> true, 'ada'=> true, 'ada2005'=> true, 'ada95'=> true, 'adl'=> true, 'agda'=> true, 'aheui'=> true, 'ahk'=> true, 'alloy'=> true, 'ambienttalk'=> true, 'ambienttalk/2'=> true, 'ampl'=> true, 'antlr'=> true, 'antlr-actionscript'=> true, 'antlr-as'=> true, 'antlr-c#'=> true, 'antlr-cpp'=> true, 'antlr-csharp'=> true, 'antlr-java'=> true, 'antlr-objc'=> true, 'antlr-perl'=> true, 'antlr-python'=> true, 'antlr-rb'=> true, 'antlr-ruby'=> true, 'apache'=> true, 'apacheconf'=> true, 'apl'=> true, 'applescript'=> true, 'arduino'=> true, 'arexx'=> true, 'arrow'=> true, 'as'=> true, 'as3'=> true, 'asm'=> true, 'aspectj'=> true, 'aspx-cs'=> true, 'aspx-vb'=> true, 'asy'=> true, 'asymptote'=> true, 'at'=> true, 'augeas'=> true, 'autohotkey'=> true, 'autoit'=> true, 'awk'=> true, 'b3d'=> true, 'bare'=> true, 'basemake'=> true, 'bash'=> true, 'basic'=> true, 'bat'=> true, 'batch'=> true, 'bbcbasic'=> true, 'bbcode'=> true, 'bc'=> true, 'befunge'=> true, 'bf'=> true, 'bib'=> true, 'bibtex'=> true, 'blitzbasic'=> true, 'blitzmax'=> true, 'bmax'=> true, 'bnf'=> true, 'boa'=> true, 'boo'=> true, 'boogie'=> true, 'bplus'=> true, 'brainfuck'=> true, 'bro'=> true, 'bsdmake'=> true, 'bst'=> true, 'bst-pybtex'=> true, 'bugs'=> true, 'c'=> true, 'c#'=> true, 'c++'=> true, 'c++-objdumb'=> true, 'c-objdump'=> true, 'ca65'=> true, 'cadl'=> true, 'camkes'=> true, 'capdl'=> true, 'capnp'=> true, 'cbmbas'=> true, 'ceylon'=> true, 'cf3'=> true, 'cfc'=> true, 'cfengine3'=> true, 'cfg'=> true, 'cfm'=> true, 'cfs'=> true, 'chai'=> true, 'chaiscript'=> true, 'chapel'=> true, 'charmci'=> true, 'cheetah'=> true, 'chpl'=> true, 'cirru'=> true, 'cl'=> true, 'clay'=> true, 'clean'=> true, 'clipper'=> true, 'clj'=> true, 'cljs'=> true, 'clojure'=> true, 'clojurescript'=> true, 'cmake'=> true, 'cobol'=> true, 'cobolfree'=> true, 'coffee'=> true, 'coffee-script'=> true, 'coffeescript'=> true, 'common-lisp'=> true, 'componentpascal'=> true, 'console'=> true, 'control'=> true, 'coq'=> true, 'cp'=> true, 'cpp'=> true, 'cpp-objdump'=> true, 'cpsa'=> true, 'cr'=> true, 'crmsh'=> true, 'croc'=> true, 'cry'=> true, 'cryptol'=> true, 'crystal'=> true, 'csh'=> true, 'csharp'=> true, 'csound'=> true, 'csound-csd'=> true, 'csound-document'=> true, 'csound-orc'=> true, 'csound-sco'=> true, 'csound-score'=> true, 'css'=> true, 'css+django'=> true, 'css+erb'=> true, 'css+genshi'=> true, 'css+genshitext'=> true, 'css+jinja'=> true, 'css+lasso'=> true, 'css+mako'=> true, 'css+mozpreproc'=> true, 'css+myghty'=> true, 'css+php'=> true, 'css+ruby'=> true, 'css+smarty'=> true, 'cu'=> true, 'cucumber'=> true, 'cuda'=> true, 'cxx-objdump'=> true, 'cypher'=> true, 'cython'=> true, 'd'=> true, 'd-objdump'=> true, 'dart'=> true, 'dasm16'=> true, 'debcontrol'=> true, 'debsources'=> true, 'delphi'=> true, 'devicetree'=> true, 'dg'=> true, 'diff'=> true, 'django'=> true, 'dmesg'=> true, 'do'=> true, 'docker'=> true, 'dockerfile'=> true, 'dosbatch'=> true, 'doscon'=> true, 'dosini'=> true, 'dpatch'=> true, 'dtd'=> true, 'dts'=> true, 'duby'=> true, 'duel'=> true, 'dylan'=> true, 'dylan-console'=> true, 'dylan-lid'=> true, 'dylan-repl'=> true, 'earl-grey'=> true, 'earlgrey'=> true, 'easytrieve'=> true, 'ebnf'=> true, 'ec'=> true, 'ecl'=> true, 'eg'=> true, 'eiffel'=> true, 'elisp'=> true, 'elixir'=> true, 'elm'=> true, 'emacs'=> true, 'emacs-lisp'=> true, 'email'=> true, 'eml'=> true, 'erb'=> true, 'erl'=> true, 'erlang'=> true, 'evoque'=> true, 'ex'=> true, 'execline'=> true, 'exs'=> true, 'extempore'=> true, 'ezhil'=> true, 'f#'=> true, 'factor'=> true, 'fan'=> true, 'fancy'=> true, 'felix'=> true, 'fennel'=> true, 'fish'=> true, 'fishshell'=> true, 'flatline'=> true, 'flo'=> true, 'floscript'=> true, 'flx'=> true, 'fnl'=> true, 'forth'=> true, 'fortran'=> true, 'fortranfixed'=> true, 'foxpro'=> true, 'freefem'=> true, 'fsharp'=> true, 'fstar'=> true, 'fy'=> true, 'gap'=> true, 'gas'=> true, 'gawk'=> true, 'gd'=> true, 'gdscript'=> true, 'genshi'=> true, 'genshitext'=> true, 'gherkin'=> true, 'glsl'=> true, 'gnuplot'=> true, 'go'=> true, 'golo'=> true, 'gooddata-cl'=> true, 'gosu'=> true, 'groff'=> true, 'groovy'=> true, 'gst'=> true, 'haml'=> true, 'handlebars'=> true, 'haskell'=> true, 'haxe'=> true, 'haxeml'=> true, 'hexdump'=> true, 'hlsl'=> true, 'hs'=> true, 'hsa'=> true, 'hsail'=> true, 'hspec'=> true, 'html'=> true, 'html+cheetah'=> true, 'html+django'=> true, 'html+erb'=> true, 'html+evoque'=> true, 'html+genshi'=> true, 'html+handlebars'=> true, 'html+jinja'=> true, 'html+kid'=> true, 'html+lasso'=> true, 'html+mako'=> true, 'html+myghty'=> true, 'html+ng2'=> true, 'html+php'=> true, 'html+ruby'=> true, 'html+smarty'=> true, 'html+spitfire'=> true, 'html+twig'=> true, 'html+velocity'=> true, 'htmlcheetah'=> true, 'htmldjango'=> true, 'http'=> true, 'hx'=> true, 'hxml'=> true, 'hxsl'=> true, 'hy'=> true, 'hybris'=> true, 'hylang'=> true, 'i6'=> true, 'i6t'=> true, 'i7'=> true, 'icon'=> true, 'idl'=> true, 'idl4'=> true, 'idr'=> true, 'idris'=> true, 'iex'=> true, 'igor'=> true, 'igorpro'=> true, 'ik'=> true, 'inform6'=> true, 'inform7'=> true, 'ini'=> true, 'io'=> true, 'ioke'=> true, 'irb'=> true, 'irc'=> true, 'isabelle'=> true, 'j'=> true, 'jade'=> true, 'jags'=> true, 'jasmin'=> true, 'jasminxt'=> true, 'java'=> true, 'javascript'=> true, 'javascript+cheetah'=> true, 'javascript+django'=> true, 'javascript+erb'=> true, 'javascript+genshi'=> true, 'javascript+genshitext'=> true, 'javascript+jinja'=> true, 'javascript+lasso'=> true, 'javascript+mako'=> true, 'javascript+mozpreproc'=> true, 'javascript+myghty'=> true, 'javascript+php'=> true, 'javascript+ruby'=> true, 'javascript+smarty'=> true, 'javascript+spitfire'=> true, 'jbst'=> true, 'jcl'=> true, 'jinja'=> true, 'jl'=> true, 'jlcon'=> true, 'jproperties'=> true, 'js'=> true, 'js+cheetah'=> true, 'js+django'=> true, 'js+erb'=> true, 'js+genshi'=> true, 'js+genshitext'=> true, 'js+jinja'=> true, 'js+lasso'=> true, 'js+mako'=> true, 'js+myghty'=> true, 'js+php'=> true, 'js+ruby'=> true, 'js+smarty'=> true, 'js+spitfire'=> true, 'jsgf'=> true, 'json'=> true, 'json-ld'=> true, 'json-object'=> true, 'jsonld'=> true, 'jsonml+bst'=> true, 'jsp'=> true, 'julia'=> true, 'juttle'=> true, 'kal'=> true, 'kconfig'=> true, 'kernel-config'=> true, 'kid'=> true, 'kmsg'=> true, 'koka'=> true, 'kotlin'=> true, 'ksh'=> true, 'lagda'=> true, 'lasso'=> true, 'lassoscript'=> true, 'latex'=> true, 'lcry'=> true, 'lcryptol'=> true, 'lean'=> true, 'less'=> true, 'lhaskell'=> true, 'lhs'=> true, 'lid'=> true, 'lidr'=> true, 'lidris'=> true, 'lighttpd'=> true, 'lighty'=> true, 'limbo'=> true, 'linux-config'=> true, 'liquid'=> true, 'lisp'=> true, 'literate-agda'=> true, 'literate-cryptol'=> true, 'literate-haskell'=> true, 'literate-idris'=> true, 'live-script'=> true, 'livescript'=> true, 'llvm'=> true, 'llvm-mir'=> true, 'llvm-mir-body'=> true, 'logos'=> true, 'logtalk'=> true, 'lsl'=> true, 'lua'=> true, 'm2'=> true, 'make'=> true, 'makefile'=> true, 'mako'=> true, 'man'=> true, 'maql'=> true, 'mask'=> true, 'mason'=> true, 'mathematica'=> true, 'matlab'=> true, 'matlabsession'=> true, 'mawk'=> true, 'md'=> true, 'menuconfig'=> true, 'mf'=> true, 'mime'=> true, 'minid'=> true, 'miniscript'=> true, 'mma'=> true, 'modelica'=> true, 'modula2'=> true, 'moin'=> true, 'monkey'=> true, 'monte'=> true, 'moo'=> true, 'moocode'=> true, 'moon'=> true, 'moonscript'=> true, 'mosel'=> true, 'mozhashpreproc'=> true, 'mozpercentpreproc'=> true, 'mq4'=> true, 'mq5'=> true, 'mql'=> true, 'mql4'=> true, 'mql5'=> true, 'ms'=> true, 'msc'=> true, 'mscgen'=> true, 'mupad'=> true, 'mxml'=> true, 'myghty'=> true, 'mysql'=> true, 'nasm'=> true, 'nawk'=> true, 'nb'=> true, 'ncl'=> true, 'nemerle'=> true, 'nesc'=> true, 'newlisp'=> true, 'newspeak'=> true, 'ng2'=> true, 'nginx'=> true, 'nim'=> true, 'nimrod'=> true, 'nit'=> true, 'nix'=> true, 'nixos'=> true, 'notmuch'=> true, 'nroff'=> true, 'nsh'=> true, 'nsi'=> true, 'nsis'=> true, 'numpy'=> true, 'nusmv'=> true, 'obj-c'=> true, 'obj-c++'=> true, 'obj-j'=> true, 'objc'=> true, 'objc++'=> true, 'objdump'=> true, 'objdump-nasm'=> true, 'objective-c'=> true, 'objective-c++'=> true, 'objective-j'=> true, 'objectivec'=> true, 'objectivec++'=> true, 'objectivej'=> true, 'objectpascal'=> true, 'objj'=> true, 'ocaml'=> true, 'octave'=> true, 'odin'=> true, 'ooc'=> true, 'opa'=> true, 'openbugs'=> true, 'openedge'=> true, 'pacmanconf'=> true, 'pan'=> true, 'parasail'=> true, 'pas'=> true, 'pascal'=> true, 'pawn'=> true, 'pcmk'=> true, 'peg'=> true, 'perl'=> true, 'perl6'=> true, 'php'=> true, 'php3'=> true, 'php4'=> true, 'php5'=> true, 'pig'=> true, 'pike'=> true, 'pkgconfig'=> true, 'pl'=> true, 'pl6'=> true, 'plpgsql'=> true, 'po'=> true, 'pointless'=> true, 'pony'=> true, 'posh'=> true, 'postgres'=> true, 'postgres-console'=> true, 'postgresql'=> true, 'postgresql-console'=> true, 'postscr'=> true, 'postscript'=> true, 'pot'=> true, 'pov'=> true, 'powershell'=> true, 'praat'=> true, 'progress'=> true, 'prolog'=> true, 'promql'=> true, 'properties'=> true, 'proto'=> true, 'protobuf'=> true, 'ps1'=> true, 'ps1con'=> true, 'psm1'=> true, 'psql'=> true, 'psysh'=> true, 'pug'=> true, 'puppet'=> true, 'py'=> true, 'py2'=> true, 'py2tb'=> true, 'py3'=> true, 'py3tb'=> true, 'pycon'=> true, 'pypy'=> true, 'pypylog'=> true, 'pyrex'=> true, 'pytb'=> true, 'python'=> true, 'python2'=> true, 'python3'=> true, 'pyx'=> true, 'qbasic'=> true, 'qbs'=> true, 'qml'=> true, 'qvt'=> true, 'qvto'=> true, 'r'=> true, 'racket'=> true, 'ragel'=> true, 'ragel-c'=> true, 'ragel-cpp'=> true, 'ragel-d'=> true, 'ragel-em'=> true, 'ragel-java'=> true, 'ragel-objc'=> true, 'ragel-rb'=> true, 'ragel-ruby'=> true, 'raku'=> true, 'raw'=> true, 'rb'=> true, 'rbcon'=> true, 'rconsole'=> true, 'rd'=> true, 'reason'=> true, 'reasonml'=> true, 'rebol'=> true, 'red'=> true, 'red/system'=> true, 'redcode'=> true, 'registry'=> true, 'resource'=> true, 'resourcebundle'=> true, 'rest'=> true, 'restructuredtext'=> true, 'rexx'=> true, 'rhtml'=> true, 'ride'=> true, 'rkt'=> true, 'rnc'=> true, 'rng-compact'=> true, 'roboconf-graph'=> true, 'roboconf-instances'=> true, 'robotframework'=> true, 'rout'=> true, 'rql'=> true, 'rs'=> true, 'rsl'=> true, 'rst'=> true, 'rts'=> true, 'ruby'=> true, 'rust'=> true, 's'=> true, 'sage'=> true, 'salt'=> true, 'sarl'=> true, 'sas'=> true, 'sass'=> true, 'sbatch'=> true, 'sc'=> true, 'scala'=> true, 'scaml'=> true, 'scd'=> true, 'scdoc'=> true, 'scheme'=> true, 'scilab'=> true, 'scm'=> true, 'scss'=> true, 'sgf'=> true, 'sh'=> true, 'shell'=> true, 'shell-session'=> true, 'shen'=> true, 'shex'=> true, 'shexc'=> true, 'sieve'=> true, 'silver'=> true, 'singularity'=> true, 'slash'=> true, 'slim'=> true, 'sls'=> true, 'slurm'=> true, 'smali'=> true, 'smalltalk'=> true, 'smarty'=> true, 'sml'=> true, 'snobol'=> true, 'snowball'=> true, 'solidity'=> true, 'sources.list'=> true, 'sourceslist'=> true, 'sp'=> true, 'sparql'=> true, 'spec'=> true, 'spitfire'=> true, 'splus'=> true, 'sql'=> true, 'sqlite3'=> true, 'squeak'=> true, 'squid'=> true, 'squid.conf'=> true, 'squidconf'=> true, 'ssp'=> true, 'st'=> true, 'stan'=> true, 'stata'=> true, 'supercollider'=> true, 'sv'=> true, 'swift'=> true, 'swig'=> true, 'systemverilog'=> true, 't-sql'=> true, 'tads3'=> true, 'tap'=> true, 'tasm'=> true, 'tcl'=> true, 'tcsh'=> true, 'tcshcon'=> true, 'tea'=> true, 'teraterm'=> true, 'teratermmacro'=> true, 'termcap'=> true, 'terminfo'=> true, 'terraform'=> true, 'tex'=> true, 'text'=> true, 'tf'=> true, 'thrift'=> true, 'tid'=> true, 'tnt'=> true, 'todotxt'=> true, 'toml'=> true, 'trac-wiki'=> true, 'trafficscript'=> true, 'treetop'=> true, 'ts'=> true, 'tsql'=> true, 'ttl'=> true, 'turtle'=> true, 'twig'=> true, 'typescript'=> true, 'typoscript'=> true, 'typoscriptcssdata'=> true, 'typoscripthtmldata'=> true, 'ucode'=> true, 'udiff'=> true, 'unicon'=> true, 'urbiscript'=> true, 'usd'=> true, 'usda'=> true, 'v'=> true, 'vala'=> true, 'vapi'=> true, 'vb.net'=> true, 'vbnet'=> true, 'vbscript'=> true, 'vcl'=> true, 'vclsnippet'=> true, 'vclsnippets'=> true, 'vctreestatus'=> true, 'velocity'=> true, 'verilog'=> true, 'vfp'=> true, 'vgl'=> true, 'vhdl'=> true, 'vim'=> true, 'wdiff'=> true, 'webidl'=> true, 'whiley'=> true, 'winbatch'=> true, 'winbugs'=> true, 'x10'=> true, 'xbase'=> true, 'xml'=> true, 'xml+cheetah'=> true, 'xml+django'=> true, 'xml+erb'=> true, 'xml+evoque'=> true, 'xml+genshi'=> true, 'xml+jinja'=> true, 'xml+kid'=> true, 'xml+lasso'=> true, 'xml+mako'=> true, 'xml+myghty'=> true, 'xml+php'=> true, 'xml+ruby'=> true, 'xml+smarty'=> true, 'xml+spitfire'=> true, 'xml+velocity'=> true, 'xorg.conf'=> true, 'xq'=> true, 'xql'=> true, 'xqm'=> true, 'xquery'=> true, 'xqy'=> true, 'xslt'=> true, 'xten'=> true, 'xtend'=> true, 'xul+mozpreproc'=> true, 'yaml'=> true, 'yaml+jinja'=> true, 'yang'=> true, 'zeek'=> true, 'zephir'=> true, 'zig'=> true, 'zsh'=> true,]
Context object that contains information about the state of a specific ResourceLoader web request.
getReqBase()
Get the request base parameters, omitting any defaults.
encodeJson( $data)
Wrapper around json_encode that avoids needless escapes, and pretty-prints in debug mode.
Abstraction for ResourceLoader modules, with name registration and maxage functionality.
Module for ResourceLoader initialization.
getStoreVary(ResourceLoaderContext $context)
Get the key on which the JavaScript module cache (mw.loader.store) will vary.
getScript(ResourceLoaderContext $context)
static getImplicitDependencies(array $registryData, string $moduleName, array $handled=[])
Recursively get all explicit and implicit dependencies for to the given module.
static compileUnresolvedDependencies(array &$registryData)
Optimize the dependency tree in $this->modules.
getBaseModules()
Base modules implicitly available to all modules.
getModuleRegistrations(ResourceLoaderContext $context)
Get registration code for all modules.
getStoreKey()
Get the localStorage key for the entire module store.
static makeLoaderSourcesScript(ResourceLoaderContext $context, array $sources)
Format JS code which calls mw.loader.addSource() with the given parameters.
static makeLoaderRegisterScript(ResourceLoaderContext $context, array $modules)
Format JS code which calls mw.loader.register() with the given parameters.
static makeHash( $value)
Create a hash for module versioning purposes.
static makeLoaderStateScript(ResourceLoaderContext $context, array $states)
Returns a JS call to mw.loader.state, which sets the state of modules to a given value:
static filter( $filter, $data, array $options=[])
Run JavaScript or CSS data through a filter, caching the filtered result for future calls.
$IP
Definition rebuild.php:19
return true
Definition router.php:92
if($IP===false)
Definition status.php:5