r82595 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r82594‎ | r82595 | r82596 >
Date:09:59, 22 February 2011
Author:ialex
Status:deferred
Tags:
Comment:
Rewrote the extension to use the ressource loader and jQuery.
Now requires MW 1.17+
Modified paths:
  • /trunk/extensions/Configure/CHANGELOG (modified) (history)
  • /trunk/extensions/Configure/Configure.api.php (modified) (history)
  • /trunk/extensions/Configure/Configure.func.php (modified) (history)
  • /trunk/extensions/Configure/Configure.js (modified) (history)
  • /trunk/extensions/Configure/Configure.php (modified) (history)
  • /trunk/extensions/Configure/settings/Settings-core.php (modified) (history)
  • /trunk/extensions/Configure/specials/ConfigurationPage.php (modified) (history)

Diff [purge]

Index: trunk/extensions/Configure/Configure.api.php
@@ -8,7 +8,7 @@
99 }
1010
1111 public function execute() {
12 - global $wgConf, $wgUser, $wgConfigureWikis;
 12+ global $wgConf, $wgUser, $wgConfigureWikis, $wgConfigureAPI;
1313 $params = $this->extractRequestParams();
1414 $result = $this->getResult();
1515
@@ -17,6 +17,17 @@
1818 }
1919
2020 $prop = array_flip( $params['prop'] );
 21+
 22+ if ( isset( $prop['ajax'] ) ) {
 23+ $ret = $this->ajaxGetNewGroup( $params['ajaxsetting'], $params['ajaxgroup'] );
 24+ $result->addValue( $this->getModuleName(), $ret[0], $ret[1] );
 25+ return;
 26+ }
 27+
 28+ if ( !$wgConfigureAPI ) {
 29+ $this->dieUsage( "The ``configure'' module has been disabled.", 'moduledisabled' );
 30+ }
 31+
