mediawiki-extensions-Visual.../maintenance/makeStaticLoader.php

342 lines
9 KiB
PHP
Raw Normal View History

<?php
$IP = getenv( 'MW_INSTALL_PATH' );
if ( $IP === false ) {
$IP = __DIR__ . '/../../..';
}
require_once $IP . '/maintenance/Maintenance.php';
/**
* A generator for creating a static HTML loading sequence
* for VisualEditor.
*
* Example usage:
*
* # Update our static files
* $ php maintenance/makeStaticLoader.php --target demo --write-file demos/ve/index.php
* $ php maintenance/makeStaticLoader.php --target test --write-file modules/ve/test/index.php
*
* @author Timo Tijhof, 2013
*/
class MakeStaticLoader extends Maintenance {
public function __construct() {
parent::__construct();
$this->addOption(
'target',
'Which target to use ("demo" or "test"). Default: demo',
false,
true
);
$this->addOption(
'indent',
'Indentation prefix to use (number of tabs or a string)',
false,
true
);
$this->addOption(
've-path',
'Override path to "VisualEditor/modules" (no trailing slash). Default by --target',
false,
true
);
$this->addOption(
'write-file',
'Automatically replace the "Generated by" sections in this file. Default: false',
false,
true
);
$this->addOption(
'fixdir',
'Embed the absolute path in require() statements. Defaults to relative path. '
. '(use this if you evaluate the resulting script in php-STDIN instead of from a file)',
false,
true
);
$this->addOption( 'section', 'head, body or both', false, true );
}
public function execute() {
global $wgResourceModules, $wgHtml5, $wgWellFormedXml;
$wgHtml5 = true;
$wgWellFormedXml = false;
$section = $this->getOption( 'section', 'both' );
$target = $this->getOption( 'target', 'demo' );
$indent = $this->getOption( 'indent', 2 );
$writeFile = $this->getOption( 'write-file', false );
if ( is_numeric( $indent ) ) {
$indent = str_repeat( "\t", $indent );
}
// Path to /modules/
$vePath = $this->getOption( 've-path',
$target === 'demo' ?
// From /demos/ve/index.php
'../../modules' :
// From /modules/ve/test/index.html
'../..'
);
// If we're running this script from STDIN,
// hardcode the full path
$i18nScript = $this->getOption( 'fixdir' ) ?
dirname( __DIR__ ) . '/VisualEditor.i18n.php' :
$vePath . '/../VisualEditor.i18n.php';
$self = isset( $_SERVER['PHP_SELF'] ) ? $_SERVER['PHP_SELF'] : ( lcfirst( __CLASS__ ) . '.php' );
$fakeModules = array(
// These are dependencies that exist in MediaWiki core (such as jquery.js), but we
// can't reference those modules as there is no reliable url to access them from
// standalone. This must also include dependencies like oojs and jquery.uls which
// are only registered by VisualEditor if they aren't registered by MediaWiki).
'jquery' => array(
'scripts' => array(
'jquery/jquery.js',
),
),
'jquery.client' => array(
'scripts' => array(
'jquery/jquery.client.js',
),
),
'oojs' => array(
'scripts' => array(
'oojs/oojs.js',
),
),
'oojs-ui' => array(
'scripts' => array(
'oojs-ui/oojs-ui.js',
),
'styles' => array(
'oojs-ui/oojs-ui.svg.css',
),
),
'jquery.uls.grid' => array(
'styles' => 'jquery.uls/css/jquery.uls.grid.css',
),
'jquery.uls.data' => array(
'scripts' => array(
'jquery.uls/src/jquery.uls.data.js',
'jquery.uls/src/jquery.uls.data.utils.js',
)
),
'jquery.uls.compact' => array(
'styles' => 'jquery.uls/css/jquery.uls.compact.css',
),
'jquery.uls' => array(
'scripts' => array(
'jquery.uls/src/jquery.uls.core.js',
'jquery.uls/src/jquery.uls.lcd.js',
'jquery.uls/src/jquery.uls.languagefilter.js',
'jquery.uls/src/jquery.uls.regionfilter.js',
),
'styles' => array(
'jquery.uls/css/jquery.uls.css',
'jquery.uls/css/jquery.uls.lcd.css',
),
),
'Standalone init' => array(
'headAdd' => '<script>
if (
document.createElementNS &&
document.createElementNS( \'http://www.w3.org/2000/svg\', \'svg\' ).createSVGRect
) {
document.write(
\'<link rel="stylesheet" \' +
\'href="' . $vePath . '/ve/ui/styles/ve.ui.Icons-vector.css">\'
);
} else {
document.write(
\'<link rel="stylesheet" \' +
\'href="' . $vePath . '/ve/ui/styles/ve.ui.Icons-raster.css">\'
);
}
</script>',
'bodyAdd' => '<script>
<?php
require ' . var_export( $i18nScript, true ) . ';
echo \'ve.init.platform.addMessages( \' . json_encode( $messages[\'en\'] ) . " );\n";
?>
ve.init.platform.setModulesUrl( \'' . $vePath . '\' );
</script>'
),
);
$modules = array(
// Dependencies for ext.visualEditor.base:
'jquery',
'oojs',
'oojs-ui',
'unicodejs.wordbreak',
// Dependencies for ext.visualEditor.standalone:
'ext.visualEditor.base',
'ext.visualEditor.standalone',
'Standalone init',
// Dependencies for ext.visualEditor.core:
'rangy',
// Dependencies for ext.visualEditor.language
'ext.visualEditor.core',
'jquery.uls.grid',
'jquery.uls.data',
'jquery.uls.compact',
'jquery.uls',
'ext.visualEditor.language',
);
$head = $body = '';
$resourceLoader = new ResourceLoader();
foreach ( $modules as $module ) {
if ( isset( $fakeModules[ $module ] ) ) {
$registry = $fakeModules[ $module ];
} else {
$moduleObj = $resourceLoader->getModule( $module );
if ( !$moduleObj ) {
echo "\nError: Module $module\n not found!\n";
exit( 1 );
}
$registry = isset( $wgResourceModules[$module] ) ?
$wgResourceModules[$module] :
$moduleObj->getDefinitionSummary( ResourceLoaderContext::newDummyContext() );
}
$headAdd = $bodyAdd = '';
if ( isset( $registry['styles'] ) && $target !== 'test' ){
foreach ( (array)$registry['styles'] as $path ) {
if ( strpos( $path, 've-mw/' ) === 0 ) {
continue;
}
$headAdd .= $indent . Html::element( 'link', array(
'rel' => 'stylesheet',
'href' => "$vePath/$path",
) ) . "\n";
}
}
if ( isset( $registry['scripts'] ) ) {
foreach ( (array)$registry['scripts'] as $path ) {
if ( strpos( $path, 've-mw/' ) === 0 ) {
continue;
}
$bodyAdd .= $indent . Html::element( 'script', array( 'src' => "$vePath/$path" ) ) . "\n";
}
}
if ( isset( $registry['debugScripts'] ) ) {
foreach ( (array)$registry['debugScripts'] as $path ) {
if ( strpos( $path, 've-mw/' ) === 0 ) {
continue;
}
$bodyAdd .= $indent . Html::element( 'script', array( 'src' => "$vePath/$path" ) ) . "\n";
}
}
if ( isset( $registry['headAdd'] ) ) {
$headAdd .= $indent . implode( "\n$indent", explode( "\n", $registry['headAdd'] ) ) . "\n";
}
if ( isset( $registry['bodyAdd'] ) ) {
$bodyAdd .= $indent . implode( "\n$indent", explode( "\n", $registry['bodyAdd'] ) ) . "\n";
}
if ( $headAdd ) {
$head .= "$indent<!-- $module -->\n$headAdd";
}
if ( $bodyAdd ) {
$body .= "$indent<!-- $module -->\n$bodyAdd";
}
}
$head = rtrim( $head );
$body = rtrim( $body );
// Output
if ( $writeFile ) {
$contents = is_readable( $writeFile ) ? file_get_contents( $writeFile ) : false;
if ( !$contents ) {
echo "\nError: Write file not readable or empty!\n";
exit( 1 );
}
$lines = explode( "\n", $contents . "\n" );
$inHead = $inBody = $inGenerated = false;
foreach ( $lines as $i => &$line ) {
$text = trim( $line );
if ( $text === '<head>' ) {
$inHead = true;
$inBody = false;
$inGenerated = false;
} elseif ( $text === '<body>' ) {
$inHead = false;
$inBody = true;
$inGenerated = false;
} elseif ( strpos( $text, '<!-- Generated by' ) === 0 ) {
// Only set $inGenerated if we're in a generated section
// that we want to replace (--section=body, don't replace head).
if ( $inHead ) {
if ( $section === 'both' || $section === 'head' ) {
$inGenerated = true;
if ( !$head ) {
$line = '';
} else {
$line = "$indent<!-- Generated by $self -->\n$head";
}
}
} elseif ( $inBody ) {
if ( $section === 'both' || $section === 'body' ) {
$inGenerated = true;
if ( !$body ) {
$line = '';
} else {
$line = "$indent<!-- Generated by $self -->\n$body";
}
}
}
} elseif ( $text === '' ) {
$inGenerated = false;
} else {
// Strip the lines directly connected to the "<!-- Generated by"
if ( $inGenerated ) {
unset( $lines[$i] );
}
}
}
if ( !file_put_contents( $writeFile, trim( implode( "\n", $lines ) ) . "\n" ) ) {
echo "\nError: Write to file failed!\n";
exit( 1 );
}
echo "Done!\n";
} else {
if ( $head ) {
if ( $section === 'both' ) {
echo "<head>\n\n$indent<!-- Generated by $self -->\n$head\n\n</head>";
} elseif ( $section === 'head' ) {
echo $head;
}
}
if ( $body ) {
if ( $section === 'both' ) {
echo "<body>\n\n$indent<!-- Generated by $self -->\n$body\n\n</body>\n";
} elseif ( $section === 'body' ) {
echo $body;
}
}
}
}
}
$maintClass = 'MakeStaticLoader';
require_once RUN_MAINTENANCE_IF_MAIN;