r86887 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r86886‎ | r86887 | r86888 >
Date:19:10, 25 April 2011
Author:maxsem
Status:ok
Tags:
Comment:
New extension: ApiSandbox, based on rejected GSoC proposal by Salil P. A. Unfinished, don't localise yet.
Modified paths:
  • /trunk/extensions/ApiSandbox (added) (history)
  • /trunk/extensions/ApiSandbox/ApiSandbox.alias.php (added) (history)
  • /trunk/extensions/ApiSandbox/ApiSandbox.i18n.php (added) (history)
  • /trunk/extensions/ApiSandbox/ApiSandbox.php (added) (history)
  • /trunk/extensions/ApiSandbox/SpecialApiSandbox.php (added) (history)
  • /trunk/extensions/ApiSandbox/ext.apiSandbox.css (added) (history)
  • /trunk/extensions/ApiSandbox/ext.apiSandbox.js (added) (history)

Diff [purge]

Index: trunk/extensions/ApiSandbox/SpecialApiSandbox.php
@@ -0,0 +1,81 @@
 2+<?php
 3+
 4+class SpecialApiSandbox extends SpecialPage {
 5+
 6+ /**
 7+ * Constructor
 8+ */
 9+ public function __construct() {
 10+ parent::__construct( 'ApiSandbox', '', true );
 11+ }
 12+
 13+ /**
 14+ * Main execution function
 15+ * @param $par Parameters passed to the page
 16+ */
 17+ public function execute( $par ) {
 18+ global $wgEnableAPI;
 19+
 20+ $out = $this->getContext()->getOutput();
 21+
 22+ if ( !$wgEnableAPI ) {
 23+ $out->showErrorPage( 'error', 'apisb-api-disabled' );
 24+ }
 25+
 26+ $this->setHeaders();
 27+ $out->setPageTitle( wfMessage( 'apisb-title' )->parse() );
 28+ $out->addModules( 'ext.apiSandbox' );
 29+
 30+ $out->addHTML( '<noscript>' . wfMessage( 'apisb-no-js' )->escaped() . '</noscript>
 31+<div id="api-sandbox-content" style="display: none">' );
 32+ $out->addWikiMsg( 'apisb-intro' );
 33+ $out->addHTML( $this->openFieldset( 'parameters' )
 34+ . $this->getInputs() . '
 35+</fieldset>
 36+' . $this->openFieldset( 'result' ) . '
 37+</fieldset>' );
 38+
 39+ $out->addHTML( '</div>' ); # <div id="api-sandbox-content">
 40+ }
 41+
 42+ private function getInputs() {
 43+ global $wgEnableWriteAPI;
 44+
 45+ $apiMain = new ApiMain( new FauxRequest( array() ), $wgEnableWriteAPI );
 46+ $apiQuery = new ApiQuery( $apiMain, 'query' );
 47+
 48+ $s = '<table class="api-sandbox-options">
 49+<tbody>
 50+<tr><td class="api-sandbox-label"><label for="api-sandbox-action">action=</label></td><td class="api-sandbox-value">'
 51+ . $this->getSelect( 'action', $apiMain->getModules() ) . '</td><td id="api-sandbox-help" rowspan="2"></td></tr>
 52+';
 53+ $s .= '<tr id="api-sandbox-prop-row" style="display: none"><td class="api-sandbox-label"><label for="api-sandbox-prop">prop=</label></td><td class="api-sandbox-value">'
 54+ . $this->getSelect( 'prop', $apiQuery->getModules() )
 55+ . '</td></tr>
 56+</table>
 57+<div id="api-sandbox-further-inputs"></div>
 58+';
 59+ return $s;
 60+ }
 61+
 62+ private function getSelect( $name, $items ) {
 63+ $items = array_keys( $items );
 64+ sort( $items );
 65+ $s = Html::openElement( 'select', array( 'class' => 'api-sandbox-input', 'name' => $name, 'id' => "api-sandbox-$name" ) );
 66+ $s .= "\n\t" . Html::element( 'option',
 67+ array( 'value' => '-', 'selected' => 'selected' ),
 68+ wfMessage( "apisb-select-$name" )->text()
 69+ );
 70+ foreach ( $items as $item ) {
 71+ $s .= "\n\t" . Html::element( 'option', array( 'value' => $item ), $item );
 72+ }
 73+ $s .= "\n" . Html::closeElement( 'select' ) . "\n";
 74+ return $s;
 75+ }
 76+
 77+ private function openFieldset( $name ) {
 78+ return "\n" . Html::openElement( 'fieldset', array( 'id' => "api-sandbox-$name" ) )
 79+ . "\n\t" . Html::rawElement( 'legend', array(), wfMessage( "apisb-$name" )->parse() )
 80+ . "\n";
 81+ }
 82+}
\ No newline at end of file
Property changes on: trunk/extensions/ApiSandbox/SpecialApiSandbox.php
___________________________________________________________________
Added: svn:eol-style
183 + native
Index: trunk/extensions/ApiSandbox/ext.apiSandbox.js
@@ -0,0 +1,174 @@
 2+$( document ).ready( function() {
 3+ var content = $( '#api-sandbox-content' );
 4+ if ( !content.length ) {
 5+ return;
 6+ }
 7+ content.show();
 8+
 9+ var action = $( '#api-sandbox-action' );
 10+ var prop = $( '#api-sandbox-prop' );
 11+ var propRow = $( '#api-sandbox-prop-row' );
 12+ var help = $( '#api-sandbox-help' );
 13+ var further = $( '#api-sandbox-further-inputs' );
 14+ var actionCache = [];
 15+ var propCache = [];
 16+
 17+ function isset( x ) {
 18+ return typeof x != 'undefined';
 19+ }
 20+
 21+ function showLoading( element ) {
 22+ element.html( mw.msg( 'apisb-loading' ) ); // @todo:
 23+ }
 24+
 25+ function showLoadError( element ) {
 26+ element.html( '<span style="error">' + mw.msg( 'apisb-load-error' ) + '</span>' );
 27+ }
 28+
 29+ function parseParamInfo( data ) {
 30+ further.text( '' );
 31+ if ( !isset( data.paraminfo )
 32+ || ( !isset( data.paraminfo.modules ) && !isset( data.paraminfo.querymodules ) )
 33+ )
 34+ {
 35+ showLoadError( further );
 36+ return;
 37+ }
 38+ if ( isset( data.paraminfo.modules ) ) {
 39+ actionCache[data.paraminfo.modules[0].name] = data.paraminfo.modules[0];
 40+ createInputs( actionCache[data.paraminfo.modules[0].name] );
 41+ } else {
 42+ propCache[data.paraminfo.querymodules[0].name] = data.paraminfo.querymodules[0];
 43+ createInputs( propCache[data.paraminfo.querymodules[0].name] );
 44+ }
 45+
 46+ }
 47+
 48+ function getQueryInfo( action, prop ) {
 49+ var isQuery = action == 'query';
 50+ if ( action == '-' || ( isQuery && prop == '-' ) ) {
 51+ return;
 52+ }
 53+ var cached;
 54+ if ( isQuery ) {
 55+ cached = propCache[prop];
 56+ } else {
 57+ cached = actionCache[action];
 58+ }
 59+ if ( typeof cached != 'object' ) { // stupid FF adds watch() everywhere
 60+ showLoading( further );
 61+ var data = {
 62+ format: 'json',
 63+ action: 'paraminfo',
 64+ };
 65+ if (isQuery ) {
 66+ data.querymodules = prop;
 67+ } else {
 68+ data.modules = action;
 69+ }
 70+ $.getJSON(
 71+ mw.config.get( 'wgScriptPath' ) + '/api' + mw.config.get( 'wgScriptExtension' ),
 72+ data,
 73+ parseParamInfo
 74+ );
 75+ } else {
 76+ createInputs( cached );
 77+ }
 78+ }
 79+
 80+ function createInputs( info ) {
 81+ help.text( info.description );
 82+ var s = '<table class="api-sandbox-options">\n<tbody>';
 83+ for ( var i = 0; i < info.parameters.length; i++ ) {
 84+ var param = info.parameters[i];
 85+ var name = info.prefix + param.name;
 86+ var desc = mw.html.escape( param.description );
 87+ if ( desc.indexOf( '\n ' ) >= 0 ) {
 88+ desc = desc.replace( /^(.*?)((?:\n\s+[^\n]*)+)(.*?)$/m, '$1<ul>$2</ul>$3' );
 89+ desc = desc.replace( /\n\s+([^\n]*)/g, '\n<li>$1</li>' );
 90+ }
 91+ desc = desc.replace( /\n(?!<)/, '\n<br/>' );
 92+
 93+ s += '<tr><td class="api-sandbox-label"><label for="param-' + name + '">' + name + '=</label></td>'
 94+ + '<td class="api-sandbox-value">' + input( param, name )
 95+ + '</td><td>' + desc + '</td></tr>';
 96+ }
 97+ s += '\n</tbody>\n</table>\n';
 98+ further.html( s );
 99+ }
 100+
 101+ function input( param, name ) {
 102+ var s = param.type;
 103+ var value = '';
 104+ switch ( param.type ) {
 105+ case 'limit':
 106+ value = 10;
 107+ case 'integer':
 108+ case 'string':
 109+ case 'user':
 110+ s = '<input class="api-sandbox-input" id="param-' + name + '" value="' + value + '"/>';
 111+ break;
 112+ case 'bool':
 113+ case 'boolean':
 114+ s = '<input id="param-' + name + '" type="checkbox"/>';
 115+ break;
 116+ default:
 117+ if ( typeof param.type == 'object' ) {
 118+ var id = 'param-' + name;
 119+ var attributes = { 'id': id };
 120+ if ( isset( param.multi ) ) {
 121+ attributes.multiple = 'multiple';
 122+ s = select( param.type, attributes, false );
 123+ } else {
 124+ s = select( param.type, attributes, true );
 125+ }
 126+ }
 127+ }
 128+ return s;
 129+ }
 130+
 131+ function select( values, attributes, selected ) {
 132+ var s = '<select class="api-sandbox-input"';
 133+ if ( isset( attributes.multiple ) ) {
 134+ s += ' size="' + values.length + '"';
 135+ }
 136+ for ( var a in attributes ) {
 137+ s += ' ' + a + '="' + attributes[a] + '"';
 138+ }
 139+ s += '>';
 140+ if ( typeof selected != 'array' ) {
 141+ if ( selected ) {
 142+ s += '\n<option value="" selected="selected">' + mw.msg( 'apisb-select-value' ) + '</option>';
 143+ }
 144+ selected = [];
 145+ }
 146+ for ( var i = 0; i < values.length; i++ ) {
 147+ s += '\n<option value="' + values[i] + '"';
 148+ if ( $.inArray( values[i], selected ) >= 0 ) {
 149+ s += ' selected="selected"';
 150+ }
 151+ s += '>' + values[i] + '</option>';
 152+ }
 153+ s += '\n</select>';
 154+ return s;
 155+ }
 156+
 157+ function updateBasics() {
 158+ var a = action.val();
 159+ var p = prop.val();
 160+ var isQuery = a == 'query';
 161+ if ( isQuery ) {
 162+ propRow.show();
 163+ } else {
 164+ propRow.hide();
 165+ }
 166+ further.text( '' );
 167+ help.text( '' );
 168+ getQueryInfo( a, p );
 169+ }
 170+
 171+ action.change( updateBasics );
 172+ prop.change( updateBasics );
 173+
 174+
 175+});
\ No newline at end of file
Property changes on: trunk/extensions/ApiSandbox/ext.apiSandbox.js
___________________________________________________________________
Added: svn:eol-style
1176 + native
Index: trunk/extensions/ApiSandbox/ApiSandbox.alias.php
@@ -0,0 +1,18 @@
 2+<?php
 3+/**
 4+ * Aliases for Special:ApiSandbox
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ */
 9+
 10+$specialPageAliases = array();
 11+
 12+/**
 13+ * English
 14+ */
 15+$specialPageAliases['en'] = array(
 16+ 'ApiSandbox' => array( 'ApiSandbox' ),
 17+);
 18+
 19+$aliases =& $specialPageAliases;
Property changes on: trunk/extensions/ApiSandbox/ApiSandbox.alias.php
___________________________________________________________________
Added: svn:eol-style
120 + native
Index: trunk/extensions/ApiSandbox/ApiSandbox.i18n.php
@@ -0,0 +1,18 @@
 2+<?php
 3+
 4+$messages = array();
 5+
 6+$messages['en'] = array(
 7+ 'apisb-desc' => 'Allows to debug [http://www.mediawiki.org/wiki/API MediaWiki API] calls from browser',
 8+ 'apisb-title' => 'API sandbox',
 9+ 'apisb-no-js' => "'''Error''': this feature requires JavaScript.",
 10+ 'apisb-intro' => 'Blah blah intro, dude!',
 11+ 'apisb-api-disabled' => 'API is disabled on this site.',
 12+ 'apisb-parameters' => 'Parameters',
 13+ 'apisb-result' => 'Result',
 14+ 'apisb-select-action' => 'Select action',
 15+ 'apisb-select-prop' => 'Select property',
 16+ 'apisb-select-value' => 'Select value',
 17+ 'apisb-loading' => 'Loading...',
 18+ 'apisb-load-error' => 'Error loading API description',
 19+);
\ No newline at end of file
Property changes on: trunk/extensions/ApiSandbox/ApiSandbox.i18n.php
___________________________________________________________________
Added: svn:eol-style
120 + native
Index: trunk/extensions/ApiSandbox/ApiSandbox.php
@@ -0,0 +1,33 @@
 2+<?php
 3+/**
 4+ * API sandbox extension. Initial author Max Semenik, based on idea by Salil P. A.
 5+ * License: WTFPL 2.0
 6+ */
 7+
 8+
 9+$wgExtensionCredits['other'][] = array(
 10+ 'path' => __FILE__,
 11+ 'name' => 'ApiSandbox',
 12+ 'author' => array( 'Max Semenik' ),
 13+ 'url' => 'http://mediawiki.org/wiki/Extension:ApiSandbox',
 14+ 'descriptionmsg' => 'apisb-desc',
 15+);
 16+
 17+$dir = dirname(__FILE__) . '/';
 18+
 19+$wgExtensionMessagesFiles['ApiSandbox'] = $dir . 'ApiSandbox.i18n.php';
 20+$wgExtensionAliasesFiles['ApiSandbox'] = $dir . 'ApiSandbox.alias.php';
 21+
 22+$wgAutoloadClasses['SpecialApiSandbox'] = $dir . 'SpecialApiSandbox.php';
 23+
 24+$wgSpecialPages['ApiSandbox'] = 'SpecialApiSandbox';
 25+$wgSpecialPageGroups['Gadgets'] = 'wiki';
 26+
 27+$wgResourceModules['ext.apiSandbox'] = array(
 28+ 'scripts' => 'ext.apiSandbox.js',
 29+ 'styles' => 'ext.apiSandbox.css',
 30+ 'dependencies' => array( 'jquery.json' ),
 31+ 'localBasePath' => dirname( __FILE__ ),
 32+ 'remoteExtPath' => 'ApiSandbox',
 33+ 'messages' => array( 'apisb-loading', 'apisb-load-error', 'apisb-select-value' ),
 34+);
Property changes on: trunk/extensions/ApiSandbox/ApiSandbox.php
___________________________________________________________________
Added: svn:eol-style
135 + native
Index: trunk/extensions/ApiSandbox/ext.apiSandbox.css
@@ -0,0 +1,20 @@
 2+table.api-sandbox-options {
 3+ width: 100%;
 4+}
 5+
 6+td.api-sandbox-label {
 7+ text-align: right;
 8+ width: 12em;
 9+ vertical-align: top;
 10+ font-family: monospace;
 11+}
 12+
 13+td.api-sandbox-value {
 14+ width: 18em;
 15+ vertical-align: top;
 16+ overflow: auto;
 17+}
 18+
 19+.api-sandbox-input {
 20+ width: 17em;
 21+}
\ No newline at end of file
Property changes on: trunk/extensions/ApiSandbox/ext.apiSandbox.css
___________________________________________________________________
Added: svn:eol-style
122 + native

Sign-offs

UserFlagDate
Reedytested01:46, 30 June 2011

Status & tagging log