7 * @param {jQuery.Event} e
9 function doLivePreview( e
) {
10 var $wikiPreview
, copySelectors
, removeSelectors
, $copyElements
, $spinner
,
11 targetUrl
, postData
, $previewDataHolder
;
15 $( mw
).trigger( 'LivePreviewPrepare' );
17 $wikiPreview
= $( '#wikiPreview' );
19 // Show #wikiPreview if it's hidden to be able to scroll to it
20 // (if it is hidden, it's also empty, so nothing changes in the rendering)
23 // Jump to where the preview will appear
24 $wikiPreview
[0].scrollIntoView();
26 // List of selectors matching elements that we will
27 // update from from the ajax-loaded preview page.
39 $copyElements
= $( copySelectors
.join( ',' ) );
41 // Not shown during normal preview, to be removed if present
46 $( removeSelectors
.join( ',' ) ).remove();
48 $spinner
= $.createSpinner( {
52 $wikiPreview
.before( $spinner
);
55 marginTop
: $spinner
.height()
57 // Make sure preview area is at least as tall as 2x the height of the spinner.
58 // 1x because if its smaller, it will spin behind the edit toolbar.
59 // (this happens on the first preview when editPreview is still empty)
60 // 2x because the spinner has 1x margin top breathing room.
61 $wikiPreview
.css( 'minHeight', $spinner
.height() * 2 );
63 // Can't use fadeTo because it calls show(), and we might want to keep some elements hidden
64 // (e.g. empty #catlinks)
65 $copyElements
.animate( {
69 $previewDataHolder
= $( '<div>' );
70 targetUrl
= $( '#editform' ).attr( 'action' );
72 // Gather all the data from the form
73 postData
= $( '#editform' ).formToArray();
79 // Load new preview data.
80 // TODO: This should use the action=parse API instead of loading the entire page
81 // Though that requires figuring out how to conver that raw data into proper HTML.
82 $previewDataHolder
.load( targetUrl
+ ' ' + copySelectors
.join( ',' ), postData
, function () {
84 // Copy the contents of the specified elements from the loaded page to the real page.
85 // Also copy their class attributes.
86 for ( i
= 0; i
< copySelectors
.length
; i
++ ) {
87 $from = $previewDataHolder
.find( copySelectors
[i
] );
91 .append( $from.contents() )
92 .attr( 'class', $from.attr( 'class' ) );
96 $copyElements
.animate( {
100 $( mw
).trigger( 'LivePreviewDone', [copySelectors
] );
104 $( document
).ready( function () {
105 // Do not enable on user .js/.css pages, as there's no sane way of "previewing"
106 // the scripts or styles without reloading the page.
107 if ( $( '#mw-userjsyoucanpreview' ).length
|| $( '#mw-usercssyoucanpreview' ).length
) {
111 // The following elements can change in a preview but are not output
112 // by the server when they're empty until the preview reponse.
113 // TODO: Make the server output these always (in a hidden state), so we don't
114 // have to fish and (hopefully) put them in the right place (since skins
115 // can change where they are output).
117 if ( !document
.getElementById( 'p-lang' ) && document
.getElementById( 'p-tb' ) ) {
119 $( '<div>' ).prop( 'id', 'p-lang' )
123 if ( !$( '.mw-summary-preview' ).length
) {
124 $( '.editCheckboxes' ).before(
125 $( '<div>' ).prop( 'className', 'mw-summary-preview' )
129 if ( !document
.getElementById( 'wikiDiff' ) && document
.getElementById( 'wikiPreview' ) ) {
130 $( '#wikiPreview' ).after(
131 $( '<div>' ).prop( 'id', 'wikiDiff')
135 // Make sure diff styles are loaded
136 mw
.loader
.load( 'mediawiki.action.history.diff' );
138 $( document
.body
).on( 'click', '#wpPreview, #wpDiff', doLivePreview
);
141 }( mediaWiki
, jQuery
) );