spiderfw 0.6.1 → 0.6.2

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 (204) hide show
  1. data/CHANGELOG +5 -0
  2. data/VERSION +1 -1
  3. data/apps/core/auth/lib/rbac.rb +15 -0
  4. data/apps/core/auth/models/mixins/rbac_provider.rb +28 -10
  5. data/apps/core/auth/po/it/spider_auth.po +3 -2
  6. data/apps/core/auth/po/spider_auth.pot +3 -2
  7. data/apps/core/auth/views/login.shtml +1 -1
  8. data/apps/core/components/po/it/spider_components.po +11 -12
  9. data/apps/core/components/po/spider_components.pot +11 -10
  10. data/apps/core/components/public/css/crud.css +4 -0
  11. data/apps/core/components/public/js/jquery/jquery-ui-1.8.11/css/Aristo/jquery-ui.custom.css +1 -0
  12. data/apps/core/components/public/js/jquery/plugins/bsmselect/README.md +1 -0
  13. data/apps/core/components/public/js/jquery/plugins/bsmselect/js/jquery.bsmselect.js +11 -11
  14. data/apps/core/components/public/js/jquery/plugins/jquery.form.js +325 -154
  15. data/apps/core/components/public/js/spider.js +6 -0
  16. data/apps/core/components/widgets/admin/admin.rb +44 -1
  17. data/apps/core/components/widgets/crud/crud.rb +48 -27
  18. data/apps/core/components/widgets/crud/crud.shtml +5 -3
  19. data/apps/core/components/widgets/table/table.rb +3 -3
  20. data/apps/core/forms/po/it/spider_forms.po +4 -4
  21. data/apps/core/forms/po/spider_forms.pot +4 -3
  22. data/apps/core/forms/public/ckeditor/CHANGES.html +1295 -0
  23. data/apps/core/forms/public/ckeditor/INSTALL.html +92 -0
  24. data/apps/core/forms/public/ckeditor/LICENSE.html +1334 -0
  25. data/apps/core/forms/public/ckeditor/adapters/jquery.js +2 -2
  26. data/apps/core/forms/public/ckeditor/ckeditor.js +141 -133
  27. data/apps/core/forms/public/ckeditor/ckeditor_basic.js +8 -0
  28. data/apps/core/forms/public/ckeditor/ckeditor_basic_source.js +20 -0
  29. data/apps/core/forms/public/ckeditor/ckeditor_source.js +25 -0
  30. data/apps/core/forms/public/ckeditor/config.js +11 -0
  31. data/apps/core/forms/public/ckeditor/contents.css +23 -0
  32. data/apps/core/forms/public/ckeditor/lang/_languages.js +2 -2
  33. data/apps/core/forms/public/ckeditor/lang/_translationstatus.txt +58 -57
  34. data/apps/core/forms/public/ckeditor/lang/af.js +2 -2
  35. data/apps/core/forms/public/ckeditor/lang/ar.js +2 -2
  36. data/apps/core/forms/public/ckeditor/lang/bg.js +2 -2
  37. data/apps/core/forms/public/ckeditor/lang/bn.js +2 -2
  38. data/apps/core/forms/public/ckeditor/lang/bs.js +2 -2
  39. data/apps/core/forms/public/ckeditor/lang/ca.js +2 -2
  40. data/apps/core/forms/public/ckeditor/lang/cs.js +2 -2
  41. data/apps/core/forms/public/ckeditor/lang/cy.js +2 -2
  42. data/apps/core/forms/public/ckeditor/lang/da.js +2 -2
  43. data/apps/core/forms/public/ckeditor/lang/de.js +2 -2
  44. data/apps/core/forms/public/ckeditor/lang/el.js +2 -2
  45. data/apps/core/forms/public/ckeditor/lang/en-au.js +2 -2
  46. data/apps/core/forms/public/ckeditor/lang/en-ca.js +2 -2
  47. data/apps/core/forms/public/ckeditor/lang/en-gb.js +2 -2
  48. data/apps/core/forms/public/ckeditor/lang/en.js +2 -2
  49. data/apps/core/forms/public/ckeditor/lang/eo.js +2 -2
  50. data/apps/core/forms/public/ckeditor/lang/es.js +2 -2
  51. data/apps/core/forms/public/ckeditor/lang/et.js +2 -2
  52. data/apps/core/forms/public/ckeditor/lang/eu.js +2 -2
  53. data/apps/core/forms/public/ckeditor/lang/fa.js +2 -2
  54. data/apps/core/forms/public/ckeditor/lang/fi.js +2 -2
  55. data/apps/core/forms/public/ckeditor/lang/fo.js +2 -2
  56. data/apps/core/forms/public/ckeditor/lang/fr-ca.js +2 -2
  57. data/apps/core/forms/public/ckeditor/lang/fr.js +2 -2
  58. data/apps/core/forms/public/ckeditor/lang/gl.js +2 -2
  59. data/apps/core/forms/public/ckeditor/lang/gu.js +2 -2
  60. data/apps/core/forms/public/ckeditor/lang/he.js +2 -2
  61. data/apps/core/forms/public/ckeditor/lang/hi.js +2 -2
  62. data/apps/core/forms/public/ckeditor/lang/hr.js +2 -2
  63. data/apps/core/forms/public/ckeditor/lang/hu.js +2 -2
  64. data/apps/core/forms/public/ckeditor/lang/is.js +2 -2
  65. data/apps/core/forms/public/ckeditor/lang/it.js +2 -2
  66. data/apps/core/forms/public/ckeditor/lang/ja.js +2 -2
  67. data/apps/core/forms/public/ckeditor/lang/ka.js +6 -0
  68. data/apps/core/forms/public/ckeditor/lang/km.js +2 -2
  69. data/apps/core/forms/public/ckeditor/lang/ko.js +2 -2
  70. data/apps/core/forms/public/ckeditor/lang/lt.js +2 -2
  71. data/apps/core/forms/public/ckeditor/lang/lv.js +2 -2
  72. data/apps/core/forms/public/ckeditor/lang/mn.js +2 -2
  73. data/apps/core/forms/public/ckeditor/lang/ms.js +2 -2
  74. data/apps/core/forms/public/ckeditor/lang/nb.js +2 -2
  75. data/apps/core/forms/public/ckeditor/lang/nl.js +2 -2
  76. data/apps/core/forms/public/ckeditor/lang/no.js +2 -2
  77. data/apps/core/forms/public/ckeditor/lang/pl.js +2 -2
  78. data/apps/core/forms/public/ckeditor/lang/pt-br.js +2 -2
  79. data/apps/core/forms/public/ckeditor/lang/pt.js +2 -2
  80. data/apps/core/forms/public/ckeditor/lang/ro.js +2 -2
  81. data/apps/core/forms/public/ckeditor/lang/ru.js +2 -2
  82. data/apps/core/forms/public/ckeditor/lang/sk.js +2 -2
  83. data/apps/core/forms/public/ckeditor/lang/sl.js +2 -2
  84. data/apps/core/forms/public/ckeditor/lang/sr-latn.js +2 -2
  85. data/apps/core/forms/public/ckeditor/lang/sr.js +2 -2
  86. data/apps/core/forms/public/ckeditor/lang/sv.js +2 -2
  87. data/apps/core/forms/public/ckeditor/lang/th.js +2 -2
  88. data/apps/core/forms/public/ckeditor/lang/tr.js +2 -2
  89. data/apps/core/forms/public/ckeditor/lang/uk.js +2 -2
  90. data/apps/core/forms/public/ckeditor/lang/vi.js +2 -2
  91. data/apps/core/forms/public/ckeditor/lang/zh-cn.js +2 -2
  92. data/apps/core/forms/public/ckeditor/lang/zh.js +2 -2
  93. data/apps/core/forms/public/ckeditor/plugins/a11yhelp/dialogs/a11yhelp.js +2 -2
  94. data/apps/core/forms/public/ckeditor/plugins/a11yhelp/lang/en.js +2 -2
  95. data/apps/core/forms/public/ckeditor/plugins/a11yhelp/lang/he.js +1 -1
  96. data/apps/core/forms/public/ckeditor/plugins/about/dialogs/about.js +2 -2
  97. data/apps/core/forms/public/ckeditor/plugins/adobeair/plugin.js +6 -0
  98. data/apps/core/forms/public/ckeditor/plugins/ajax/plugin.js +6 -0
  99. data/apps/core/forms/public/ckeditor/plugins/autogrow/plugin.js +2 -2
  100. data/apps/core/forms/public/ckeditor/plugins/bbcode/plugin.js +9 -0
  101. data/apps/core/forms/public/ckeditor/plugins/clipboard/dialogs/paste.js +3 -3
  102. data/apps/core/forms/public/ckeditor/plugins/colordialog/dialogs/colordialog.js +3 -3
  103. data/apps/core/forms/public/ckeditor/plugins/devtools/lang/en.js +6 -0
  104. data/apps/core/forms/public/ckeditor/plugins/devtools/plugin.js +6 -0
  105. data/apps/core/forms/public/ckeditor/plugins/dialog/dialogDefinition.js +1 -1
  106. data/apps/core/forms/public/ckeditor/plugins/div/dialogs/div.js +1 -1
  107. data/apps/core/forms/public/ckeditor/plugins/docprops/dialogs/docprops.js +10 -0
  108. data/apps/core/forms/public/ckeditor/plugins/docprops/plugin.js +6 -0
  109. data/apps/core/forms/public/ckeditor/plugins/find/dialogs/find.js +4 -4
  110. data/apps/core/forms/public/ckeditor/plugins/flash/dialogs/flash.js +4 -4
  111. data/apps/core/forms/public/ckeditor/plugins/forms/dialogs/button.js +2 -2
  112. data/apps/core/forms/public/ckeditor/plugins/forms/dialogs/checkbox.js +2 -2
  113. data/apps/core/forms/public/ckeditor/plugins/forms/dialogs/form.js +2 -2
  114. data/apps/core/forms/public/ckeditor/plugins/forms/dialogs/hiddenfield.js +2 -2
  115. data/apps/core/forms/public/ckeditor/plugins/forms/dialogs/radio.js +2 -2
  116. data/apps/core/forms/public/ckeditor/plugins/forms/dialogs/select.js +4 -4
  117. data/apps/core/forms/public/ckeditor/plugins/forms/dialogs/textarea.js +2 -2
  118. data/apps/core/forms/public/ckeditor/plugins/forms/dialogs/textfield.js +2 -3
  119. data/apps/core/forms/public/ckeditor/plugins/iframe/dialogs/iframe.js +7 -0
  120. data/apps/core/forms/public/ckeditor/plugins/iframe/images/placeholder.png +0 -0
  121. data/apps/core/forms/public/ckeditor/plugins/iframedialog/plugin.js +2 -2
  122. data/apps/core/forms/public/ckeditor/plugins/image/dialogs/image.js +8 -8
  123. data/apps/core/forms/public/ckeditor/plugins/link/dialogs/anchor.js +2 -2
  124. data/apps/core/forms/public/ckeditor/plugins/link/dialogs/link.js +7 -7
  125. data/apps/core/forms/public/ckeditor/plugins/liststyle/dialogs/liststyle.js +1 -1
  126. data/apps/core/forms/public/ckeditor/plugins/pastefromword/filter/default.js +7 -6
  127. data/apps/core/forms/public/ckeditor/plugins/pastetext/dialogs/pastetext.js +2 -2
  128. data/apps/core/forms/public/ckeditor/plugins/placeholder/dialogs/placeholder.js +6 -0
  129. data/apps/core/forms/public/ckeditor/plugins/placeholder/lang/en.js +6 -0
  130. data/apps/core/forms/public/ckeditor/plugins/placeholder/lang/he.js +6 -0
  131. data/apps/core/forms/public/ckeditor/plugins/placeholder/placeholder.gif +0 -0
  132. data/apps/core/forms/public/ckeditor/plugins/placeholder/plugin.js +6 -0
  133. data/apps/core/forms/public/ckeditor/plugins/scayt/dialogs/options.js +4 -4
  134. data/apps/core/forms/public/ckeditor/plugins/scayt/dialogs/toolbar.css +1 -1
  135. data/apps/core/forms/public/ckeditor/plugins/smiley/dialogs/smiley.js +3 -3
  136. data/apps/core/forms/public/ckeditor/plugins/specialchar/dialogs/specialchar.js +3 -3
  137. data/apps/core/forms/public/ckeditor/plugins/specialchar/lang/en.js +6 -0
  138. data/apps/core/forms/public/ckeditor/plugins/styles/styles/default.js +1 -1
  139. data/apps/core/forms/public/ckeditor/plugins/stylesheetparser/plugin.js +6 -0
  140. data/apps/core/forms/public/ckeditor/plugins/table/dialogs/table.js +3 -3
  141. data/apps/core/forms/public/ckeditor/plugins/tableresize/plugin.js +2 -2
  142. data/apps/core/forms/public/ckeditor/plugins/tabletools/dialogs/tableCell.js +4 -4
  143. data/apps/core/forms/public/ckeditor/plugins/templates/dialogs/templates.js +2 -2
  144. data/apps/core/forms/public/ckeditor/plugins/templates/templates/default.js +1 -1
  145. data/apps/core/forms/public/ckeditor/plugins/uicolor/dialogs/uicolor.js +1 -1
  146. data/apps/core/forms/public/ckeditor/plugins/uicolor/lang/en.js +1 -1
  147. data/apps/core/forms/public/ckeditor/plugins/uicolor/lang/he.js +1 -1
  148. data/apps/core/forms/public/ckeditor/plugins/uicolor/plugin.js +1 -1
  149. data/apps/core/forms/public/ckeditor/plugins/uicolor/yui/assets/yui.css +1 -1
  150. data/apps/core/forms/public/ckeditor/plugins/uicolor/yui/yui.js +1 -1
  151. data/apps/core/forms/public/ckeditor/plugins/wsc/dialogs/ciframe.html +1 -1
  152. data/apps/core/forms/public/ckeditor/plugins/wsc/dialogs/tmpFrameset.html +1 -1
  153. data/apps/core/forms/public/ckeditor/plugins/wsc/dialogs/wsc.css +1 -1
  154. data/apps/core/forms/public/ckeditor/plugins/wsc/dialogs/wsc.js +3 -3
  155. data/apps/core/forms/public/ckeditor/plugins/xml/plugin.js +6 -0
  156. data/apps/core/forms/public/ckeditor/skins/kama/dialog.css +5 -5
  157. data/apps/core/forms/public/ckeditor/skins/kama/editor.css +9 -8
  158. data/apps/core/forms/public/ckeditor/skins/kama/icons.png +0 -0
  159. data/apps/core/forms/public/ckeditor/skins/kama/icons_rtl.png +0 -0
  160. data/apps/core/forms/public/ckeditor/skins/kama/skin.js +3 -3
  161. data/apps/core/forms/public/ckeditor/skins/kama/templates.css +1 -1
  162. data/apps/core/forms/public/ckeditor/themes/default/theme.js +4 -4
  163. data/apps/core/forms/public/css/form.css +1 -0
  164. data/apps/core/forms/public/css/html_area.css +3 -0
  165. data/apps/core/forms/public/html_area.js +4 -4
  166. data/apps/core/forms/public/search_select.js +2 -2
  167. data/apps/core/forms/public/select.js +5 -5
  168. data/apps/core/forms/tags/element_label.erb +5 -2
  169. data/apps/core/forms/tags/element_row.erb +7 -6
  170. data/apps/core/forms/tags/row.erb +6 -4
  171. data/apps/core/forms/widgets/form/form.rb +5 -4
  172. data/apps/core/forms/widgets/inputs/html_area/html_area.rb +10 -4
  173. data/apps/core/forms/widgets/inputs/html_area/html_area.shtml +1 -0
  174. data/apps/core/forms/widgets/inputs/select/select.rb +18 -5
  175. data/apps/core/forms/widgets/inputs/select/select.shtml +3 -0
  176. data/apps/master/po/master.pot +408 -0
  177. data/apps/messenger/po/it/spider_messenger.po +6 -10
  178. data/apps/messenger/po/spider_messenger.pot +2 -1
  179. data/blueprints/home/{Gemfile → Gemfile.disabled} +0 -0
  180. data/lib/spiderfw/config/configuration.rb +5 -0
  181. data/lib/spiderfw/config/options/spider.rb +2 -2
  182. data/lib/spiderfw/controller/controller.rb +4 -1
  183. data/lib/spiderfw/controller/mixins/http_mixin.rb +2 -0
  184. data/lib/spiderfw/create.rb +9 -5
  185. data/lib/spiderfw/model/base_model.rb +32 -9
  186. data/lib/spiderfw/model/condition.rb +7 -0
  187. data/lib/spiderfw/model/datatypes/text.rb +3 -1
  188. data/lib/spiderfw/model/mappers/db_mapper.rb +19 -5
  189. data/lib/spiderfw/model/mappers/mapper.rb +1 -1
  190. data/lib/spiderfw/model/mixins/tree.rb +2 -1
  191. data/lib/spiderfw/model/query_set.rb +14 -13
  192. data/lib/spiderfw/model/storage/db/adapters/mysql.rb +7 -2
  193. data/lib/spiderfw/model/storage/db/db_schema.rb +4 -2
  194. data/lib/spiderfw/model/storage/db/db_storage.rb +4 -4
  195. data/lib/spiderfw/model/unit_of_work.rb +3 -1
  196. data/lib/spiderfw/templates/blocks/html.rb +2 -2
  197. data/lib/spiderfw/templates/blocks/lambda.rb +25 -0
  198. data/lib/spiderfw/templates/blocks/recurse.rb +41 -0
  199. data/lib/spiderfw/templates/blocks/widget.rb +2 -3
  200. data/lib/spiderfw/templates/layout.rb +20 -3
  201. data/lib/spiderfw/templates/template.rb +35 -29
  202. data/lib/spiderfw/templates/template_blocks.rb +6 -0
  203. data/lib/spiderfw/widget/widget.rb +2 -1
  204. metadata +35 -5
