Merge "Change case to use the canonical names."
[lhc/web/wiklou.git] / resources / mediawiki.action / mediawiki.action.edit.preview.js
1 /**
2 * Live edit preview.
3 */
4 ( function ( mw, $ ) {
5
6 /**
7 * @param {jQuery.Event} e
8 */
9 function doLivePreview( e ) {
10 var $wikiPreview, copySelectors, removeSelectors, $copyElements, $spinner,
11 targetUrl, postData, $previewDataHolder;
12
13 e.preventDefault();
14
15 $( mw ).trigger( 'LivePreviewPrepare' );
16
17 $wikiPreview = $( '#wikiPreview' );
18
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)
21 $wikiPreview.show();
22
23 // Jump to where the preview will appear
24 $wikiPreview[0].scrollIntoView();
25
26 // List of selectors matching elements that we will
27 // update from from the ajax-loaded preview page.
28 copySelectors = [
29 // Main
30 '#wikiPreview',
31 '#wikiDiff',
32 '#catlinks',
33 '.hiddencats',
34 '#p-lang',
35 // Editing-related
36 '.templatesUsed',
37 '.mw-summary-preview'
38 ];
39 $copyElements = $( copySelectors.join( ',' ) );
40
41 // Not shown during normal preview, to be removed if present
42 removeSelectors = [
43 '.mw-newarticletext'
44 ];
45
46 $( removeSelectors.join( ',' ) ).remove();
47
48 $spinner = $.createSpinner( {
49 size: 'large',
50 type: 'block'
51 });
52 $wikiPreview.before( $spinner );
53 $spinner.css( {
54 position: 'absolute',
55 marginTop: $spinner.height()
56 } );
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 );
62
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( {
66 opacity: 0.4
67 }, 'fast' );
68
69 $previewDataHolder = $( '<div>' );
70 targetUrl = $( '#editform' ).attr( 'action' );
71
72 // Gather all the data from the form
73 postData = $( '#editform' ).formToArray();
74 postData.push( {
75 name: e.target.name,
76 value: ''
77 } );
78
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 () {
83 var i, $from;
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] );
88
89 $( copySelectors[i] )
90 .empty()
91 .append( $from.contents() )
92 .attr( 'class', $from.attr( 'class' ) );
93 }
94
95 $spinner.remove();
96 $copyElements.animate( {
97 opacity: 1
98 }, 'fast' );
99
100 $( mw ).trigger( 'LivePreviewDone', [copySelectors] );
101 } );
102 }
103
104 $( document ).ready( function () {
105 // The following elements can change in a preview but are not output
106 // by the server when they're empty until the preview reponse.
107 // TODO: Make the server output these always (in a hidden state), so we don't
108 // have to fish and (hopefully) put them in the right place (since skins
109 // can change where they are output).
110
111 if ( !document.getElementById( 'p-lang' ) && document.getElementById( 'p-tb' ) ) {
112 $( '#p-tb' ).after(
113 $( '<div>' ).prop( 'id', 'p-lang' )
114 );
115 }
116
117 if ( !$( '.mw-summary-preview' ).length ) {
118 $( '.editCheckboxes' ).before(
119 $( '<div>' ).prop( 'className', 'mw-summary-preview' )
120 );
121 }
122
123 if ( !document.getElementById( 'wikiDiff' ) && document.getElementById( 'wikiPreview' ) ) {
124 $( '#wikiPreview' ).after(
125 $( '<div>' ).prop( 'id', 'wikiDiff')
126 );
127 }
128
129 // Make sure diff styles are loaded
130 mw.loader.load( 'mediawiki.action.history.diff' );
131
132 $( document.body ).on( 'click', '#wpPreview, #wpDiff', doLivePreview );
133 } );
134
135 }( mediaWiki, jQuery ) );