html5forms-rails 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. data/CHANGELOG.md +5 -0
  2. data/Gemfile +11 -0
  3. data/README.md +208 -0
  4. data/Rakefile +49 -0
  5. data/VERSION +1 -0
  6. data/demos/html5-form-demo.html +79 -0
  7. data/html5forms-rails.gemspec +142 -0
  8. data/lib/html5forms.rb +6 -0
  9. data/vendor/assets/images/colorpicker/blank.gif +0 -0
  10. data/vendor/assets/images/colorpicker/colorpicker_background.png +0 -0
  11. data/vendor/assets/images/colorpicker/colorpicker_hex.png +0 -0
  12. data/vendor/assets/images/colorpicker/colorpicker_hsb_b.png +0 -0
  13. data/vendor/assets/images/colorpicker/colorpicker_hsb_h.png +0 -0
  14. data/vendor/assets/images/colorpicker/colorpicker_hsb_s.png +0 -0
  15. data/vendor/assets/images/colorpicker/colorpicker_indic.gif +0 -0
  16. data/vendor/assets/images/colorpicker/colorpicker_overlay.png +0 -0
  17. data/vendor/assets/images/colorpicker/colorpicker_rgb_b.png +0 -0
  18. data/vendor/assets/images/colorpicker/colorpicker_rgb_g.png +0 -0
  19. data/vendor/assets/images/colorpicker/colorpicker_rgb_r.png +0 -0
  20. data/vendor/assets/images/colorpicker/colorpicker_select.gif +0 -0
  21. data/vendor/assets/images/colorpicker/colorpicker_submit.png +0 -0
  22. data/vendor/assets/images/colorpicker/custom_background.png +0 -0
  23. data/vendor/assets/images/colorpicker/custom_hex.png +0 -0
  24. data/vendor/assets/images/colorpicker/custom_hsb_b.png +0 -0
  25. data/vendor/assets/images/colorpicker/custom_hsb_h.png +0 -0
  26. data/vendor/assets/images/colorpicker/custom_hsb_s.png +0 -0
  27. data/vendor/assets/images/colorpicker/custom_indic.gif +0 -0
  28. data/vendor/assets/images/colorpicker/custom_rgb_b.png +0 -0
  29. data/vendor/assets/images/colorpicker/custom_rgb_g.png +0 -0
  30. data/vendor/assets/images/colorpicker/custom_rgb_r.png +0 -0
  31. data/vendor/assets/images/colorpicker/custom_submit.png +0 -0
  32. data/vendor/assets/images/colorpicker/select.png +0 -0
  33. data/vendor/assets/images/colorpicker/select2.png +0 -0
  34. data/vendor/assets/images/colorpicker/slider.png +0 -0
  35. data/vendor/assets/images/h5f/form_validation.png +0 -0
  36. data/vendor/assets/images/html5form-shim/asterisk.png +0 -0
  37. data/vendor/assets/images/html5form-shim/down.png +0 -0
  38. data/vendor/assets/images/html5form-shim/fail.png +0 -0
  39. data/vendor/assets/images/html5form-shim/ok.png +0 -0
  40. data/vendor/assets/images/html5forms/jscolor/arrow.gif +0 -0
  41. data/vendor/assets/images/html5forms/jscolor/cross.gif +0 -0
  42. data/vendor/assets/images/html5forms/jscolor/hs.png +0 -0
  43. data/vendor/assets/images/html5forms/jscolor/hv.png +0 -0
  44. data/vendor/assets/images/html5forms/slider/slider-1.png +0 -0
  45. data/vendor/assets/images/html5forms/slider/slider-disabled-1.png +0 -0
  46. data/vendor/assets/images/html5forms/slider/slider-disabled.png +0 -0
  47. data/vendor/assets/images/html5forms/slider/slider.png +0 -0
  48. data/vendor/assets/javascripts/colorpicker.js +484 -0
  49. data/vendor/assets/javascripts/colorpicker.min.js +9 -0
  50. data/vendor/assets/javascripts/h5f.js +328 -0
  51. data/vendor/assets/javascripts/h5f.min.js +4 -0
  52. data/vendor/assets/javascripts/html5forms/EventHelpers.min.js +15 -0
  53. data/vendor/assets/javascripts/html5forms/autocomplete.min.js +1 -0
  54. data/vendor/assets/javascripts/html5forms/cssQuery-p.min.js +6 -0
  55. data/vendor/assets/javascripts/html5forms/dev/EventHelpers.js +486 -0
  56. data/vendor/assets/javascripts/html5forms/dev/autocomplete.js +387 -0
  57. data/vendor/assets/javascripts/html5forms/dev/cssQuery-p.js +6 -0
  58. data/vendor/assets/javascripts/html5forms/dev/html5.js +121 -0
  59. data/vendor/assets/javascripts/html5forms/dev/html5Forms.js +892 -0
  60. data/vendor/assets/javascripts/html5forms/dev/html5Widgets.js +1417 -0
  61. data/vendor/assets/javascripts/html5forms/dev/jscolor.js +840 -0
  62. data/vendor/assets/javascripts/html5forms/dev/slider.js +797 -0
  63. data/vendor/assets/javascripts/html5forms/dev/timer.js +137 -0
  64. data/vendor/assets/javascripts/html5forms/dev/visibleIf.js +1100 -0
  65. data/vendor/assets/javascripts/html5forms/html5.min.js +2 -0
  66. data/vendor/assets/javascripts/html5forms/html5Forms.min.js +1 -0
  67. data/vendor/assets/javascripts/html5forms/html5Widgets.min.js +20 -0
  68. data/vendor/assets/javascripts/html5forms/jscolor.min.js +10 -0
  69. data/vendor/assets/javascripts/html5forms/slider.min.js +25 -0
  70. data/vendor/assets/javascripts/html5forms/timer.min.js +1 -0
  71. data/vendor/assets/javascripts/html5forms/visibleIf.min.js +19 -0
  72. data/vendor/assets/javascripts/html5forms.fallback.js +115 -0
  73. data/vendor/assets/javascripts/html5forms.fallback.min.js +11 -0
  74. data/vendor/assets/javascripts/jquery.html5form-shim.js +402 -0
  75. data/vendor/assets/javascripts/jquery.html5form.min.js +4 -0
  76. data/vendor/assets/javascripts/jquery.placehold.min.js +7 -0
  77. data/vendor/assets/javascripts/ui.spinner.js +649 -0
  78. data/vendor/assets/javascripts/ui.spinner.min.js +7 -0
  79. data/vendor/assets/javascripts/webforms2/webforms2-msie.js +1 -0
  80. data/vendor/assets/javascripts/webforms2/webforms2-p.js +14 -0
  81. data/vendor/assets/javascripts/webforms2/webforms2.js +14 -0
  82. data/vendor/assets/javascripts/webforms2/webforms2_src.js +3195 -0
  83. data/vendor/assets/stylesheets/colorpicker.css +161 -0
  84. data/vendor/assets/stylesheets/h5f.css +86 -0
  85. data/vendor/assets/stylesheets/html5form-shim.css +109 -0
  86. data/vendor/assets/stylesheets/html5forms/number.css +35 -0
  87. data/vendor/assets/stylesheets/html5forms/slider.css +169 -0
  88. data/vendor/assets/stylesheets/html5forms/slider_ie.css +41 -0
  89. data/vendor/assets/stylesheets/html5forms/visibleIf.css +23 -0
  90. data/vendor/assets/stylesheets/html5forms.layout.css +116 -0
  91. data/vendor/assets/stylesheets/ui.spinner.css +3 -0
  92. data/vendor/assets/stylesheets/webforms2.css +42 -0
  93. metadata +221 -0
