right-rails 0.6.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. data/CHANGELOG +8 -0
  2. data/README.rdoc +71 -0
  3. data/Rakefile +144 -14
  4. data/generators/right_rails/right_rails_generator.rb +18 -21
  5. data/init.rb +11 -32
  6. data/lib/generators/right_rails/right_rails_generator.rb +27 -0
  7. data/lib/generators/right_rails/templates/iframed.html.erb +10 -0
  8. data/lib/right-rails.rb +1 -1
  9. data/lib/right_rails/config.rb +278 -0
  10. data/lib/right_rails/controller_extensions.rb +10 -5
  11. data/lib/right_rails/helpers/basic.rb +10 -66
  12. data/lib/right_rails/helpers/forms.rb +141 -139
  13. data/lib/right_rails/helpers/misc.rb +45 -67
  14. data/lib/right_rails/helpers/rails.rb +40 -105
  15. data/lib/right_rails/helpers.rb +364 -1
  16. data/lib/right_rails/java_script_generator.rb +34 -24
  17. data/lib/right_rails.rb +6 -1
  18. data/{images → public/images}/colorpicker.png +0 -0
  19. data/{images → public/images}/resizable.png +0 -0
  20. data/public/javascripts/right/autocompleter-src.js +612 -0
  21. data/public/javascripts/right/autocompleter.js +18 -0
  22. data/public/javascripts/right/calendar-src.js +1448 -0
  23. data/public/javascripts/right/calendar.js +36 -0
  24. data/public/javascripts/right/colorpicker-src.js +967 -0
  25. data/public/javascripts/right/colorpicker.js +26 -0
  26. data/{javascripts/right-dnd-src.js → public/javascripts/right/dnd-src.js} +86 -52
  27. data/public/javascripts/right/dnd.js +20 -0
  28. data/{javascripts/right-effects-src.js → public/javascripts/right/effects-src.js} +90 -45
  29. data/public/javascripts/right/effects.js +17 -0
  30. data/{javascripts/right-ui-i18n-de.js → public/javascripts/right/i18n/de.js} +7 -7
  31. data/{javascripts/right-ui-i18n-en-us.js → public/javascripts/right/i18n/en-us.js} +1 -1
  32. data/{javascripts/right-ui-i18n-es.js → public/javascripts/right/i18n/es.js} +7 -7
  33. data/{javascripts/right-ui-i18n-fr.js → public/javascripts/right/i18n/fr.js} +7 -7
  34. data/{javascripts/right-ui-i18n-hu.js → public/javascripts/right/i18n/hu.js} +7 -7
  35. data/{javascripts/right-ui-i18n-jp.js → public/javascripts/right/i18n/jp.js} +7 -7
  36. data/{javascripts/right-ui-i18n-nl.js → public/javascripts/right/i18n/nl.js} +7 -7
  37. data/{javascripts/right-ui-i18n-pt-br.js → public/javascripts/right/i18n/pt-br.js} +7 -7
  38. data/{javascripts/right-ui-i18n-ru.js → public/javascripts/right/i18n/ru.js} +7 -7
  39. data/{javascripts/right-ui-i18n-ua.js → public/javascripts/right/i18n/ua.js} +17 -12
  40. data/public/javascripts/right/in-edit-src.js +352 -0
  41. data/public/javascripts/right/in-edit.js +13 -0
  42. data/public/javascripts/right/json-src.js +160 -0
  43. data/public/javascripts/right/json.js +10 -0
  44. data/public/javascripts/right/lightbox-src.js +881 -0
  45. data/public/javascripts/right/lightbox.js +24 -0
  46. data/{javascripts/right-rails-src.js → public/javascripts/right/rails-src.js} +195 -171
  47. data/public/javascripts/right/rails.js +14 -0
  48. data/public/javascripts/right/rater-src.js +366 -0
  49. data/public/javascripts/right/rater.js +13 -0
  50. data/public/javascripts/right/resizable-src.js +420 -0
  51. data/public/javascripts/right/resizable.js +15 -0
  52. data/public/javascripts/right/selectable-src.js +687 -0
  53. data/public/javascripts/right/selectable.js +22 -0
  54. data/public/javascripts/right/slider-src.js +377 -0
  55. data/public/javascripts/right/slider.js +14 -0
  56. data/public/javascripts/right/sortable-src.js +392 -0
  57. data/public/javascripts/right/sortable.js +16 -0
  58. data/public/javascripts/right/tabs-src.js +1123 -0
  59. data/public/javascripts/right/tabs.js +29 -0
  60. data/public/javascripts/right/tooltip-src.js +307 -0
  61. data/public/javascripts/right/tooltip.js +12 -0
  62. data/public/javascripts/right/uploader-src.js +283 -0
  63. data/public/javascripts/right/uploader.js +13 -0
  64. data/{javascripts → public/javascripts}/right-olds-src.js +134 -186
  65. data/public/javascripts/right-olds.js +18 -0
  66. data/public/javascripts/right-safe-src.js +161 -0
  67. data/public/javascripts/right-safe.js +8 -0
  68. data/{javascripts → public/javascripts}/right-src.js +2558 -1750
  69. data/public/javascripts/right.js +92 -0
  70. data/spec/lib/right_rails/config_spec.rb +133 -0
  71. data/spec/lib/right_rails/controller_extensions_spec.rb +1 -1
  72. data/spec/lib/right_rails/helpers/basic_spec.rb +77 -66
  73. data/spec/lib/right_rails/helpers/forms_spec.rb +231 -33
  74. data/spec/lib/right_rails/helpers/misc_spec.rb +94 -26
  75. data/spec/lib/right_rails/helpers/rails_spec.rb +42 -7
  76. data/spec/lib/right_rails/helpers_spec.rb +125 -0
  77. data/spec/lib/right_rails/java_script_generator_spec.rb +30 -0
  78. data/spec/rcov.opts +3 -0
  79. data/spec/spec_helper.rb +12 -7
  80. metadata +70 -61
  81. data/README.textile +0 -69
  82. data/javascripts/right-autocompleter-src.js +0 -318
  83. data/javascripts/right-autocompleter.js +0 -9
  84. data/javascripts/right-behavior-src.js +0 -261
  85. data/javascripts/right-behavior.js +0 -8
  86. data/javascripts/right-calendar-src.js +0 -946
  87. data/javascripts/right-calendar.js +0 -9
  88. data/javascripts/right-colorpicker-src.js +0 -635
  89. data/javascripts/right-colorpicker.js +0 -9
  90. data/javascripts/right-dnd.js +0 -9
  91. data/javascripts/right-effects.js +0 -6
  92. data/javascripts/right-events-src.js +0 -321
  93. data/javascripts/right-events.js +0 -6
  94. data/javascripts/right-in-edit-src.js +0 -194
  95. data/javascripts/right-in-edit.js +0 -6
  96. data/javascripts/right-json-src.js +0 -141
  97. data/javascripts/right-json.js +0 -6
  98. data/javascripts/right-lightbox-src.js +0 -651
  99. data/javascripts/right-lightbox.js +0 -9
  100. data/javascripts/right-olds.js +0 -9
  101. data/javascripts/right-rails.js +0 -9
  102. data/javascripts/right-rater-src.js +0 -253
  103. data/javascripts/right-rater.js +0 -9
  104. data/javascripts/right-resizable-src.js +0 -336
  105. data/javascripts/right-resizable.js +0 -9
  106. data/javascripts/right-selectable-src.js +0 -565
  107. data/javascripts/right-selectable.js +0 -7
  108. data/javascripts/right-slider-src.js +0 -288
  109. data/javascripts/right-slider.js +0 -7
  110. data/javascripts/right-sortable-src.js +0 -225
  111. data/javascripts/right-sortable.js +0 -9
  112. data/javascripts/right-tabs-src.js +0 -937
  113. data/javascripts/right-tabs.js +0 -6
  114. data/javascripts/right-tooltips-src.js +0 -195
  115. data/javascripts/right-tooltips.js +0 -9
  116. data/javascripts/right-uploader-src.js +0 -167
  117. data/javascripts/right-uploader.js +0 -9
  118. data/javascripts/right.js +0 -7
