LivePreview: coding conventions and overall code prettiness
[lhc/web/wiklou.git] / skins / common / preview.js
1 /**
2 * Live preview script for MediaWiki
3 */
4 ( function( mw, $ ) {
5 var doLivePreview = function( e ) {
6 e.preventDefault();
7
8 $( mw ).trigger( 'LivePreviewPrepare' );
9
10 var $wikiPreview = $( '#wikiPreview' );
11
12 // this needs to be checked before we unconditionally show the preview
13 var previewVisible = false;
14 if ( $wikiPreview.is( ':visible' ) ) {
15 previewVisible = true;
16 }
17
18 // show #wikiPreview if it's hidden to be able to scroll to it
19 // (if it is hidden, it's also empty, so nothing changes in the rendering)
20 $wikiPreview.show();
21 // jump to where the preview will appear
22 $wikiPreview[0].scrollIntoView();
23
24 // list of elements that will be loaded from the preview page
25 var copySelectors = [
26 '#wikiPreview', '#wikiDiff', '#catlinks', '.hiddencats', '#p-lang', // the meat
27 '.templatesUsed', '.mw-summary-preview' // editing-related
28 ];
29 var $copyElements = $( copySelectors.join( ',' ) );
30
31 var $loadSpinner = $( '<div>' ).addClass( 'mw-ajax-loader' );
32 $loadSpinner.css( 'top', '0' ); // move away from header (default is -16px)
33
34 // If the preview is already visible, overlay the spinner on top of it.
35 if ( previewVisible ) {
36 $( '#mw-content-text' ).css( 'position', 'relative' ); // FIXME this seems like a bad idea
37
38 $loadSpinner.css( {
39 'position': 'absolute',
40 'z-index': '3',
41 'left': '50%',
42 'margin-left': '-16px'
43 } );
44 }
45
46 // fade out the elements and display the throbber
47 $( '#mw-content-text' ).prepend( $loadSpinner );
48 // we can't use fadeTo because it calls show(), and we might want to keep some elements hidden
49 // (e.g. empty #catlinks)
50 $copyElements.animate( { 'opacity': 0.4 }, 'fast' );
51
52 var $previewDataHolder = $( '<div>' );
53 var target = $( '#editform' ).attr( 'action' ) || window.location.href;
54
55 // gather all the data from the form
56 var postData = $( '#editform' ).formToArray(); // formToArray: from jquery.form
57 postData.push( { 'name' : e.target.name, 'value' : '1' } );
58
59 // load new preview data
60 // FIXME this should use the action=parse API instead of loading the entire page
61 $previewDataHolder.load( target + ' ' + copySelectors.join( ',' ), postData, function() {
62 // Copy the contents of the specified elements from the loaded page to the real page.
63 // Also copy their class attributes.
64 for ( var i = 0; i < copySelectors.length; i++ ) {
65 var $from = $previewDataHolder.find( copySelectors[i] );
66 var $to = $( copySelectors[i] );
67
68 $to.empty().append( $from.contents() );
69 $to.attr( 'class', $from.attr( 'class' ) );
70 }
71
72 $loadSpinner.remove();
73 $copyElements.animate( { 'opacity': 1 }, 'fast' );
74
75 $( mw ).trigger( 'LivePreviewDone', [copySelectors] );
76 } );
77 };
78
79 $( document ).ready( function() {
80 // construct the elements we need if they are missing (usually when action=edit)
81 // we don't need to hide them, because they are empty when created
82
83 // interwiki links
84 if ( !document.getElementById( 'p-lang' ) && document.getElementById( 'p-tb' ) ) {
85 $( '#p-tb' ).after( $( '<div>' ).attr( 'id', 'p-lang' ) );
86 }
87
88 // summary preview
89 if ( $( '.mw-summary-preview' ).length === 0 ) {
90 $( '.editCheckboxes' ).before( $( '<div>' ).addClass( 'mw-summary-preview' ) );
91 }
92
93 // diff
94 if ( !document.getElementById( 'wikiDiff' ) && document.getElementById( 'wikiPreview' ) ) {
95 $( '#wikiPreview' ).after( $( '<div>' ).attr( 'id', 'wikiDiff' ) );
96 }
97
98 // diff styles are usually only loaded during, well, diff, and we might need them
99 // (mw.loader takes care of stuff if they happen to be loaded already)
100 mw.loader.load( 'mediawiki.action.history.diff' );
101
102 $( '#wpPreview, #wpDiff' ).click( doLivePreview );
103 } );
104 } )( mediaWiki, jQuery );