r96759 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r96758‎ | r96759 | r96760 >
Date:23:38, 10 September 2011
Author:krinkle
Status:ok
Tags:
Comment:
[ResourceLoader2] Address issues raised in r96309 CR
* Ensure (partial) classname is escaped when generating HTML instead of requiring the input to be safe. Although the input is from developers (not from users), it's not obvious when calling the function that it requires escaping beforehand.
* Adding $ as first argument in the closure and calling it with jQuery
* Fix typo in the documentation
* Improve documentation (listing callback arguments)
* Wrote documentation for newPropHtml()
* Removed the automatic separation of the prefix with a dash. People can provide this themselves if wanted. A good default is given.
* Letting the plugin maintain the 'props' object, instead of leaving it up to the callback. This removes a lot of code duplication and removes the need for users to implement their own "arrayRemove"-function, moved this utility into the plugin.
* Calling .splice() before the looping over json.query.gadgetpages (since the array will become shorter, less items to loop over)
Modified paths:
  • /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.ui.js (modified) (history)
  • /branches/RL2/extensions/Gadgets/modules/jquery.createPropCloud.js (modified) (history)

Diff [purge]

Index: branches/RL2/extensions/Gadgets/modules/jquery.createPropCloud.js
@@ -2,18 +2,47 @@
33 * jQuery PropCloud plugin
44 * @author Timo Tijhof, 2011
55 */
6 -( function() {
 6+( function( $ ) {
77
 8+ /**
 9+ * Remove all occurences of a value from an array.
 10+ *
 11+ * @param arr {Array} Array to be changed
 12+ * @param val {Mixed} Value to be removed from the array
 13+ * @return {Array} May or may not be changed, reference kept
 14+ */
 15+ function arrayRemove( arr, val ) {
 16+ var i;
 17+ // Parentheses are crucial here. Without them, var i will be a
 18+ // boolean instead of a number, resulting in an infinite loop!
 19+ while ( ( i = arr.indexOf( val ) ) !== -1 ) {
 20+ arr.splice( i, 1 );
 21+ }
 22+ return arr;
 23+ }
 24+
 25+ /**
 26+ * Create prop-element for a given label.
 27+ *
 28+ * @param label {String}
 29+ * @param o {Object} $.fn.createPropCloud options object
 30+ * @return {jQuery} <span class="(prefix)prop"> .. </span>
 31+ */
832 function newPropHtml( label, o ) {
9 - return $( '<span class="' + o.prefix + 'prop"></span>' )
 33+ return $( '<span>' ).addClass( o.prefix + 'prop' )
1034 .append(
11 - $( '<span class="' + o.prefix + 'prop-label"></span>' ).text( label )
 35+ $( '<span>' ).addClass( o.prefix + 'prop-label' ).text( label )
1236 )
1337 .append(
14 - $( '<span class="' + o.prefix + 'prop-delete"></span> ')
 38+ $( '<span>' )
 39+ .addClass( o.prefix + 'prop-delete' )
1540 .attr( 'title', o.removeTooltip )
1641 .click( function() {
 42+ // Update UI
1743 $(this).parent().remove();
 44+ // Update props
 45+ arrayRemove( o.props, label );
 46+ // Callback
1847 o.onRemove( label );
1948 }
2049 )
@@ -27,7 +56,7 @@
2857 *
2958 * <div class="editor-propcloud">
3059 * <div class="editor-propcontainer">
31 - * <span editor="jquery-prop">
 60+ * <span class="editor-prop">
3261 * <span class="editor-prop-label"> .. </span>
3362 * <span class="editor-prop-delete" title="Remove this item"></span>
3463 * </span>
@@ -45,8 +74,10 @@
4675 * - props {Array} Array of properties to start with
4776 * - autocompleteSource {Function|Array} Source of autocomplete suggestions (required)
4877 * See also http://jqueryui.com/demos/autocomplete/#options (source)
49 - * - onAdd {Function} Callback when an item is added
50 - * - onRemove {Function} Callback when an item is deleted
 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).
5182 * - removeTooltip {String} Tooltip for the remove-icon
5283 *
5384 * @return {jQuery} prop cloud (input field inside)
@@ -54,19 +85,18 @@
5586 $.fn.createPropCloud = function( o ) {
5687 // Some defaults
5788 o = $.extend({
58 - prefix: 'editor',
 89+ prefix: 'editor-',
5990 props: [],
6091 autocompleteSource: [],
6192 onAdd: function( prop ) {},
6293 onRemove: function( prop ) {},
6394 removeTooltip: 'Remove this item'
6495 }, o );
65 - o.prefix = o.prefix + '-';
6696
6797 var $el = this.eq(0),
6898 $input = $el.addClass( o.prefix + 'propinput' ),
69 - $cloud = $input.wrap( '<div class="' + o.prefix + 'propcloud"></div>' ).parent(),
70 - $container = $( '<div class="' + o.prefix + 'propcontainer"></div>' );
 99+ $cloud = $input.wrap( '<div>' ).parent().addClass( o.prefix + 'propcloud' ),
 100+ $container = $( '<div>' ).addClass( o.prefix + 'propcontainer' );
71101
72102 // Append while container is still off the DOM
73103 // This is faster and prevents visible build-up
@@ -85,7 +115,11 @@
86116
87117 // Prevent duplicate values
88118 if ( o.props.indexOf( val ) === -1 ) {
 119+ // Update UI
89120 $container.append( newPropHtml( val, o ) );
 121+ // Update props
 122+ o.props.push( val );
 123+ // Callback for custom stuff
90124 o.onAdd( val );
91125 }
92126
@@ -104,4 +138,4 @@
105139 return $cloud;
106140 };
107141
108 -})();
\ No newline at end of file
 142+})( jQuery );
\ No newline at end of file
Index: branches/RL2/extensions/Gadgets/modules/ext.gadgets.gadgetmanager.api.js
@@ -5,7 +5,7 @@
66 * @copyright © 2011 Timo Tijhof
77 * @license GNU General Public Licence 2.0 or later
88 */
9 -( function() {
 9+( function( $ ) {
1010
1111 var
1212 /**
@@ -13,7 +13,8 @@
1414 */
1515 gadgetCache = {},
1616 /**
17 - * @var {Object|Null} If cache, object with category ids and the member counts */
 17+ * @var {Object} If cached, object keyed by category id with categormember-count as value.
 18+ * Set to null if there is no cache, yet, or when the cache is cleared. */
1819 gadgetCategoryCache = null;
1920
2021 /* Local functions */
@@ -184,4 +185,4 @@
185186 }
186187 };
187188
188 -})();
 189+})( jQuery );
