summaryrefslogtreecommitdiff
path: root/resources/mediawiki.action/mediawiki.action.edit.preview.js
blob: c5cd61effac10279acda9e3c830c13681b77a6c6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/**
 * Live edit preview.
 */
( function ( mw, $ ) {

	/**
	 * @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' );

		$wikiPreview = $( '#wikiPreview' );
		$editform = $( '#editform' );

		// 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();

		// 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
			'#wikiPreview',
			'#wikiDiff',
			'#catlinks',
			'.hiddencats',
			'#p-lang',
			// Editing-related
			'.templatesUsed',
			'.limitreport',
			'.mw-summary-preview'
		];
		$copyElements = $( copySelectors.join( ',' ) );

		// Not shown during normal preview, to be removed if present
		$( '.mw-newarticletext' ).remove();

		$spinner = $.createSpinner( {
			size: 'large',
			type: 'block'
		});
		$wikiPreview.before( $spinner );
		$spinner.css( {
			marginTop: $spinner.height()
		} );

		// Can't use fadeTo because it calls show(), and we might want to keep some elements hidden
		// (e.g. empty #catlinks)
		$copyElements.animate( { opacity: 0.4 }, 'fast' );

		$previewDataHolder = $( '<div>' );
		targetUrl = $editform.attr( 'action' );

		// Gather all the data from the form
		postData = $editform.formToArray();
		postData.push( {
			name: e.target.name,
			value: ''
		} );

		// 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;

			// 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] );

				$( copySelectors[i] )
					.empty()
					.append( $from.contents() )
					.attr( 'class', $from.attr( 'class' ) );
			}

			// Deprecated: Use mw.hook instead
			$( mw ).trigger( 'LivePreviewDone', [copySelectors] );

			mw.hook( 'wikipage.content' ).fire( $wikiPreview );

			$spinner.remove();
			$copyElements.animate( {
				opacity: 1
			}, 'fast' );
		} );
	}

	$( function () {
		// Do not enable on user .js/.css pages, as there's no sane way of "previewing"
		// the scripts or styles without reloading the page.
		if ( $( '#mw-userjsyoucanpreview' ).length || $( '#mw-usercssyoucanpreview' ).length ) {
			return;
		}

		// The following elements can change in a preview but are not output
		// by the server when they're empty until the preview response.
		// TODO: Make the server output these always (in a hidden state), so we don't
		// 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 ( !$( '.mw-summary-preview' ).length ) {
			$( '.editCheckboxes' ).before(
				$( '<div>' ).addClass( 'mw-summary-preview' )
			);
		}

		if ( !document.getElementById( 'wikiDiff' ) && document.getElementById( 'wikiPreview' ) ) {
			$( '#wikiPreview' ).after(
				$( '<div>' ).attr( 'id', 'wikiDiff' )
			);
		}

		// This should be moved down to '#editform', but is kept on the body for now
		// because the LiquidThreads extension is re-using this module with only half
		// the EditPage (doesn't include #editform presumably, bug 55463).
		$( document.body ).on( 'click', '#wpPreview, #wpDiff', doLivePreview );
	} );

}( mediaWiki, jQuery ) );