nitro 0.26.0 → 0.27.0

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 (78) hide show
  1. data/CHANGELOG +312 -0
  2. data/INSTALL +3 -1
  3. data/ProjectInfo +6 -9
  4. data/README +32 -5
  5. data/Rakefile +5 -1
  6. data/bin/nitrogen +3 -60
  7. data/doc/MIGRATION +24 -0
  8. data/doc/RELEASES +141 -0
  9. data/doc/lhttpd.txt +3 -0
  10. data/lib/glue/magick.rb +38 -0
  11. data/lib/glue/thumbnails.rb +3 -0
  12. data/lib/glue/webfile.rb +137 -0
  13. data/lib/nitro.rb +1 -1
  14. data/lib/nitro/adapter/acgi.rb +235 -0
  15. data/lib/nitro/adapter/cgi.rb +16 -17
  16. data/lib/nitro/adapter/scgi.rb +4 -4
  17. data/lib/nitro/adapter/webrick.rb +9 -2
  18. data/lib/nitro/cgi.rb +49 -49
  19. data/lib/nitro/cgi/response.rb +4 -0
  20. data/lib/nitro/cgi/stream.rb +7 -7
  21. data/lib/nitro/cgi/utils.rb +2 -1
  22. data/lib/nitro/compiler.rb +47 -4
  23. data/lib/nitro/compiler/elements.rb +40 -20
  24. data/lib/nitro/compiler/layout.rb +21 -0
  25. data/lib/nitro/compiler/localization.rb +3 -1
  26. data/lib/nitro/compiler/markup.rb +2 -0
  27. data/lib/nitro/compiler/morphing.rb +16 -4
  28. data/lib/nitro/compiler/script.rb +109 -0
  29. data/lib/nitro/context.rb +10 -10
  30. data/lib/nitro/dispatcher.rb +4 -2
  31. data/lib/nitro/element.rb +107 -26
  32. data/lib/nitro/element/{java_script.rb → javascript.rb} +7 -1
  33. data/lib/nitro/flash.rb +4 -1
  34. data/lib/nitro/helper.rb +15 -0
  35. data/lib/nitro/helper/benchmark.rb +8 -2
  36. data/lib/nitro/helper/form.rb +3 -3
  37. data/lib/nitro/helper/form/controls.rb +131 -29
  38. data/lib/nitro/helper/{dojo.rb → form/test.xhtml} +0 -0
  39. data/lib/nitro/helper/javascript.rb +69 -59
  40. data/lib/nitro/helper/{scriptaculous.rb → javascript/dojo.rb} +0 -0
  41. data/lib/nitro/helper/javascript/morphing.rb +163 -0
  42. data/lib/nitro/helper/javascript/prototype.rb +96 -0
  43. data/lib/nitro/helper/javascript/scriptaculous.rb +18 -0
  44. data/lib/nitro/helper/layout.rb +42 -0
  45. data/lib/nitro/helper/table.rb +190 -27
  46. data/lib/nitro/{adapter → helper}/wee.rb +9 -3
  47. data/lib/nitro/render.rb +23 -17
  48. data/lib/nitro/scaffolding.rb +19 -2
  49. data/lib/nitro/server.rb +4 -8
  50. data/lib/nitro/server/runner.rb +28 -6
  51. data/lib/nitro/session.rb +7 -7
  52. data/lib/nitro_and_og.rb +2 -0
  53. data/proto/public/Makefile.acgi +40 -0
  54. data/proto/public/acgi.c +138 -0
  55. data/proto/public/js/builder.js +7 -3
  56. data/proto/public/js/controls.js +32 -12
  57. data/proto/public/js/dragdrop.js +4 -3
  58. data/proto/public/js/effects.js +111 -62
  59. data/proto/public/js/scriptaculous.js +10 -13
  60. data/proto/public/js/slider.js +88 -31
  61. data/proto/public/scaffold/new.xhtml +2 -2
  62. data/setup.rb +1585 -0
  63. data/src/part/admin.rb +6 -0
  64. data/src/part/admin/controller.rb +3 -3
  65. data/src/part/admin/skin.rb +1 -8
  66. data/test/nitro/adapter/tc_webrick.rb +2 -0
  67. data/test/nitro/tc_controller_aspect.rb +1 -1
  68. data/test/nitro/tc_element.rb +5 -6
  69. data/test/nitro/tc_table.rb +66 -0
  70. metadata +277 -271
  71. data/doc/architecture.txt +0 -2
  72. data/doc/bugs.txt +0 -15
  73. data/doc/tutorial.txt +0 -26
  74. data/install.rb +0 -37
  75. data/lib/nitro/compiler/script_generator.rb +0 -14
  76. data/lib/nitro/compiler/shaders.rb +0 -206
  77. data/lib/nitro/helper/prototype.rb +0 -49
  78. data/lib/nitro/scaffold/relations.rb +0 -54
data/lib/nitro/server.rb CHANGED
@@ -111,20 +111,16 @@ class Server
111
111
  unless options.is_a?(Hash)
112
112
  options = { :controller => options }
113
113
  end
114
-
114
+
115
115
  runner = Runner.new
116
116
  runner.setup_options
117
117
  runner.setup_mode
118
118
  runner.daemonize if runner.daemon
119
-
119
+
120
120
  server = Server.new
121
121
  server.start(options)
122
-
123
- unless $NITRO_NO_INVOKE
124
- runner.invoke(server)
125
- else
126
- Logger.info 'Running in console mode.'
127
- end
122
+
123
+ runner.invoke(server) unless $NITRO_NO_INVOKE
128
124
 
129
125
  return server
130
126
  end
@@ -3,6 +3,9 @@ require 'optparse'
3
3
  require 'glue/configuration'
4
4
  require 'nitro/compiler'
5
5
 
6
+ #require 'nano/kernel/autoreload'
7
+ require 'glue/autoreload'
8
+
6
9
  module Nitro
7
10
 
8
11
  # The Runner is a helper class that encapsulates a web
@@ -216,7 +219,6 @@ class Runner
216
219
  def setup_debug
217
220
  $DBG = true
218
221
  Compiler.reload = true
219
- require 'nano/kernel/autoreload'
220
222
  autoreload(3)
221
223
  Caching.caching_enabled = false
222
224
 
@@ -226,6 +228,7 @@ class Runner
226
228
  def setup_stage
227
229
  $DBG = false
228
230
  Compiler.reload = true
231
+ autoreload(3)
229
232
  Logger.set(Logger.new('log/app.log'))
230
233
 
231
234
  load_external_configuration(:stage)
@@ -233,7 +236,14 @@ class Runner
233
236
 
234
237
  def setup_live
235
238
  $DBG = false
236
- Compiler.reload = false
239
+
240
+ # Enable the reloading even on live apps by default.
241
+ # But have a longer thread sleep time.
242
+ # If you really need sligthly faster dispatching enable
243
+ # reloading (Compiler.reload = false)
244
+
245
+ Compiler.reload = true
246
+ autoreload(2 * 60)
237
247
  Logger.set(Logger.new('log/app.log'))
238
248
 
239
249
  load_external_configuration(:live)
@@ -244,21 +254,26 @@ class Runner
244
254
  # ...
245
255
 
246
256
  def invoke(server)
247
- if 'fcgi_proc' == ENV['NITRO_INVOKE']
257
+ case ENV['NITRO_INVOKE']
258
+ when 'fcgi_proc'
248
259
  require 'nitro/adapter/fastcgi'
249
260
  FastCGI.start(server)
250
261
 
251
- elsif 'scgi_proc' == ENV['NITRO_INVOKE']
262
+ when 'scgi_proc'
252
263
  require 'nitro/adapter/scgi'
253
264
  Scgi.start(server)
254
265
 
255
- elsif 'cgi_proc' == ENV['NITRO_INVOKE']
266
+ when 'cgi_proc'
256
267
  require 'nitro/adapter/cgi'
257
268
  CgiAdapter.start(server)
258
269
 
259
- elsif 'irb' == ENV['NITRO_INVOKE']
270
+ when 'irb'
260
271
  $server = server
261
272
 
273
+ when 'acgi_proc'
274
+ require 'nitro/adapter/acgi'
275
+ ACGI.start(server)
276
+
262
277
  else
263
278
  invoke_server(server)
264
279
  end
@@ -314,6 +329,10 @@ class Runner
314
329
  when :cgi
315
330
  require 'nitro/adapter/cgi'
316
331
  puts "==> Using standard CGI. Please look into using Fast/Scgi"
332
+
333
+ when :acgi
334
+ require 'nitro/adapter/acgi'
335
+ puts "==> Launching ACGI."
317
336
  end
318
337
 
319
338
  when :stop
@@ -325,6 +344,9 @@ class Runner
325
344
 
326
345
  when :apache
327
346
  `apachectl -d #{Dir.pwd} -f conf/apache.conf -k stop`
347
+
348
+ when :acgi
349
+ `public/acgi.cgi stop`
328
350
  end
329
351
 
330
352
  end
data/lib/nitro/session.rb CHANGED
@@ -27,7 +27,7 @@ module Nitro
27
27
  # TODO rehash of the session cookie
28
28
 
29
29
  class Session < Hash
30
- is Expirable
30
+ include Expirable
31
31
 
32
32
  # Session id salt.
33
33
 
@@ -62,12 +62,8 @@ class Session < Hash
62
62
  # * :memcached (not available yet)
63
63
 
64
64
  def store_type=(store_type)
65
- # gmosx: RDoc complains about this, so lets use an
66
- # eval, AAAAAAAARGH!
67
- # require "nitro/session/#{store_type}"
68
- Logger.debug "Using #{store_type} sessions."
69
-
70
- eval %{ require 'nitro/session/#{store_type}' }
65
+ # gmosx: RDoc friendly.
66
+ require 'nitro/session/' + store_type.to_s
71
67
  end
72
68
  alias_method :set_store_type, :store_type=
73
69
 
@@ -112,10 +108,14 @@ class Session < Hash
112
108
  attr_reader :session_id
113
109
 
114
110
  # Create the session for the given context.
111
+ # If the hook method 'created' is defined it is called
112
+ # at the end. Typically used to initialize the session
113
+ # hash.
115
114
 
116
115
  def initialize(context = nil)
117
116
  @session_id = create_id
118
117
  expires_after(Session.keepalive)
118
+ created if respond_to?(:created)
119
119
  end
120
120
 
121
121
  # Synchronize the session store, by
@@ -0,0 +1,2 @@
1
+ require 'nitro'
2
+ require 'og'
@@ -0,0 +1,40 @@
1
+ ruby=ruby
2
+
3
+ all : acgi.cgi ipc
4
+
5
+ acgi.cgi: acgi
6
+ mv ./acgi ./acgi.cgi
7
+ chmod 755 ./acgi.cgi
8
+
9
+ ipc:
10
+ mkdir /tmp/acgi_ipc/ > /dev/null 2>&1 || true
11
+ chmod 777 /tmp/acgi_ipc/ > /dev/null 2>&1 || true
12
+ mkfifo /tmp/acgi_ipc/server.commands > /dev/null 2>&1 || true
13
+ mkfifo /tmp/acgi_ipc/server.environment > /dev/null 2>&1 || true
14
+ mkfifo /tmp/acgi_ipc/server.stdin > /dev/null 2>&1 || true
15
+ mkfifo /tmp/acgi_ipc/server.stdout > /dev/null 2>&1 || true
16
+ mkfifo /tmp/acgi_ipc/server.stderr > /dev/null 2>&1 || true
17
+ touch /tmp/acgi_ipc/client.lock > /dev/null 2>&1 || true
18
+ touch /tmp/acgi_ipc/server.lock > /dev/null 2>&1 || true
19
+ chmod 777 /tmp/acgi_ipc/* > /dev/null 2>&1 || true
20
+ chmod 777 /tmp/acgi_ipc/ > /dev/null 2>&1 || true
21
+ chmod 777 . > /dev/null 2>&1 || true
22
+
23
+ clean:
24
+ rm -f acgi.cgi
25
+ rm -rf /tmp/acgi_ipc
26
+
27
+ start:
28
+ server.cgi start
29
+
30
+ stop:
31
+ server.cgi stop
32
+
33
+ restart:
34
+ server.cgi restart
35
+
36
+ pid:
37
+ server.cgi pid
38
+
39
+ status:
40
+ server.cgi status
@@ -0,0 +1,138 @@
1
+ #include <stdlib.h>
2
+ #include <stdio.h>
3
+ #include <fcntl.h>
4
+ #include <unistd.h>
5
+
6
+
7
+ #define BUF_SIZE 8192
8
+ //#define STRING(str) #str
9
+ //#define BUF_FILL_FORMAT "%" STRING(BUF_SIZE) "c"
10
+ #define BUF_FILL_FORMAT "%8192c"
11
+
12
+ #define IPC_DIR "/tmp/acgi_ipc"
13
+ #define PATH_SEPARATOR "/"
14
+
15
+ #define CLIENT_LOCK_PATH IPC_DIR PATH_SEPARATOR "client.lock"
16
+ #define SERVER_LOCK_PATH IPC_DIR PATH_SEPARATOR "server.lock"
17
+ #define SERVER_ENVIRONMENT_PATH IPC_DIR PATH_SEPARATOR "server.environment"
18
+ #define SERVER_STDIN_PATH IPC_DIR PATH_SEPARATOR "server.stdin"
19
+ #define SERVER_STDOUT_PATH IPC_DIR PATH_SEPARATOR "server.stdout"
20
+ #define SERVER_STDERR_PATH IPC_DIR PATH_SEPARATOR "server.stderr"
21
+
22
+ //#define SERVER_RB "nohup ruby ../run.rb </dev/null >/dev/null 2>&1 &"
23
+ #define SERVER_RB "ruby ../run.rb"
24
+
25
+ static int argc;
26
+ static char **argv;
27
+ static char **env;
28
+ static FILE *fs_client_lock;
29
+ static FILE *fs_server_lock;
30
+ static FILE *fs_environment;
31
+ static FILE *fs_stdin;
32
+ static FILE *fs_stderr;
33
+ static FILE *fs_stdout;
34
+ static struct flock lock;
35
+ static char **e;
36
+ static char buf[BUF_SIZE];
37
+ static int n;
38
+
39
+ static void
40
+ ensure_server_running ()
41
+ {
42
+ int ret;
43
+ char *cmd;
44
+ fs_server_lock = fopen (SERVER_LOCK_PATH, "w");
45
+ lock.l_type = F_WRLCK;
46
+ if(fcntl (fileno (fs_server_lock), F_SETLK, &lock) == 0)
47
+ {
48
+ cmd = SERVER_RB;
49
+ system (cmd);
50
+ lock.l_type = F_UNLCK;
51
+ fcntl (fileno (fs_server_lock), F_SETLKW, &lock);
52
+ flock(fileno(fs_server_lock), (LOCK_UN|LOCK_NB));
53
+ }
54
+ }
55
+ static void
56
+ aquire_lock ()
57
+ {
58
+ fs_client_lock = fopen (CLIENT_LOCK_PATH, "w");
59
+ lock.l_type = F_WRLCK;
60
+ fcntl (fileno (fs_client_lock), F_SETLKW, &lock);
61
+ }
62
+ static void
63
+ send_env ()
64
+ {
65
+ fs_environment = fopen (SERVER_ENVIRONMENT_PATH, "w");
66
+ for (e = env; *e; e++)
67
+ {
68
+ fprintf (fs_environment, "%s%c", *e, '\0');
69
+ }
70
+ fclose (fs_environment);
71
+ }
72
+ static void
73
+ send_stdin ()
74
+ {
75
+ buf[0] = n = 0;
76
+ fs_stdin = fopen (SERVER_STDIN_PATH, "w");
77
+ while ((n = fscanf (stdin, BUF_FILL_FORMAT, &buf[0])) > 0)
78
+ {
79
+ fprintf (fs_stdin, "%*s", n, buf);
80
+ }
81
+ fclose (fs_stdin);
82
+ }
83
+ static void
84
+ open_stdout_and_stderr ()
85
+ {
86
+ fs_stdout = fopen (SERVER_STDOUT_PATH, "r");
87
+ fs_stderr = fopen (SERVER_STDERR_PATH, "r");
88
+ }
89
+ static void
90
+ receive_stdout ()
91
+ {
92
+ buf[0] = n = 0;
93
+ while ((n = fscanf (fs_stdout, BUF_FILL_FORMAT, &buf[0])) > 0)
94
+ {
95
+ fprintf (stdout, "%*s", n, buf);
96
+ }
97
+ fclose (fs_stdout);
98
+ }
99
+ static void
100
+ receive_stderr ()
101
+ {
102
+ buf[0] = n = 0;
103
+ while ((n = fscanf (fs_stderr, BUF_FILL_FORMAT, &buf[0])) > 0)
104
+ {
105
+ fprintf (stderr, "%*s", n, buf);
106
+ }
107
+ fclose (fs_stderr);
108
+ }
109
+ static void
110
+ release_lock ()
111
+ {
112
+ lock.l_type = F_UNLCK;
113
+ fcntl (fileno (fs_client_lock), F_SETLK, &lock);
114
+ }
115
+
116
+ int
117
+ main (__argc, __argv, __env)
118
+ int __argc;
119
+ char **__argv;
120
+ char **__env;
121
+ {
122
+ argc = __argc;
123
+ argv = __argv;
124
+ env = __env;
125
+
126
+ putenv ("ACGI_SERVER=1");
127
+ putenv ("NITRO_INVOKE=acgi_proc");
128
+
129
+ ensure_server_running ();
130
+ aquire_lock ();
131
+ send_env ();
132
+ send_stdin ();
133
+ open_stdout_and_stderr ();
134
+ receive_stdout ();
135
+ receive_stderr ();
136
+ release_lock ();
137
+ return 0;
138
+ }
@@ -27,7 +27,9 @@ var Builder = {
27
27
  // try innerHTML approach
28
28
  var parentTag = this.NODEMAP[elementName] || 'div';
29
29
  var parentElement = document.createElement(parentTag);
30
- parentElement.innerHTML = "<" + elementName + "></" + elementName + ">";
30
+ try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
31
+ parentElement.innerHTML = "<" + elementName + "></" + elementName + ">";
32
+ } catch(e) {}
31
33
  var element = parentElement.firstChild || null;
32
34
 
33
35
  // see if browser added wrapping tags
@@ -48,8 +50,10 @@ var Builder = {
48
50
  } else {
49
51
  var attrs = this._attributes(arguments[1]);
50
52
  if(attrs.length) {
51
- parentElement.innerHTML = "<" +elementName + " " +
52
- attrs + "></" + elementName + ">";
53
+ try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
54
+ parentElement.innerHTML = "<" +elementName + " " +
55
+ attrs + "></" + elementName + ">";
56
+ } catch(e) {}
53
57
  element = parentElement.firstChild || null;
54
58
  // workaround firefox 1.0.X bug
55
59
  if(!element) {
@@ -221,8 +221,13 @@ Autocompleter.Base.prototype = {
221
221
  this.options.updateElement(selectedElement);
222
222
  return;
223
223
  }
224
-
225
- var value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
224
+ var value = '';
225
+ if (this.options.select) {
226
+ var nodes = document.getElementsByClassName(this.options.select, selectedElement) || [];
227
+ if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
228
+ } else
229
+ value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
230
+
226
231
  var lastTokenPos = this.findLastToken();
227
232
  if (lastTokenPos != -1) {
228
233
  var newValue = this.element.value.substr(0, lastTokenPos + 1);
@@ -448,7 +453,9 @@ Ajax.InPlaceEditor.prototype = {
448
453
  this.element = $(element);
449
454
 
450
455
  this.options = Object.extend({
456
+ okButton: true,
451
457
  okText: "ok",
458
+ cancelLink: true,
452
459
  cancelText: "cancel",
453
460
  savingText: "Saving...",
454
461
  clickToEditText: "Click to edit",
@@ -471,6 +478,7 @@ Ajax.InPlaceEditor.prototype = {
471
478
  highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor,
472
479
  highlightendcolor: "#FFFFFF",
473
480
  externalControl: null,
481
+ submitOnBlur: false,
474
482
  ajaxOptions: {}
475
483
  }, options || {});
476
484
 
@@ -536,16 +544,20 @@ Ajax.InPlaceEditor.prototype = {
536
544
  this.form.appendChild(br);
537
545
  }
538
546
 
539
- okButton = document.createElement("input");
540
- okButton.type = "submit";
541
- okButton.value = this.options.okText;
542
- this.form.appendChild(okButton);
547
+ if (this.options.okButton) {
548
+ okButton = document.createElement("input");
549
+ okButton.type = "submit";
550
+ okButton.value = this.options.okText;
551
+ this.form.appendChild(okButton);
552
+ }
543
553
 
544
- cancelLink = document.createElement("a");
545
- cancelLink.href = "#";
546
- cancelLink.appendChild(document.createTextNode(this.options.cancelText));
547
- cancelLink.onclick = this.onclickCancel.bind(this);
548
- this.form.appendChild(cancelLink);
554
+ if (this.options.cancelLink) {
555
+ cancelLink = document.createElement("a");
556
+ cancelLink.href = "#";
557
+ cancelLink.appendChild(document.createTextNode(this.options.cancelText));
558
+ cancelLink.onclick = this.onclickCancel.bind(this);
559
+ this.form.appendChild(cancelLink);
560
+ }
549
561
  },
550
562
  hasHTMLLineBreaks: function(string) {
551
563
  if (!this.options.handleLineBreaks) return false;
@@ -561,24 +573,32 @@ Ajax.InPlaceEditor.prototype = {
561
573
  } else {
562
574
  text = this.getText();
563
575
  }
576
+
577
+ var obj = this;
564
578
 
565
579
  if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) {
566
580
  this.options.textarea = false;
567
581
  var textField = document.createElement("input");
582
+ textField.obj = this;
568
583
  textField.type = "text";
569
584
  textField.name = "value";
570
585
  textField.value = text;
571
586
  textField.style.backgroundColor = this.options.highlightcolor;
572
587
  var size = this.options.size || this.options.cols || 0;
573
588
  if (size != 0) textField.size = size;
589
+ if (this.options.submitOnBlur)
590
+ textField.onblur = this.onSubmit.bind(this);
574
591
  this.editField = textField;
575
592
  } else {
576
593
  this.options.textarea = true;
577
594
  var textArea = document.createElement("textarea");
595
+ textArea.obj = this;
578
596
  textArea.name = "value";
579
597
  textArea.value = this.convertHTMLLineBreaks(text);
580
598
  textArea.rows = this.options.rows;
581
599
  textArea.cols = this.options.cols || 40;
600
+ if (this.options.submitOnBlur)
601
+ textArea.onblur = this.onSubmit.bind(this);
582
602
  this.editField = textArea;
583
603
  }
584
604
 
@@ -747,4 +767,4 @@ Form.Element.DelayedObserver.prototype = {
747
767
  this.timer = null;
748
768
  this.callback(this.element, $F(this.element));
749
769
  }
750
- };
770
+ };