diff options
Diffstat (limited to 'www/wiki/extensions/SemanticMediaWiki/includes/SMW_Outputs.php')
-rw-r--r-- | www/wiki/extensions/SemanticMediaWiki/includes/SMW_Outputs.php | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/www/wiki/extensions/SemanticMediaWiki/includes/SMW_Outputs.php b/www/wiki/extensions/SemanticMediaWiki/includes/SMW_Outputs.php new file mode 100644 index 00000000..2d2c1e4f --- /dev/null +++ b/www/wiki/extensions/SemanticMediaWiki/includes/SMW_Outputs.php @@ -0,0 +1,225 @@ +<?php + +/** + * This class attempts to provide safe yet simple means for managing data that is relevant + * for the final HTML output of MediaWiki. In particular, this concerns additions to the HTML + * header in the form of scripts of stylesheets. + * + * The problem is that many components in SMW create hypertext that should eventually be displayed. + * The normal way of accessing such text are functions of the form getText() which return a + * (hypertext) string. Such a string, however, might refer to styles or scripts that are also + * needed. It is not possible to directly add those scripts to the MediaWiki output, since the form + * of this output depends on the context in which the function is called. Many functions might be + * called both during parsing and directly in special pages that do not use the usual parsing and + * caching mechanisms. + * + * Ideally, all functions that generate hypertext with dependencies would also include parameters to + * record required scripts. Since this would require major API changes, the current solution is to have + * a "temporal" global storage for the required items, managed in this class. It is not safe to use + * such a global store across hooks -- you never know what happens in between! Hence, every function + * that creates SMW outputs that may require head items must afterwards clear the temporal store by + * writing its contents to the according output. + * + * @ingroup SMW + * + * @author Markus Krötzsch + */ +class SMWOutputs { + + /** + * Protected member for temporarily storing header items. + * Format $id => $headItem where $id is used only to avoid duplicate + * items in the time before they are forwarded to the output. + */ + protected static $headItems = []; + + /** + * Protected member for temporarily storing additional Javascript + * snippets. Format $id => $scriptText where $id is used only to + * avoid duplicate scripts in the time before they are forwarded + * to the output. + */ + protected static $scripts = []; + + /** + * Protected member for temporarily storing resource modules. + * + * @var array + */ + protected static $resourceModules = []; + + /** + * Protected member for temporarily storing resource modules. + * + * @var array + */ + protected static $resourceStyles = []; + + /** + * Adds a resource module to the parser output. + * + * @since 1.5.3 + * + * @param string $moduleName + */ + public static function requireResource( $moduleName ) { + self::$resourceModules[$moduleName] = $moduleName; + } + + /** + * @since 3.0 + * + * @param string $stylesName + */ + public static function requireStyle( $stylesName ) { + self::$resourceStyles[$stylesName] = $stylesName; + } + + /** + * Require the presence of header scripts, provided as strings with + * enclosing script tags. Note that the same could be achieved with + * requireHeadItems, but scripts use a special method "addScript" in + * MediaWiki OutputPage, hence we distinguish them. + * + * The id is used to avoid that the requirement for one script is + * recorded multiple times in SMWOutputs. + * + * @param string $id + * @param string $item + */ + public static function requireScript( $id, $script ) { + self::$scripts[$id] = $script; + } + + /** + * Adds head items that are not Resource Loader modules. Should only + * be used for custom head items such as RSS fedd links. + * + * The id is used to avoid that the requirement for one script is + * recorded multiple times in SMWOutputs. + * + * Support for calling this with the old constants SMW_HEADER_STYLE + * and SMW_HEADER_TOOLTIP will vanish in SMW 1.7 at the latest. + * + * @param mixed $id + * @param string $item + */ + public static function requireHeadItem( $id, $item = '' ) { + if ( is_numeric( $id ) ) { + switch ( $id ) { + case SMW_HEADER_TOOLTIP: + self::requireResource( 'ext.smw.tooltips' ); + break; + case SMW_HEADER_STYLE: + self::requireStyle( 'ext.smw.style' ); + break; + } + } else { + self::$headItems[$id] = $item; + } + } + + /** + * This function takes output requirements as can be found in a given ParserOutput + * object and puts them back in to the internal temporal requirement list from + * which they can be committed to some other output. It is needed when code that + * would normally call SMWOutputs::requireHeadItem() has need to use a full + * independent parser call (Parser::parse()) that produces its own parseroutput. + * If omitted, all output items potentially committed to this parseroutput during + * parsing will not be passed on to higher levels. + * + * Note that this is not required if the $parseroutput is further processed by + * MediaWiki, but there are cases where the output is discarded and only its text + * is used. + * + * @param ParserOutput $parserOutput + */ + static public function requireFromParserOutput( ParserOutput $parserOutput ) { + // Note: we do not attempt to recover which head items where scripts here. + + $parserOutputHeadItems = $parserOutput->getHeadItems(); + + self::$headItems = array_merge( (array)self::$headItems, $parserOutputHeadItems ); + + /// TODO Is the following needed? + if ( isset( $parserOutput->mModules ) ) { + foreach ( $parserOutput->mModules as $module ) { + self::$resourceModules[$module] = $module; + } + } + } + + /** + * Actually commit the collected requirements to a given parser that is about to parse + * what will later be the HTML output. This makes sure that HTML output based on the + * parser results contains all required output items. + * + * If the parser creates output for a normal wiki page, then the committed items will + * also become part of the page cache so that they will correctly be added to all page + * outputs built from this cache later on. + * + * @param Parser $parser + */ + static public function commitToParser( Parser $parser ) { + /// TODO find out and document when this b/c code can go away + if ( method_exists( $parser, 'getOutput' ) ) { + $po = $parser->getOutput(); + } else { + $po = $parser->mOutput; + } + + if ( isset( $po ) ) { + self::commitToParserOutput( $po ); + } + } + + /** + * Similar to SMWOutputs::commitToParser() but acting on a ParserOutput object. + * + * @param ParserOutput $parserOutput + */ + static public function commitToParserOutput( ParserOutput $parserOutput ) { + + foreach ( self::$scripts as $key => $script ) { + $parserOutput->addHeadItem( $script . "\n", $key ); + } + + foreach ( self::$headItems as $key => $item ) { + $parserOutput->addHeadItem( "\t\t" . $item . "\n", $key ); + } + + $parserOutput->addModuleStyles( array_values( self::$resourceStyles ) ); + $parserOutput->addModules( array_values( self::$resourceModules ) ); + + self::$resourceStyles = []; + self::$resourceModules = []; + self::$headItems = []; + } + + /** + * Actually commit the collected requirements to a given OutputPage object that + * will later generate the HTML output. This makes sure that HTML output contains + * all required output items. Note that there is no parser caching at this level of + * processing. In particular, data should not be committed to $wgOut in methods + * that run during page parsing, since these would not run next time when the page + * is produced from parser cache. + * + * @param OutputPage $output + */ + static public function commitToOutputPage( OutputPage $output ) { + foreach ( self::$scripts as $script ) { + $output->addScript( $script ); + } + foreach ( self::$headItems as $key => $item ) { + $output->addHeadItem( $key, "\t\t" . $item . "\n" ); + } + + $output->addModuleStyles( array_values( self::$resourceStyles ) ); + $output->addModules( array_values( self::$resourceModules ) ); + + self::$resourceStyles = []; + self::$resourceModules = []; + self::$headItems = []; + } + +} |