nitro 0.26.0 → 0.27.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ };