MaxSem has uploaded a new change for review.
https://gerrit.wikimedia.org/r/103721
Change subject: Split JS to several files for improved modularity
......................................................................
Split JS to several files for improved modularity
Change-Id: I389cec418be72b3b021404abb7b0b530f71dd50f
---
M ApiSandbox.php
A resources/UiBuilder.js
A resources/apiSandbox.js
R resources/main.js
R resources/styles.css
5 files changed, 246 insertions(+), 228 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/ApiSandbox
refs/changes/21/103721/1
diff --git a/ApiSandbox.php b/ApiSandbox.php
index 9418788..93d5544 100644
--- a/ApiSandbox.php
+++ b/ApiSandbox.php
@@ -20,10 +20,14 @@
$wgSpecialPageGroups['ApiSandbox'] = 'wiki';
$wgResourceModules['ext.apiSandbox'] = array(
- 'scripts' => 'ext.apiSandbox.js',
- 'styles' => 'ext.apiSandbox.css',
- 'localBasePath' => __DIR__ . '/modules',
- 'remoteExtPath' => 'ApiSandbox/modules',
+ 'scripts' => array(
+ 'apiSandbox.js',
+ 'UiBuilder.js',
+ 'main.js',
+ ),
+ 'styles' => 'styles.css',
+ 'localBasePath' => __DIR__ . '/resources',
+ 'remoteExtPath' => 'ApiSandbox/resources',
'messages' => array(
'apisb-loading',
'apisb-load-error',
diff --git a/resources/UiBuilder.js b/resources/UiBuilder.js
new file mode 100644
index 0000000..08d1ba0
--- /dev/null
+++ b/resources/UiBuilder.js
@@ -0,0 +1,209 @@
+/*global jQuery, mediaWiki, apiSandbox*/
+/*jslint regexp: true, browser: true, continue: true, sloppy: true, white:
true, forin: true, plusplus: true */
+( function ( $, mw, apiSandbox, undefined ) {
+ /**
+ * HTML-escapes and pretty-formats an API description string
+ *
+ * @param s {String} String to escape
+ * @return {String}
+ */
+ var smartEscape = function( s ) {
+ if ( !s ) {
+ return ''; // @todo: fully verify paraminfo output
+ }
+ s = mw.html.escape( s );
+ if ( s.indexOf( '\n ' ) >= 0 ) {
+ // turns *-bulleted list into a HTML list
+ s = s.replace( /^(.*?)((?:\n\s+\*?[^\n]*)+)(.*?)$/m,
'$1<ul>$2</ul>$3' ); // outer tags
+ s = s.replace( /\n\s+\*?([^\n]*)/g, '\n<li>$1</li>' );
// <li> around bulleted lines
+ }
+ s = s.replace( /\n(?!<)/, '\n<br/>' );
+ s = s.replace( /(?:https?:)?\/\/[^\s<>]+/g, function ( s ) {
+ // linkify URLs, input is already HTML-escaped above
+ return '<a href="' + s + '">' + s + '</a>';
+ } );
+ return s;
+ };
+
+
+ /**
+ * Class that creates inputs for a query and builds request data
+ *
+ * @constructor
+ * @param $container {jQuery} Container to put UI into
+ * @param info {Object} Query information
+ * @param prefix {String} Additional prefix for parameter names
+ */
+ function UiBuilder( $container, info, prefix ) {
+ this.$container = $container;
+ this.info = info;
+ this.prefix = prefix + info.prefix;
+ this.params = info.parameters;
+
+ $container.addClass( 'api-sandbox-builder' ).data( 'builder',
this );
+
+ this.createInputs();
+ }
+
+ UiBuilder.prototype = {
+ /**
+ * Creates inputs and places them into container
+ */
+ createInputs: function () {
+ var $table, $tbody, i, length, param, name;
+
+ $table = $( '<table class="api-sandbox-params
mw-datatable"><thead><tr></tr></thead><tbody></tbody></table>' )
+ .find( '> thead > tr' )
+ .append( mw.html.element( 'th', { 'class':
'api-sandbox-params-label' }, mw.msg( 'apisb-params-param' ) ) )
+ .append( mw.html.element( 'th', { 'class':
'api-sandbox-params-value' }, mw.msg( 'apisb-params-input' ) ) )
+ .append( mw.html.element( 'th', {}, mw.msg(
'apisb-params-desc' ) ) )
+ .end();
+ $tbody = $table.find( '> tbody' );
+ for ( i = 0, length = this.params.length; i < length; i
+= 1 ) {
+ param = this.params[i];
+ name = this.prefix + param.name;
+
+ $( '<tr>' )
+ .append(
+ $( '<td
class="api-sandbox-params-label"></td>' )
+ .html( mw.html.element(
'label',
+ { 'for':
'param-' + name }, name )
+ )
+ )
+ .append( $( '<td
class="api-sandbox-params-value"></td>' ).html( this.input( param, name ) ) )
+ .append( $( '<td class="mw-content-ltr"
dir="ltr">' ).html( smartEscape( param.description ) ) )
+ .appendTo( $tbody );
+ }
+ this.$container.html( $table );
+ },
+
+ /**
+ * Adds module help to a container
+ * @param $container {jQuery} Container to use
+ */
+ setHelp: function ( $container ) {
+ var linkHtml = '',
+ descHtml = smartEscape( this.info.description );
+
+ if ( this.info.helpurls && this.info.helpurls[0] ) {
+ descHtml = descHtml + ' ';
+ linkHtml = mw.msg( 'parentheses',
mw.html.element( 'a', {
+ 'target': '_blank',
+ 'href': this.info.helpurls[0]
+ }, mw.msg( 'apisb-docs-more' ) ) );
+ }
+ $container.html( descHtml ).append( linkHtml );
+ },
+
+ input: function ( param, name ) {
+ var s, id, attributes,
+ value = '';
+ switch ( param.type ) {
+ case 'limit':
+ value = '10';
+ // fall through:
+ case 'user':
+ case 'timestamp':
+ case 'integer':
+ case 'string':
+ s = mw.html.element( 'input', {
+ 'class': 'api-sandbox-input',
+ 'id': 'param-' + name,
+ 'value': value,
+ 'type': 'text'
+ } );
+ break;
+
+ case 'bool':
+ // normalisation for later use
+ param.type = 'boolean';
+ // fall through:
+ case 'boolean':
+ s = mw.html.element( 'input', {
+ 'id': 'param-' + name,
+ 'type': 'checkbox'
+ } );
+ break;
+
+ case 'namespace':
+ param.type =
apiSandbox.namespaceOptions;
+ // fall through:
+ default:
+ if ( typeof param.type === 'object' ) {
+ id = 'param-' + name;
+ attributes = { 'id': id };
+ if ( param.multi !== undefined
) {
+ attributes.multiple =
true;
+ s = this.select(
param.type, attributes, false );
+ } else {
+ s = this.select(
param.type, attributes, true );
+ }
+ } else {
+ s = mw.html.element( 'code',
{}, mw.msg( 'parentheses', param.type ) );
+ }
+ }
+ return s;
+ },
+
+ select: function ( values, attributes, selected ) {
+ var i, length, value, face, attrs,
+ s = '';
+
+ attributes['class'] = 'api-sandbox-input';
+ if ( attributes.multiple === true ) {
+ attributes.size = Math.min( values.length, 10 );
+ }
+ if ( !$.isArray( selected ) ) {
+ if ( selected ) {
+ s += mw.html.element( 'option', {
+ value: '',
+ selected: true
+ }, mw.msg( 'apisb-select-value' ) );
+ }
+ selected = [];
+ }
+
+ for ( i = 0, length = values.length; i < length; i += 1
) {
+ value = typeof values[i] === 'object' ?
values[i].key : values[i];
+ face = typeof values[i] === 'object' ?
values[i].value : values[i];
+ attrs = { 'value': value };
+
+ if ( $.inArray( value, selected ) >= 0 ) {
+ attrs.selected = true;
+ }
+
+ s += mw.html.element( 'option', attrs, face );
+ }
+ s = mw.html.element( 'select', attributes, new
mw.html.Raw( s ) );
+ return s;
+ },
+
+ getRequestData: function () {
+ var params = '', i, length, param, name, $node, value;
+
+ for ( i = 0, length = this.params.length; i < length; i
+= 1 ) {
+ param = this.params[i];
+ name = this.prefix + param.name;
+ $node = $( '#param-' + name );
+ if ( param.type === 'boolean' ) {
+ if ( $node.prop( 'checked' ) === true )
{
+ //the = is needed (at least in
post), see bug 25174
+ params += '&' + name + '=';
+ }
+ } else {
+ value = $node.val();
+ if ( value === undefined || value ===
null || value === '' ) {
+ continue;
+ }
+ if ( $.isArray( value ) ) {
+ value = value.join( '|' );
+ }
+ params += '&' + encodeURIComponent(
name ) + '=' + encodeURIComponent( value );
+ }
+ }
+ return params;
+ }
+ };
+
+ apiSandbox.UiBuilder = UiBuilder;
+}( jQuery, mediaWiki, mw.apiSandbox ) );
\ No newline at end of file
diff --git a/resources/apiSandbox.js b/resources/apiSandbox.js
new file mode 100644
index 0000000..5d8561a
--- /dev/null
+++ b/resources/apiSandbox.js
@@ -0,0 +1,21 @@
+/*jslint regexp: true, browser: true, continue: true, sloppy: true, white:
true, forin: true, plusplus: true */
+mediaWiki.apiSandbox = {
+ namespaceOptions: [],
+
+ // build namespace cache
+ init: function() {
+ $.each( mw.config.get( 'wgFormattedNamespaces' ), function (
nsId, nsName ) {
+ if ( Number( nsId ) >= 0 ) {
+ if ( nsId === '0' ) {
+ nsName = mw.msg( 'apisb-ns-main' );
+ }
+ mw.apiSandbox.namespaceOptions.push( {
+ key: nsId,
+ value: nsName
+ } );
+ }
+ } );
+ }
+};
+
+mediaWiki.apiSandbox.init();
\ No newline at end of file
diff --git a/modules/ext.apiSandbox.js b/resources/main.js
similarity index 70%
rename from modules/ext.apiSandbox.js
rename to resources/main.js
index 1283e63..2b8b51a 100644
--- a/modules/ext.apiSandbox.js
+++ b/resources/main.js
@@ -1,19 +1,20 @@
-/*global jQuery, mediaWiki*/
+/*global jQuery, mediaWiki, apiSandbox*/
/*jslint regexp: true, browser: true, continue: true, sloppy: true, white:
true, forin: true, plusplus: true */
-( function ( $, mw, undefined ) {
+( function ( $, mw, apiSandbox, undefined ) {
var mainRequest, genericRequest, generatorRequest, queryRequest, //
UiBuilder objects
// Caches
- paramInfo, namespaceOptions,
+ paramInfo,
// page elements
$format, $action, $query, $queryRow, $help, $mainContainer,
$genericContainer,
$generatorContainer, $queryContainer, $generatorBox, $form,
$submit, $requestUrl, $requestPost,
- $output, $postRow, $buttonsContainer, $examplesButton,
$examplesContent, $pageScroll;
+ $output, $postRow, $buttonsContainer, $examplesButton,
$examplesContent, $pageScroll,
+ UiBuilder = apiSandbox.UiBuilder;
/** Local utility functions **/
- // get the first element in a list that is "scrollable"
- // depends on browser and skin (i.e. body or html)
+ // get the first element in a list that is "scrollable"
+ // depends on browser and skin (i.e. body or html)
function getScrollableElement( /* selectors, ... */ ) {
var i, argLen, el, $el, canScroll;
for ( i = 0, argLen = arguments.length; i < argLen; i += 1 ) {
@@ -384,30 +385,6 @@
}
/**
- * HTML-escapes and pretty-formats an API description string
- *
- * @param s {String} String to escape
- * @return {String}
- */
- function smartEscape( s ) {
- if ( !s ) {
- return ''; // @todo: fully verify paraminfo output
- }
- s = mw.html.escape( s );
- if ( s.indexOf( '\n ' ) >= 0 ) {
- // turns *-bulleted list into a HTML list
- s = s.replace( /^(.*?)((?:\n\s+\*?[^\n]*)+)(.*?)$/m,
'$1<ul>$2</ul>$3' ); // outer tags
- s = s.replace( /\n\s+\*?([^\n]*)/g, '\n<li>$1</li>' );
// <li> around bulleted lines
- }
- s = s.replace( /\n(?!<)/, '\n<br/>' );
- s = s.replace( /(?:https?:)?\/\/[^\s<>]+/g, function ( s ) {
- // linkify URLs, input is already HTML-escaped above
- return '<a href="' + s + '">' + s + '</a>';
- } );
- return s;
- }
-
- /**
* Updates UI after basic query parameters have been changed
*/
function updateUI( callback, callIfEmpty ) {
@@ -472,185 +449,6 @@
} );
}
- /**
- * Constructor that creates inputs for a query and builds request data
- *
- * @constructor
- * @param $container {jQuery} Container to put UI into
- * @param info {Object} Query information
- * @param prefix {String} Additional prefix for parameter names
- */
- function UiBuilder( $container, info, prefix ) {
- this.$container = $container;
- this.info = info;
- this.prefix = prefix + info.prefix;
- this.params = info.parameters;
-
- $container.addClass( 'api-sandbox-builder' ).data( 'builder',
this );
-
- this.createInputs();
- }
-
- UiBuilder.prototype = {
- /**
- * Creates inputs and places them into container
- */
- createInputs: function () {
- var $table, $tbody, i, length, param, name;
-
- $table = $( '<table class="api-sandbox-params
mw-datatable"><thead><tr></tr></thead><tbody></tbody></table>' )
- .find( '> thead > tr' )
- .append( mw.html.element( 'th', {
'class': 'api-sandbox-params-label' }, mw.msg( 'apisb-params-param' ) ) )
- .append( mw.html.element( 'th', {
'class': 'api-sandbox-params-value' }, mw.msg( 'apisb-params-input' ) ) )
- .append( mw.html.element( 'th', {},
mw.msg( 'apisb-params-desc' ) ) )
- .end();
- $tbody = $table.find( '> tbody' );
- for ( i = 0, length = this.params.length; i < length; i
+= 1 ) {
- param = this.params[i];
- name = this.prefix + param.name;
-
- $( '<tr>' )
- .append(
- $( '<td
class="api-sandbox-params-label"></td>' )
- .html( mw.html.element(
'label',
- { 'for':
'param-' + name }, name )
- )
- )
- .append( $( '<td
class="api-sandbox-params-value"></td>' ).html( this.input( param, name ) ) )
- .append( $( '<td class="mw-content-ltr"
dir="ltr">' ).html( smartEscape( param.description ) ) )
- .appendTo( $tbody );
- }
- this.$container.html( $table );
- },
-
- /**
- * Adds module help to a container
- * @param $container {jQuery} Container to use
- */
- setHelp: function ( $container ) {
- var linkHtml = '',
- descHtml = smartEscape( this.info.description );
-
- if ( this.info.helpurls && this.info.helpurls[0] ) {
- descHtml = descHtml + ' ';
- linkHtml = mw.msg( 'parentheses',
mw.html.element( 'a', {
- 'target': '_blank',
- 'href': this.info.helpurls[0]
- }, mw.msg( 'apisb-docs-more' ) ) );
- }
- $container.html( descHtml ).append( linkHtml );
- },
-
- input: function ( param, name ) {
- var s, id, attributes,
- value = '';
- switch ( param.type ) {
- case 'limit':
- value = '10';
- // fall through:
- case 'user':
- case 'timestamp':
- case 'integer':
- case 'string':
- s = mw.html.element( 'input', {
- 'class': 'api-sandbox-input',
- 'id': 'param-' + name,
- 'value': value,
- 'type': 'text'
- } );
- break;
-
- case 'bool':
- // normalisation for later use
- param.type = 'boolean';
- // fall through:
- case 'boolean':
- s = mw.html.element( 'input', {
- 'id': 'param-' + name,
- 'type': 'checkbox'
- } );
- break;
-
- case 'namespace':
- param.type = namespaceOptions;
- // fall through:
- default:
- if ( typeof param.type === 'object' ) {
- id = 'param-' + name;
- attributes = { 'id': id };
- if ( param.multi !== undefined
) {
- attributes.multiple =
true;
- s = this.select(
param.type, attributes, false );
- } else {
- s = this.select(
param.type, attributes, true );
- }
- } else {
- s = mw.html.element( 'code',
{}, mw.msg( 'parentheses', param.type ) );
- }
- }
- return s;
- },
-
- select: function ( values, attributes, selected ) {
- var i, length, value, face, attrs,
- s = '';
-
- attributes['class'] = 'api-sandbox-input';
- if ( attributes.multiple === true ) {
- attributes.size = Math.min( values.length, 10 );
- }
- if ( !$.isArray( selected ) ) {
- if ( selected ) {
- s += mw.html.element( 'option', {
- value: '',
- selected: true
- }, mw.msg( 'apisb-select-value' ) );
- }
- selected = [];
- }
-
- for ( i = 0, length = values.length; i < length; i += 1
) {
- value = typeof values[i] === 'object' ?
values[i].key : values[i];
- face = typeof values[i] === 'object' ?
values[i].value : values[i];
- attrs = { 'value': value };
-
- if ( $.inArray( value, selected ) >= 0 ) {
- attrs.selected = true;
- }
-
- s += mw.html.element( 'option', attrs, face );
- }
- s = mw.html.element( 'select', attributes, new
mw.html.Raw( s ) );
- return s;
- },
-
- getRequestData: function () {
- var params = '', i, length, param, name, $node, value;
-
- for ( i = 0, length = this.params.length; i < length; i
+= 1 ) {
- param = this.params[i];
- name = this.prefix + param.name;
- $node = $( '#param-' + name );
- if ( param.type === 'boolean' ) {
- if ( $node.prop( 'checked' ) === true )
{
- //the = is needed (at least in
post), see bug 25174
- params += '&' + name + '=';
- }
- } else {
- value = $node.val();
- if ( value === undefined || value ===
null || value === '' ) {
- continue;
- }
- if ( $.isArray( value ) ) {
- value = value.join( '|' );
- }
- params += '&' + encodeURIComponent(
name ) + '=' + encodeURIComponent( value );
- }
- }
- return params;
- }
- }; // end of UiBuilder.prototype
-
/** When the dom is ready... **/
$( function () {
@@ -704,20 +502,6 @@
// init caches
paramInfo = { modules: {}, querymodules: {} };
- namespaceOptions = [];
-
- // build namespace cache
- $.each( mw.config.get( 'wgFormattedNamespaces' ), function (
nsId, nsName ) {
- if ( Number( nsId ) >= 0 ) {
- if ( nsId === '0' ) {
- nsName = mw.msg( 'apisb-ns-main' );
- }
- namespaceOptions.push( {
- key: nsId,
- value: nsName
- } );
- }
- } );
// load stuff we need from the beginning
getParamInfo(
@@ -816,4 +600,4 @@
} );
doHash();
} );
-}( jQuery, mediaWiki ) );
+}( jQuery, mediaWiki, mw.apiSandbox ) );
diff --git a/modules/ext.apiSandbox.css b/resources/styles.css
similarity index 100%
rename from modules/ext.apiSandbox.css
rename to resources/styles.css
--
To view, visit https://gerrit.wikimedia.org/r/103721
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I389cec418be72b3b021404abb7b0b530f71dd50f
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/ApiSandbox
Gerrit-Branch: master
Gerrit-Owner: MaxSem <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits