User:Mooeypoo/articlesandbox.js

var ARTICLE_REPO = mw.config.get( 'articlesandbox-article-repo' ) || '', // Language messages = { he: { 'articlesandbox-title': 'אשף ערכים', 'articlesandbox-button': 'אשף ערכים', 'articlesandbox-dismiss': 'ביטול', 'articlesandbox-goback': 'חזרה למסך הקודם', 'articlesandbox-create-article': ' ערך', 'articlesandbox-create-article-for': ' ערך עבור $1', 'articlesandbox-sections': 'רשימת ערכים', 'articlesandbox-create-button': ' ערך', 'articlesandbox-create-input-placeholder': 'כותרת הערך', 'articlesandbox-create-articlesummary': 'נוצר באמצעות |אשף הערכים' },		en: { 'articlesandbox-title': 'Article helper', 'articlesandbox-button': 'Article helper', 'articlesandbox-dismiss': 'Dismiss', 'articlesandbox-goback': 'Go back', 'articlesandbox-create-article': 'Create article', 'articlesandbox-create-article-for': 'Create article for $1', 'articlesandbox-sections': 'Available article templates', 'articlesandbox-create-button': 'Create article', 'articlesandbox-create-input-placeholder': 'Article title', 'articlesandbox-create-articlesummary': 'Created by |ArticleSandbox user script' }	};

// Import CSS importStylesheet( 'User:Mooeypoo/articlesandbox.css' ); // TODO: Add css loading to the $.ready promise with $.when // mw.loader.load( 'https://www.mediawiki.org/w/index.php?title=User:Mooeypoo/articlesandbox.css&action=raw&ctype=text/css', 'text/css' );

// Set language, with default 'English' mw.messages.set(messages['en']); var lang = mw.config.get('wgUserLanguage'); if (lang && lang != 'en' && lang in messages) { mw.messages.set(messages[lang]); }