Index: branches/RL2/extensions/Gadgets/modules/ext.gadgets.gadgetmanager.ui.js
@@ -5,7 +5,7 @@
66 * @copyright © 2011 Timo Tijhof
77 * @license GNU General Public Licence 2.0 or later
88 */
9 -( function() {
 9+( function( $ ) {
1010
1111 var
1212 /**
@@ -94,25 +94,6 @@
9595 */
9696 gadgetCategoriesCache = [];
9797
98 - /* Local functions */
99 -
100 - /**
101 - * Remove all occurences of a value from an array.
102 - *
103 - * @param arr {Array} Array to be changed
104 - * @param val {Mixed} Value to be removed from the array
105 - * @return {Array} May or may not be changed, reference kept
106 - */
107 - function arrayRemove( arr, val ) {
108 - var i;
109 - // Parentheses are crucial here. Without them, var i will be a
110 - // boolean instead of a number, resulting in an infinite loop!
111 - while ( ( i = arr.indexOf( val ) ) !== -1 ) {
112 - arr.splice( i, 1 );
113 - }
114 - return arr;
115 - }
116 -
11798 /* Public functions */
11899
119100 gm.ui = {
@@ -175,7 +156,7 @@
176157 var buttons = {};
177158 buttons[mw.msg( 'gadgetmanager-editor-save' )] = function() {
178159 gm.api.doModifyGadget( gadget, function( status, msg ) {
179 - alert( "Save result: \n- status: " + status + "\n- msg: " + msg );
 160+ mw.log( "gm.api.doModifyGadget: status: ", status, "msg: ", + msg );
180161 /* @todo Notification
181162 addNotification( {
182163 msg: msg,
@@ -243,10 +224,10 @@
244225 gpprefix: data.term
245226 }, function( json ) {
246227 if ( json && json.query && json.query.gadgetpages ) {
247 - var suggestions = $.map( json.query.gadgetpages, function( val, i ) {
 228+ var suggestions = json.query.gadgetpages.splice( 0, suggestLimit );
 229+ suggestions = $.map( suggestions, function( val, i ) {
248230 return val.pagename;
249231 });
250 - suggestions = suggestions.splice( 0, suggestLimit );
251232
252233 // Update cache
253234 suggestCacheScripts[data.term] = suggestions;
@@ -258,10 +239,8 @@
259240 }
260241 );
261242 },
262 - prefix: 'mw-gadgetmanager',
263 - removeTooltip: mw.msg( 'gadgetmanager-editor-removeprop-tooltip' ),
264 - onAdd: function( prop ) { metadata.module.scripts.push( prop ); },
265 - onRemove: function( prop ) { arrayRemove( metadata.module.scripts, prop ); }
 243+ prefix: 'mw-gadgetmanager-',
 244+ removeTooltip: mw.msg( 'gadgetmanager-editor-removeprop-tooltip' )
266245 });
267246
268247 // Module properties: styles
@@ -297,10 +276,8 @@
298277 }
299278 );
300279 },
301 - prefix: 'mw-gadgetmanager',
302 - removeTooltip: mw.msg( 'gadgetmanager-editor-removeprop-tooltip' ),
303 - onAdd: function( prop ) { metadata.module.styles.push( prop ); },
304 - onRemove: function( prop ) { arrayRemove( metadata.module.styles, prop ); }
 280+ prefix: 'mw-gadgetmanager-',
 281+ removeTooltip: mw.msg( 'gadgetmanager-editor-removeprop-tooltip' )
305282 });
306283
307284 // Module properties: dependencies
@@ -313,10 +290,8 @@
314291 var output = $.ui.autocomplete.filter( suggestCacheDependencies, data.term );
315292 response( output.slice( 0, suggestLimit ) );
316293 },
317 - prefix: 'mw-gadgetmanager',
318 - removeTooltip: mw.msg( 'gadgetmanager-editor-removeprop-tooltip' ),
319 - onAdd: function( prop ) { metadata.module.dependencies.push( prop ); },
320 - onRemove: function( prop ) { arrayRemove( metadata.module.dependencies, prop ); }
 294+ prefix: 'mw-gadgetmanager-',
 295+ removeTooltip: mw.msg( 'gadgetmanager-editor-removeprop-tooltip' )
321296 });
322297
323298 // Module properties: messages
@@ -352,10 +327,8 @@
353328 }
354329 );
355330 },
356 - prefix: 'mw-gadgetmanager',
357 - removeTooltip: mw.msg( 'gadgetmanager-editor-removeprop-tooltip' ),
358 - onAdd: function( prop ) { metadata.module.messages.push( prop ); },
359 - onRemove: function( prop ) { arrayRemove( metadata.module.messages, prop ); }
 331+ prefix: 'mw-gadgetmanager-',
 332+ removeTooltip: mw.msg( 'gadgetmanager-editor-removeprop-tooltip' )
360333 });
361334
362335 // Gadget settings: category
@@ -383,10 +356,8 @@
384357 var output = $.ui.autocomplete.filter( suggestCacheRights, data.term );
385358 response( output.slice( 0, suggestLimit ) );
386359 },
387 - prefix: 'mw-gadgetmanager',
388 - removeTooltip: mw.msg( 'gadgetmanager-editor-removeprop-tooltip' ),
389 - onAdd: function( prop ) { metadata.settings.rights.push( prop ); },
390 - onRemove: function( prop ) { arrayRemove( metadata.settings.rights, prop ); }
 360+ prefix: 'mw-gadgetmanager-',
 361+ removeTooltip: mw.msg( 'gadgetmanager-editor-removeprop-tooltip' )
391362 });
392363
393364 // Gadget settings: Default
@@ -414,4 +385,4 @@
415386 // Launch on document ready
416387 $( document ).ready( gm.ui.initUI );
417388
418 -})();
 389+})( jQuery );
Index: branches/RL2/extensions/Gadgets/SpecialGadgetManager.php
@@ -96,7 +96,7 @@
9797 if ( $wgGadgetEnableSharing ) {
9898 $html .= '<th>' . wfMessage( 'gadgetmanager-tablehead-shared' )->escaped() . '</th>';
9999 }
100 - $html .= '<th>' . wfMessage( 'gadgetmanager-tablehead-lastmod' )->escaped() . '</tr>';
 100+ $html .= '<th>' . wfMessage( 'gadgetmanager-tablehead-lastmod' )->escaped() . '</th></tr>';
101101
102102 // Populate table rows for the current category
103103 foreach ( $gadgets as $gadgetName => $gadget ) {
@@ -130,7 +130,7 @@
131131
132132 // Last modified
133133 $lastModText = '';
134 - $definitionTitle = Title::newFromText( $gadget->getName() . '.js', NS_GADGET_DEFINITION );
 134+ $definitionTitle = Title::makeTitleSafe( NS_GADGET_DEFINITION, $gadget->getName() . '.js' );
135135 if ( $definitionTitle ) {
136136 $definitionRev = Revision::newFromTitle( $definitionTitle );
137137 if ( $definitionRev ) {

Sign-offs

UserFlagDate
Nikerabbitinspected09:55, 11 September 2011

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r96309[ResourceLoader2] Gadget manager (start of ajax editor)...krinkle22:28, 5 September 2011

Status & tagging log