Merge "Type hint against LinkTarget in WatchedItemStore"
[lhc/web/wiklou.git] / includes / resourceloader / ResourceLoaderOOUIModule.php
1 <?php
2 /**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
17 *
18 * @file
19 */
20
21 /**
22 * Convenience methods for dealing with OOUI themes and their relations to MW skins.
23 *
24 * @since 1.30
25 */
26 trait ResourceLoaderOOUIModule {
27 protected static $knownScriptsModules = [ 'core' ];
28 protected static $knownStylesModules = [ 'core', 'widgets', 'toolbars', 'windows' ];
29 protected static $knownImagesModules = [
30 'indicators',
31 // Extra icons
32 'icons-accessibility',
33 'icons-alerts',
34 'icons-content',
35 'icons-editing-advanced',
36 'icons-editing-citation',
37 'icons-editing-core',
38 'icons-editing-list',
39 'icons-editing-styling',
40 'icons-interactions',
41 'icons-layout',
42 'icons-location',
43 'icons-media',
44 'icons-moderation',
45 'icons-movement',
46 'icons-user',
47 'icons-wikimedia',
48 ];
49
50 // Note that keys must be lowercase, values TitleCase.
51 protected static $builtinSkinThemeMap = [
52 'default' => 'WikimediaUI',
53 ];
54
55 // Note that keys must be TitleCase.
56 protected static $builtinThemePaths = [
57 'WikimediaUI' => [
58 'scripts' => 'resources/lib/ooui/oojs-ui-wikimediaui.js',
59 'styles' => 'resources/lib/ooui/oojs-ui-{module}-wikimediaui.css',
60 'images' => 'resources/lib/ooui/themes/wikimediaui/{module}.json',
61 ],
62 'Apex' => [
63 'scripts' => 'resources/lib/ooui/oojs-ui-apex.js',
64 'styles' => 'resources/lib/ooui/oojs-ui-{module}-apex.css',
65 'images' => 'resources/lib/ooui/themes/apex/{module}.json',
66 ],
67 ];
68
69 /**
70 * Return a map of skin names (in lowercase) to OOUI theme names, defining which theme a given
71 * skin should use.
72 *
73 * @return array
74 */
75 public static function getSkinThemeMap() {
76 $themeMap = self::$builtinSkinThemeMap;
77 $themeMap += ExtensionRegistry::getInstance()->getAttribute( 'SkinOOUIThemes' );
78 return $themeMap;
79 }
80
81 /**
82 * Return a map of theme names to lists of paths from which a given theme should be loaded.
83 *
84 * Keys are theme names, values are associative arrays. Keys of the inner array are 'scripts',
85 * 'styles', or 'images', and values are paths. Paths may be strings or ResourceLoaderFilePaths.
86 *
87 * Additionally, the string '{module}' in paths represents the name of the module to load.
88 *
89 * @return array
90 */
91 protected static function getThemePaths() {
92 $themePaths = self::$builtinThemePaths;
93 $themePaths += ExtensionRegistry::getInstance()->getAttribute( 'OOUIThemePaths' );
94
95 list( $defaultLocalBasePath, $defaultRemoteBasePath ) =
96 ResourceLoaderFileModule::extractBasePaths();
97
98 // Allow custom themes' paths to be relative to the skin/extension that defines them,
99 // like with ResourceModuleSkinStyles
100 foreach ( $themePaths as $theme => &$paths ) {
101 list( $localBasePath, $remoteBasePath ) =
102 ResourceLoaderFileModule::extractBasePaths( $paths );
103 if ( $localBasePath !== $defaultLocalBasePath || $remoteBasePath !== $defaultRemoteBasePath ) {
104 foreach ( $paths as &$path ) {
105 $path = new ResourceLoaderFilePath( $path, $localBasePath, $remoteBasePath );
106 }
107 }
108 }
109
110 return $themePaths;
111 }
112
113 /**
114 * Return a path to load given module of given theme from.
115 *
116 * The file at this path may not exist. This should be handled by the caller (throwing an error or
117 * falling back to default theme).
118 *
119 * @param string $theme OOUI theme name, for example 'WikimediaUI' or 'Apex'
120 * @param string $kind Kind of the module: 'scripts', 'styles', or 'images'
121 * @param string $module Module name, for valid values see $knownScriptsModules,
122 * $knownStylesModules, $knownImagesModules
123 * @return string|ResourceLoaderFilePath
124 */
125 protected function getThemePath( $theme, $kind, $module ) {
126 $paths = self::getThemePaths();
127 $path = $paths[$theme][$kind];
128 if ( $path instanceof ResourceLoaderFilePath ) {
129 $path = new ResourceLoaderFilePath(
130 str_replace( '{module}', $module, $path->getPath() ),
131 $path->getLocalBasePath(),
132 $path->getRemoteBasePath()
133 );
134 } else {
135 $path = str_replace( '{module}', $module, $path );
136 }
137 return $path;
138 }
139
140 /**
141 * @param string $theme See getThemePath()
142 * @param string $module See getThemePath()
143 * @return string|ResourceLoaderFilePath
144 */
145 protected function getThemeScriptsPath( $theme, $module ) {
146 if ( !in_array( $module, self::$knownScriptsModules ) ) {
147 throw new InvalidArgumentException( "Invalid OOUI scripts module '$module'" );
148 }
149 return $this->getThemePath( $theme, 'scripts', $module );
150 }
151
152 /**
153 * @param string $theme See getThemePath()
154 * @param string $module See getThemePath()
155 * @return string|ResourceLoaderFilePath
156 */
157 protected function getThemeStylesPath( $theme, $module ) {
158 if ( !in_array( $module, self::$knownStylesModules ) ) {
159 throw new InvalidArgumentException( "Invalid OOUI styles module '$module'" );
160 }
161 return $this->getThemePath( $theme, 'styles', $module );
162 }
163
164 /**
165 * @param string $theme See getThemePath()
166 * @param string $module See getThemePath()
167 * @return string|ResourceLoaderFilePath
168 */
169 protected function getThemeImagesPath( $theme, $module ) {
170 if ( !in_array( $module, self::$knownImagesModules ) ) {
171 throw new InvalidArgumentException( "Invalid OOUI images module '$module'" );
172 }
173 return $this->getThemePath( $theme, 'images', $module );
174 }
175 }