Index: trunk/extensions/ArticleAssessmentPilot/Makefile |
— | — | @@ -1,39 +0,0 @@ |
2 | | -# |
3 | | -# Handy makefile to combine and minify css and javascript files |
4 | | -# |
5 | | -SHELL := /bin/bash |
6 | | - |
7 | | -JS := \ |
8 | | - js/ArticleAssessment.js\ |
9 | | - js/jquery.cookie.js\ |
10 | | - js/jquery.stars.js\ |
11 | | - js/jquery.tipsy.js |
12 | | - |
13 | | -all: \ |
14 | | - js/ArticleAssessment.combined.min.js |
15 | | - |
16 | | - |
17 | | -# JavaScript Combination |
18 | | -js/ArticleAssessment.combined.js: $(JS) |
19 | | - cat $(JS) > js/ArticleAssessment.combined.js |
20 | | - |
21 | | -# JavaScript Minification |
22 | | - |
23 | | -js/ArticleAssessment.combined.min.js: js/ArticleAssessment.combined.js jsmin |
24 | | - if [ -e ./jsmin ]; then ./jsmin < js/ArticleAssessment.combined.js > js/ArticleAssessment.combined.min.js;\ |
25 | | - else jsmin < js/ArticleAssessment.combined.js > js/ArticleAssessment.combined.min.js; fi |
26 | | - |
27 | | -# JSMin - For more info on JSMin, see: http://www.crockford.com/javascript/jsmin.html |
28 | | - |
29 | | -jsmin: |
30 | | - type -P jsmin &>/dev/null || ( wget http://www.crockford.com/javascript/jsmin.c; gcc jsmin.c -o jsmin ) |
31 | | - |
32 | | -# Actions |
33 | | - |
34 | | -distclean: clean |
35 | | - rm -rf jsmin |
36 | | - rm -rf jsmin.c |
37 | | - |
38 | | -clean: |
39 | | - rm -f js/ArticleAssessment.combined.* |
40 | | - |
Index: trunk/extensions/ArticleAssessmentPilot/modules/jquery.tipsy/jquery.tipsy.js |
— | — | @@ -0,0 +1,202 @@ |
| 2 | +// tipsy, facebook style tooltips for jquery |
| 3 | +// version 1.0.0a |
| 4 | +// (c) 2008-2010 jason frame [jason@onehackoranother.com] |
| 5 | +// released under the MIT license |
| 6 | + |
| 7 | +(function($) { |
| 8 | + |
| 9 | + function Tipsy(element, options) { |
| 10 | + this.$element = $(element); |
| 11 | + this.options = options; |
| 12 | + this.enabled = true; |
| 13 | + this.fixTitle(); |
| 14 | + } |
| 15 | + |
| 16 | + Tipsy.prototype = { |
| 17 | + show: function() { |
| 18 | + var title = this.getTitle(); |
| 19 | + if (title && this.enabled) { |
| 20 | + var $tip = this.tip(); |
| 21 | + |
| 22 | + $tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title); |
| 23 | + $tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity |
| 24 | + $tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).appendTo(document.body); |
| 25 | + |
| 26 | + var pos = $.extend({}, this.$element.offset(), { |
| 27 | + width: this.$element[0].offsetWidth, |
| 28 | + height: this.$element[0].offsetHeight |
| 29 | + }); |
| 30 | + |
| 31 | + var actualWidth = $tip[0].offsetWidth, actualHeight = $tip[0].offsetHeight; |
| 32 | + var gravity = (typeof this.options.gravity == 'function') |
| 33 | + ? this.options.gravity.call(this.$element[0]) |
| 34 | + : this.options.gravity; |
| 35 | + |
| 36 | + var tp; |
| 37 | + switch (gravity.charAt(0)) { |
| 38 | + case 'n': |
| 39 | + tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2}; |
| 40 | + break; |
| 41 | + case 's': |
| 42 | + tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2}; |
| 43 | + break; |
| 44 | + case 'e': |
| 45 | + tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset}; |
| 46 | + break; |
| 47 | + case 'w': |
| 48 | + tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset}; |
| 49 | + break; |
| 50 | + } |
| 51 | + |
| 52 | + if (gravity.length == 2) { |
| 53 | + if (gravity.charAt(1) == 'w') { |
| 54 | + tp.left = pos.left + pos.width / 2 - 15; |
| 55 | + } else { |
| 56 | + tp.left = pos.left + pos.width / 2 - actualWidth + 15; |
| 57 | + } |
| 58 | + } |
| 59 | + |
| 60 | + $tip.css(tp).addClass('tipsy-' + gravity); |
| 61 | + |
| 62 | + if (this.options.fade) { |
| 63 | + $tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity}); |
| 64 | + } else { |
| 65 | + $tip.css({visibility: 'visible', opacity: this.options.opacity}); |
| 66 | + } |
| 67 | + } |
| 68 | + }, |
| 69 | + |
| 70 | + hide: function() { |
| 71 | + if (this.options.fade) { |
| 72 | + this.tip().stop().fadeOut(function() { $(this).remove(); }); |
| 73 | + } else { |
| 74 | + this.tip().remove(); |
| 75 | + } |
| 76 | + }, |
| 77 | + |
| 78 | + fixTitle: function() { |
| 79 | + var $e = this.$element; |
| 80 | + if ($e.attr('title') || typeof($e.attr('original-title')) != 'string') { |
| 81 | + $e.attr('original-title', $e.attr('title') || '').removeAttr('title'); |
| 82 | + } |
| 83 | + }, |
| 84 | + |
| 85 | + getTitle: function() { |
| 86 | + var title, $e = this.$element, o = this.options; |
| 87 | + this.fixTitle(); |
| 88 | + var title, o = this.options; |
| 89 | + if (typeof o.title == 'string') { |
| 90 | + title = $e.attr(o.title == 'title' ? 'original-title' : o.title); |
| 91 | + } else if (typeof o.title == 'function') { |
| 92 | + title = o.title.call($e[0]); |
| 93 | + } |
| 94 | + title = ('' + title).replace(/(^\s*|\s*$)/, ""); |
| 95 | + return title || o.fallback; |
| 96 | + }, |
| 97 | + |
| 98 | + tip: function() { |
| 99 | + if (!this.$tip) { |
| 100 | + this.$tip = $('<div class="tipsy"></div>').html('<div class="tipsy-arrow"></div><div class="tipsy-inner"></div>'); |
| 101 | + } |
| 102 | + return this.$tip; |
| 103 | + }, |
| 104 | + |
| 105 | + validate: function() { |
| 106 | + if (!this.$element[0].parentNode) { |
| 107 | + this.hide(); |
| 108 | + this.$element = null; |
| 109 | + this.options = null; |
| 110 | + } |
| 111 | + }, |
| 112 | + |
| 113 | + enable: function() { this.enabled = true; }, |
| 114 | + disable: function() { this.enabled = false; }, |
| 115 | + toggleEnabled: function() { this.enabled = !this.enabled; } |
| 116 | + }; |
| 117 | + |
| 118 | + $.fn.tipsy = function(options) { |
| 119 | + |
| 120 | + if (options === true) { |
| 121 | + return this.data('tipsy'); |
| 122 | + } else if (typeof options == 'string') { |
| 123 | + var tipsy = this.data('tipsy'); |
| 124 | + if (tipsy) tipsy[options](); |
| 125 | + return this; |
| 126 | + } |
| 127 | + |
| 128 | + options = $.extend({}, $.fn.tipsy.defaults, options); |
| 129 | + |
| 130 | + function get(ele) { |
| 131 | + var tipsy = $.data(ele, 'tipsy'); |
| 132 | + if (!tipsy) { |
| 133 | + tipsy = new Tipsy(ele, $.fn.tipsy.elementOptions(ele, options)); |
| 134 | + $.data(ele, 'tipsy', tipsy); |
| 135 | + } |
| 136 | + return tipsy; |
| 137 | + } |
| 138 | + |
| 139 | + function enter() { |
| 140 | + var tipsy = get(this); |
| 141 | + tipsy.hoverState = 'in'; |
| 142 | + if (options.delayIn == 0) { |
| 143 | + tipsy.show(); |
| 144 | + } else { |
| 145 | + tipsy.fixTitle(); |
| 146 | + setTimeout(function() { if (tipsy.hoverState == 'in') tipsy.show(); }, options.delayIn); |
| 147 | + } |
| 148 | + }; |
| 149 | + |
| 150 | + function leave() { |
| 151 | + var tipsy = get(this); |
| 152 | + tipsy.hoverState = 'out'; |
| 153 | + if (options.delayOut == 0) { |
| 154 | + tipsy.hide(); |
| 155 | + } else { |
| 156 | + setTimeout(function() { if (tipsy.hoverState == 'out') tipsy.hide(); }, options.delayOut); |
| 157 | + } |
| 158 | + }; |
| 159 | + |
| 160 | + if (!options.live) this.each(function() { get(this); }); |
| 161 | + |
| 162 | + if (options.trigger != 'manual') { |
| 163 | + var binder = options.live ? 'live' : 'bind', |
| 164 | + eventIn = options.trigger == 'hover' ? 'mouseenter' : 'focus', |
| 165 | + eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur'; |
| 166 | + this[binder](eventIn, enter)[binder](eventOut, leave); |
| 167 | + } |
| 168 | + |
| 169 | + return this; |
| 170 | + |
| 171 | + }; |
| 172 | + |
| 173 | + $.fn.tipsy.defaults = { |
| 174 | + delayIn: 0, |
| 175 | + delayOut: 0, |
| 176 | + fade: false, |
| 177 | + fallback: '', |
| 178 | + gravity: 'n', |
| 179 | + html: false, |
| 180 | + live: false, |
| 181 | + offset: 0, |
| 182 | + opacity: 0.8, |
| 183 | + title: 'title', |
| 184 | + trigger: 'hover' |
| 185 | + }; |
| 186 | + |
| 187 | + // Overwrite this method to provide options on a per-element basis. |
| 188 | + // For example, you could store the gravity in a 'tipsy-gravity' attribute: |
| 189 | + // return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' }); |
| 190 | + // (remember - do not modify 'options' in place!) |
| 191 | + $.fn.tipsy.elementOptions = function(ele, options) { |
| 192 | + return $.metadata ? $.extend({}, options, $(ele).metadata()) : options; |
| 193 | + }; |
| 194 | + |
| 195 | + $.fn.tipsy.autoNS = function() { |
| 196 | + return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n'; |
| 197 | + }; |
| 198 | + |
| 199 | + $.fn.tipsy.autoWE = function() { |
| 200 | + return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w'; |
| 201 | + }; |
| 202 | + |
| 203 | +})(jQuery); |
Property changes on: trunk/extensions/ArticleAssessmentPilot/modules/jquery.tipsy/jquery.tipsy.js |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 204 | + native |
Index: trunk/extensions/ArticleAssessmentPilot/modules/jquery.tipsy/images/tipsy.gif |
Cannot display: file marked as a binary type. |
svn:mime-type = image/gif |
Property changes on: trunk/extensions/ArticleAssessmentPilot/modules/jquery.tipsy/images/tipsy.gif |
___________________________________________________________________ |
Added: svn:mime-type |
2 | 205 | + image/gif |
Index: trunk/extensions/ArticleAssessmentPilot/modules/jquery.tipsy/images/arrow.gif |
Cannot display: file marked as a binary type. |
svn:mime-type = image/gif |
Property changes on: trunk/extensions/ArticleAssessmentPilot/modules/jquery.tipsy/images/arrow.gif |
___________________________________________________________________ |
Added: svn:mime-type |
3 | 206 | + image/gif |
Index: trunk/extensions/ArticleAssessmentPilot/modules/ext.articleAssessment/ext.articleAssessment.css |
— | — | @@ -0,0 +1,242 @@ |
| 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 | +.article-assessment-wrapper .ui-stars-star { |
| 16 | + float: left; |
| 17 | + display: block; |
| 18 | + overflow: hidden; |
| 19 | + text-indent: -999em; |
| 20 | + cursor: pointer; |
| 21 | + padding-right: 4px; |
| 22 | +} |
| 23 | +.article-assessment-wrapper .ui-stars-star a { |
| 24 | + width: 21px; |
| 25 | + height: 21px; |
| 26 | + line-height: 0; |
| 27 | + display: block; |
| 28 | + background: url(../images/stars.gif) no-repeat 0 0; |
| 29 | +} |
| 30 | +.article-assessment-wrapper .ui-stars-star a { |
| 31 | + background-position: 0 0px; |
| 32 | +} |
| 33 | + |
| 34 | +.article-assessment-wrapper .ui-stars-star-on a { |
| 35 | + background-position: 0 -21px; |
| 36 | +} |
| 37 | +.article-assessment-wrapper .ui-stars-star-rated a { |
| 38 | + background-position: 0 -42px; |
| 39 | +} |
| 40 | +.article-assessment-wrapper .ui-stars-star-stale a { |
| 41 | + background-position: 0 -63px; |
| 42 | +} |
| 43 | +.article-assessment-wrapper .ui-stars-star-hover a { |
| 44 | + background-position: 0 -21px; |
| 45 | +} |
| 46 | +.article-assessment-wrapper .ui-stars-star-disabled, |
| 47 | +.article-assessment-wrapper .ui-stars-star-disabled a { |
| 48 | + cursor: default !important; |
| 49 | +} |
| 50 | +.article-assessment-wrapper .ui-stars-cancel { |
| 51 | + display: none; |
| 52 | +} |
| 53 | +/* End ui-stars styles */ |
| 54 | + |
| 55 | +/* Tipsy Styles */ |
| 56 | +.tipsy { padding: 5px 5px 10px; font-size: 12px; position: absolute; z-index: 100000; overflow: visible; } |
| 57 | +.tipsy-inner { padding: 5px 8px 4px 8px; background-color: #d6f3ff; color: black; border: 1px solid #5dc9f4; max-width: 300px; text-align: left; } |
| 58 | +.tipsy-arrow { position: absolute; background: url( '../images/arrow.gif' ) no-repeat top left; width: 13px; height: 13px; } |
| 59 | +.tipsy-se .tipsy-arrow { bottom: -2px; right: 10px; background-position: 0% 100%; } |
| 60 | + |
| 61 | +/* End Tipsy styles */ |
| 62 | +.article-assessment-wrapper #article-assessment-rate, |
| 63 | +.article-assessment-wrapper #article-assessment-ratings { |
| 64 | + background: #f7f7f7; |
| 65 | + float: left; |
| 66 | +} |
| 67 | + |
| 68 | +.article-assessment-wrapper #article-assessment-rate { |
| 69 | + width: 650px; |
| 70 | + margin-right: 10px; |
| 71 | +} |
| 72 | +.article-assessment-wrapper legend { |
| 73 | + font-weight: bold; |
| 74 | +} |
| 75 | +.article-assessment-wrapper .field-wrapper { |
| 76 | + float: left; |
| 77 | + width: 270px; |
| 78 | + padding-right: 28px; |
| 79 | +} |
| 80 | +.article-assessment-wrapper .rating-field { |
| 81 | + float: right; |
| 82 | + width: 125px; |
| 83 | + line-height: 24px; |
| 84 | + padding-right: 5px; |
| 85 | +} |
| 86 | +.article-assessment-wrapper .rating-field-label{ |
| 87 | + float: left; |
| 88 | + font-weight: bold; |
| 89 | + line-height: 24px; |
| 90 | +} |
| 91 | +.article-assessment-wrapper .rating-field-label { |
| 92 | + margin-right: 10px; |
| 93 | +} |
| 94 | +.article-assessment-wrapper .rating-field-hint { |
| 95 | + width: 11px; |
| 96 | + height: 24px; |
| 97 | + display: block; |
| 98 | + float: right; |
| 99 | + background: url(../images/question.gif) 0 50% no-repeat; |
| 100 | +} |
| 101 | +.article-assessment-wrapper .rating-field-hint:hover { |
| 102 | + background: url(../images/question-hover.gif) 0 50% no-repeat; |
| 103 | +} |
| 104 | + |
| 105 | +.article-assessment-wrapper .article-assessment-flash { |
| 106 | + float: left; |
| 107 | + font-size: 11px; |
| 108 | + padding: 1px 5px; |
| 109 | + width: 560px; |
| 110 | + text-align: left; |
| 111 | + display: block; |
| 112 | +} |
| 113 | +.article-assessment-wrapper .article-assessment-stale-msg { |
| 114 | + background: #d6f3ff; |
| 115 | + border: 2px solid #5dc9f4; |
| 116 | +} |
| 117 | +.article-assessment-wrapper .article-assessment-success-msg { |
| 118 | + background: #e8e8e8; |
| 119 | + border: 2px solid #006505; |
| 120 | +} |
| 121 | +.article-assessment-wrapper .article-assessment-error-msg { |
| 122 | + background: #e8e8e8; |
| 123 | + border: 2px solid #a91100; |
| 124 | +} |
| 125 | +.article-assessment-wrapper .article-assessment-rating-field-name { |
| 126 | + float: left; |
| 127 | + width: 110px; |
| 128 | + font-weight: bold; |
| 129 | + font-size: 11px; |
| 130 | +} |
| 131 | +.article-assessment-wrapper .article-assessment-rating-field-value-wrapper { |
| 132 | + background: url( ../images/rating_bg.gif ) 0 0 no-repeat; |
| 133 | + width: 120px; |
| 134 | + height: 13px; |
| 135 | + display: block; |
| 136 | + float: left; |
| 137 | + padding: 2px; |
| 138 | + text-indent: -9999px; |
| 139 | + margin-top: 4px; |
| 140 | +} |
| 141 | +.article-assessment-wrapper .article-assessment-rate-instructions, |
| 142 | +.article-assessment-wrapper .article-assessment-rate-feedback, |
| 143 | +.article-assessment-wrapper .article-assessment-show-ratings, |
| 144 | +.article-assessment-wrapper .article-assessment-hide-ratings { |
| 145 | + font-size: 11px; |
| 146 | + font-style: italic; |
| 147 | +} |
| 148 | +.article-assessment-wrapper .article-assessment-rate-instructions { |
| 149 | + float: left; |
| 150 | +} |
| 151 | +.article-assessment-wrapper .article-assessment-rate-feedback { |
| 152 | + float: right; |
| 153 | +} |
| 154 | +.article-assessment-wrapper .article-assessment-rating-field-value-wrapper .article-assessment-rating-field-value { |
| 155 | + background: url( ../images/rating_bar.gif ) 0 0 no-repeat; |
| 156 | + height: 9px; |
| 157 | + float: right; |
| 158 | + display: block; |
| 159 | +} |
| 160 | +.article-assessment-wrapper .article-assessment-rating-fields { |
| 161 | + margin: 8px 0; |
| 162 | +} |
| 163 | +.article-assessment-wrapper .article-assessment-rating-fields .field-wrapper { |
| 164 | + margin-bottom: 5px; |
| 165 | +} |
| 166 | +.article-assessment-rating-count { |
| 167 | + font-size: 11px; |
| 168 | + margin-left: 5px; |
| 169 | + float: left; |
| 170 | +} |
| 171 | +.article-assessment-submit input { |
| 172 | + margin: 2px 0; |
| 173 | + float: right; |
| 174 | +} |
| 175 | +.article-assessment-wrapper .article-assessment-ratings-disabled .article-assessment-rating-field-value-wrapper { |
| 176 | + background: url( ../images/rating_disabled_bg.gif ) 0 0 no-repeat; |
| 177 | +} |
| 178 | +.article-assessment-wrapper .article-assessment-ratings-disabled .article-assessment-rating-field-value { |
| 179 | + display: none; |
| 180 | +} |
| 181 | +.article-assessment-wrapper .article-assessment-ratings-disabled .article-assessment-rating-count { |
| 182 | + visibility: hidden; |
| 183 | + |
| 184 | +} |
| 185 | +.article-assessment-wrapper .article-assessment-ratings-disabled .article-assessment-rating-field-name { |
| 186 | + color: #9f9f9f; |
| 187 | +} |
| 188 | + |
| 189 | +/* Simple Survey Dialog Styling */ |
| 190 | +#article-assessment-dialog.loading { |
| 191 | + display: block; |
| 192 | + height: 24px; |
| 193 | + width: 24px; |
| 194 | + background: url( ../images/loading.gif ) center no-repeat; |
| 195 | + text-indent: -9999px; |
| 196 | + margin: 0 auto; |
| 197 | +} |
| 198 | +#article-assessment-dialog textarea { |
| 199 | + margin-left: -2em; |
| 200 | + padding-right: 2em; |
| 201 | +} |
| 202 | +.article-assessment-error-msg { |
| 203 | + padding: 20px 0; |
| 204 | +} |
| 205 | + |
| 206 | + |
| 207 | +/* Self Clearing Floats */ |
| 208 | +.article-assessment-wrapper .article-assessment-information:after, |
| 209 | +.article-assessment-wrapper .field-wrapper:after, |
| 210 | +.article-assessment-wrapper .article-assessment-rating-fields:after, |
| 211 | +.article-assessment-rating:after, |
| 212 | +.article-assessment-wrapper .article-assessment-submit:after, |
| 213 | +.article-assessment-wrapper .rating-fields:after { |
| 214 | + content: "."; |
| 215 | + display: block; |
| 216 | + height: 0; |
| 217 | + clear: both; |
| 218 | + visibility: hidden; |
| 219 | +} |
| 220 | +.article-assessment-wrapper .field-wrapper, |
| 221 | +.article-assessment-wrapper .article-assessment-information, |
| 222 | +.article-assessment-wrapper .article-assessment-rating-fields, |
| 223 | +.article-assessment-rating, |
| 224 | +.article-assessment-wrapper .article-assessment-submit, |
| 225 | +.article-assessment-wrapper .rating-fields { |
| 226 | + display: inline-block; |
| 227 | +} |
| 228 | +* html .article-assessment-wrapper .field-wrapper, |
| 229 | +* html .article-assessment-wrapper .article-assessment-information, |
| 230 | +* html .article-assessment-wrapper .article-assessment-rating-fields, |
| 231 | +* html .article-assessment-rating, |
| 232 | +* html .article-assessment-wrapper .article-assessment-submit, |
| 233 | +* html .article-assessment-wrapper .rating-fields { |
| 234 | + height: 1%; |
| 235 | +} |
| 236 | +.article-assessment-wrapper .field-wrapper, |
| 237 | +.article-assessment-wrapper .article-assessment-information, |
| 238 | +.article-assessment-wrapper .article-assessment-rating-fields, |
| 239 | +.article-assessment-rating, |
| 240 | +.article-assessment-wrapper .article-assessment-submit, |
| 241 | +.article-assessment-wrapper .rating-fields { |
| 242 | + display: block; |
| 243 | +} |
\ No newline at end of file |
Property changes on: trunk/extensions/ArticleAssessmentPilot/modules/ext.articleAssessment/ext.articleAssessment.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 244 | + native |
Index: trunk/extensions/ArticleAssessmentPilot/modules/ext.articleAssessment/ext.articleAssessment.js |
— | — | @@ -0,0 +1,536 @@ |
| 2 | +( function( $ ) { |
| 3 | + $.ArticleAssessment = { |
| 4 | + 'config': { |
| 5 | + 'authtoken': '', |
| 6 | + 'userID': '', |
| 7 | + 'pageID': wgArticleId, |
| 8 | + 'revID': wgCurRevisionId |
| 9 | + }, |
| 10 | + 'messages': {}, |
| 11 | + 'settings': { |
| 12 | + 'endpoint': wgScriptPath + '/api.php?', |
| 13 | + 'fieldMessages' : [ |
| 14 | + 'wellsourced', |
| 15 | + 'neutrality', |
| 16 | + 'completeness', |
| 17 | + 'readability' |
| 18 | + ], |
| 19 | + 'fieldHintSuffix': '-tooltip', |
| 20 | + 'fieldPrefix': 'articleassessment-rating-', |
| 21 | + 'fieldHTML': '<div class="field-wrapper"> \ |
| 22 | + <label class="rating-field-label"></label> \ |
| 23 | + <select class="rating-field"> \ |
| 24 | + <option value="1">1</option> \ |
| 25 | + <option value="2">2</option> \ |
| 26 | + <option value="3">3</option> \ |
| 27 | + <option value="4">4</option> \ |
| 28 | + <option value="5">5</option> \ |
| 29 | + </select> \ |
| 30 | + </div>', |
| 31 | + 'structureHTML': '<div class="article-assessment-wrapper nonopopups"> \ |
| 32 | + <form action="rate" method="post" id="article-assessment"> \ |
| 33 | + <fieldset id="article-assessment-rate"> \ |
| 34 | + <legend></legend> \ |
| 35 | + <div class="article-assessment-information"> \ |
| 36 | + <span class="article-assessment-rate-instructions"></span> \ |
| 37 | + <span class="article-assessment-rate-feedback"></span> \ |
| 38 | + </div> \ |
| 39 | + <div class="article-assessment-rating-fields"></div> \ |
| 40 | + <div class="article-assessment-submit"> \ |
| 41 | + <input type="submit" value="Submit" /> \ |
| 42 | + </div> \ |
| 43 | + </fieldset> \ |
| 44 | + <fieldset id="article-assessment-ratings"> \ |
| 45 | + <legend></legend> \ |
| 46 | + <div class="article-assessment-information"> \ |
| 47 | + <span class="article-assessment-show-ratings"></span> \ |
| 48 | + <span class="article-assessment-hide-ratings"></span> \ |
| 49 | + </div> \ |
| 50 | + </fieldset> \ |
| 51 | + </form> \ |
| 52 | + </div>', |
| 53 | + 'ratingHTML': '<div class="article-assessment-rating"> \ |
| 54 | + <span class="article-assessment-rating-field-name"></span> \ |
| 55 | + <span class="article-assessment-rating-field-value-wrapper"> \ |
| 56 | + <span class="article-assessment-rating-field-value">0%</span> \ |
| 57 | + </span> \ |
| 58 | + <span class="article-assessment-rating-count"></span> \ |
| 59 | + </div>' |
| 60 | + }, |
| 61 | + |
| 62 | + 'fn' : { |
| 63 | + 'init': function( $$options ) { |
| 64 | + // merge options with the config |
| 65 | + var settings = $.extend( {}, $.ArticleAssessment.settings, $$options ); |
| 66 | + var config = $.ArticleAssessment.config; |
| 67 | + // if this is an anon user, get a unique identifier for them |
| 68 | + // load up the stored ratings and update the markup if the cookie exists |
| 69 | + var userToken = $.cookie( 'mwArticleAssessmentUserToken' ); |
| 70 | + if ( typeof userToken == 'undefined' || userToken == null ) { |
| 71 | + function randomString( string_length ) { |
| 72 | + var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz"; |
| 73 | + var randomstring = ''; |
| 74 | + for ( var i = 0; i < string_length; i++ ) { |
| 75 | + var rnum = Math.floor( Math.random() * chars.length ); |
| 76 | + randomstring += chars.substring( rnum, rnum + 1 ); |
| 77 | + } |
| 78 | + return randomstring; |
| 79 | + } |
| 80 | + userToken = randomString( 32 ); |
| 81 | + $.cookie( 'mwArticleAssessmentUserToken', userToken, { 'expires': 30, 'path': '/' } ); |
| 82 | + } |
| 83 | + if ( !wgUserName ) { |
| 84 | + config.userID = userToken; |
| 85 | + } |
| 86 | + // setup our markup using the template variables in settings |
| 87 | + var $structure = $( settings.structureHTML ), |
| 88 | + instructions = $.ArticleAssessment.fn.getMsg( 'articleassessment-pleaserate' ), |
| 89 | + feedback = $.ArticleAssessment.fn.getMsg( 'articleassessment-featurefeedback' ), |
| 90 | + yourfeedback = $.ArticleAssessment.fn.getMsg( 'articleassessment-yourfeedback'), |
| 91 | + articlerating = $.ArticleAssessment.fn.getMsg( 'articleassessment-articlerating' ), |
| 92 | + resultshide = $.ArticleAssessment.fn.getMsg( 'articleassessment-results-hide' ), |
| 93 | + resultsshow = $.ArticleAssessment.fn.getMsg( 'articleassessment-results-show' ); |
| 94 | + submitbutton = $.ArticleAssessment.fn.getMsg( 'articleassessment-submit' ); |
| 95 | + $structure |
| 96 | + .find( '#article-assessment-rate legend' ) |
| 97 | + .html( yourfeedback ) |
| 98 | + .end() |
| 99 | + .find( '.article-assessment-rate-instructions' ) |
| 100 | + .html( instructions ) |
| 101 | + .end() |
| 102 | + .find( '.article-assessment-rate-feedback' ) |
| 103 | + .html( feedback ) |
| 104 | + .find( '.feedbacklink' ) |
| 105 | + .wrap( '<a href="#"></a>' ) |
| 106 | + .parent() |
| 107 | + .click( $.ArticleAssessment.fn.showFeedback ) |
| 108 | + .end() |
| 109 | + .end() |
| 110 | + .end() |
| 111 | + .find( '#article-assessment-ratings legend' ) |
| 112 | + .html( articlerating ) |
| 113 | + .end() |
| 114 | + .find( '.article-assessment-show-ratings' ) |
| 115 | + .html( resultsshow ) |
| 116 | + .find( '.showlink' ) |
| 117 | + .wrap( '<a href="#"></a>' ) |
| 118 | + .parent() |
| 119 | + .click( $.ArticleAssessment.fn.showRatings ) |
| 120 | + .end() |
| 121 | + .end() |
| 122 | + .end() |
| 123 | + .find( '.article-assessment-hide-ratings' ) |
| 124 | + .html( resultshide ) |
| 125 | + .find ( '.hidelink' ) |
| 126 | + .wrap( '<a href="#"></a>' ) |
| 127 | + .parent() |
| 128 | + .click( $.ArticleAssessment.fn.hideRatings ) |
| 129 | + .end() |
| 130 | + .end() |
| 131 | + .end() |
| 132 | + .find( '.article-assessment-submit input' ) |
| 133 | + .val( submitbutton ) |
| 134 | + .end(); |
| 135 | + // hide the feedback link if we need to |
| 136 | + if( $.cookie( 'mwArticleAssessmentHideFeedbackLink' ) ) { |
| 137 | + $structure |
| 138 | + .find( '.article-assessment-rate-feedback' ) |
| 139 | + .hide(); |
| 140 | + } |
| 141 | + for ( var i = 0; i < settings.fieldMessages.length; i++ ) { |
| 142 | + var $field = $( settings.fieldHTML ), |
| 143 | + $rating = $( settings.ratingHTML ), |
| 144 | + label = $.ArticleAssessment.fn.getMsg( settings.fieldPrefix + settings.fieldMessages[i] ), |
| 145 | + field = settings.fieldMessages[i], |
| 146 | + hint = $.ArticleAssessment.fn.getMsg( settings.fieldPrefix + settings.fieldMessages[i] + settings.fieldHintSuffix ), |
| 147 | + count = $.ArticleAssessment.fn.getMsg( 'articleassessment-noratings', [0, 0] ); |
| 148 | + // initialize the field html |
| 149 | + $field |
| 150 | + .attr( 'id', 'articleassessment-rate-' + field ) |
| 151 | + .find( 'label' ) |
| 152 | + .attr( 'for', 'rating_' + field ) |
| 153 | + .attr( 'original-title', hint ) |
| 154 | + .html( label ) |
| 155 | + .end() |
| 156 | + .find( 'select' ) |
| 157 | + .attr( 'id', 'rating_' + field ) |
| 158 | + .attr( 'name', 'rating[' + field + ']' ); |
| 159 | + // initialize the rating html |
| 160 | + $rating |
| 161 | + .attr( 'id', 'articleassessment-rating-' + field ) |
| 162 | + .find( '.article-assessment-rating-field-name' ) |
| 163 | + .html( label ) |
| 164 | + .end() |
| 165 | + .find( '.article-assessment-rating-count' ) |
| 166 | + .html( count ); |
| 167 | + // append the field and rating html |
| 168 | + $structure |
| 169 | + .find( '.article-assessment-rating-fields' ) |
| 170 | + .append( $field ) |
| 171 | + .end() |
| 172 | + .find( '#article-assessment-ratings' ) |
| 173 | + .append( $rating ); |
| 174 | + } |
| 175 | + // store our settings and configuration for later |
| 176 | + $structure.find( '#article-assessment' ).data( 'articleAssessment-context', { 'settings': settings, 'config': config } ); |
| 177 | + $( '#catlinks' ).before( $structure ); |
| 178 | + // Hide the ratings initially |
| 179 | + $.ArticleAssessment.fn.hideRatings(); |
| 180 | + |
| 181 | + |
| 182 | + // set the height of our smaller fieldset to match the taller |
| 183 | + if ( $( '#article-assessment-rate' ).height() > $( '#article-assessment-ratings' ).height() ) { |
| 184 | + $( '#article-assessment-ratings' ).css( 'minHeight', $( '#article-assessment-rate' ).height() ); |
| 185 | + } else { |
| 186 | + $( '#article-assessment-rate' ).css( 'minHeight', $( '#article-assessment-ratings' ).height() ); |
| 187 | + } |
| 188 | + // attempt to fetch the ratings |
| 189 | + $.ArticleAssessment.fn.getRatingData(); |
| 190 | + |
| 191 | + // initialize the star plugin |
| 192 | + $( '.rating-field' ).each( function() { |
| 193 | + $( this ) |
| 194 | + .wrapAll( '<div class="rating-field"></div>' ) |
| 195 | + .parent() |
| 196 | + .stars( { |
| 197 | + inputType: 'select', |
| 198 | + callback: function( value, link ) { |
| 199 | + // remove any stale or rated classes |
| 200 | + value.$stars.each( function() { |
| 201 | + $( this ) |
| 202 | + .removeClass( 'ui-stars-star-stale' ) |
| 203 | + .removeClass( 'ui-stars-star-rated' ); |
| 204 | + // enable our submit button if it's still disabled |
| 205 | + $( '#article-assessment input:disabled' ).removeAttr( 'disabled' ); |
| 206 | + } ); |
| 207 | + } |
| 208 | + } ); |
| 209 | + }); |
| 210 | + // intialize the tooltips |
| 211 | + $( '.field-wrapper label[original-title]' ).each( function() { |
| 212 | + $( this ) |
| 213 | + .after( $( '<span class="rating-field-hint" />' ) |
| 214 | + .attr( 'original-title', $( this ).attr( 'original-title' ) ) |
| 215 | + .tipsy( { gravity : 'se', opacity: '0.9' } ) ); |
| 216 | + } ); |
| 217 | + // bind submit event to the form |
| 218 | + $( '#article-assessment' ) |
| 219 | + .submit( function() { $.ArticleAssessment.fn.submitRating(); return false; } ); |
| 220 | + // prevent the submit button for being active until all ratings are filled out |
| 221 | + $( '#article-assessment input[type=submit]' ) |
| 222 | + .attr( 'disabled', 'disabled' ); |
| 223 | + }, |
| 224 | + 'showRatings': function() { |
| 225 | + $( '#article-assessment-ratings' ) |
| 226 | + .removeClass( 'article-assessment-ratings-disabled' ) |
| 227 | + .find( '.article-assessment-show-ratings' ) |
| 228 | + .hide() |
| 229 | + .end() |
| 230 | + .find( '.article-assessment-hide-ratings' ) |
| 231 | + .show(); |
| 232 | + return false; |
| 233 | + }, |
| 234 | + 'hideRatings': function() { |
| 235 | + $( '#article-assessment-ratings' ) |
| 236 | + .addClass( 'article-assessment-ratings-disabled' ) |
| 237 | + .find( '.article-assessment-hide-ratings' ) |
| 238 | + .hide() |
| 239 | + .end() |
| 240 | + .find( '.article-assessment-show-ratings' ) |
| 241 | + .show(); |
| 242 | + return false; |
| 243 | + |
| 244 | + }, |
| 245 | + |
| 246 | + // Request the ratings data for the current article |
| 247 | + 'getRatingData': function() { |
| 248 | + var config = $( '#article-assessment' ).data( 'articleAssessment-context' ).config; |
| 249 | + var requestData = { |
| 250 | + 'action': 'query', |
| 251 | + 'list': 'articleassessment', |
| 252 | + 'aapageid': config.pageID, |
| 253 | + 'aauserrating': 1, |
| 254 | + 'format': 'json' |
| 255 | + } |
| 256 | + if ( config.userID.length == 32 ) { |
| 257 | + requestData.aaanontoken = config.userID; |
| 258 | + } |
| 259 | + |
| 260 | + var request = $.ajax( { |
| 261 | + url: wgScriptPath + '/api.php', |
| 262 | + data: requestData, |
| 263 | + dataType: 'json', |
| 264 | + success: $.ArticleAssessment.fn.afterGetRatingData, |
| 265 | + error: function( XMLHttpRequest, textStatus, errorThrown ) { |
| 266 | + $.ArticleAssessment.fn.flashNotice( $.ArticleAssessment.fn.getMsg( 'articleassessment-error' ), |
| 267 | + { 'class': 'article-assessment-error-msg' } ); |
| 268 | + } |
| 269 | + } ); |
| 270 | + }, |
| 271 | + 'afterGetRatingData' : function( data ) { |
| 272 | + var settings = $( '#article-assessment' ).data( 'articleAssessment-context' ).settings, |
| 273 | + userHasRated = false; |
| 274 | + // add the correct data to the markup |
| 275 | + if ( typeof data.query != 'undefined' && typeof data.query.articleassessment != 'undefined' && |
| 276 | + typeof data.query.articleassessment[0] != 'undefined' ) { |
| 277 | + for ( var r in data.query.articleassessment[0].ratings ) { |
| 278 | + var rating = data.query.articleassessment[0].ratings[r], |
| 279 | + $rating = $( '#' + rating.ratingdesc ), |
| 280 | + count = rating.count, |
| 281 | + total = ( rating.total / count ).toFixed( 1 ), |
| 282 | + label = $.ArticleAssessment.fn.getMsg( 'articleassessment-noratings', [total, count] ); |
| 283 | + $rating |
| 284 | + .find( '.article-assessment-rating-field-value' ) |
| 285 | + .text( total ) |
| 286 | + .end() |
| 287 | + .find( '.article-assessment-rating-count' ) |
| 288 | + .html( label ); |
| 289 | + if( rating.userrating ) { |
| 290 | + userHasRated = true; |
| 291 | + // this user rated. Word. Show them their ratings |
| 292 | + var $rateControl = $( '#' + rating.ratingdesc.replace( 'rating', 'rate' ) + ' .rating-field' ); |
| 293 | + $rateControl.stars( 'select', rating.userrating ); |
| 294 | + } |
| 295 | + } |
| 296 | + // show the ratings if the user has rated |
| 297 | + if( userHasRated ) { |
| 298 | + $.ArticleAssessment.fn.showRatings(); |
| 299 | + } |
| 300 | + // if the rating is more than 5 revisions old, mark it as stale |
| 301 | + if ( typeof data.query.articleassessment[0].stale != 'undefined' ) { |
| 302 | + // add the stale star class to each on star |
| 303 | + $( '.ui-stars-star-on' ) |
| 304 | + .addClass( 'ui-stars-star-stale' ); |
| 305 | + // add the stale message |
| 306 | + var msg = $.ArticleAssessment.fn.getMsg( 'articleassessment-stalemessage-norevisioncount' ); |
| 307 | + $.ArticleAssessment.fn.flashNotice( msg, { 'class': 'article-assessment-stale-msg' } ); |
| 308 | + } else { |
| 309 | + // if it's not a stale rating, we want to make the stars blue |
| 310 | + $( '.ui-stars-star-on' ).addClass( 'ui-stars-star-rated' ); |
| 311 | + } |
| 312 | + } |
| 313 | + // initialize the ratings |
| 314 | + $( '.article-assessment-rating-field-value' ).each( function() { |
| 315 | + $( this ) |
| 316 | + .css( { |
| 317 | + 'width': 120 - ( 120 * ( parseFloat( $( this ).text() ) / 5 ) ) + 'px' |
| 318 | + } ) |
| 319 | + } ); |
| 320 | + }, |
| 321 | + 'submitRating': function() { |
| 322 | + var config = $( '#article-assessment' ).data( 'articleAssessment-context' ).config; |
| 323 | + // clear out the stale message |
| 324 | + $.ArticleAssessment.fn.flashNotice( ); |
| 325 | + |
| 326 | + // lock the star inputs & submit |
| 327 | + $( '.rating-field' ).stars( 'disable' ); |
| 328 | + $( '#article-assessment input' ).attr( 'disabled', 'disabled' ); |
| 329 | + // get our results for submitting |
| 330 | + var results = {}; |
| 331 | + $( '.rating-field input' ).each( function() { |
| 332 | + // expects the hidden inputs to have names like 'rating[field-name]' which we use to |
| 333 | + // be transparent about what values we're sending to the server |
| 334 | + var fieldName = $( this ).attr( 'name' ).match( /\[([a-zA-Z0-9\-]*)\]/ )[1]; |
| 335 | + results[ fieldName ] = $( this ).val(); |
| 336 | + } ); |
| 337 | + var request = $.ajax( { |
| 338 | + url: wgScriptPath + '/api.php', |
| 339 | + type: 'POST', |
| 340 | + data: { |
| 341 | + 'action': 'articleassessment', |
| 342 | + 'revid': config.revID, |
| 343 | + 'pageid': config.pageID, |
| 344 | + 'r1' : results['wellsourced'], |
| 345 | + 'r2' : results['neutrality'], |
| 346 | + 'r3' : results['completeness'], |
| 347 | + 'r4' : results['readability'], |
| 348 | + 'anontoken': config.userID, |
| 349 | + 'format': 'json' |
| 350 | + }, |
| 351 | + dataType: 'json', |
| 352 | + success: $.ArticleAssessment.fn.afterSubmitRating, |
| 353 | + error: function( XMLHttpRequest, textStatus, errorThrown ) { |
| 354 | + $.ArticleAssessment.fn.flashNotice( $.ArticleAssessment.fn.getMsg( 'articleassessment-error' ), |
| 355 | + { 'class': 'article-assessment-error-msg' } ); |
| 356 | + } |
| 357 | + } ); |
| 358 | + }, |
| 359 | + 'afterSubmitRating': function ( data ) { |
| 360 | + // update the ratings |
| 361 | + $.ArticleAssessment.fn.getRatingData(); |
| 362 | + // set the stars to rated status |
| 363 | + $( '.ui-stars-star-on' ).addClass( 'ui-stars-star-rated' ); |
| 364 | + // unlock the stars & submit |
| 365 | + $( '.rating-field' ).stars( 'enable' ); |
| 366 | + $( '#article-assessment input:disabled' ).removeAttr( 'disabled' ); |
| 367 | + // update the results |
| 368 | + |
| 369 | + // show the results |
| 370 | + $.ArticleAssessment.fn.showRatings(); |
| 371 | + // say thank you |
| 372 | + $.ArticleAssessment.fn.flashNotice( $.ArticleAssessment.fn.getMsg( 'articleassessment-thanks' ), |
| 373 | + { 'class': 'article-assessment-success-msg' } ); |
| 374 | + }, |
| 375 | + // places a message on the interface |
| 376 | + 'flashNotice': function( text, options ) { |
| 377 | + if ( arguments.length == 0 ) { |
| 378 | + // clear existing messages, but don't add a new one |
| 379 | + $( '#article-assessment .article-assessment-flash' ).remove(); |
| 380 | + } else { |
| 381 | + // clear and add a new message |
| 382 | + $( '#article-assessment .article-assessment-flash' ).remove(); |
| 383 | + var className = options['class']; |
| 384 | + // create our new message |
| 385 | + $msg = $( '<div />' ) |
| 386 | + .addClass( 'article-assessment-flash' ) |
| 387 | + .html( text ); |
| 388 | + // if the class option was passed, add it |
| 389 | + if( options['class'] ) { |
| 390 | + $msg.addClass( options['class'] ); |
| 391 | + } |
| 392 | + // place our new message on the page |
| 393 | + $( '#article-assessment .article-assessment-submit' ) |
| 394 | + .append( $msg ); |
| 395 | + } |
| 396 | + }, |
| 397 | + 'showFeedback': function() { |
| 398 | + $.ArticleAssessment.fn.withJUI( function() { |
| 399 | + var $dialogDiv = $( '#article-assessment-dialog' ); |
| 400 | + if ( $dialogDiv.size() == 0 ) { |
| 401 | + $dialogDiv = $( '<div id="article-assessment-dialog" class="loading" />' ) |
| 402 | + .dialog( { |
| 403 | + width: 600, |
| 404 | + height: 400, |
| 405 | + bgiframe: true, |
| 406 | + autoOpen: true, |
| 407 | + modal: true, |
| 408 | + title: $.ArticleAssessment.fn.getMsg( 'articleassessment-survey-title' ), |
| 409 | + close: function() { |
| 410 | + $( this ) |
| 411 | + .dialog( 'option', 'height', 400 ) |
| 412 | + .find( '.article-assessment-success-msg, .article-assessment-error-msg' ) |
| 413 | + .remove() |
| 414 | + .end() |
| 415 | + .find( 'form' ) |
| 416 | + .show(); |
| 417 | + } |
| 418 | + } ); |
| 419 | + $dialogDiv.load( |
| 420 | + wgScript + '?title=Special:SimpleSurvey&survey=articlerating&raw=1', |
| 421 | + function() { |
| 422 | + $( this ).find( 'form' ).bind( 'submit', $.ArticleAssessment.fn.submitFeedback ); |
| 423 | + $( this ).removeClass( 'loading' ); |
| 424 | + } |
| 425 | + ); |
| 426 | + } |
| 427 | + $dialogDiv.dialog( 'open' ); |
| 428 | + } ); |
| 429 | + return false; |
| 430 | + }, |
| 431 | + 'submitFeedback': function() { |
| 432 | + var $dialogDiv = $( '#article-assessment-dialog' ); |
| 433 | + $dialogDiv |
| 434 | + .find( 'form' ) |
| 435 | + .hide() |
| 436 | + .end() |
| 437 | + .addClass( 'loading' ); |
| 438 | + // Submit straight to the special page. Yes, this is a dirty dirty hack |
| 439 | + // Build request from form data |
| 440 | + var formData = {}; |
| 441 | + $dialogDiv.find( 'input[type=text], input[type=radio]:checked, input[type=checkbox]:checked, ' + |
| 442 | + 'input[type=hidden], textarea' ).each( function() { |
| 443 | + var name = $( this ).attr( 'name' ); |
| 444 | + if ( name !== '' ) { |
| 445 | + if ( name.substr( -2 ) == '[]' ) { |
| 446 | + var trimmedName = name.substr( 0, name.length - 2 ); |
| 447 | + if ( typeof formData[trimmedName] == 'undefined' ) { |
| 448 | + formData[trimmedName] = []; |
| 449 | + } |
| 450 | + formData[trimmedName].push( $( this ).val() ); |
| 451 | + } else { |
| 452 | + formData[name] = $( this ).val(); |
| 453 | + } |
| 454 | + } |
| 455 | + } ); |
| 456 | + formData.title = 'Special:SimpleSurvey'; |
| 457 | + |
| 458 | + $.ajax( { |
| 459 | + url: wgScript, |
| 460 | + type: 'POST', |
| 461 | + data: formData, |
| 462 | + dataType: 'html', |
| 463 | + success: function( data ) { |
| 464 | + // This is an evil screenscraping method to determine whether |
| 465 | + // the submission was successful |
| 466 | + var success = $( data ).find( '.simplesurvey-success' ).size() > 0; |
| 467 | + // TODO: Style success-msg, error-msg |
| 468 | + var $msgDiv = $( '<div />' ) |
| 469 | + .addClass( success ? 'article-assessment-success-msg' : 'article-assessment-error-msg' ) |
| 470 | + .html( $.ArticleAssessment.fn.getMsg( success? 'articleassessment-survey-thanks' : 'articleassessment-error' ) ) |
| 471 | + .appendTo( $dialogDiv ); |
| 472 | + $dialogDiv.removeClass( 'loading' ); |
| 473 | + |
| 474 | + // This is absurdly unnecessary from the looks of it, but it seems this is somehow |
| 475 | + // needed in certain cases. |
| 476 | + $.ArticleAssessment.fn.withJUI( function() { |
| 477 | + $dialogDiv.dialog( 'option', 'height', $msgDiv.height() + 100 ) |
| 478 | + } ); |
| 479 | + |
| 480 | + if ( success ) { |
| 481 | + // Hide the dialog link |
| 482 | + $( '#article-assessment .article-assessment-rate-feedback' ).hide(); |
| 483 | + // set a cookie to keep the dialog link hidden |
| 484 | + $.cookie( 'mwArticleAssessmentHideFeedbackLink', true, { 'expires': 30, 'path': '/' } ); |
| 485 | + |
| 486 | + } |
| 487 | + }, |
| 488 | + error: function( XMLHttpRequest, textStatus, errorThrown ) { |
| 489 | + // TODO: Duplicates code, factor out, maybe |
| 490 | + var $msgDiv = $( '<div />' ) |
| 491 | + .addClass( 'article-assessment-error-msg' ) |
| 492 | + .html( $.ArticleAssessment.fn.getMsg( 'articleassessment-error' ) ) |
| 493 | + .appendTo( $dialogDiv ); |
| 494 | + $dialogDiv.removeClass( 'loading' ); |
| 495 | + $.ArticleAssessment.fn.withJUI( function() { |
| 496 | + $dialogDiv.dialog( 'option', 'height', $msgDiv.height() + 100 ) |
| 497 | + } ); |
| 498 | + } |
| 499 | + } ); |
| 500 | + return false; |
| 501 | + }, |
| 502 | + 'addMessages': function( messages ) { |
| 503 | + for ( var key in messages ) { |
| 504 | + $.ArticleAssessment.messages[key] = messages[key]; |
| 505 | + } |
| 506 | + }, |
| 507 | + /** |
| 508 | + * Get a message |
| 509 | + * FIXME: Parameter expansion is broken in all sorts of edge cases |
| 510 | + */ |
| 511 | + 'getMsg': function( key, args ) { |
| 512 | + if ( !( key in $.ArticleAssessment.messages ) ) { |
| 513 | + return '[' + key + ']'; |
| 514 | + } |
| 515 | + var msg = $.ArticleAssessment.messages[key]; |
| 516 | + if ( typeof args == 'object' || typeof args == 'array' ) { |
| 517 | + for ( var i = 0; i < args.length; i++ ) { |
| 518 | + msg = msg.replace( new RegExp( '\\$' + ( parseInt( i ) + 1 ), 'g' ), args[i] ); |
| 519 | + } |
| 520 | + } else if ( typeof args == 'string' || typeof args == 'number' ) { |
| 521 | + msg = msg.replace( /\$1/g, args ); |
| 522 | + } |
| 523 | + return msg; |
| 524 | + }, |
| 525 | + 'withJUI': function( callback ) { |
| 526 | + if ( typeof $.ui == 'undefined' ) { |
| 527 | + $.getScript( wgArticleAssessmentJUIPath, callback ); |
| 528 | + } else { |
| 529 | + callback(); |
| 530 | + } |
| 531 | + } |
| 532 | + } |
| 533 | + }; |
| 534 | + $( document ).ready( function () { |
| 535 | + $.ArticleAssessment.fn.init( ); |
| 536 | + } ); //document ready |
| 537 | +} )( jQuery ); |
Property changes on: trunk/extensions/ArticleAssessmentPilot/modules/ext.articleAssessment/ext.articleAssessment.js |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 538 | + native |
Index: trunk/extensions/ArticleAssessmentPilot/modules/ext.articleAssessment/images/rating_bg.gif |
Cannot display: file marked as a binary type. |
svn:mime-type = image/gif |
Property changes on: trunk/extensions/ArticleAssessmentPilot/modules/ext.articleAssessment/images/rating_bg.gif |
___________________________________________________________________ |
Added: svn:mime-type |
2 | 539 | + image/gif |
Index: trunk/extensions/ArticleAssessmentPilot/modules/ext.articleAssessment/images/loading.gif |
Cannot display: file marked as a binary type. |
svn:mime-type = image/gif |
Property changes on: trunk/extensions/ArticleAssessmentPilot/modules/ext.articleAssessment/images/loading.gif |
___________________________________________________________________ |
Added: svn:mime-type |
3 | 540 | + image/gif |
Index: trunk/extensions/ArticleAssessmentPilot/modules/ext.articleAssessment/images/rating_disabled_bg.gif |
Cannot display: file marked as a binary type. |
svn:mime-type = image/gif |
Property changes on: trunk/extensions/ArticleAssessmentPilot/modules/ext.articleAssessment/images/rating_disabled_bg.gif |
___________________________________________________________________ |
Added: svn:mime-type |
4 | 541 | + image/gif |
Index: trunk/extensions/ArticleAssessmentPilot/modules/ext.articleAssessment/images/question.gif |
Cannot display: file marked as a binary type. |
svn:mime-type = image/gif |
Property changes on: trunk/extensions/ArticleAssessmentPilot/modules/ext.articleAssessment/images/question.gif |
___________________________________________________________________ |
Added: svn:mime-type |
5 | 542 | + image/gif |
Index: trunk/extensions/ArticleAssessmentPilot/modules/ext.articleAssessment/images/question-hover.gif |
Cannot display: file marked as a binary type. |
svn:mime-type = image/gif |
Property changes on: trunk/extensions/ArticleAssessmentPilot/modules/ext.articleAssessment/images/question-hover.gif |
___________________________________________________________________ |
Added: svn:mime-type |
6 | 543 | + image/gif |
Index: trunk/extensions/ArticleAssessmentPilot/modules/ext.articleAssessment/images/rating_bar.gif |
Cannot display: file marked as a binary type. |
svn:mime-type = image/gif |
Property changes on: trunk/extensions/ArticleAssessmentPilot/modules/ext.articleAssessment/images/rating_bar.gif |
___________________________________________________________________ |
Added: svn:mime-type |
7 | 544 | + image/gif |
Index: trunk/extensions/ArticleAssessmentPilot/modules/jquery.stars/images/stars.gif |
Cannot display: file marked as a binary type. |
svn:mime-type = image/gif |
Property changes on: trunk/extensions/ArticleAssessmentPilot/modules/jquery.stars/images/stars.gif |
___________________________________________________________________ |
Added: svn:mime-type |
8 | 545 | + image/gif |
Index: trunk/extensions/ArticleAssessmentPilot/modules/jquery.stars/images/jquery.ui.stars.gif |
Cannot display: file marked as a binary type. |
svn:mime-type = image/gif |
Property changes on: trunk/extensions/ArticleAssessmentPilot/modules/jquery.stars/images/jquery.ui.stars.gif |
___________________________________________________________________ |
Added: svn:mime-type |
9 | 546 | + image/gif |
Index: trunk/extensions/ArticleAssessmentPilot/modules/jquery.stars/jquery.stars.js |
— | — | @@ -0,0 +1,305 @@ |
| 2 | +/*! |
| 3 | + * jQuery Stars v1 |
| 4 | + * adapted by Adam Miller (acm6603@gmail.com) |
| 5 | + * |
| 6 | + * Adapted from jQuery UI Stars v3.0.1 |
| 7 | + * Marek "Orkan" Zajac (orkans@gmail.com) |
| 8 | + * http://plugins.jquery.com/project/Star_Rating_widget |
| 9 | + * |
| 10 | + */ |
| 11 | +(function($) { |
| 12 | +$.stars = { |
| 13 | + defaults : { |
| 14 | + inputType: 'radio', // [radio|select] |
| 15 | + split: 0, // decrease number of stars by splitting each star into pieces [2|3|4|...] |
| 16 | + disabled: false, // set to [true] to make the stars initially disabled |
| 17 | + cancelTitle: 'Cancel Rating', |
| 18 | + cancelValue: 0, // default value of Cancel btn. |
| 19 | + cancelShow: true, |
| 20 | + disableValue: true, // set to [false] to not disable the hidden input when Cancel btn is clicked, so the value will present in POST data. |
| 21 | + oneVoteOnly: false, |
| 22 | + showTitles: false, |
| 23 | + captionEl: null, // jQuery object - target for text captions |
| 24 | + callback: null, // function(ui, type, value, event) |
| 25 | + /* |
| 26 | + * CSS classes |
| 27 | + */ |
| 28 | + starWidth: 16, // width of the star image |
| 29 | + cancelClass: 'ui-stars-cancel', |
| 30 | + starClass: 'ui-stars-star', |
| 31 | + starOnClass: 'ui-stars-star-on', |
| 32 | + starHoverClass: 'ui-stars-star-hover', |
| 33 | + starDisabledClass: 'ui-stars-star-disabled', |
| 34 | + cancelHoverClass: 'ui-stars-cancel-hover', |
| 35 | + cancelDisabledClass: 'ui-stars-cancel-disabled' |
| 36 | + }, |
| 37 | + create: function( ) { |
| 38 | + var self = this, o = this.options, starId = 0; |
| 39 | + this.element.data('former.stars', this.element.html()); |
| 40 | + o.isSelect = o.inputType == 'select'; |
| 41 | + this.$form = $(this.element).closest('form'); |
| 42 | + this.$selec = o.isSelect ? $('select', this.element) : null; |
| 43 | + this.$rboxs = o.isSelect ? $('option', this.$selec) : $(':radio', this.element); |
| 44 | + /* |
| 45 | + * Map all inputs from $rboxs array to Stars elements |
| 46 | + */ |
| 47 | + this.$stars = this.$rboxs.map(function(i) |
| 48 | + { |
| 49 | + var el = { |
| 50 | + value: this.value, |
| 51 | + title: (o.isSelect ? this.text : this.title) || this.value, |
| 52 | + isDefault: (o.isSelect && this.defaultSelected) || this.defaultChecked |
| 53 | + }; |
| 54 | + if(i==0) { |
| 55 | + o.split = typeof o.split != 'number' ? 0 : o.split; |
| 56 | + o.val2id = []; |
| 57 | + o.id2val = []; |
| 58 | + o.id2title = []; |
| 59 | + o.name = o.isSelect ? self.$selec.get(0).name : this.name; |
| 60 | + o.disabled = o.disabled || (o.isSelect ? $(self.$selec).attr('disabled') : $(this).attr('disabled')); |
| 61 | + } |
| 62 | + /* |
| 63 | + * Consider it as a Cancel button? |
| 64 | + */ |
| 65 | + if(el.value == o.cancelValue) { |
| 66 | + o.cancelTitle = el.title; |
| 67 | + return null; |
| 68 | + } |
| 69 | + o.val2id[el.value] = starId; |
| 70 | + o.id2val[starId] = el.value; |
| 71 | + o.id2title[starId] = el.title; |
| 72 | + if(el.isDefault) { |
| 73 | + o.checked = starId; |
| 74 | + o.value = o.defaultValue = el.value; |
| 75 | + o.title = el.title; |
| 76 | + } |
| 77 | + var $s = $('<div/>').addClass(o.starClass); |
| 78 | + var $a = $('<a/>').attr('title', o.showTitles ? el.title : '').text(el.value); |
| 79 | + /* |
| 80 | + * Prepare division settings |
| 81 | + */ |
| 82 | + if(o.split) { |
| 83 | + var oddeven = (starId % o.split); |
| 84 | + var stwidth = Math.floor(o.starWidth / o.split); |
| 85 | + $s.width(stwidth); |
| 86 | + $a.css('margin-left', '-' + (oddeven * stwidth) + 'px'); |
| 87 | + } |
| 88 | + starId++; |
| 89 | + return $s.append($a).get(0); |
| 90 | + }); |
| 91 | + /* |
| 92 | + * How many Stars? |
| 93 | + */ |
| 94 | + o.items = starId; |
| 95 | + /* |
| 96 | + * Remove old content |
| 97 | + */ |
| 98 | + o.isSelect ? this.$selec.remove() : this.$rboxs.remove(); |
| 99 | + /* |
| 100 | + * Append Stars interface |
| 101 | + */ |
| 102 | + this.$cancel = $('<div/>').addClass(o.cancelClass).append( $('<a/>').attr('title', o.showTitles ? o.cancelTitle : '').text(o.cancelValue) ); |
| 103 | + o.cancelShow &= !o.disabled && !o.oneVoteOnly; |
| 104 | + o.cancelShow && this.element.append(this.$cancel); |
| 105 | + this.element.append(this.$stars); |
| 106 | + /* |
| 107 | + * Initial selection |
| 108 | + */ |
| 109 | + if(o.checked === undefined) { |
| 110 | + o.checked = -1; |
| 111 | + o.value = o.defaultValue = o.cancelValue; |
| 112 | + o.title = ''; |
| 113 | + } |
| 114 | + /* |
| 115 | + * The only FORM element, that has been linked to the stars control. The value field is updated on each Star click event |
| 116 | + */ |
| 117 | + this.$value = $("<input type='hidden' name='"+o.name+"' value='"+o.value+"' />"); |
| 118 | + this.element.append(this.$value); |
| 119 | + /* |
| 120 | + * Attach stars event handler |
| 121 | + */ |
| 122 | + this.$stars.bind('click.stars', function(e) { |
| 123 | + if(!o.forceSelect && o.disabled) return false; |
| 124 | + var i = self.$stars.index(this); |
| 125 | + o.checked = i; |
| 126 | + o.value = o.id2val[i]; |
| 127 | + o.title = o.id2title[i]; |
| 128 | + self.$value.attr({disabled: o.disabled ? 'disabled' : '', value: o.value}); |
| 129 | + fillTo(i, false); |
| 130 | + self.disableCancel(); |
| 131 | + !o.forceSelect && self.callback(e, 'star'); |
| 132 | + }) |
| 133 | + .bind('mouseover.stars', function() { |
| 134 | + if(o.disabled) return false; |
| 135 | + var i = self.$stars.index(this); |
| 136 | + fillTo(i, true); |
| 137 | + }) |
| 138 | + .bind('mouseout.stars', function() { |
| 139 | + if(o.disabled) return false; |
| 140 | + fillTo(self.options.checked, false); |
| 141 | + }); |
| 142 | + /* |
| 143 | + * Attach cancel event handler |
| 144 | + */ |
| 145 | + this.$cancel.bind('click.stars', function(e) { |
| 146 | + if(!o.forceSelect && (o.disabled || o.value == o.cancelValue)) return false; |
| 147 | + o.checked = -1; |
| 148 | + o.value = o.cancelValue; |
| 149 | + o.title = ''; |
| 150 | + self.$value.val(o.value); |
| 151 | + o.disableValue && self.$value.attr({disabled: 'disabled'}); |
| 152 | + fillNone(); |
| 153 | + self.disableCancel(); |
| 154 | + !o.forceSelect && self.callback(e, 'cancel'); |
| 155 | + }) |
| 156 | + .bind('mouseover.stars', function() { |
| 157 | + if(self.disableCancel()) return false; |
| 158 | + self.$cancel.addClass(o.cancelHoverClass); |
| 159 | + fillNone(); |
| 160 | + self.showCap(o.cancelTitle); |
| 161 | + }) |
| 162 | + .bind('mouseout.stars', function() { |
| 163 | + if(self.disableCancel()) return false; |
| 164 | + self.$cancel.removeClass(o.cancelHoverClass); |
| 165 | + self.$stars.triggerHandler('mouseout.stars'); |
| 166 | + }); |
| 167 | + /* |
| 168 | + * Attach onReset event handler to the parent FORM |
| 169 | + */ |
| 170 | + this.$form.bind('reset.stars', function(){ |
| 171 | + !o.disabled && self.select(o.defaultValue); |
| 172 | + }); |
| 173 | + /* |
| 174 | + * Clean up to avoid memory leaks in certain versions of IE 6 |
| 175 | + */ |
| 176 | + // CHANGE: Only do this in IE, so as not to break bfcache in Firefox --catrope |
| 177 | + if ( window.attachEvent && !window.addEventListener ) { |
| 178 | + $(window).unload(function(){ |
| 179 | + self.$cancel.unbind('.stars'); |
| 180 | + self.$stars.unbind('.stars'); |
| 181 | + self.$form.unbind('.stars'); |
| 182 | + self.$selec = self.$rboxs = self.$stars = self.$value = self.$cancel = self.$form = null; |
| 183 | + }); |
| 184 | + } |
| 185 | + /* |
| 186 | + * Star selection helpers |
| 187 | + */ |
| 188 | + function fillTo(index, hover) { |
| 189 | + if(index != -1) { |
| 190 | + var addClass = hover ? o.starHoverClass : o.starOnClass; |
| 191 | + var remClass = hover ? o.starOnClass : o.starHoverClass; |
| 192 | + self.$stars.eq(index).prevAll('.' + o.starClass).andSelf().removeClass(remClass).addClass(addClass); |
| 193 | + self.$stars.eq(index).nextAll('.' + o.starClass).removeClass(o.starHoverClass + ' ' + o.starOnClass); |
| 194 | + self.showCap(o.id2title[index]); |
| 195 | + } |
| 196 | + else fillNone(); |
| 197 | + }; |
| 198 | + function fillNone() { |
| 199 | + self.$stars.removeClass(o.starOnClass + ' ' + o.starHoverClass); |
| 200 | + self.showCap(''); |
| 201 | + }; |
| 202 | + /* |
| 203 | + * Finally, set up the Stars |
| 204 | + */ |
| 205 | + this.select( o.value ); |
| 206 | + o.disabled && this.disable(); |
| 207 | + }, |
| 208 | + /* |
| 209 | + * Private functions |
| 210 | + */ |
| 211 | + disableCancel: function() { |
| 212 | + var o = this.options, disabled = o.disabled || o.oneVoteOnly || (o.value == o.cancelValue); |
| 213 | + if(disabled) this.$cancel.removeClass(o.cancelHoverClass).addClass(o.cancelDisabledClass); |
| 214 | + else this.$cancel.removeClass(o.cancelDisabledClass); |
| 215 | + this.$cancel.css('opacity', disabled ? 0.5 : 1); |
| 216 | + return disabled; |
| 217 | + }, |
| 218 | + disableAll: function() { |
| 219 | + var o = this.options; |
| 220 | + this.disableCancel(); |
| 221 | + if(o.disabled) this.$stars.filter('div').addClass(o.starDisabledClass); |
| 222 | + else this.$stars.filter('div').removeClass(o.starDisabledClass); |
| 223 | + }, |
| 224 | + showCap: function(s) { |
| 225 | + var o = this.options; |
| 226 | + if(o.captionEl) o.captionEl.text(s); |
| 227 | + }, |
| 228 | + /* |
| 229 | + * Public functions |
| 230 | + */ |
| 231 | + value: function() { |
| 232 | + return this.options.value; |
| 233 | + }, |
| 234 | + select: function( val ) { |
| 235 | + var o = this.options, e = (val == o.cancelValue) ? this.$cancel : this.$stars.eq(o.val2id[val]); |
| 236 | + o.forceSelect = true; |
| 237 | + e.triggerHandler('click.stars'); |
| 238 | + o.forceSelect = false; |
| 239 | + }, |
| 240 | + selectID: function(id) { |
| 241 | + var o = this.options, e = (id == -1) ? this.$cancel : this.$stars.eq(id); |
| 242 | + o.forceSelect = true; |
| 243 | + e.triggerHandler('click.stars'); |
| 244 | + o.forceSelect = false; |
| 245 | + }, |
| 246 | + enable: function() { |
| 247 | + this.options.disabled = false; |
| 248 | + this.disableAll(); |
| 249 | + }, |
| 250 | + disable: function() { |
| 251 | + this.options.disabled = true; |
| 252 | + this.disableAll(); |
| 253 | + }, |
| 254 | + destroy: function() { |
| 255 | + this.$form.unbind('.stars'); |
| 256 | + this.$cancel.unbind('.stars').remove(); |
| 257 | + this.$stars.unbind('.stars').remove(); |
| 258 | + this.$value.remove(); |
| 259 | + this.element.unbind('.stars').html(this.element.data('former.stars')).removeData('stars'); |
| 260 | + return this; |
| 261 | + }, |
| 262 | + callback: function(e, type) { |
| 263 | + var o = this.options; |
| 264 | + o.callback && o.callback(this, type, o.value, e); |
| 265 | + o.oneVoteOnly && !o.disabled && this.disable(); |
| 266 | + } |
| 267 | +} |
| 268 | +$.fn.stars = function ( ) { |
| 269 | + // convert the arguments to an array |
| 270 | + var args = Array.prototype.slice.call(arguments); |
| 271 | + // default value to return -- overwritten by api calls |
| 272 | + var out = $( this ); |
| 273 | + $( this ).each( function() { |
| 274 | + // get the context if it's already been initialized |
| 275 | + var context = $( this ).data( 'stars-context' ); |
| 276 | + if ( typeof context == 'undefined' || context == null ) { |
| 277 | + // setup the context if it hasn't been yet |
| 278 | + context = $.extend( {}, { |
| 279 | + element: $( this ), |
| 280 | + options: $.stars.defaults |
| 281 | + }, $.stars ); |
| 282 | + } |
| 283 | + // Handle various calling styles |
| 284 | + if ( args.length > 0 ) { |
| 285 | + if ( typeof args[0] == 'object' ) { |
| 286 | + // merge the passed options into defaults |
| 287 | + context.options = $.extend( {}, context.options, args[0] ); |
| 288 | + // initialize |
| 289 | + $.stars.create.call( context ); |
| 290 | + } else if ( typeof args[0] == 'string' ) { |
| 291 | + // API call |
| 292 | + var funcName = args[0]; |
| 293 | + // call the function, and if it returns something, store the output in our return var |
| 294 | + out = $.stars[funcName].call( context, args.slice(1) ) || out; |
| 295 | + } |
| 296 | + } else { |
| 297 | + // initialize with the defaults |
| 298 | + $.stars.create.call( context ); |
| 299 | + } |
| 300 | + // save our context, bay-bee |
| 301 | + $( this ).data( 'stars-context', context ); |
| 302 | + } ); |
| 303 | + |
| 304 | + return out; |
| 305 | +}; |
| 306 | +} )( jQuery ); |
Property changes on: trunk/extensions/ArticleAssessmentPilot/modules/jquery.stars/jquery.stars.js |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 307 | + native |