r97104 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r97103‎ | r97104 | r97105 >
Date:21:43, 14 September 2011
Author:krinkle
Status:ok (Comments)
Tags:todo 
Comment:
[ResourceLoader2] Next phase of the gadget manager
* Changed internal object named 'gadget' to be the object returned by the API. The API provides all the needed data. Previously it was a manually constructed object of which the 'metadata' property came from the api:
{
id: $el.data('gadgetname'),
title: $el.text(),
metadata: query.gadgets[0].metadata
}.
* Now passing around the gadget object by reference and keeping it up to date, from original retrieval from the api, all the way to JSON.stringify sent to ApiEdit.
* Implementing the doModifyGadget() stub:
-- ApiEdit
-- Using gadget.definitiontimestamp from the API as basetimestamp for ApiEdit (instead of another request like prop=revisions&rvprop=timestamp).
-- For the 'starttimestamp': a ISO 8601 formatted version of the Date() object that is created when the user first opens the editor.
(Date.prototype.toISOString is not available cross-browser yet and includes milliseconds as well, in contrary to what MediaWiki uses).
* Changing API methods to not pass status as second argument. Instead using separate success/error callbacks.
* Clean up gm.ui methods a bit
* Change ui methods to use a passed categories array instead of defining it, calling a function which assumes the variable is set and then unsetting it (why did I do that?). So removing gadgetCategoriesCache in the UI code (It still makes sense in the API file).
* Add some /qqq entries for i18n
* Making gadgetmanager-table sortable. +increasing padding-right on the cells to account for the sortHead-icon. +wrapping <th> row in <thead>


NOTE:
* The editor is fairly complete, but there is still work to be done.
* Right now it's working fairly well in modern browsers.
* Going to come back to this part later on. Right now the branch needs a working preferences panel for shared gadgets first.
Modified paths:
  • /branches/RL2/extensions/Gadgets/Gadgets.i18n.php (modified) (history)
  • /branches/RL2/extensions/Gadgets/Gadgets.php (modified) (history)
  • /branches/RL2/extensions/Gadgets/SpecialGadgetManager.php (modified) (history)
  • /branches/RL2/extensions/Gadgets/modules/ext.gadgets.gadgetmanager.api.js (modified) (history)
  • /branches/RL2/extensions/Gadgets/modules/ext.gadgets.gadgetmanager.prejs.css (modified) (history)
  • /branches/RL2/extensions/Gadgets/modules/ext.gadgets.gadgetmanager.ui.js (modified) (history)
  • /branches/RL2/extensions/Gadgets/modules/jquery.createPropCloud.js (modified) (history)

Diff [purge]

Index: branches/RL2/extensions/Gadgets/SpecialGadgetManager.php
@@ -57,7 +57,7 @@
5858 return;
5959 }
6060 // There is atleast one gadget, let's get started.
61 - $this->getOutput()->addWikiMsg( 'gadgetmanager-pagetext' );
 61+ $this->getOutput()->addWikiMsg( 'gadgetmanager-pagetext', SpecialPage::getTitleFor( 'Recentchanges' )->getFullURL('namespace=' . NS_GADGET_DEFINITION ) );
6262 $html = '';
6363
6464 // Sort categories alphabetically
@@ -80,7 +80,7 @@
8181 );
8282
8383 // Start per-category gadgets table
84 - $html .= '<table class="mw-gadgetmanager-gadgets mw-datatable"><tr>';
 84+ $html .= '<table class="mw-gadgetmanager-gadgets mw-datatable sortable"><thead><tr>';
8585 $html .=
8686 '<th>' . wfMessage( 'gadgetmanager-tablehead-title' )->escaped()
8787 . '</th><th>' . wfMessage( 'gadgetmanager-tablehead-default' )->escaped()
@@ -89,7 +89,8 @@
9090 if ( $wgGadgetEnableSharing ) {
9191 $html .= '<th>' . wfMessage( 'gadgetmanager-tablehead-shared' )->escaped() . '</th>';
9292 }
93 - $html .= '<th>' . wfMessage( 'gadgetmanager-tablehead-lastmod' )->escaped() . '</th></tr>';
 93+ $html .= '<th>' . wfMessage( 'gadgetmanager-tablehead-lastmod' )->escaped() . '</th>';
 94+ $html .= '</tr></thead><tbody>';