@@ -1,7 +1,7 @@
1
- /*
1
+ /*!
2
2
  * jQuery Form Plugin
3
- * version: 2.33 (22-SEP-2009)
4
- * @requires jQuery v1.2.6 or later
3
+ * version: 2.73 (03-MAY-2011)
4
+ * @requires jQuery v1.3.2 or later
5
5
  *
6
6
  * Examples and documentation at: http://malsup.com/jquery/form/
7
7
  * Dual licensed under the MIT and GPL licenses:
@@ -18,11 +18,11 @@
18
18
  to bind your own submit handler to the form. For example,
19
19
 
20
20
  $(document).ready(function() {
21
- $('#myForm').bind('submit', function() {
21
+ $('#myForm').bind('submit', function(e) {
22
+ e.preventDefault(); // <-- important
22
23
  $(this).ajaxSubmit({
23
24
  target: '#output'
24
25
  });
25
- return false; // <-- important!
26
26
  });
27
27
  });
28
28
 
@@ -50,20 +50,24 @@ $.fn.ajaxSubmit = function(options) {
50
50
  return this;
51
51
  }
52
52
 
53
- if (typeof options == 'function')
53
+ if (typeof options == 'function') {
54
54
  options = { success: options };
55
+ }
55
56
 
56
- var url = $.trim(this.attr('action'));
57
- url = url || window.location.href || '';
57
+ var action = this.attr('action');
58
+ var url = (typeof action === 'string') ? $.trim(action) : '';
58
59
  if (url) {
59
60
  // clean url (don't include hash vaue)
60
61
  url = (url.match(/^([^#]+)/)||[])[1];
61
- }
62
+ }
63
+ url = url || window.location.href || '';
62
64
 
63
- options = $.extend({
65
+ options = $.extend(true, {
64
66
  url: url,
65
- type: this.attr('method') || 'GET'
66
- }, options || {});
67
+ success: $.ajaxSettings.success,
68
+ type: this[0].getAttribute('method') || 'GET', // IE7 massage (see issue 57)
69
+ iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
70
+ }, options);
67
71
 
68
72
  // hook for manipulating the form data before it is extracted;
69
73
  // convenient for use with rich editors like tinyMCE or FCKEditor
@@ -80,16 +84,20 @@ $.fn.ajaxSubmit = function(options) {
80
84
  return this;
81
85
  }
82
86
 
83
- var a = this.formToArray(options.semantic);
87
+ var n,v,a = this.formToArray(options.semantic);
84
88
  if (options.data) {
85
89
  options.extraData = options.data;
86
- for (var n in options.data) {
87
- if(options.data[n] instanceof Array) {
88
- for (var k in options.data[n])
89
- a.push( { name: n, value: options.data[n][k] } );
90
- }
91
- else
92
- a.push( { name: n, value: options.data[n] } );
90
+ for (n in options.data) {
91
+ if(options.data[n] instanceof Array) {
92
+ for (var k in options.data[n]) {
93
+ a.push( { name: n, value: options.data[n][k] } );
94
+ }
95
+ }
96
+ else {
97
+ v = options.data[n];
98
+ v = $.isFunction(v) ? v() : v; // if value is fn, invoke it
99
+ a.push( { name: n, value: v } );
100
+ }
93
101
  }
94
102
  }
95
103
 
@@ -112,50 +120,57 @@ $.fn.ajaxSubmit = function(options) {
112
120
  options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
113
121
  options.data = null; // data is null for 'get'
114
122
  }
115
- else
123
+ else {
116
124
  options.data = q; // data is the query string for 'post'
125
+ }
117
126
 
118
127
  var $form = this, callbacks = [];
119
- if (options.resetForm) callbacks.push(function() { $form.resetForm(); });
120
- if (options.clearForm) callbacks.push(function() { $form.clearForm(); });
128
+ if (options.resetForm) {
129
+ callbacks.push(function() { $form.resetForm(); });
130
+ }
131
+ if (options.clearForm) {
132
+ callbacks.push(function() { $form.clearForm(); });
133
+ }
121
134
 
122
135
  // perform a load on the target only if dataType is not provided
123
136
  if (!options.dataType && options.target) {
124
137
  var oldSuccess = options.success || function(){};
125
138
  callbacks.push(function(data) {
126
- $(options.target).html(data).each(oldSuccess, arguments);
139
+ var fn = options.replaceTarget ? 'replaceWith' : 'html';
140
+ $(options.target)[fn](data).each(oldSuccess, arguments);
127
141
  });
128
142
  }
129
- else if (options.success)
143
+ else if (options.success) {
130
144
  callbacks.push(options.success);
145
+ }
131
146
 
132
- options.success = function(data, status) {
133
- for (var i=0, max=callbacks.length; i < max; i++)
134
- callbacks[i].apply(options, [data, status, $form]);
147
+ options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
148
+ var context = options.context || options; // jQuery 1.4+ supports scope context
149
+ for (var i=0, max=callbacks.length; i < max; i++) {
150
+ callbacks[i].apply(context, [data, status, xhr || $form, $form]);
151
+ }
135
152
  };
136
153
 
137
154
  // are there files to upload?
138
- var files = $('input:file', this).fieldValue();
139
- var found = false;
140
- for (var j=0; j < files.length; j++)
141
- if (files[j])
142
- found = true;
143
-
144
- var multipart = false;
145
- // var mp = 'multipart/form-data';
146
- // multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
155
+ var fileInputs = $('input:file', this).length > 0;
156
+ var mp = 'multipart/form-data';
157
+ var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
147
158
 
148
159
  // options.iframe allows user to force iframe mode
149
- if (options.iframe || found || multipart) {
160
+ // 06-NOV-09: now defaulting to iframe mode if file input is detected
161
+ if (options.iframe !== false && (fileInputs || options.iframe || multipart)) {
150
162
  // hack to fix Safari hang (thanks to Tim Molendijk for this)
151
163
  // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
152
- if (options.closeKeepAlive)
164
+ if (options.closeKeepAlive) {
153
165
  $.get(options.closeKeepAlive, fileUpload);
154
- else
166
+ }
167
+ else {
155
168
  fileUpload();
156
- }
157
- else
158
- $.ajax(options);
169
+ }
170
+ }
171
+ else {
172
+ $.ajax(options);
173
+ }
159
174
 
160
175
  // fire 'notify' event
161
176
  this.trigger('form-submit-notify', [this, options]);
@@ -166,16 +181,17 @@ $.fn.ajaxSubmit = function(options) {
166
181
  function fileUpload() {
167
182
  var form = $form[0];
168
183
 
169
- if ($(':input[name=submit]', form).length) {
170
- alert('Error: Form elements must not be named "submit".');
184
+ if ($(':input[name=submit],:input[id=submit]', form).length) {
185
+ // if there is an input with a name or id of 'submit' then we won't be
186
+ // able to invoke the submit fn on the form (at least not x-browser)
187
+ alert('Error: Form elements must not have name or id of "submit".');
171
188
  return;
172
189
  }
173
-
174
- var opts = $.extend({}, $.ajaxSettings, options);
175
- var s = $.extend(true, {}, $.extend(true, {}, $.ajaxSettings), opts);
176
-
177
- var id = 'jqFormIO' + (new Date().getTime());
178
- var $io = $('<iframe id="' + id + '" name="' + id + '" src="about:blank" />');
190
+
191
+ var s = $.extend(true, {}, $.ajaxSettings, options);
192
+ s.context = s.context || s;
193
+ var id = 'jqFormIO' + (new Date().getTime()), fn = '_'+id;
194
+ var $io = $('<iframe id="' + id + '" name="' + id + '" src="'+ s.iframeSrc +'" />');
179
195
  var io = $io[0];
180
196
 
181
197
  $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
@@ -189,55 +205,69 @@ $.fn.ajaxSubmit = function(options) {
189
205
  getAllResponseHeaders: function() {},
190
206
  getResponseHeader: function() {},
191
207
  setRequestHeader: function() {},
192
- abort: function() {
208
+ abort: function(status) {
209
+ var e = (status === 'timeout' ? 'timeout' : 'aborted');
210
+ log('aborting upload... ' + e);
193
211
  this.aborted = 1;
194
- $io.attr('src','about:blank'); // abort op in progress
212
+ $io.attr('src', s.iframeSrc); // abort op in progress
213
+ xhr.error = e;
214
+ s.error && s.error.call(s.context, xhr, e, e);
215
+ g && $.event.trigger("ajaxError", [xhr, s, e]);
216
+ s.complete && s.complete.call(s.context, xhr, e);
195
217
  }
196
218
  };
197
219
 
198
- var g = opts.global;
220
+ var g = s.global;
199
221
  // trigger ajax global events so that activity/block indicators work like normal
200
- if (g && ! $.active++) $.event.trigger("ajaxStart");
201
- if (g) $.event.trigger("ajaxSend", [xhr, opts]);
222
+ if (g && ! $.active++) {
223
+ $.event.trigger("ajaxStart");
224
+ }
225
+ if (g) {
226
+ $.event.trigger("ajaxSend", [xhr, s]);
227
+ }
202
228
 
203
- if (s.beforeSend && s.beforeSend(xhr, s) === false) {
204
- s.global && $.active--;
229
+ if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
230
+ if (s.global) {
231
+ $.active--;
232
+ }
205
233
  return;
206
234
  }
207
- if (xhr.aborted)
235
+ if (xhr.aborted) {
208
236
  return;
237
+ }
209
238
 
210
- var cbInvoked = 0;
211
- var timedOut = 0;
239
+ var timedOut = 0, timeoutHandle;
212
240
 
213
241
  // add submitting element to data if we know it
214
242
  var sub = form.clk;
215
243
  if (sub) {
216
244
  var n = sub.name;
217
245
  if (n && !sub.disabled) {
218
- options.extraData = options.extraData || {};
219
- options.extraData[n] = sub.value;
246
+ s.extraData = s.extraData || {};
247
+ s.extraData[n] = sub.value;
220
248
  if (sub.type == "image") {
221
- options.extraData[name+'.x'] = form.clk_x;
222
- options.extraData[name+'.y'] = form.clk_y;
249
+ s.extraData[n+'.x'] = form.clk_x;
250
+ s.extraData[n+'.y'] = form.clk_y;
223
251
  }
224
252
  }
225
253
  }
226
254
 
227
255
  // take a breath so that pending repaints get some cpu time before the upload starts
228
- setTimeout(function() {
256
+ function doSubmit() {
229
257
  // make sure form attrs are set
230
258
  var t = $form.attr('target'), a = $form.attr('action');
231
259
 
232
260
  // update form attrs in IE friendly way
233
261
  form.setAttribute('target',id);
234
- if (form.getAttribute('method') != 'POST')
262
+ if (form.getAttribute('method') != 'POST') {
235
263
  form.setAttribute('method', 'POST');
236
- if (form.getAttribute('action') != opts.url)
237
- form.setAttribute('action', opts.url);
264
+ }
265
+ if (form.getAttribute('action') != s.url) {
266
+ form.setAttribute('action', s.url);
267
+ }
238
268
 
239
269
  // ie borks in some cases when setting encoding
240
- if (! options.skipEncodingOverride) {
270
+ if (! s.skipEncodingOverride) {
241
271
  $form.attr({
242
272
  encoding: 'multipart/form-data',
243
273
  enctype: 'multipart/form-data'
@@ -245,116 +275,195 @@ $.fn.ajaxSubmit = function(options) {
245
275
  }
246
276
 
247
277
  // support timout
248
- if (opts.timeout)
249
- setTimeout(function() { timedOut = true; cb(); }, opts.timeout);
278
+ if (s.timeout) {
279
+ timeoutHandle = setTimeout(function() { timedOut = true; cb(true); }, s.timeout);
280
+ }
250
281
 
251
282
  // add "extra" data to form if provided in options
252
283
  var extraInputs = [];
253
284
  try {
254
- if (options.extraData)
255
- for (var n in options.extraData)
285
+ if (s.extraData) {
286
+ for (var n in s.extraData) {
256
287
  extraInputs.push(
257
- $('<input type="hidden" name="'+n+'" value="'+options.extraData[n]+'" />')
288
+ $('<input type="hidden" name="'+n+'" value="'+s.extraData[n]+'" />')
258
289
  .appendTo(form)[0]);
290
+ }
291
+ }
259
292
 
260
293
  // add iframe to doc and submit the form
261
294
  $io.appendTo('body');
262
- io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
295
+ io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
263
296
  form.submit();
264
297
  }
265
298
  finally {
266
299
  // reset attrs and remove "extra" input elements
267
300
  form.setAttribute('action',a);
268
- t ? form.setAttribute('target', t) : $form.removeAttr('target');
301
+ if(t) {
302
+ form.setAttribute('target', t);
303
+ } else {
304
+ $form.removeAttr('target');
305
+ }
269
306
  $(extraInputs).remove();
270
307
  }
271
- }, 10);
272
-
273
- var domCheckCount = 50;
308
+ }
274
309
 
275
- function cb() {
276
- if (cbInvoked++) return;
310
+ if (s.forceSync) {
311
+ doSubmit();
312
+ }
313
+ else {
314
+ setTimeout(doSubmit, 10); // this lets dom updates render
315
+ }
316
+
317
+ var data, doc, domCheckCount = 50, callbackProcessed;
277
318
 
278
- io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);
319
+ function cb(e) {
320
+ if (xhr.aborted || callbackProcessed) {
321
+ return;
322
+ }
323
+ if (e === true && xhr) {
324
+ xhr.abort('timeout');
325
+ return;
326
+ }
327
+
328
+ var doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
329
+ if (!doc || doc.location.href == s.iframeSrc) {
330
+ // response not received yet
331
+ if (!timedOut)
332
+ return;
333
+ }
334
+ io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);
279
335
 
280
336
  var ok = true;
281
337
  try {
282
- if (timedOut) throw 'timeout';
283
- // extract the server response from the iframe
284
- var data, doc;
338
+ if (timedOut) {
339
+ throw 'timeout';
340
+ }
285
341
 
286
- doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
287
-
288
- var isXml = opts.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
342
+ var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
289
343
  log('isXml='+isXml);
290
- if (!isXml && (doc.body == null || doc.body.innerHTML == '')) {
291
- if (--domCheckCount) {
344
+ if (!isXml && window.opera && (doc.body == null || doc.body.innerHTML == '')) {
345
+ if (--domCheckCount) {
292
346
  // in some browsers (Opera) the iframe DOM is not always traversable when
293
347
  // the onload callback fires, so we loop a bit to accommodate
294
- cbInvoked = 0;
295
- setTimeout(cb, 100);
348
+ log('requeing onLoad callback, DOM not available');
349
+ setTimeout(cb, 250);
296
350
  return;
297
351
  }
298
- log('Could not access iframe DOM after 50 tries.');
299
- return;
352
+ // let this fall through because server response could be an empty document
353
+ //log('Could not access iframe DOM after mutiple tries.');
354
+ //throw 'DOMException: not available';
300
355
  }
301
356
 
302
- xhr.responseText = doc.body ? doc.body.innerHTML : null;
357
+ //log('response detected');
358
+ xhr.responseText = doc.body ? doc.body.innerHTML : doc.documentElement ? doc.documentElement.innerHTML : null;
303
359
  xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
360
+ if (isXml)
361
+ s.dataType = 'xml';
304
362
  xhr.getResponseHeader = function(header){
305
- var headers = {'content-type': opts.dataType};
363
+ var headers = {'content-type': s.dataType};
306
364
  return headers[header];
307
365
  };
308
366
 
309
- if (opts.dataType == 'json' || opts.dataType == 'script') {
367
+ var scr = /(json|script|text)/.test(s.dataType);
368
+ if (scr || s.textarea) {
310
369
  // see if user embedded response in textarea
311
370
  var ta = doc.getElementsByTagName('textarea')[0];
312
- if (ta)
371
+ if (ta) {
313
372
  xhr.responseText = ta.value;
314
- else {
373
+ }
374
+ else if (scr) {
315
375
  // account for browsers injecting pre around json response
316
376
  var pre = doc.getElementsByTagName('pre')[0];
317
- if (pre)
318
- xhr.responseText = pre.innerHTML;
377
+ var b = doc.getElementsByTagName('body')[0];
378
+ if (pre) {
379
+ xhr.responseText = pre.textContent;
380
+ }
381
+ else if (b) {
382
+ xhr.responseText = b.innerHTML;
383
+ }
319
384
  }
320
385
  }
321
- else if (opts.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
386
+ else if (s.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
322
387
  xhr.responseXML = toXml(xhr.responseText);
323
388
  }
324
- data = $.httpData(xhr, opts.dataType);
389
+
390
+ data = httpData(xhr, s.dataType, s);
325
391
  }
326
392
  catch(e){
393
+ log('error caught:',e);
394
+ ok = false;
395
+ xhr.error = e;
396
+ s.error && s.error.call(s.context, xhr, 'error', e);
397
+ g && $.event.trigger("ajaxError", [xhr, s, e]);
398
+ }
399
+
400
+ if (xhr.aborted) {
401
+ log('upload aborted');
327
402
  ok = false;
328
- $.handleError(opts, xhr, 'error', e);
329
403
  }
330
404
 
331
405
  // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
332
406
  if (ok) {
333
- opts.success(data, 'success');
334
- if (g) $.event.trigger("ajaxSuccess", [xhr, opts]);
407
+ s.success && s.success.call(s.context, data, 'success', xhr);
408
+ g && $.event.trigger("ajaxSuccess", [xhr, s]);
409
+ }
410
+
411
+ g && $.event.trigger("ajaxComplete", [xhr, s]);
412
+
413
+ if (g && ! --$.active) {
414
+ $.event.trigger("ajaxStop");
335
415
  }
336
- if (g) $.event.trigger("ajaxComplete", [xhr, opts]);
337
- if (g && ! --$.active) $.event.trigger("ajaxStop");
338
- if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error');
416
+
417
+ s.complete && s.complete.call(s.context, xhr, ok ? 'success' : 'error');
418
+
419
+ callbackProcessed = true;
420
+ if (s.timeout)
421
+ clearTimeout(timeoutHandle);
339
422
 
340
423
  // clean up
341
424
  setTimeout(function() {
425
+ $io.removeData('form-plugin-onload');
342
426
  $io.remove();
343
427
  xhr.responseXML = null;
344
428
  }, 100);
345
- };
429
+ }
346
430
 
347
- function toXml(s, doc) {
431
+ var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+)
348
432
  if (window.ActiveXObject) {
349
433
  doc = new ActiveXObject('Microsoft.XMLDOM');
350
434
  doc.async = 'false';
351
435
  doc.loadXML(s);
352
436
  }
353
- else
437
+ else {
354
438
  doc = (new DOMParser()).parseFromString(s, 'text/xml');
355
- return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
439
+ }
440
+ return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null;
356
441
  };
357
- };
442
+ var parseJSON = $.parseJSON || function(s) {
443
+ return window['eval']('(' + s + ')');
444
+ };
445
+
446
+ var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4
447
+ var ct = xhr.getResponseHeader('content-type') || '',
448
+ xml = type === 'xml' || !type && ct.indexOf('xml') >= 0,
449
+ data = xml ? xhr.responseXML : xhr.responseText;
450
+
451
+ if (xml && data.documentElement.nodeName === 'parsererror') {
452
+ $.error && $.error('parsererror');
453
+ }
454
+ if (s && s.dataFilter) {
455
+ data = s.dataFilter(data, type);
456
+ }
457
+ if (typeof data === 'string') {
458
+ if (type === 'json' || !type && ct.indexOf('json') >= 0) {
459
+ data = parseJSON(data);
460
+ } else if (type === "script" || !type && ct.indexOf("javascript") >= 0) {
461
+ $.globalEval(data);
462
+ }
463
+ }
464
+ return data;
465
+ };
466
+ }
358
467
  };
359
468
 
360
469
  /**
@@ -373,18 +482,40 @@ $.fn.ajaxSubmit = function(options) {
373
482
  * the form itself.
374
483
  */
