abstract class ApiFormatBase extends ApiBase {
private $mIsHtml, $mFormat, $mUnescapeAmps, $mHelp;
private $mBuffer, $mDisabled = false;
+ private $mIsWrappedHtml = false;
protected $mForceDefaultParams = false;
/**
$this->mIsHtml = ( substr( $format, -2, 2 ) === 'fm' ); // ends with 'fm'
if ( $this->mIsHtml ) {
$this->mFormat = substr( $format, 0, -2 ); // remove ending 'fm'
+ $this->mIsWrappedHtml = $this->getMain()->getCheck( 'wrappedhtml' );
} else {
$this->mFormat = $format;
}
return $this->mIsHtml;
}
+ /**
+ * Returns true when the special wrapped mode is enabled.
+ * @since 1.27
+ * @return bool
+ */
+ protected function getIsWrappedHtml() {
+ return $this->mIsWrappedHtml;
+ }
+
/**
* Disable the formatter.
*
* Initialize the printer function and prepare the output headers.
* @param bool $unused Always false since 1.25
*/
- function initPrinter( $unused = false ) {
+ public function initPrinter( $unused = false ) {
if ( $this->mDisabled ) {
return;
}
- $mime = $this->getIsHtml() ? 'text/html' : $this->getMimeType();
+ $mime = $this->getIsWrappedHtml()
+ ? 'text/mediawiki-api-prettyprint-wrapped'
+ : ( $this->getIsHtml() ? 'text/html' : $this->getMimeType() );
// Some printers (ex. Feed) do their own header settings,
// in which case $mime will be set to null
$out->addModuleStyles( 'mediawiki.apipretty' );
$out->setPageTitle( $context->msg( 'api-format-title' ) );
- // When the format without suffix 'fm' is defined, there is a non-html version
- if ( $this->getMain()->getModuleManager()->isDefined( $lcformat, 'format' ) ) {
- $msg = $context->msg( 'api-format-prettyprint-header' )->params( $format, $lcformat );
- } else {
- $msg = $context->msg( 'api-format-prettyprint-header-only-html' )->params( $format );
- }
+ if ( !$this->getIsWrappedHtml() ) {
+ // When the format without suffix 'fm' is defined, there is a non-html version
+ if ( $this->getMain()->getModuleManager()->isDefined( $lcformat, 'format' ) ) {
+ $msg = $context->msg( 'api-format-prettyprint-header' )->params( $format, $lcformat );
+ } else {
+ $msg = $context->msg( 'api-format-prettyprint-header-only-html' )->params( $format );
+ }
- $header = $msg->parseAsBlock();
- $out->addHTML(
- Html::rawElement( 'div', array( 'class' => 'api-pretty-header' ),
- ApiHelp::fixHelpLinks( $header )
- )
- );
+ $header = $msg->parseAsBlock();
+ $out->addHTML(
+ Html::rawElement( 'div', [ 'class' => 'api-pretty-header' ],
+ ApiHelp::fixHelpLinks( $header )
+ )
+ );
+ }
- if ( Hooks::run( 'ApiFormatHighlight', array( $context, $result, $mime, $format ) ) ) {
+ if ( Hooks::run( 'ApiFormatHighlight', [ $context, $result, $mime, $format ] ) ) {
$out->addHTML(
- Html::element( 'pre', array( 'class' => 'api-pretty-content' ), $result )
+ Html::element( 'pre', [ 'class' => 'api-pretty-content' ], $result )
);
}
- // API handles its own clickjacking protection.
- // Note, that $wgBreakFrames will still override $wgApiFrameOptions for format mode.
- $out->allowClickjacking();
- $out->output();
+ if ( $this->getIsWrappedHtml() ) {
+ // This is a special output mode mainly intended for ApiSandbox use
+ $time = microtime( true ) - $this->getConfig()->get( 'RequestTime' );
+ $json = FormatJson::encode(
+ [
+ 'html' => $out->getHTML(),
+ 'modules' => array_values( array_unique( array_merge(
+ $out->getModules(),
+ $out->getModuleScripts(),
+ $out->getModuleStyles()
+ ) ) ),
+ 'time' => round( $time * 1000 ),
+ ],
+ false, FormatJson::ALL_OK
+ );
+
+ // Bug 66776: wfMangleFlashPolicy() is needed to avoid a nasty bug in
+ // Flash, but what it does isn't friendly for the API, so we need to
+ // work around it.
+ if ( preg_match( '/\<\s*cross-domain-policy\s*\>/i', $json ) ) {
+ $json = preg_replace(
+ '/\<(\s*cross-domain-policy\s*)\>/i', '\\u003C$1\\u003E', $json
+ );
+ }
+
+ echo $json;
+ } else {
+ // API handles its own clickjacking protection.
+ // Note, that $wgBreakFrames will still override $wgApiFrameOptions for format mode.
+ $out->allowClickjacking();
+ $out->output();
+ }
} else {
// For non-HTML output, clear all errors that might have been
// displayed if display_errors=On
return $this->mBuffer;
}
+ public function getAllowedParams() {
+ $ret = [];
+ if ( $this->getIsHtml() ) {
+ $ret['wrappedhtml'] = [
+ ApiBase::PARAM_DFLT => false,
+ ApiBase::PARAM_HELP_MSG => 'apihelp-format-param-wrappedhtml',
+
+ ];
+ }
+ return $ret;
+ }
+
protected function getExamplesMessages() {
- return array(
+ return [
'action=query&meta=siteinfo&siprop=namespaces&format=' . $this->getModuleName()
- => array( 'apihelp-format-example-generic', $this->getFormat() )
- );
+ => [ 'apihelp-format-example-generic', $this->getFormat() ]
+ ];
}
public function getHelpUrls() {
}
// Armor links (bug 61362)
- $masked = array();
+ $masked = [];
$text = preg_replace_callback( '#<a .*?</a>#', function ( $matches ) use ( &$masked ) {
$sha = sha1( $matches[0] );
$masked[$sha] = $matches[0];