mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-24 22:35:41 +00:00
Merge "ArticleTarget: Change rendering of category preview"
This commit is contained in:
commit
4ca3f1661d
|
@ -589,6 +589,8 @@
|
|||
"colon-separator",
|
||||
"newsectionsummary",
|
||||
"pagecategories",
|
||||
"pagecategorieslink",
|
||||
"hidden-categories",
|
||||
"parentheses",
|
||||
"redirectto",
|
||||
"tooltip-minoredit",
|
||||
|
|
|
@ -877,36 +877,22 @@ ve.init.mw.DesktopArticleTarget.prototype.onMetaItemRemoved = function ( metaIte
|
|||
/**
|
||||
* Redisplay the category list on the page
|
||||
*
|
||||
* This is used for the preview while editing. Leaving the editor either restores the initial
|
||||
* categories, or uses the ones generated by the save API.
|
||||
*
|
||||
* @param {ve.dm.MetaItem[]} categoryItems Array of category metaitems to display
|
||||
*/
|
||||
ve.init.mw.DesktopArticleTarget.prototype.rebuildCategories = function ( categoryItems ) {
|
||||
var target = this;
|
||||
// We need to fetch this from the API because the category list is skin-
|
||||
// dependent, so the HTML output could be absolutely anything.
|
||||
this.getContentApi().post( {
|
||||
formatversion: 2,
|
||||
action: 'parse',
|
||||
contentmodel: 'wikitext',
|
||||
text: categoryItems.map( function ( categoryItem ) {
|
||||
// TODO: wikitext-building is a bad smell here, but is done
|
||||
// because there's no other API call that will get the category
|
||||
// markup. Adding such an API, if other use cases for it emerge,
|
||||
// might make sense.
|
||||
if ( categoryItem.getAttribute( 'sortkey' ) ) {
|
||||
return '[[' + categoryItem.getAttribute( 'category' ) + '|' + categoryItem.getAttribute( 'sortkey' ) + ']]';
|
||||
}
|
||||
return '[[' + categoryItem.getAttribute( 'category' ) + ']]';
|
||||
} ).join( '\n' ),
|
||||
prop: 'categorieshtml'
|
||||
} ).then( function ( response ) {
|
||||
var $categories;
|
||||
if ( !response || !response.parse || !response.parse.categorieshtml ) {
|
||||
return;
|
||||
}
|
||||
$categories = $( $.parseHTML( response.parse.categorieshtml ) );
|
||||
target.transformCategoryLinks( $categories );
|
||||
mw.hook( 'wikipage.categories' ).fire( $categories );
|
||||
$( '#catlinks' ).replaceWith( $categories );
|
||||
this.renderCategories( categoryItems ).done( function ( $categories ) {
|
||||
// Clone the existing catlinks for any specific properties which might
|
||||
// be needed by the rest of the page. Also gives us a not-attached
|
||||
// version, which we can pass to wikipage.categories as it requests.
|
||||
var $catlinks = $( '#catlinks' ).clone().empty().append( $categories.children() );
|
||||
target.transformCategoryLinks( $catlinks );
|
||||
mw.hook( 'wikipage.categories' ).fire( $catlinks );
|
||||
$( '#catlinks' ).replaceWith( $catlinks );
|
||||
ve.init.platform.linkCache.styleParsoidElements( $catlinks, target.doc );
|
||||
} );
|
||||
};
|
||||
|
||||
|
|
|
@ -2583,3 +2583,78 @@ ve.init.mw.ArticleTarget.prototype.updateRedirectInterface = function ( $sub, $m
|
|||
$( '#mw-content-text' ).before( $msg );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Render a list of categories
|
||||
*
|
||||
* @param {ve.dm.MetaItem[]} categoryItems Array of category metaitems to display
|
||||
* @return {jQuery.Promise} A promise which will be resolved with the rendered categories
|
||||
*/
|
||||
ve.init.mw.ArticleTarget.prototype.renderCategories = function ( categoryItems ) {
|
||||
var $normal, $hidden,
|
||||
promises = [],
|
||||
categories = { hidden: [], normal: [] };
|
||||
categoryItems.forEach( function ( categoryItem ) {
|
||||
var attributes = ve.cloneObject( ve.getProp( categoryItem, 'element', 'attributes' ) );
|
||||
promises.push( ve.init.platform.linkCache.get( attributes.category ).done( function ( result ) {
|
||||
if ( result.hidden ) {
|
||||
categories.hidden.push( attributes );
|
||||
} else {
|
||||
categories.normal.push( attributes );
|
||||
}
|
||||
} ) );
|
||||
} );
|
||||
return $.when.apply( $, promises ).then( function () {
|
||||
var $output = $( '<div class="catlinks" />' );
|
||||
function renderPageLink( page ) {
|
||||
var title = mw.Title.newFromText( page.category || page );
|
||||
return $( '<a>' ).attr( 'rel', 'mw:WikiLink' ).attr( 'href', title.getUrl() ).text( title.getMainText() );
|
||||
}
|
||||
function renderPageLinks( pages ) {
|
||||
var i, $list = $( '<ul />' );
|
||||
for ( i = 0; i < pages.length; i++ ) {
|
||||
$list.append( $( '<li />' ).append( renderPageLink( pages[ i ] ) ) );
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
function categorySort( a, b ) {
|
||||
var sortA = a.sortkey || a.category,
|
||||
sortB = b.sortkey || b.category;
|
||||
if ( sortA < sortB ) {
|
||||
return -1;
|
||||
}
|
||||
if ( sortA > sortB ) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if ( categories.normal.length ) {
|
||||
categories.normal.sort( categorySort );
|
||||
$normal = $( '<div class="mw-normal-catlinks" />' );
|
||||
$normal.append(
|
||||
renderPageLink( ve.msg( 'pagecategorieslink' ) ).text( ve.msg( 'pagecategories', categories.normal.length ) ),
|
||||
ve.msg( 'colon-separator' ),
|
||||
renderPageLinks( categories.normal )
|
||||
);
|
||||
$output.append( $normal );
|
||||
}
|
||||
if ( categories.hidden.length ) {
|
||||
categories.hidden.sort( categorySort );
|
||||
$hidden = $( '<div class="mw-hidden-catlinks" />' );
|
||||
if ( mw.user.options.get( 'showhiddencats' ) ) {
|
||||
$hidden.addClass( 'mw-hidden-cats-user-shown' );
|
||||
} else if ( mw.config.get( 'wgNamespaceIds' ).category === mw.config.get( 'wgNamespaceNumber' ) ) {
|
||||
$hidden.addClass( 'mw-hidden-cats-ns-shown' );
|
||||
} else {
|
||||
$hidden.addClass( 'mw-hidden-cats-hidden' );
|
||||
}
|
||||
$hidden.append(
|
||||
ve.msg( 'hidden-categories', categories.hidden.length ),
|
||||
ve.msg( 'colon-separator' ),
|
||||
renderPageLinks( categories.hidden )
|
||||
);
|
||||
$output.append( $hidden );
|
||||
}
|
||||
return $output;
|
||||
} );
|
||||
};
|
||||
|
|
|
@ -56,6 +56,7 @@ ve.init.mw.LinkCache.static.processPage = function ( page ) {
|
|||
known: page.known !== undefined,
|
||||
redirect: page.redirect !== undefined,
|
||||
disambiguation: ve.getProp( page, 'pageprops', 'disambiguation' ) !== undefined,
|
||||
hidden: ve.getProp( page, 'pageprops', 'hiddencat' ) !== undefined,
|
||||
imageUrl: ve.getProp( page, 'thumbnail', 'source' ),
|
||||
description: page.description
|
||||
};
|
||||
|
@ -191,7 +192,7 @@ ve.init.mw.LinkCache.prototype.getRequestPromise = function ( subqueue ) {
|
|||
prop: 'info|pageprops|pageimages|description',
|
||||
pithumbsize: 80,
|
||||
pilimit: subqueue.length,
|
||||
ppprop: 'disambiguation',
|
||||
ppprop: 'disambiguation|hiddencat',
|
||||
titles: subqueue,
|
||||
'continue': ''
|
||||
} );
|
||||
|
|
|
@ -189,10 +189,11 @@ ve.ui.MWSaveDialog.prototype.setDiffAndReview = function ( wikitextDiffPromise,
|
|||
* @param {HTMLDocument} [baseDoc] Base document against which to normalise links, if document provided
|
||||
*/
|
||||
ve.ui.MWSaveDialog.prototype.showPreview = function ( docOrMsg, baseDoc ) {
|
||||
var body, contents, $heading, redirectMeta,
|
||||
var body, contents, $heading, redirectMeta, deferred,
|
||||
$redirect = $(),
|
||||
categories = [],
|
||||
modules = [];
|
||||
modules = [],
|
||||
dialog = this;
|
||||
|
||||
if ( docOrMsg instanceof HTMLDocument ) {
|
||||
// Extract required modules for stylesheet tags (avoids re-loading styles)
|
||||
|
@ -210,7 +211,7 @@ ve.ui.MWSaveDialog.prototype.showPreview = function ( docOrMsg, baseDoc ) {
|
|||
body = docOrMsg.body;
|
||||
// Take a snapshot of all categories
|
||||
Array.prototype.forEach.call( body.querySelectorAll( 'link[rel~="mw:PageProp/Category"]' ), function ( element ) {
|
||||
categories.push( ve.dm.MWCategoryMetaItem.static.toDataElement( [ element ] ).attributes.category );
|
||||
categories.push( ve.dm.nodeFactory.createFromElement( ve.dm.MWCategoryMetaItem.static.toDataElement( [ element ] ) ) );
|
||||
} );
|
||||
// Import body to current document, then resolve attributes against original document (parseDocument called #fixBase)
|
||||
document.adoptNode( body );
|
||||
|
@ -258,25 +259,27 @@ ve.ui.MWSaveDialog.prototype.showPreview = function ( docOrMsg, baseDoc ) {
|
|||
)
|
||||
);
|
||||
|
||||
if ( categories.length ) {
|
||||
// Simple category list rendering
|
||||
this.$previewViewer.append(
|
||||
$( '<div>' ).addClass( 'catlinks' ).append(
|
||||
document.createTextNode( ve.msg( 'pagecategories', categories.length ) + ve.msg( 'colon-separator' ) ),
|
||||
$( '<ul>' ).append( categories.map( function ( category ) {
|
||||
var title = mw.Title.newFromText( category );
|
||||
return $( '<li>' ).append( $( '<a>' ).attr( 'rel', 'mw:WikiLink' ).attr( 'href', title.getUrl() ).text( title.getMainText() ) );
|
||||
} ) )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
ve.targetLinksToNewWindow( this.$previewViewer[ 0 ] );
|
||||
// Add styles so links render with their appropriate classes
|
||||
ve.init.platform.linkCache.styleParsoidElements( this.$previewViewer, baseDoc );
|
||||
|
||||
if ( categories.length ) {
|
||||
// If there are categories, we need to render them. This involves
|
||||
// a delay, since they might be hidden categories.
|
||||
deferred = ve.init.target.renderCategories( categories ).done( function ( $categories ) {
|
||||
dialog.$previewViewer.append( $categories );
|
||||
|
||||
ve.targetLinksToNewWindow( $categories[ 0 ] );
|
||||
// Add styles so links render with their appropriate classes
|
||||
ve.init.platform.linkCache.styleParsoidElements( $categories, baseDoc );
|
||||
} );
|
||||
} else {
|
||||
deferred = $.Deferred.resolve();
|
||||
}
|
||||
deferred.done( function () {
|
||||
// Run hooks so other things can alter the document
|
||||
mw.hook( 'wikipage.content' ).fire( this.$previewViewer );
|
||||
mw.hook( 'wikipage.content' ).fire( dialog.$previewViewer );
|
||||
} );
|
||||
} else {
|
||||
this.$previewViewer.empty().append(
|
||||
$( '<em>' ).text( docOrMsg )
|
||||
|
|
Loading…
Reference in a new issue