375
484
  $.fn.ajaxForm = function(options) {
485
+ // in jQuery 1.3+ we can fix mistakes with the ready state
486
+ if (this.length === 0) {
487
+ var o = { s: this.selector, c: this.context };
488
+ if (!$.isReady && o.s) {
489
+ log('DOM not ready, queuing ajaxForm');
490
+ $(function() {
491
+ $(o.s,o.c).ajaxForm(options);
492
+ });
493
+ return this;
494
+ }
495
+ // is your DOM ready? http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
496
+ log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
497
+ return this;
498
+ }
499
+
376
500
  return this.ajaxFormUnbind().bind('submit.form-plugin', function(e) {
377
- $(this).ajaxSubmit(options);
378
- e.stopPropagation();
379
- return false;
501
+ if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
502
+ e.preventDefault();
503
+ $(this).ajaxSubmit(options);
504
+ }
380
505
  }).bind('click.form-plugin', function(e) {
381
- var $el = $(e.target);
506
+ var target = e.target;
507
+ var $el = $(target);
382
508
  if (!($el.is(":submit,input:image"))) {
383
- return;
509
+ // is this a child element of the submit el? (ex: a span within a button)
510
+ var t = $el.closest(':submit');
511
+ if (t.length == 0) {
512
+ return;
513
+ }
514
+ target = t[0];
384
515
  }
385
516
  var form = this;
386
- form.clk = e.target;
387
- if (e.target.type == 'image') {
517
+ form.clk = target;
518
+ if (target.type == 'image') {
388
519
  if (e.offsetX != undefined) {
389
520
  form.clk_x = e.offsetX;
390
521
  form.clk_y = e.offsetY;
@@ -393,12 +524,12 @@ $.fn.ajaxForm = function(options) {
393
524
  form.clk_x = e.pageX - offset.left;
394
525
  form.clk_y = e.pageY - offset.top;
395
526
  } else {
396
- form.clk_x = e.pageX - e.target.offsetLeft;
397
- form.clk_y = e.pageY - e.target.offsetTop;
527
+ form.clk_x = e.pageX - target.offsetLeft;
528
+ form.clk_y = e.pageY - target.offsetTop;
398
529
  }
399
530
  }
400
531
  // clear form vars
401
- setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 10);
532
+ setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
402
533
  });
403
534
  };