mw.loader.using( [ 'oojs-ui', 'mediawiki.util', 'mediawiki.api' ] ).then( function {	// Dialog settings; this must be inside the loader.using scope	// since it requires OOUI	var ArticleDialog = function ArticleDialog( config ) {		ArticleDialog.parent.call( this, config );		this.chosenItem = null;	};	OO.inheritClass( ArticleDialog, OO.ui.ProcessDialog );	ArticleDialog.static.actions = [		{ label: mw.msg( 'articlesandbox-dismiss' ), modes: ['articles', 'create'], flags: 'safe' },		{ action: 'back', label: mw.msg( 'articlesandbox-goback' ), modes: 'create', flags: 'safe', icon: 'arrowPrevious' }	];	ArticleDialog.static.title = mw.msg( 'articlesandbox-title' );	ArticleDialog.static.name = 'articlehelperdialog';	ArticleDialog.static.size = 'medium';	ArticleDialog.prototype.initialize = function  {		var dialog = this;		ArticleDialog.parent.prototype.initialize.apply( this, arguments );		this.content = new OO.ui.PanelLayout( { padded: true, expanded: false } ); this.$articlesPage = $( ' ' ) .addClass( 'articlesandbox-page-articles' )

this.createPageTitle = new OO.ui.LabelWidget( {			label: mw.msg( 'articlesandbox-create-article' ),			classes: [ 'articlesandbox-page-create-title' ]		} ), this.$createPageForm = $( ' ' ) .addClass( 'articlesandbox-page-create-form' ); this.$createPage = $( ' ' ) .addClass( 'articlesandbox-page-create' ) .append(				this.createPageTitle.$element,				this.$createPageForm			);

// Build the dialog body this.content.$element.append(			this.$articlesPage,			this.$createPage		);

this.$body.append( this.content.$element ); };

ArticleDialog.prototype.getActionProcess = function ( action ) { if ( action === 'back' ) { this.showPage( 'articles' ); }		return ArticleDialog.parent.prototype.getActionProcess.call( this, action ); };	ArticleDialog.prototype.getSetupProcess = function ( data ) { return ArticleDialog.parent.prototype.getSetupProcess.call( this, data ) .next( function {	        	this.showPage( 'articles' );	        }, this ); };	ArticleDialog.prototype.buildCreatePageForm = function ( item ) { var data = item ? item.getData : {}, makeHiddenInput = function ( name, value ) { return $( ' ' ) .attr( 'type', 'hidden' ) .attr( 'name', name ) .attr( 'value', value ); },			// Mock a inputbox process $form = $( ' ' ) .attr( 'action', '/w/index.php' ) .attr( 'method', 'get' ) .attr( 'id', 'createbox' ) .attr( 'name', 'createbox' ) .append(					makeHiddenInput( 'action', 'edit' ),					makeHiddenInput( 'preload', data.path ),					makeHiddenInput( 'summary', mw.msg( 'articlesandbox-create-articlesummary' ) ),					makeHiddenInput( 'prefix', 'Special:MyPage/sandbox/')				); $form.append(			new OO.ui.TextInputWidget( { name: 'title', placeholder: mw.msg( 'articlesandbox-create-input-placeholder' ) } ).$element,			new OO.ui.ButtonInputWidget( { type: 'submit', icon: 'add', flags: [ 'progressive' ], label: mw.msg( 'articlesandbox-create-button' ), } ).$element		); this.createPageTitle.setLabel( mw.msg( 'articlesandbox-create-article-for', data.name ) ); this.$createPageForm.empty.append( $form ); };

ArticleDialog.prototype.showPage = function ( name ) { name = name || 'articles';

this.$articlesPage.toggleClass( 'oo-ui-element-hidden', name !== 'articles' ); this.$createPage.toggleClass( 'oo-ui-element-hidden', name !== 'create' );

this.getActions.setMode( name ); };

ArticleDialog.prototype.onArticleListChoose = function ( item ) { var data = item.getData;

this.chosenItem = item;

if ( data.list ) { // Reset selection data.list.selectItem( null ); }

this.buildCreatePageForm( item ); this.showPage( 'create' ); };

ArticleDialog.prototype.createArticleListWidget = function ( articles ) { var listWidget = new OO.ui.SelectWidget( {				classes: [ 'articlesandbox-articles-section-list' ]			} ), pages = articles ? Object.keys( articles ) : [];

// Event listWidget.connect( this, { choose: 'onArticleListChoose' } );

// Add items from top layer pages.forEach( function ( page ) {			var items = [];			if ( $.isEmptyObject( articles[ page ]._articles ) ) {				// This is a leaf article, add item				items.push( new OO.ui.DecoratedOptionWidget( {					data: {						list: listWidget,						name: page,						path: articles[ page ]._path					},					icon: 'edit',					label: page				} ) );			} else {				// This is a category of sub pages, ignore that,				// it's being handled in #addArticleSection			}			listWidget.addItems( items );		} ); return listWidget; };

ArticleDialog.prototype.createArticlesSection = function ( title, articles ) { var dialog = this, listWidget = this.createArticleListWidget( articles ), pages = articles ? Object.keys( articles ) : [], titleWidget = new OO.ui.LabelWidget( {				classes: [ 'articlesandbox-articles-section-title' ],				label: title			} ), $section = $( ' ' ) .addClass( 'articlesandbox-articles-section' ) .append( titleWidget.$element, listWidget.$element );

// Look for sub sections pages.forEach( function ( page ) {			if ( !$.isEmptyObject( articles[ page ]._articles ) ) {				// This is another section, recurse				$section.append( dialog.createArticlesSection( page, articles[ page ]._articles ) );			}		} );		return $section; };

/**	 * Build the content based on the article structure given * 	 * @param {Object} articles Article structure with paths */	ArticleDialog.prototype.buildContent = function ( articles ) { var $articleSection = this.createArticlesSection(			mw.msg( 'articlesandbox-sections' ),			articles		); this.$articlesPage.append( $articleSection ); };

ArticleDialog.prototype.getBodyHeight = function { return this.content.$element.outerHeight( true ); };

var mainDialog = new ArticleDialog, windowManager = new OO.ui.WindowManager, mainButton = new OO.ui.ButtonWidget( {			label: mw.msg( 'articlesandbox-button' ),			icon: 'article',			flags: [ 'progressive' ]		} ); mainButton.setDisabled( true );

windowManager.addWindows( [ mainDialog ] );

// Attach events mainButton.on( 'click', function {		windowManager.openWindow( mainDialog );	} );

// Get the data buildArticleStructure .then( function ( articles ) {			mainDialog.buildContent( articles );			mainButton.setDisabled( false );		} );

$( document ).ready( function {		// Attach to DOM		$( '#right-navigation' ).append( mainButton.$element );		$( 'body' ).append( windowManager.$element );	} );

} );

/** * Build the article structure from the API */ function buildArticleStructure { var path, flatPath, articles = {};

if ( !ARTICLE_REPO ) { return $.Deferred.resolve( {} ); }

return ( new mw.Api ).get( {		action: 'query',		format: 'json',		list: 'prefixsearch',		pssearch: ARTICLE_REPO	} ) .then(		// Success		function ( queryData ) {			var articlesArr = queryData.query.prefixsearch;			articlesArr.forEach( function ( articleData ) { var pieces = [], title = articleData.title;

if ( title.indexOf( ARTICLE_REPO ) !== 0 ) { return; }				pieces = title.replace( ARTICLE_REPO, '' ).split( '/' ); pieces = pieces.filter( function ( piece ) {					return !!piece; // Get rid of empty strings				} );

// Build article structure path = articles; flatPath = ''; pieces.forEach( function ( piece ) {					flatPath += '/' + piece;

path[ piece ] = path[ piece ] || { _path: ARTICLE_REPO + flatPath, _articles: {} };					// Shift reference path = path[piece]._articles; } );			} );			return articles; },		// Convert failure to empty success function { return $.Deferred.resolve( {} ); }	); }

function createDialog { }