X-Git-Url: http://git.cyclocoop.org/%7B%24admin_url%7Dcompta/comptes/journal.php?a=blobdiff_plain;f=includes%2FEditPage.php;h=c7b014a7ff45f58cb68d9804f6ca3bcb024f676c;hb=47437e0653542aae57ea456b24486efb48ee8aac;hp=78455fb0aa289081b1e887f93b090f351d15cc4e;hpb=74fa6071c2e5be4a182c4bf6863bee095ab0c03e;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/EditPage.php b/includes/EditPage.php index 78455fb0aa..c7b014a7ff 100644 --- a/includes/EditPage.php +++ b/includes/EditPage.php @@ -20,6 +20,8 @@ * @file */ +use MediaWiki\Logger\LoggerFactory; + /** * The edit page/HTML interface (split from Article) * The actual database and text munging is still in Article, @@ -258,9 +260,6 @@ class EditPage { /** @var bool */ public $tooBig = false; - /** @var bool */ - public $kblength = false; - /** @var bool */ public $missingComment = false; @@ -394,6 +393,9 @@ class EditPage { /** @var bool */ protected $edit; + /** @var bool|int */ + protected $contentLength = false; + /** * @var bool Set in ApiEditPage, based on ContentHandler::allowsDirectApiEditing */ @@ -1249,9 +1251,31 @@ class EditPage { return $handler->makeEmptyContent(); } else { - # nasty side-effect, but needed for consistency - $this->contentModel = $rev->getContentModel(); - $this->contentFormat = $rev->getContentFormat(); + // Content models should always be the same since we error + // out if they are different before this point. + $logger = LoggerFactory::getInstance( 'editpage' ); + if ( $this->contentModel !== $rev->getContentModel() ) { + $logger->warning( "Overriding content model from current edit {prev} to {new}", [ + 'prev' => $this->contentModel, + 'new' => $rev->getContentModel(), + 'title' => $this->getTitle()->getPrefixedDBkey(), + 'method' => __METHOD__ + ] ); + $this->contentModel = $rev->getContentModel(); + } + + // Given that the content models should match, the current selected + // format should be supported. + if ( !$content->isSupportedFormat( $this->contentFormat ) ) { + $logger->warning( "Current revision content format unsupported. Overriding {prev} to {new}", [ + + 'prev' => $this->contentFormat, + 'new' => $rev->getContentFormat(), + 'title' => $this->getTitle()->getPrefixedDBkey(), + 'method' => __METHOD__ + ] ); + $this->contentFormat = $rev->getContentFormat(); + } return $content; } @@ -1286,7 +1310,7 @@ class EditPage { return $this->mPreloadContent; } - $handler = ContentHandler::getForTitle( $this->getTitle() ); + $handler = ContentHandler::getForModelID( $this->contentModel ); if ( $preload === '' ) { return $handler->makeEmptyContent(); @@ -1450,7 +1474,7 @@ class EditPage { case self::AS_CANNOT_USE_CUSTOM_MODEL: case self::AS_PARSE_ERROR: - $wgOut->addWikiText( '
' . $status->getWikiText() . '
' ); + $wgOut->addWikiText( '
' . "\n" . $status->getWikiText() . '
' ); return true; case self::AS_SUCCESS_NEW_ARTICLE: @@ -1527,7 +1551,7 @@ class EditPage { // is if an extension hook aborted from inside ArticleSave. // Render the status object into $this->hookError // FIXME this sucks, we should just use the Status object throughout - $this->hookError = '
' . $status->getWikiText() . + $this->hookError = '
' ."\n" . $status->getWikiText() . '
'; return true; } @@ -1750,8 +1774,8 @@ class EditPage { return $status; } - $this->kblength = (int)( strlen( $this->textbox1 ) / 1024 ); - if ( $this->kblength > $wgMaxArticleSize ) { + $this->contentLength = strlen( $this->textbox1 ); + if ( $this->contentLength > $wgMaxArticleSize * 1024 ) { // Error will be displayed by showEditForm() $this->tooBig = true; $status->setResult( false, self::AS_CONTENT_TOO_BIG ); @@ -2038,8 +2062,8 @@ class EditPage { } // Check for length errors again now that the section is merged in - $this->kblength = (int)( strlen( $this->toEditText( $content ) ) / 1024 ); - if ( $this->kblength > $wgMaxArticleSize ) { + $this->contentLength = strlen( $this->toEditText( $content ) ); + if ( $this->contentLength > $wgMaxArticleSize * 1024 ) { $this->tooBig = true; $status->setResult( false, self::AS_MAX_ARTICLE_SIZE_EXCEEDED ); return $status; @@ -2690,8 +2714,9 @@ class EditPage { $wgOut->addHTML( Html::rawElement( 'div', [ 'class' => 'hiddencats' ], Linker::formatHiddenCategories( $this->page->getHiddenCategories() ) ) ); - $wgOut->addHTML( Html::rawElement( 'div', [ 'class' => 'limitreport' ], - self::getPreviewLimitReport( $this->mParserOutput ) ) ); + if ( $this->mParserOutput ) { + $wgOut->setLimitReportData( $this->mParserOutput->getLimitReportData() ); + } $wgOut->addModules( 'mediawiki.action.edit.collapsibleFooter' ); @@ -2889,6 +2914,9 @@ class EditPage { ); } if ( $this->getTitle()->isSubpageOf( $wgUser->getUserPage() ) ) { + $wgOut->wrapWikiMsg( '
$1
', + $this->isCssSubpage ? 'usercssispublic' : 'userjsispublic' + ); if ( $this->formtype !== 'preview' ) { if ( $this->isCssSubpage && $wgAllowUserCss ) { $wgOut->wrapWikiMsg( @@ -2944,15 +2972,15 @@ class EditPage { 'wrap' => "
\n$1
" ] ); } - if ( $this->kblength === false ) { - $this->kblength = (int)( strlen( $this->textbox1 ) / 1024 ); + if ( $this->contentLength === false ) { + $this->contentLength = strlen( $this->textbox1 ); } - if ( $this->tooBig || $this->kblength > $wgMaxArticleSize ) { + if ( $this->tooBig || $this->contentLength > $wgMaxArticleSize * 1024 ) { $wgOut->wrapWikiMsg( "
\n$1\n
", [ 'longpageerror', - $wgLang->formatNum( $this->kblength ), + $wgLang->formatNum( round( $this->contentLength / 1024, 3 ) ), $wgLang->formatNum( $wgMaxArticleSize ) ] ); @@ -3026,7 +3054,7 @@ class EditPage { * @param string $summary The text of the summary to display */ protected function showSummaryInput( $isSubjectPreview, $summary = "" ) { - global $wgOut, $wgContLang; + global $wgOut; # Add a class if 'missingsummary' is triggered to allow styling of the summary line $summaryClass = $this->missingSummary ? 'mw-summarymissed' : 'mw-summary'; if ( $isSubjectPreview ) { @@ -3038,7 +3066,6 @@ class EditPage { return; } } - $summary = $wgContLang->recodeForEdit( $summary ); $labelText = wfMessage( $isSubjectPreview ? 'subject' : 'summary' )->parse(); list( $label, $input ) = $this->getSummaryInput( $summary, @@ -3419,41 +3446,12 @@ HTML return ''; } - $limitReport = Html::rawElement( 'div', [ 'class' => 'mw-limitReportExplanation' ], - wfMessage( 'limitreport-title' )->parseAsBlock() + return ResourceLoader::makeInlineScript( + ResourceLoader::makeConfigSetScript( + [ 'wgPageParseReport' => $output->getLimitReportData() ], + true + ) ); - - // Show/hide animation doesn't work correctly on a table, so wrap it in a div. - $limitReport .= Html::openElement( 'div', [ 'class' => 'preview-limit-report-wrapper' ] ); - - $limitReport .= Html::openElement( 'table', [ - 'class' => 'preview-limit-report wikitable' - ] ) . - Html::openElement( 'tbody' ); - - foreach ( $output->getLimitReportData() as $key => $value ) { - if ( Hooks::run( 'ParserLimitReportFormat', - [ $key, &$value, &$limitReport, true, true ] - ) ) { - $keyMsg = wfMessage( $key ); - $valueMsg = wfMessage( [ "$key-value-html", "$key-value" ] ); - if ( !$valueMsg->exists() ) { - $valueMsg = new RawMessage( '$1' ); - } - if ( !$keyMsg->isDisabled() && !$valueMsg->isDisabled() ) { - $limitReport .= Html::openElement( 'tr' ) . - Html::rawElement( 'th', null, $keyMsg->parse() ) . - Html::rawElement( 'td', null, $valueMsg->params( $value )->parse() ) . - Html::closeElement( 'tr' ); - } - } - } - - $limitReport .= Html::closeElement( 'tbody' ) . - Html::closeElement( 'table' ) . - Html::closeElement( 'div' ); - - return $limitReport; } protected function showStandardInputs( &$tabindex = 2 ) { @@ -3513,13 +3511,12 @@ HTML if ( Hooks::run( 'EditPageBeforeConflictDiff', [ &$this, &$wgOut ] ) ) { $stats = $wgOut->getContext()->getStats(); $stats->increment( 'edit.failures.conflict' ); - if ( $this->mTitle->isTalkPage() ) { - $stats->increment( 'edit.failures.conflict.byType.talk' ); - } else { - $stats->increment( 'edit.failures.conflict.byType.subject' ); - } - if ( $this->mTitle->getNamespace() === NS_PROJECT ) { - $stats->increment( 'edit.failures.conflict.byNamespace.project' ); + // Only include 'standard' namespaces to avoid creating unknown numbers of statsd metrics + if ( + $this->mTitle->getNamespace() >= NS_MAIN && + $this->mTitle->getNamespace() <= NS_CATEGORY_TALK + ) { + $stats->increment( 'edit.failures.conflict.byNamespaceId.' . $this->mTitle->getNamespace() ); } $wgOut->wrapWikiMsg( '

$1

', "yourdiff" ); @@ -3648,7 +3645,7 @@ HTML * @return string */ function getPreviewText() { - global $wgOut, $wgUser, $wgRawHtml, $wgLang; + global $wgOut, $wgRawHtml, $wgLang; global $wgAllowUserCss, $wgAllowUserJs; $stats = $wgOut->getContext()->getStats(); @@ -3702,10 +3699,6 @@ HTML $note = wfMessage( 'previewnote' )->plain() . ' ' . $continueEditing; } - $parserOptions = $this->page->makeParserOptions( $this->mArticle->getContext() ); - $parserOptions->setIsPreview( true ); - $parserOptions->setIsSectionPreview( !is_null( $this->section ) && $this->section !== '' ); - # don't parse non-wikitext pages, show message about preview if ( $this->mTitle->isCssJsSubpage() || $this->mTitle->isCssOrJsPage() ) { if ( $this->mTitle->isCssJsSubpage() ) { @@ -3749,18 +3742,9 @@ HTML ContentHandler::runLegacyHooks( 'EditPageGetPreviewText', $hook_args ); Hooks::run( 'EditPageGetPreviewContent', $hook_args ); - $parserOptions->enableLimitReport(); - - # For CSS/JS pages, we should have called the ShowRawCssJs hook here. - # But it's now deprecated, so never mind - - $pstContent = $content->preSaveTransform( $this->mTitle, $wgUser, $parserOptions ); - $scopedCallback = $parserOptions->setupFakeRevision( - $this->mTitle, $pstContent, $wgUser ); - $parserOutput = $pstContent->getParserOutput( $this->mTitle, null, $parserOptions ); - - $parserOutput->setEditSectionTokens( false ); // no section edit links - $previewHTML = $parserOutput->getText(); + $parserResult = $this->doPreviewParse( $content ); + $parserOutput = $parserResult['parserOutput']; + $previewHTML = $parserResult['html']; $this->mParserOutput = $parserOutput; $wgOut->addParserOutputMetadata( $parserOutput ); @@ -3768,7 +3752,6 @@ HTML $note .= "\n\n" . implode( "\n\n", $parserOutput->getWarnings() ); } - ScopedCallback::consume( $scopedCallback ); } catch ( MWContentSerializationException $ex ) { $m = wfMessage( 'content-failed-to-parse', @@ -3799,6 +3782,41 @@ HTML return $previewhead . $previewHTML . $this->previewTextAfterContent; } + /** + * Get parser options for a preview + * @return ParserOptions + */ + protected function getPreviewParserOptions() { + $parserOptions = $this->page->makeParserOptions( $this->mArticle->getContext() ); + $parserOptions->setIsPreview( true ); + $parserOptions->setIsSectionPreview( !is_null( $this->section ) && $this->section !== '' ); + $parserOptions->enableLimitReport(); + return $parserOptions; + } + + /** + * Parse the page for a preview. Subclasses may override this class, in order + * to parse with different options, or to otherwise modify the preview HTML. + * + * @param Content @content The page content + * @return Associative array with keys: + * - parserOutput: The ParserOutput object + * - html: The HTML to be displayed + */ + protected function doPreviewParse( Content $content ) { + global $wgUser; + $parserOptions = $this->getPreviewParserOptions(); + $pstContent = $content->preSaveTransform( $this->mTitle, $wgUser, $parserOptions ); + $scopedCallback = $parserOptions->setupFakeRevision( + $this->mTitle, $pstContent, $wgUser ); + $parserOutput = $pstContent->getParserOutput( $this->mTitle, null, $parserOptions ); + ScopedCallback::consume( $scopedCallback ); + $parserOutput->setEditSectionTokens( false ); // no section edit links + return [ + 'parserOutput' => $parserOutput, + 'html' => $parserOutput->getText() ]; + } + /** * @return array */ @@ -4160,11 +4178,9 @@ HTML * @return string */ protected function safeUnicodeOutput( $text ) { - global $wgContLang; - $codedText = $wgContLang->recodeForEdit( $text ); return $this->checkUnicodeCompliantBrowser() - ? $codedText - : $this->makeSafe( $codedText ); + ? $text + : $this->makesafe( $text ); } /**