404
535
 
@@ -420,15 +551,23 @@ $.fn.ajaxFormUnbind = function() {
420
551
  */
421
552
  $.fn.formToArray = function(semantic) {
422
553
  var a = [];
423
- if (this.length == 0) return a;
554
+ if (this.length === 0) {
555
+ return a;
556
+ }
424
557
 
425
558
  var form = this[0];
426
559
  var els = semantic ? form.getElementsByTagName('*') : form.elements;
427
- if (!els) return a;
428
- for(var i=0, max=els.length; i < max; i++) {
429
- var el = els[i];
430
- var n = el.name;
431
- if (!n) continue;
560
+ if (!els) {
561
+ return a;
562
+ }
563
+
564
+ var i,j,n,v,el,max,jmax;
565
+ for(i=0, max=els.length; i < max; i++) {
566
+ el = els[i];
567
+ n = el.name;
568
+ if (!n) {
569
+ continue;
570
+ }
432
571
 
433
572
  if (semantic && form.clk && el.type == "image") {
434
573
  // handle image inputs on the fly when semantic == true
@@ -439,18 +578,21 @@ $.fn.formToArray = function(semantic) {
439
578
  continue;
440
579
  }
441
580
 
442
- var v = $.fieldValue(el, true);
581
+ v = $.fieldValue(el, true);
443
582
  if (v && v.constructor == Array) {
444
- for(var j=0, jmax=v.length; j < jmax; j++)
583
+ for(j=0, jmax=v.length; j < jmax; j++) {
445
584
  a.push({name: n, value: v[j]});
585
+ }
446
586
  }
447
- else if (v !== null && typeof v != 'undefined')
587
+ else if (v !== null && typeof v != 'undefined') {
448
588
  a.push({name: n, value: v});
589
+ }
449
590
  }
450
591
 
451
592
  if (!semantic && form.clk) {
452
593
  // input type=='image' are not found in elements array! handle it here
453
- var $input = $(form.clk), input = $input[0], n = input.name;
594
+ var $input = $(form.clk), input = $input[0];
595
+ n = input.name;
454
596
  if (n && !input.disabled && input.type == 'image') {
455
597
  a.push({name: n, value: $input.val()});
456
598
  a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
@@ -476,14 +618,18 @@ $.fn.fieldSerialize = function(successful) {
476
618
  var a = [];
477
619
  this.each(function() {
478
620
  var n = this.name;
479
- if (!n) return;
621
+ if (!n) {
622
+ return;
623
+ }
480
624
  var v = $.fieldValue(this, successful);
481
625
  if (v && v.constructor == Array) {
482
- for (var i=0,max=v.length; i < max; i++)
626
+ for (var i=0,max=v.length; i < max; i++) {
483
627
  a.push({name: n, value: v[i]});
628
+ }
484
629
  }
485
- else if (v !== null && typeof v != 'undefined')
630
+ else if (v !== null && typeof v != 'undefined') {
486
631
  a.push({name: this.name, value: v});
632
+ }
487
633
  });
488
634
  //hand off to jQuery.param for proper encoding
489
635
  return $.param(a);
@@ -531,8 +677,9 @@ $.fn.fieldValue = function(successful) {
531
677
  for (var val=[], i=0, max=this.length; i < max; i++) {
532
678
  var el = this[i];
533
679
  var v = $.fieldValue(el, successful);
534
- if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length))
680
+ if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) {
535
681
  continue;
682
+ }
536
683
  v.constructor == Array ? $.merge(val, v) : val.push(v);
537
684
  }
538
685
  return val;
@@ -543,17 +690,22 @@ $.fn.fieldValue = function(successful) {
543
690
  */
544
691
  $.fieldValue = function(el, successful) {
545
692
  var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
546
- if (typeof successful == 'undefined') successful = true;
693
+ if (successful === undefined) {
694
+ successful = true;
695
+ }
547
696
 
548
697
  if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
549
698
  (t == 'checkbox' || t == 'radio') && !el.checked ||
550
699
  (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
551
- tag == 'select' && el.selectedIndex == -1))
700
+ tag == 'select' && el.selectedIndex == -1)) {
552
701
  return null;
702
+ }
553
703
 
554
704
  if (tag == 'select') {
555
705
  var index = el.selectedIndex;
556
- if (index < 0) return null;
706
+ if (index < 0) {
707
+ return null;
708
+ }
557
709
  var a = [], ops = el.options;
558
710
  var one = (t == 'select-one');
559
711
  var max = (one ? index+1 : ops.length);
@@ -561,15 +713,18 @@ $.fieldValue = function(el, successful) {
561
713
  var op = ops[i];
562
714
  if (op.selected) {
563
715
  var v = op.value;
564
- if (!v) // extra pain for IE...
716
+ if (!v) { // extra pain for IE...
565
717
  v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
566
- if (one) return v;
718
+ }
719
+ if (one) {
720
+ return v;
721
+ }
567
722
  a.push(v);
568
723
  }
569
724
  }
570
725
  return a;
571
726
  }
572
- return el.value;
727
+ return $(el).val();
573
728
  };
574
729
 
575
730
  /**
@@ -592,12 +747,15 @@ $.fn.clearForm = function() {
592
747
  $.fn.clearFields = $.fn.clearInputs = function() {
593
748
  return this.each(function() {
594
749
  var t = this.type, tag = this.tagName.toLowerCase();
595
- if (t == 'text' || t == 'password' || tag == 'textarea')
750
+ if (t == 'text' || t == 'password' || tag == 'textarea') {
596
751
  this.value = '';
597
- else if (t == 'checkbox' || t == 'radio')
752
+ }
753
+ else if (t == 'checkbox' || t == 'radio') {
598
754
  this.checked = false;
599
- else if (tag == 'select')
755
+ }
756
+ else if (tag == 'select') {
600
757
  this.selectedIndex = -1;
758
+ }
601
759
  });
602
760
  };
603
761
 
@@ -608,8 +766,9 @@ $.fn.resetForm = function() {
608
766
  return this.each(function() {
609
767
  // guard against an input with the name of 'reset'
610
768
  // note that IE reports the reset function as an 'object'
611
- if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType))
769
+ if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) {
612
770
  this.reset();
771
+ }
613
772
  });
614
773
  };
615
774
 
@@ -617,7 +776,9 @@ $.fn.resetForm = function() {
617
776
  * Enables or disables any matching elements.
618
777
  */
619
778
  $.fn.enable = function(b) {
620
- if (b == undefined) b = true;
779
+ if (b === undefined) {
780
+ b = true;
781
+ }
621
782
  return this.each(function() {
622
783
  this.disabled = !b;
623
784
  });
@@ -628,11 +789,14 @@ $.fn.enable = function(b) {
628
789
  * selects/deselects and matching option elements.
629
790
  */
630
791
  $.fn.selected = function(select) {
631
- if (select == undefined) select = true;
792
+ if (select === undefined) {
793
+ select = true;
794
+ }
632
795
  return this.each(function() {
633
796
  var t = this.type;
634
- if (t == 'checkbox' || t == 'radio')
797
+ if (t == 'checkbox' || t == 'radio') {
635
798
  this.checked = select;
799
+ }
636
800
  else if (this.tagName.toLowerCase() == 'option') {
637
801
  var $sel = $(this).parent('select');
638
802
  if (select && $sel[0] && $sel[0].type == 'select-one') {
@@ -647,8 +811,15 @@ $.fn.selected = function(select) {
647
811
  // helper fn for console logging
648
812
  // set $.fn.ajaxSubmit.debug to true to enable debug logging
649
813
  function log() {
650
- if ($.fn.ajaxSubmit.debug && window.console && window.console.log)
651
- window.console.log('[jquery.form] ' + Array.prototype.join.call(arguments,''));
814
+ if ($.fn.ajaxSubmit.debug) {
815
+ var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
816
+ if (window.console && window.console.log) {
817
+ window.console.log(msg);
818
+ }
819
+ else if (window.opera && window.opera.postError) {
820
+ window.opera.postError(msg);
821
+ }
822
+ }
652
823
  };
653
824
 
654
825
  })(jQuery);