summaryrefslogtreecommitdiff
path: root/resources/src/mediawiki.action/mediawiki.action.edit.preview.js
diff options
context:
space:
mode:
Diffstat (limited to 'resources/src/mediawiki.action/mediawiki.action.edit.preview.js')
-rw-r--r--resources/src/mediawiki.action/mediawiki.action.edit.preview.js257
1 files changed, 196 insertions, 61 deletions
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.preview.js b/resources/src/mediawiki.action/mediawiki.action.edit.preview.js
index 6b212c28..f24703af 100644
--- a/resources/src/mediawiki.action/mediawiki.action.edit.preview.js
+++ b/resources/src/mediawiki.action/mediawiki.action.edit.preview.js
@@ -8,17 +8,29 @@
* @param {jQuery.Event} e
*/
function doLivePreview( e ) {
- var $wikiPreview, $editform, copySelectors, $copyElements, $spinner,
- targetUrl, postData, $previewDataHolder;
-
- e.preventDefault();
-
- // Deprecated: Use mw.hook instead
- $( mw ).trigger( 'LivePreviewPrepare' );
+ var isDiff, api, request, postData, copySelectors, section,
+ $wikiPreview, $wikiDiff, $editform, $textbox, $summary, $copyElements, $spinner, $errorBox;
+ isDiff = ( e.target.name === 'wpDiff' );
$wikiPreview = $( '#wikiPreview' );
+ $wikiDiff = $( '#wikiDiff' );
$editform = $( '#editform' );
+ $textbox = $editform.find( '#wpTextbox1' );
+ $summary = $editform.find( '#wpSummary' );
+ $errorBox = $( '.errorbox' );
+ section = $editform.find( '[name="wpSection"]' ).val();
+
+ if ( $textbox.length === 0 ) {
+ return;
+ }
+ // Show changes for a new section is not yet supported
+ if ( isDiff && section === 'new' ) {
+ return;
+ }
+ e.preventDefault();
+ // Remove any previously displayed errors
+ $errorBox.remove();
// Show #wikiPreview if it's hidden to be able to scroll to it
// (if it is hidden, it's also empty, so nothing changes in the rendering)
$wikiPreview.show();
@@ -26,15 +38,12 @@
// Jump to where the preview will appear
$wikiPreview[0].scrollIntoView();
- // List of selectors matching elements that we will
- // update from from the ajax-loaded preview page.
copySelectors = [
// Main
'#firstHeading',
'#wikiPreview',
'#wikiDiff',
'#catlinks',
- '.hiddencats',
'#p-lang',
// Editing-related
'.templatesUsed',
@@ -59,70 +68,184 @@
// (e.g. empty #catlinks)
$copyElements.animate( { opacity: 0.4 }, 'fast' );
- $previewDataHolder = $( '<div>' );
- targetUrl = $editform.attr( 'action' );
- targetUrl += targetUrl.indexOf( '?' ) !== -1 ? '&' : '?';
- targetUrl += $.param( {
- debug: mw.config.get( 'debug' ),
+ api = new mw.Api();
+ postData = {
+ action: 'parse',
uselang: mw.config.get( 'wgUserLanguage' ),
- useskin: mw.config.get( 'skin' )
- } );
+ title: mw.config.get( 'wgPageName' ),
+ text: $textbox.textSelection( 'getContents' ),
+ summary: $summary.textSelection( 'getContents' )
+ };
- // Gather all the data from the form
- postData = $editform.formToArray();
- postData.push( {
- name: e.target.name,
- value: ''
- } );
+ if ( section !== '' ) {
+ postData.sectionpreview = '';
+ if ( section === 'new' ) {
+ postData.section = section;
+ postData.sectiontitle = postData.summary;
+ }
+ }
- // Load new preview data.
- // TODO: This should use the action=parse API instead of loading the entire page,
- // although that requires figuring out how to convert that raw data into proper HTML.
- $previewDataHolder.load( targetUrl + ' ' + copySelectors.join( ',' ), postData, function () {
- var i, $from, $next, $parent;
+ if ( isDiff ) {
+ $wikiPreview.hide();
- // Copy the contents of the specified elements from the loaded page to the real page.
- // Also copy their class attributes.
- for ( i = 0; i < copySelectors.length; i++ ) {
- $from = $previewDataHolder.find( copySelectors[i] );
+ // First PST the input, then diff it
+ postData.onlypst = '';
+ request = api.post( postData );
+ request.done( function ( response ) {
+ var postData;
+ postData = {
+ action: 'query',
+ indexpageids: '',
+ prop: 'revisions',
+ titles: mw.config.get( 'wgPageName' ),
+ rvdifftotext: response.parse.text['*'],
+ rvprop: ''
+ };
+ if ( section !== '' ) {
+ postData.rvsection = section;
+ }
+ return api.post( postData ).done( function ( result2 ) {
+ try {
+ var diffHtml = result2.query.pages[result2.query.pageids[0]]
+ .revisions[0].diff['*'];
+ $wikiDiff.find( 'table.diff tbody' ).html( diffHtml );
+ } catch ( e ) {
+ // "result.blah is undefined" error, ignore
+ mw.log.warn( e );
+ }
+ $wikiDiff.show();
+ } );
+ } );
+ } else {
+ $wikiDiff.hide();
+ $.extend( postData, {
+ pst: '',
+ preview: '',
+ prop: 'text|displaytitle|modules|categorieshtml|templates|langlinks|limitreporthtml',
+ disableeditsection: true
+ } );
+ request = api.post( postData );
+ request.done( function ( response ) {
+ var li, newList, $displaytitle, $content, $parent, $list;
+ if ( response.parse.modules ) {
+ mw.loader.load( response.parse.modules.concat(
+ response.parse.modulescripts,
+ response.parse.modulestyles,
+ response.parse.modulemessages ) );
+ }
+ if ( response.parse.displaytitle ) {
+ $displaytitle = $( $.parseHTML( response.parse.displaytitle ) );
+ $( '#firstHeading' ).msg(
+ mw.config.get( 'wgEditMessage', 'editing' ),
+ $displaytitle
+ );
+ document.title = mw.msg(
+ 'pagetitle',
+ mw.msg(
+ mw.config.get( 'wgEditMessage', 'editing' ),
+ $displaytitle.text()
+ )
+ );
+ }
+ if ( response.parse.categorieshtml ) {
+ $( '#catlinks' ).replaceWith( response.parse.categorieshtml['*'] );
+ }
+ if ( response.parse.templates ) {
+ newList = [];
+ $.each( response.parse.templates, function ( i, template ) {
+ li = $( '<li>' )
+ .append( $( '<a>' )
+ .attr( {
+ 'href': mw.util.getUrl( template['*'] ),
+ 'class': ( template.exists !== undefined ? '' : 'new' )
+ } )
+ .text( template['*'] )
+ );
+ newList.push( li );
+ } );
- if ( copySelectors[i] === '#wikiPreview' ) {
- $next = $wikiPreview.next();
- // If there is no next node, use parent instead.
- // Only query parent if needed, false otherwise.
- $parent = !$next.length && $wikiPreview.parent();
+ $editform.find( '.templatesUsed .mw-editfooter-list' ).detach().empty().append( newList ).appendTo( '.templatesUsed' );
+ }
+ if ( response.parse.limitreporthtml ) {
+ $( '.limitreport' ).html( response.parse.limitreporthtml['*'] );
+ }
+ if ( response.parse.langlinks && mw.config.get( 'skin' ) === 'vector' ) {
+ newList = [];
+ $.each( response.parse.langlinks, function ( i, langlink ) {
+ li = $( '<li>' )
+ .addClass( 'interlanguage-link interwiki-' + langlink.lang )
+ .append( $( '<a>' )
+ .attr( {
+ 'href': langlink.url,
+ 'title': langlink['*'] + ' - ' + langlink.langname,
+ 'lang': langlink.lang,
+ 'hreflang': langlink.lang
+ } )
+ .text( langlink.autonym )
+ );
+ newList.push( li );
+ } );
+ $list = $( '#p-lang ul' );
+ $parent = $list.parent();
+ $list.detach().empty().append( newList ).prependTo( $parent );
+ }
- $wikiPreview
+ if ( response.parse.text['*'] ) {
+ $content = $wikiPreview.children( '.mw-content-ltr,.mw-content-rtl' );
+ $content
.detach()
- .empty()
- .append( $from.contents() )
- .attr( 'class', $from.attr( 'class' ) );
+ .html( response.parse.text['*'] );
- mw.hook( 'wikipage.content' ).fire( $wikiPreview );
+ mw.hook( 'wikipage.content' ).fire( $content );
// Reattach
- if ( $parent ) {
- $parent.append( $wikiPreview );
- } else {
- $next.before( $wikiPreview );
- }
+ $wikiPreview.append( $content );
+
+ $wikiPreview.show();
- } else {
- $( copySelectors[i] )
- .empty()
- .append( $from.contents() )
- .attr( 'class', $from.attr( 'class' ) );
}
+ } );
+ }
+ request.done( function ( response ) {
+ var isSubject = ( section === 'new' ),
+ summaryMsg = isSubject ? 'subject-preview' : 'summary-preview';
+ if ( response.parse.parsedsummary ) {
+ $editform.find( '.mw-summary-preview' )
+ .empty()
+ .append(
+ mw.message( summaryMsg ).parse(),
+ ' ',
+ $( '<span>' ).addClass( 'comment' ).html(
+ // There is no equivalent to rawParams
+ mw.message( 'parentheses' ).escaped()
+ .replace( '$1', response.parse.parsedsummary['*'] )
+ )
+ );
}
-
- // Deprecated: Use mw.hook instead
- $( mw ).trigger( 'LivePreviewDone', [copySelectors] );
-
+ } );
+ request.always( function () {
$spinner.remove();
$copyElements.animate( {
opacity: 1
}, 'fast' );
} );
+ request.fail( function ( code, result ) {
+ var errorMsg = 'API error: ' + code;
+ if ( code === 'http' ) {
+ errorMsg = 'HTTP error: ';
+ if ( result.exception ) {
+ errorMsg += result.exception;
+ } else {
+ errorMsg += result.textStatus;
+ }
+ }
+ $errorBox = $( '<div>' )
+ .addClass( 'errorbox' )
+ .html( '<strong>' + mw.message( 'previewerrortext' ).escaped() + '</strong><br>' )
+ .append( document.createTextNode( errorMsg ) );
+ $wikiDiff.hide();
+ $wikiPreview.hide().before( $errorBox );
+ } );
}
$( function () {
@@ -138,21 +261,33 @@
// have to fish and (hopefully) put them in the right place (since skins
// can change where they are output).
- if ( !document.getElementById( 'p-lang' ) && document.getElementById( 'p-tb' ) ) {
- $( '#p-tb' ).after(
- $( '<div>' ).attr( 'id', 'p-lang' )
+ if ( !document.getElementById( 'p-lang' ) && document.getElementById( 'p-tb' ) && mw.config.get( 'skin' ) === 'vector' ) {
+ $( '.portal:last' ).after(
+ $( '<div>' ).attr( {
+ 'class': 'portal',
+ 'id': 'p-lang',
+ 'role': 'navigation',
+ 'title': mw.msg( 'tooltip-p-lang' ),
+ 'aria-labelledby': 'p-lang-label'
+ } )
+ .append( $( '<h3>' ).attr( 'id', 'p-lang-label' ).text( mw.msg( 'otherlanguages' ) ) )
+ .append( $( '<div>' ).addClass( 'body' ).append( '<ul>' ) )
);
}
if ( !$( '.mw-summary-preview' ).length ) {
- $( '.editCheckboxes' ).before(
+ $( '#wpSummary' ).after(
$( '<div>' ).addClass( 'mw-summary-preview' )
);
}
if ( !document.getElementById( 'wikiDiff' ) && document.getElementById( 'wikiPreview' ) ) {
$( '#wikiPreview' ).after(
- $( '<div>' ).attr( 'id', 'wikiDiff' )
+ $( '<div>' )
+ .hide()
+ .attr( 'id', 'wikiDiff' )
+ .html( '<table class="diff"><col class="diff-marker"/><col class="diff-content"/>' +
+ '<col class="diff-marker"/><col class="diff-content"/><tbody/></table>' )
);
}