Index: branches/RL2/extensions/Gadgets/modules/jquery.createPropCloud.js |
— | — | @@ -2,18 +2,47 @@ |
3 | 3 | * jQuery PropCloud plugin |
4 | 4 | * @author Timo Tijhof, 2011 |
5 | 5 | */ |
6 | | -( function() { |
| 6 | +( function( $ ) { |
7 | 7 | |
| 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 | + */ |
8 | 32 | function newPropHtml( label, o ) { |
9 | | - return $( '<span class="' + o.prefix + 'prop"></span>' ) |
| 33 | + return $( '<span>' ).addClass( o.prefix + 'prop' ) |
10 | 34 | .append( |
11 | | - $( '<span class="' + o.prefix + 'prop-label"></span>' ).text( label ) |
| 35 | + $( '<span>' ).addClass( o.prefix + 'prop-label' ).text( label ) |
12 | 36 | ) |
13 | 37 | .append( |
14 | | - $( '<span class="' + o.prefix + 'prop-delete"></span> ') |
| 38 | + $( '<span>' ) |
| 39 | + .addClass( o.prefix + 'prop-delete' ) |
15 | 40 | .attr( 'title', o.removeTooltip ) |
16 | 41 | .click( function() { |
| 42 | + // Update UI |
17 | 43 | $(this).parent().remove(); |
| 44 | + // Update props |
| 45 | + arrayRemove( o.props, label ); |
| 46 | + // Callback |
18 | 47 | o.onRemove( label ); |
19 | 48 | } |
20 | 49 | ) |
— | — | @@ -27,7 +56,7 @@ |
28 | 57 | * |
29 | 58 | * <div class="editor-propcloud"> |
30 | 59 | * <div class="editor-propcontainer"> |
31 | | - * <span editor="jquery-prop"> |
| 60 | + * <span class="editor-prop"> |
32 | 61 | * <span class="editor-prop-label"> .. </span> |
33 | 62 | * <span class="editor-prop-delete" title="Remove this item"></span> |
34 | 63 | * </span> |
— | — | @@ -45,8 +74,10 @@ |
46 | 75 | * - props {Array} Array of properties to start with |
47 | 76 | * - autocompleteSource {Function|Array} Source of autocomplete suggestions (required) |
48 | 77 | * 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). |
51 | 82 | * - removeTooltip {String} Tooltip for the remove-icon |
52 | 83 | * |
53 | 84 | * @return {jQuery} prop cloud (input field inside) |
— | — | @@ -54,19 +85,18 @@ |
55 | 86 | $.fn.createPropCloud = function( o ) { |
56 | 87 | // Some defaults |
57 | 88 | o = $.extend({ |
58 | | - prefix: 'editor', |
| 89 | + prefix: 'editor-', |
59 | 90 | props: [], |
60 | 91 | autocompleteSource: [], |
61 | 92 | onAdd: function( prop ) {}, |
62 | 93 | onRemove: function( prop ) {}, |
63 | 94 | removeTooltip: 'Remove this item' |
64 | 95 | }, o ); |
65 | | - o.prefix = o.prefix + '-'; |
66 | 96 | |
67 | 97 | var $el = this.eq(0), |
68 | 98 | $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' ); |
71 | 101 | |
72 | 102 | // Append while container is still off the DOM |
73 | 103 | // This is faster and prevents visible build-up |
— | — | @@ -85,7 +115,11 @@ |
86 | 116 | |
87 | 117 | // Prevent duplicate values |
88 | 118 | if ( o.props.indexOf( val ) === -1 ) { |
| 119 | + // Update UI |
89 | 120 | $container.append( newPropHtml( val, o ) ); |
| 121 | + // Update props |
| 122 | + o.props.push( val ); |
| 123 | + // Callback for custom stuff |
90 | 124 | o.onAdd( val ); |
91 | 125 | } |
92 | 126 | |
— | — | @@ -104,4 +138,4 @@ |
105 | 139 | return $cloud; |
106 | 140 | }; |
107 | 141 | |
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 @@ |
6 | 6 | * @copyright © 2011 Timo Tijhof |
7 | 7 | * @license GNU General Public Licence 2.0 or later |
8 | 8 | */ |
9 | | -( function() { |
| 9 | +( function( $ ) { |
10 | 10 | |
11 | 11 | var |
12 | 12 | /** |
— | — | @@ -13,7 +13,8 @@ |
14 | 14 | */ |
15 | 15 | gadgetCache = {}, |
16 | 16 | /** |
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. */ |
18 | 19 | gadgetCategoryCache = null; |
19 | 20 | |
20 | 21 | /* Local functions */ |
— | — | @@ -184,4 +185,4 @@ |
185 | 186 | } |
186 | 187 | }; |
187 | 188 | |
188 | | -})(); |
| 189 | +})( jQuery ); |
Index: branches/RL2/extensions/Gadgets/modules/ext.gadgets.gadgetmanager.ui.js |
— | — | @@ -5,7 +5,7 @@ |
6 | 6 | * @copyright © 2011 Timo Tijhof |
7 | 7 | * @license GNU General Public Licence 2.0 or later |
8 | 8 | */ |
9 | | -( function() { |
| 9 | +( function( $ ) { |
10 | 10 | |
11 | 11 | var |
12 | 12 | /** |
— | — | @@ -94,25 +94,6 @@ |
95 | 95 | */ |
96 | 96 | gadgetCategoriesCache = []; |
97 | 97 | |
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 | | - |
117 | 98 | /* Public functions */ |
118 | 99 | |
119 | 100 | gm.ui = { |
— | — | @@ -175,7 +156,7 @@ |
176 | 157 | var buttons = {}; |
177 | 158 | buttons[mw.msg( 'gadgetmanager-editor-save' )] = function() { |
178 | 159 | 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 ); |
180 | 161 | /* @todo Notification |
181 | 162 | addNotification( { |
182 | 163 | msg: msg, |
— | — | @@ -243,10 +224,10 @@ |
244 | 225 | gpprefix: data.term |
245 | 226 | }, function( json ) { |
246 | 227 | 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 ) { |
248 | 230 | return val.pagename; |
249 | 231 | }); |
250 | | - suggestions = suggestions.splice( 0, suggestLimit ); |
251 | 232 | |
252 | 233 | // Update cache |
253 | 234 | suggestCacheScripts[data.term] = suggestions; |
— | — | @@ -258,10 +239,8 @@ |
259 | 240 | } |
260 | 241 | ); |
261 | 242 | }, |
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' ) |
266 | 245 | }); |
267 | 246 | |
268 | 247 | // Module properties: styles |
— | — | @@ -297,10 +276,8 @@ |
298 | 277 | } |
299 | 278 | ); |
300 | 279 | }, |
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' ) |
305 | 282 | }); |
306 | 283 | |
307 | 284 | // Module properties: dependencies |
— | — | @@ -313,10 +290,8 @@ |
314 | 291 | var output = $.ui.autocomplete.filter( suggestCacheDependencies, data.term ); |
315 | 292 | response( output.slice( 0, suggestLimit ) ); |
316 | 293 | }, |
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' ) |
321 | 296 | }); |
322 | 297 | |
323 | 298 | // Module properties: messages |
— | — | @@ -352,10 +327,8 @@ |
353 | 328 | } |
354 | 329 | ); |
355 | 330 | }, |
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' ) |
360 | 333 | }); |
361 | 334 | |
362 | 335 | // Gadget settings: category |
— | — | @@ -383,10 +356,8 @@ |
384 | 357 | var output = $.ui.autocomplete.filter( suggestCacheRights, data.term ); |
385 | 358 | response( output.slice( 0, suggestLimit ) ); |
386 | 359 | }, |
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' ) |
391 | 362 | }); |
392 | 363 | |
393 | 364 | // Gadget settings: Default |
— | — | @@ -414,4 +385,4 @@ |
415 | 386 | // Launch on document ready |
416 | 387 | $( document ).ready( gm.ui.initUI ); |
417 | 388 | |
418 | | -})(); |
| 389 | +})( jQuery ); |
Index: branches/RL2/extensions/Gadgets/SpecialGadgetManager.php |
— | — | @@ -96,7 +96,7 @@ |
97 | 97 | if ( $wgGadgetEnableSharing ) { |
98 | 98 | $html .= '<th>' . wfMessage( 'gadgetmanager-tablehead-shared' )->escaped() . '</th>'; |
99 | 99 | } |
100 | | - $html .= '<th>' . wfMessage( 'gadgetmanager-tablehead-lastmod' )->escaped() . '</tr>'; |
| 100 | + $html .= '<th>' . wfMessage( 'gadgetmanager-tablehead-lastmod' )->escaped() . '</th></tr>'; |
101 | 101 | |
102 | 102 | // Populate table rows for the current category |
103 | 103 | foreach ( $gadgets as $gadgetName => $gadget ) { |
— | — | @@ -130,7 +130,7 @@ |
131 | 131 | |
132 | 132 | // Last modified |
133 | 133 | $lastModText = ''; |
134 | | - $definitionTitle = Title::newFromText( $gadget->getName() . '.js', NS_GADGET_DEFINITION ); |
| 134 | + $definitionTitle = Title::makeTitleSafe( NS_GADGET_DEFINITION, $gadget->getName() . '.js' ); |
135 | 135 | if ( $definitionTitle ) { |
136 | 136 | $definitionRev = Revision::newFromTitle( $definitionTitle ); |
137 | 137 | if ( $definitionRev ) { |