jenkins-bot has submitted this change and it was merged. Change subject: Allow server-side service rendering ......................................................................
Allow server-side service rendering Generates html to allow server-side PNG generation Change-Id: I86ac640b2ae02247c718c7a794b011130d15ee94 --- M Graph.body.php M Graph.php 2 files changed, 89 insertions(+), 45 deletions(-) Approvals: Yurik: Looks good to me, approved jenkins-bot: Verified diff --git a/Graph.body.php b/Graph.body.php index 9b89931..4cefa99 100644 --- a/Graph.body.php +++ b/Graph.body.php @@ -12,7 +12,6 @@ use FormatJson; use Html; use JsonConfig\JCContent; -use JsonConfig\JCContentView; use JsonConfig\JCSingleton; use Parser; use ParserOptions; @@ -40,17 +39,12 @@ array $args, Parser $parser, \PPFrame $frame ) { // expand template arguments and other wiki markup - // TODO: we might want to add some magic $args parameter to disable template expansion - $input = $parser->recursiveTagParse( $input, $frame ); - - $content = new Content( $input, 'graph-temp.json', true ); - if ( $content->isValid() ) { - self::updateParser( $parser->getOutput() ); - } - return $content->getHtml(); + $input = $parser->recursivePreprocess( $input, $frame ); + self::updateParserOutput( $parser->getOutput() ); + return self::buildHtml( $input, $parser->getTitle(), $parser->getRevisionId() ); } - public static function updateParser( ParserOutput $parserOutput ) { + public static function updateParserOutput( ParserOutput $parserOutput ) { global $wgGraphDataDomains; $parserOutput->addJsConfigVars( 'wgGraphDataDomains', $wgGraphDataDomains ); $parserOutput->addModules( 'ext.graph' ); @@ -71,6 +65,61 @@ } return true; } + + /** + * @param string $jsonText + * @param Title $title + * @param int $revid + * @return string + */ + public static function buildHtml( $jsonText, $title, $revid ) { + + global $wgGraphImgServiceUrl; + static $hashIds = array(); + + $status = FormatJson::parse( $jsonText, FormatJson::TRY_FIXING | FormatJson::STRIP_COMMENTS ); + if ( !$status->isGood() ) { + return $status->getWikiText(); + } + + $json = FormatJson::encode( $status->getValue(), false, FormatJson::ALL_OK ); + + $spanAttrs = array( + 'class' => 'mw-wiki-graph', + 'data-spec' => $json, + ); + + // ensure that the same ID is not used multiple times, + // e.g. identical graph is included multiple times + $id = 'mw-graph-' . sha1( $json ); + if ( array_key_exists( $id, $hashIds ) ) { + $hashIds[$id] += 1; + $id = $id . '-' . $hashIds[$id]; + } else { + $hashIds[$id] = 1; + } + $spanAttrs['id'] = $id; + + if ( $wgGraphImgServiceUrl ) { + $title = !$title ? '' : rawurlencode( str_replace( $title->getText(), ' ', '_' ) ); + $revid = rawurlencode( (string)$revid ) ?: '0'; + $url = sprintf( $wgGraphImgServiceUrl, $title, $revid, $id ); + + // TODO: Use "width" and "height" from the definition if available + // In some cases image might still be larger - need to investigate + $img = Html::rawElement( 'img', array( 'src' => $url ) ); + + $backendImgLinks = + Html::inlineScript( 'if(!mw.window){document.write(' . + FormatJson::encode( $img, false, FormatJson::UTF8_OK ) . + ');}' ) . + Html::rawElement( 'noscript', array(), $img ); + } else { + $backendImgLinks = ''; + } + + return Html::element( 'span', $spanAttrs ) . $backendImgLinks; + } } /** @@ -89,40 +138,29 @@ class Content extends JCContent { public function getWikitextForTransclusion() { - return $this->getHtml(); + // + // TODO: Somehow we need to avoid wgParser here + global $wgParser; + Singleton::updateParserOutput( $wgParser->getOutput() ); + return Singleton::buildHtml( + $this->getNativeData(), + $wgParser->getTitle(), + $wgParser->getRevisionId() ); } - public function getParserOutput( Title $title, $revId = null, ParserOptions $options = null, - $generateHtml = true ) { - return Singleton::updateParser( parent::getParserOutput( $title, $revId, $options, $generateHtml ) ); + protected function fillParserOutput( Title $title, $revId, ParserOptions $options, $generateHtml, + ParserOutput &$output ) { + global $wgParser; + $text = $this->getNativeData(); + $parser = $wgParser->getFreshParser(); +// $output = $parser->parse( $text, $title, $options, true, true, $revId ); + $text = $parser->preprocess( $text, $title, $options, $revId ); + + Singleton::updateParserOutput( $output ); + $output->setText( $generateHtml ? Singleton::buildHtml( $text, $title, $revId ) : '' ); } - protected function createDefaultView() { - return new ContentView(); - } -} - -class ContentView extends JCContentView { - - /** - * Render JCContent object as HTML - * @param JCContent $content - * @return string - */ - public function valueToHtml( JCContent $content ) { - return Html::element( 'div', array( - 'class' => 'mw-wiki-graph', - 'data-spec' => FormatJson::encode( $content->getData(), false, FormatJson::UTF8_OK ), - ) ); - } - - /** - * Returns default content for this object. - * The returned valued does not have to be valid JSON - * @param string $modelId - * @return string - */ - public function getDefault( $modelId ) { - return '{}'; + public function getCompactJson() { + return FormatJson::encode( $this->getData(), false, FormatJson::ALL_OK ); } } diff --git a/Graph.php b/Graph.php index 81aa27e..e2411a2 100644 --- a/Graph.php +++ b/Graph.php @@ -31,21 +31,27 @@ $graphBodyFile = __DIR__ . DIRECTORY_SEPARATOR . 'Graph.body.php'; $wgAutoloadClasses['Graph\Singleton'] = $graphBodyFile; $wgAutoloadClasses['Graph\Content'] = $graphBodyFile; -$wgAutoloadClasses['Graph\ContentView'] = $graphBodyFile; unset( $graphBodyFile ); /** - * @var bool Set to true to enable <graph> tag in wiki markup + * @var bool $wgEnableGraphParserTag Set to true to enable <graph> tag in wiki markup */ $wgEnableGraphParserTag = false; -/** - * @var false|string[] a list of domains that the vega code is allowed to pull data from. +/** @var false|string[] $wgGraphDataDomains a list of domains that the vega code is allowed to pull data from. * If false, there are no restrictions. An empty list disables any external data (inline only). * NOTE: Setting this value to anything other than 'false' will also enable safe mode formula/filter evaluation */ $wgGraphDataDomains = array(); +/** @var string|false $wgGraphImgServiceUrl A format string to form a backend service request for the img. + * For example: '/api/v1/pages/%1$s/graph/%2$s/%3$s.png' + * Parameters will be supplied in this order: title, revid, graph-hash-id + * All parameters will be escaped with rawurlencode() + * If the value is false, no <noscript> urls will be generated + */ +$wgGraphImgServiceUrl = false; + $wgHooks['ParserFirstCallInit'][] = 'Graph\Singleton::onParserFirstCallInit'; $wgHooks['EditPage::showEditForm:initial'][] = 'Graph\Singleton::editPageShowEditFormInitial'; -- To view, visit https://gerrit.wikimedia.org/r/182955 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I86ac640b2ae02247c718c7a794b011130d15ee94 Gerrit-PatchSet: 4 Gerrit-Project: mediawiki/extensions/Graph Gerrit-Branch: master Gerrit-Owner: Yurik <yu...@wikimedia.org> Gerrit-Reviewer: MaxSem <maxsem.w...@gmail.com> Gerrit-Reviewer: Milimetric <dandree...@wikimedia.org> Gerrit-Reviewer: Yurik <yu...@wikimedia.org> Gerrit-Reviewer: Yuvipanda <yuvipa...@gmail.com> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits