diff --git a/ApiVisualEditor.php b/ApiVisualEditor.php index a649128731..dd575448b5 100644 --- a/ApiVisualEditor.php +++ b/ApiVisualEditor.php @@ -467,19 +467,33 @@ class ApiVisualEditor extends ApiBase { $wikipage = WikiPage::factory( $page ); $popts = $wikipage->makeParserOptions( 'canonical' ); $cached = ParserCache::singleton()->get( $article, $popts, true ); + $isOldRevision = isset( $params['oldid'] ) && $params['oldid'] != 0 && + $params['oldid'] != $page->getLatestRevID(); + $links = array( + // Array of linked pages that are missing + 'missing' => array(), + // For current revisions: true (treat all non-missing pages as existing) + // For old revisions: array of linked pages that exist + 'extant' => $isOldRevision ? array() : true, + ); if ( $cached ) { foreach ( $cached->getLinks() as $ns => $dbks ) { foreach ( $dbks as $dbk => $id ) { - $links[ Title::makeTitle( $ns, $dbk )->getPrefixedText() ] = array( - 'missing' => $id == 0 - ); + $pft = Title::makeTitle( $ns, $dbk )->getPrefixedText(); + if ( $id == 0 ) { + $links['missing'][] = $pft; + } elseif ( $isOldRevision ) { + $links['extant'][] = $pft; + } } } } - - $links[$page->getPrefixedText()] = array( - 'missing' => !$page->exists() - ); + // Add information about current page + if ( !$page->exists() ) { + $links['missing'][] = $page->getPrefixedText(); + } elseif ( $isOldRevision ) { + $links['extant'][] = $page->getPrefixedText(); + } // On parser cache miss, just don't bother populating red link data diff --git a/modules/ve-mw/init/ve.init.mw.LinkCache.js b/modules/ve-mw/init/ve.init.mw.LinkCache.js index 98a619d5eb..5abb7df09d 100644 --- a/modules/ve-mw/init/ve.init.mw.LinkCache.js +++ b/modules/ve-mw/init/ve.init.mw.LinkCache.js @@ -47,6 +47,32 @@ } ); }; + /** + * Enable or disable automatic assumption of existence. + * + * While enabled, any get() for a title that's not already in the cache will return + * { missing: false } and write that to the cache. + * + * @param {boolean} assume Assume all uncached titles exist + */ + ve.init.mw.LinkCache.prototype.setAssumeExistence = function ( assume ) { + this.assumeExistence = !!assume; + }; + + /** + * @inheritdoc + */ + ve.init.mw.LinkCache.prototype.get = function ( title ) { + var data = {}; + if ( this.assumeExistence ) { + data[this.normalizeTitle( title )] = { missing: false }; + this.set( data ); + } + + // Parent method + return ve.init.mw.LinkCache.super.prototype.get.call( this, title ); + }; + /** * @inheritdoc */ diff --git a/modules/ve-mw/init/ve.init.mw.Target.js b/modules/ve-mw/init/ve.init.mw.Target.js index 23ccbfa286..bb3ea4ed14 100644 --- a/modules/ve-mw/init/ve.init.mw.Target.js +++ b/modules/ve-mw/init/ve.init.mw.Target.js @@ -408,7 +408,8 @@ ve.init.mw.Target.onModulesReady = function () { * @fires loadError */ ve.init.mw.Target.onLoad = function ( response ) { - var data = response ? response.visualeditor : null; + var i, len, linkData, + data = response ? response.visualeditor : null; if ( !data && !response.error ) { ve.init.mw.Target.onLoadError.call( @@ -451,7 +452,21 @@ ve.init.mw.Target.onLoad = function ( response ) { // Populate link cache if ( data.links ) { - ve.init.platform.linkCache.set( data.links ); + // Format from the API: { missing: [titles], extant: true|[titles] } + // Format expected by LinkCache: { title: { missing: true|false } } + linkData = {}; + for ( i = 0, len = data.links.missing.length; i < len; i++ ) { + linkData[data.links.missing[i]] = { missing: true }; + } + if ( data.links.extant === true ) { + // Set back to false by onReady() + ve.init.platform.linkCache.setAssumeExistence( true ); + } else { + for ( i = 0, len = data.links.extant.length; i < len; i++ ) { + linkData[data.links.extant[i]] = { missing: false }; + } + } + ve.init.platform.linkCache.set( linkData ); } // Everything worked, the page was loaded, continue as soon as the modules are loaded @@ -521,6 +536,8 @@ ve.init.mw.Target.prototype.onReady = function () { this.loading = false; this.edited = false; this.setupSurface( this.doc, function () { + // onLoad() may have called setAssumeExistence( true ); + ve.init.platform.linkCache.setAssumeExistence( false ); target.startSanityCheck(); target.emit( 'surfaceReady' ); } );