Merge "RCFilters: Style the Saved Links placeholder and add a title"
[lhc/web/wiklou.git] / includes / api / ApiParse.php
index 7d22d9c..91e49ab 100644 (file)
@@ -22,6 +22,8 @@
  * @file
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * @ingroup API
  */
@@ -278,6 +280,54 @@ class ApiParse extends ApiBase {
                $result_array['title'] = $titleObj->getPrefixedText();
                $result_array['pageid'] = $pageid ?: $pageObj->getId();
 
+               if ( $params['disabletoc'] ) {
+                       $p_result->setTOCEnabled( false );
+               }
+
+               if ( isset( $params['useskin'] ) ) {
+                       $factory = MediaWikiServices::getInstance()->getSkinFactory();
+                       $skin = $factory->makeSkin( Skin::normalizeKey( $params['useskin'] ) );
+               } else {
+                       $skin = null;
+               }
+
+               $outputPage = null;
+               if ( $skin || isset( $prop['headhtml'] ) || isset( $prop['categorieshtml'] ) ) {
+                       // Enabling the skin via 'useskin', 'headhtml', or 'categorieshtml'
+                       // gets OutputPage and Skin involved, which (among others) applies
+                       // these hooks:
+                       // - ParserOutputHooks
+                       // - Hook: LanguageLinks
+                       // - Hook: OutputPageParserOutput
+                       // - Hook: OutputPageMakeCategoryLinks
+                       $context = new DerivativeContext( $this->getContext() );
+                       $context->setTitle( $titleObj );
+                       $context->setWikiPage( $pageObj );
+
+                       if ( $skin ) {
+                               // Use the skin specified by 'useskin'
+                               $context->setSkin( $skin );
+                               // Context clones the skin, refetch to stay in sync. (T166022)
+                               $skin = $context->getSkin();
+                       } else {
+                               // Make sure the context's skin refers to the context. Without this,
+                               // $outputPage->getSkin()->getOutput() !== $outputPage which
+                               // confuses some of the output.
+                               $context->setSkin( $context->getSkin() );
+                       }
+
+                       $outputPage = new OutputPage( $context );
+                       $outputPage->addParserOutputMetadata( $p_result );
+                       $context->setOutput( $outputPage );
+
+                       if ( $skin ) {
+                               // Based on OutputPage::output()
+                               foreach ( $skin->getDefaultModules() as $group ) {
+                                       $outputPage->addModules( $group );
+                               }
+                       }
+               }
+
                if ( !is_null( $oldid ) ) {
                        $result_array['revid'] = intval( $oldid );
                }
@@ -286,10 +336,6 @@ class ApiParse extends ApiBase {
                        $result_array['redirects'] = $redirValues;
                }
 
-               if ( $params['disabletoc'] ) {
-                       $p_result->setTOCEnabled( false );
-               }
-
                if ( isset( $prop['text'] ) ) {
                        $result_array['text'] = $p_result->getText();
                        $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'text';
@@ -303,26 +349,26 @@ class ApiParse extends ApiBase {
                }
 
                if ( isset( $prop['langlinks'] ) ) {
-                       $langlinks = $p_result->getLanguageLinks();
-
-                       if ( $params['effectivelanglinks'] ) {
-                               // Link flags are ignored for now, but may in the future be
-                               // included in the result.
-                               $linkFlags = [];
-                               Hooks::run( 'LanguageLinks', [ $titleObj, &$langlinks, &$linkFlags ] );
+                       if ( $skin ) {
+                               $langlinks = $outputPage->getLanguageLinks();
+                       } else {
+                               $langlinks = $p_result->getLanguageLinks();
+                               // The deprecated 'effectivelanglinks' option depredates OutputPage
+                               // support via 'useskin'. If not already applied, then run just this
+                               // one hook of OutputPage::addParserOutputMetadata here.
+                               if ( $params['effectivelanglinks'] ) {
+                                       $linkFlags = [];
+                                       Hooks::run( 'LanguageLinks', [ $titleObj, &$langlinks, &$linkFlags ] );
+                               }
                        }
-               } else {
-                       $langlinks = false;
-               }
 
-               if ( isset( $prop['langlinks'] ) ) {
                        $result_array['langlinks'] = $this->formatLangLinks( $langlinks );
                }
                if ( isset( $prop['categories'] ) ) {
                        $result_array['categories'] = $this->formatCategoryLinks( $p_result->getCategories() );
                }
                if ( isset( $prop['categorieshtml'] ) ) {
-                       $result_array['categorieshtml'] = $this->categoriesHtml( $p_result->getCategories() );
+                       $result_array['categorieshtml'] = $outputPage->getSkin()->getCategories();
                        $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'categorieshtml';
                }
                if ( isset( $prop['links'] ) ) {
@@ -350,38 +396,42 @@ class ApiParse extends ApiBase {
                }
 
                if ( isset( $prop['headitems'] ) ) {
-                       $result_array['headitems'] = $this->formatHeadItems( $p_result->getHeadItems() );
+                       if ( $skin ) {
+                               $result_array['headitems'] = $this->formatHeadItems( $outputPage->getHeadItemsArray() );
+                       } else {
+                               $result_array['headitems'] = $this->formatHeadItems( $p_result->getHeadItems() );
+                       }
                        $this->addDeprecation( 'apiwarn-deprecation-parse-headitems', 'action=parse&prop=headitems' );
                }
 
                if ( isset( $prop['headhtml'] ) ) {
-                       $context = new DerivativeContext( $this->getContext() );
-                       $context->setTitle( $titleObj );
-                       $context->setWikiPage( $pageObj );
-
-                       // We need an OutputPage tied to $context, not to the
-                       // RequestContext at the root of the stack.
-                       $output = new OutputPage( $context );
-                       $output->addParserOutputMetadata( $p_result );
-
-                       $result_array['headhtml'] = $output->headElement( $context->getSkin() );
+                       $result_array['headhtml'] = $outputPage->headElement( $context->getSkin() );
                        $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'headhtml';
                }
 
                if ( isset( $prop['modules'] ) ) {
-                       $result_array['modules'] = array_values( array_unique( $p_result->getModules() ) );
-                       $result_array['modulescripts'] = array_values( array_unique( $p_result->getModuleScripts() ) );
-                       $result_array['modulestyles'] = array_values( array_unique( $p_result->getModuleStyles() ) );
+                       if ( $skin ) {
+                               $result_array['modules'] = $outputPage->getModules();
+                               $result_array['modulescripts'] = $outputPage->getModuleScripts();
+                               $result_array['modulestyles'] = $outputPage->getModuleStyles();
+                       } else {
+                               $result_array['modules'] = array_values( array_unique( $p_result->getModules() ) );
+                               $result_array['modulescripts'] = array_values( array_unique( $p_result->getModuleScripts() ) );
+                               $result_array['modulestyles'] = array_values( array_unique( $p_result->getModuleStyles() ) );
+                       }
                }
 
                if ( isset( $prop['jsconfigvars'] ) ) {
-                       $result_array['jsconfigvars'] =
-                               ApiResult::addMetadataToResultVars( $p_result->getJsConfigVars() );
+                       $jsconfigvars = $skin ? $outputPage->getJsConfigVars() : $p_result->getJsConfigVars();
+                       $result_array['jsconfigvars'] = ApiResult::addMetadataToResultVars( $jsconfigvars );
                }
 
                if ( isset( $prop['encodedjsconfigvars'] ) ) {
+                       $jsconfigvars = $skin ? $outputPage->getJsConfigVars() : $p_result->getJsConfigVars();
                        $result_array['encodedjsconfigvars'] = FormatJson::encode(
-                               $p_result->getJsConfigVars(), false, FormatJson::ALL_OK
+                               $jsconfigvars,
+                               false,
+                               FormatJson::ALL_OK
                        );
                        $result_array[ApiResult::META_SUBELEMENTS][] = 'encodedjsconfigvars';
                }
@@ -392,7 +442,11 @@ class ApiParse extends ApiBase {
                }
 
                if ( isset( $prop['indicators'] ) ) {
-                       $result_array['indicators'] = (array)$p_result->getIndicators();
+                       if ( $skin ) {
+                               $result_array['indicators'] = (array)$outputPage->getIndicators();
+                       } else {
+                               $result_array['indicators'] = (array)$p_result->getIndicators();
+                       }
                        ApiResult::setArrayType( $result_array['indicators'], 'BCkvp', 'name' );
                }
 
@@ -662,13 +716,6 @@ class ApiParse extends ApiBase {
                return $result;
        }
 
-       private function categoriesHtml( $categories ) {
-               $context = $this->getContext();
-               $context->getOutput()->addCategoryLinks( $categories );
-
-               return $context->getSkin()->getCategories();
-       }
-
        private function formatLinks( $links ) {
                $result = [];
                foreach ( $links as $ns => $nslinks ) {
@@ -794,7 +841,10 @@ class ApiParse extends ApiBase {
                        'wrapoutputclass' => 'mw-parser-output',
                        'pst' => false,
                        'onlypst' => false,
-                       'effectivelanglinks' => false,
+                       'effectivelanglinks' => [
+                               ApiBase::PARAM_DFLT => false,
+                               ApiBase::PARAM_DEPRECATED => true,
+                       ],
                        'section' => null,
                        'sectiontitle' => [
                                ApiBase::PARAM_TYPE => 'string',
@@ -816,6 +866,9 @@ class ApiParse extends ApiBase {
                        'preview' => false,
                        'sectionpreview' => false,
                        'disabletoc' => false,
+                       'useskin' => [
+                               ApiBase::PARAM_TYPE => array_keys( Skin::getAllowedSkins() ),
+                       ],
                        'contentformat' => [
                                ApiBase::PARAM_TYPE => ContentHandler::getAllContentFormats(),
                        ],