Index: trunk/extensions/Reviews/Reviews.php |
— | — | @@ -129,7 +129,7 @@ |
130 | 130 | 'reviews-submission-saving', |
131 | 131 | ), |
132 | 132 | 'dependencies' => array( |
133 | | - 'jquery.json', 'ext.reviews', 'jquery.ui.button', |
| 133 | + 'jquery.json', 'ext.reviews', 'jquery.ui.button', 'jquery.ui.stars', |
134 | 134 | ), |
135 | 135 | ); |
136 | 136 | |
— | — | @@ -142,6 +142,18 @@ |
143 | 143 | ), |
144 | 144 | ); |
145 | 145 | |
| 146 | +$wgResourceModules['jquery.ui.stars'] = $moduleTemplate + array( |
| 147 | + 'scripts' => array( |
| 148 | + 'jquery.ui.stars/jquery.ui.stars.js', |
| 149 | + ), |
| 150 | + 'styles' => array( |
| 151 | + 'jquery.ui.stars/jquery.ui.stars.css', |
| 152 | + ), |
| 153 | + 'dependencies' => array( |
| 154 | + 'jquery.ui.widget', |
| 155 | + ), |
| 156 | +); |
| 157 | + |
146 | 158 | unset( $moduleTemplate ); |
147 | 159 | |
148 | 160 | $egReviewsSettings = array(); |
Index: trunk/extensions/Reviews/resources/reviews.js |
— | — | @@ -8,6 +8,26 @@ |
9 | 9 | |
10 | 10 | window.reviews = new( function() { |
11 | 11 | |
| 12 | + this.htmlSelect = function( options, value, attributes, onChangeCallback ) { |
| 13 | + $select = $( '<select />' ).attr( attributes ); |
| 14 | + |
| 15 | + for ( message in options ) { |
| 16 | + if ( options.hasOwnProperty( message ) ) { |
| 17 | + var attribs = { 'value': options[message] }; |
| 18 | + |
| 19 | + if ( value === options[message] ) { |
| 20 | + attribs.selected = 'selected'; |
| 21 | + } |
| 22 | + |
| 23 | + $select.append( $( '<option />' ).text( message ).attr( attribs ) ); |
| 24 | + } |
| 25 | + } |
| 26 | + |
| 27 | + if ( typeof onChangeCallback !== 'undefined' ) { |
| 28 | + $select.change( function() { onChangeCallback( $( this ).val() ) } ); |
| 29 | + } |
| 30 | + |
| 31 | + return $select; |
| 32 | + }; |
12 | 33 | |
13 | | - |
14 | 34 | } )(); |
\ No newline at end of file |
Index: trunk/extensions/Reviews/resources/reviews.review.js |
— | — | @@ -25,7 +25,7 @@ |
26 | 26 | 'page_id': this.fields.page_id, |
27 | 27 | 'title': this.fields.title, |
28 | 28 | 'text': this.fields.text, |
29 | | - 'rating': 0, |
| 29 | + 'rating': this.fields.rating, |
30 | 30 | 'ratings': '{}' |
31 | 31 | }; |
32 | 32 | |
Index: trunk/extensions/Reviews/resources/jquery.ui.stars/jquery.ui.stars.js |
— | — | @@ -0,0 +1,316 @@ |
| 2 | +/*! |
| 3 | + * jQuery UI Stars v3.0.1 |
| 4 | + * http://plugins.jquery.com/project/Star_Rating_widget |
| 5 | + * |
| 6 | + * Copyright (c) 2010 Marek "Orkan" Zajac (orkans@gmail.com) |
| 7 | + * Dual licensed under the MIT and GPL licenses. |
| 8 | + * http://docs.jquery.com/License |
| 9 | + * |
| 10 | + * $Rev: 164 $ |
| 11 | + * $Date:: 2010-05-01 #$ |
| 12 | + * $Build: 35 (2010-05-01) |
| 13 | + * |
| 14 | + * Depends: |
| 15 | + * jquery.ui.core.js |
| 16 | + * jquery.ui.widget.js |
| 17 | + * |
| 18 | + */ |
| 19 | +(function($) { |
| 20 | + |
| 21 | +$.widget('ui.stars', { |
| 22 | + options: { |
| 23 | + inputType: 'radio', // [radio|select] |
| 24 | + split: 0, // decrease number of stars by splitting each star into pieces [2|3|4|...] |
| 25 | + disabled: false, // set to [true] to make the stars initially disabled |
| 26 | + cancelTitle: 'Cancel Rating', |
| 27 | + cancelValue: 0, // default value of Cancel btn. |
| 28 | + cancelShow: true, |
| 29 | + disableValue: true, // set to [false] to not disable the hidden input when Cancel btn is clicked, so the value will present in POST data. |
| 30 | + oneVoteOnly: false, |
| 31 | + showTitles: false, |
| 32 | + captionEl: null, // jQuery object - target for text captions |
| 33 | + callback: null, // function(ui, type, value, event) |
| 34 | + |
| 35 | + /* |
| 36 | + * CSS classes |
| 37 | + */ |
| 38 | + starWidth: 16, // width of the star image |
| 39 | + cancelClass: 'ui-stars-cancel', |
| 40 | + starClass: 'ui-stars-star', |
| 41 | + starOnClass: 'ui-stars-star-on', |
| 42 | + starHoverClass: 'ui-stars-star-hover', |
| 43 | + starDisabledClass: 'ui-stars-star-disabled', |
| 44 | + cancelHoverClass: 'ui-stars-cancel-hover', |
| 45 | + cancelDisabledClass: 'ui-stars-cancel-disabled' |
| 46 | + }, |
| 47 | + |
| 48 | + _create: function() { |
| 49 | + var self = this, o = this.options, starId = 0; |
| 50 | + this.element.data('former.stars', this.element.html()); |
| 51 | + |
| 52 | + o.isSelect = o.inputType == 'select'; |
| 53 | + this.$form = $(this.element).closest('form'); |
| 54 | + this.$selec = o.isSelect ? $('select', this.element) : null; |
| 55 | + this.$rboxs = o.isSelect ? $('option', this.$selec) : $(':radio', this.element); |
| 56 | + |
| 57 | + /* |
| 58 | + * Map all inputs from $rboxs array to Stars elements |
| 59 | + */ |
| 60 | + this.$stars = this.$rboxs.map(function(i) |
| 61 | + { |
| 62 | + var el = { |
| 63 | + value: this.value, |
| 64 | + title: (o.isSelect ? this.text : this.title) || this.value, |
| 65 | + isDefault: (o.isSelect && this.defaultSelected) || this.defaultChecked |
| 66 | + }; |
| 67 | + |
| 68 | + if(i==0) { |
| 69 | + o.split = typeof o.split != 'number' ? 0 : o.split; |
| 70 | + o.val2id = []; |
| 71 | + o.id2val = []; |
| 72 | + o.id2title = []; |
| 73 | + o.name = o.isSelect ? self.$selec.get(0).name : this.name; |
| 74 | + o.disabled = o.disabled || (o.isSelect ? $(self.$selec).attr('disabled') : $(this).attr('disabled')); |
| 75 | + } |
| 76 | + |
| 77 | + /* |
| 78 | + * Consider it as a Cancel button? |
| 79 | + */ |
| 80 | + if(el.value == o.cancelValue) { |
| 81 | + o.cancelTitle = el.title; |
| 82 | + return null; |
| 83 | + } |
| 84 | + |
| 85 | + o.val2id[el.value] = starId; |
| 86 | + o.id2val[starId] = el.value; |
| 87 | + o.id2title[starId] = el.title; |
| 88 | + |
| 89 | + if(el.isDefault) { |
| 90 | + o.checked = starId; |
| 91 | + o.value = o.defaultValue = el.value; |
| 92 | + o.title = el.title; |
| 93 | + } |
| 94 | + |
| 95 | + var $s = $('<div/>').addClass(o.starClass); |
| 96 | + var $a = $('<a/>').attr('title', o.showTitles ? el.title : '').text(el.value); |
| 97 | + |
| 98 | + /* |
| 99 | + * Prepare division settings |
| 100 | + */ |
| 101 | + if(o.split) { |
| 102 | + var oddeven = (starId % o.split); |
| 103 | + var stwidth = Math.floor(o.starWidth / o.split); |
| 104 | + $s.width(stwidth); |
| 105 | + $a.css('margin-left', '-' + (oddeven * stwidth) + 'px'); |
| 106 | + } |
| 107 | + |
| 108 | + starId++; |
| 109 | + return $s.append($a).get(0); |
| 110 | + }); |
| 111 | + |
| 112 | + /* |
| 113 | + * How many Stars? |
| 114 | + */ |
| 115 | + o.items = starId; |
| 116 | + |
| 117 | + /* |
| 118 | + * Remove old content |
| 119 | + */ |
| 120 | + o.isSelect ? this.$selec.remove() : this.$rboxs.remove(); |
| 121 | + |
| 122 | + /* |
| 123 | + * Append Stars interface |
| 124 | + */ |
| 125 | + this.$cancel = $('<div/>').addClass(o.cancelClass).append( $('<a/>').attr('title', o.showTitles ? o.cancelTitle : '').text(o.cancelValue) ); |
| 126 | + o.cancelShow &= !o.disabled && !o.oneVoteOnly; |
| 127 | + o.cancelShow && this.element.append(this.$cancel); |
| 128 | + this.element.append(this.$stars); |
| 129 | + |
| 130 | + /* |
| 131 | + * Initial selection |
| 132 | + */ |
| 133 | + if(o.checked === undefined) { |
| 134 | + o.checked = -1; |
| 135 | + o.value = o.defaultValue = o.cancelValue; |
| 136 | + o.title = ''; |
| 137 | + } |
| 138 | + |
| 139 | + /* |
| 140 | + * The only FORM element, that has been linked to the stars control. The value field is updated on each Star click event |
| 141 | + */ |
| 142 | + this.$value = $("<input type='hidden' name='"+o.name+"' value='"+o.value+"' />"); |
| 143 | + this.element.append(this.$value); |
| 144 | + |
| 145 | + |
| 146 | + /* |
| 147 | + * Attach stars event handler |
| 148 | + */ |
| 149 | + this.$stars.bind('click.stars', function(e) { |
| 150 | + if(!o.forceSelect && o.disabled) return false; |
| 151 | + |
| 152 | + var i = self.$stars.index(this); |
| 153 | + o.checked = i; |
| 154 | + o.value = o.id2val[i]; |
| 155 | + o.title = o.id2title[i]; |
| 156 | + self.$value.attr({disabled: o.disabled ? 'disabled' : '', value: o.value}); |
| 157 | + |
| 158 | + fillTo(i, false); |
| 159 | + self._disableCancel(); |
| 160 | + |
| 161 | + !o.forceSelect && self.callback(e, 'star'); |
| 162 | + }) |
| 163 | + .bind('mouseover.stars', function() { |
| 164 | + if(o.disabled) return false; |
| 165 | + var i = self.$stars.index(this); |
| 166 | + fillTo(i, true); |
| 167 | + }) |
| 168 | + .bind('mouseout.stars', function() { |
| 169 | + if(o.disabled) return false; |
| 170 | + fillTo(self.options.checked, false); |
| 171 | + }); |
| 172 | + |
| 173 | + |
| 174 | + /* |
| 175 | + * Attach cancel event handler |
| 176 | + */ |
| 177 | + this.$cancel.bind('click.stars', function(e) { |
| 178 | + if(!o.forceSelect && (o.disabled || o.value == o.cancelValue)) return false; |
| 179 | + |
| 180 | + o.checked = -1; |
| 181 | + o.value = o.cancelValue; |
| 182 | + o.title = ''; |
| 183 | + |
| 184 | + self.$value.val(o.value); |
| 185 | + o.disableValue && self.$value.attr({disabled: 'disabled'}); |
| 186 | + |
| 187 | + fillNone(); |
| 188 | + self._disableCancel(); |
| 189 | + |
| 190 | + !o.forceSelect && self.callback(e, 'cancel'); |
| 191 | + }) |
| 192 | + .bind('mouseover.stars', function() { |
| 193 | + if(self._disableCancel()) return false; |
| 194 | + self.$cancel.addClass(o.cancelHoverClass); |
| 195 | + fillNone(); |
| 196 | + self._showCap(o.cancelTitle); |
| 197 | + }) |
| 198 | + .bind('mouseout.stars', function() { |
| 199 | + if(self._disableCancel()) return false; |
| 200 | + self.$cancel.removeClass(o.cancelHoverClass); |
| 201 | + self.$stars.triggerHandler('mouseout.stars'); |
| 202 | + }); |
| 203 | + |
| 204 | + |
| 205 | + /* |
| 206 | + * Attach onReset event handler to the parent FORM |
| 207 | + */ |
| 208 | + this.$form.bind('reset.stars', function(){ |
| 209 | + !o.disabled && self.select(o.defaultValue); |
| 210 | + }); |
| 211 | + |
| 212 | + |
| 213 | + /* |
| 214 | + * Clean up to avoid memory leaks in certain versions of IE 6 |
| 215 | + */ |
| 216 | + $(window).unload(function(){ |
| 217 | + self.$cancel.unbind('.stars'); |
| 218 | + self.$stars.unbind('.stars'); |
| 219 | + self.$form.unbind('.stars'); |
| 220 | + self.$selec = self.$rboxs = self.$stars = self.$value = self.$cancel = self.$form = null; |
| 221 | + }); |
| 222 | + |
| 223 | + |
| 224 | + /* |
| 225 | + * Star selection helpers |
| 226 | + */ |
| 227 | + function fillTo(index, hover) { |
| 228 | + if(index != -1) { |
| 229 | + var addClass = hover ? o.starHoverClass : o.starOnClass; |
| 230 | + var remClass = hover ? o.starOnClass : o.starHoverClass; |
| 231 | + self.$stars.eq(index).prevAll('.' + o.starClass).andSelf().removeClass(remClass).addClass(addClass); |
| 232 | + self.$stars.eq(index).nextAll('.' + o.starClass).removeClass(o.starHoverClass + ' ' + o.starOnClass); |
| 233 | + self._showCap(o.id2title[index]); |
| 234 | + } |
| 235 | + else fillNone(); |
| 236 | + }; |
| 237 | + function fillNone() { |
| 238 | + self.$stars.removeClass(o.starOnClass + ' ' + o.starHoverClass); |
| 239 | + self._showCap(''); |
| 240 | + }; |
| 241 | + |
| 242 | + |
| 243 | + /* |
| 244 | + * Finally, set up the Stars |
| 245 | + */ |
| 246 | + this.select(o.value); |
| 247 | + o.disabled && this.disable(); |
| 248 | + |
| 249 | + }, |
| 250 | + |
| 251 | + /* |
| 252 | + * Private functions |
| 253 | + */ |
| 254 | + _disableCancel: function() { |
| 255 | + var o = this.options, disabled = o.disabled || o.oneVoteOnly || (o.value == o.cancelValue); |
| 256 | + if(disabled) this.$cancel.removeClass(o.cancelHoverClass).addClass(o.cancelDisabledClass); |
| 257 | + else this.$cancel.removeClass(o.cancelDisabledClass); |
| 258 | + this.$cancel.css('opacity', disabled ? 0.5 : 1); |
| 259 | + return disabled; |
| 260 | + }, |
| 261 | + _disableAll: function() { |
| 262 | + var o = this.options; |
| 263 | + this._disableCancel(); |
| 264 | + if(o.disabled) this.$stars.filter('div').addClass(o.starDisabledClass); |
| 265 | + else this.$stars.filter('div').removeClass(o.starDisabledClass); |
| 266 | + }, |
| 267 | + _showCap: function(s) { |
| 268 | + var o = this.options; |
| 269 | + if(o.captionEl) o.captionEl.text(s); |
| 270 | + }, |
| 271 | + |
| 272 | + /* |
| 273 | + * Public functions |
| 274 | + */ |
| 275 | + value: function() { |
| 276 | + return this.options.value; |
| 277 | + }, |
| 278 | + select: function(val) { |
| 279 | + var o = this.options, e = (val == o.cancelValue) ? this.$cancel : this.$stars.eq(o.val2id[val]); |
| 280 | + o.forceSelect = true; |
| 281 | + e.triggerHandler('click.stars'); |
| 282 | + o.forceSelect = false; |
| 283 | + }, |
| 284 | + selectID: function(id) { |
| 285 | + var o = this.options, e = (id == -1) ? this.$cancel : this.$stars.eq(id); |
| 286 | + o.forceSelect = true; |
| 287 | + e.triggerHandler('click.stars'); |
| 288 | + o.forceSelect = false; |
| 289 | + }, |
| 290 | + enable: function() { |
| 291 | + this.options.disabled = false; |
| 292 | + this._disableAll(); |
| 293 | + }, |
| 294 | + disable: function() { |
| 295 | + this.options.disabled = true; |
| 296 | + this._disableAll(); |
| 297 | + }, |
| 298 | + destroy: function() { |
| 299 | + this.$form.unbind('.stars'); |
| 300 | + this.$cancel.unbind('.stars').remove(); |
| 301 | + this.$stars.unbind('.stars').remove(); |
| 302 | + this.$value.remove(); |
| 303 | + this.element.unbind('.stars').html(this.element.data('former.stars')).removeData('stars'); |
| 304 | + return this; |
| 305 | + }, |
| 306 | + callback: function(e, type) { |
| 307 | + var o = this.options; |
| 308 | + o.callback && o.callback(this, type, o.value, e); |
| 309 | + o.oneVoteOnly && !o.disabled && this.disable(); |
| 310 | + } |
| 311 | +}); |
| 312 | + |
| 313 | +$.extend($.ui.stars, { |
| 314 | + version: '3.0.1' |
| 315 | +}); |
| 316 | + |
| 317 | +})(jQuery); |
Index: trunk/extensions/Reviews/resources/jquery.ui.stars/jquery.ui.stars.gif |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/extensions/Reviews/resources/jquery.ui.stars/jquery.ui.stars.gif |
___________________________________________________________________ |
Added: svn:mime-type |
1 | 318 | + application/octet-stream |
Index: trunk/extensions/Reviews/resources/jquery.ui.stars/jquery.ui.stars.css |
— | — | @@ -0,0 +1,45 @@ |
| 2 | +/*! |
| 3 | + * jQuery UI Stars v3.0.1 |
| 4 | + * http://plugins.jquery.com/project/Star_Rating_widget |
| 5 | + * |
| 6 | + * Copyright (c) 2010 Marek "Orkan" Zajac (orkans@gmail.com) |
| 7 | + * Dual licensed under the MIT and GPL licenses. |
| 8 | + * http://docs.jquery.com/License |
| 9 | + * |
| 10 | + * $Rev: 164 $ |
| 11 | + * $Date:: 2010-05-01 #$ |
| 12 | + * $Build: 35 (2010-05-01) |
| 13 | + * |
| 14 | + */ |
| 15 | +.ui-stars-star, |
| 16 | +.ui-stars-cancel { |
| 17 | + float: left; |
| 18 | + display: block; |
| 19 | + overflow: hidden; |
| 20 | + text-indent: -999em; |
| 21 | + cursor: pointer; |
| 22 | +} |
| 23 | +.ui-stars-star a, |
| 24 | +.ui-stars-cancel a { |
| 25 | + width: 16px; |
| 26 | + height: 15px; |
| 27 | + display: block; |
| 28 | + background: url(jquery.ui.stars.gif) no-repeat 0 0; |
| 29 | +} |
| 30 | +.ui-stars-star a { |
| 31 | + background-position: 0 -32px; |
| 32 | +} |
| 33 | +.ui-stars-star-on a { |
| 34 | + background-position: 0 -48px; |
| 35 | +} |
| 36 | +.ui-stars-star-hover a { |
| 37 | + background-position: 0 -64px; |
| 38 | +} |
| 39 | +.ui-stars-cancel-hover a { |
| 40 | + background-position: 0 -16px; |
| 41 | +} |
| 42 | +.ui-stars-star-disabled, |
| 43 | +.ui-stars-star-disabled a, |
| 44 | +.ui-stars-cancel-disabled a { |
| 45 | + cursor: default !important; |
| 46 | +} |
Index: trunk/extensions/Reviews/resources/jquery.reviewControl.js |
— | — | @@ -19,19 +19,27 @@ |
20 | 20 | this.titleInput = null; |
21 | 21 | |
22 | 22 | this.fieldName = function( name ) { |
23 | | - return 'review-' + ( this.review.fields.id === false ? 'new' : this.review.fields.id ) + '-' + name; |
| 23 | + return 'review-' + ( typeof this.review.fields.id === 'undefined' ? 'new' : this.review.fields.id ) + '-' + name; |
24 | 24 | }; |
25 | 25 | |
26 | 26 | this.buildInterface = function() { |
27 | | - this.titleInput = $( '<input />' ).attr( { |
| 27 | + this.titleInput = $( '<input />' ).attr( { |
28 | 28 | 'type': 'text', |
29 | 29 | 'size': 45, |
30 | 30 | 'name': this.fieldName( 'title' ) |
31 | 31 | } ).val( this.review.fields.title ); |
32 | 32 | |
33 | | - this.textInput = $( '<textarea />' ).attr( { |
| 33 | + this.textInput = $( '<textarea />' ).attr( { |
34 | 34 | 'name': this.fieldName( 'text' ) |
35 | 35 | } ).text( this.review.fields.text ); |
| 36 | + |
| 37 | + this.ratingInput = reviews.htmlSelect( |
| 38 | + { 1: 1, 2: 2, 3: 3, 4: 4, 5: 5 }, // TODO |
| 39 | + this.review.fields.rating, |
| 40 | + { 'name': this.fieldName( 'rating' ), 'id': this.fieldName( 'rating' ) } |
| 41 | + ); |
| 42 | + |
| 43 | + this.ratingInput = $( '<div />' ).attr( 'id', this.fieldName( 'ratingdiv' ) ).html( this.ratingInput ); |
36 | 44 | |
37 | 45 | this.button = $( '<button />' ) |
38 | 46 | .button( { 'label': mw.msg( 'reviews-submission-submit' ) } ) |
— | — | @@ -40,7 +48,15 @@ |
41 | 49 | } ); |
42 | 50 | |
43 | 51 | $this.html( '' ); |
44 | | - $this.append( this.titleInput, this.textInput, this.button ); |
| 52 | + $this.append( this.titleInput, this.textInput, this.ratingInput, this.button ); |
| 53 | + |
| 54 | + this.ratingInput.stars( { |
| 55 | + inputType: 'select', |
| 56 | + cancelShow: false, |
| 57 | + callback: function(ui, type, value) { |
| 58 | + _this.review.fields.rating = parseInt( value ); |
| 59 | + } |
| 60 | + } ); |
45 | 61 | }; |
46 | 62 | |
47 | 63 | this.setup = function() { |
Index: trunk/extensions/Reviews/README |
— | — | @@ -21,9 +21,12 @@ |
22 | 22 | === jQuery UI === |
23 | 23 | |
24 | 24 | This extension uses code from the jQuery UI library. |
25 | | -jQuery is dual licensed under the MIT [0] and GPL [1] licenses. |
| 25 | +jQuery UI is dual licensed under the MIT [0] and GPL [1] licenses. |
26 | 26 | |
| 27 | +=== jQuery UI stars === |
27 | 28 | |
| 29 | +This extension uses the jQuery UI stars plugin Copyright © Orkan 2008-2011. |
| 30 | +jQuery UI stars is dual licensed under the MIT [0] and GPL [1] licenses. |
28 | 31 | |
29 | 32 | [0] http://www.opensource.org/licenses/mit-license.php |
30 | 33 | [1] http://www.opensource.org/licenses/gpl-license.php |