User:Salvatore Ingala/PreferencesEditor.js

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/**
 * Simple GUI preferences editor built on top of jquery.formBuilder.js
 */

$( function() {
    mw.util.addPortletLink('p-tb', 'javascript:;', 'Preferences editor', 't-prefsEditor');

	function showDescriptionDialog( desc ) {
		$(	'<div title="Preference editor - result">' +
				'<p>This is the final configuration</p>' +
				'<textarea rows="15" cols="80">' + $.toJSON( desc ) + '</textarea>' +
			'</div>' )
			.dialog( {
				modal: true,
				resizable: false,
				close: function() { $( this ).remove(); },
				buttons: {
					"OK": function() { $( this ).dialog( 'close' ); }
				}
			} );
	}

	function showPreviewDialog( desc, gadgetName ) {
		$( desc )
			.formBuilder( {
                idPrefix: "prefeditor-preview-",
                msgPrefix: "Gadget-" + gadgetName + "-"
            } )
			.dialog( {
				modal: true,
				resizable: false,
				width: 550,
				title: "Dialog preview",
				close: function() { $( this ).remove(); },
				buttons: {
					"OK": function() {
						$( this ).dialog( 'close' );
					}
				}
			} );
	}

	function showEditorDialog( desc, gadgetName ) {
        gadgetName = gadgetName || "";
		var dialogBody = $( desc ).formBuilder( {
			idPrefix: "prefeditor-",
            msgPrefix: "Gadget-" + gadgetName + "-",
			editable: true
		} );
		
		$( dialogBody ).dialog( {
			modal: true,
			width: 550,
			resizable: false,
			title: 'Preferences editor',
			close: function() { $( this ).remove(); },
			buttons: {
				"OK": function() {
					var isValid = $( this ).formBuilder( 'validate' );
					if ( isValid ) {
						showDescriptionDialog( $( this ).formBuilder( 'getDescription' ) ); 
						$( this ).dialog( "close" );
					}
				},
				"Preview": function() {
					var isValid = $( this ).formBuilder( 'validate' );
					if ( isValid ) {
						showPreviewDialog( $( this ).formBuilder( 'getDescription' ), gadgetName ); 
					}
				},
				"Close": function() {
					$( this ).dialog( "close" );
				}
			}
		} );
	}

	$( '#t-prefsEditor' ).click( function() {
		$( mw.loader.using( [ 'jquery.ui', 'jquery.formBuilder', 'jquery.json', 'ext.gadgets' ], function() {
			var $dialogBody = $(	'<div title="Preference editor">' +
					'<p>Insert a JSON preferences description to start editing, or just press OK to start from scratch.</p>' +
					'<textarea rows="15" cols="80"></textarea>' +
				'</div>' );
			
			if ( mw.gadgets.configurableGadgets && mw.gadgets.configurableGadgets.length > 0 ) {
				$dialogBody.append( $( '<p>...or load configuration of an existing gadget:</p><select><option></option><option>' +
						mw.gadgets.configurableGadgets.join( '</option><option>' ) +
						'</option></select>' ) );
				
				$dialogBody.find( 'select' ).change( function( event ) {
					var gadget = $( this ).val();
					if ( gadget !== '' ) {
						$.ajax( {
							url: mw.config.get( 'wgScriptPath' ) + '/api.php',
							type: "GET",
							data: {
								'action': 'query',
								'prop': 'revisions',
								'rvprop': 'content',
								'format': 'json',
								'titles': "MediaWiki:Gadget-" + mw.util.wikiUrlencode( gadget ) + ".preferences"
							},
							dataType: "json",
							success: function( response ) {
								if ( typeof response.error == 'undefined' ) {
									$dialogBody.dialog( 'close' );
									
									var pages = response.query.pages;
									var descJson;
									for ( var pageId in pages ) {
										var page = pages[pageId];
										descJson = page.revisions[0]['*'];
									}
									
									showEditorDialog( $.secureEvalJSON( descJson ), gadget );
								} else {
									alert( "It was not possible to retrieve preferences for gadget " + gadget );
								}
							},
							error: function( response ) {
								alert( "It was not possible to retrieve preferences for gadget " + gadget );
							}
						} );
					}
				} );
			}
			
			$dialogBody.dialog( {
					modal: true,
					resizable: false,
					close: function() { $( this ).remove(); },
					buttons: {
						"Cancel": function() {
							$( this ).dialog( 'close' );
						},
						"OK": function() {
							var json = $( this ).find( 'textarea' ).val(),
								description;
							if ( json == '' ) {
								description = { fields:[] }; //empty
							} else {
								try {
									description = $.secureEvalJSON( json );
								} catch( e ) {
									alert( "Invalid JSON!" );
									return;
								}
							}

							$( this ).dialog( 'close' );
							showEditorDialog( description );
						}
					}
				} );
		} ) );
	} );
} );