File: ext.wikiEditor.js

package info (click to toggle)
mediawiki 1%3A1.43.3%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 417,464 kB
  • sloc: php: 1,062,949; javascript: 664,290; sql: 9,714; python: 5,458; xml: 3,489; sh: 1,131; makefile: 64
file content (201 lines) | stat: -rw-r--r-- 6,413 bytes parent folder | download
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
/*
 * JavaScript for WikiEditor
 */

/**
 * @module module:ext.wikiEditor
 */

var editingSessionId;

// This sets $.wikiEditor and $.fn.wikiEditor
require( './jquery.wikiEditor.js' );

function logEditEvent( data ) {
	if ( mw.config.get( 'wgMFMode' ) !== null ) {
		// Visiting a ?action=edit URL can, depending on user settings, result
		// in the MobileFrontend overlay appearing on top of WikiEditor. In
		// these cases, don't log anything.
		return;
	}
	mw.track( 'editAttemptStep', Object.assign( {
		// eslint-disable-next-line camelcase
		editor_interface: 'wikitext',
		platform: 'desktop', // FIXME T249944
		integration: 'page'
	}, data ) );
}

function logEditFeature( feature, action ) {
	if ( mw.config.get( 'wgMFMode' ) !== null ) {
		// Visiting a ?action=edit URL can, depending on user settings, result
		// in the MobileFrontend overlay appearing on top of WikiEditor. In
		// these cases, don't log anything.
		return;
	}
	mw.track( 'visualEditorFeatureUse', {
		feature: feature,
		action: action,
		// eslint-disable-next-line camelcase
		editor_interface: 'wikitext',
		platform: 'desktop', // FIXME T249944
		integration: 'page'
	} );
}

function logAbort( switchingToVE, unmodified ) {
	if ( switchingToVE ) {
		logEditFeature( 'editor-switch', 'visual-desktop' );
	}

	var abortType;
	if ( switchingToVE && unmodified ) {
		abortType = 'switchnochange';
	} else if ( switchingToVE ) {
		abortType = 'switchwithout';
	} else if ( unmodified ) {
		abortType = 'nochange';
	} else {
		abortType = 'abandon';
	}

	logEditEvent( {
		action: 'abort',
		type: abortType
	} );
}

$( function () {
	var $textarea = $( '#wpTextbox1' ),
		$editingSessionIdInput = $( '#editingStatsId' ),
		origText = $textarea.val();

	// T263505, T249038
	$( '#wikieditorUsed' ).val( 'yes' );

	if ( $editingSessionIdInput.length ) {
		editingSessionId = $editingSessionIdInput.val();
		if ( window.performance && window.performance.timing ) {
			// We want to track from the time the user started to try to
			// launch the editor which navigationStart approximates. All
			// of our supported browsers *should* allow this. Rather than
			// fall back to the timestamp when the page loaded for those
			// that don't, we just ignore them, so as to not skew the
			// results towards better-performance in those cases.
			var readyTime = Date.now();
			logEditEvent( {
				action: 'ready',
				timing: readyTime - window.performance.timing.navigationStart
			} );
			$textarea.on( 'wikiEditor-toolbar-doneInitialSections', function () {
				logEditEvent( {
					action: 'loaded',
					timing: Date.now() - window.performance.timing.navigationStart
				} );
			} ).one( 'input', function () {
				logEditEvent( {
					action: 'firstChange',
					timing: Date.now() - readyTime
				} );
			} );
		}
		var $form = $textarea.closest( 'form' );
		if ( mw.user.options.get( 'uselivepreview' ) ) {
			$form.find( '#wpPreview' ).on( 'click', function () {
				logEditFeature( 'preview', 'preview-live' );
			} );
		}

		var submitting;
		$form.on( 'submit', function () {
			submitting = true;
		} );
		var onUnloadFallback = window.onunload;

		window.onunload = function () {
			var unmodified = mw.config.get( 'wgAction' ) !== 'submit' && origText === $textarea.val(),
				caVeEdit = $( '#ca-ve-edit' )[ 0 ],
				switchingToVE = caVeEdit && (
					document.activeElement === caVeEdit ||
					$.contains( caVeEdit, document.activeElement )
				);

			var fallbackResult;
			if ( onUnloadFallback ) {
				fallbackResult = onUnloadFallback();
			}

			if ( !submitting ) {
				logAbort( switchingToVE, unmodified );
			}

			// If/when the user uses the back button to go back to the edit form
			// and the browser serves this from bfcache, regenerate the session ID
			// so we don't use the same ID twice. Ideally we'd do this by listening to the pageshow
			// event and checking e.originalEvent.persisted, but that doesn't work in Chrome:
			// https://code.google.com/p/chromium/issues/detail?id=344507
			// So instead we modify the DOM here, after sending the abort event.
			editingSessionId = mw.user.generateRandomSessionId();
			$editingSessionIdInput.val( editingSessionId );

			return fallbackResult;
		};
		$textarea.on( 'wikiEditor-switching-visualeditor', function () {
			var unmodified = mw.config.get( 'wgAction' ) !== 'submit' && origText === $textarea.val();
			// A non-navigation switch to VE has occurred. As such, avoid eventually
			// double-logging an abort when VE is done.
			window.onunload = onUnloadFallback;

			logAbort( true, unmodified );
		} );

		// Add logging for Realtime Preview.
		mw.hook( 'ext.WikiEditor.realtimepreview.enable' ).add( function () {
			logEditFeature( 'preview', 'preview-realtime-on' );
		} );
		mw.hook( 'ext.WikiEditor.realtimepreview.inuse' ).add( function () {
			logEditFeature( 'preview', 'preview-realtime-inuse' );
		} );
		mw.hook( 'ext.WikiEditor.realtimepreview.disable' ).add( function () {
			logEditFeature( 'preview', 'preview-realtime-off' );
		} );
		mw.hook( 'ext.WikiEditor.realtimepreview.loaded' ).add( function () {
			logEditFeature( 'preview', 'preview-realtime-loaded' );
		} );
		mw.hook( 'ext.WikiEditor.realtimepreview.stop' ).add( function () {
			logEditFeature( 'preview', 'preview-realtime-error-stopped' );
		} );
		mw.hook( 'ext.WikiEditor.realtimepreview.reloadError' ).add( function () {
			logEditFeature( 'preview', 'preview-realtime-reload-error' );
		} );
		mw.hook( 'ext.WikiEditor.realtimepreview.reloadHover' ).add( function () {
			logEditFeature( 'preview', 'preview-realtime-reload-hover' );
		} );
		mw.hook( 'ext.WikiEditor.realtimepreview.reloadManual' ).add( function () {
			logEditFeature( 'preview', 'preview-realtime-reload-manual' );
		} );
	}

	// The old toolbar is still in place and needs to be removed so there aren't two toolbars
	$( '#toolbar' ).remove();
	// Add toolbar module
	// TODO: Implement .wikiEditor( 'remove' )
	mw.addWikiEditor( $textarea );
} );

mw.addWikiEditor = function ( $textarea ) {
	if ( $textarea.css( 'display' ) === 'none' ) {
		return;
	}

	$textarea.wikiEditor(
		'addModule', require( './jquery.wikiEditor.toolbar.config.js' )
	);

	var dialogsConfig = require( './jquery.wikiEditor.dialogs.config.js' );
	// Replace icons
	dialogsConfig.replaceIcons( $textarea );
	// Add dialogs module
	$textarea.wikiEditor( 'addModule', dialogsConfig.getDefaultConfig() );

};