update domain in click to refresh message
[namibia] / public / js / vendor / jquery-realperson.js
1 /* http://keith-wood.name/realPerson.html
2    Real Person Form Submission for jQuery v1.1.1.
3    Written by Keith Wood (kwood{at}iinet.com.au) June 2009.
4    Available under the MIT (https://github.com/jquery/jquery/blob/master/MIT-LICENSE.txt) license. 
5    Please attribute the author if you use it. */
6
7 (function($) { // Hide scope, no $ conflict
8
9 /* Real person manager. */
10 function RealPerson() {
11         this._defaults = {
12                 length: 6, // Number of characters to use
13                 includeNumbers: false, // True to use numbers as well as letters
14                 regenerate: 'Click to change', // Instruction text to regenerate
15                 hashName: '{n}Hash' // Name of the hash value field to compare with,
16                         // use {n} to substitute with the original field name
17         };
18 }
19
20 var CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
21 var DOTS = [
22         ['   *   ', '  * *  ', '  * *  ', ' *   * ', ' ***** ', '*     *', '*     *'],
23         ['****** ', '*     *', '*     *', '****** ', '*     *', '*     *', '****** '],
24         [' ***** ', '*     *', '*      ', '*      ', '*      ', '*     *', ' ***** '],
25         ['****** ', '*     *', '*     *', '*     *', '*     *', '*     *', '****** '],
26         ['*******', '*      ', '*      ', '****   ', '*      ', '*      ', '*******'],
27         ['*******', '*      ', '*      ', '****   ', '*      ', '*      ', '*      '],
28         [' ***** ', '*     *', '*      ', '*      ', '*   ***', '*     *', ' ***** '],
29         ['*     *', '*     *', '*     *', '*******', '*     *', '*     *', '*     *'],
30         ['*******', '   *   ', '   *   ', '   *   ', '   *   ', '   *   ', '*******'],
31         ['      *', '      *', '      *', '      *', '      *', '*     *', ' ***** '],
32         ['*     *', '*   ** ', '* **   ', '**     ', '* **   ', '*   ** ', '*     *'],
33         ['*      ', '*      ', '*      ', '*      ', '*      ', '*      ', '*******'],
34         ['*     *', '**   **', '* * * *', '*  *  *', '*     *', '*     *', '*     *'],
35         ['*     *', '**    *', '* *   *', '*  *  *', '*   * *', '*    **', '*     *'],
36         [' ***** ', '*     *', '*     *', '*     *', '*     *', '*     *', ' ***** '],
37         ['****** ', '*     *', '*     *', '****** ', '*      ', '*      ', '*      '],
38         [' ***** ', '*     *', '*     *', '*     *', '*   * *', '*    * ', ' **** *'],
39         ['****** ', '*     *', '*     *', '****** ', '*   *  ', '*    * ', '*     *'],
40         [' ***** ', '*     *', '*      ', ' ***** ', '      *', '*     *', ' ***** '],
41         ['*******', '   *   ', '   *   ', '   *   ', '   *   ', '   *   ', '   *   '],
42         ['*     *', '*     *', '*     *', '*     *', '*     *', '*     *', ' ***** '],
43         ['*     *', '*     *', ' *   * ', ' *   * ', '  * *  ', '  * *  ', '   *   '],
44         ['*     *', '*     *', '*     *', '*  *  *', '* * * *', '**   **', '*     *'],
45         ['*     *', ' *   * ', '  * *  ', '   *   ', '  * *  ', ' *   * ', '*     *'],
46         ['*     *', ' *   * ', '  * *  ', '   *   ', '   *   ', '   *   ', '   *   '],
47         ['*******', '     * ', '    *  ', '   *   ', '  *    ', ' *     ', '*******'],
48         ['  ***  ', ' *   * ', '*   * *', '*  *  *', '* *   *', ' *   * ', '  ***  '],
49         ['   *   ', '  **   ', ' * *   ', '   *   ', '   *   ', '   *   ', '*******'],
50         [' ***** ', '*     *', '      *', '     * ', '   **  ', ' **    ', '*******'],
51         [' ***** ', '*     *', '      *', '    ** ', '      *', '*     *', ' ***** '],
52         ['    *  ', '   **  ', '  * *  ', ' *  *  ', '*******', '    *  ', '    *  '],
53         ['*******', '*      ', '****** ', '      *', '      *', '*     *', ' ***** '],
54         ['  **** ', ' *     ', '*      ', '****** ', '*     *', '*     *', ' ***** '],
55         ['*******', '     * ', '    *  ', '   *   ', '  *    ', ' *     ', '*      '],
56         [' ***** ', '*     *', '*     *', ' ***** ', '*     *', '*     *', ' ***** '],
57         [' ***** ', '*     *', '*     *', ' ******', '      *', '     * ', ' ****  ']];
58
59 $.extend(RealPerson.prototype, {
60         /* Class name added to elements to indicate already configured with real person. */
61         markerClassName: 'hasRealPerson',
62         /* Name of the data property for instance settings. */
63         propertyName: 'realperson',
64
65         /* Override the default settings for all real person instances.
66            @param  options  (object) the new settings to use as defaults
67            @return  (RealPerson) this object */
68         setDefaults: function(options) {
69                 $.extend(this._defaults, options || {});
70                 return this;
71         },
72
73         /* Attach the real person functionality to an input field.
74            @param  target   (element) the control to affect
75            @param  options  (object) the custom options for this instance */
76         _attachPlugin: function(target, options) {
77                 target = $(target);
78                 if (target.hasClass(this.markerClassName)) {
79                         return;
80                 }
81                 var inst = {options: $.extend({}, this._defaults)};
82                 target.addClass(this.markerClassName).data(this.propertyName, inst);
83                 this._optionPlugin(target, options);
84         },
85
86         /* Retrieve or reconfigure the settings for a control.
87            @param  target   (element) the control to affect
88            @param  options  (object) the new options for this instance or
89                             (string) an individual property name
90            @param  value    (any) the individual property value (omit if options
91                             is an object or to retrieve the value of a setting)
92            @return  (any) if retrieving a value */
93         _optionPlugin: function(target, options, value) {
94                 target = $(target);
95                 var inst = target.data(this.propertyName);
96                 if (!options || (typeof options == 'string' && value == null)) { // Get option
97                         var name = options;
98                         options = (inst || {}).options;
99                         return (options && name ? options[name] : options);
100                 }
101
102                 if (!target.hasClass(this.markerClassName)) {
103                         return;
104                 }
105                 options = options || {};
106                 if (typeof options == 'string') {
107                         var name = options;
108                         options = {};
109                         options[name] = value;
110                 }
111                 $.extend(inst.options, options);
112                 target.prevAll('.' + this.propertyName + '-challenge,.' + this.propertyName + '-hash').
113                         remove().end().before(this._generateHTML(target, inst));
114         },
115
116         /* Generate the additional content for this control.
117            @param  target  (jQuery) the input field
118            @param  inst    (object) the current instance settings
119            @return  (string) the additional content */
120         _generateHTML: function(target, inst) {
121                 var text = '';
122                 for (var i = 0; i < inst.options.length; i++) {
123                         text += CHARS.charAt(Math.floor(Math.random() *
124                                 (inst.options.includeNumbers ? 36 : 26)));
125                 }
126                 var html = '<div class="' + this.propertyName + '-challenge">' +
127                         '<div class="' + this.propertyName + '-text">';
128                 for (var i = 0; i < DOTS[0].length; i++) {
129                         for (var j = 0; j < text.length; j++) {
130                                 html += DOTS[CHARS.indexOf(text.charAt(j))][i].replace(/ /g, '&nbsp;') +
131                                         '&nbsp;&nbsp;';
132                         }
133                         html += '<br>';
134                 }
135                 html += '</div><div class="' + this.propertyName + '-regen">' + inst.options.regenerate +
136                         '</div></div><input type="hidden" class="' + this.propertyName + '-hash" name="' +
137                         inst.options.hashName.replace(/\{n\}/, target.attr('name')) +
138                         '" value="' + this._hash(text) + '">';
139                 return html;
140         },
141
142         /* Enable the plugin functionality for a control.
143            @param  target  (element) the control to affect */
144         _enablePlugin: function(target) {
145                 target = $(target);
146                 if (!target.hasClass(this.markerClassName)) {
147                         return;
148                 }
149                 target.removeClass(this.propertyName + '-disabled').prop('disabled', false).
150                         prevAll('.' + this.propertyName + '-challenge').removeClass(this.propertyName + '-disabled');
151         },
152
153         /* Disable the plugin functionality for a control.
154            @param  target  (element) the control to affect */
155         _disablePlugin: function(target) {
156                 target = $(target);
157                 if (!target.hasClass(this.markerClassName)) {
158                         return;
159                 }
160                 target.addClass(this.propertyName + '-disabled').prop('disabled', true).
161                         prevAll('.' + this.propertyName + '-challenge').addClass(this.propertyName + '-disabled');
162         },
163
164         /* Remove the plugin functionality from a control.
165            @param  target  (element) the control to affect */
166         _destroyPlugin: function(target) {
167                 target = $(target);
168                 if (!target.hasClass(this.markerClassName)) {
169                         return;
170                 }
171                 target.removeClass(this.markerClassName).
172                         removeData(this.propertyName).
173                         prevAll('.' + this.propertyName + '-challenge,.' + this.propertyName + '-hash').remove();
174         },
175
176         /* Compute a hash value for the given text.
177            @param  value  (string) the text to hash
178            @return  the corresponding hash value */
179         _hash: function(value) {
180                 var hash = 5381;
181                 for (var i = 0; i < value.length; i++) {
182                         hash = ((hash << 5) + hash) + value.charCodeAt(i);
183                 }
184                 return hash;
185         }
186 });
187
188 // The list of commands that return values and don't permit chaining
189 var getters = [''];
190
191 /* Determine whether a command is a getter and doesn't permit chaining.
192    @param  command    (string, optional) the command to run
193    @param  otherArgs  ([], optional) any other arguments for the command
194    @return  true if the command is a getter, false if not */
195 function isNotChained(command, otherArgs) {
196         if (command == 'option' && (otherArgs.length == 0 ||
197                         (otherArgs.length == 1 && typeof otherArgs[0] == 'string'))) {
198                 return true;
199         }
200         return $.inArray(command, getters) > -1;
201 }
202
203 /* Attach the real person functionality to a jQuery selection.
204    @param  options  (object) the new settings to use for these instances (optional) or
205                     (string) the command to run (optional)
206    @return  (jQuery) for chaining further calls or
207             (any) getter value */
208 $.fn.realperson = function(options) {
209         var otherArgs = Array.prototype.slice.call(arguments, 1);
210         if (isNotChained(options, otherArgs)) {
211                 return plugin['_' + options + 'Plugin'].apply(plugin, [this[0]].concat(otherArgs));
212         }
213         return this.each(function() {
214                 if (typeof options == 'string') {
215                         if (!plugin['_' + options + 'Plugin']) {
216                                 throw 'Unknown command: ' + options;
217                         }
218                         plugin['_' + options + 'Plugin'].apply(plugin, [this].concat(otherArgs));
219                 }
220                 else {
221                         plugin._attachPlugin(this, options || {});
222                 }
223         });
224 };
225
226 /* Initialise the real person functionality. */
227 var plugin = $.realperson = new RealPerson(); // Singleton instance
228
229 $(document).on('click', 'div.' + plugin.propertyName + '-challenge', function() {
230         if (!$(this).hasClass(plugin.propertyName + '-disabled')) {
231                 $(this).nextAll('.' + plugin.markerClassName).realperson('option', {});
232         }
233 });
234
235 })(jQuery);