2132 // Version list
2233 if ( isset( $prop['versionlist'] ) ) {
2334 if ( $wgUser->isAllowed( 'viewconfig' ) ) {
@@ -324,37 +335,97 @@
325336 return $settingRet;
326337 }
327338
 339+ protected function ajaxGetNewGroup( $setting, $group ) {
 340+ $settings = ConfigurationSettings::singleton( CONF_SETTINGS_BOTH );
 341+ if ( $settings->getSettingType( $setting ) != 'array' ) {
 342+ return array( 'error', 'notarray' );
 343+ }
 344+
 345+ $type = $settings->getArrayType( $setting );
 346+ switch( $type ) {
 347+ case 'group-bool':
 348+ if ( isset( $GLOBALS[$setting] ) && isset( $GLOBALS[$setting][$group] ) )
 349+ return array( 'error', 'exists' );
 350+
 351+ $row = ConfigurationPage::buildGroupSettingRow( $setting, $type, User::getAllRights(), true, $group, array() );
 352+
 353+ // Firefox seems to not like that :(
 354+ return array( 'ajax', str_replace( ' ', ' ', $row ) );
 355+ case 'promotion-conds':
 356+ if ( isset( $GLOBALS[$setting] ) && isset( $GLOBALS[$setting][$group] ) )
 357+ return array( 'error', 'exists' );
 358+
 359+ return array( 'ajax', ConfigurationPage::buildPromotionCondsSettingRow( $setting, true, $group, array() ) );
 360+ default:
 361+ return array( 'error', 'notvalidarray' );
 362+ }
 363+ }
 364+
328365 protected function getAllowedParams() {
329 - return array(
330 - 'prop' => array(
331 - ApiBase::PARAM_ISMULTI => true,
332 - ApiBase::PARAM_TYPE => array(
333 - 'versionlist',
334 - 'wikilist',
335 - 'settings',
336 - 'extensions',
 366+ global $wgConfigureAPI;
 367+
 368+ if ( $wgConfigureAPI ) {
 369+ return array(
 370+ 'prop' => array(
 371+ ApiBase::PARAM_ISMULTI => true,
 372+ ApiBase::PARAM_TYPE => array(
 373+ 'versionlist',
 374+ 'wikilist',
 375+ 'settings',
 376+ 'extensions',
 377+ 'ajax',
 378+ ),
 379+ ApiBase::PARAM_DFLT => 'versionlist|wikilist',
337380 ),
338 - ApiBase::PARAM_DFLT => 'versionlist|wikilist',
339 - ),
340 - 'version' => null,
341 - 'wiki' => null,
342 - 'group' => false,
343 - );
 381+ 'version' => null,
 382+ 'wiki' => null,
 383+ 'group' => false,
 384+ 'ajaxgroup' => null,
 385+ 'ajaxsetting' => null,
 386+ );
 387+ } else {
 388+ return array(
 389+ 'prop' => array(
 390+ ApiBase::PARAM_ISMULTI => true,
 391+ ApiBase::PARAM_TYPE => array(
 392+ 'ajax',
 393+ ),
 394+ ),
 395+ 'ajaxgroup' => null,
 396+ 'ajaxsetting' => null,
 397+ );
 398+ }
344399 }
345400
346401 protected function getParamDescription() {
347 - return array(
348 - 'prop' => array(
349 - 'Which information to get:',
350 - '- versionlist: Get the list of old configurations',
351 - '- wikilist: Get the list the wikis to configuration',
352 - '- settings: Get settings of a specific version',
353 - '- extensions: List of installed extensions',
354 - ),
355 - 'version' => 'Version to get settings from',
356 - 'wiki' => 'Wiki to get settings from (default: current wiki)',
357 - 'group' => 'Whether to group settings',
358 - );
 402+ global $wgConfigureAPI;
 403+
 404+ if ( $wgConfigureAPI ) {
 405+ return array(
 406+ 'prop' => array(
 407+ 'Which information to get:',
 408+ '- versionlist: Get the list of old configurations',
 409+ '- wikilist: Get the list the wikis to configuration',
 410+ '- settings: Get settings of a specific version',
 411+ '- extensions: List of installed extensions',
 412+ '- ajax: Get part of the html form on Special:Configure (for internal use)',
 413+ ),
 414+ 'version' => 'Version to get settings from',
 415+ 'wiki' => 'Wiki to get settings from (default: current wiki)',
 416+ 'group' => 'Whether to group settings',
 417+ 'ajaxgroup' => 'for prop=ajax, new group name',
 418+ 'ajaxsetting' =>'for prop=ajax, setting name',
 419+ );
 420+ } else {
 421+ return array(
 422+ 'prop' => array(
 423+ 'Which information to get:',
 424+ '- ajax: Get part of the html form on Special:Configure (for internal use)',
 425+ ),
 426+ 'ajaxgroup' => 'for prop=ajax, new group name',
 427+ 'ajaxsetting' =>'for prop=ajax, setting name',
 428+ );
 429+ }
359430 }
360431
361432 public function getPossibleErrors() {
Index: trunk/extensions/Configure/CHANGELOG
@@ -1,6 +1,11 @@
22 This file lists changes on this extension. Localisation updates are done
33 through translatewiki.net and are not listed here.
44
 5+0.16.0 - 22 February 2010
 6+ Rewrote the extension to use the ressource loader and jQuery.
 7+ THIS VERSION NOW REQUIRES MediaWiki 1.17 TO WORK.
 8+
 9+
510 0.15.38 - 2 December 2010
611 Updated CentralNotice, CodeReview, Collection, FlaggedRevs, GroupsSidebar and
712 SemanticForms extensions.
Index: trunk/extensions/Configure/Configure.js
@@ -4,307 +4,469 @@
55 * flexibility
66 */
77
8 - var allSettings = undefined;
 8+// Tabs and TOC
 9+// ------------
910
10 -function setupConfigure(){
 11+$( '#configure' )
 12+ .addClass( 'jsprefs' )
 13+ .wrap( '<table><tbody><tr><td class="config-col-form"></td></tr></tbody></table>' )
 14+ .parent()
 15+ .before( '<td class="config-col-toc"><ul class="configtoc" id="configtoc"></ul></td>' );
1116
12 - // For old versions
13 - if( typeof getElementsByClassName != "function" )
14 - return;
 17+$( '#configure' )
 18+ .children( 'fieldset' )
 19+ .addClass( 'configsection' )
 20+ .hide()
 21+ .children( 'legend' )
 22+ .each( function( i ) {
 23+ $( this ).parent().attr( 'id', 'config-section-' + i );
 24+ if ( i === 0 ) {
 25+ $( this ).parent().show();
 26+ }
1527
16 - // Tabs and TOC
17 - // ------------
 28+ var item = $( '<li></li>' )
 29+ .addClass( i === 0 ? 'selected' : null )
 30+ .append(
 31+ $( '<a></a>' )
 32+ .text( $( this ).text() )
 33+ .attr( 'href', '#config-section-' + i )
 34+ .mousedown( function( e ) {
 35+ $( this ).parent().parent().find( 'li' ).removeClass( 'selected' );
 36+ $( this ).parent().addClass( 'selected' );
 37+ e.preventDefault();
 38+ return false;
 39+ } )
 40+ .click( function( e ) {
 41+ $( '#configure > fieldset' ).hide();
 42+ $( '#config-section-' + i ).show();
 43+ $( '#config-section-' + i + ' h2' ).show();
 44+ $( '#config-section-' + i + ' .configure-table' ).show();
 45+ e.preventDefault();
 46+ return false;
 47+ } )
 48+ );
1849
19 - var configform = document.getElementById( 'configure' );
20 - if (!configform || !document.createElement) {
21 - return;
22 - }
 50+ $( this ).parent().find( 'table.configure-table' ).each( function( j ) {
 51+ $( this ).attr( 'id', 'config-table-' + i + '-' + j );
 52+ } );
2353
24 - configform.className = configform.className + 'jsprefs';
25 - var sections = [];
26 - var children = configform.childNodes;
27 - var hid = 0;
28 - var toc = document.createElement( 'ul' );
29 - toc.className = 'configtoc';
30 - toc.id = 'configtoc';
31 - toc.subLen = {};
32 - toc.confSub = -1;
33 - for( var i = 0; i < children.length; i++ ){
34 - if ( children[i].nodeName.toLowerCase() == 'fieldset' ) {
35 - children[i].id = 'config-section-' + i;
36 - children[i].className = 'configsection';
37 - var legends = children[i].getElementsByTagName( 'legend' );
38 - if ( legends[0] && legends[0].firstChild.nodeValue ) {
39 - var legend = legends[0].firstChild.nodeValue;
40 - } else {
41 - var legend = '# ' + seci;
42 - }
 54+ var heads = $( this ).parent().find( 'h2' )
 55+ if ( heads.length > 1 ) {
 56+ var sub = $( '<ul></ul>' ).hide();
4357
44 - var li = document.createElement( 'li' );
45 - if ( i == 0 ) {
46 - li.className = 'selected';
47 - }
 58+ heads.each( function( j ) {
 59+ $( this ).attr( 'id', 'config-head-' + i + '-' + j );
 60+ sub.append(
 61+ $( '<li></li>' )
 62+ .addClass( i === 0 ? 'selected' : null )
 63+ .append(
 64+ $( '<a></a>' )
 65+ .text( $( this ).text() )
 66+ .attr( 'href', '#config-table-' + i + '-' + j )
 67+ .mousedown( function( e ) {
 68+ $( this ).parent().parent().find( 'li' ).removeClass( 'selected' );
 69+ $( this ).parent().addClass( 'selected' );
 70+ $( this ).parent().parent().parent().parent().find( 'li' ).removeClass( 'selected' );
 71+ $( this ).parent().parent().parent().addClass( 'selected' );
 72+ e.preventDefault();
 73+ return false;
 74+ } )
 75+ .click( function( e ) {
 76+ $( '#configure > fieldset' ).hide();
 77+ $( '#config-section-' + i ).show();
 78+ $( '#config-section-' + i + ' h2' ).hide();
 79+ $( '#config-section-' + i + ' .configure-table' ).hide();
 80+ $( '#config-head-' + i + '-' + j ).show();
 81+ $( '#config-table-' + i + '-' + j ).show();
 82+ e.preventDefault();
 83+ return false;
 84+ } )
 85+ ) );
 86+ } );
4887
49 - var headers = children[i].getElementsByTagName( 'h2' );
50 - var tables = getElementsByClassName( children[i], 'table', 'configure-table' );
 88+ item.append( sub );
 89+ item.prepend( $( '<a></a>' )
 90+ .text( '[+]' )
 91+ .attr( 'href', 'javascript:' )
 92+ .mousedown( function( e ) {
 93+ e.preventDefault();
 94+ return false;
 95+ } )
 96+ .click( function( e ) {
 97+ if ( sub.css( 'display' ) == 'none' ) {
 98+ sub.show();
 99+ $(this).text( '[-]' );
 100+ } else {
 101+ sub.hide();
 102+ $(this).text( '[+]' );
 103+ }
 104+ } ) );
 105+ }
51106
52 - if (headers.length > 1 && headers.length == tables.length) {
53 - var a = document.createElement( 'a' );
54 - a.onmousedown = a.onclick = configTocToggleElement;
55 - a.tocId = i;
56 - a.collapsed = true;
57 - a.appendChild( document.createTextNode( '[+]' ) );
58 - li.appendChild( a );
59 - }
 107+ $( '#configtoc' ).append( item );
 108+ } );
60109
61 - var a = document.createElement('a');
62 - a.href = '#' + children[i].id;
63 - a.id = 'toc-link-'+children[i].id;
64 - a.onmousedown = a.onclick = configToggle;
65 - a.confSec = i;
66 - a.confSub = -1;
67 - if (hid != 1) {
68 - a.className = 'selected';
69 - }
70 - a.appendChild( document.createTextNode( legend ) );
71 - li.appendChild( a );
72 -
73 - if( headers.length == tables.length && headers.length > 1 ){
74 - var len = headers.length;
75 - toc.subLen[i] = len;
76 - var span = document.createElement( 'span' );
77 - span.className = 'config-toc-delimiter';
78 - li.appendChild( span );
79 - var ul = document.createElement( 'ul' );
80 - ul.style.display = "none";
81 - ul.id = "config-toc-" + i;
82 -
83 - for( var subsect = 0; subsect < len; subsect++ ){
84 - headers[subsect].id = 'config-head-' + i + '-' + subsect;
85 - tables[subsect].id = 'config-table-' + i + '-' + subsect;
86 - var a = document.createElement( 'a' );
87 - a.href = '#' + headers[subsect].id;
88 - a.onmousedown = a.onclick = configToggle;
89 - a.confSec = i;
90 - a.confSub = subsect;
91 - a.appendChild( document.createTextNode( headers[subsect].firstChild.nodeValue ) );
92 - var li2 = document.createElement('li');
93 - li2.appendChild( a );
94 - ul.appendChild( li2 );
95 - }
96 - li.appendChild( ul );
 110+$( '.config-col-toc' ).append(
 111+ $( '<a></a>' )
 112+ .css( 'align', 'right' )
 113+ .attr( 'href', 'javascript:;' )
 114+ .append( $( '<img />' )
 115+ .attr( 'src', stylepath + '/common/images/Arr_l.png' )
 116+ )
 117+ .mousedown( function( e ) {
 118+ e.preventDefault();
 119+ return false;
 120+ } )
 121+ .click( function( e ) {
 122+ if ( $( '#configtoc' ).css( 'display' ) == 'none' ) {
 123+ $( '#configtoc' ).show();
 124+ $( this ).children( 'img' ).remove();
 125+ $( this ).append( $( '<img />' )
 126+ .attr( 'src', stylepath + '/common/images/Arr_l.png' )
 127+ );
97128 } else {
98 - toc.subLen[i] = 0;
 129+ $( '#configtoc' ).hide();
 130+ $( this ).children( 'img' ).remove();
 131+ $( this ).append( $( '<img />' )
 132+ .attr( 'src', stylepath + '/common/images/Arr_r.png' )
 133+ );
99134 }
100 - toc.appendChild( li );
101 - if( hid == 1 ){
102 - children[i].style.display = 'none';
103 - } else {
104 - // IE wants 1, but FF and others want 0
105 - toc.confSec = i;
106 - }
107 - hid = 1;
 135+ e.preventDefault();
 136+ return false;
108137 }
109 - }
 138+ )
 139+);
110140
111 - var toggleToc = document.createElement( 'a' );
112 - toggleToc.style.align = "right";
113 - toggleToc.onmousedown = toggleToc.onclick = configTocToggle;
114 - toggleToc.appendChild( getArrowImg( 'l' ) );
 141+// Associative tables
 142+// ------------------
115143
116 - var table = document.createElement( 'table' );
117 - var tbody = document.createElement( 'tbody' );
118 - var tr = document.createElement( 'tr' );
119 - var tdToc = document.createElement( 'td' );
120 - var tdForm = document.createElement( 'td' );
121 - tdToc.appendChild( toggleToc );
122 - tdToc.appendChild( toc );
123 - tdToc.className = 'config-col-toc';
124 - tdForm.appendChild( configform );
125 - tdForm.className = 'config-col-form';
126 - tr.appendChild( tdToc );
127 - tr.appendChild( tdForm );
128 - tbody.appendChild( tr );
129 - table.appendChild( tbody );
130 - document.getElementById( 'configure-form' ).appendChild( table );
131 -
132 - // Associative tables
133 - // ------------------
134 -
135 - var tables = getElementsByClassName( configform, 'table', 'assoc' );
136 - var reg = new RegExp( '(^| )disabled($| )' );
137 - for( var t = 0; t < tables.length ; t++ ){
138 - table = tables[t];
139 - if( reg.test( table.className ) )
140 - continue;
141 - // Button "remove this row"
142 - var trs = table.getElementsByTagName( 'tr' );
143 - for( var r = 0; r < trs.length; r++ ){
144 - tr = trs[r];
145 - if( r == 0 ){ // header
146 - var th = document.createElement( 'th' );
147 - th.appendChild( document.createTextNode( wgConfigureRemove ) );
148 - tr.appendChild( th );
149 - } else {
150 - var td = document.createElement( 'td' );
151 - td.className = 'button';
152 - var button = document.createElement( 'input' );
153 - button.type = 'button';
154 - button.value = wgConfigureRemoveRow;
155 - button.onclick = removeAssocCallback( table, r );
156 - td.appendChild( button );
157 - tr.appendChild( td );
158 - }
 144+/**
 145+ * Fix an associative table
 146+ */
 147+window.fixAssocTable = function( table ){
 148+ var startName = 'wp' + table.attr( 'id' );
 149+ table.chidren( 'tr' ).each( function( i ) {
 150+ if ( i == 0 ) {
 151+ continue;
159152 }
160 - // Button "add a new row"
161 - var button = document.createElement( 'input' );
162 - button.type = 'button';
163 - button.className = 'button-add';
164 - button.value = wgConfigureAdd;
165 - button.onclick = createAssocCallback( table );
166 - table.parentNode.appendChild( button );
167 - }
 153+ var inputs = $( this ).chidren( 'input' );
 154+ inputs[0].attr( 'name', startName + '-key-' + (i - 1) );
 155+ inputs[1].attr( 'name', startName + '-val-' + (i - 1) );
 156+ } );
 157+}
168158
169 - var thumbs = getElementsByClassName( configform, 'input', 'image-selector' );
170 - for( var t = 0; t < thumbs.length; t++ ){
171 - var textbox = thumbs[t];
172 - var conf = textbox.id.substr( 18 );
173 - var img = document.getElementById( 'image-url-preview-'+conf );
 159+$( '#configure table.assoc' ).each( function() {
 160+ var table = $( this );
174161
175 - addHandler( textbox, 'blur', createImageUrlCallback( textbox, img ) );
 162+ if ( table.hasClass( 'disabled' ) ) {
 163+ return;
176164 }
 165+ table.children( 'tr' ).each( function( i ) {
 166+ if ( i == 0 ) {
 167+ $( this ).append( $( '<th></th>' ).text( mediaWiki.msg( 'configure-js-remove-row' ) ) );
 168+ } else {
 169+ $( this ).append(
 170+ $( '<td></td>' )
 171+ .addClass( 'button' )
 172+ .append(
 173+ $( '<input></input>' )
 174+ .attr( 'type', 'button' )
 175+ .attr( 'value', mediaWiki.msg( 'configure-js-remove-row' ) )
 176+ .click( function() {
 177+ $( this ).parent().parent().remove();
 178+ fixAssocTable( table );
 179+ } )
 180+ )
 181+ );
 182+ }
 183+ } );
 184+ table.parent().append(
 185+ $( '<input></input>' )
 186+ .attr( 'type', 'button' )
 187+ .attr( 'value', mediaWiki.msg( 'configure-js-add' ) )
 188+ .addClass( 'button' )
 189+ .click( function() {
 190+ table.append(
 191+ $( '<tr></tr>' )
 192+ .append(
 193+ $( '<td></td>' )
 194+ .append(
 195+ $( '<input></input>' )
 196+ .attr( 'type', 'text' )
 197+ )
 198+ )
 199+ .append(
 200+ $( '<td></td>' )
 201+ .append(
 202+ $( '<input></input>' )
 203+ .attr( 'type', 'text' )
 204+ )
 205+ )
 206+ .append(
 207+ $( '<td></td>' )
 208+ .append(
 209+ $( '<input></input>' )
 210+ .attr( 'type', 'button' )
 211+ .attr( 'value', mediaWiki.msg( 'configure-js-remove-row' ) )
 212+ .click( function() {
 213+ $( this ).parent().parent().remove();
 214+ fixAssocTable( table );
 215+ } )
 216+ )
 217+ )
 218+ );
 219+ fixAssocTable( table );
 220+ } )
 221+ );
 222+} );
177223
178 - // $wgGroupPermissions and $wgAutopromote stuff, only if ajax is enabled
179 - // ---------------------------------------------------------------------
 224+// Images
 225+// ------
180226
181 - if( wgConfigureUseAjax ){
182 - var tables = getElementsByClassName( configform, 'table', 'ajax-group' );
183 - for( var t = 0; t < tables.length ; t++ ){
184 - table = tables[t];
185 - // Button "remove this row"
186 - var trs = getElementsByClassName( table, 'tr', 'configure-maintable-row' );
187 - for( var r = 0; r < trs.length; r++ ){
188 - tr = trs[r];
189 - if( r == 0 ){ // header
190 - var th = document.createElement( 'th' );
191 - th.appendChild( document.createTextNode( wgConfigureRemove ) );
192 - tr.appendChild( th );
193 - } else {
194 - var td = document.createElement( 'td' );
195 - td.className = 'button';
196 - var button = document.createElement( 'input' );
197 - button.type = 'button';
198 - button.value = wgConfigureRemoveRow;
199 - button.onclick = removeAjaxGroupCallback( table, r );
200 - td.appendChild( button );
201 - tr.appendChild( td );
 227+$( '.image-selector' ).blur( function() {
 228+ var data = {
 229+ 'action': 'query',
 230+ 'titles': $( this ).attr( 'value' ),
 231+ 'prop': 'imageinfo',
 232+ 'iiprop': 'url',
 233+ 'format': 'json'
 234+ };
 235+ var input = $( this );
 236+ $.getJSON(
 237+ mw.config.get( 'wgScriptPath' ) + '/api' + mw.config.get( 'wgScriptExtension' ),
 238+ data,
 239+ function( obj ) {
 240+ var found = false;
 241+ for ( var i in obj.query.pages ) {
 242+ if( obj.query.pages[i].imageinfo && obj.query.pages[i].imageinfo[0].url ) {
 243+ $( '#image-url-preview-' + input.attr( 'id' ).substr( 18 ) ).attr( 'src', obj.query.pages[i].imageinfo[0].url );
 244+ found = true;
202245 }
203246 }
204 - // Button "add a new row"
205 - var button = document.createElement( 'input' );
206 - button.type = 'button';
207 - button.className = 'button-add';
208 - button.value = wgConfigureAdd;
209 - button.onclick = createAjaxGroupCallback( table );
210 - table.parentNode.appendChild( button );
211 - }
212 -
213 - document.getElementById( 'configure-form' ).onsubmit = function(){
214 - var tables = getElementsByClassName( configform, 'table', 'ajax-group' );
215 - for( var t = 0; t < tables.length ; t++ ){
216 - var table = tables[t];
217 - var id = table.id;
218 - var cont = '';
219 - var trs = getElementsByClassName( table, 'tr', 'configure-maintable-row' );
220 - for( var r = 1; r < trs.length; r++ ){
221 - var tr = trs[r];
222 - if( cont != '' ) cont += "\n";
223 - cont += tr.id;
224 - }
225 - var input = document.createElement( 'input' );
226 - input.type = 'hidden';
227 - input.name = 'wp' + id + '-vals';
228 - input.value = cont;
229 - table.parentNode.appendChild( input );
 247+ if ( !found ) {
 248+ $( '#image-url-preview-' + input.attr( 'id' ).substr( 18 ) ).attr( 'src', input.attr( 'value' ) );
230249 }
231250 }
232 - }
 251+ );
 252+} );
233253
234 - /** Collapsible big lists */
235 - var biglists = getElementsByClassName( configform, '*', 'configure-biglist' );
 254+// $wgGroupPermissions and $wgAutopromote stuff, only if ajax is enabled
 255+// ---------------------------------------------------------------------
236256
237 - for( var l = 0; l < biglists.length; l++ ) {
238 - var list = biglists[l];
 257+$( '.ajax-group' ).each( function() {
 258+ var table = $( this );
 259+ // Button "remove this row"
 260+ table.children( 'tr' ).each( function( i ) {
 261+ if ( i == 0 ) {
 262+ $( this ).append( $( '<th></th>' ).text( mediaWiki.msg( 'configure-js-remove' ) ) );
 263+ } else {
 264+ $( this ).append(
 265+ $( '<td></td>' )
 266+ .addClass( 'button' )
 267+ .append(
 268+ $( '<input></input>' )
 269+ .attr( 'type', 'button' )
 270+ .attr( 'value', mediaWiki.msg( 'configure-js-remove-row' ) )
 271+ .click( function() {
 272+ $( this ).parent().parent().remove();
 273+ } )
 274+ )
 275+ );
 276+ }
 277+ } );
 278+ // Button "add a new row"
 279+ table.parent().append(
 280+ $( '<input></input>' )
 281+ .addClass( 'button-add' )
 282+ .attr( 'type', 'button' )
 283+ .attr( 'value', mediaWiki.msg( 'configure-js-add' ) )
 284+ .click( function() {
 285+ var groupname = prompt( mediaWiki.msg( 'configure-js-prompt-group' ) );
 286+ if( groupname == null )
 287+ return;
239288
240 - list.id = 'configure-biglist-content-'+l;
241 - list.style.display = 'none';
 289+ var data = {
 290+ 'action': 'configure',
 291+ 'prop': 'ajax',
 292+ 'format': 'json',
 293+ 'ajaxgroup': groupname,
 294+ 'ajaxsetting': table.attr( 'id' )
 295+ };
242296
243 - var tn = document.createTextNode( wgConfigureBiglistHidden );
244 - var div = document.createElement( 'div' );
245 - var toggleLink = document.createElement( 'a' );
 297+ $.getJSON(
 298+ mw.config.get( 'wgScriptPath' ) + '/api' + mw.config.get( 'wgScriptExtension' ),
 299+ data,
 300+ function( obj ) {
 301+ if ( obj.configure.ajax ) {
 302+ var resp = obj.configure.ajax;
 303+ error = false;
 304+ table.append(
 305+ $( '<tr></tr>' )
 306+ .addClass( 'configure-maintable-row' )
 307+ .attr( 'id', 'wp' + table.attr( 'id' ) + groupname )
 308+ .append( $( '<td></td>' ).text( groupname ) )
 309+ .append( $( '<td></td>' ).html( resp ) )
 310+ .append(
 311+ $( '<td></td>' )
 312+ .append(
 313+ $( '<input></input>' )
 314+ .attr( 'type', 'button' )
 315+ .attr( 'value', mediaWiki.msg( 'configure-js-remove-row' ) )
 316+ .click( function() {
 317+ $( this ).parent().parent().remove();
 318+ } )
 319+ )
 320+ )
 321+ );
 322+ } else {
 323+ alert( mediaWiki.msg( 'configure-js-group-exists' ) );
 324+ }
 325+ }
 326+ );
 327+ } )
 328+ );
 329+} );
246330
247 - toggleLink.appendChild( document.createTextNode( wgConfigureBiglistShow ) );
248 - toggleLink.className = 'configure-biglist-toggle-link';
249 - toggleLink.onclick = createToggleCallback( l );
250 - toggleLink.id = 'configure-biglist-link-'+l;
251 - toggleLink.href = 'javascript:';
 331+$( '#configure-form' ).submit( function(){
 332+ $( '.ajax-group' ).each( function() {
 333+ var table = $( this );
 334+ var cont = '';
 335+ table.children( 'tr.configure-maintable-row' ).each( function() {
 336+ if( cont != '' ) cont += "\n";
 337+ cont += $( this ).attr( 'id' );
 338+ } );
 339+ table.parent().append(
 340+ $( '<input></input>' )
 341+ .attr( 'type', 'hidden' )
 342+ .attr( 'name', 'wp' + table.attr( 'id' ) + '-vals' )
 343+ .attr( 'value', cont )
 344+ );
 345+ } );
 346+} );
252347
253 - div.id = 'configure-biglist-placeholder-'+l;
254 - div.className = 'configure-biglist-placeholder';
255 - div.appendChild( tn );
256 - div.insertBefore( toggleLink, div.childNodes[0] );
257 - list.parentNode.insertBefore( div, list );
 348+// Big lists
 349+// ---------
258350
259 - // Summaries
260 - var summary = document.createElement( 'div' );
261 - summary.id = 'configure-biglist-summary-'+l;
262 - summary.className = 'configure-biglist-summary';
263 - summariseSetting( list, summary );
264 - list.parentNode.insertBefore( summary, list );
265 - }
 351+// Summarise the setting contained in 'div' to the summary field 'summary'.
 352+window.summariseSetting = function( div ) {
266353
267 - /** Search box initialise */
268 - buildSearchIndex();
 354+ if ( div.hasClass( 'assoc' ) ) {
 355+ // If it's too big to display as an associative array, it's too big to display as a summary.
 356+ return '';
 357+ } else if ( div.hasClass( 'ns-bool' ) || div.hasClass( 'ns-simple' ) || div.hasClass( 'group-bool-element' ) || div.hasClass( 'group-array-element' ) ) {
 358+ var matches = [];
 359+ div.find( 'label' ).each( function() {
 360+ if ( $( '#' + $( this ).attr( 'for' ) ).attr( 'checked' ) ) {
 361+ matches.push( $( this ).text() );
 362+ }
 363+ } );
 364+ return matches.join( ', ' );
 365+ } else if ( div.hasClass( 'ns-array' ) || div.hasClass( 'ns-text' ) || div.hasClass( 'configure-rate-limits-action' ) ) {
 366+ // Basic strategy: find all labels, and list the values of their corresponding inputs, if those inputs have a value
269367
270 - // Insert a little search form just before the configuration form
271 - document.getElementById( 'configure-search-form' ).style.display = 'block';
272 - addHandler( document.getElementById( 'configure-search-input' ), 'keyup', function() { doSearch( this.value ); } )
273 -}
 368+ var body = $( '<tbody></tbody>' )
 369+ .append( $( '<tr></tr>' )
 370+ .append( $( '<th></th>' ).text( div.find( 'th:first' ).text() ) )
 371+ .append( $( '<th></th>' ).text( div.find( 'th:last' ).text() ) )
 372+ );
274373
275 -function doSearch( query ) {
276 - query = document.getElementById( 'configure-search-input' ).value.toLowerCase();
 374+ var rows = false;
277375
278 - var results = document.getElementById( 'configure-search-results' );
 376+ if ( div.hasClass( 'configure-rate-limits-action' ) ) {
 377+ div.find( 'tr' ).each( function( i ) {
 378+ if ( i == 0 ) {
 379+ return;
 380+ }
 381+ var typeDesc = $( this ).find( 'td:first' ).text();
 382+ var periodField = $( '#' + $( this ).attr( 'id' ) + '-period' );
 383+ var countField = $( '#' + $( this ).attr( 'id' ) + '-count' );
279384
280 - // Empty the existing results
281 - while( results.firstChild ) {
282 - results.removeChild(results.firstChild);
283 - }
 385+ if ( periodField.attr( 'value' ) > 0 ) {
 386+ rows = true;
284387
285 - if ( query == '' ) {
286 - return;
287 - }
 388+ body.append( $( '<tr></tr>' )
 389+ .append( $( '<td></td>' ).text( typeDesc ) )
 390+ .append( $( '<td></td>' ).text( mediaWiki.msg(
 391+ 'configure-throttle-summary', countField.attr( 'value' ), periodField.attr( 'value' ) ) ) )
 392+ );
 393+ }
 394+ } );
 395+ } else {
 396+ div.find( 'label' ).each( function( i ) {
 397+ if ( i == 0 ) {
 398+ return;
 399+ }
 400+ var arrayfield = $( '#' + $( this ).attr( 'for' ) );
 401+ if ( arrayfield.attr( 'value' ) > 0 ) {
 402+ rows = true;
288403
289 - var isMatch = function(element) { return element.description.indexOf( query ) !== -1; };
290 - for( var i=0; i<allSettings.length; ++i ) {
291 - var data = allSettings[i];
292 - if ( isMatch( data ) ) {
293 - var a = document.createElement( 'a' );
294 - var li = document.createElement( 'li' );
 404+ body.append( $( '<tr></tr>' )
 405+ .append( $( '<td></td>' ).text( $( this ).text() ) )
 406+ .append( $( '<td></td>' ).text( arrayfield.attr( 'value' ) ) )
 407+ );
 408+ }
 409+ } );
 410+ }
295411
296 - a.href = '#config-head-'+data.fid+'-'+data.sid;
297 - a.onclick = configToggle;
298 - a.confSec = data.fid;
299 - a.confSub = data.sid;
300 - a.appendChild( document.createTextNode( data.displayDescription ) );
301 - li.appendChild( a );
302 -
303 - results.appendChild( li );
 412+ if ( !rows ) {
 413+ body.append( $( '<tr></tr>' )
 414+ .append( $( '<th></th>' )
 415+ .attr( 'colspan', 2 )
 416+ .text( mediaWiki.msg( 'configure-js-summary-none' ) )
 417+ )
 418+ );
304419 }
 420+
 421+ return $( '<table></table>' ).addClass( 'assoc' ).append( body ).html();
 422+ } else if ( div.hasClass( 'promotion-conds-element' ) || div.hasClass( 'configure-rate-limits-action' ) ) {
 423+ return '';
 424+ } else {
 425+ return 'Useless type';
305426 }
306427 }
307428
308 -function buildSearchIndex() {
 429+$( '.configure-biglist' ).each( function( l ) {
 430+ var list = $( this );
 431+ var summary = $( '<div></div>' )
 432+ .addClass( 'configure-biglist-summary' )
 433+ .html( summariseSetting( list ) );
 434+ var header = $( '<span></span>' ).text( mediaWiki.msg( 'configure-js-biglist-hidden' ) );
 435+ var toogle = $( '<a></a>' )
 436+ .addClass( 'configure-biglist-toggle-link' )
 437+ .attr( 'href', 'javascript:' )
 438+ .text( mediaWiki.msg( 'configure-js-biglist-show' ) )
 439+ .click( function() {
 440+ if ( list.css( 'display' ) == 'none' ) {
 441+ toogle.text( mediaWiki.msg( 'configure-js-biglist-hide' ) );
 442+ header.text( mediaWiki.msg( 'configure-js-biglist-shown' ) );
 443+ list.show();
 444+ summary.hide();
 445+ } else {
 446+ toogle.text( mediaWiki.msg( 'configure-js-biglist-show' ) );
 447+ header.text( mediaWiki.msg( 'configure-js-biglist-hidden' ) );
 448+ list.hide();
 449+ summary.html( summariseSetting( list ) ).show();
 450+ }
 451+ } );
 452+
 453+ list.hide();
 454+ list.before(
 455+ $( '<div></div>' )
 456+ .addClass( 'configure-biglist-placeholder' )
 457+ .append( toogle )
 458+ .append( header )
 459+ );
 460+ list.before(
 461+ summary
 462+ );
 463+} );
 464+
 465+// Search
 466+// ------
 467+
 468+window.allSettings = undefined;
 469+
 470+( function() {
309471 allSettings = [];
310472
311473 // For each section...
@@ -313,7 +475,7 @@
314476 for( var fid=0; fid<fieldsets.length; ++fid ) {
315477 // For each subsection...
316478 var fieldset = fieldsets[fid];
317 - var fieldset_title = getInnerText( fieldset.getElementsByTagName( 'legend' )[0] );
 479+ var fieldset_title = window.getInnerText( fieldset.getElementsByTagName( 'legend' )[0] );
318480 var subsections = getElementsByClassName( fieldset, 'table', 'configure-table' );
319481 for( var sid=0; sid<subsections.length; ++sid ) {
320482 var subsection;
@@ -344,480 +506,44 @@
345507 var description;
346508
347509 if ( desc_cell.getElementsByTagName( 'p' ).length ) { // Ward off comments like "This setting has been customised"
348 - description = getInnerText( desc_cell.getElementsByTagName( 'p' )[0] );
 510+ description = window.getInnerText( desc_cell.getElementsByTagName( 'p' )[0] );
349511 } else {
350 - description = getInnerText( desc_cell );
 512+ description = window.getInnerText( desc_cell );
351513 }
352514
353515 allSettings.push( { 'description': description.toLowerCase(), 'fid':fid+1, 'sid':sid, 'displayDescription': description } );
354516 }
355517 }
356518 }
357 -}
 519+} )();
358520
359 -// Summarise the setting contained in 'div' to the summary field 'summary'.
360 -function summariseSetting( div, summary ) {
361 - // Empty the existing summary
362 - while(summary.firstChild) {
363 - summary.removeChild(summary.firstChild);
364 - }
 521+$( '#configure-search-form' ).show();
 522+$( '#configure-search-input' ).keyup( function() {
 523+ var query = $( '#configure-search-input' ).attr( 'value' ).toLowerCase();
365524
366 - // Based on class, do something.
367 - var elementType = ' '+div.className+' ';
 525+ $( '#configure-search-results' ).children( 'li' ).remove();
368526
369 - var isType = function(type) { return elementType.indexOf( ' '+type+' ' ) !== -1; };
370 -
371 - if ( isType('assoc') ) {
372 - // If it's too big to display as an associative array, it's too big to display as a summary.
373 - } else if ( isType( 'ns-bool' ) || isType( 'ns-simple' ) || isType( 'group-bool-element' ) || isType( 'group-array-element' ) ) {
374 - var labels = div.getElementsByTagName( 'label' );
375 - var matches = [];
376 - for( var i=0; i<labels.length; ++i ) {
377 - var label = labels[i];
378 - var checkbox = document.getElementById( label.htmlFor );
379 - var idcandidates = label.getElementsByTagName( 'tt' );
380 - var displayid = label.innerHTML;
381 - if (idcandidates.length) {
382 - displayid = '<tt>'+idcandidates[0].innerHTML+'</tt>'; // Ew ew ew ew ew ew
383 - }
384 -
385 - if (checkbox.checked) {
386 - matches.push( displayid ); // Yuck
387 - }
388 - }
389 -
390 - summary.innerHTML = matches.join( ', ' ); // Be aware of velociraptors.
391 - } else if ( isType( 'ns-array' ) || isType( 'ns-text' ) || isType( 'configure-rate-limits-action' ) ) {
392 - // Basic strategy: find all labels, and list the values of their corresponding inputs, if those inputs have a value
393 - var header_key = undefined;
394 - var header_value = undefined;
395 -
396 - var headers = div.getElementsByTagName( 'th' );
397 - header_key = getInnerText( headers[0] );
398 - header_value = getInnerText( headers[1] );
399 -
400 - var table = document.createElement( 'table' );
401 - table.className = 'assoc';
402 - table.appendChild( document.createElement( 'tbody' ) );
403 - table = table.firstChild;
404 -
405 - var tr = document.createElement( 'tr' );
406 - var key_th = document.createElement( 'th' );
407 - var value_th = document.createElement( 'th' );
408 - key_th.appendChild( document.createTextNode( header_key ) );
409 - value_th.appendChild( document.createTextNode( header_value ) );
410 -
411 - tr.appendChild( key_th );
412 - tr.appendChild( value_th );
413 - table.appendChild( tr );
414 -
415 - var rows = false;
416 -
417 - if ( isType( 'configure-rate-limits-action' ) ) {
418 - var allRows = div.getElementsByTagName( 'tr' );
419 - for( var i=0; i<allRows.length; ++i ) {
420 - var row = allRows[i];
421 - var idparts = row.id.split( '-' );
422 - var action = idparts[2];
423 - var type = idparts[3];
424 - var typeDesc = getInnerText( row.getElementsByTagName( 'td' )[0] );
425 - var periodField = document.getElementById( row.id+'-period' );
426 - var countField = document.getElementById( row.id+'-count' );
427 -
428 - if ( periodField && periodField.value>0 ) {
429 - rows = true;
430 -
431 - tr = document.createElement( 'tr' );
432 - var key_td = document.createElement( 'td' );
433 - var value_td = document.createElement( 'td' );
434 -
435 - // Create a cute summary.
436 - var summ = wgConfigureThrottleSummary;
437 - summ = summ.replace( '$1', countField.value );
438 - summ = summ.replace( '$2', periodField.value );
439 - key_td.appendChild( document.createTextNode( typeDesc ) );
440 - value_td.appendChild( document.createTextNode( summ ) );
441 -
442 - tr.appendChild( key_td );
443 - tr.appendChild( value_td );
444 -
445 - table.appendChild( tr );
446 - }
447 - }
448 - } else {
449 - var labels = div.getElementsByTagName( 'label' );
450 - for( var i=0; i<labels.length; ++i ) {
451 - var label = labels[i];
452 - var arrayfield = document.getElementById( label.htmlFor );
453 -
454 - if ( arrayfield && arrayfield.value ) {
455 - rows = true;
456 -
457 - tr = document.createElement( 'tr' );
458 - var key_td = document.createElement( 'td' );
459 - var value_td = document.createElement( 'td' );
460 -
461 - key_td.appendChild( document.createTextNode( getInnerText( label ) ) );
462 - value_td.appendChild( document.createTextNode( arrayfield.value ) );
463 -
464 - tr.appendChild( key_td );
465 - tr.appendChild( value_td );
466 -
467 - table.appendChild( tr );
468 - }
469 - }
470 - }
471 -
472 - if ( !rows ) {
473 - tr = document.createElement( 'tr' );
474 - var td = document.createElement( 'td' );
475 - td.setAttribute( 'colspan', 2 );
476 - td.appendChild( document.createTextNode( wgConfigureSummaryNone ) );
477 - tr.appendChild( td );
478 - table.appendChild( tr );
479 - }
480 -
481 - summary.appendChild( table );
482 - } else if ( isType( 'promotion-conds-element' ) ) {
483 - } else if ( isType( 'configure-rate-limits-action' ) ) {
484 - } else {
485 - summary.appendChild( document.createTextNode( 'Useless type:'+elementType ) );
 527+ if ( query == '' ) {
 528+ return;
486529 }
487 -}
488530
489 -// Collapsible stuff
490 -function createToggleCallback( id ){
491 - return function(){
492 - var content = document.getElementById( 'configure-biglist-content-'+id );
493 - var toggleLink = document.getElementById( 'configure-biglist-link-'+id );
494 - var div = document.getElementById( 'configure-biglist-placeholder-'+id );
495 - var summary = document.getElementById( 'configure-biglist-summary-'+id );
496 - var act;
497 - var newLinkText;
498 - var newPlaceholderText;
499 -
500 - if ( toggleLink.firstChild.nodeValue == wgConfigureBiglistShow ) {
501 - act = 'show';
502 - newLinkText = wgConfigureBiglistHide;
503 - content.style.display = 'block';
504 - summary.style.display = 'none';
505 - newPlaceholderText = wgConfigureBiglistShown;
506 - } else {
507 - act = 'hide';
508 - newLinkText = wgConfigureBiglistShow;
509 - content.style.display = 'none';
510 - summary.style.display = 'block';
511 - summariseSetting( content, summary );
512 - newPlaceholderText = wgConfigureBiglistHidden
 531+ var isMatch = function( element ) { return element.description.indexOf( query ) !== -1; }
 532+ for( var i=0; i<allSettings.length; ++i ) {
 533+ var data = allSettings[i];
 534+ if ( isMatch( data ) ) {
 535+ $( '#configure-search-results' ).append(
 536+ $( '<li></li>' ).append(
 537+ $( '<a></a>' )
 538+ .attr( 'href', '#config-head-'+data.fid+'-'+data.sid )
 539+ .text( data.displayDescription )
 540+ .click( function() {
 541+ $( '#configure > fieldset' ).hide();
 542+ $( '#config-section-' + data.fid ).show();
 543+ $( '#config-section-' + data.fid + ' h2' ).show();
 544+ $( '#config-section-' + data.fid + ' .configure-table' ).show();
 545+ } )
 546+ )
 547+ );
513548 }
514 -
515 - toggleLink.removeChild( toggleLink.firstChild );
516 - toggleLink.appendChild( document.createTextNode( newLinkText ) );
517 -
518 - div.removeChild( div.childNodes[1] );
519 - div.appendChild( document.createTextNode( newPlaceholderText ) );
520549 }
521 -}
522 -
523 -// ------------------
524 -// Assoc tables stuff
525 -// ------------------
526 -
527 -/**
528 - * This is actually a damn hack to break the reference to table variable when
529 - * used directly
530 - *
531 - * @param Dom object representing a table
532 - */
533 -function createAssocCallback( table ){
534 - return function(){
535 - addAssocRow( table );
536 - }
537 -}
538 -
539 -/**
540 - * same as before
541 - *
542 - * @param Dom object representing a table
543 - */
544 -function removeAssocCallback( table, r ){
545 - return function(){
546 - removeAssocRow( table, r );
547 - }
548 -}
549 -
550 -/**
551 - * Add a new row in a associative table
552 - *
553 - * @param Dom object representing a table
554 - */
555 -function addAssocRow( table ){
556 - var r = table.getElementsByTagName( 'tr' ).length;
557 - var startName = 'wp' + table.id;
558 - var tr = document.createElement( 'tr' );
559 -
560 - var td1 = document.createElement( 'td' );
561 - var key = document.createElement( 'input' );
562 - key.type = 'text';
563 - key.name = startName + '-key-' + (r - 1);
564 - td1.appendChild( key );
565 -
566 - var td2 = document.createElement( 'td' );
567 - var val = document.createElement( 'input' );
568 - val.type = 'text';
569 - val.name = startName + '-val-' + (r - 1);
570 - td2.appendChild( val );
571 -
572 - var td3 = document.createElement( 'td' );
573 - td3.className = 'button';
574 - var button = document.createElement( 'input' );
575 - button.type = 'button';
576 - button.className = 'button-add';
577 - button.value = wgConfigureRemoveRow;
578 - button.onclick = removeAssocCallback( table, r );
579 - td3.appendChild( button );
580 -
581 - tr.appendChild( td1 );
582 - tr.appendChild( td2 );
583 - tr.appendChild( td3 );
584 - table.appendChild( tr );
585 -}
586 -
587 -/**
588 - * Remove a new row in a associative
589 - *
590 - * @param Dom object representing a table
591 - * @param integer
592 - */
593 -function removeAssocRow( table, r ){
594 - var trs = table.getElementsByTagName( 'tr' );
595 - var tr = trs[r];
596 - tr.parentNode.removeChild( tr );
597 - fixAssocTable( table );
598 -}
599 -
600 -/**
601 - * Fix an associative table
602 - *
603 - * @param Dom object representing a table
604 - */
605 -function fixAssocTable( table ){
606 - var startName = 'wp' + table.id;
607 - var trs = table.getElementsByTagName( 'tr' );
608 - for( var r = 1; r < trs.length; r++ ){
609 - var tr = trs[r];
610 - var inputs = tr.getElementsByTagName( 'input' );
611 - inputs[0].name = startName + '-key-' + (r - 1);
612 - inputs[1].name = startName + '-val-' + (r - 1);
613 - inputs[2].onclick = removeAssocCallback( table, r );
614 - }
615 -}
616 -
617 -// ----------------------
618 -// Ajax group table stuff
619 -// ----------------------
620 -
621 -/**
622 - * This is actually a damn hack to break the reference to table variable when
623 - * used directly
624 - *
625 - * @param Dom object representing a table
626 - */
627 -function createAjaxGroupCallback( table ){
628 - return function(){
629 - addAjaxGroupRow( table );
630 - }
631 -}
632 -
633 -/**
634 - * same as before
635 - *
636 - * @param Dom object representing a table
637 - */
638 -function removeAjaxGroupCallback( table, r ){
639 - return function(){
640 - removeAjaxGroupRow( table, r );
641 - }
642 -}
643 -
644 -/**
645 - * Add a new row in a "group-bool" table
646 - *
647 - * @param Dom object representing a table
648 - */
649 -function addAjaxGroupRow( table ){
650 - r = getElementsByClassName( table, 'tr', 'configure-maintable-row' ).length;
651 - startName = 'wp' + table.id;
652 - var groupname = prompt( wgConfigurePromptGroup );
653 - var tbody = table.getElementsByTagName( 'tbody' )[0];
654 - if( groupname == null )
655 - return;
656 -
657 - var tr = document.createElement( 'tr' );
658 - tr.className = 'configure-maintable-row';
659 - tr.id = startName + '-' + groupname;
660 -
661 - var td1 = document.createElement( 'td' );
662 - td1.appendChild( document.createTextNode( groupname ) );
663 -
664 - var td2 = document.createElement( 'td' );
665 - error = false;
666 - sajax_do_call( 'efConfigureAjax', [ table.id, groupname ], function( x ){
667 - var resp = x.responseText;
668 - if( resp == '<err#>' || x.status != 200 )
669 - error = true;
670 - td2.innerHTML = resp;
671 - } );
672 - if( error ){
673 - alert( wgConfigureGroupExists );
674 - return;
675 - }
676 -
677 - var td3 = document.createElement( 'td' );
678 - td3.className = 'button';
679 - var button = document.createElement( 'input' );
680 - button.type = 'button';
681 - button.className = 'button-add';
682 - button.value = wgConfigureRemoveRow;
683 - button.onclick = removeAjaxGroupCallback( table, r );
684 - td3.appendChild( button );
685 -
686 - tr.appendChild( td1 );
687 - tr.appendChild( td2 );
688 - tr.appendChild( td3 );
689 - tbody.appendChild( tr );
690 -}
691 -
692 -/**
693 - * Remove a new row in a "ajax-group" table
694 - *
695 - * @param Dom object representing a table
696 - * @param integer
697 - */
698 -function removeAjaxGroupRow( table, r ){
699 - var trs = getElementsByClassName( table, 'tr', 'configure-maintable-row' );
700 - var tr = trs[r];
701 - var tbody = table.getElementsByTagName( 'tbody' )[0];
702 - tbody.removeChild( tr );
703 -}
704 -
705 -/**
706 - * Fix an "group-bool" table
707 - *
708 - * @param Dom object representing a table
709 - */
710 -function fixAjaxGroupTable( table ){
711 - var startName = 'wp' + table.id;
712 - var trs = getElementsByClassName( table, 'tr', 'configure-maintable-row' );
713 - for( var r = 1; r < trs.length; r++ ){
714 - var tr = trs[r];
715 - var inputs = tr.getElementsByTagName( 'input' );
716 - inputs[inputs.length - 1].onclick = removeAjaxGroupCallback( table, r );
717 - }
718 -}
719 -
720 -// ---------
721 -// TOC stuff
722 -// ---------
723 -
724 -/**
725 - * Helper for TOC
726 - */
727 -function configToggle() {
728 - var confSec = this.confSec;
729 - var confSub = this.confSub;
730 - var toc = document.getElementById( 'configtoc' );
731 - var oldSec = toc.confSec;
732 - var oldId = 'config-section-' + oldSec;
733 - document.getElementById( oldId ).style.display = "none";
734 - document.getElementById( 'toc-link-'+oldId ).className = '';
735 - var newId = 'config-section-' + confSec;
736 - document.getElementById( newId ).style.display = "block";
737 - document.getElementById( 'toc-link-'+newId ).className = 'selected';
738 -
739 - for( var i = 0; i < toc.subLen[confSec]; i++ ){
740 - var headId = 'config-head-' + confSec + '-' + i;
741 - var tableId = 'config-table-' + confSec + '-' + i;
742 - var head = document.getElementById( headId );
743 - head.style.display = ( confSub == -1 || confSub == i ) ? "block" : "none";
744 - var table = document.getElementById( tableId );
745 - table.style.display = ( confSub == -1 || confSub == i ) ? "block" : "none";
746 - }
747 - toc.confSec = confSec;
748 - toc.confSub = confSub;
749 - return false;
750 -}
751 -
752 -/**
753 - * Toggle the TOC
754 - */
755 -function configTocToggleElement(){
756 - var id = this.tocId;
757 - var tocId = "config-toc-" + id;
758 - var toc = document.getElementById( tocId );
759 - if( this.collapsed ){
760 - toc.style.display = "block";
761 - this.removeChild( this.firstChild );
762 - this.appendChild( document.createTextNode( '[−]' ) );
763 - this.collapsed = false;
764 - } else {
765 - toc.style.display = "none";
766 - this.removeChild( this.firstChild );
767 - this.appendChild( document.createTextNode( '[+]' ) );
768 - this.collapsed = true;
769 - }
770 -}
771 -
772 -/**
773 - * Toggle the entire TOC
774 - */
775 -function configTocToggle(){
776 - var toc = document.getElementById( 'configtoc' );
777 - if( toc.style.display == "none" ){
778 - toc.parentNode.className = 'config-col-toc';
779 - toc.style.display = "block";
780 - this.removeChild( this.firstChild );
781 - this.appendChild( getArrowImg( 'l' ) );
782 - } else {
783 - toc.parentNode.className = 'config-col-toc-hidden';
784 - toc.style.display = "none";
785 - this.removeChild( this.firstChild );
786 - this.appendChild( getArrowImg( 'r' ) );
787 - }
788 -}
789 -
790 -/**
791 - * Handle [Get thumbnail URL] button clicks
792 - */
793 -function createImageUrlCallback( textbox, img ) {
794 - return function() {
795 - sajax_do_call( 'wfAjaxGetFileUrl',
796 - [textbox.value],
797 - function(response) {
798 - var text = response.responseText;
799 - // basic error handling
800 - if( text.substr( 0, 9 ) == "<!DOCTYPE" ) {
801 - img.src = textbox.value;
802 - } else {
803 - img.src = response.responseText;
804 - }
805 - }
806 - );
807 - }
808 -}
809 -
810 -/**
811 - * Get an image object representing an arrow
812 - * @param dir String: arrow direction, one of the following strings:
813 - * - u: up
814 - * - d: down
815 - * - l: left
816 - * - r: right
817 - */
818 -function getArrowImg( dir ){
819 - var img = document.createElement( 'img' );
820 - img.src = stylepath + "/common/images/Arr_" + dir + ".png";
821 - return img;
822 -}
823 -
824 -hookEvent( "load", setupConfigure );
 550+} );
Index: trunk/extensions/Configure/settings/Settings-core.php
@@ -1217,38 +1217,4 @@
12181218 /**
12191219 * Array of settings depending of the Core version
12201220 */
1221 -$settingsVersion = array(
1222 - # Removed in 1.17
1223 - 'wgSQLiteDataDirMode' => array( array( '1.17alpha', '<' ) ),
1224 - 'wgCategoryPrefixedDefaultSortkey' => array( array( '1.17alpha', '<' ) ),
1225 - 'wgServerName' => array( array( '1.17alpha', '<' ) ),
1226 - 'wgExternalAuthConfig' => array( array( '1.17alpha', '<' ) ),
1227 -
1228 - # Added in 1.17
1229 - 'wgAllowUserCssPrefs' => array( array( '1.17alpha', '>=' ) ),
1230 - 'wgGalleryOptions' => array( array( '1.17alpha', '>=' ) ),
1231 - 'wgAllowImageTag' => array( array( '1.17alpha', '>=' ) ),
1232 - 'wgLogAutocreatedAccounts' => array( array( '1.17alpha', '>=' ) ),
1233 - 'wgLocalStylePath' => array( array( '1.17alpha', '>=' ) ),
1234 - 'wgVectorShowVariantName' => array( array( '1.17alpha', '>=' ) ),
1235 - 'wgSQLMode' => array( array( '1.17alpha', '>=' ) ),
1236 - 'wgAdaptiveMessageCache' => array( array( '1.17alpha', '>=' ) ),
1237 - 'wgAdditionalMailParams' => array( array( '1.17alpha', '>=' ) ),
1238 - 'wgAllUnicodeFixes' => array( array( '1.17alpha', '>=' ) ),
1239 - 'wgAllowAsyncCopyUploads' => array( array( '1.17alpha', '>=' ) ),
1240 - 'wgBetterDirectionality' => array( array( '1.17alpha', '>=' ) ),
1241 - 'wgCanonicalLanguageLinks' => array( array( '1.17alpha', '>=' ) ),
1242 - 'wgCategoryCollation' => array( array( '1.17alpha', '>=' ) ),
1243 - 'wgExternalAuthConf' => array( array( '1.17alpha', '>=' ) ),
1244 - 'wgLicenseTerms' => array( array( '1.17alpha', '>=' ) ),
1245 - 'wgLoadScript' => array( array( '1.17alpha', '>=' ) ),
1246 - 'wgPasswordSenderName' => array( array( '1.17alpha', '>=' ) ),
1247 - 'wgResourceLoaderDebug' => array( array( '1.17alpha', '>=' ) ),
1248 - 'wgResourceLoaderInlinePrivateModules' => array( array( '1.17alpha', '>=' ) ),
1249 - 'wgResourceLoaderMaxage' => array( array( '1.17alpha', '>=' ) ),
1250 - 'wgResourceLoaderUseESI' => array( array( '1.17alpha', '>=' ) ),
1251 - 'wgSecureLogin' => array( array( '1.17alpha', '>=' ) ),
1252 - 'wgSecureLoginStickHTTPS' => array( array( '1.17alpha', '>=' ) ),
1253 - 'wgUpgradeKey' => array( array( '1.17alpha', '>=' ) ),
1254 - 'wgUploadMissingFileUrl' => array( array( '1.17alpha', '>=' ) ),
1255 -);
 1221+$settingsVersion = array();
Index: trunk/extensions/Configure/Configure.func.php
@@ -11,41 +11,6 @@
1212 */
1313
1414 /**
15 - * Ajax function to create row for a new group in $wgGroupPermissions or
16 - * $wgAutopromote
17 - *
18 - * @param $setting String: setting name
19 - * @param $group String: new group name
20 - * @return either <err#> on error or html fragment
21 - */
22 -function efConfigureAjax( $setting, $group ) {
23 - global $wgUser;
24 -
25 - $settings = ConfigurationSettings::singleton( CONF_SETTINGS_BOTH );
26 - if ( $settings->getSettingType( $setting ) != 'array' )
27 - return '<err#>';
28 -
29 - $type = $settings->getArrayType( $setting );
30 - switch( $type ) {
31 - case 'group-bool':
32 - if ( isset( $GLOBALS[$setting] ) && isset( $GLOBALS[$setting][$group] ) )
33 - return '<err#>';
34 -
35 - $row = ConfigurationPage::buildGroupSettingRow( $setting, $type, User::getAllRights(), true, $group, array() );
36 -
37 - // Firefox seems to not like that :(
38 - return str_replace( '&#160;', ' ', $row );
39 - case 'promotion-conds':
40 - if ( isset( $GLOBALS[$setting] ) && isset( $GLOBALS[$setting][$group] ) )
41 - return '<err#>';
42 -
43 - return ConfigurationPage::buildPromotionCondsSettingRow( $setting, true, $group, array() );
44 - default:
45 - return '<err#>';
46 - }
47 -}
48 -
49 -/**
5015 * Initalize the settings stored in a serialized file.
5116 * This have to be done before the end of LocalSettings.php but is in a function
5217 * because administrators might configure some settings between the moment where
@@ -95,16 +60,6 @@
9661 }
9762
9863 /**
99 - * Declare the API module only if $wgConfigureAPI is true
100 - */
101 -function efConfigureSetupAPI() {
102 - global $wgConfigureAPI, $wgAPIModules;
103 - if ( $wgConfigureAPI === true ) {
104 - $wgAPIModules['configure'] = 'ApiConfigure';
105 - }
106 -}
107 -
108 -/**
10964 * Add custom rights defined in $wgRestrictionLevels
11065 */
11166 function efConfigureGetAllRights( &$rights ) {
@@ -115,32 +70,6 @@
11671 }
11772
11873 /**
119 - * Add JS variable to the output, for use in Configure.js
120 - */
121 -function efConfigureMakeGlobalVariablesScript( &$vars ) {
122 - global $wgConfigureAddJsVariables, $wgUseAjax;
123 -
124 - if ( !$wgConfigureAddJsVariables )
125 - return true;
126 -
127 - $vars['wgConfigureAdd'] = wfMsg( 'configure-js-add' );
128 - $vars['wgConfigureRemove'] = wfMsg( 'configure-js-remove' );
129 - $vars['wgConfigureRemoveRow'] = wfMsg( 'configure-js-remove-row' );
130 - $vars['wgConfigurePromptGroup'] = wfMsg( 'configure-js-prompt-group' );
131 - $vars['wgConfigureGroupExists'] = wfMsg( 'configure-js-group-exists' );
132 - $vars['wgConfigureUseAjax'] = (bool)$wgUseAjax;
133 - $vars['wgConfigureGetImageUrl'] = wfMsg( 'configure-js-get-image-url' );
134 - $vars['wgConfigureImageError'] = wfMsg( 'configure-js-image-error' );
135 - $vars['wgConfigureBiglistShown'] = wfMsg( 'configure-js-biglist-shown' );
136 - $vars['wgConfigureBiglistHidden'] = wfMsg( 'configure-js-biglist-hidden' );
137 - $vars['wgConfigureBiglistShow'] = wfMsg( 'configure-js-biglist-show' );
138 - $vars['wgConfigureBiglistHide'] = wfMsg( 'configure-js-biglist-hide' );
139 - $vars['wgConfigureSummaryNone'] = wfMsg( 'configure-js-summary-none' );
140 - $vars['wgConfigureThrottleSummary'] = wfMsg( 'configure-throttle-summary' );
141 - return true;
142 -}
143 -
144 -/**
14574 * Display link to Special:Configure
14675 */
14776 function efConfigureFarmerAdminPermissions( $farmer ) {
@@ -157,7 +86,7 @@
15887 * Avoid displaying anything :)
15988 */
16089 function efConfigureFarmerAdminSkin( $farmer ) {
161 - return false;
 90+ return false;
16291 }
16392
16493 /**
Index: trunk/extensions/Configure/specials/ConfigurationPage.php
@@ -290,11 +290,11 @@
291291 $msg = wfMsgNoTrans( $ok ? 'configure-saved' : 'configure-error' );
292292 $class = $ok ? 'successbox' : 'errorbox';
293293
294 - $wgOut->addWikiText( "<div class=\"$class\"><strong>$msg</strong></div>" );
 294+ $wgOut->addWikiText( Html::rawElement( 'div', array( 'class' => $class ), "<strong>$msg</strong>" ) );
295295
296296 $sk = $wgUser->getSkin();
297297 $linkText = wfMsgExt( 'configure-backlink', 'parseinline' );
298 - $wgOut->addHTML( Xml::tags( 'p', array( 'style' => 'clear: both;' ), $sk->link( $this->getTitle(), $linkText ) ) );
 298+ $wgOut->addHTML( Html::rawElement( 'p', array( 'style' => 'clear:both;' ), $sk->link( $this->getTitle(), $linkText ) ) );
299299 }
300300
301301 /**
@@ -423,7 +423,7 @@
424424 ## Take out the first ten...
425425 $links = array_slice( $links, 0, 10 );
426426
427 - $text = '<fieldset><legend>' . wfMsgHtml( 'configure-old' ) . '</legend>';
 427+ $text = Html::element( 'legend', null, wfMsg( 'configure-old' ) );
428428 if ( !count( $links ) ) {
429429 $text .= wfMsgExt( 'configure-no-old', array( 'parse' ) );
430430 } else {
@@ -433,11 +433,10 @@
434434 $text .= "</li>\n</ul>\n";
435435 }
436436 $link = SpecialPage::getTitleFor( 'ViewConfig' );
437 - $text .= Xml::tags( 'p', null, $skin->link( $link, wfMsgHtml( 'configure-view-all-versions' ), array(), array(), array( 'known' ) ) );
438 - $text .= Xml::tags( 'p', null, $skin->link( $link, wfMsgHtml( 'configure-view-default' ), array(), array( 'version' => 'default' ), array( 'known' ) ) );
 437+ $text .= Html::rawElement( 'p', null, $skin->link( $link, wfMsgHtml( 'configure-view-all-versions' ), array(), array(), array( 'known' ) ) );
 438+ $text .= Html::rawElement( 'p', null, $skin->link( $link, wfMsgHtml( 'configure-view-default' ), array(), array( 'version' => 'default' ), array( 'known' ) ) );
439439
440 - $text .= '</fieldset>';
441 - return $text;
 440+ return Html::rawElement( 'fieldset', null, $text );
442441 }
443442
444443 /**
@@ -447,10 +446,10 @@
448447 global $wgConfigureWikis, $wgScript;
449448 if ( $wgConfigureWikis === false || !$this->isUserAllowedInterwiki() )
450449 return '';
451 - $form = '<fieldset><legend>' . wfMsgHtml( 'configure-select-wiki' ) . '</legend>';
 450+ $form = Html::element( 'legend', null, wfMsg( 'configure-select-wiki' ) );
452451 $form .= wfMsgExt( 'configure-select-wiki-desc', array( 'parse' ) );
453 - $form .= Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) );
454 - $form .= Xml::hidden( 'title', $this->getTitle()->getPrefixedDBkey() );
 452+ $form .= Html::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) );
 453+ $form .= Html::hidden( 'title', $this->getTitle()->getPrefixedDBkey() );
455454 if ( is_array( $wgConfigureWikis ) ) {
456455 $selector = new XmlSelect( 'wiki', 'wiki', $this->mWiki );
457456 foreach( $wgConfigureWikis as $wiki ) {
@@ -458,11 +457,11 @@
459458 }
460459 $form .= $selector->getHTML() . '&#160;';
461460 } else {
462 - $form .= Xml::input( 'wiki', false, $this->mWiki ) . '&#160;';
 461+ $form .= Html::input( 'wiki', $this->mWiki, 'text' ) . '&#160;';
463462 }
464 - $form .= Xml::submitButton( wfMsg( 'configure-select-wiki-submit' ) );
465 - $form .= '</form></fieldset>';
466 - return $form;
 463+ $form .= Html::input( null, wfMsg( 'configure-select-wiki-submit' ), 'submit' );
 464+ $form .= Html::closeElement( 'form' );
 465+ return Html::rawElement( 'fieldset', null, $form );
467466 }
468467
469468 /**
@@ -852,43 +851,40 @@
853852 $wgOut->addHTML(
854853 ( $this->mCanEdit ?
855854 $this->getWikiSelectForm() .
856 - Xml::openElement( 'form', array( 'method' => 'post', 'action' => $action,
 855+ Html::openElement( 'form', array( 'method' => 'post', 'action' => $action,
857856 'id' => 'configure-form' ) ) . "\n" :
858 - Xml::openElement( 'div', array( 'id' => 'configure-form' ) )
 857+ Html::openElement( 'div', array( 'id' => 'configure-form' ) )
859858 ) .
860859 $this->buildOldVersionSelect() . "\n" .
861860 $this->buildSearchForm() . "\n" .
862 - Xml::openElement( 'div', array( 'id' => 'configure' ) ) . "\n" .
 861+ Html::openElement( 'div', array( 'id' => 'configure' ) ) . "\n" .
863862 $this->buildAllSettings() . "\n" .
864863 ( $this->mCanEdit ?
865 - Xml::buildForm( array( 'configure-form-reason' => Xml::input( 'wpReason', 45, $reason ) ) ) . "\n" .
866 - Xml::openElement( 'div', array( 'id' => 'prefsubmit' ) ) . "\n" .
867 - Xml::openElement( 'div', array() ) . "\n" .
868 - Xml::hidden( 'wpEditToken', $wgUser->editToken() ) . "\n" .
869 - Xml::element( 'input', array( 'type' => 'submit', 'name' => 'wpSave',
870 - 'class' => 'btnSavePrefs', 'value' => wfMsgHtml( 'configure-btn-save' ) ) ) . "\n" .
871 - Xml::element( 'input', array( 'type' => 'submit', 'name' => 'wpPreview',
872 - 'value' => wfMsgHtml( 'showdiff' ) ) ) . "\n" .
873 - Xml::closeElement( 'div' ) . "\n" .
874 - Xml::closeElement( 'div' ) . "\n" .
875 - Xml::element( 'input', array( 'type' => 'hidden', 'name' => 'wpEditToken',
876 - 'value' => $wgUser->editToken() ) ) . "\n" .
877 - ( $this->mWiki ? Xml::element( 'input', array( 'type' => 'hidden', 'name' => 'wpWiki',
878 - 'value' => $this->mWiki ) ) . "\n" : '' )
 864+ wfMsgExt( 'configure-form-reason', 'parseinline' ) . ' ' . Html::input( 'wpReason', $reason, 'text', array( 'size' => 45 ) ) . "\n" .
 865+ Html::openElement( 'div', array( 'id' => 'prefsubmit' ) ) . "\n" .
 866+ Html::openElement( 'div', array() ) . "\n" .
 867+ Html::hidden( 'wpEditToken', $wgUser->editToken() ) . "\n" .
 868+ Html::input( 'wpSave', wfMsg( 'configure-btn-save' ), 'submit', array( 'class' => 'btnSavePrefs' ) ) . "\n" .
 869+ Html::input( 'wpPreview', wfMsg( 'showdiff' ), 'submit' ) . "\n" .
 870+ Html::closeElement( 'div' ) . "\n" .
 871+ Html::closeElement( 'div' ) . "\n" .
 872+ Html::hidden( 'wpEditToken', $wgUser->editToken() ) . "\n" .
 873+ ( $this->mWiki ? Html::hidden( 'wpWiki', $this->mWiki ) . "\n" : '' )
879874 : ''
880875 ) .
881 - Xml::closeElement( 'div' ) . "\n" .
882 - Xml::closeElement( $this->mCanEdit ? 'form' : 'div' )
 876+ Html::closeElement( 'div' ) . "\n" .
 877+ Html::closeElement( $this->mCanEdit ? 'form' : 'div' )
883878 );
884879 $this->injectScriptsAndStyles();
885880 }
886881
887882 /** Show a hidden-by-default search form */
888883 protected function buildSearchForm() {
889 - $form = wfMsgExt( 'configure-js-search-prompt', 'parseinline' ) . wfMsgExt( 'word-separator', array( 'escapenoentities' ) ) .
890 - Xml::element( 'input', array( 'id' => 'configure-search-input', 'size' => 45 ) );
891 - $form = Xml::tags( 'p', null, $form ) . "\n" . Xml::openElement( 'ul', array( 'id' => 'configure-search-results' ) ) . '</ul>';
892 - $form = Xml::fieldset( wfMsg( 'configure-js-search-legend' ), $form, array( 'style' => 'display: none;', 'id' => 'configure-search-form' ) );
 884+ $input = wfMsgExt( 'configure-js-search-prompt', 'parseinline' ) . wfMsgExt( 'word-separator', array( 'escapenoentities' ) ) .
 885+ Html::element( 'input', array( 'id' => 'configure-search-input', 'size' => 45 ) );
 886+ $form = Html::element( 'legend', null, wfMsg( 'configure-js-search-legend' ) ) . Html::rawElement( 'p', null, $input ) . "\n" .
 887+ Html::openElement( 'ul', array( 'id' => 'configure-search-results' ) ) . Html::closeElement( 'ul' );
 888+ $form = Html::rawElement( 'fieldset', array( 'style' => 'display: none;', 'id' => 'configure-search-form' ), $form );
893889 return $form;
894890 }
895891
@@ -896,12 +892,9 @@
897893 * Inject JavaScripts and Stylesheets in page output
898894 */
899895 protected function injectScriptsAndStyles() {
900 - global $wgOut, $wgExtensionAssetsPath, $wgConfigureStyleVersion, $wgConfigureAddJsVariables;
 896+ global $wgOut;
901897
902 - $wgConfigureAddJsVariables = true; // tell efConfigureMakeGlobalVariablesScript() to add JS variables
903 -
904 - $wgOut->addExtensionStyle( "{$wgExtensionAssetsPath}/Configure/Configure.css?{$wgConfigureStyleVersion}" );
905 - $wgOut->addScriptFile( "{$wgExtensionAssetsPath}/Configure/Configure.js?{$wgConfigureStyleVersion}" );
 898+ $wgOut->addModules( 'ext.configure' );
906899 }
907900
908901 /**
@@ -915,7 +908,7 @@
916909 $msgVal = wfMsgExt( $msgName, array( 'parseinline' ) );
917910 if ( wfEmptyMsg( $msgName, $msgVal ) )
918911 $msgVal = $msg;
919 - return "\n<h2>" . $msgVal . "</h2>\n<table class=\"configure-table\">\n";
 912+ return "\n<h2>" . $msgVal . "</h2>" . Html::openElement( 'table', array( 'class' => 'configure-table' ) ) . "\n";
920913 }
921914
922915 /**
@@ -928,28 +921,32 @@
929922 protected function buildInput( $conf, $params = array() ) {
930923 $read = isset( $params['read'] ) ? $params['read'] : $this->userCanRead( $conf );
931924 if ( !$read )
932 - return '<span class="disabled">' . wfMsgExt( 'configure-view-not-allowed', array( 'parseinline' ) ) . '</span>';
 925+ return Html::rawElement( 'span', array( 'class' => 'disabled' ), wfMsgExt( 'configure-view-not-allowed', array( 'parseinline' ) ) );
933926 $allowed = isset( $params['edit'] ) ? $params['edit'] : $this->userCanEdit( $conf );
934927 $type = isset( $params['type'] ) ? $params['type'] : $this->getSettingType( $conf );
935928 $default = isset( $params['value'] ) ? $params['value'] : $this->getSettingValue( $conf );
936929 if ( $type == 'text' || $type == 'int' ) {
937930 if ( !$allowed )
938931 return '<code>' . htmlspecialchars( (string)$default ) . '</code>';
939 - return Xml::input( "wp$conf", $type == 'text' ? 45 : 10, (string)$default );
 932+ return Html::input( "wp$conf", (string)$default, 'text', array( 'size' => $type == 'text' ? 45 : 10 ) );
940933 }
941934 if ( $type == 'image-url' ) {
942935 if ( !$allowed )
943936 return '<code>' . htmlspecialchars( (string)$default ) . '</code>';
944937 return wfMsgExt( 'configure-image-url-explanation', 'parseinline' ) . '<br />' .
945 - Xml::input( "wp$conf", 45, (string)$default,
946 - array( 'class' => 'image-selector', 'id' => 'image-url-textbox-'.$conf )
 938+ Html::element( 'input', array( 'name' => "wp$conf", 'size' => 45, 'value' => (string)$default,
 939+ 'class' => 'image-selector', 'id' => 'image-url-textbox-' . $conf )
947940 ) . '&#160;' .
948 - Xml::element( 'img', array( 'id' => 'image-url-preview-'.$conf, 'src' => $default ) );
 941+ Html::element( 'img', array( 'id' => 'image-url-preview-'.$conf, 'src' => $default ) );
949942 }
950943 if ( $type == 'bool' ) {
951944 if ( !$allowed )
952945 return '<code>' . ( $default ? 'true' : 'false' ) . '</code>';
953 - return Xml::check( "wp$conf", $default, array( 'value' => '1' ) );
 946+ $attribs = array( 'type' => 'checkbox', 'name' => "wp$conf", 'value' => '1' );
 947+ if ( $allowed ) {
 948+ $attribs['checked'] = 'checked';
 949+ }
 950+ return Html::element( 'input', $attribs );
954951 }
955952 if ( $type == 'array' ) {
956953 return $this->buildArrayInput( $conf, $default, $allowed );
@@ -968,11 +965,10 @@
969966 $attribs = array( 'value' => $code );
970967 if ( $code == $default )
971968 $attribs['selected'] = 'selected';
972 - $options .= Xml::element( 'option', $attribs, "$code - $name" ) . "\n";
 969+ $options .= Html::element( 'option', $attribs, "$code - $name" ) . "\n";
973970 }
974971
975 - return Xml::openElement( 'select', array( 'id' => 'wp' . $conf, 'name' => 'wp' . $conf ) ) .
976 - $options . "</select>";
 972+ return Html::rawElement( 'select', array( 'id' => 'wp' . $conf, 'name' => 'wp' . $conf ), $options );
977973 } else {
978974 return '<code>' . ( isset( $languages[$default] ) ?
979975 htmlspecialchars( "$default - " . $languages[$default] ) :
@@ -986,7 +982,14 @@
987983 foreach ( $type as $val => $name ) {
988984 $checked = is_int( $val ) ?
989985 $val === (int)$default : strval($default) === strval($val);
990 - $ret .= Xml::radioLabel( $name, 'wp' . $conf, $val, 'wp' . $conf . $val, $checked ) . "\n";
 986+
 987+ $opts = array( 'name' => 'wp' . $conf );
 988+ if ( $checked ) {
 989+ $opts['checked'] = 'checked';
 990+ }
 991+ $ret .= Html::input( 'wp' . $conf . $val, $val, 'radio', $opts ) .
 992+ '&#160;' . Html::element( 'label', array( 'for' => 'wp' . $conf . $val ), $name );
 993+
991994 }
992995 return $ret;
993996 }
@@ -1003,7 +1006,7 @@
10041007 protected function buildArrayInput( $conf, $default, $allowed ) {
10051008 $type = $this->getArrayType( $conf );
10061009 if ( $type === null || $type == 'array' )
1007 - return $allowed ? '<span class="array">(array)</span>' : '<span class="array-disabled">(array)</span>';
 1010+ return Html::rawElement( 'span', array( 'class' => $allowed ? 'array' : 'array-disabled' ), '(array)' );
10081011 if ( $type == 'simple' ) {
10091012 if ( !$allowed ) {
10101013 return "<pre>" .
@@ -1011,10 +1014,8 @@
10121015 "\n</pre>";
10131016 }
10141017 $text = wfMsgExt( 'configure-arrayinput-oneperline', 'parseinline' );
1015 - $text .= "<textarea id='wp{$conf}' name='wp{$conf}' cols='30' rows='8' style='width: 95%;'>";
1016 - if ( is_array( $default ) )
1017 - $text .= implode( "\n", $default );
1018 - $text .= "</textarea>\n";
 1018+ $text .= Html::textarea( "wp{$conf}", is_array( $default ) ? implode( "\n", $default ) : '',
 1019+ array( 'id' => "wp{$conf}", 'rows' => 8, 'style' => 'width:95%;' ) );
10191020 return $text;
10201021 }
10211022 if ( $type == 'assoc' ) {
@@ -1035,50 +1036,52 @@
10361037 if ( count( $default ) > 5 )
10371038 $classes[] = 'configure-biglist';
10381039
1039 - $text = Xml::openElement( 'table', array( 'class' => ( implode( ' ', $classes ) ),
 1040+ $text = Html::openElement( 'table', array( 'class' => ( implode( ' ', $classes ) ),
10401041 'id' => $conf ) ) . "\n";
1041 - $text .= "<tr><th>{$keydesc}</th><th>{$valdesc}</th></tr>\n";
 1042+ $text .= Html::rawElement( 'tr', array(), Html::rawElement( 'th', array(), $keydesc ) . Html::rawElement( 'th', array(), $valdesc ) );
10421043 if ( is_array( $default ) && count( $default ) > 0 ) {
10431044 $i = 0;
10441045 foreach ( $default as $key => $val ) {
1045 - $text .= '<tr><td>';
 1046+ $text .= Html::openElement( 'tr' ) . Html::openElement( 'td' );
10461047 if ( $allowed )
1047 - $text .= Xml::element( 'input', array(
 1048+ $text .= Html::element( 'input', array(
10481049 'name' => 'wp' . $conf . "-key-{$i}",
10491050 'type' => 'text', 'value' => $key, 'size' => 20
1050 - ) ) . "<br />\n";
 1051+ ) ) . Html::element( 'br' ) . "\n";
10511052 else
10521053 $text .= '<code>' . htmlspecialchars( $key ) . '</code>';
1053 - $text .= '</td><td>';
 1054+ $text .= Html::closeElement( 'td' ) . Html::openElement( 'td' );
10541055 if ( $allowed )
1055 - $text .= Xml::element( 'input', array(
 1056+ $text .= Html::element( 'input', array(
10561057 'name' => 'wp' . $conf . "-val-{$i}",
10571058 'type' => 'text', 'value' => $val, 'size' => 20
1058 - ) ) . "<br />\n";
 1059+ ) ) . Html::element( 'br' ) . "\n";
10591060 else
10601061 $text .= '<code>' . htmlspecialchars( $val ) . '</code>';
1061 - $text .= '</td></tr>';
 1062+ $text .= Html::closeElement( 'td' ) . Html::closeElement( 'tr' );
10621063 $i++;
10631064 }
10641065 } else {
10651066 if ( $allowed ) {
1066 - $text .= '<tr><td>';
1067 - $text .= Xml::element( 'input', array(
 1067+ $text .= Html::openElement( 'tr' ) . Html::openElement( 'td' );
 1068+ $text .= Html::element( 'input', array(
10681069 'name' => 'wp' . $conf . "-key-0",
10691070 'type' => 'text', 'value' => '', 'size' => 20,
1070 - ) ) . "<br />\n";
1071 - $text .= '</td><td>';
1072 - $text .= Xml::element( 'input', array(
 1071+ ) ) . Html::element( 'br' ) . "\n";
 1072+ $text .= Html::closeElement( 'td' ) . Html::openElement( 'td' );
 1073+ $text .= Html::element( 'input', array(
10731074 'name' => 'wp' . $conf . "-val-0",
10741075 'type' => 'text', 'value' => '', 'size' => 20,
1075 - ) ) . "<br />\n";
1076 - $text .= '</td></tr>';
 1076+ ) ) . Html::element( 'br' ) . "\n";
 1077+ $text .= Html::closeElement( 'td' ) . Html::closeElement( 'tr' );
10771078 } else {
1078 - $text .= "<tr><td style='width:10em; height:1.5em;'><hr /></td>" .
1079 - "<td style='width:10em; height:1.5em;'><hr /></td></tr>\n";
 1079+ $text .= Html::rawElement( 'tr', array(),
 1080+ Html::rawElement( 'td', array( 'style' => 'width:10em;height:1.5em;' ), Html::element( 'hr' ) ) .
 1081+ Html::rawElement( 'td', array( 'style' => 'width:10em;height:1.5em;' ), Html::element( 'hr' ) )
 1082+ ) . "\n";
10801083 }
10811084 }
1082 - $text .= '</table>';
 1085+ $text .= Html::closeElement( 'table' );
10831086 return $text;
10841087 }
10851088 if ( $type == 'rate-limits' ) { ## Some of this is stolen from assoc, since it's an assoc with an assoc.
@@ -1095,7 +1098,7 @@
10961099 if ( !$allowed )
10971100 $classes[] = 'disabled';
10981101
1099 - $rows = Xml::tags( 'tr', null, Xml::tags( 'th', null, $keydesc ) . " " . Xml::tags( 'th', null, $valdesc ) )."\n";
 1102+ $rows = Html::rawElement( 'tr', array(), Html::rawElement( 'th', array(), $keydesc ) . " " . Html::rawElement( 'th', array(), $valdesc ) )."\n";
11001103
11011104 # TODO put this stuff in one place.
11021105 $validActions = array( 'edit', 'move', 'mailpassword', 'emailuser', 'rollback' );
@@ -1106,11 +1109,11 @@
11071110 if ( isset( $default[$action] ) )
11081111 $val = $default[$action];
11091112
1110 - $key = Xml::tags( 'td', null, wfMsgExt( "configure-throttle-action-$action", 'parseinline' ) );
 1113+ $key = Html::rawElement( 'td', array(), wfMsgExt( "configure-throttle-action-$action", 'parseinline' ) );
11111114
11121115 ## Build YET ANOTHER ASSOC TABLE ARGH!
1113 - $innerRows = Xml::tags( 'tr', null, Xml::tags( 'th', null, wfMsgExt( 'configure-throttle-group', 'parseinline' ) ) . ' ' .
1114 - Xml::tags( 'th', null, wfMsgExt( 'configure-throttle-limit', 'parseinline' ) ) )."\n";
 1116+ $innerRows = Html::rawElement( 'tr', array(), Html::rawElement( 'th', array(), wfMsgExt( 'configure-throttle-group', 'parseinline' ) ) . ' ' .
 1117+ Html::rawElement( 'th', array(), wfMsgExt( 'configure-throttle-limit', 'parseinline' ) ) )."\n";
11151118 foreach( $validGroups as $type ) {
11161119 $limits = null;
11171120 if ( isset( $default[$action][$type] ) )
@@ -1121,26 +1124,29 @@
11221125 $count = $period = 0;
11231126
11241127 $id = 'wp'.$conf.'-key-'.$action.'-'.$type;
1125 - $left_col = Xml::tags( 'td', null, wfMsgExt( "configure-throttle-group-$type", 'parseinline' ) );
 1128+ $left_col = Html::rawElement( 'td', array(), wfMsgExt( "configure-throttle-group-$type", 'parseinline' ) );
11261129
11271130 if ( $allowed ) {
1128 - $right_col = Xml::inputLabel( wfMsg( 'configure-throttle-count' ), "$id-count", "$id-count", 15, $count ) . ' <br /> ' .
1129 - Xml::inputLabel( wfMsg( 'configure-throttle-period' ), "$id-period", "$id-period", 15, $period );
 1131+ $right_col = Html::element( 'label', array( 'for' => "$id-count" ), wfMsg( 'configure-throttle-count' ) ) .
 1132+ '&#160;' . Html::input( "$id-count", $count, 'text', array( 'name' => "$id-count", 'size' => 15 ) ) .
 1133+ Html::element( 'br' ) .
 1134+ Html::element( 'label', array( 'for' => "$id-period" ), wfMsg( 'configure-throttle-period' ) ) .
 1135+ '&#160;' . Html::input( "$id-period", $period, 'text', array( 'name' => "$id-period", 'size' => 15 ) );
11301136 } else {
11311137 $right_col = ($count && $period) ? wfMsg( 'configure-throttle-summary', $count, $period ) : wfMsg( 'configure-throttle-none' );
11321138 ## Laziness: Make summaries work by putting the data in hidden fields, rather than a special case in JS.
1133 - $right_col .= "\n" . Xml::hidden( "$id-count", $count, array( 'id' => "$id-count" ) ) . Xml::hidden( "$id-period", $period, array( 'id' => "$id-period" ) );
 1139+ $right_col .= "\n" . Html::hidden( "$id-count", $count, array( 'id' => "$id-count" ) ) . Html::hidden( "$id-period", $period, array( 'id' => "$id-period" ) );
11341140 }
1135 - $right_col = Xml::tags( 'td', null, $right_col );
 1141+ $right_col = Html::rawElement( 'td', array(), $right_col );
11361142
1137 - $innerRows .= Xml::tags( 'tr', array( 'id' => $id ), $left_col . $right_col ) . "\n";
 1143+ $innerRows .= Html::rawElement( 'tr', array( 'id' => $id ), $left_col . $right_col ) . "\n";
11381144 }
11391145
1140 - $value = Xml::tags( 'td', null, Xml::tags( 'table', array( 'class' => 'configure-biglist configure-rate-limits-action' ), Xml::tags( 'tbody', null, $innerRows ) ) );
1141 - $rows .= Xml::tags( 'tr', null, $key.$value )."\n";
 1146+ $value = Html::rawElement( 'td', array(), Html::rawElement( 'table', array( 'class' => 'configure-biglist configure-rate-limits-action' ), Html::rawElement( 'tbody', array(), $innerRows ) ) );
 1147+ $rows .= Html::rawElement( 'tr', array(), $key.$value )."\n";
11421148 }
11431149
1144 - return Xml::tags( 'table', array( 'class' => implode( ' ', $classes ) ), Xml::tags( 'tbody', null, $rows ) );
 1150+ return Html::rawElement( 'table', array( 'class' => implode( ' ', $classes ) ), Html::rawElement( 'tbody', null, $rows ) );
11451151 }
11461152 if ( $type == 'simple-dual' ) {
11471153 $var = array();
@@ -1172,16 +1178,21 @@
11731179 } else {
11741180 $checked = in_array( $ns, (array)$default );
11751181 }
1176 - $text .= "<span style='white-space:nowrap;'>".
1177 - Xml::checkLabel(
1178 - $name,
1179 - "wp{$conf}-ns{$ns}",
1180 - "wp{$conf}-ns{$ns}",
1181 - $checked,
1182 - $attr
1183 - ) . "</span>\n";
 1182+ $inputAttribs = array(
 1183+ 'name' => "wp{$conf}-ns{$ns}",
 1184+ 'id' => "wp{$conf}-ns{$ns}",
 1185+ 'type' => 'checkbox',
 1186+ 'value' => 1
 1187+ );
 1188+ if ( $checked ) {
 1189+ $inputAttribs['checked'] = 'checked';
 1190+ }
 1191+ $inputAttribs += $attr;
 1192+ $text .= Html::rawElement( 'span', array( 'style' => 'white-space:nowrap;' ),
 1193+ Html::element( 'input', $inputAttribs ) . '&#160;' .
 1194+ Html::element( 'label', array( 'for' => "wp{$conf}-ns{$ns}" ), $name ) ) . "\n";
11841195 }
1185 - $text = Xml::tags( 'div', array( 'class' => 'configure-biglist '.$type ), $text );
 1196+ $text = Html::rawElement( 'div', array( 'class' => 'configure-biglist '.$type ), $text );
11861197 return $text;
11871198 }
11881199 if ( $type == 'ns-text' ) {
@@ -1191,24 +1202,25 @@
11921203
11931204 if ( wfEmptyMsg( "configure-setting-$conf-value", $valdesc ) )
11941205 $valdesc = wfMsgHtml( 'configure-desc-val' );
1195 - $text = "<table class='configure-array-table ns-text configure-biglist'>\n<tr><th>{$nsdesc}</th><th>{$valdesc}</th></tr>\n";
 1206+ $text = Html::openElement( 'table', array( 'class' => 'configure-array-table ns-text configure-biglist' ) ) . "\n" .
 1207+ Html::rawElement( 'tr', array(), Html::rawElement( 'th', array(), $nsdesc ) . Html::rawElement( 'th', array(), $valdesc ) ) . "\n";
11961208 foreach ( $wgContLang->getNamespaces() as $ns => $name ) {
11971209 $name = str_replace( '_', ' ', $name );
11981210 if ( '' == $name ) {
11991211 $name = wfMsgExt( 'blanknamespace', array( 'parseinline' ) );
12001212 }
1201 - $text .= '<tr><td>' . $name . '</td><td>';
 1213+ $text .= Html::openElement( 'tr', array() ) . Html::rawElement( 'td', array(), $name ) . Html::openElement( 'td', array() );
12021214 if ( $allowed )
1203 - $text .= Xml::element( 'input', array(
 1215+ $text .= Html::element( 'input', array(
12041216 'size' => 20,
12051217 'name' => "wp{$conf}-ns{$ns}",
12061218 'type' => 'text', 'value' => isset( $default[$ns] ) ? $default[$ns] : ''
12071219 ) ) . "\n";
12081220 else
12091221 $text .= htmlspecialchars( isset( $default[$ns] ) ? $default[$ns] : '' );
1210 - $text .= '</td></tr>';
 1222+ $text .= Html::closeElement( 'td' ) . Html::closeElement( 'tr' );
12111223 }
1212 - $text .= '</table>';
 1224+ $text .= Html::closeElement( 'table' );
12131225 return $text;
12141226 }
12151227 if ( $type == 'ns-array' ) {
@@ -1218,7 +1230,8 @@
12191231
12201232 if ( wfEmptyMsg( "configure-setting-$conf-value", $valdesc ) )
12211233 $valdesc = wfMsgHtml( 'configure-desc-val' );
1222 - $text = "<table class='ns-array configure-biglist configure-array-table'>\n<tr><th>{$nsdesc}</th><th>{$valdesc}</th></tr>\n";
 1234+ $text = Html::openElement( 'table', array( 'class' => 'ns-array configure-biglist configure-array-table' ) ) . "\n" .
 1235+ Html::rawElement( 'tr', array(), Html::rawElement( 'th', array(), $nsdesc ) . Html::rawElement( 'th', array(), $valdesc ) ) . "\n";
12231236 foreach ( $wgContLang->getNamespaces() as $ns => $name ) {
12241237 if ( $ns < 0 )
12251238 continue;
@@ -1226,22 +1239,22 @@
12271240 if ( '' == $name ) {
12281241 $name = wfMsgExt( 'blanknamespace', array( 'parseinline' ) );
12291242 }
1230 - $text .= '<tr><td>' . Xml::label( $name, "wp{$conf}-ns{$ns}" ) . '</td><td>';
 1243+ $text .= Html::openElement( 'tr' ) . Html::rawElement( 'td', array(),
 1244+ Html::rawElement( 'label', array( 'for' => "wp{$conf}-ns{$ns}" ), $name ) ) . Html::openElement( 'td' );
12311245 if ( $allowed ) {
1232 - $text .= Xml::openElement( 'textarea', array(
1233 - 'name' => "wp{$conf}-ns{$ns}",
1234 - 'id' => "wp{$conf}-ns{$ns}",
1235 - 'cols' => 30,
1236 - 'rows' => 5, ) ) .
1237 - ( isset( $default[$ns] ) ? implode( "\n", (array)$default[$ns] ) : '' ) .
1238 - Xml::closeElement( 'textarea' ) . "<br />\n";
 1246+ $text .= Html::textarea( "wp{$conf}-ns{$ns}", isset( $default[$ns] ) ? implode( "\n", (array)$default[$ns] ) : '',
 1247+ array(
 1248+ 'id' => "wp{$conf}-ns{$ns}",
 1249+ 'rows' => 5
 1250+ )
 1251+ ) . Html::element( 'br' ) . "\n";
12391252 } else {
12401253 $text .= "<pre>" . ( isset( $default[$ns] ) ?
12411254 htmlspecialchars( implode( "\n", (array)$default[$ns] ) ) : '' ) . "\n</pre>";
12421255 }
1243 - $text .= '</td></tr>';
 1256+ $text .= Html::closeElement( 'td' ) . Html::closeElement( 'tr' );
12441257 }
1245 - $text .= '</table>';
 1258+ $text .= Html::closeElement( 'table' );
12461259 return $text;
12471260 }
12481261 if ( $type == 'group-bool' || $type == 'group-array' ) {
@@ -1264,23 +1277,25 @@
12651278 }
12661279 $all = array_diff( $all, $this->getSettingValue( 'wgImplicitGroups' ) );
12671280 }
1268 - sort($all);
 1281+ sort( $all );
12691282 $groupdesc = wfMsgHtml( 'configure-desc-group' );
12701283 $valdesc = wfMsgExt( "configure-setting-$conf-value", 'parseinline' );
12711284
12721285 if ( wfEmptyMsg( "configure-setting-$conf-value", $valdesc ) )
12731286 $valdesc = wfMsgHtml( 'configure-desc-val' );
1274 - $encConf = htmlspecialchars( $conf );
12751287 $classes = "{$type} configure-array-table" . ( $type == 'group-bool' ? ' ajax-group' : '' );
1276 - $text = "<table id=\"{$encConf}\" class=\"$classes\">\n";
1277 - $text .= "<tr class=\"configure-maintable-row\"><th>{$groupdesc}</th><th>{$valdesc}</th></tr>\n";
 1288+ $text = Html::openElement( 'table', array( 'id' => $conf, 'class' => $classes ) ) ."\n";
 1289+ $text .= Html::rawElement( 'tr', array( 'class' => 'configure-maintable-row' ),
 1290+ Html::rawElement( 'th', array(), $groupdesc ) . Html::rawElement( 'th', array(), $valdesc ) ) . "\n";
12781291 foreach ( $iter as $group => $levs ) {
12791292 $row = self::buildGroupSettingRow( $conf, $type, $all, $allowed, $group, $levs );
12801293 $groupName = User::getGroupName( $group );
1281 - $encId = Sanitizer::escapeId( 'wp' . $conf . '-' . $group );
1282 - $text .= "<tr class=\"configure-maintable-row\" id=\"{$encId}\">\n<td class=\"configure-grouparray-group\">{$groupName}</td>\n<td class=\"configure-grouparray-value\">{$row}</td>\n</tr>";
 1294+
 1295+ $text .= Html::rawElement( 'tr', array( 'class' => 'configure-maintable-row', 'id' => 'wp' . $conf . '-' . $group ),
 1296+ Html::rawElement( 'td', array( 'class' => 'configure-grouparray-group' ), $groupName ) . "\n" .
 1297+ Html::rawElement( 'td', array( 'class' => 'configure-grouparray-value' ), $row ) );
12831298 }
1284 - $text .= '</table>';
 1299+ $text .= Html::closeElement( 'table' );
12851300 return $text;
12861301 }
12871302 if ( $type == 'promotion-conds' ) {
@@ -1289,18 +1304,20 @@
12901305 $valdesc = wfMsgExt( "configure-setting-$conf-value", 'parseinline' );
12911306 if ( wfEmptyMsg( "configure-setting-$conf-value", $valdesc ) )
12921307 $valdesc = wfMsgHtml( 'configure-desc-val' );
1293 - $encConf = htmlspecialchars( $conf );
1294 - $text = "<table id= '{$encConf}' class='{$type} configure-array-table ajax-group'>\n";
1295 - $text .= "<tr class=\"configure-maintable-row\"><th>{$groupdesc}</th><th>{$valdesc}</th></tr>\n";
 1308+ $text = Html::openElement( 'table', array( 'id' => $conf, 'class' => "{$type} configure-array-table ajax-group" ) ) ."\n";
 1309+ $text .= Html::rawElement( 'tr', array( 'class' => 'configure-maintable-row' ),
 1310+ Html::rawElement( 'th', array(), $groupdesc ) . Html::rawElement( 'th', array(), $valdesc ) ) . "\n";
12961311
12971312 foreach ( $default as $group => $groupConds ) {
12981313 $row = self::buildPromotionCondsSettingRow( $conf, $allowed, $group, $groupConds );
12991314 $groupName = User::getGroupName( $group );
1300 - $encId = Sanitizer::escapeId( 'wp' . $conf . '-' . $group );
1301 - $text .= "<tr class=\"configure-maintable-row\" id=\"{$encId}\">\n<td class=\"configure-promotion-group\">{$groupName}</td>\n<td class=\"configure-promotion-value\">{$row}</td>\n</tr>";
 1315+
 1316+ $text .= Html::rawElement( 'tr', array( 'class' => 'configure-maintable-row', 'id' => 'wp' . $conf . '-' . $group ),
 1317+ Html::rawElement( 'td', array( 'class' => 'configure-promotion-group' ), $groupName ) . "\n" .
 1318+ Html::rawElement( 'td', array( 'class' => 'configure-promotion-value' ), $row ) );
13021319 }
13031320
1304 - $text .= '</table>';
 1321+ $text .= Html::closeElement( 'table' );
13051322 return $text;
13061323 }
13071324 }
@@ -1320,7 +1337,7 @@
13211338 APCOND_INGROUPS => 'array', APCOND_ISIP => 'text', APCOND_IPINRANGE => 'text',
13221339 APCOND_AGE_FROM_EDIT => 'int' );
13231340
1324 - $row = '<div class="configure-biglist promotion-conds-element">';
 1341+ $row = Html::openElement( 'div', array( 'class' => 'configure-biglist promotion-conds-element' ) );
13251342 $row .= wfMsgHtml( 'configure-condition-operator' ) . ' ';
13261343 $encConf = htmlspecialchars( $conf );
13271344 $encGroup = htmlspecialchars( $group );
@@ -1332,10 +1349,14 @@
13331350
13341351 $extra = $allowed ? array() : array( 'disabled' => 'disabled' );
13351352 foreach ( $options as $desc => $opt ) {
1336 - $row .= Xml::radioLabel( wfMsg( 'configure-condition-operator-'.$desc ), $encId.'-opt', $desc,
1337 - $encId.'-opt-'.$desc, $curOpt == $opt, $extra ) . "\n";
 1353+ $opts = array( 'name' => $encId.'-opt' ) + $extra;
 1354+ if ( $curOpt == $opt ) {
 1355+ $opts['checked'] = 'checked';
 1356+ }
 1357+ $row .= Html::input( $encId.'-opt-'.$desc, $desc, 'radio', $opts ) .
 1358+ '&#160;' . Html::element( 'label', array( 'for' => $encId.'-opt-'.$desc ), wfMsg( 'configure-condition-operator-'.$desc ) );
13381359 }
1339 - $row .= "<br />\n";
 1360+ $row .= Html::element( 'br' ) . "\n";
13401361
13411362 if ( !is_array( $groupConds ) )
13421363 $groupConds = array( $groupConds );
@@ -1356,28 +1377,34 @@
13571378 }
13581379 }
13591380
1360 - $row .= "<table class=\"configure-table-promotion\">\n";
1361 - $row .= '<tr><th>' . wfMsgHtml( 'configure-condition-name' ) . '</th><th>' . wfMsgHtml( 'configure-condition-requirement' ) . "</th></tr>\n";
 1381+ $row .= Html::openElement( 'table', array( 'class' => 'configure-table-promotion' ) );
 1382+
 1383+ $row .= Html::rawElement( 'tr', array(), Html::element( 'th', array(), wfMsg( 'configure-condition-name' ) ) .
 1384+ Html::element( 'th', array(), wfMsg( 'configure-condition-requirement' ) ) )."\n";
13621385 foreach ( $conds as $condName => $condType ) {
1363 - $desc = wfMsgHtml( 'configure-condition-name-' . $condName );
1364 - $row .= "<tr><td><label for=\"{$encId}-cond-{$condName}\">{$desc}</label></td><td>";
 1386+ $desc = wfMsg( 'configure-condition-name-' . $condName );
 1387+ $row .= Html::openElement( 'tr' ) . Html::rawElement( 'td', array(),
 1388+ Html::element( 'label', array( 'for' => "{$encId}-cond-{$condName}" ), $desc ) ) . Html::openElement( 'td' );
13651389 switch( $condType ) {
13661390 case 'bool':
1367 - $row .= Xml::check( $encId.'-cond-'.$condName, isset( $condsVal[$condName] ) && $condsVal[$condName],
1368 - array( 'id' => $encId.'-cond-'.$condName ) + $extra ) . "<br />\n";
1369 - break;
 1391+ $opts = array( 'id' => $encId.'-cond-'.$condName ) + $extra;
 1392+ if ( isset( $condsVal[$condName] ) && $condsVal[$condName] )
 1393+ $opts['checked'] = 'checked';
 1394+ $row .= Html::input( $encId.'-cond-'.$condName, '1', 'checkbox', $opts );
13701395 case 'text':
13711396 case 'int':
1372 - $row .= Xml::input( $encId.'-cond-'.$condName, ( $condType == 'int' ? 20 : 40 ),
1373 - isset( $condsVal[$condName] ) ? $condsVal[$condName] : ( $condType == 'int' ? 0 : '' ), $extra ) . "<br />\n";
 1397+ $row .= Html::input( $encId.'-cond-'.$condName, isset( $condsVal[$condName] ) ? $condsVal[$condName] : ( $condType == 'int' ? 0 : '' ), 'text',
 1398+ array( 'size' => $condType == 'int' ? 20 : 40 ) + $extra ) .
 1399+ Html::element( 'br' ) . "\n";
13741400 break;
13751401 case 'array':
13761402 $id = "{$encId}-cond-{$condName}";
13771403 if ( $allowed ) {
1378 - $row .= "<textarea id='{$id}' name='{$id}' cols='30' rows='4' style='width: 95%;'>";
13791404 if ( isset( $condsVal[$condName] ) && $condsVal[$condName] )
1380 - $row .= htmlspecialchars( implode( "\n", $condsVal[$condName] ) );
1381 - $row .= "</textarea>\n";
 1405+ $cont = htmlspecialchars( implode( "\n", $condsVal[$condName] ) );
 1406+ else
 1407+ $cont = '';
 1408+ $row .= Html::textarea( $id, $cont, array( 'id' => $id, 'rows' => '4', 'style' => 'width:95%;' ) );
13821409 } else {
13831410 $row .= "<pre>";
13841411 if ( isset( $condsVal[$condName] ) && $condsVal[$condName] )
@@ -1385,9 +1412,9 @@
13861413 $row .= "</pre>\n";
13871414 }
13881415 }
1389 - $row .= "</td></tr>";
 1416+ $row .= Html::closeElement( 'td' ) . Html::closeElement( 'tr' );
13901417 }
1391 - $row .= "</table></div>";
 1418+ $row .= Html::closeElement( 'table' ) . Html::closeElement( 'div' );
13921419 return $row;
13931420 }
13941421
@@ -1404,7 +1431,8 @@
14051432 */
14061433 public static function buildGroupSettingRow( $conf, $type, $all, $allowed, $group, $levs ){
14071434 $attr = ( !$allowed ) ? array( 'disabled' => 'disabled' ) : array();
1408 - $row = '<div class="configure-biglist '.$type.'-element"><ul>';
 1435+
 1436+ $row = Html::openElement( 'div', array( 'class' => 'configure-biglist '.$type.'-element' ) ) . Html::openElement( 'ul' );
14091437 foreach ( $all as $right ) {
14101438 if ( $type == 'group-bool' )
14111439 $checked = ( isset( $levs[$right] ) && $levs[$right] );
@@ -1412,12 +1440,13 @@
14131441 $checked = in_array( $right, $levs );
14141442 $id = Sanitizer::escapeId( 'wp' . $conf . '-' . $group . '-' . $right );
14151443 if( $type == 'group-bool' )
1416 - $desc = User::getRightDescription( $right ) . " (" .Xml::element( 'tt', array( 'class' => 'configure-right-id' ), $right ) . ")";
 1444+ $desc = User::getRightDescription( $right ) . " (" .Html::element( 'tt', array( 'class' => 'configure-right-id' ), $right ) . ")";
14171445 else
14181446 $desc = User::getGroupName( $right );
1419 - $row .= '<li>' . Xml::check( $id, $checked, $attr + array( 'id' => $id ) ) . '&#160;' . Xml::tags( 'label', array( 'for' => $id ), $desc ) . "</li>\n";
 1447+ $checkedArr = $checked ? array( 'checked' => 'checked' ) : array();
 1448+ $row .= Html::rawElement( 'li', array(), Html::input( $id, '1', 'checkbox', $attr + array( 'id' => $id ) + $checkedArr ) . '&#160;' . Html::rawElement( 'label', array( 'for' => $id ), $desc ) ) . "\n";
14201449 }
1421 - $row .= '</ul></div>';
 1450+ $row .= Html::closeElement( 'ul' ) . Html::closeElement( 'div' );
14221451 return $row;
14231452 }
14241453
@@ -1440,14 +1469,11 @@
14411470 $showLink = isset( $params['link'] ) ? $params['link'] : true;
14421471
14431472 ## First TD
1444 - $attribs = array();
1445 - $attribs['align'] = $wgContLang->isRtl() ? 'right' : 'left';
1446 - $attribs['valign'] = 'top';
14471473 $msgVal = wfMsgExt( $msg, array( 'parseinline' ) );
1448 - $rawVal = Xml::element( 'tt', null, "\$$conf" );
 1474+ $rawVal = Html::element( 'tt', null, "\$$conf" );
14491475 if ( $showLink ) {
14501476 $url = 'http://www.mediawiki.org/wiki/Manual:$' . $conf;
1451 - $link = Xml::tags( 'a', array( 'href' => $url, 'class' => 'configure-doc' ), $rawVal );
 1477+ $link = Html::rawElement( 'a', array( 'href' => $url, 'class' => 'configure-doc' ), $rawVal );
14521478 } else {
14531479 $link = $rawVal;
14541480 }
@@ -1457,16 +1483,19 @@
14581484 $msgVal = "$msgVal ($link)";
14591485
14601486 if ( $params['customised'] )
1461 - $msgVal = Xml::tags( 'p', null, $msgVal ).wfMsgExt( 'configure-customised', 'parse' );
 1487+ $msgVal = Html::rawElement( 'p', null, $msgVal ).wfMsgExt( 'configure-customised', 'parse' );
 1488+
 1489+ $attribs = array();
 1490+ $attribs['style'] = 'text-align:' . ( $wgContLang->isRtl() ? 'right' : 'left' ) . ';vertical-align:top;';
14621491 $attribs['class'] = 'configure-left-column';
1463 - $td1 = Xml::tags( 'td', $attribs, $msgVal );
 1492+ $td1 = Html::rawElement( 'td', $attribs, $msgVal );
14641493
14651494 ## Only the class is customised per-cell, so we'll just redefine that.
14661495 $attribs['class'] = 'configure-right-column';
14671496
1468 - $td2 = Xml::tags( 'td', $attribs, $this->buildInput( $conf, $params ) );
 1497+ $td2 = Html::rawElement( 'td', $attribs, $this->buildInput( $conf, $params ) );
14691498
1470 - return Xml::tags( 'tr', array( 'class' => implode( ' ', $rowClasses ) ), $td1 . $td2 ) . "\n";
 1499+ return Html::rawElement( 'tr', array( 'class' => implode( ' ', $rowClasses ) ), $td1 . $td2 ) . "\n";
14711500 }
14721501
14731502 /**
@@ -1554,13 +1583,13 @@
15551584 }
15561585
15571586 if ( $thisGroup ) {
1558 - $thisSection .= $this->buildTableHeading( $group ) . $thisGroup . Xml::closeElement( 'table' );
 1587+ $thisSection .= $this->buildTableHeading( $group ) . $thisGroup . Html::closeElement( 'table' );
15591588 }
15601589 }
15611590
15621591 if ( $thisSection ) {
1563 - $thisSection = Xml::tags( 'legend', null, wfMsgExt( "configure-section-$title", array( 'parseinline' ) ) ) . $thisSection;
1564 - $ret .= Xml::tags( 'fieldset', null, $thisSection );
 1592+ $thisSection = Html::rawElement( 'legend', null, wfMsgExt( "configure-section-$title", array( 'parseinline' ) ) ) . $thisSection;
 1593+ $ret .= Html::rawElement( 'fieldset', null, $thisSection );
15651594 }
15661595 }
15671596
Index: trunk/extensions/Configure/Configure.php
@@ -3,7 +3,7 @@
44
55 /**
66 * Special page to allow users to configure the wiki via a web based interface
7 - * Require MediaWiki version 1.16.0 or greater
 7+ * Require MediaWiki version 1.17.0 or greater
88 *
99 * @file
1010 * @ingroup Extensions
@@ -17,7 +17,7 @@
1818 'author' => array( 'Alexandre Emsenhuber', 'Andrew Garrett' ),
1919 'url' => 'http://www.mediawiki.org/wiki/Extension:Configure',
2020 'descriptionmsg' => 'configure-desc',
21 - 'version' => '0.15.38',
 21+ 'version' => '0.16.0',
2222 );
2323
2424 # Configuration part
@@ -175,13 +175,6 @@
176176 */
177177 $wgConfigureStyleVersion = '21';
178178
179 -/**
180 - * Whether to add JS variables to the output
181 - * THIS IS *NOT* A CONFIGURATION OPTION AND MUST *NOT* BE CHANGED IN
182 - * LocalSetting.php
183 - */
184 -$wgConfigureAddJsVariables = false;
185 -
186179 # Adding new rights...
187180 $wgAvailableRights[] = 'configure';
188181 $wgAvailableRights[] = 'configure-all';
@@ -284,10 +277,31 @@
285278
286279 # API module
287280 $wgAutoloadClasses['ApiConfigure'] = $dir . 'Configure.api.php';
288 -$wgExtensionFunctions[] = 'efConfigureSetupAPI';
 281+$wgAPIModules['configure'] = 'ApiConfigure';
289282
290 -# Adding the ajax function
291 -$wgAjaxExportList[] = 'efConfigureAjax';
 283+# Ressource loader
 284+$wgResourceModules['ext.configure'] = array(
 285+ 'scripts' => 'configure.js',
 286+ 'styles' => 'configure.css',
 287+
 288+ 'messages' => array(
 289+ 'configure-js-add',
 290+ 'configure-js-remove',
 291+ 'configure-js-remove-row',
 292+ 'configure-js-prompt-group',
 293+ 'configure-js-group-exists',
 294+ 'configure-js-get-image-url',
 295+ 'configure-js-image-error',
 296+ 'configure-js-biglist-shown',
 297+ 'configure-js-biglist-hidden',
 298+ 'configure-js-biglist-show',
 299+ 'configure-js-biglist-hide',
 300+ 'configure-js-summary-none',
 301+ 'configure-throttle-summary',
 302+ ),
292303
293 -# JS stuff
294 -$wgHooks['MakeGlobalVariablesScript'][] = 'efConfigureMakeGlobalVariablesScript';
 304+ 'dependencies' => 'mediawiki.legacy.wikibits',
 305+
 306+ 'localBasePath' => dirname( __FILE__ ),
 307+ 'remoteExtPath' => 'Configure'
 308+);

Status & tagging log