@@ -0,0 +1,352 @@
1
+ /**
2
+ * Inline editor feature for RightJS
3
+ * http://rightjs.org/ui/in-edit
4
+ *
5
+ * Copyright (C) 2009-2010 Nikolay Nemshilov
6
+ */
7
+ var InEdit = RightJS.InEdit = (function(document, RightJS) {
8
+ /**
9
+ * This module defines the basic widgets constructor
10
+ * it creates an abstract proxy with the common functionality
11
+ * which then we reuse and override in the actual widgets
12
+ *
13
+ * Copyright (C) 2010 Nikolay Nemshilov
14
+ */
15
+
16
+ /**
17
+ * In-Edit plugin initalization
18
+ *
19
+ * Copyright (C) 2010 Nikolay Nemshilov
20
+ */
21
+ var R = RightJS,
22
+ $ = RightJS.$,
23
+ $w = RightJS.$w,
24
+ Xhr = RightJS.Xhr,
25
+ Object = RightJS.Object,
26
+ Element = RightJS.Element,
27
+ Input = RightJS.Input;
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+ /**
37
+ * The widget units constructor
38
+ *
39
+ * @param String tag-name or Object methods
40
+ * @param Object methods
41
+ * @return Widget wrapper
42
+ */
43
+ function Widget(tag_name, methods) {
44
+ if (!methods) {
45
+ methods = tag_name;
46
+ tag_name = 'DIV';
47
+ }
48
+
49
+ /**
50
+ * An Abstract Widget Unit
51
+ *
52
+ * Copyright (C) 2010 Nikolay Nemshilov
53
+ */
54
+ var AbstractWidget = new RightJS.Wrapper(RightJS.Element.Wrappers[tag_name] || RightJS.Element, {
55
+ /**
56
+ * The common constructor
57
+ *
58
+ * @param Object options
59
+ * @param String optional tag name
60
+ * @return void
61
+ */
62
+ initialize: function(key, options) {
63
+ this.key = key;
64
+ var args = [{'class': 'rui-' + key}];
65
+
66
+ // those two have different constructors
67
+ if (!(this instanceof RightJS.Input || this instanceof RightJS.Form)) {
68
+ args.unshift(tag_name);
69
+ }
70
+ this.$super.apply(this, args);
71
+
72
+ if (RightJS.isString(options)) {
73
+ options = RightJS.$(options);
74
+ }
75
+
76
+ // if the options is another element then
77
+ // try to dynamically rewrap it with our widget
78
+ if (options instanceof RightJS.Element) {
79
+ this._ = options._;
80
+ if ('$listeners' in options) {
81
+ options.$listeners = options.$listeners;
82
+ }
83
+ options = {};
84
+ }
85
+ this.setOptions(options, this);
86
+ return this;
87
+ },
88
+
89
+ // protected
90
+
91
+ /**
92
+ * Catches the options
93
+ *
94
+ * @param Object user-options
95
+ * @param Element element with contextual options
96
+ * @return void
97
+ */
98
+ setOptions: function(options, element) {
99
+ element = element || this;
100
+ RightJS.Options.setOptions.call(this,
101
+ RightJS.Object.merge(options, eval("("+(
102
+ element.get('data-'+ this.key) || '{}'
103
+ )+")"))
104
+ );
105
+ return this;
106
+ }
107
+ });
108
+
109
+ /**
110
+ * Creating the actual widget class
111
+ *
112
+ */
113
+ var Klass = new RightJS.Wrapper(AbstractWidget, methods);
114
+
115
+ // creating the widget related shortcuts
116
+ RightJS.Observer.createShortcuts(Klass.prototype, Klass.EVENTS || []);
117
+
118
+ return Klass;
119
+ }
120
+
121
+
122
+ /**
123
+ * A shared module to create textual spinners
124
+ *
125
+ * Copyright (C) 2010 Nikolay Nemshilov
126
+ */
127
+ var Spinner = new RightJS.Wrapper(RightJS.Element, {
128
+ /**
129
+ * Constructor
130
+ *
131
+ * @param Number optional spinner size (4 by default)
132
+ * @return void
133
+ */
134
+ initialize: function(size) {
135
+ this.$super('div', {'class': 'rui-spinner'});
136
+ this.dots = [];
137
+
138
+ for (var i=0; i < (size || 4); i++) {
139
+ this.dots.push(new RightJS.Element('div'));
140
+ }
141
+
142
+ this.dots[0].addClass('glowing');
143
+ this.insert(this.dots);
144
+ RightJS(this.shift).bind(this).periodical(300);
145
+ },
146
+
147
+ /**
148
+ * Shifts the spinner elements
149
+ *
150
+ * @return void
151
+ */
152
+ shift: function() {
153
+ if (this.visible()) {
154
+ var dot = this.dots.pop();
155
+ this.dots.unshift(dot);
156
+ this.insert(dot, 'top');
157
+ }
158
+ }
159
+ });
160
+
161
+ /**
162
+ * An inline editor feature
163
+ *
164
+ * Copyright (C) 2009-2010 Nikolay Nemshilov
165
+ */
166
+ var InEdit = new Widget('FORM', {
167
+ extend: {
168
+ version: '2.0.0',
169
+
170
+ EVENTS: $w('show hide send update'),
171
+
172
+ Options: {
173
+ url: null, // the url address where to send the stuff
174
+ name: 'text', // the field name
175
+ method: 'put', // the method
176
+
177
+ type: 'text', // the input type, 'text', 'file', 'password' or 'textarea'
178
+
179
+ toggle: null, // a reference to an element that should get hidden when the editor is active
180
+
181
+ update: true, // a marker if the element should be updated with the response-text
182
+
183
+ Xhr: {} // additional Xhr options
184
+ },
185
+
186
+ i18n: {
187
+ Save: 'Save',
188
+ Cancel: 'Cancel'
189
+ },
190
+
191
+ current: null // currently opened editor
192
+ },
193
+
194
+ /**
195
+ * Constructor
196
+ *
197
+ * @param mixed an element reference
198
+ * @param Object options
199
+ * @return void
200
+ */
201
+ initialize: function(element, options) {
202
+ this.element = $(element);
203
+
204
+ this
205
+ .$super('in-edit', options)
206
+ .set('action', this.options.url)
207
+ .insert([
208
+ this.field = new Input({type: this.options.type, name: this.options.name, 'class': 'field'}),
209
+ this.spinner = new Spinner(4),
210
+ this.submit = new Input({type: 'submit', 'class': 'submit', value: InEdit.i18n.Save}),
211
+ this.cancel = new Element('a', {'class': 'cancel', href: '#', html: InEdit.i18n.Cancel})
212
+ ])
213
+ .onClick(this.clicked)
214
+ .onSubmit(this.send);
215
+ },
216
+
217
+ /**
218
+ * Shows the inline-editor form
219
+ *
220
+ * @return InEdit this
221
+ */
222
+ show: function() {
223
+ if (InEdit.current !== this) {
224
+ if (InEdit.current) { InEdit.current.hide(); }
225
+
226
+ this.oldContent = this.element.html();
227
+
228
+ if (!R(['file', 'password']).include(this.options.type)) {
229
+ this.field.setValue(this.oldContent);
230
+ }
231
+
232
+ this.element.update(this);
233
+
234
+ this.spinner.hide();
235
+ this.submit.show();
236
+
237
+ if (this.options.toggle) {
238
+ $(this.options.toggle).hide();
239
+ }
240
+ }
241
+
242
+ if (this.options.type !== 'file') {
243
+ this.field.focus();
244
+ }
245
+
246
+ InEdit.current = this;
247
+ return this.fire('show', this);
248
+ },
249
+
250
+ /**
251
+ * Hides the form and brings the content back
252
+ *
253
+ * @param String optional new content
254
+ * @return InEdit this
255
+ */
256
+ hide: function() {
257
+ this.element._.innerHTML = this.oldContent;
258
+
259
+ if (this.xhr) {
260
+ this.xhr.cancel();
261
+ }
262
+
263
+ return this.finish();
264
+ },
265
+
266
+ /**
267
+ * Triggers the form remote submit
268
+ *
269
+ * @return InEdit this
270
+ */
271
+ send: function(event) {
272
+ if (event) { event.stop(); }
273
+
274
+ this.spinner.show().resize(this.submit.size());
275
+ this.submit.hide();
276
+
277
+ this.xhr = new Xhr(this.options.url, Object.merge(this.options.Xhr, {
278
+ method: this.options.method,
279
+ spinner: this.spinner,
280
+ onComplete: R(this.receive).bind(this)
281
+ })).send(this);
282
+
283
+ return this.fire('send', this);
284
+ },
285
+
286
+ // protected
287
+
288
+ // finishes up with the form
289
+ finish: function() {
290
+ if (this.options.toggle) {
291
+ $(this.options.toggle).show();
292
+ }
293
+
294
+ InEdit.current = null;
295
+ return this.fire('hide', this);
296
+ },
297
+
298
+ // the xhr callback
299
+ receive: function() {
300
+ if (this.options.update) {
301
+ this.element.update(this.xhr.text);
302
+ this.fire('update', this);
303
+ }
304
+
305
+ this.xhr = null;
306
+
307
+ this.finish();
308
+ },
309
+
310
+ // catches clicks on the element
311
+ clicked: function(event) {
312
+ if (event.target === this.cancel) {
313
+ event.stop();
314
+ this.hide();
315
+ }
316
+ }
317
+
318
+ });
319
+
320
+ /**
321
+ * The document hooks for in-edit form
322
+ *
323
+ * Copyright (C) 2010 Nikolay Nemshilov
324
+ */
325
+ $(document).onKeydown(function(event) {
326
+ // processing the `ESC` button
327
+ if (event.keyCode === 27 && InEdit.current) {
328
+ InEdit.current.hide();
329
+ }
330
+ });
331
+
332
+ /**
333
+ * The element level inline editor extension
334
+ *
335
+ * Copyright (C) 2009-2010 Nikolay Nemshilov
336
+ */
337
+ Element.include({
338
+ /**
339
+ * Triggers an inline-editor feature on the element
340
+ *
341
+ * @param Object options for the InEdit class
342
+ * @return InEdit object
343
+ */
344
+ inEdit: function(options) {
345
+ return new InEdit(this, options).show();
346
+ }
347
+ });
348
+
349
+ document.write("<style type=\"text/css\">div.rui-spinner,div.rui-spinner div{margin:0;padding:0;border:none;background:none;list-style:none;font-weight:normal;float:none;display:inline-block; *display:inline; *zoom:1;border-radius:.12em;-moz-border-radius:.12em;-webkit-border-radius:.12em}div.rui-spinner{text-align:center;white-space:nowrap;background:#EEE;border:1px solid #DDD;height:1.2em;padding:0 .2em}div.rui-spinner div{width:.4em;height:70%;background:#BBB;margin-left:1px}div.rui-spinner div:first-child{margin-left:0}div.rui-spinner div.glowing{background:#777}form.rui-in-edit,form.rui-in-edit .cancel{margin:0;padding:0;float:none;position:static}form.rui-in-edit{display:inline-block; *display:inline; *zoom:1;border:none;background:none}form.rui-in-edit div.rui-spinner{margin-right:.2em}form.rui-in-edit div.rui-spinner div{margin-top:.2em}form.rui-in-edit textarea.field{width:100%;margin-bottom:.5em}form.rui-in-edit .field,form.rui-in-edit .submit{margin-right:.2em}form.rui-in-edit,form.rui-in-edit .field,form.rui-in-edit .submit,form.rui-in-edit div.rui-spinner,form.rui-in-edit .cancel{vertical-align:middle}</style>");
350
+
351
+ return InEdit;
352
+ })(document, RightJS);
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Inline editor feature for RightJS
3
+ * http://rightjs.org/ui/in-edit
4
+ *
5
+ * Copyright (C) 2009-2010 Nikolay Nemshilov
6
+ */
7
+ var InEdit=RightJS.InEdit=function(i,a){var g=a.$,m=a.$w,n=a.Xhr,o=a.Object,j=a.Element,k=a.Input,p=new a.Wrapper(a.Element,{initialize:function(b){this.$super("div",{"class":"rui-spinner"});this.dots=[];for(var e=0;e<(b||4);e++)this.dots.push(new a.Element("div"));this.dots[0].addClass("glowing");this.insert(this.dots);a(this.shift).bind(this).periodical(300)},shift:function(){if(this.visible()){var b=this.dots.pop();this.dots.unshift(b);this.insert(b,"top")}}}),d=new (function(b,e){if(!e){e=b;b=
8
+ "DIV"}var f=new a.Wrapper(a.Element.Wrappers[b]||a.Element,{initialize:function(h,c){this.key=h;var l=[{"class":"rui-"+h}];this instanceof a.Input||this instanceof a.Form||l.unshift(b);this.$super.apply(this,l);if(a.isString(c))c=a.$(c);if(c instanceof a.Element){this._=c._;if("$listeners"in c)c.$listeners=c.$listeners;c={}}this.setOptions(c,this);return this},setOptions:function(h,c){c=c||this;a.Options.setOptions.call(this,a.Object.merge(h,eval("("+(c.get("data-"+this.key)||"{}")+")")));return this}});
9
+ f=new a.Wrapper(f,e);a.Observer.createShortcuts(f.prototype,f.EVENTS||[]);return f})("FORM",{extend:{version:"2.0.0",EVENTS:m("show hide send update"),Options:{url:null,name:"text",method:"put",type:"text",toggle:null,update:true,Xhr:{}},i18n:{Save:"Save",Cancel:"Cancel"},current:null},initialize:function(b,e){this.element=g(b);this.$super("in-edit",e).set("action",this.options.url).insert([this.field=new k({type:this.options.type,name:this.options.name,"class":"field"}),this.spinner=new p(4),this.submit=
10
+ new k({type:"submit","class":"submit",value:d.i18n.Save}),this.cancel=new j("a",{"class":"cancel",href:"#",html:d.i18n.Cancel})]).onClick(this.clicked).onSubmit(this.send)},show:function(){if(d.current!==this){d.current&&d.current.hide();this.oldContent=this.element.html();a(["file","password"]).include(this.options.type)||this.field.setValue(this.oldContent);this.element.update(this);this.spinner.hide();this.submit.show();this.options.toggle&&g(this.options.toggle).hide()}this.options.type!=="file"&&
11
+ this.field.focus();d.current=this;return this.fire("show",this)},hide:function(){this.element._.innerHTML=this.oldContent;this.xhr&&this.xhr.cancel();return this.finish()},send:function(b){b&&b.stop();this.spinner.show().resize(this.submit.size());this.submit.hide();this.xhr=(new n(this.options.url,o.merge(this.options.Xhr,{method:this.options.method,spinner:this.spinner,onComplete:a(this.receive).bind(this)}))).send(this);return this.fire("send",this)},finish:function(){this.options.toggle&&g(this.options.toggle).show();
12
+ d.current=null;return this.fire("hide",this)},receive:function(){if(this.options.update){this.element.update(this.xhr.text);this.fire("update",this)}this.xhr=null;this.finish()},clicked:function(b){if(b.target===this.cancel){b.stop();this.hide()}}});g(i).onKeydown(function(b){b.keyCode===27&&d.current&&d.current.hide()});j.include({inEdit:function(b){return(new d(this,b)).show()}});i.write('<style type="text/css">div.rui-spinner,div.rui-spinner div{margin:0;padding:0;border:none;background:none;list-style:none;font-weight:normal;float:none;display:inline-block; *display:inline; *zoom:1;border-radius:.12em;-moz-border-radius:.12em;-webkit-border-radius:.12em}div.rui-spinner{text-align:center;white-space:nowrap;background:#EEE;border:1px solid #DDD;height:1.2em;padding:0 .2em}div.rui-spinner div{width:.4em;height:70%;background:#BBB;margin-left:1px}div.rui-spinner div:first-child{margin-left:0}div.rui-spinner div.glowing{background:#777}form.rui-in-edit,form.rui-in-edit .cancel{margin:0;padding:0;float:none;position:static}form.rui-in-edit{display:inline-block; *display:inline; *zoom:1;border:none;background:none}form.rui-in-edit div.rui-spinner{margin-right:.2em}form.rui-in-edit div.rui-spinner div{margin-top:.2em}form.rui-in-edit textarea.field{width:100%;margin-bottom:.5em}form.rui-in-edit .field,form.rui-in-edit .submit{margin-right:.2em}form.rui-in-edit,form.rui-in-edit .field,form.rui-in-edit .submit,form.rui-in-edit div.rui-spinner,form.rui-in-edit .cancel{vertical-align:middle}</style>');
13
+ return d}(document,RightJS);
@@ -0,0 +1,160 @@
1
+ /**
2
+ * The JSON encode/decode feature for RightJS
3
+ * See http://rightjs.org/plugins/json
4
+ *
5
+ * Copyright (C) 2009-2010 Nikolay V. Nemshilov
6
+ */
7
+ var JSON = function(RightJS, window) {
8
+
9
+ /**
10
+ * The generic JSON interface
11
+ *
12
+ * Credits:
13
+ * Based on the original JSON escaping implementation
14
+ * http://www.json.org/json2.js
15
+ *
16
+ * @copyright (C) 2009-2010 Nikolay V. Nemshilov
17
+ */
18
+
19
+ /**
20
+ * Initialization script
21
+ *
22
+ * Copyright (C) 2010 Nikolay Nemshilov
23
+ */
24
+
25
+ var
26
+
27
+ JSON = window.JSON || {},
28
+
29
+ // see the original JSON decoder implementation for descriptions http://www.json.org/json2.js
30
+ cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
31
+ specials = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\'},
32
+ quotables = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
33
+
34
+
35
+ // quotes the string
36
+ function quote(string) {
37
+ return string.replace(quotables, function(chr) {
38
+ return specials[chr] || '\\u' + ('0000' + chr.charCodeAt(0).toString(16)).slice(-4);
39
+ });
40
+ }
41
+
42
+ // adds the leading zero symbol
43
+ function zerofy(num) {
44
+ return (num < 10 ? '0' : '')+num;
45
+ }
46
+
47
+ /**
48
+ * Checking if there is the JSON to String method
49
+ */
50
+ if (!('stringify' in JSON)) {
51
+ JSON.stringify = function(value) {
52
+ if (value === null) {
53
+ return 'null';
54
+ } else if (value.toJSON) {
55
+ return value.toJSON();
56
+ } else {
57
+
58
+ switch(typeof(value)) {
59
+ case 'boolean': return String(value);
60
+ case 'number': return String(value+0);
61
+ case 'string': return '"'+ quote(value) + '"';
62
+ case 'object':
63
+
64
+ if (value instanceof Array) {
65
+ return '['+value.map(JSON.stringify).join(',')+']';
66
+
67
+ } else if (value instanceof Date) {
68
+ return '"' + value.getUTCFullYear() + '-' +
69
+ zerofy(value.getUTCMonth() + 1) + '-' +
70
+ zerofy(value.getUTCDate()) + 'T' +
71
+ zerofy(value.getUTCHours()) + ':' +
72
+ zerofy(value.getUTCMinutes()) + ':' +
73
+ zerofy(value.getUTCSeconds()) + '.' +
74
+ zerofy(value.getMilliseconds()) + 'Z' +
75
+ '"';
76
+
77
+ } else {
78
+ var result = [];
79
+ for (var key in value) {
80
+ result.push(JSON.encode(key)+":"+JSON.encode(value[key]));
81
+ }
82
+ return '{'+result.join(',')+'}';
83
+ }
84
+ }
85
+ }
86
+ };
87
+ }
88
+
89
+ /**
90
+ * Checking if there is the string to JSON method
91
+ */
92
+ if (!('parse' in JSON)) {
93
+ JSON.parse = function(string) {
94
+ if (isString(string) && string) {
95
+ // getting back the UTF-8 symbols
96
+ string = string.replace(cx, function (a) {
97
+ return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
98
+ });
99
+
100
+ // checking the JSON string consistency
101
+ if (/^[\],:{}\s]*$/.test(string.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
102
+ .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
103
+ .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
104
+ return eval('('+string+')');
105
+ }
106
+ }
107
+
108
+ throw "JSON parse error: "+string;
109
+ };
110
+ }
111
+
112
+ RightJS.$alias(JSON, {
113
+ encode: 'stringify',
114
+ decode: 'parse'
115
+ });
116
+
117
+
118
+ /**
119
+ * Wraps up the Cooke set/get methods so that the values
120
+ * were automatically exported/imported into JSON strings
121
+ * and it allowed transparent objects and arrays saving
122
+ *
123
+ * @copyright (C) 2009-2010 Nikolay V. Nemshilov
124
+ */
125
+
126
+ if (RightJS.Cookie) {
127
+ var old_set = RightJS.Cookie.prototype.set,
128
+ old_get = RightJS.Cookie.prototype.get;
129
+
130
+ RightJS.Cookie.include({
131
+ set: function(value) {
132
+ return old_set.call(this, JSON.stringify(value));
133
+ },
134
+
135
+ get: function() {
136
+ return JSON.parse(old_get.call(this));
137
+ }
138
+ });
139
+ }
140
+
141
+
142
+ /**
143
+ * Better JSON sanitizing for the Xhr requests
144
+ *
145
+ * Copyright (C) 2009-2010 Nikolay Nemshilov
146
+ */
147
+ if (RightJS.Xhr) {
148
+ RightJS.Xhr.prototype.sanitizedJSON = function() {
149
+ try {
150
+ return JSON.decode(this.text);
151
+ } catch(e) {
152
+ if (this.secureJSON) { throw e; }
153
+ return null;
154
+ }
155
+ };
156
+ }
157
+
158
+
159
+ return JSON;
160
+ }(RightJS, window);
@@ -0,0 +1,10 @@
1
+ /**
2
+ * The JSON encode/decode feature for RightJS
3
+ * See http://rightjs.org/plugins/json
4
+ *
5
+ * Copyright (C) 2009-2010 Nikolay V. Nemshilov
6
+ */
7
+ var JSON=function(c,g){function h(a){return a.replace(i,function(d){return j[d]||"\\u"+("0000"+d.charCodeAt(0).toString(16)).slice(-4)})}function e(a){return(a<10?"0":"")+a}var b=g.JSON||{},k=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,j={"\u0008":"\\b","\t":"\\t","\n":"\\n","\u000c":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},i=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
8
+ if(!("stringify"in b))b.stringify=function(a){if(a===null)return"null";else if(a.toJSON)return a.toJSON();else switch(typeof a){case "boolean":return String(a);case "number":return String(a+0);case "string":return'"'+h(a)+'"';case "object":if(a instanceof Array)return"["+a.map(b.stringify).join(",")+"]";else if(a instanceof Date)return'"'+a.getUTCFullYear()+"-"+e(a.getUTCMonth()+1)+"-"+e(a.getUTCDate())+"T"+e(a.getUTCHours())+":"+e(a.getUTCMinutes())+":"+e(a.getUTCSeconds())+"."+e(a.getMilliseconds())+
9
+ 'Z"';else{var d=[];for(var f in a)d.push(b.encode(f)+":"+b.encode(a[f]));return"{"+d.join(",")+"}"}}};if(!("parse"in b))b.parse=function(a){if(isString(a)&&a){a=a.replace(k,function(d){return"\\u"+("0000"+d.charCodeAt(0).toString(16)).slice(-4)});if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return eval("("+a+")")}throw"JSON parse error: "+a;};c.$alias(b,
10
+ {encode:"stringify",decode:"parse"});if(c.Cookie){var l=c.Cookie.prototype.set,m=c.Cookie.prototype.get;c.Cookie.include({set:function(a){return l.call(this,b.stringify(a))},get:function(){return b.parse(m.call(this))}})}if(c.Xhr)c.Xhr.prototype.sanitizedJSON=function(){try{return b.decode(this.text)}catch(a){if(this.secureJSON)throw a;return null}};return b}(RightJS,window);