9495
9596 // Populate table rows for the current category
9697 foreach ( $gadgets as $gadgetId => $gadget ) {
@@ -151,14 +152,14 @@
152153 )
153154 );
154155 }
155 - $html .= "<td>$lastModText</td>";
 156+ $html .= "<td class=\"mw-gadgetmanager-gadgets-lastmod\">$lastModText</td>";
156157 }
157158
158159 $html .= '</tr>';
159160 }
160161
161162 // End of per-category gadgets table
162 - $html .= '</table>';
 163+ $html .= '</tbody></table>';
163164 }
164165
165166 return $html;
Index: branches/RL2/extensions/Gadgets/Gadgets.i18n.php
@@ -27,11 +27,11 @@
2828 Administrators manage to the [[Special:GadgetManager|gadget definitions]] and the [[Special:Gadgets|titles and descriptions]] of available gadgets.',
2929 'gadgets-preference-description' => '$1: $2',
3030
31 - # For Special:Gadgets (overview for users and people with editinterface)
 31+ # For Special:Gadgets (overview for users; titles, messages, description, exporting etc.)
3232 'gadgets' => 'Gadgets',
3333 'gadgets-title' => 'Gadgets',
34 - 'gadgets-pagetext' => "Below is a list of special gadgets users can enable on their [[Special:Preferences#mw-prefsection-gadgets|preferences page]], as defined by the [[MediaWiki:Gadgets-definition|definitions]].
35 -This overview provides easy access to the system message pages that define each gadget's description and code.",
 34+ 'gadgets-pagetext' => "Below is a list of gadgets available on this wiki. Users can enable or disable these through their [[Special:Preferences#mw-prefsection-gadgets|preferences page]].
 35+This overview provides easy access to the system message pages that define each gadget's description and title.",
3636 'gadgets-uses' => 'Uses',
3737 'gadgets-required-rights' => 'Requires the {{PLURAL:$2|$1 right|following rights: $1}}.',
3838 'gadgets-default' => 'Enabled for everyone by default.',
@@ -39,15 +39,13 @@
4040 'gadgets-export-title' => 'Gadget export',
4141 'gadgets-not-found' => 'Gadget "$1" not found.',
4242 'gadgets-export-text' => 'To export the $1 gadget, click on "{{int:gadgets-export-download}}" button, save the downloaded file,
43 -go to Special:Import on destination wiki and upload it. Then add the following to MediaWiki:Gadgets-definition page:
44 -<pre>$2</pre>
45 -You must have appropriate permissions on destination wiki (including the right to edit system messages) and import from file uploads must be enabled.',
 43+go to Special:Import on destination wiki and upload it. You must have appropriate permissions on the destination wiki (including the right to edit in the {{ns:Gadget}} and {{ns:Gadget definition}} namespaces) and the import from file uploads must be enabled.',
4644 'gadgets-export-download' => 'Download',
4745
48 - # For Special:GadgetManager (for gadget meta-data management)
 46+ # For Special:GadgetManager (for gadget definition management)
4947 'gadgetmanager' => 'Gadget manager',
50 - 'gadgetmanager-title' => 'Gadget manager',
51 - 'gadgetmanager-pagetext' => 'Below is an overview of all gadgets defined on this wiki. Users can opt in or opt out of these through their [[Special:Preferences#mw-prefsection-gadgets|preferences page]].',
 48+ 'gadgetmanager-title' => 'Gadget management',
 49+ 'gadgetmanager-pagetext' => 'Welcome to the gadget management interface. Below is an overview of all gadgets defined on this wiki. Users can opt in or opt out of these through their [[Special:Preferences#mw-prefsection-gadgets|preferences page]]. All modifications to gadget definitions can be followed in the [$1 recent changes].',
5250 'gadgetmanager-nogadgets' => 'This wiki currently has no gadgets defined.',
5351 'gadgetmanager-uncategorized' => 'Uncategorized',
5452 'gadgetmanager-tablehead-title' => 'Gadget title',
@@ -74,10 +72,7 @@
7573 'gadgetmanager-prop-default-yes' => 'This gadget is loaded by default.',
7674 'gadgetmanager-prop-hidden-yes' => 'This is a hidden gadget.',
7775 'gadgetmanager-prop-shared-yes' => 'This gadget is shared.',
78 - 'gadgetmanager-modifylink' => 'modify',
79 - 'gadgetmanager-modifylink-tooltip' => 'Modify this gadget',
80 - 'gadgetmanager-deletelink' => 'delete',
81 - 'gadgetmanager-deletelink-tooltip' => 'Delete ths gadget',
 76+ 'gadgetmanager-comment-modify' => 'Modified definition of gadget [[Special:GadgetManager/$1|$1]]',
