Foxtrott has uploaded a new change for review. https://gerrit.wikimedia.org/r/124275
Change subject: rework extension (switch LESS compiler, composer install, upgrade Bootstrap version) ...................................................................... rework extension (switch LESS compiler, composer install, upgrade Bootstrap version) Change-Id: Ibbc7b79f208fbee51d3b54f1d85f325cac909858 --- D .gitmodules M Bootstrap.php D ResourceLoaderBootstrapModule.php D bootstrap A composer.json R includes/BootstrapManager.php A includes/Hooks.php A includes/ResourceLoaderBootstrapModule.php 8 files changed, 362 insertions(+), 265 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Bootstrap refs/changes/75/124275/1 diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 8b0f01a..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "bootstrap"] - path = bootstrap - url = https://github.com/s7eph4n/bootstrap.git diff --git a/Bootstrap.php b/Bootstrap.php index ec3fad8..8ea835a 100644 --- a/Bootstrap.php +++ b/Bootstrap.php @@ -2,11 +2,11 @@ /** * An extension providing the Bootstrap library to other extensions * - * @see https://www.mediawiki.org/wiki/Extension:Bootstrap - * @see http://twitter.github.io/bootstrap + * @see https://www.mediawiki.org/wiki/Extension:Bootstrap + * @see http://twitter.github.io/bootstrap * - * @author Stephan Gambke - * @version 0.2 alpha + * @author Stephan Gambke + * @version 1.0-alpha * * @defgroup Bootstrap Bootstrap */ @@ -15,7 +15,7 @@ * The main file of the Bootstrap extension * * @copyright (C) 2013, Stephan Gambke - * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License, version 3 (or later) + * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License, version 3 (or later) * * This file is part of the MediaWiki extension Bootstrap. * The Bootstrap extension is free software: you can redistribute it and/or @@ -32,66 +32,45 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * * @file - * @ingroup Bootstrap + * @ingroup Bootstrap */ -if ( !defined( 'MEDIAWIKI' ) ) { - die( 'This file is part of the MediaWiki extension Bootstrap, it is not a valid entry point.' ); -} -if ( version_compare( $wgVersion, '1.22alpha', 'lt' ) ) { - die( '<b>Error:</b> This version of <a href="https://www.mediawiki.org/wiki/Extension:Bootstrap">Bootstrap</a> is only compatible with MediaWiki 1.22 or above. You need to upgrade MediaWiki first.' ); -} -/** - * The extension version - */ -define( 'BS_VERSION', '0.3 alpha' ); +call_user_func( function () { -// register the extension -$wgExtensionCredits['other'][] = array( - 'path' => __FILE__, - 'name' => 'Bootstrap', - 'author' => '[http://www.mediawiki.org/wiki/User:F.trott Stephan Gambke]', - 'url' => 'https://www.mediawiki.org/wiki/Extension:Bootstrap', - 'descriptionmsg' => 'bootstrap-desc', - 'version' => BS_VERSION, -); -// server-local path to this file -$dir = dirname( __FILE__ ); + if ( !defined( 'MEDIAWIKI' ) ) { + die( 'This file is part of the MediaWiki extension Bootstrap, it is not a valid entry point.' ); + } -// remote path to the Bootstrap extension -$scriptPath = ( $wgExtensionAssetsPath === false ? $wgScriptPath . '/extensions' : $wgExtensionAssetsPath ) . '/Bootstrap'; + if ( version_compare( $GLOBALS[ 'wgVersion' ], '1.22alpha', 'lt' ) ) { + die( '<b>Error:</b> This version of <a href="https://www.mediawiki.org/wiki/Extension:Bootstrap">Bootstrap</a> is only compatible with MediaWiki 1.22 or above. You need to upgrade MediaWiki first.' ); + } -// register message files -$wgMessagesDirs['Bootstrap'] = __DIR__ . '/i18n'; -$wgExtensionMessagesFiles['Bootstrap'] = $dir . '/Bootstrap.i18n.php'; + /** + * The extension version + */ + define( 'BS_VERSION', '1.0-alpha' ); -$wgAutoloadClasses['bootstrap\ResourceLoaderBootstrapModule'] = $dir . '/ResourceLoaderBootstrapModule.php'; -$wgAutoloadClasses['Bootstrap'] = $dir . '/Bootstrap.class.php'; + // register the extension + $GLOBALS[ 'wgExtensionCredits' ][ 'other' ][ ] = array( + 'path' => __FILE__, + 'name' => 'Bootstrap', + 'author' => '[http://www.mediawiki.org/wiki/User:F.trott Stephan Gambke]', + 'url' => 'https://www.mediawiki.org/wiki/Extension:Bootstrap', + 'descriptionmsg' => 'bootstrap-desc', + 'version' => BS_VERSION, + ); -// register skeleton resource module with the Resource Loader -$wgResourceModules['ext.bootstrap.styles'] = array( - 'localBasePath' => $dir, - 'remoteExtPath' => 'Bootstrap', - 'class' => 'bootstrap\ResourceLoaderBootstrapModule', - 'styles' => array(), - 'variables' => array( - 'icon-font-path' => "\"$scriptPath/bootstrap/fonts/\"", - ), - 'paths' => array( $dir . '/bootstrap/less' ), - 'dependencies' => array(), -); + // register message files + $GLOBALS[ 'wgMessagesDirs' ][ 'Bootstrap' ] = __DIR__ . '/i18n'; + $GLOBALS[ 'wgExtensionMessagesFiles' ][ 'Bootstrap' ] = __DIR__ . '/Bootstrap.i18n.php'; -$wgResourceModules['ext.bootstrap.scripts'] = array( - 'localBasePath' => $dir, - 'remoteExtPath' => 'Bootstrap', - 'scripts' => array(), -); + // register classes + $GLOBALS[ 'wgAutoloadClasses' ][ 'bootstrap\ResourceLoaderBootstrapModule' ] = __DIR__ . '/includes/ResourceLoaderBootstrapModule.php'; + $GLOBALS[ 'wgAutoloadClasses' ][ 'bootstrap\BootstrapManager' ] = __DIR__ . '/includes/BootstrapManager.php'; + $GLOBALS[ 'wgAutoloadClasses' ][ 'bootstrap\Hooks' ] = __DIR__ . '/includes/Hooks.php'; -$wgResourceModules[ 'ext.bootstrap' ] = array( - 'dependencies' => array( 'ext.bootstrap.styles', 'ext.bootstrap.scripts' ), -); + $GLOBALS[ 'wgHooks' ][ 'SetupAfterCache' ][ ] = 'bootstrap\Hooks::onSetupAfterCache'; -unset( $dir ); -unset( $scriptPath ); +} ); diff --git a/ResourceLoaderBootstrapModule.php b/ResourceLoaderBootstrapModule.php deleted file mode 100644 index e6f972d..0000000 --- a/ResourceLoaderBootstrapModule.php +++ /dev/null @@ -1,153 +0,0 @@ -<?php -/** - * File holding the ResourceLoaderBootstrapModule class - * - * @copyright (C) 2013, Stephan Gambke - * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License, version 3 (or later) - * - * This file is part of the MediaWiki extension Bootstrap. - * The Bootstrap extension is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Bootstrap extension is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * @file - * @ingroup Bootstrap - */ - -namespace Bootstrap; - -use lessc; -use ResourceLoader; -use ResourceLoaderContext; -use ResourceLoaderFileModule; - -/** - * ResourceLoader module based on local JavaScript/LESS files. - * - * Different to the behaviour of ResourceLoaderFileModule this module compiles all LESS files in one compile context. - * - * It recognizes the following additional fields in $wgResourceModules: - * * styles: array of LESS file names (with or without extension .less) - * * variables: array of key value pairs representing LESS variables, that will be added to the LESS script after all - * files imports, i.e. that may override any variable set in style files - * * paths: array of paths to search for style files; all these paths together represent one virtual file base and will - * be searched for a style file; this means it is not possible to include two LESS files with the same name - * even if in different paths - * - * @package Bootstrap - */ -class ResourceLoaderBootstrapModule extends ResourceLoaderFileModule { - - protected $variables = array(); - protected $paths = array(); - - public function __construct( $options = array(), $localBasePath = null, $remoteBasePath = null - ) { - - parent::__construct( $options, $localBasePath, $remoteBasePath ); - - if ( isset( $options[ 'variables' ] ) ) { - $this->variables = $options[ 'variables' ]; - } - - if ( isset( $options[ 'paths' ] ) ) { - $this->paths = $options[ 'paths' ]; - } - - } - - /** - * Get the compiled Bootstrap styles - * - * @param ResourceLoaderContext $context - * - * @return array - */ - public function getStyles( ResourceLoaderContext $context ) { - - global $IP, $wgUser; - - // Try for cache hit - $data = $wgUser->getId(); // caching styles per user - $cacheKey = wfMemcKey( 'ext', 'bootstrap', $data ); - - $cache = wfGetCache( CACHE_ANYTHING ); - $cacheResult = $cache->get( $cacheKey ); - - // only use styles from cache if LocalSettings was not modified after the caching - if ( is_array( $cacheResult ) && $cacheResult[ 'storetime' ] >= filemtime( $IP . '/LocalSettings.php' ) ) { - - wfDebug( "ext.bootstrap: Cache hit: Got styles from cache.\n" ); - $styles = $cacheResult[ 'styles' ]; - - } else { - - if ( is_array( $cacheResult ) ) { - wfDebug( "ext.bootstrap: Cache miss: Cache outdated, LocalSettings have changed.\n" ); - } else { - wfDebug( "ext.bootstrap: Cache miss: Styles not found in cache.\n" ); - } - - $compiler = new lessc(); - - // prepare a temp file containing all the variables to load - // have to use a temp file for variables because inline variables do not overwrite @import'ed variables even if - // set after the @import (see https://github.com/leafo/lessphp/issues/302 ) - $tmpFile = null; - - if ( !empty( $this->variables ) ) { - - $tmpFile = tempnam( sys_get_temp_dir(), 'php' ); - - $handle = fopen( $tmpFile, 'w' ); - - foreach ( $this->variables as $key => $value ) { - fwrite( $handle, "@$key: $value;\n" ); - } - - fclose( $handle ); - - $this->styles[ ] = basename( $tmpFile ); - $this->paths[ ] = dirname( $tmpFile ); - - } - - // add all - $lessCode = implode( array_map( function ( $module ) { return "@import \"$module\";\n"; }, $this->styles ) ); - - // add additional paths for external files - foreach ( $this->paths as $path ) { - $compiler->addImportDir( $path ); - } - - try { - - $styles = array( 'all' => $compiler->compile( $lessCode ) ); - $cache->set( $cacheKey, array( 'styles' => $styles, 'storetime' => time() ) ); - - } catch ( \Exception $e ) { - wfDebug( $e->getMessage() ); - $styles = array( 'all' => '/* LESS compile error: ' . $e->getMessage() . '*/' ); - } - - unlink( $tmpFile ); - - } - - return $styles; - } - - public function supportsURLLoading() { - - return false; - } -} diff --git a/bootstrap b/bootstrap deleted file mode 160000 index 1e8a0bb..0000000 --- a/bootstrap +++ /dev/null -Subproject commit 1e8a0bbfb67e44ce9fd8a845239a775f5fcabf7a diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..384a07c --- /dev/null +++ b/composer.json @@ -0,0 +1,45 @@ +{ + "name" : "mediawiki/bootstrap", + "type" : "mediawiki-extension", + "description": "Provides the Twitter Bootstrap3 web front-end framework to MediaWiki skins and extensions", + "keywords" : [ + "wiki", + "MediaWiki", + "extension", + "Twitter", + "Bootstrap" + ], + "homepage" : "https://www.mediawiki.org/wiki/Extension:Bootstrap", + "license" : "GPL-3.0+", + "authors" : [ + { + "name" : "Stephan Gambke", + "email": "[email protected]", + "role" : "Developer" + } + ], + "support" : { + "wiki" : "https://www.mediawiki.org/wiki/Extension:Bootstrap", + "forum" : "https://www.mediawiki.org/wiki/Extension_talk:Bootstrap", + "source": "https://git.wikimedia.org/tree/mediawiki%2Fextensions%2FBootstrap", + "issues": "https://www.mediawiki.org/wiki/Extension_talk:Bootstrap", + "irc" : "irc://irc.freenode.org/mediawiki" + }, + "require" : { + "php" : ">=5.3.0", + "composer/installers": "1.*,>=1.0.1", + "oyejorge/less.php" : "~1.5", + "twitter/bootstrap" : "~3.0" + }, + "autoload" : { + "files": [ + "Bootstrap.php" + ] + }, + "extra" : { + "branch-alias": { + "dev-master": "1.x-dev" + + } + } +} diff --git a/Bootstrap.class.php b/includes/BootstrapManager.php similarity index 72% rename from Bootstrap.class.php rename to includes/BootstrapManager.php index 82a3079..2a66b7c 100644 --- a/Bootstrap.class.php +++ b/includes/BootstrapManager.php @@ -23,13 +23,15 @@ * @ingroup Bootstrap */ +namespace bootstrap; + /** * Class managing the Bootstrap framework. */ -class Bootstrap { +class BootstrapManager { - static private $bootstrap = null; + static private $bootstrapManagerSingleton = null; static private $moduleDescriptions = array( 'variables' => array( 'styles' => 'variables' ), 'mixins' => array( 'styles' => 'mixins' ), @@ -65,24 +67,24 @@ 'close' => array( 'styles' => 'close' ), // Components w/ JavaScript - 'modals' => array( 'styles' => 'modals', 'scripts' => 'bootstrap/js/modal.js' ), - 'tooltip' => array( 'styles' => 'tooltip', 'scripts' => 'bootstrap/js/tooltip.js' ), - 'popovers' => array( 'styles' => 'popovers', 'scripts' => 'bootstrap/js/popover.js', 'dependencies' => 'tooltip' ), - 'carousel' => array( 'styles' => 'carousel', 'scripts' => 'bootstrap/js/carousel.js' ), + 'modals' => array( 'styles' => 'modals', 'scripts' => 'modal' ), + 'tooltip' => array( 'styles' => 'tooltip', 'scripts' => 'tooltip' ), + 'popovers' => array( 'styles' => 'popovers', 'scripts' => 'popover', 'dependencies' => 'tooltip' ), + 'carousel' => array( 'styles' => 'carousel', 'scripts' => 'carousel' ), // Utility classes 'utilities' => array( 'styles' => 'utilities' ), 'responsive-utilities' => array( 'styles' => 'responsive-utilities' ), // JS-only components - 'affix' => array( 'scripts' => 'bootstrap/js/affix.js' ), - 'alert' => array( 'scripts' => 'bootstrap/js/alert.js' ), - 'button' => array( 'scripts' => 'bootstrap/js/button.js' ), - 'collapse' => array( 'scripts' => 'bootstrap/js/collapse.js' ), - 'dropdown' => array( 'scripts' => 'bootstrap/js/dropdown.js' ), - 'scrollspy' => array( 'scripts' => 'bootstrap/js/scrollspy.js' ), - 'tab' => array( 'scripts' => 'bootstrap/js/tab.js' ), - 'transition' => array( 'scripts' => 'bootstrap/js/transition.js' ), + 'affix' => array( 'scripts' => 'affix' ), + 'alert' => array( 'scripts' => 'alert' ), + 'button' => array( 'scripts' => 'button' ), + 'collapse' => array( 'scripts' => 'collapse' ), + 'dropdown' => array( 'scripts' => 'dropdown' ), + 'scrollspy' => array( 'scripts' => 'scrollspy' ), + 'tab' => array( 'scripts' => 'tab' ), + 'transition' => array( 'scripts' => 'transition' ), ); @@ -101,23 +103,23 @@ private $mModuleDescriptions; - public function __construct() { + protected function __construct() { $this->mModuleDescriptions = self::$moduleDescriptions; } /** * Returns the Bootstrap singleton. * - * @return Bootstrap + * @return BootstrapManager */ - public static function getBootstrap() { + public static function getBootstrapManager() { // if singleton was not yet created - if ( self::$bootstrap === null ) { + if ( self::$bootstrapManagerSingleton === null ) { self::initializeBootstrap(); } - return self::$bootstrap; + return self::$bootstrapManagerSingleton; } /** @@ -125,10 +127,10 @@ */ protected static function initializeBootstrap() { - self::$bootstrap = new Bootstrap(); + self::$bootstrapManagerSingleton = new BootstrapManager(); // add core Bootstrap modules - self::$bootstrap->addBootstrapModule( self::$coreModules ); + self::$bootstrapManagerSingleton->addBootstrapModule( self::$coreModules ); } /** @@ -138,14 +140,12 @@ */ public function addBootstrapModule( $modules ) { - $modules = (array)$modules; + $modules = (array) $modules; foreach ( $modules as $module ) { // if the module is known - if ( array_key_exists( $module, $this->mModuleDescriptions ) ) { - - global $wgResourceModules; + if ( isset( $this->mModuleDescriptions[ $module ] ) ) { $description = $this->mModuleDescriptions[ $module ]; @@ -159,30 +159,34 @@ $this->addBootstrapModule( $description[ 'dependencies' ] ); } - // add less files to $wgResourceModules - if ( isset( $description[ 'styles' ] ) ) { - - $wgResourceModules[ 'ext.bootstrap.styles' ][ 'styles' ] = - array_merge( - $wgResourceModules[ 'ext.bootstrap.styles' ][ 'styles' ], - (array) $description[ 'styles' ] - ); - } - - // add script files to $wgResourceModules - if ( isset( $description[ 'scripts' ] ) ) { - - $wgResourceModules[ 'ext.bootstrap.scripts' ][ 'scripts' ] = - array_merge( - $wgResourceModules[ 'ext.bootstrap.scripts' ][ 'scripts' ], - (array) $description[ 'scripts' ] - ); - - } + $this->addFilesToGlobalResourceModules( 'styles', $description, '.less' ); + $this->addFilesToGlobalResourceModules( 'scripts', $description, '.js' ); } } + } + + /** + * @param string $filetype 'styles'|'scripts' + * @param array|string $description + * @param $fileExt + * + * @internal param $relativePath + */ + protected function addFilesToGlobalResourceModules ( $filetype, $description, $fileExt ) { + + if ( isset( $description[ $filetype ] ) ) { + + $path = $GLOBALS[ 'wgResourceModules' ][ 'ext.bootstrap.' . $filetype ][ 'localBasePath' ]; + + $GLOBALS[ 'wgResourceModules' ][ 'ext.bootstrap.' . $filetype ][ $filetype ] = + array_merge( + $GLOBALS[ 'wgResourceModules' ][ 'ext.bootstrap.' . $filetype ][ $filetype ], + array_map( function ( $filename ) use ( $fileExt ) { return $filename . $fileExt; }, (array) $description[ $filetype ]) + ); + + } } /** @@ -194,18 +198,15 @@ } /** - * @param string $path * @param string $file + * @param string $remotePath + * + * @internal param string $path */ - public function addExternalModule( $path, $file ) { + public function addExternalModule( $file, $remotePath = '' ) { global $wgResourceModules; - - if ( !in_array( $path, $wgResourceModules[ 'ext.bootstrap.styles' ][ 'paths' ] ) ) { - $wgResourceModules[ 'ext.bootstrap.styles' ][ 'paths' ][ ] = $path; - } - - $wgResourceModules[ 'ext.bootstrap.styles' ][ 'styles' ][ ] = $file; + $wgResourceModules[ 'ext.bootstrap.styles' ][ 'external styles' ][ $file ] = $remotePath; } /** diff --git a/includes/Hooks.php b/includes/Hooks.php new file mode 100644 index 0000000..9160fe4 --- /dev/null +++ b/includes/Hooks.php @@ -0,0 +1,67 @@ +<?php +/** + * File holding the BootstrapManager class + * + * @copyright (C) 2013, Stephan Gambke + * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License, version 3 (or later) + * + * This file is part of the MediaWiki extension Bootstrap. + * The Bootstrap extension is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Bootstrap extension is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * @file + * @ingroup Bootstrap + */ + +namespace bootstrap; + +/** + * Class Hooks holds the Bootstrap extension hook handlers + * + * @package bootstrap + */ +class Hooks { + + + public static function onSetupAfterCache() { + + $localBasePath = $GLOBALS[ 'IP' ] . '/vendor/twitter/bootstrap'; + $remoteBasePath = $GLOBALS[ 'wgScriptPath' ] . '/vendor/twitter/bootstrap'; + + // register skeleton resource module with the Resource Loader + $GLOBALS[ 'wgResourceModules' ][ 'ext.bootstrap.styles' ] = array( + 'localBasePath' => $localBasePath . '/less', + 'remoteBasePath' => $remoteBasePath. '/less', + 'class' => 'bootstrap\ResourceLoaderBootstrapModule', + 'styles' => array(), + 'variables' => array( + 'icon-font-path' => "\"$remoteBasePath/fonts/\"", + ), + 'dependencies' => array(), + ); + + $GLOBALS[ 'wgResourceModules' ][ 'ext.bootstrap.scripts' ] = array( + 'localBasePath' => $localBasePath . '/js', + 'remoteBasePath' => $remoteBasePath. '/js', + 'scripts' => array(), + ); + + $GLOBALS[ 'wgResourceModules' ][ 'ext.bootstrap' ] = array( + 'dependencies' => array( 'ext.bootstrap.styles', 'ext.bootstrap.scripts' ), + ); + + return true; + + } + +} diff --git a/includes/ResourceLoaderBootstrapModule.php b/includes/ResourceLoaderBootstrapModule.php new file mode 100644 index 0000000..622139e --- /dev/null +++ b/includes/ResourceLoaderBootstrapModule.php @@ -0,0 +1,161 @@ +<?php +/** + * File holding the ResourceLoaderBootstrapModule class + * + * @copyright (C) 2013, Stephan Gambke + * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License, version 3 (or later) + * + * This file is part of the MediaWiki extension Bootstrap. + * The Bootstrap extension is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Bootstrap extension is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * @file + * @ingroup Bootstrap + */ + +namespace bootstrap; + +use lessc; +use ResourceLoader; +use ResourceLoaderContext; +use ResourceLoaderFileModule; + +/** + * ResourceLoader module based on local JavaScript/LESS files. + * + * Different to the behaviour of ResourceLoaderFileModule this module compiles all LESS files in one compile context. + * + * It recognizes the following additional fields in $wgResourceModules: + * * styles: array of LESS file names (with or without extension .less) + * * variables: array of key value pairs representing LESS variables, that will be added to the LESS script after all + * files imports, i.e. that may override any variable set in style files + * * paths: array of paths to search for style files; all these paths together represent one virtual file base and will + * be searched for a style file; this means it is not possible to include two LESS files with the same name + * even if in different paths + * + * @package Bootstrap + */ +class ResourceLoaderBootstrapModule extends ResourceLoaderFileModule { + + protected $variables = array(); + protected $paths = array(); + protected $extStyles = array(); + + protected $styleText = null; + + public function __construct( $options = array(), $localBasePath = null, $remoteBasePath = null + ) { + + parent::__construct( $options, $localBasePath, $remoteBasePath ); + + if ( isset( $options[ 'variables' ] ) ) { + $this->variables = $options[ 'variables' ]; + } + + if ( isset( $options[ 'paths' ] ) ) { + $this->paths = $options[ 'paths' ]; + } + + if ( isset( $options[ 'external styles' ] ) ) { + $this->extStyles = $options[ 'external styles' ]; + } + + } + + /** + * Get the compiled Bootstrap styles + * + * @param ResourceLoaderContext $context + * + * @return array + */ + public function getStyles( ResourceLoaderContext $context ) { + + if ( $this->styleText === null ) { + + $this->retrieveStylesFromCache( $context ); + + if ( $this->styleText === null ) { + + $this->compileStyles(); + $this->updateCache( $context ); + + } + } + + return array( 'all' => $this->styleText ); + } + + protected function getCacheKey( ResourceLoaderContext $context ) { + return wfMemcKey( 'ext', 'bootstrap', $context->getHash() ); + } + + protected function retrieveStylesFromCache( ResourceLoaderContext $context ) { + + // Try for cache hit + $cache = wfGetCache( CACHE_ANYTHING ); + $cacheResult = $cache->get( $this->getCacheKey( $context ) ); + + if ( is_array( $cacheResult ) ) { + + if ( $cacheResult[ 'storetime' ] >= filemtime( $GLOBALS[ 'IP' ] . '/LocalSettings.php' ) ) { + + $this->styleText = $cacheResult[ 'styles' ]; + + wfDebug( "ext.bootstrap: Cache hit: Got styles from cache.\n" ); + } else { + wfDebug( "ext.bootstrap: Cache miss: Cache outdated, LocalSettings have changed.\n" ); + } + } else { + wfDebug( "ext.bootstrap: Cache miss: Styles not found in cache.\n" ); + } + } + + protected function updateCache( ResourceLoaderContext $context ) { + + $cache = wfGetCache( CACHE_ANYTHING ); + $cache->set( $this->getCacheKey( $context ), array( 'styles' => $this->styleText, 'storetime' => time() ) ); + + } + + protected function compileStyles() { + + $parser = new \Less_Parser(); + $remotePath = $this->getRemotePath( '' ); + + try { + + foreach ( $this->styles as $style ) { + $parser->parseFile( $this->getLocalPath( $style ), $remotePath ); + } + + foreach ( $this->extStyles as $stylefile => $remotePath ) { + $parser->parseFile( $stylefile, $remotePath ); + } + + $parser->ModifyVars( $this->variables ); + + $this->styleText = $parser->getCss(); + + } catch ( \Exception $e ) { + wfDebug( $e->getMessage() ); + $this->styleText = '/* LESS compile error: ' . $e->getMessage() . '*/'; + } + + } + + public function supportsURLLoading() { + + return false; + } +} -- To view, visit https://gerrit.wikimedia.org/r/124275 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ibbc7b79f208fbee51d3b54f1d85f325cac909858 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Bootstrap Gerrit-Branch: master Gerrit-Owner: Foxtrott <[email protected]> _______________________________________________ MediaWiki-commits mailing list [email protected] https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
