shinmun 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. data/.gitignore +1 -0
  2. data/LICENSE +18 -0
  3. data/README.md +249 -0
  4. data/Rakefile +60 -0
  5. data/bin/shinmun +12 -0
  6. data/example/posts/2008/9/example.md +19 -0
  7. data/example/posts/blog.yml +10 -0
  8. data/example/posts/uuid.state +3 -0
  9. data/example/public/controllers/comments.php +56 -0
  10. data/example/public/images/loading.gif +0 -0
  11. data/example/public/javascripts/comments.js +60 -0
  12. data/example/public/javascripts/highlight.js +505 -0
  13. data/example/public/javascripts/images/bg-fill.png +0 -0
  14. data/example/public/javascripts/images/bg.png +0 -0
  15. data/example/public/javascripts/images/blockquote.png +0 -0
  16. data/example/public/javascripts/images/bold.png +0 -0
  17. data/example/public/javascripts/images/code.png +0 -0
  18. data/example/public/javascripts/images/h1.png +0 -0
  19. data/example/public/javascripts/images/hr.png +0 -0
  20. data/example/public/javascripts/images/img.png +0 -0
  21. data/example/public/javascripts/images/italic.png +0 -0
  22. data/example/public/javascripts/images/link.png +0 -0
  23. data/example/public/javascripts/images/ol.png +0 -0
  24. data/example/public/javascripts/images/redo.png +0 -0
  25. data/example/public/javascripts/images/separator.png +0 -0
  26. data/example/public/javascripts/images/ul.png +0 -0
  27. data/example/public/javascripts/images/undo.png +0 -0
  28. data/example/public/javascripts/images/wmd-on.png +0 -0
  29. data/example/public/javascripts/images/wmd.png +0 -0
  30. data/example/public/javascripts/jquery-form.js +869 -0
  31. data/example/public/javascripts/jquery.js +3383 -0
  32. data/example/public/javascripts/languages/1c.js +82 -0
  33. data/example/public/javascripts/languages/axapta.js +52 -0
  34. data/example/public/javascripts/languages/bash.js +80 -0
  35. data/example/public/javascripts/languages/diff.js +64 -0
  36. data/example/public/javascripts/languages/dos.js +33 -0
  37. data/example/public/javascripts/languages/dynamic.js +460 -0
  38. data/example/public/javascripts/languages/ini.js +36 -0
  39. data/example/public/javascripts/languages/javascript.js +38 -0
  40. data/example/public/javascripts/languages/lisp.js +86 -0
  41. data/example/public/javascripts/languages/mel.js +50 -0
  42. data/example/public/javascripts/languages/profile.js +50 -0
  43. data/example/public/javascripts/languages/renderman.js +71 -0
  44. data/example/public/javascripts/languages/smalltalk.js +53 -0
  45. data/example/public/javascripts/languages/sql.js +50 -0
  46. data/example/public/javascripts/languages/static.js +175 -0
  47. data/example/public/javascripts/languages/vbscript.js +25 -0
  48. data/example/public/javascripts/languages/www.js +245 -0
  49. data/example/public/javascripts/prettyDate.js +36 -0
  50. data/example/public/javascripts/showdown.js +421 -0
  51. data/example/public/javascripts/template.js +165 -0
  52. data/example/public/javascripts/wmd-base.js +1799 -0
  53. data/example/public/javascripts/wmd-plus.js +311 -0
  54. data/example/public/javascripts/wmd.js +73 -0
  55. data/example/public/stylesheets/grid.css +243 -0
  56. data/example/public/stylesheets/grid.png +0 -0
  57. data/example/public/stylesheets/highlight/ascetic.css +38 -0
  58. data/example/public/stylesheets/highlight/dark.css +96 -0
  59. data/example/public/stylesheets/highlight/default.css +91 -0
  60. data/example/public/stylesheets/highlight/far.css +95 -0
  61. data/example/public/stylesheets/highlight/idea.css +75 -0
  62. data/example/public/stylesheets/highlight/sunburst.css +112 -0
  63. data/example/public/stylesheets/highlight/zenburn.css +108 -0
  64. data/example/public/stylesheets/print.css +76 -0
  65. data/example/public/stylesheets/reset.css +45 -0
  66. data/example/public/stylesheets/style.css +141 -0
  67. data/example/public/stylesheets/typography.css +59 -0
  68. data/example/templates/feed.rxml +21 -0
  69. data/example/templates/layout.rhtml +54 -0
  70. data/example/templates/page.rhtml +4 -0
  71. data/example/templates/post.rhtml +57 -0
  72. data/example/templates/posts.rhtml +10 -0
  73. data/lib/shinmun.rb +420 -0
  74. metadata +151 -0
@@ -0,0 +1,869 @@
1
+ /*
2
+ * jQuery Form Plugin
3
+ * version: 2.07 (03/04/2008)
4
+ * @requires jQuery v1.2.2 or later
5
+ *
6
+ * Examples at: http://malsup.com/jquery/form/
7
+ * Dual licensed under the MIT and GPL licenses:
8
+ * http://www.opensource.org/licenses/mit-license.php
9
+ * http://www.gnu.org/licenses/gpl.html
10
+ *
11
+ * Revision: $Id$
12
+ */
13
+ (function($) {
14
+ /**
15
+ * ajaxSubmit() provides a mechanism for submitting an HTML form using AJAX.
16
+ *
17
+ * ajaxSubmit accepts a single argument which can be either a success callback function
18
+ * or an options Object. If a function is provided it will be invoked upon successful
19
+ * completion of the submit and will be passed the response from the server.
20
+ * If an options Object is provided, the following attributes are supported:
21
+ *
22
+ * target: Identifies the element(s) in the page to be updated with the server response.
23
+ * This value may be specified as a jQuery selection string, a jQuery object,
24
+ * or a DOM element.
25
+ * default value: null
26
+ *
27
+ * url: URL to which the form data will be submitted.
28
+ * default value: value of form's 'action' attribute
29
+ *
30
+ * type: The method in which the form data should be submitted, 'GET' or 'POST'.
31
+ * default value: value of form's 'method' attribute (or 'GET' if none found)
32
+ *
33
+ * data: Additional data to add to the request, specified as key/value pairs (see $.ajax).
34
+ *
35
+ * beforeSubmit: Callback method to be invoked before the form is submitted.
36
+ * default value: null
37
+ *
38
+ * success: Callback method to be invoked after the form has been successfully submitted
39
+ * and the response has been returned from the server
40
+ * default value: null
41
+ *
42
+ * dataType: Expected dataType of the response. One of: null, 'xml', 'script', or 'json'
43
+ * default value: null
44
+ *
45
+ * semantic: Boolean flag indicating whether data must be submitted in semantic order (slower).
46
+ * default value: false
47
+ *
48
+ * resetForm: Boolean flag indicating whether the form should be reset if the submit is successful
49
+ *
50
+ * clearForm: Boolean flag indicating whether the form should be cleared if the submit is successful
51
+ *
52
+ *
53
+ * The 'beforeSubmit' callback can be provided as a hook for running pre-submit logic or for
54
+ * validating the form data. If the 'beforeSubmit' callback returns false then the form will
55
+ * not be submitted. The 'beforeSubmit' callback is invoked with three arguments: the form data
56
+ * in array format, the jQuery object, and the options object passed into ajaxSubmit.
57
+ * The form data array takes the following form:
58
+ *
59
+ * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
60
+ *
61
+ * If a 'success' callback method is provided it is invoked after the response has been returned
62
+ * from the server. It is passed the responseText or responseXML value (depending on dataType).
63
+ * See jQuery.ajax for further details.
64
+ *
65
+ *
66
+ * The dataType option provides a means for specifying how the server response should be handled.
67
+ * This maps directly to the jQuery.httpData method. The following values are supported:
68
+ *
69
+ * 'xml': if dataType == 'xml' the server response is treated as XML and the 'success'
70
+ * callback method, if specified, will be passed the responseXML value
71
+ * 'json': if dataType == 'json' the server response will be evaluted and passed to
72
+ * the 'success' callback, if specified
73
+ * 'script': if dataType == 'script' the server response is evaluated in the global context
74
+ *
75
+ *
76
+ * Note that it does not make sense to use both the 'target' and 'dataType' options. If both
77
+ * are provided the target will be ignored.
78
+ *
79
+ * The semantic argument can be used to force form serialization in semantic order.
80
+ * This is normally true anyway, unless the form contains input elements of type='image'.
81
+ * If your form must be submitted with name/value pairs in semantic order and your form
82
+ * contains an input of type='image" then pass true for this arg, otherwise pass false
83
+ * (or nothing) to avoid the overhead for this logic.
84
+ *
85
+ *
86
+ * When used on its own, ajaxSubmit() is typically bound to a form's submit event like this:
87
+ *
88
+ * $("#form-id").submit(function() {
89
+ * $(this).ajaxSubmit(options);
90
+ * return false; // cancel conventional submit
91
+ * });
92
+ *
93
+ * When using ajaxForm(), however, this is done for you.
94
+ *
95
+ * @example
96
+ * $('#myForm').ajaxSubmit(function(data) {
97
+ * alert('Form submit succeeded! Server returned: ' + data);
98
+ * });
99
+ * @desc Submit form and alert server response
100
+ *
101
+ *
102
+ * @example
103
+ * var options = {
104
+ * target: '#myTargetDiv'
105
+ * };
106
+ * $('#myForm').ajaxSubmit(options);
107
+ * @desc Submit form and update page element with server response
108
+ *
109
+ *
110
+ * @example
111
+ * var options = {
112
+ * success: function(responseText) {
113
+ * alert(responseText);
114
+ * }
115
+ * };
116
+ * $('#myForm').ajaxSubmit(options);
117
+ * @desc Submit form and alert the server response
118
+ *
119
+ *
120
+ * @example
121
+ * var options = {
122
+ * beforeSubmit: function(formArray, jqForm) {
123
+ * if (formArray.length == 0) {
124
+ * alert('Please enter data.');
125
+ * return false;
126
+ * }
127
+ * }
128
+ * };
129
+ * $('#myForm').ajaxSubmit(options);
130
+ * @desc Pre-submit validation which aborts the submit operation if form data is empty
131
+ *
132
+ *
133
+ * @example
134
+ * var options = {
135
+ * url: myJsonUrl.php,
136
+ * dataType: 'json',
137
+ * success: function(data) {
138
+ * // 'data' is an object representing the the evaluated json data
139
+ * }
140
+ * };
141
+ * $('#myForm').ajaxSubmit(options);
142
+ * @desc json data returned and evaluated
143
+ *
144
+ *
145
+ * @example
146
+ * var options = {
147
+ * url: myXmlUrl.php,
148
+ * dataType: 'xml',
149
+ * success: function(responseXML) {
150
+ * // responseXML is XML document object
151
+ * var data = $('myElement', responseXML).text();
152
+ * }
153
+ * };
154
+ * $('#myForm').ajaxSubmit(options);
155
+ * @desc XML data returned from server
156
+ *
157
+ *
158
+ * @example
159
+ * var options = {
160
+ * resetForm: true
161
+ * };
162
+ * $('#myForm').ajaxSubmit(options);
163
+ * @desc submit form and reset it if successful
164
+ *
165
+ * @example
166
+ * $('#myForm).submit(function() {
167
+ * $(this).ajaxSubmit();
168
+ * return false;
169
+ * });
170
+ * @desc Bind form's submit event to use ajaxSubmit
171
+ *
172
+ *
173
+ * @name ajaxSubmit
174
+ * @type jQuery
175
+ * @param options object literal containing options which control the form submission process
176
+ * @cat Plugins/Form
177
+ * @return jQuery
178
+ */
179
+ $.fn.ajaxSubmit = function(options) {
180
+ if (typeof options == 'function')
181
+ options = { success: options };
182
+
183
+ options = $.extend({
184
+ url: this.attr('action') || window.location.toString(),
185
+ type: this.attr('method') || 'GET'
186
+ }, options || {});
187
+
188
+ // hook for manipulating the form data before it is extracted;
189
+ // convenient for use with rich editors like tinyMCE or FCKEditor
190
+ var veto = {};
191
+ this.trigger('form-pre-serialize', [this, options, veto]);
192
+ if (veto.veto) return this;
193
+
194
+ var a = this.formToArray(options.semantic);
195
+ if (options.data) {
196
+ options.extraData = options.data;
197
+ for (var n in options.data)
198
+ a.push( { name: n, value: options.data[n] } );
199
+ }
200
+
201
+ // give pre-submit callback an opportunity to abort the submit
202
+ if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) return this;
203
+
204
+ // fire vetoable 'validate' event
205
+ this.trigger('form-submit-validate', [a, this, options, veto]);
206
+ if (veto.veto) return this;
207
+
208
+ var q = $.param(a);
209
+
210
+ if (options.type.toUpperCase() == 'GET') {
211
+ options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
212
+ options.data = null; // data is null for 'get'
213
+ }
214
+ else
215
+ options.data = q; // data is the query string for 'post'
216
+
217
+ var $form = this, callbacks = [];
218
+ if (options.resetForm) callbacks.push(function() { $form.resetForm(); });
219
+ if (options.clearForm) callbacks.push(function() { $form.clearForm(); });
220
+
221
+ // perform a load on the target only if dataType is not provided
222
+ if (!options.dataType && options.target) {
223
+ var oldSuccess = options.success || function(){};
224
+ callbacks.push(function(data) {
225
+ $(options.target).html(data).each(oldSuccess, arguments);
226
+ });
227
+ }
228
+ else if (options.success)
229
+ callbacks.push(options.success);
230
+
231
+ options.success = function(data, status) {
232
+ for (var i=0, max=callbacks.length; i < max; i++)
233
+ callbacks[i](data, status, $form);
234
+ };
235
+
236
+ // are there files to upload?
237
+ var files = $('input:file', this).fieldValue();
238
+ var found = false;
239
+ for (var j=0; j < files.length; j++)
240
+ if (files[j])
241
+ found = true;
242
+
243
+ // options.iframe allows user to force iframe mode
244
+ if (options.iframe || found) {
245
+ // hack to fix Safari hang (thanks to Tim Molendijk for this)
246
+ // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
247
+ if ($.browser.safari && options.closeKeepAlive)
248
+ $.get(options.closeKeepAlive, fileUpload);
249
+ else
250
+ fileUpload();
251
+ }
252
+ else
253
+ $.ajax(options);
254
+
255
+ // fire 'notify' event
256
+ this.trigger('form-submit-notify', [this, options]);
257
+ return this;
258
+
259
+
260
+ // private function for handling file uploads (hat tip to YAHOO!)
261
+ function fileUpload() {
262
+ var form = $form[0];
263
+ var opts = $.extend({}, $.ajaxSettings, options);
264
+
265
+ var id = 'jqFormIO' + (new Date().getTime());
266
+ var $io = $('<iframe id="' + id + '" name="' + id + '" />');
267
+ var io = $io[0];
268
+ var op8 = $.browser.opera && window.opera.version() < 9;
269
+ if ($.browser.msie || op8) io.src = 'javascript:false;document.write("");';
270
+ $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
271
+
272
+ var xhr = { // mock object
273
+ responseText: null,
274
+ responseXML: null,
275
+ status: 0,
276
+ statusText: 'n/a',
277
+ getAllResponseHeaders: function() {},
278
+ getResponseHeader: function() {},
279
+ setRequestHeader: function() {}
280
+ };
281
+
282
+ var g = opts.global;
283
+ // trigger ajax global events so that activity/block indicators work like normal
284
+ if (g && ! $.active++) $.event.trigger("ajaxStart");
285
+ if (g) $.event.trigger("ajaxSend", [xhr, opts]);
286
+
287
+ var cbInvoked = 0;
288
+ var timedOut = 0;
289
+
290
+ // take a breath so that pending repaints get some cpu time before the upload starts
291
+ setTimeout(function() {
292
+ // make sure form attrs are set
293
+ var t = $form.attr('target'), a = $form.attr('action');
294
+ $form.attr({
295
+ target: id,
296
+ encoding: 'multipart/form-data',
297
+ enctype: 'multipart/form-data',
298
+ method: 'POST',
299
+ action: opts.url
300
+ });
301
+
302
+ // support timout
303
+ if (opts.timeout)
304
+ setTimeout(function() { timedOut = true; cb(); }, opts.timeout);
305
+
306
+ // add "extra" data to form if provided in options
307
+ var extraInputs = [];
308
+ try {
309
+ if (options.extraData)
310
+ for (var n in options.extraData)
311
+ extraInputs.push(
312
+ $('<input type="hidden" name="'+n+'" value="'+options.extraData[n]+'" />')
313
+ .appendTo(form)[0]);
314
+
315
+ // add iframe to doc and submit the form
316
+ $io.appendTo('body');
317
+ io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
318
+ form.submit();
319
+ }
320
+ finally {
321
+ // reset attrs and remove "extra" input elements
322
+ $form.attr('action', a);
323
+ t ? $form.attr('target', t) : $form.removeAttr('target');
324
+ $(extraInputs).remove();
325
+ }
326
+ }, 10);
327
+
328
+ function cb() {
329
+ if (cbInvoked++) return;
330
+
331
+ io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);
332
+
333
+ var ok = true;
334
+ try {
335
+ if (timedOut) throw 'timeout';
336
+ // extract the server response from the iframe
337
+ var data, doc;
338
+ doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
339
+ xhr.responseText = doc.body ? doc.body.innerHTML : null;
340
+ xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
341
+ xhr.getResponseHeader = function(header){
342
+ var headers = {'content-type': opts.dataType};
343
+ return headers[header];
344
+ };
345
+
346
+ if (opts.dataType == 'json' || opts.dataType == 'script') {
347
+ var ta = doc.getElementsByTagName('textarea')[0];
348
+ xhr.responseText = ta ? ta.value : xhr.responseText;
349
+ }
350
+ else if (opts.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
351
+ xhr.responseXML = toXml(xhr.responseText);
352
+ }
353
+ data = $.httpData(xhr, opts.dataType);
354
+ }
355
+ catch(e){
356
+ ok = false;
357
+ $.handleError(opts, xhr, 'error', e);
358
+ }
359
+
360
+ // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
361
+ if (ok) {
362
+ opts.success(data, 'success');
363
+ if (g) $.event.trigger("ajaxSuccess", [xhr, opts]);
364
+ }
365
+ if (g) $.event.trigger("ajaxComplete", [xhr, opts]);
366
+ if (g && ! --$.active) $.event.trigger("ajaxStop");
367
+ if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error');
368
+
369
+ // clean up
370
+ setTimeout(function() {
371
+ $io.remove();
372
+ xhr.responseXML = null;
373
+ }, 100);
374
+ };
375
+
376
+ function toXml(s, doc) {
377
+ if (window.ActiveXObject) {
378
+ doc = new ActiveXObject('Microsoft.XMLDOM');
379
+ doc.async = 'false';
380
+ doc.loadXML(s);
381
+ }
382
+ else
383
+ doc = (new DOMParser()).parseFromString(s, 'text/xml');
384
+ return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
385
+ };
386
+ };
387
+ };
388
+
389
+ /**
390
+ * ajaxForm() provides a mechanism for fully automating form submission.
391
+ *
392
+ * The advantages of using this method instead of ajaxSubmit() are:
393
+ *
394
+ * 1: This method will include coordinates for <input type="image" /> elements (if the element
395
+ * is used to submit the form).
396
+ * 2. This method will include the submit element's name/value data (for the element that was
397
+ * used to submit the form).
398
+ * 3. This method binds the submit() method to the form for you.
399
+ *
400
+ * Note that for accurate x/y coordinates of image submit elements in all browsers
401
+ * you need to also use the "dimensions" plugin (this method will auto-detect its presence).
402
+ *
403
+ * The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely
404
+ * passes the options argument along after properly binding events for submit elements and
405
+ * the form itself. See ajaxSubmit for a full description of the options argument.
406
+ *
407
+ *
408
+ * @example
409
+ * var options = {
410
+ * target: '#myTargetDiv'
411
+ * };
412
+ * $('#myForm').ajaxSForm(options);
413
+ * @desc Bind form's submit event so that 'myTargetDiv' is updated with the server response
414
+ * when the form is submitted.
415
+ *
416
+ *
417
+ * @example
418
+ * var options = {
419
+ * success: function(responseText) {
420
+ * alert(responseText);
421
+ * }
422
+ * };
423
+ * $('#myForm').ajaxSubmit(options);
424
+ * @desc Bind form's submit event so that server response is alerted after the form is submitted.
425
+ *
426
+ *
427
+ * @example
428
+ * var options = {
429
+ * beforeSubmit: function(formArray, jqForm) {
430
+ * if (formArray.length == 0) {
431
+ * alert('Please enter data.');
432
+ * return false;
433
+ * }
434
+ * }
435
+ * };
436
+ * $('#myForm').ajaxSubmit(options);
437
+ * @desc Bind form's submit event so that pre-submit callback is invoked before the form
438
+ * is submitted.
439
+ *
440
+ *
441
+ * @name ajaxForm
442
+ * @param options object literal containing options which control the form submission process
443
+ * @return jQuery
444
+ * @cat Plugins/Form
445
+ * @type jQuery
446
+ */
447
+ $.fn.ajaxForm = function(options) {
448
+ return this.ajaxFormUnbind().bind('submit.form-plugin',function() {
449
+ $(this).ajaxSubmit(options);
450
+ return false;
451
+ }).each(function() {
452
+ // store options in hash
453
+ $(":submit,input:image", this).bind('click.form-plugin',function(e) {
454
+ var $form = this.form;
455
+ $form.clk = this;
456
+ if (this.type == 'image') {
457
+ if (e.offsetX != undefined) {
458
+ $form.clk_x = e.offsetX;
459
+ $form.clk_y = e.offsetY;
460
+ } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
461
+ var offset = $(this).offset();
462
+ $form.clk_x = e.pageX - offset.left;
463
+ $form.clk_y = e.pageY - offset.top;
464
+ } else {
465
+ $form.clk_x = e.pageX - this.offsetLeft;
466
+ $form.clk_y = e.pageY - this.offsetTop;
467
+ }
468
+ }
469
+ // clear form vars
470
+ setTimeout(function() { $form.clk = $form.clk_x = $form.clk_y = null; }, 10);
471
+ });
472
+ });
473
+ };
474
+
475
+
476
+ /**
477
+ * ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
478
+ *
479
+ * @name ajaxFormUnbind
480
+ * @return jQuery
481
+ * @cat Plugins/Form
482
+ * @type jQuery
483
+ */
484
+ $.fn.ajaxFormUnbind = function() {
485
+ this.unbind('submit.form-plugin');
486
+ return this.each(function() {
487
+ $(":submit,input:image", this).unbind('click.form-plugin');
488
+ });
489
+
490
+ };
491
+
492
+ /**
493
+ * formToArray() gathers form element data into an array of objects that can
494
+ * be passed to any of the following ajax functions: $.get, $.post, or load.
495
+ * Each object in the array has both a 'name' and 'value' property. An example of
496
+ * an array for a simple login form might be:
497
+ *
498
+ * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
499
+ *
500
+ * It is this array that is passed to pre-submit callback functions provided to the
501
+ * ajaxSubmit() and ajaxForm() methods.
502
+ *
503
+ * The semantic argument can be used to force form serialization in semantic order.
504
+ * This is normally true anyway, unless the form contains input elements of type='image'.
505
+ * If your form must be submitted with name/value pairs in semantic order and your form
506
+ * contains an input of type='image" then pass true for this arg, otherwise pass false
507
+ * (or nothing) to avoid the overhead for this logic.
508
+ *
509
+ * @example var data = $("#myForm").formToArray();
510
+ * $.post( "myscript.cgi", data );
511
+ * @desc Collect all the data from a form and submit it to the server.
512
+ *
513
+ * @name formToArray
514
+ * @param semantic true if serialization must maintain strict semantic ordering of elements (slower)
515
+ * @type Array<Object>
516
+ * @cat Plugins/Form
517
+ */
518
+ $.fn.formToArray = function(semantic) {
519
+ var a = [];
520
+ if (this.length == 0) return a;
521
+
522
+ var form = this[0];
523
+ var els = semantic ? form.getElementsByTagName('*') : form.elements;
524
+ if (!els) return a;
525
+ for(var i=0, max=els.length; i < max; i++) {
526
+ var el = els[i];
527
+ var n = el.name;
528
+ if (!n) continue;
529
+
530
+ if (semantic && form.clk && el.type == "image") {
531
+ // handle image inputs on the fly when semantic == true
532
+ if(!el.disabled && form.clk == el)
533
+ a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
534
+ continue;
535
+ }
536
+
537
+ var v = $.fieldValue(el, true);
538
+ if (v && v.constructor == Array) {
539
+ for(var j=0, jmax=v.length; j < jmax; j++)
540
+ a.push({name: n, value: v[j]});
541
+ }
542
+ else if (v !== null && typeof v != 'undefined')
543
+ a.push({name: n, value: v});
544
+ }
545
+
546
+ if (!semantic && form.clk) {
547
+ // input type=='image' are not found in elements array! handle them here
548
+ var inputs = form.getElementsByTagName("input");
549
+ for(var i=0, max=inputs.length; i < max; i++) {
550
+ var input = inputs[i];
551
+ var n = input.name;
552
+ if(n && !input.disabled && input.type == "image" && form.clk == input)
553
+ a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
554
+ }
555
+ }
556
+ return a;
557
+ };
558
+
559
+
560
+ /**
561
+ * Serializes form data into a 'submittable' string. This method will return a string
562
+ * in the format: name1=value1&amp;name2=value2
563
+ *
564
+ * The semantic argument can be used to force form serialization in semantic order.
565
+ * If your form must be submitted with name/value pairs in semantic order then pass
566
+ * true for this arg, otherwise pass false (or nothing) to avoid the overhead for
567
+ * this logic (which can be significant for very large forms).
568
+ *
569
+ * @example var data = $("#myForm").formSerialize();
570
+ * $.ajax('POST', "myscript.cgi", data);
571
+ * @desc Collect all the data from a form into a single string
572
+ *
573
+ * @name formSerialize
574
+ * @param semantic true if serialization must maintain strict semantic ordering of elements (slower)
575
+ * @type String
576
+ * @cat Plugins/Form
577
+ */
578
+ $.fn.formSerialize = function(semantic) {
579
+ //hand off to jQuery.param for proper encoding
580
+ return $.param(this.formToArray(semantic));
581
+ };
582
+
583
+
584
+ /**
585
+ * Serializes all field elements in the jQuery object into a query string.
586
+ * This method will return a string in the format: name1=value1&amp;name2=value2
587
+ *
588
+ * The successful argument controls whether or not serialization is limited to
589
+ * 'successful' controls (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
590
+ * The default value of the successful argument is true.
591
+ *
592
+ * @example var data = $("input").fieldSerialize();
593
+ * @desc Collect the data from all successful input elements into a query string
594
+ *
595
+ * @example var data = $(":radio").fieldSerialize();
596
+ * @desc Collect the data from all successful radio input elements into a query string
597
+ *
598
+ * @example var data = $("#myForm :checkbox").fieldSerialize();
599
+ * @desc Collect the data from all successful checkbox input elements in myForm into a query string
600
+ *
601
+ * @example var data = $("#myForm :checkbox").fieldSerialize(false);
602
+ * @desc Collect the data from all checkbox elements in myForm (even the unchecked ones) into a query string
603
+ *
604
+ * @example var data = $(":input").fieldSerialize();
605
+ * @desc Collect the data from all successful input, select, textarea and button elements into a query string
606
+ *
607
+ * @name fieldSerialize
608
+ * @param successful true if only successful controls should be serialized (default is true)
609
+ * @type String
610
+ * @cat Plugins/Form
611
+ */
612
+ $.fn.fieldSerialize = function(successful) {
613
+ var a = [];
614
+ this.each(function() {
615
+ var n = this.name;
616
+ if (!n) return;
617
+ var v = $.fieldValue(this, successful);
618
+ if (v && v.constructor == Array) {
619
+ for (var i=0,max=v.length; i < max; i++)
620
+ a.push({name: n, value: v[i]});
621
+ }
622
+ else if (v !== null && typeof v != 'undefined')
623
+ a.push({name: this.name, value: v});
624
+ });
625
+ //hand off to jQuery.param for proper encoding
626
+ return $.param(a);
627
+ };
628
+
629
+
630
+ /**
631
+ * Returns the value(s) of the element in the matched set. For example, consider the following form:
632
+ *
633
+ * <form><fieldset>
634
+ * <input name="A" type="text" />
635
+ * <input name="A" type="text" />
636
+ * <input name="B" type="checkbox" value="B1" />
637
+ * <input name="B" type="checkbox" value="B2"/>
638
+ * <input name="C" type="radio" value="C1" />
639
+ * <input name="C" type="radio" value="C2" />
640
+ * </fieldset></form>
641
+ *
642
+ * var v = $(':text').fieldValue();
643
+ * // if no values are entered into the text inputs
644
+ * v == ['','']
645
+ * // if values entered into the text inputs are 'foo' and 'bar'
646
+ * v == ['foo','bar']
647
+ *
648
+ * var v = $(':checkbox').fieldValue();
649
+ * // if neither checkbox is checked
650
+ * v === undefined
651
+ * // if both checkboxes are checked
652
+ * v == ['B1', 'B2']
653
+ *
654
+ * var v = $(':radio').fieldValue();
655
+ * // if neither radio is checked
656
+ * v === undefined
657
+ * // if first radio is checked
658
+ * v == ['C1']
659
+ *
660
+ * The successful argument controls whether or not the field element must be 'successful'
661
+ * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
662
+ * The default value of the successful argument is true. If this value is false the value(s)
663
+ * for each element is returned.
664
+ *
665
+ * Note: This method *always* returns an array. If no valid value can be determined the
666
+ * array will be empty, otherwise it will contain one or more values.
667
+ *
668
+ * @example var data = $("#myPasswordElement").fieldValue();
669
+ * alert(data[0]);
670
+ * @desc Alerts the current value of the myPasswordElement element
671
+ *
672
+ * @example var data = $("#myForm :input").fieldValue();
673
+ * @desc Get the value(s) of the form elements in myForm
674
+ *
675
+ * @example var data = $("#myForm :checkbox").fieldValue();
676
+ * @desc Get the value(s) for the successful checkbox element(s) in the jQuery object.
677
+ *
678
+ * @example var data = $("#mySingleSelect").fieldValue();
679
+ * @desc Get the value(s) of the select control
680
+ *
681
+ * @example var data = $(':text').fieldValue();
682
+ * @desc Get the value(s) of the text input or textarea elements
683
+ *
684
+ * @example var data = $("#myMultiSelect").fieldValue();
685
+ * @desc Get the values for the select-multiple control
686
+ *
687
+ * @name fieldValue
688
+ * @param Boolean successful true if only the values for successful controls should be returned (default is true)
689
+ * @type Array<String>
690
+ * @cat Plugins/Form
691
+ */
692
+ $.fn.fieldValue = function(successful) {
693
+ for (var val=[], i=0, max=this.length; i < max; i++) {
694
+ var el = this[i];
695
+ var v = $.fieldValue(el, successful);
696
+ if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length))
697
+ continue;
698
+ v.constructor == Array ? $.merge(val, v) : val.push(v);
699
+ }
700
+ return val;
701
+ };
702
+
703
+ /**
704
+ * Returns the value of the field element.
705
+ *
706
+ * The successful argument controls whether or not the field element must be 'successful'
707
+ * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
708
+ * The default value of the successful argument is true. If the given element is not
709
+ * successful and the successful arg is not false then the returned value will be null.
710
+ *
711
+ * Note: If the successful flag is true (default) but the element is not successful, the return will be null
712
+ * Note: The value returned for a successful select-multiple element will always be an array.
713
+ * Note: If the element has no value the return value will be undefined.
714
+ *
715
+ * @example var data = jQuery.fieldValue($("#myPasswordElement")[0]);
716
+ * @desc Gets the current value of the myPasswordElement element
717
+ *
718
+ * @name fieldValue
719
+ * @param Element el The DOM element for which the value will be returned
720
+ * @param Boolean successful true if value returned must be for a successful controls (default is true)
721
+ * @type String or Array<String> or null or undefined
722
+ * @cat Plugins/Form
723
+ */
724
+ $.fieldValue = function(el, successful) {
725
+ var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
726
+ if (typeof successful == 'undefined') successful = true;
727
+
728
+ if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
729
+ (t == 'checkbox' || t == 'radio') && !el.checked ||
730
+ (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
731
+ tag == 'select' && el.selectedIndex == -1))
732
+ return null;
733
+
734
+ if (tag == 'select') {
735
+ var index = el.selectedIndex;
736
+ if (index < 0) return null;
737
+ var a = [], ops = el.options;
738
+ var one = (t == 'select-one');
739
+ var max = (one ? index+1 : ops.length);
740
+ for(var i=(one ? index : 0); i < max; i++) {
741
+ var op = ops[i];
742
+ if (op.selected) {
743
+ // extra pain for IE...
744
+ var v = $.browser.msie && !(op.attributes['value'].specified) ? op.text : op.value;
745
+ if (one) return v;
746
+ a.push(v);
747
+ }
748
+ }
749
+ return a;
750
+ }
751
+ return el.value;
752
+ };
753
+
754
+
755
+ /**
756
+ * Clears the form data. Takes the following actions on the form's input fields:
757
+ * - input text fields will have their 'value' property set to the empty string
758
+ * - select elements will have their 'selectedIndex' property set to -1
759
+ * - checkbox and radio inputs will have their 'checked' property set to false
760
+ * - inputs of type submit, button, reset, and hidden will *not* be effected
761
+ * - button elements will *not* be effected
762
+ *
763
+ * @example $('form').clearForm();
764
+ * @desc Clears all forms on the page.
765
+ *
766
+ * @name clearForm
767
+ * @type jQuery
768
+ * @cat Plugins/Form
769
+ */
770
+ $.fn.clearForm = function() {
771
+ return this.each(function() {
772
+ $('input,select,textarea', this).clearFields();
773
+ });
774
+ };
775
+
776
+ /**
777
+ * Clears the selected form elements. Takes the following actions on the matched elements:
778
+ * - input text fields will have their 'value' property set to the empty string
779
+ * - select elements will have their 'selectedIndex' property set to -1
780
+ * - checkbox and radio inputs will have their 'checked' property set to false
781
+ * - inputs of type submit, button, reset, and hidden will *not* be effected
782
+ * - button elements will *not* be effected
783
+ *
784
+ * @example $('.myInputs').clearFields();
785
+ * @desc Clears all inputs with class myInputs
786
+ *
787
+ * @name clearFields
788
+ * @type jQuery
789
+ * @cat Plugins/Form
790
+ */
791
+ $.fn.clearFields = $.fn.clearInputs = function() {
792
+ return this.each(function() {
793
+ var t = this.type, tag = this.tagName.toLowerCase();
794
+ if (t == 'text' || t == 'password' || tag == 'textarea')
795
+ this.value = '';
796
+ else if (t == 'checkbox' || t == 'radio')
797
+ this.checked = false;
798
+ else if (tag == 'select')
799
+ this.selectedIndex = -1;
800
+ });
801
+ };
802
+
803
+
804
+ /**
805
+ * Resets the form data. Causes all form elements to be reset to their original value.
806
+ *
807
+ * @example $('form').resetForm();
808
+ * @desc Resets all forms on the page.
809
+ *
810
+ * @name resetForm
811
+ * @type jQuery
812
+ * @cat Plugins/Form
813
+ */
814
+ $.fn.resetForm = function() {
815
+ return this.each(function() {
816
+ // guard against an input with the name of 'reset'
817
+ // note that IE reports the reset function as an 'object'
818
+ if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType))
819
+ this.reset();
820
+ });
821
+ };
822
+
823
+
824
+ /**
825
+ * Enables or disables any matching elements.
826
+ *
827
+ * @example $(':radio').enabled(false);
828
+ * @desc Disables all radio buttons
829
+ *
830
+ * @name select
831
+ * @type jQuery
832
+ * @cat Plugins/Form
833
+ */
834
+ $.fn.enable = function(b) {
835
+ if (b == undefined) b = true;
836
+ return this.each(function() {
837
+ this.disabled = !b
838
+ });
839
+ };
840
+
841
+ /**
842
+ * Checks/unchecks any matching checkboxes or radio buttons and
843
+ * selects/deselects and matching option elements.
844
+ *
845
+ * @example $(':checkbox').select();
846
+ * @desc Checks all checkboxes
847
+ *
848
+ * @name select
849
+ * @type jQuery
850
+ * @cat Plugins/Form
851
+ */
852
+ $.fn.select = function(select) {
853
+ if (select == undefined) select = true;
854
+ return this.each(function() {
855
+ var t = this.type;
856
+ if (t == 'checkbox' || t == 'radio')
857
+ this.checked = select;
858
+ else if (this.tagName.toLowerCase() == 'option') {
859
+ var $sel = $(this).parent('select');
860
+ if (select && $sel[0] && $sel[0].type == 'select-one') {
861
+ // deselect all other options
862
+ $sel.find('option').select(false);
863
+ }
864
+ this.selected = select;
865
+ }
866
+ });
867
+ };
868
+
869
+ })(jQuery);