8277
8378 # Validation error messages
8479 'gadget-validate-invalidjson' => 'The gadget definition page contents are not a valid JSON object.',
@@ -108,17 +103,22 @@
109104 * @author Timo Tijhof
110105 */
111106 $messages['qqq'] = array(
 107+ # For Special:Version
 108+ 'gadgets' => '{{Identical|Gadgets}}',
112109 'gadgets-desc' => '{{desc}}',
 110+
 111+ # For Special:Preferences
113112 'prefs-gadgets' => 'In Gadgets extension. The name of a tab in [[Special:Preferences]] where user set their preferences for the extension.
114113
115114 {{Identical|Gadgets}}',
116115 'gadgets-prefstext' => 'In Gadgets extension. This is the explanation text displayed under the Gadgets tab in [[Special:Preferences]].',
117116 'gadgets-preference-description' => 'Used for the description HTML of a Gadget in Special:Preferences. $1 is the title of the Gadget, $2 is the description of the Gadget.',
118 - 'gadgets' => '{{Identical|Gadgets}}',
 117+
 118+ # For Special:Gadgets
119119 'gadgets-title' => '{{Identical|Gadgets}}',
120120 'gadgets-uses' => "This is used as a verb in third-person singular. It appears in front of a script name. Example: \"''Uses: Gadget-UTCLiveClock.js''\"
121121
122 -See [http://meta.wikimedia.org/wiki/Special:Gadgets Gadgets page in meta.wikimedia.org]",
 122+See [http://mediawiki.org/wiki/Special:Gadgets Gadgets overview on mediawiki.org]",
123123 'gadgets-required-rights' => 'Parameters:
124124 * $1 - a list.
125125 * $2 - the number of items in list $1 for PLURAL use.',
@@ -126,17 +126,29 @@
127127 {{Identical|Export}}',
128128 'gadgets-export-download' => 'Use the verb for this message. Submit button.
129129 {{Identical|Download}}',
130 - 'gadgetmanager-tablehead-lastmodified' => '{{Identical|Last modified}}',
 130+
 131+ # Validation error messages
 132+ 'gadget-validate-notset' => '$1 is the name of the property, e.g. settings.rights .',
 133+ 'gadget-validate-wrongtype' => '* $1 is the name of the property, e.g. settings.rights or module.messages[3].
 134+* $2 is the type that this property is expected to have
 135+* $3 is the type it actually had',
 136+
 137+ # For Special:GadgetManager
 138+ 'gadgetmanager-tablehead-lastmodified' => '{{Identical|Last modified}}
 139+{{Output|plain}}',
131140 'gadgetmanager-tablecell-lastmod' => 'This message is used on Special:GadgetManager to indicate the last modified date, time and user for gadget definitions.
132141 * $1 is a time and date (duplicated in $3 and $4)
133142 * $2 is a link to a user page with a user name as link text, followed by a series of related links
134143 * $3 is the date
135144 * $4 is the time
136145 * $5 is the user name which can be used with GENDER',
137 - 'gadget-validate-notset' => '$1 is the name of the property, e.g. settings.rights .',
138 - 'gadget-validate-wrongtype' => '* $1 is the name of the property, e.g. settings.rights or module.messages[3].
139 -* $2 is the type that this property is expected to have
140 -* $3 is the type it actually had',
 146+ 'gadgetmanager-comment-modify' => 'Edit summary used when editing definitions from [[Special:GadgetManager]].',
 147+
 148+ # User rights
 149+ 'right-gadgets-edit' => '{{doc-right}}',
 150+ 'right-gadgets-definition-create' => '{{doc-right}}',
 151+ 'right-gadgets-definition-delete' => '{{doc-right}}',
 152+ 'right-gadgets-definition-edit' => '{{doc-right}}',
141153 );
142154
143155 /** Afrikaans (Afrikaans)
Index: branches/RL2/extensions/Gadgets/Gadgets.php
@@ -166,12 +166,15 @@
167167 'jquery.ui.dialog',
168168 'mediawiki.Title',
169169 'jquery.createPropCloud',
 170+ 'jquery.json',
170171 ),
171172 'messages' => array(
172173 'gadgetmanager-editor-title',
173174 'gadgetmanager-editor-removeprop-tooltip',
174175 'gadgetmanager-editor-save',
175176 'gadgetmanager-editor-cancel',
 177+ 'gadgetmanager-propsgroup-settings',
 178+ 'gadgetmanager-propsgroup-module',
176179 'gadgetmanager-prop-scripts',
177180 'gadgetmanager-prop-styles',
178181 'gadgetmanager-prop-dependencies',
@@ -181,6 +184,7 @@
182185 'gadgetmanager-prop-default',
183186 'gadgetmanager-prop-hidden',
184187 'gadgetmanager-prop-shared',
 188+ 'gadgetmanager-comment-modify',
185189 ),
186190 ),
187191 );
Index: branches/RL2/extensions/Gadgets/modules/ext.gadgets.gadgetmanager.api.js
@@ -56,14 +56,15 @@
5757 * Get gadget blob from the API (or from cache if available).
5858 *
5959 * @param id {String} Gadget id.
60 - * @param callback {Function} To be called with an object as first argument,
61 - * and status as second argument (success or error).
 60+ * @param success {Function} To be called with the gadget object as first argument.
 61+ * @param error {Fucntion} If something went wrong (inexisting gadget, api
 62+ * error, request error), this is called with error code as first argument.
6263 * @return {jqXHR|Null}: Null if served from cache, otherwise the jqXHR.
6364 */
64 - getGadgetMetadata: function( id, callback ) {
 65+ getGadgetData: function( id, success, error ) {
6566 // Check cache
6667 if ( id in gadgetCache && gadgetCache[id] !== null ) {
67 - callback( objClone( gadgetCache[id] ), 'success' );
 68+ success( objClone( gadgetCache[id] ) );
6869 return null;
6970 }
7071 // Get from API if not cached
@@ -73,7 +74,7 @@
7475 format: 'json',
7576 action: 'query',
7677 list: 'gadgets',
77 - gaprop: 'id|metadata|desc',
 78+ gaprop: 'id|title|metadata|definitiontimestamp',
7879 gaids: id,
7980 galanguage: mw.config.get( 'wgUserLanguage' )
8081 },
@@ -81,27 +82,30 @@
8283 dataType: 'json',
8384 success: function( data ) {
8485 if ( data && data.query && data.query.gadgets && data.query.gadgets[0] ) {
85 - data = data.query.gadgets[0].metadata;
 86+ data = data.query.gadgets[0];
8687 // Update cache
8788 gadgetCache[id] = data;
88 - callback( objClone( data ), 'success' );
 89+ success( objClone( data ) );
8990 } else {
9091 // Invalidate cache
9192 gadgetCache[id] = null;
92 - callback( {}, 'error' );
 93+ if ( data && data.error ) {
 94+ error( data.error.code );
 95+ } else {
 96+ error( 'unknown' );
 97+ }
9398 }
9499 },
95100 error: function() {
96101 // Invalidate cache
97102 gadgetCache[id] = null;
98 - callback( {}, 'error' );
 103+ error( 'unknown' );
99104 }
100105 });
101106 },
102107
103108 /**
104 - * @param callback {Function} To be called with an array as first argument,
105 - * and status as second argument (success or error).
 109+ * @param callback {Function} To be called with an array as first argument.
106110 * @return {jqXHR|Null}: Null if served from cache, otherwise the jqXHR.
107111 */
108112 getGadgetCategories: function( callback ) {
@@ -133,13 +137,13 @@
134138 } else {
135139 // Invalidate cache
136140 gadgetCategoryCache = null;
137 - callback( [], 'error' );
 141+ callback( [] );
138142 }
139143 },
140144 error: function() {
141145 // Invalidate cache
142146 gadgetCategoryCache = null;
143 - callback( [], 'error' );
 147+ callback( [] );
144148 }
145149 });
146150 },
@@ -149,22 +153,56 @@
150154 *
151155 * @param gadget {Object}
152156 * - id {String} Id of the gadget to modify
153 - * - blob {Object} Gadget meta data
154 - * @param callback {Function} Called with two arguments:
155 - * - status ('ok' or 'error')
156 - * - msg (localized, something like "Successful", "Conflict occurred" etc.)
157 - * @return {jqXHR|Null}: Null if served from cache, otherwise the jqXHR.
 157+ * - metadata {Object} Gadget meta data
 158+ * @param o {Object} Additional options:
 159+ * - starttimestamp {String} ISO_8601 timestamp of when user started editing
 160+ * - success {Function} Called with one argument (API response object of the
 161+ * 'edit' action)
 162+ * - error {Function} Called with one argument (status from API if availabe,
 163+ * otherwise, if the request failed, 'unknown' is given)
 164+ * @return {jqXHR}