@@ -0,0 +1,1417 @@
1
+ /*******************************************************************************
2
+ * This notice must be untouched at all times.
3
+ *
4
+ * This javascript library contains helper routines to assist with event
5
+ * handling consinstently among browsers
6
+ *
7
+ * html5Widgets.js v.1.1 by Zoltan Hawryluk
8
+ * latest version and documentation available at http://www.useragentman.com/
9
+ *
10
+ * Changelog:
11
+ * version 1.0: initial release
12
+ * version 1.1: implemented oninput method for form elements for unsupported browsers
13
+ * fix IE9 to ensure backspace and delete keys fire an oninput event.
14
+ * version 1.2: Added Number Element Widget
15
+ *
16
+ * released under the MIT License:
17
+ * http://www.opensource.org/licenses/mit-license.php
18
+ *
19
+ *******************************************************************************/
20
+
21
+ var html5Widgets = new function(){
22
+ var me = this;
23
+
24
+
25
+ var delayEventTimeout = null;
26
+
27
+ me.inputNodes = new Array();
28
+ me.outputNodes = new Array();
29
+ me.formElements = null;
30
+ me.placeholderNodes = new Array();
31
+ me.dummyLink = document.createElement('input');
32
+ var quoteRe = /\"/g;
33
+
34
+ var dummyIDCount = 0;
35
+ var supportsNatively = new Object();
36
+
37
+ var isBadChrome = navigator.userAgent.indexOf('Chrome');
38
+ var valueRe = /this\.value/g;
39
+ var varRe = /([a-zA-Z][a-zA-Z0-9]*\.value)/g;
40
+ var isDebug;
41
+
42
+ var isIE9 = false;
43
+
44
+ /*@cc_on
45
+ @if (@_jscript_version == 9)
46
+ isIE9 = true;
47
+ @end
48
+ @*/
49
+
50
+
51
+
52
+ me.init = function(){
53
+
54
+ if (EventHelpers.hasPageLoadHappened(arguments)) {
55
+ return;
56
+ }
57
+
58
+ supportsNatively['oninput'] = EventHelpers.isSupported('input', 'form');
59
+
60
+ isDebug = CSSHelpers.isMemberOfClass(document.body, 'html5Widgets-debug')
61
+
62
+ // dummy link setup
63
+ me.type = 'text'
64
+ me.dummyLink.style.position = 'absolute';
65
+ me.dummyLink.style.top = '-200px';
66
+ document.body.appendChild(me.dummyLink)
67
+
68
+ var inputSupport = Modernizr.input
69
+
70
+ if (!inputSupport['placeholder']) {
71
+ setPlaceholders();
72
+ }
73
+ indexOutputNodes();
74
+ insertElements();
75
+
76
+ me.resolveOutputs();
77
+
78
+ /* document.getElementById('supports').innerHTML =
79
+ DebugHelpers.getProperties(Modernizr.inputtypes, 'inputtypes') + " " +
80
+ DebugHelpers.getProperties(Modernizr.input, 'input') + " " +
81
+ DebugHelpers.getProperties(Modernizr, 'Modernizr'); */
82
+
83
+ }
84
+
85
+
86
+
87
+ function supports_input_placeholder() {
88
+ var i = document.createElement('input');
89
+ return 'placeholder' in i;
90
+ }
91
+
92
+ function setPlaceholders() {
93
+
94
+ var nodes = [document.getElementsByTagName('input'), document.getElementsByTagName('textarea')];
95
+
96
+ for (var i=0; i<nodes.length; i++) {
97
+ for (var j=0; j<nodes[i].length; j++) {
98
+ var node = nodes[i][j];
99
+
100
+ if (DOMHelpers.getAttributeValue(node, 'placeholder')) {
101
+ me.placeholderNodes.push(new PlaceholderInput(node));
102
+ }
103
+ }
104
+ }
105
+ }
106
+
107
+
108
+
109
+
110
+
111
+ function getNextDummyID () {
112
+ dummyIDCount ++;
113
+ return "id" + dummyIDCount;
114
+ }
115
+
116
+ function indexOutputNodes () {
117
+ var outputElements = document.getElementsByTagName('output');
118
+ for (var i=0; i<outputElements.length; i++) {
119
+ var outputEl = outputElements[i];
120
+ if (outputEl.value != undefined && outputEl.onforminput != undefined) {
121
+
122
+ // this browser supports the output tag .. bail
123
+ supportsNatively["output"] = true;
124
+ break;
125
+ }
126
+ me.outputNodes.push(new OutputElement(outputEl))
127
+ }
128
+
129
+ me.formElements = document.getElementsByTagName('form');
130
+
131
+ }
132
+
133
+ function setOutputEvents(nodeName) {
134
+ var formElements = document.getElementsByTagName(nodeName);
135
+
136
+ for (var i=0; i<formElements.length; i++) {
137
+ var formElement = formElements[i];
138
+ // first - set event to resolve output tags
139
+ EventHelpers.addEvent(formElement, 'change', me.resolveOutputs);
140
+ EventHelpers.addEvent(formElement, 'keyup', me.resolveOutputs);
141
+ EventHelpers.addEvent(formElement, 'cut', me.resolveOutputs);
142
+ }
143
+ }
144
+
145
+
146
+ function insertElements(){
147
+ var inputSupport = Modernizr.inputtypes;
148
+
149
+
150
+ // Remove the onload event as we are creating the sliders with a JS call
151
+ if (window.fdSliderController) {
152
+ fdSliderController.removeOnLoadEvent();
153
+ }
154
+
155
+ var formElementTypes = ["input", "select", "textarea"];
156
+ for (var i=0; i<formElementTypes.length; i++) {
157
+ setOutputEvents(formElementTypes[i]);
158
+ }
159
+
160
+ var formElements = document.getElementsByTagName('input');
161
+
162
+ // leave if this browser supports the range type.
163
+ if (formElements.length <= 0) {
164
+ return;
165
+ }
166
+
167
+ for (var i = 0; i < formElements.length; i++) {
168
+
169
+
170
+ var formElement = formElements[i];
171
+
172
+
173
+ //var elType = getAttributeValue(formElement, 'type');
174
+ var elType = DOMHelpers.getAttributeValue(formElement, 'type');
175
+ //jslog.debug(elType)
176
+ if (!formElement.name) {
177
+ formElement.name = getNextDummyID();
178
+ }
179
+
180
+ switch (elType) {
181
+
182
+ case "range":
183
+
184
+ if (!inputSupport.range) {
185
+
186
+ me.inputNodes.push(new RangeElement(formElement));
187
+ }
188
+
189
+ break;
190
+
191
+ case "date":
192
+ case "week":
193
+ case "month":
194
+ case "datetime":
195
+ case "datetime-local":
196
+
197
+ // check to see if the browser supports the type.
198
+ if (!inputSupport[elType] || (window.html5Forms && html5Forms.forceJSDatePicker)) {
199
+ me.inputNodes.push(new CalendarElement(formElement, elType));
200
+ }
201
+ break;
202
+ case "color":
203
+ if (!inputSupport.color || isBadChrome) {
204
+ me.inputNodes.push(new ColorElement(formElement, elType));
205
+ }
206
+
207
+ break;
208
+ case "number":
209
+
210
+ if (!inputSupport.number) {
211
+ me.inputNodes.push(new NumberElement(formElement, elType));
212
+ }
213
+
214
+ break;
215
+ }
216
+
217
+ }
218
+
219
+
220
+
221
+ if (window.fdSliderController) {
222
+ fdSliderController.redrawAll();
223
+ }
224
+
225
+ if (window.jscolor) {
226
+ jscolor.init();
227
+ }
228
+ }
229
+
230
+
231
+
232
+
233
+ function delayedFireEvent(el, ev, callback){
234
+
235
+ if (!document.createEventObject ) {
236
+ me.fireEvent(el, ev);
237
+ if (callback) {
238
+ callback();
239
+ }
240
+ }
241
+ else {
242
+
243
+
244
+ if (delayEventTimeout != null) {
245
+ clearTimeout(delayEventTimeout)
246
+ }
247
+
248
+ delayEventTimeout = setTimeout(
249
+ function(){
250
+ EventHelpers.fireEvent(el, ev);
251
+
252
+ if (callback) {
253
+ callback();
254
+ }
255
+ }
256
+ , 1);
257
+
258
+ }
259
+ }
260
+
261
+ me.fireEvent = function(el, ev){
262
+ EventHelpers.fireEvent(el, ev);
263
+ }
264
+
265
+ me.resolveOutputs = function (e) {
266
+
267
+ // This resolves the onforminput events on the output nodes
268
+ for (var i=0; i<me.outputNodes.length; i++) {
269
+ var outputNode = me.outputNodes[i];
270
+ outputNode.resolve();
271
+ }
272
+
273
+ // This resolves the oninput events on the form nodes
274
+ if (!supportsNatively['oninput']) {
275
+ for (var i=0; i<me.formElements.length; i++) {
276
+ var formNode = me.formElements[i];
277
+ var oninput = DOMHelpers.getAttributeValue(formNode, 'oninput');
278
+ if (oninput) {
279
+ eval(me.getValueFormula(oninput, formNode));
280
+ }
281
+ }
282
+ } else if (isIE9 && e) {
283
+ // must deal with buggy implementation - delete and backspace don't fire
284
+ // the oninput event
285
+ var input = EventHelpers.getEventTarget(e);
286
+ switch (e.type) {
287
+
288
+ case "keyup":
289
+ var key = EventHelpers.getKey(e);
290
+
291
+ switch (key) {
292
+ case 8:
293
+ case 46:
294
+ case 88:
295
+ EventHelpers.fireEvent(input.form, 'input');
296
+ }
297
+ break;
298
+ case "cut":
299
+ delayedFireEvent(input.form, 'input');
300
+ break;
301
+ }
302
+
303
+ }
304
+ }
305
+
306
+ me.hideInput = function (node) {
307
+
308
+ node.style.position = 'absolute';
309
+ node.style.top = '-1000px';
310
+ node.style.left = '-1000px';
311
+ node.style.visibility = 'hidden'
312
+ }
313
+
314
+ me.getValueFormula = function(expr, parentForm) {
315
+ var formula = expr
316
+ if (formula == null) {
317
+ return null;
318
+ }
319
+ formula = formula
320
+ .replace(valueRe, 'value')
321
+ .replace(varRe, 'document.forms["' + parentForm.id + '"].$1');
322
+ return formula;
323
+ }
324
+
325
+
326
+ function showError(err) {
327
+ if (isDebug) {
328
+ alert(err);
329
+ }
330
+ throw(err);
331
+ }
332
+
333
+
334
+
335
+ /*
336
+ * Range Element
337
+ */
338
+
339
+ function RangeElement(node){
340
+ var me = this,
341
+ parentForm,
342
+ hasFiredChangeEvent = false;
343
+
344
+ me.node = node;
345
+ me.sliderNode = null;
346
+
347
+
348
+ function init (){
349
+ parentForm = DOMHelpers.getAncestorByTagName(node, 'form');
350
+ var min = parseFloat(DOMHelpers.getAttributeValue(me.node, 'min'));
351
+ var max = parseFloat(DOMHelpers.getAttributeValue(me.node, 'max'));
352
+
353
+ if (!window.fdSliderController) {
354
+ showError("slider.js must be included in order for the range element to work in this browser. See documentation for more details.");
355
+ }
356
+
357
+ if (isNaN(min)) {
358
+ min = 0;
359
+ }
360
+
361
+ if (isNaN(max)) {
362
+ max = 100;
363
+ }
364
+
365
+
366
+ var step = DOMHelpers.getAttributeValue(me.node, 'step');
367
+
368
+ if (step == null) {
369
+ step = "1"
370
+ } else if (typeof(step) == 'number') {
371
+ step = step + "";
372
+ }
373
+
374
+ // Must add id if not there (Requirement of the script)
375
+ if (!me.node.id) {
376
+ me.node.id = "HTML5Form-slider" + getNextDummyID();
377
+ }
378
+
379
+
380
+
381
+ // Create an Object to hold the slider's initialisation data
382
+ var options = {
383
+ // A reference to the input
384
+ inp: me.node,
385
+ // A String containing the increment value (and the return precision, in this case 2 decimal places "x.20")
386
+ inc: step,
387
+ // Maximum keyboard increment (automatically uses double the normal increment if not given)
388
+ maxInc: step,
389
+ // Numeric range
390
+ range: [min, max],
391
+ // Callback functions
392
+ callbacks: {
393
+ "update": [me.changeEvent]
394
+ },
395
+ // String representing the classNames to give the created slider
396
+ classNames: "html5Widgets-slider fd_jump",
397
+ // Tween the handle onclick?
398
+ tween: false,
399
+ // Is this a vertical slider
400
+ vertical: false,
401
+ // Do we hide the associated input on slider creation
402
+ hideInput: false,
403
+ // Does the handle jump to the nearest click value point when the bar is clicked (tween cannot then be true)
404
+ clickJump: true,
405
+ // Full ARIA required
406
+ fullARIA: false,
407
+ // Do we disable the mouseWheel for this slider
408
+ noMouseWheel: false
409
+
410
+ };
411
+
412
+ // Create the slider
413
+ fdSliderController.createSlider(options);
414
+
415
+ //tweak styles
416
+ me.sliderNode = document.getElementById('fd-slider-' + me.node.id);
417
+ me.sliderNode.style.width = me.node.offsetWidth + "px";
418
+
419
+ elDisplay = me.node.style.display
420
+ if (elDisplay != 'block') {
421
+ me.sliderNode.style.display = 'inline-block';
422
+ //me.sliderNode.style.paddingTop = "0.9em";
423
+ }
424
+
425
+ html5Widgets.hideInput(me.node);
426
+
427
+ document.getElementById('fd-slider-' + me.node.id).style.zIndex = '0';
428
+
429
+ me.node.tabIndex = "-1";
430
+ me.node.type = "text";
431
+
432
+ // Event Handling
433
+ EventHelpers.addEvent(me.node, 'change', changeOriginalNodeEvent);
434
+ }
435
+
436
+ me.changeEvent = function (e){
437
+ var oninput = DOMHelpers.getAttributeValue(parentForm, 'oninput');
438
+
439
+ if (oninput) {
440
+ eval(html5Widgets.getValueFormula(oninput, parentForm));
441
+ }
442
+
443
+ /* The if statement is to prevent this to continuously fire in an endless loop */
444
+ if (!hasFiredChangeEvent) {
445
+ hasFiredChangeEvent = true;
446
+ delayedFireEvent(me.node, 'change', function () {
447
+ hasFiredChangeEvent = false;
448
+ });
449
+ }
450
+ }
451
+
452
+ function changeOriginalNodeEvent(e) {
453
+
454
+ fdSliderController.updateSlider(me.node.id);
455
+ }
456
+
457
+ init();
458
+
459
+ }
460
+
461
+ function CalendarElement (node, type) {
462
+ var me = this;
463
+
464
+ me.node = node;
465
+ me.type = type;
466
+
467
+ var badDateTimeValueRe =
468
+ /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}Z{0,1}$/;
469
+ var displayDateTimeValueRe =
470
+ /^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}$/;
471
+ var originalVisibilityState;
472
+
473
+ function init() {
474
+
475
+ if (!window.Calendar && isDebug) {
476
+ showError("jscalendar scripts and CSS must be included for date and time form elements to work. See documentation for more details. ")
477
+ }
478
+
479
+ // Must add id if not there (Requirement of the script)
480
+ if (!me.node.id) {
481
+ me.node.id = "HTML5Form-calendar" + getNextDummyID();
482
+ }
483
+
484
+ /*
485
+ * If this is the result of coming back to the page from history,
486
+ * then it may have an old reformatted version in it from a previous
487
+ * submit. Let's re-format it back.
488
+ */
489
+
490
+ prepareForDisplay();
491
+
492
+
493
+ var formatString = "";
494
+ switch (me.type) {
495
+ case 'date':
496
+ formatString = "%Y-%m-%d";
497
+ break;
498
+ case 'month':
499
+ formatString = "%Y-%m";
500
+ break;
501
+ case 'week':
502
+ formatString = "%Y-W%W";
503
+ break;
504
+ case 'datetime':
505
+ placeUTCInfo();
506
+ case 'datetime-local':
507
+ case 'datetime':
508
+ formatString = "%Y-%m-%d %H:%M"
509
+ break;
510
+ }
511
+
512
+ /*
513
+ * Chrome, unfortunately, only implements type="date", and it's
514
+ * implementation displays the data in DD/MM/YYYY format. Even
515
+ * though it submits the data in YYYY-MM-DD format, this can
516
+ * be confusing to users if there is a, say, datetime widget
517
+ * with a date widget and they show different formats. In order
518
+ * to fix this, I change the type to "text" so that it uses the
519
+ * polyfill instead of the native one. Note that type="date"
520
+ * widgets in Chrome are only changed to type="text" when
521
+ * html5Forms.js's script tag has its
522
+ * data-webforms2-force-js-date-picker attribute set to "true".
523
+ */
524
+ me.node.type = 'text';
525
+
526
+ //me.node.readOnly = true;
527
+
528
+
529
+
530
+ Calendar.setup(
531
+ {
532
+ eventName :"click",
533
+ showsTime : type.indexOf('time') >= 0,
534
+ cache : true,
535
+ inputField : me.node.id, // ID of the input field
536
+ ifFormat : formatString, // the date format
537
+ button : me.node.id // ID of the button
538
+ }
539
+ );
540
+
541
+
542
+
543
+
544
+
545
+ EventHelpers.addEvent(me.node, 'click', forceCalToTop);
546
+ EventHelpers.addEvent(me.node, 'focus', focusEvent)
547
+ EventHelpers.addEvent(me.node, 'keypress', openCalendar);
548
+ EventHelpers.addEvent(me.node, 'blur', closeCalendar);
549
+
550
+ EventHelpers.addEvent(me.node, 'keypress', keydownEvent)
551
+ //me.node.type = "text";
552
+
553
+ // this will call submitEvent() after the form has been validated by
554
+ // webforms2.js
555
+ if (window.$wf2) {
556
+ $wf2.callBeforeValidation.push(prepareForSubmission);
557
+ $wf2.callAfterValidation.push(validationEvent);
558
+ }
559
+
560
+ }
561
+
562
+ function placeUTCInfo() {
563
+
564
+ var label = document.createElement('span');
565
+ label.innerHTML = "UTC";
566
+ label.style.paddingLeft = "5px";
567
+
568
+ DOMHelpers.insertAfter(me.node, label);
569
+
570
+ var width = label.offsetWidth;
571
+
572
+ me.node.style.width = (me.node.offsetWidth - 5 - width) + 'px';
573
+
574
+ }
575
+
576
+ function prepareForSubmission() {
577
+ var splitVals;
578
+
579
+ switch (me.type) {
580
+ case "datetime":
581
+ case "datetime-local":
582
+
583
+ originalVisibilityState = me.node.style.visibility;
584
+ me.node.style.visibility = 'hidden';
585
+ if (me.node.value.match(displayDateTimeValueRe)) {
586
+ splitVals = me.node.value.split(' ');
587
+ me.node.value = splitVals[0] + "T" + splitVals[1];
588
+ }
589
+
590
+ switch (me.type) {
591
+ case "datetime-local":
592
+ break;
593
+ case "datetime":
594
+ if (me.node.value != "") {
595
+ me.node.value += "Z";
596
+ }
597
+ }
598
+
599
+ }
600
+ }
601
+
602
+ function prepareForDisplay() {
603
+ switch(me.type) {
604
+ case "datetime":
605
+ case "datetime-local":
606
+ if ( me.node.value.match(badDateTimeValueRe)) {
607
+ me.node.value = me.node.value.replace(/T/, ' ').replace(/Z/, '');
608
+ }
609
+ if (originalVisibilityState != null) {
610
+ me.node.style.visibility = originalVisibilityState;
611
+ }
612
+
613
+ }
614
+
615
+
616
+ }
617
+
618
+ function validationEvent(e, hasValidated) {
619
+ if (!hasValidated) {
620
+ prepareForDisplay();
621
+ }
622
+ }
623
+
624
+ function forceCalToTop(e) {
625
+ var cal = window.calendar;
626
+
627
+ cal.element.style.zIndex = 100;
628
+ }
629
+
630
+ function focusEvent(e) {
631
+ var el = EventHelpers.getEventTarget(e);
632
+ EventHelpers.fireEvent(el, 'click')
633
+ }
634
+
635
+ function openCalendar(e) {
636
+
637
+ var cal = window.calendar;
638
+
639
+ cal.element.style.zIndex = 100;
640
+ if (cal.open != undefined) {
641
+ cal.open();
642
+ }
643
+ //EventHelpers.fireEvent(this, 'blur');
644
+ //EventHelpers.fireEvent(this, 'focus');
645
+ }
646
+
647
+ function closeCalendar(e){
648
+
649
+ var cal = window.calendar;
650
+ if (cal) {
651
+ cal.hide();
652
+ }
653
+ }
654
+
655
+ function keydownEvent(e) {
656
+
657
+ var c = EventHelpers.getKey(e);
658
+
659
+ switch(c){
660
+ case 13:
661
+ html5Widgets.dummyLink.focus();
662
+ this.focus();
663
+ EventHelpers.preventDefault(e);
664
+ openCalendar(e);
665
+ break;
666
+ case 9:
667
+ closeCalendar(e);
668
+ break;
669
+ default:
670
+ EventHelpers.preventDefault(e);
671
+ break;
672
+ }
673
+
674
+
675
+ }
676
+
677
+ function submitEvent(e) {
678
+ prepareForSubmission();
679
+ }
680
+
681
+ init();
682
+
683
+ }
684
+
685
+
686
+
687
+
688
+
689
+
690
+
691
+ /*
692
+ * Output Element
693
+ */
694
+ function OutputElement (node) {
695
+ var me = this;
696
+ me.node = node;
697
+
698
+ var value;
699
+ var valueFormula;
700
+ var parentForm;
701
+
702
+
703
+
704
+ function init () {
705
+ parentForm = DOMHelpers.getAncestorByTagName(node, 'form');
706
+ if (!parentForm.id) {
707
+ parentForm.id = getNextDummyID();
708
+ }
709
+
710
+ valueFormula = html5Widgets.getValueFormula(DOMHelpers.getAttributeValue(me.node, 'onforminput'), parentForm);
711
+ }
712
+
713
+
714
+
715
+ me.resolve = function () {
716
+ if (valueFormula == null) {
717
+ return;
718
+ } else {
719
+ eval(valueFormula);
720
+ me.node.innerHTML = value;
721
+ me.node.value = value;
722
+ }
723
+
724
+ }
725
+
726
+
727
+ init();
728
+ }
729
+
730
+ function ColorElement (node) {
731
+ var me = this;
732
+
733
+ /* note: color picker setPad() is what you are looking for */
734
+ me.node = node;
735
+
736
+ function init () {
737
+ if (!window.jscolor) {
738
+ showError('jscolor script must be included in order for the color input type to work in this browser. See documentation for more details.')
739
+ }
740
+ CSSHelpers.addClass(me.node, 'color');
741
+ CSSHelpers.addClass(me.node, '{hash:true,caps:false}');
742
+ me.node.type = "text";
743
+ }
744
+
745
+
746
+ init();
747
+ }
748
+
749
+ /*
750
+ * NumberElement: refactored from http://www.kethinov.com/jsstepper.php.
751
+ */
752
+
753
+ function NumberElement (node) {
754
+ var me = this,
755
+ min = parseFloat(DOMHelpers.getAttributeValue(node, 'min')),
756
+ max = parseFloat(DOMHelpers.getAttributeValue(node, 'max')),
757
+ step = parseFloat(DOMHelpers.getAttributeValue(node, 'step'));
758
+
759
+ me.node = node;
760
+
761
+
762
+
763
+ if (isNaN(step)) {
764
+ // we don't have to create the up and down arraw widgets
765
+ return;
766
+ }
767
+
768
+ EventHelpers.addEvent(node, 'keyup', keyUpEvent);
769
+
770
+
771
+ function keyUpEvent() {
772
+
773
+ if (isNumeric(this.value)) {
774
+
775
+ /* if (this.value > max) this.value = max;
776
+ else if (this.value < min) this.value = this.min; */
777
+
778
+ } else if (this.value != '') {
779
+ var val = parseFloat(this.value);
780
+ if (isNaN(val)) {
781
+ this.value = '';
782
+ } else {
783
+ this.value = val;
784
+ }
785
+ }
786
+
787
+ }
788
+
789
+
790
+
791
+ function nearestValid(value, direction) {
792
+
793
+ var n = (value - min)/step,
794
+ r;
795
+ //alert(StringHelpers.sprintf("n: %s, value: %s, min: %s, step: %s", n, value, min, step))
796
+ if (n == parseInt(n)) {
797
+ r = value;
798
+ } else {
799
+
800
+ if (direction < 0) {
801
+ n = Math.floor(n + 1);
802
+ } else {
803
+ n = Math.ceil(n -1);
804
+ }
805
+
806
+ r = min + step * n;
807
+ }
808
+
809
+ if (r > max) {
810
+ r -= step;
811
+ } else if (r < min) {
812
+ r+= step
813
+ }
814
+
815
+ return r;
816
+ }
817
+
818
+ function buttonMouseDownEvent(e) {
819
+
820
+ var buttonType = this.className;
821
+ var stepMult = step;
822
+ if (buttonType == 'dnbutton') {
823
+ stepMult = -step;
824
+ }
825
+
826
+
827
+ var min = this.min;
828
+ var max = this.max;
829
+ if (
830
+ (stepMult < 0 && (node.value > min || isNaN(min))) ||
831
+ (stepMult > 0 && (node.value < max || isNaN(max)))
832
+ ) {
833
+ setValue(me.node, nearestValid(parseFloat(node.value) + stepMult, stepMult));
834
+ }
835
+
836
+ var delayedOnce = false;
837
+ var date = new Date();
838
+ var curDate = null;
839
+
840
+ this.interval = setInterval(function() {
841
+ if (!delayedOnce) {
842
+ curDate = new Date();
843
+ if (curDate - date > 500) delayedOnce = true;
844
+ }
845
+ else if (
846
+ (stepMult < 0 && (node.value > min || isNaN(min))) ||
847
+ (stepMult > 0 && (node.value < max || isNaN(max)))
848
+ ) {
849
+ setValue(me.node, nearestValid(parseFloat(node.value) + stepMult, stepMult));
850
+ }
851
+ }, 50);
852
+ EventHelpers.preventDefault(e);
853
+ }
854
+
855
+ function setValue(node, value) {
856
+ if (isNaN(value)) {
857
+ node.value = '';
858
+ } else {
859
+ node.value = value;
860
+ }
861
+ }
862
+
863
+ function buttonClickEvent(e) {
864
+ clearInterval(this.interval);
865
+ EventHelpers.preventDefault(e);
866
+ }
867
+ function buttonMouseUpEvent(e) {
868
+ clearInterval(this.interval);
869
+ EventHelpers.preventDefault(e);
870
+ }
871
+
872
+ function isNumeric(n) {
873
+ return !isNaN(parseFloat(n)) && isFinite(n);
874
+ }
875
+
876
+
877
+ function hasNativeSpinner() {
878
+ try {
879
+ return window.getComputedStyle(me.node, '-webkit-inner-spin-button').WebkitAppearance != undefined;
880
+ } catch (ex) {
881
+ return false;
882
+ }
883
+ }
884
+
885
+ function init () {
886
+ var upbutton = document.createElement('a');
887
+ upbutton.className = 'upbutton';
888
+ upbutton.appendChild(document.createTextNode("\u25B2"));
889
+ upbutton.targInput = node;
890
+ upbutton.max = max;
891
+
892
+ var dnbutton = document.createElement('a');
893
+ dnbutton.className = 'dnbutton';
894
+ dnbutton.appendChild(document.createTextNode("\u25BC"));
895
+ dnbutton.targInput = node;
896
+ dnbutton.min = min;
897
+ dnbutton.max = max;
898
+
899
+ EventHelpers.addEvent(upbutton, 'mousedown', buttonMouseDownEvent);
900
+ EventHelpers.addEvent(dnbutton, 'mousedown', buttonMouseDownEvent);
901
+
902
+ EventHelpers.addEvent(upbutton, 'click', buttonClickEvent);
903
+ EventHelpers.addEvent(upbutton, 'mouseup', buttonMouseUpEvent);
904
+ EventHelpers.addEvent(dnbutton, 'click', buttonClickEvent);
905
+ EventHelpers.addEvent(dnbutton, 'mouseup', buttonMouseUpEvent);
906
+
907
+
908
+ if (!hasNativeSpinner()) {
909
+ var controlsNode = document.createElement('div');
910
+ controlsNode.className = 'html5-numberControls';
911
+ controlsNode.appendChild(upbutton);
912
+ controlsNode.appendChild(dnbutton);
913
+
914
+ var wrapperNode = document.createElement('div')
915
+ wrapperNode.className = 'html5-numberWrapper';
916
+ wrapperNode.appendChild(controlsNode);
917
+ var parentNode = node.parentNode;
918
+
919
+
920
+
921
+
922
+ parentNode.insertBefore(wrapperNode, node);
923
+
924
+
925
+ var nodeWidth = node.offsetWidth;
926
+ var nodeStyle = CSSHelpers.getCurrentStyle(node);
927
+
928
+ node.style.width = (nodeWidth - upbutton.offsetWidth -9) + 'px';
929
+ wrapperNode.style.width = nodeWidth + 'px';
930
+ wrapperNode.style.marginTop = nodeStyle.marginTop;
931
+ wrapperNode.style.height = (node.offsetHeight) + 'px';
932
+ }
933
+
934
+
935
+
936
+ }
937
+ /* Finally: if the form field has a value onload that is not a number, remove it
938
+ if (!isNumeric(node.value)) {
939
+ node.value = '';
940
+ EventHelpers.fireEvent(node, 'change');
941
+ }*/
942
+ init();
943
+ }
944
+
945
+ function PlaceholderInput (node) {
946
+ var me = this;
947
+
948
+ me.node = node;
949
+
950
+ var form, defaultText;
951
+
952
+ function init () {
953
+ defaultText = DOMHelpers.getAttributeValue(node, 'placeholder');
954
+ form = DOMHelpers.getAncestorByTagName(node, 'form');
955
+
956
+ me.setPlaceholderText(true);
957
+ EventHelpers.addEvent(me.node, 'blur', blurEvent);
958
+ EventHelpers.addEvent(me.node, 'focus', focusEvent);
959
+
960
+ if (me.node.form) {
961
+ EventHelpers.addEvent(me.node.form, 'submit', removePlaceholderText);
962
+ }
963
+
964
+ if (window.$wf2) {
965
+ if ($wf2.callBeforeValidation != undefined) {
966
+ $wf2.callBeforeValidation.push(removePlaceholderText);
967
+ }
968
+
969
+ if ($wf2.callAfterValidation != undefined) {
970
+ $wf2.callAfterValidation.push(postValidationEvent);
971
+ }
972
+ }
973
+ }
974
+
975
+ me.setPlaceholderText = function (isLoadEvent) {
976
+ //jslog.debug(StringHelpers.sprintf('initiator: %s', this));
977
+ var isAutofocus = DOMHelpers.getAttributeValue(me.node, 'autofocus') != null;
978
+
979
+
980
+ if (me.node.value == "" || (isLoadEvent && me.node.value == defaultText)) {
981
+ CSSHelpers.addClass(me.node, 'html5-hasPlaceholderText');
982
+ me.node.value = defaultText;
983
+
984
+ }
985
+
986
+ if (isLoadEvent && isAutofocus && me.node.value == defaultText ) {
987
+ CSSHelpers.removeClass(me.node, 'html5-hasPlaceholderText');
988
+ me.node.value = '';
989
+ }
990
+
991
+
992
+
993
+ }
994
+
995
+ function focusEvent(e) {
996
+
997
+ CSSHelpers.addClass(me.node, 'html5-hasFocus');
998
+ removePlaceholderText();
999
+ }
1000
+
1001
+ function blurEvent(e) {
1002
+ //jslog.debug('removed focus on ' + me.node.name)
1003
+ CSSHelpers.removeClass(me.node, 'html5-hasFocus');
1004
+ me.setPlaceholderText();
1005
+ }
1006
+
1007
+ function removePlaceholderText() {
1008
+ //jslog.debug('removePlaceholderText() for ' + me.node.name)
1009
+ if (CSSHelpers.isMemberOfClass(me.node, 'html5-hasPlaceholderText')) {
1010
+ me.node.value = "";
1011
+ CSSHelpers.removeClass(me.node, 'html5-hasPlaceholderText');
1012
+ }
1013
+ }
1014
+
1015
+ function postValidationEvent(e, didValidate) {
1016
+ ////jslog.debug(StringHelpers.sprintf('post Validation: %s, didValidate = %s, has focus = %s', me.node.name, didValidate, CSSHelpers.isMemberOfClass(me.node, 'html5-hasFocus') ) )
1017
+ if (!didValidate && !CSSHelpers.isMemberOfClass(me.node, 'html5-hasFocus')) {
1018
+ me.setPlaceholderText();
1019
+ }
1020
+ }
1021
+
1022
+ init();
1023
+ }
1024
+
1025
+ var CSSHelpers = new function () {
1026
+ var me = this;
1027
+
1028
+ var blankRe = new RegExp('\\s');
1029
+
1030
+ /**
1031
+ * Generates a regular expression string that can be used to detect a class name
1032
+ * in a tag's class attribute. It is used by a few methods, so I
1033
+ * centralized it.
1034
+ *
1035
+ * @param {String} className - a name of a CSS class.
1036
+ */
1037
+
1038
+ function getClassReString(className) {
1039
+ return '\\s'+className+'\\s|^' + className + '\\s|\\s' + className + '$|' + '^' + className +'$';
1040
+ }
1041
+
1042
+ function getClassPrefixReString(className) {
1043
+ return '\\s'+className+'-[0-9a-zA-Z_]+\\s|^' + className + '[0-9a-zA-Z_]+\\s|\\s' + className + '[0-9a-zA-Z_]+$|' + '^' + className +'[0-9a-zA-Z_]+$';
1044
+ }
1045
+
1046
+
1047
+ /**
1048
+ * Make an HTML object be a member of a certain class.
1049
+ *
1050
+ * @param {Object} obj - an HTML object
1051
+ * @param {String} className - a CSS class name.
1052
+ */
1053
+ me.addClass = function (obj, className) {
1054
+
1055
+ if (blankRe.test(className)) {
1056
+ return;
1057
+ }
1058
+
1059
+ // only add class if the object is not a member of it yet.
1060
+ if (!me.isMemberOfClass(obj, className)) {
1061
+ obj.className += " " + className;
1062
+ }
1063
+
1064
+ }
1065
+
1066
+ /**
1067
+ * Make an HTML object *not* be a member of a certain class.
1068
+ *
1069
+ * @param {Object} obj - an HTML object
1070
+ * @param {Object} className - a CSS class name.
1071
+ */
1072
+ me.removeClass = function (obj, className) {
1073
+
1074
+ if (blankRe.test(className)) {
1075
+ return;
1076
+ }
1077
+
1078
+
1079
+ var re = new RegExp(getClassReString(className) , "g");
1080
+
1081
+ var oldClassName = obj.className;
1082
+
1083
+
1084
+ if (obj.className) {
1085
+ obj.className = oldClassName.replace(re, ' ');
1086
+ }
1087
+
1088
+ }
1089
+
1090
+ /**
1091
+ * Determines if an HTML object is a member of a specific class.
1092
+ * @param {Object} obj - an HTML object.
1093
+ * @param {Object} className - the CSS class name.
1094
+ */
1095
+ me.isMemberOfClass = function (obj, className) {
1096
+
1097
+ if (blankRe.test(className))
1098
+ return false;
1099
+
1100
+ var re = new RegExp(getClassReString(className) , "g");
1101
+
1102
+ return (re.test(obj.className));
1103
+
1104
+
1105
+ }
1106
+
1107
+ /* from http://blog.stchur.com/2006/06/21/css-computed-style/ */
1108
+ me.getCurrentStyle = function(obj)
1109
+ {
1110
+ var computedStyle;
1111
+ if (typeof obj.currentStyle != 'undefined')
1112
+ { computedStyle = obj.currentStyle; }
1113
+ else
1114
+ { computedStyle = document.defaultView.getComputedStyle(obj, null); }
1115
+
1116
+ return computedStyle;
1117
+ }
1118
+ }
1119
+
1120
+
1121
+
1122
+ var DOMHelpers = new function () {
1123
+ var me = this;
1124
+
1125
+ /**
1126
+ * Given an HTML or XML object, find the an attribute by name.
1127
+ *
1128
+ * @param {Object} obj - a DOM object.
1129
+ * @param {String} attrName - the name of an attribute inside the DOM object.
1130
+ * @return {Object} - the attribute object or null if there isn't one.
1131
+ */
1132
+ me.getAttributeByName = function (obj, attrName) {
1133
+ var i;
1134
+
1135
+ var attributes = obj.attributes;
1136
+ for (i=0; i<attributes.length; i++) {
1137
+ var attr = attributes[i]
1138
+ if (attr.nodeName == attrName && attr.specified) {
1139
+ return attr;
1140
+ }
1141
+ }
1142
+ return null;
1143
+ }
1144
+ /**
1145
+ * Given an HTML or XML object, find the value of an attribute.
1146
+ *
1147
+ * @param {Object} obj - a DOM object.
1148
+ * @param {String} attrName - the name of an attribute inside the DOM object.
1149
+ * @return {String} - the value of the attribute.
1150
+ */
1151
+ me.getAttributeValue = function (obj, attrName) {
1152
+ var attr = me.getAttributeByName(obj, attrName);
1153
+
1154
+ if (attr != null) {
1155
+ return attr.nodeValue;
1156
+ } else {
1157
+ var typeRe = new RegExp(attrName + '=(\\"([a-zA-Z\-]*)\\"|[a-zA-Z\-]*)');
1158
+ //jslog.debug(XMLHelpers.getOuterXML(obj))
1159
+ var typeVal = XMLHelpers.getOuterXML(obj).split('>')[0].match(typeRe);
1160
+ //jslog.debug(typeVal)
1161
+ if (typeVal && typeVal.length >= 1) {
1162
+ return typeVal[1].replace(quoteRe, '');
1163
+ } else {
1164
+ return null;
1165
+ }
1166
+
1167
+ }
1168
+ }
1169
+
1170
+ me.insertAfter = function (refNode, nodeToInsert) {
1171
+ var parent = refNode.parentNode;
1172
+
1173
+ var nextSibling = refNode.nextSibling;
1174
+ if (nextSibling) {
1175
+ parent.insertBefore(nodeToInsert, nextSibling);
1176
+ } else {
1177
+ parent.appendChild(nodeToInsert);
1178
+ }
1179
+ }
1180
+
1181
+ /**
1182
+ * Given an tag, find the first ancestor tag of a given tag name.
1183
+ *
1184
+ * @param {Object} obj - a HTML or XML tag.
1185
+ * @param {String} tagName - the name of the ancestor tag to find.
1186
+ * @return {Object} - the ancestor tag, or null if not found.
1187
+ */
1188
+ me.getAncestorByTagName = function(obj, tagName) {
1189
+
1190
+ for (var node = obj.parentNode;
1191
+ node.nodeName.toLowerCase() != 'body';
1192
+ node = node.parentNode) {
1193
+
1194
+ if (tagName.toLowerCase() == node.nodeName.toLowerCase()) {
1195
+ return node;
1196
+ }
1197
+
1198
+ }
1199
+ return null;
1200
+ }
1201
+
1202
+ me.removeNode = function (node) {
1203
+ var parentNode = node.parentNode;
1204
+ if (parentNode) {
1205
+ parentNode.removeChild(node);
1206
+ }
1207
+ }
1208
+
1209
+ }
1210
+
1211
+ var StringHelpers = new function () {
1212
+ var me = this;
1213
+
1214
+ /*******************************************************************************
1215
+ * Function sprintf(format_string,arguments...) Javascript emulation of the C
1216
+ * printf function (modifiers and argument types "p" and "n" are not supported
1217
+ * due to language restrictions)
1218
+ *
1219
+ * Copyright 2003 K&L Productions. All rights reserved
1220
+ * http://www.klproductions.com
1221
+ *
1222
+ * Terms of use: This function can be used free of charge IF this header is not
1223
+ * modified and remains with the function code.
1224
+ *
1225
+ * Legal: Use this code at your own risk. K&L Productions assumes NO
1226
+ * resposibility for anything.
1227
+ ******************************************************************************/
1228
+ me.sprintf = function (fstring)
1229
+ { var pad = function(str,ch,len)
1230
+ { var ps='';
1231
+ for(var i=0; i<Math.abs(len); i++) ps+=ch;
1232
+ return len>0?str+ps:ps+str;
1233
+ }
1234
+ var processFlags = function(flags,width,rs,arg)
1235
+ { var pn = function(flags,arg,rs)
1236
+ { if(arg>=0)
1237
+ { if(flags.indexOf(' ')>=0) rs = ' ' + rs;
1238
+ else if(flags.indexOf('+')>=0) rs = '+' + rs;
1239
+ }
1240
+ else
1241
+ rs = '-' + rs;
1242
+ return rs;
1243
+ }
1244
+ var iWidth = parseInt(width,10);
1245
+ if(width.charAt(0) == '0')
1246
+ { var ec=0;
1247
+ if(flags.indexOf(' ')>=0 || flags.indexOf('+')>=0) ec++;
1248
+ if(rs.length<(iWidth-ec)) rs = pad(rs,'0',rs.length-(iWidth-ec));
1249
+ return pn(flags,arg,rs);
1250
+ }
1251
+ rs = pn(flags,arg,rs);
1252
+ if(rs.length<iWidth)
1253
+ { if(flags.indexOf('-')<0) rs = pad(rs,' ',rs.length-iWidth);
1254
+ else rs = pad(rs,' ',iWidth - rs.length);
1255
+ }
1256
+ return rs;
1257
+ }
1258
+ var converters = new Array();
1259
+ converters['c'] = function(flags,width,precision,arg)
1260
+ { if(typeof(arg) == 'number') return String.fromCharCode(arg);
1261
+ if(typeof(arg) == 'string') return arg.charAt(0);
1262
+ return '';
1263
+ }
1264
+ converters['d'] = function(flags,width,precision,arg)
1265
+ { return converters['i'](flags,width,precision,arg);
1266
+ }
1267
+ converters['u'] = function(flags,width,precision,arg)
1268
+ { return converters['i'](flags,width,precision,Math.abs(arg));
1269
+ }
1270
+ converters['i'] = function(flags,width,precision,arg)
1271
+ { var iPrecision=parseInt(precision);
1272
+ var rs = ((Math.abs(arg)).toString().split('.'))[0];
1273
+ if(rs.length<iPrecision) rs=pad(rs,' ',iPrecision - rs.length);
1274
+ return processFlags(flags,width,rs,arg);
1275
+ }
1276
+ converters['E'] = function(flags,width,precision,arg)
1277
+ { return (converters['e'](flags,width,precision,arg)).toUpperCase();
1278
+ }
1279
+ converters['e'] = function(flags,width,precision,arg)
1280
+ { iPrecision = parseInt(precision);
1281
+ if(isNaN(iPrecision)) iPrecision = 6;
1282
+ rs = (Math.abs(arg)).toExponential(iPrecision);
1283
+ if(rs.indexOf('.')<0 && flags.indexOf('#')>=0) rs = rs.replace(/^(.*)(e.*)$/,'$1.$2');
1284
+ return processFlags(flags,width,rs,arg);
1285
+ }
1286
+ converters['f'] = function(flags,width,precision,arg)
1287
+ { iPrecision = parseInt(precision);
1288
+ if(isNaN(iPrecision)) iPrecision = 6;
1289
+ rs = (Math.abs(arg)).toFixed(iPrecision);
1290
+ if(rs.indexOf('.')<0 && flags.indexOf('#')>=0) rs = rs + '.';
1291
+ return processFlags(flags,width,rs,arg);
1292
+ }
1293
+ converters['G'] = function(flags,width,precision,arg)
1294
+ { return (converters['g'](flags,width,precision,arg)).toUpperCase();
1295
+ }
1296
+ converters['g'] = function(flags,width,precision,arg)
1297
+ { iPrecision = parseInt(precision);
1298
+ absArg = Math.abs(arg);
1299
+ rse = absArg.toExponential();
1300
+ rsf = absArg.toFixed(6);
1301
+ if(!isNaN(iPrecision))
1302
+ { rsep = absArg.toExponential(iPrecision);
1303
+ rse = rsep.length < rse.length ? rsep : rse;
1304
+ rsfp = absArg.toFixed(iPrecision);
1305
+ rsf = rsfp.length < rsf.length ? rsfp : rsf;
1306
+ }
1307
+ if(rse.indexOf('.')<0 && flags.indexOf('#')>=0) rse = rse.replace(/^(.*)(e.*)$/,'$1.$2');
1308
+ if(rsf.indexOf('.')<0 && flags.indexOf('#')>=0) rsf = rsf + '.';
1309
+ rs = rse.length<rsf.length ? rse : rsf;
1310
+ return processFlags(flags,width,rs,arg);
1311
+ }
1312
+ converters['o'] = function(flags,width,precision,arg)
1313
+ { var iPrecision=parseInt(precision);
1314
+ var rs = Math.round(Math.abs(arg)).toString(8);
1315
+ if(rs.length<iPrecision) rs=pad(rs,' ',iPrecision - rs.length);
1316
+ if(flags.indexOf('#')>=0) rs='0'+rs;
1317
+ return processFlags(flags,width,rs,arg);
1318
+ }
1319
+ converters['X'] = function(flags,width,precision,arg)
1320
+ { return (converters['x'](flags,width,precision,arg)).toUpperCase();
1321
+ }
1322
+ converters['x'] = function(flags,width,precision,arg)
1323
+ { var iPrecision=parseInt(precision);
1324
+ arg = Math.abs(arg);
1325
+ var rs = Math.round(arg).toString(16);
1326
+ if(rs.length<iPrecision) rs=pad(rs,' ',iPrecision - rs.length);
1327
+ if(flags.indexOf('#')>=0) rs='0x'+rs;
1328
+ return processFlags(flags,width,rs,arg);
1329
+ }
1330
+ converters['s'] = function(flags,width,precision,arg)
1331
+ { var iPrecision=parseInt(precision);
1332
+ var rs = arg;
1333
+ if(rs.length > iPrecision) rs = rs.substring(0,iPrecision);
1334
+ return processFlags(flags,width,rs,0);
1335
+ }
1336
+ farr = fstring.split('%');
1337
+ retstr = farr[0];
1338
+ fpRE = /^([-+ #]*)(\d*)\.?(\d*)([cdieEfFgGosuxX])(.*)$/;
1339
+ for(var i=1; i<farr.length; i++)
1340
+ { fps=fpRE.exec(farr[i]);
1341
+ if(!fps) continue;
1342
+ if(arguments[i]!=null) retstr+=converters[fps[4]](fps[1],fps[2],fps[3],arguments[i]);
1343
+ retstr += fps[5];
1344
+ }
1345
+ return retstr;
1346
+ }
1347
+ }
1348
+
1349
+ var XMLHelpers = new function () {
1350
+ var me = this;
1351
+
1352
+ /**
1353
+ * Given an XML node, return the XML inside as a string and the XML string of the node itself.
1354
+ * Similar to Internet Explorer's outerHTML property, except it is for XML, not HTML.
1355
+ * Created with information from http://www.codingforums.com/showthread.php?t=31489
1356
+ * and http://www.mercurytide.co.uk/whitepapers/issues-working-with-ajax/
1357
+ *
1358
+ * @param {Object} node - a DOM object.
1359
+ * @param {Object} options - a JS object containing options. To date,
1360
+ * the only one supported is "insertClosingTags", when set to
1361
+ * true, converts self closing tags, like <td />, to <td></td>.
1362
+ * @return {String} - the XML String inside the object.
1363
+ */
1364
+ me.getOuterXML = function (node, options) {
1365
+ var r;
1366
+ // Internet Explorer
1367
+ if (node.xml) {
1368
+ r = node.xml;
1369
+
1370
+ // Everyone else
1371
+ } else if (node.outerHTML) {
1372
+ r = node.outerHTML;
1373
+ } else if (window.XMLSerializer) {
1374
+
1375
+ var serializer = new XMLSerializer();
1376
+ var text = serializer.serializeToString(node);
1377
+ r = text;
1378
+ } else {
1379
+ return null;
1380
+ }
1381
+
1382
+ /*
1383
+ * If the XML is actually HTML and you are inserting it into an HTML
1384
+ * document, you must use the "insertClosingTags" option, otherwise
1385
+ * Opera will not like you, especially if you have empty <td> tags.
1386
+ */
1387
+ if (options) {
1388
+ if (options.insertClosingTags) {
1389
+ r = r.replace(selfClosingTagRe, "<$1></$1>");
1390
+ }
1391
+ }
1392
+ return r;
1393
+ }
1394
+ }
1395
+
1396
+
1397
+ // default styles
1398
+ var placeholderCSS = 'color: #999999; font-style: italic';
1399
+ var placeholderRequiredCSS = 'color: #ffcccc !important;'
1400
+
1401
+ var sb = "";
1402
+
1403
+ // has to be two seperate rules, or some browsers, like firefox, will not use the rule.
1404
+ if (document.getElementsByTagName('body').length == 0) {
1405
+ sb = '<style type="text/css" id="testCSS">' +
1406
+ StringHelpers.sprintf('.html5-hasPlaceholderText{%s} input::-webkit-input-placeholder {%s}', placeholderCSS, placeholderCSS) +
1407
+ '</style>';
1408
+
1409
+
1410
+ document.write(sb);
1411
+ }
1412
+ }
1413
+
1414
+
1415
+
1416
+ EventHelpers.addPageLoadEvent('html5Widgets.init');
1417
+