158165 */
159 - doModifyGadget: function( gadget, callback ) {
160 - mw.log( gadget );
161 - // @todo
162 - // Get token
163 - // JSON.stringify
164 - // Do with ApiEdit
165 - // Invalidate cache
166 - gadgetCache[gadget.id] = null;
167 - callback( 'error', '@todo: Saving not implemented yet. Check console for object that would be saved.' );
168 - return null;
 166+ doModifyGadget: function( gadget, o ) {
 167+ var t = new mw.Title(
 168+ gadget.id + '.js',
 169+ mw.config.get( 'wgNamespaceIds' ).gadget_definition
 170+ );
 171+ return $.ajax({
 172+ url: mw.util.wikiScript( 'api' ),
 173+ type: 'POST',
 174+ data: {
 175+ format: 'json',
 176+ action: 'edit',
 177+ title: t.getPrefixedDb(),
 178+ text: $.toJSON( gadget.metadata ),
 179+ summary: mw.msg( 'gadgetmanager-comment-modify', gadget.id ),
 180+ token: mw.user.tokens.get( 'editToken' ),
 181+ basetimestamp: gadget.definitiontimestamp,
 182+ starttimestamp: o.starttimestamp
 183+ },
 184+ dataType: 'json',
 185+ success: function( data ) {
 186+ // Invalidate cache
 187+ gadgetCache[gadget.id] = null;
 188+
 189+ if ( data && data.edit && data.edit ) {
 190+ if ( data.edit.result === 'Success' ) {
 191+ o.success( data.edit );
 192+ } else {
 193+ o.error( data.edit.result );
 194+ }
 195+ } else if ( data && data.error ) {
 196+ o.error( data.error.code );
 197+ } else {
 198+ o.error( 'unknown' );
 199+ }
 200+ },
 201+ error: function(){
 202+ // Invalidate cache
 203+ gadgetCache[gadget.id] = null;
 204+ o.error( 'unknown' );
 205+ }
 206+ });
169207 },
170208
171209 /**
@@ -172,14 +210,13 @@
173211 *
174212 * @param id {String} Id of the gadget to delete.
175213 * @param callback {Function} Called with one argument (ok', 'error' or 'conflict').
176 - * @return {jqXHR|Null}: Null if served from cache, otherwise the jqXHR.
 214+ * @return {jqXHR}
177215 */
178 - doDeleteGadget: function( id, callback ) {
179 - // @todo
180 - // Do with ApiDelete
 216+ doDeleteGadget: function( id, success, error ) {
 217+ // @todo ApiDelete
181218 // Invalidate cache
182219 gadgetCache[id] = null;
183 - callback( 'error' );
 220+ error( '@todo' );
184221 return null;
185222 }
186223 }
Index: branches/RL2/extensions/Gadgets/modules/ext.gadgets.gadgetmanager.ui.js
@@ -88,12 +88,35 @@
8989 /**
9090 * @var {Number} Maximum number of autocomplete suggestions in the gadget editor input fields.
9191 */
92 - suggestLimit = 7,
93 - /**
94 - * @var {Array} List of category objects with their name, localized title and member count.
95 - */
96 - gadgetCategoriesCache = [];
 92+ suggestLimit = 7;
9793
 94+ /* Local functions */
 95+
 96+ /**
 97+ * Utility function to pad a zero
 98+ * to single digit number. Used by ISODateString().
 99+ * @param n {Number}
 100+ * @return {String}
 101+ */
 102+ function pad( n ) {
 103+ return n < 10 ? '0' + n : n;
 104+ }
 105+ /**
 106+ * Format a date in an ISO 8601 format using UTC.
 107+ * https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date#Example:_ISO_8601_formatted_dates
 108+ *
 109+ * @param d {Date}
 110+ * @return {String}
 111+ */
 112+ function ISODateString( d ) {
 113+ return d.getUTCFullYear() + '-'
 114+ + pad( d.getUTCMonth() + 1 ) + '-'
 115+ + pad( d.getUTCDate() ) + 'T'
 116+ + pad( d.getUTCHours() ) + ':'
 117+ + pad( d.getUTCMinutes() ) + ':'
 118+ + pad( d.getUTCSeconds() ) + 'Z';
 119+ }
 120+
98121 /* Public functions */
99122
100123 gm.ui = {
@@ -106,13 +129,7 @@
107130 $( '.mw-gadgetmanager-gadgets .mw-gadgetmanager-gadgets-title a' )
108131 .click( function( e ) {
109132 e.preventDefault();
110 - var $el = $( this );
111 - var gadget = {
112 - id: $el.data( 'gadget-id' ),
113 - displayTitle: $el.text(),
114 - metadata: null
115 - };
116 - gm.ui.startGadgetEditor( gadget );
 133+ gm.ui.startGadgetEditor( $( this ).data( 'gadget-id' ) );
117134 });
118135 },
119136
@@ -120,55 +137,60 @@
121138 * Initialize the gadget editor dialog.
122139 *
123140 * @asynchronous
124 - * @param id {String}
125 - * @param displayTitle {String}
 141+ * @param gadgetId {String}
126142 */
127 - startGadgetEditor: function( gadget ) {
128 - // We need two things. Gadget meta-data and category information.
129 - var done = 0, ready = 2;
 143+ startGadgetEditor: function( gadgetId ) {
 144+ // Ad hoc multi-loader. We need both requests, which are asynchronous,
 145+ // to be complete. Which ever finishes first will set the local variable
 146+ // to it's return value for the other callback to use.
 147+ // @todo Notification: In case of an 'error'.
 148+ var gadget, cats;
130149
131 - gm.api.getGadgetMetadata( gadget.id, function( metadata, status ) {
132 - // @todo Notification: If status is 'error'
133 - gadget.metadata = metadata;
134 - done++;
135 - if ( done >= ready ) {
136 - gm.ui.showFancyForm( gadget );
 150+ gm.api.getGadgetCategories( function( ret ) {
 151+ if ( gadget ) {
 152+ // getGadgetData already done
 153+ return gm.ui.showFancyForm( gadget, ret );
137154 }
 155+ // getGadgetData not done yet, leave cats for it's callback to use
 156+ cats = ret;
138157 });
139158
140 - gm.api.getGadgetCategories( function( cats ) {
141 - gadgetCategoriesCache = cats;
142 - done++;
143 - if ( done >= ready ) {
144 - gm.ui.showFancyForm( gadget );
 159+ gm.api.getGadgetData( gadgetId, function( ret ) {
 160+ if ( cats ) {
 161+ // getGadgetCategories already done
 162+ return gm.ui.showFancyForm( ret, cats );
145163 }
 164+ // getGadgetCategories not done yet, leave gadget for it's callback to use
 165+ gadget = ret;
146166 });
147167 },
148168
149169 /**
150170 * Generate form, create a dialog and open it into view.
151171 *
152 - * @param gadget {Object}
 172+ * @param gadget {Object} Gadget object of the gadget to be modified.
 173+ * @param categories {Array} Gadget categories.
153174 * @return {jQuery} The (dialogged) form.
154175 */
155 - showFancyForm: function( gadget ) {
156 - var $form = gm.ui.getFancyForm( gadget.metadata );
157 - var buttons = {};
 176+ showFancyForm: function( gadget, categories ) {
 177+ var $form = gm.ui.getFancyForm( gadget.metadata, categories ),
 178+ buttons = {};
 179+
 180+ // Form submit
158181 buttons[mw.msg( 'gadgetmanager-editor-save' )] = function() {
159 - gm.api.doModifyGadget( gadget, function( status, msg ) {
160 - mw.log( "gm.api.doModifyGadget: status: ", status, "msg: ", + msg );
161 - /* @todo Notification
162 - addNotification( {
163 - msg: msg,
164 - type: status !== 'error' ? 'success' : status,
165 - timedActionDelay: 5,
166 - timedAction: function(){
167 - // refresh page
168 - }
169 - });
170 - */
 182+ gm.api.doModifyGadget( gadget, {
 183+ starttimestamp: ISODateString( new Date() ),
 184+ success: function( response ) {
 185+ $form.dialog( 'close' );
 186+ window.location.reload();
 187+ },
 188+ error: function( error ) {
 189+ mw.log( 'gm.api.doModifyGadget: error', error );
 190+ // @todo Notification: $formNotif.add( .. );
 191+ }
171192 });
172193 };
 194+
173195 return $form
174196 .dialog({
175197 autoOpen: true,
@@ -176,20 +198,14 @@
177199 modal: true,
178200 draggable: false,
179201 resizable: false,
180 - title: mw.message( 'gadgetmanager-editor-title', gadget.displayTitle ).escaped(),
 202+ title: mw.message( 'gadgetmanager-editor-title', gadget.title ).escaped(),
181203 buttons: buttons,
182204 open: function() {
183205 // Dialog is ready for action.
184206 // Push out any notifications if some were queued up already between
185207 // getting the gadget data and the display of the form.
186 - /* @todo Notification
187 - if ( gm.ui.notifications.length ) {
188 - for ( in ) {
189 - slice(i,1)_remove;
190 - gm.ui.addNotification( $form, n[i] );
191 - }
192 - }
193 - */
 208+
 209+ // @todo Notification: $formNotif.add( .. );
194210 }
195211 });
196212 },
@@ -200,9 +216,10 @@
201217 *
202218 * @param metadata {Object} Object to read and write to, used when saving
203219 * the gadget metadata back through the API.
 220+ * @param categories {Array} Gadget categories.
204221 * @return {jQuery} The form.
205222 */
206 - getFancyForm: function( metadata ) {
 223+ getFancyForm: function( metadata, categories ) {
207224 var nsGadgetId = mw.config.get( 'wgNamespaceIds' ).gadget,
208225 $form = $( tpl.fancyForm ).localize();
209226
@@ -337,8 +354,8 @@
338355 opts = '',
339356 i = 0,
340357 cat;
341 - for ( ; i < gadgetCategoriesCache.length; i++ ) {
342 - cat = gadgetCategoriesCache[i];
 358+ for ( ; i < categories.length; i++ ) {
 359+ cat = categories[i];
343360 opts += mw.html.element( 'option', {
344361 value: cat.name,
345362 selected: cat.name === current
Index: branches/RL2/extensions/Gadgets/modules/ext.gadgets.gadgetmanager.prejs.css
@@ -1,4 +1,7 @@
2 -.mw-gadgetmanager-gadgets.mw-datatable th,
 2+.mw-gadgetmanager-gadgets.mw-datatable th {
 3+ padding: 2px 21px 2px 5px;
 4+}
 5+
36 .mw-gadgetmanager-gadgets.mw-datatable td {
47 padding: 2px 5px;
58 }
Index: branches/RL2/extensions/Gadgets/modules/jquery.createPropCloud.js
@@ -70,15 +70,15 @@
7171 *
7272 * @context {jQuery}
7373 * @param o {Object} All optional
74 - * - prefix {String} Class name prefix
75 - * - props {Array} Array of properties to start with
76 - * - autocompleteSource {Function|Array} Source of autocomplete suggestions (required)
77 - * See also http://jqueryui.com/demos/autocomplete/#options (source)
78 - * - onAdd {Function} Callback for when an item is added.
79 - * Called with one argument (the value).
80 - * - onRemove {Function} Callback for when an item is removed.
81 - * Called with one argument (the value).
82 - * - removeTooltip {String} Tooltip for the remove-icon
 74+ * - prefix {String} Class name prefix
 75+ * - props {Array} Array of properties to start with
 76+ * - autocompleteSource {Function|Array} Source of autocomplete suggestions (required)
 77+ * See also http://jqueryui.com/demos/autocomplete/#options (source)
 78+ * - onAdd {Function} Callback for when an item is added.
 79+ * Called with one argument (the value).
 80+ * - onRemove {Function} Callback for when an item is removed.
 81+ * Called with one argument (the value).
 82+ * - removeTooltip {String} Tooltip for the remove-icon
8383 *
8484 * @return {jQuery} prop cloud (input field inside)
8585 */

Follow-up revisions

RevisionCommit summaryAuthorDate
r98789[RL2] Fix pleonastic comparison per r97104 CRkrinkle18:18, 3 October 2011

Comments

#Comment by Catrope (talk | contribs)   18:06, 3 October 2011
+						if ( data && data.edit && data.edit ) {

That's a bit pleonastic (WHY oh WHY does Firefox's dictionary not know about pleonastic? It's an awesome word!), maybe you meant data && data.edit && data.edit.result?

+	function ISODateString( d ) {

This is duplicated from somewhere in mw.loader, which also formats ISO 8601 timestamp. It should be factored out into a standalone module.

OK otherwise. Marking as such and adding todo for the ISO 8601 thing.

Status & tagging log