nitro 0.28.0 → 0.29.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.
- data/CHANGELOG +382 -0
- data/ProjectInfo +4 -4
- data/README +1 -1
- data/doc/AUTHORS +15 -15
- data/doc/MIGRATION +13 -0
- data/doc/RELEASES +102 -0
- data/lib/glue/sweeper.rb +1 -1
- data/lib/nitro.rb +38 -9
- data/lib/nitro/adapter/acgi.rb +1 -3
- data/lib/nitro/adapter/cgi.rb +1 -1
- data/lib/nitro/adapter/fastcgi.rb +1 -3
- data/lib/nitro/adapter/mongrel.rb +8 -6
- data/lib/nitro/adapter/webrick.rb +1 -2
- data/lib/nitro/cgi.rb +1 -1
- data/lib/nitro/compiler.rb +21 -40
- data/lib/nitro/compiler/elements.rb +72 -32
- data/lib/nitro/compiler/errors.rb +92 -42
- data/lib/nitro/compiler/include.rb +47 -17
- data/lib/nitro/compiler/morphing.rb +1 -3
- data/lib/nitro/compiler/script.rb +2 -2
- data/lib/nitro/context.rb +36 -0
- data/lib/nitro/controller.rb +140 -31
- data/lib/nitro/dispatcher.rb +27 -28
- data/lib/nitro/element.rb +52 -15
- data/lib/nitro/flash.rb +44 -0
- data/lib/nitro/helper/buffer.rb +0 -2
- data/lib/nitro/helper/form.rb +2 -2
- data/lib/nitro/helper/form/controls.rb +14 -3
- data/lib/nitro/helper/pager.rb +1 -1
- data/lib/nitro/helper/table.rb +4 -3
- data/lib/nitro/helper/xml.rb +1 -1
- data/lib/nitro/part.rb +20 -0
- data/lib/nitro/render.rb +44 -5
- data/lib/nitro/router.rb +81 -0
- data/lib/nitro/scaffolding.rb +24 -23
- data/lib/nitro/server.rb +12 -1
- data/lib/nitro/server/runner.rb +12 -0
- data/lib/nitro/session.rb +3 -12
- data/lib/nitro/session/drb.rb +2 -5
- data/lib/nitro/session/file.rb +2 -2
- data/lib/nitro/session/memcached.rb +14 -0
- data/lib/nitro/session/memory.rb +3 -26
- data/lib/nitro/session/og.rb +1 -1
- data/lib/nitro/test/assertions.rb +1 -1
- data/lib/nitro/test/context.rb +8 -2
- data/lib/nitro/test/testcase.rb +16 -7
- data/proto/public/error.xhtml +58 -21
- data/proto/public/js/controls.js +60 -15
- data/proto/public/js/dragdrop.js +105 -16
- data/proto/public/js/effects.js +19 -12
- data/proto/public/js/scriptaculous.js +1 -1
- data/proto/public/js/slider.js +2 -2
- data/proto/public/js/unittest.js +29 -20
- data/proto/public/scaffold/edit.xhtml +1 -1
- data/proto/public/scaffold/index.xhtml +2 -2
- data/proto/public/scaffold/list.xhtml +2 -2
- data/proto/public/scaffold/new.xhtml +1 -1
- data/proto/public/scaffold/search.xhtml +1 -1
- data/src/part/admin/controller.rb +5 -5
- data/src/part/admin/template/index.xhtml +2 -2
- data/test/nitro/compiler/tc_compiler.rb +23 -0
- data/test/nitro/helper/tc_table.rb +35 -0
- data/test/nitro/tc_cgi.rb +1 -1
- data/test/nitro/tc_controller.rb +3 -3
- data/test/nitro/tc_controller_aspect.rb +2 -0
- data/test/nitro/tc_dispatcher.rb +10 -1
- data/test/nitro/tc_flash.rb +14 -0
- data/test/nitro/tc_router.rb +58 -0
- data/test/nitro/tc_session.rb +26 -9
- metadata +13 -12
- data/lib/nitro/routing.rb +0 -41
- data/test/nitro/caching/tc_stores.rb +0 -17
- data/test/nitro/tc_table.rb +0 -66
data/lib/nitro/server.rb
CHANGED
@@ -77,7 +77,7 @@ class Server
|
|
77
77
|
|
78
78
|
def dispatcher
|
79
79
|
unless @dispatcher
|
80
|
-
@dispatcher = Dispatcher.new(
|
80
|
+
@dispatcher = Dispatcher.new(@map)
|
81
81
|
end
|
82
82
|
@dispatcher
|
83
83
|
end
|
@@ -87,6 +87,17 @@ class Server
|
|
87
87
|
def start(options = {})
|
88
88
|
@map['/'] = options[:controller] if options[:controller]
|
89
89
|
@dispatcher = options[:dispatcher] || Dispatcher.new(@map)
|
90
|
+
|
91
|
+
# Create the actual store. Copy values already inserted
|
92
|
+
# in the temporary cache.
|
93
|
+
#--
|
94
|
+
# FIXME: cleanup this code
|
95
|
+
#++
|
96
|
+
|
97
|
+
temp = $global
|
98
|
+
$global = $application = Context.global_cache_class.new
|
99
|
+
$global.update(temp)
|
100
|
+
|
90
101
|
return self
|
91
102
|
end
|
92
103
|
|
data/lib/nitro/server/runner.rb
CHANGED
@@ -124,6 +124,14 @@ class Runner
|
|
124
124
|
self.class.mode = :live
|
125
125
|
end
|
126
126
|
|
127
|
+
opts.on('--address IP', 'Force the server to run on this address.') do |a|
|
128
|
+
@server_address = a
|
129
|
+
end
|
130
|
+
|
131
|
+
opts.on('--port PORT', 'Force the server to run on this port.') do |p|
|
132
|
+
@server_port = p.to_i
|
133
|
+
end
|
134
|
+
|
127
135
|
opts.on('-w', '--webrick', 'Use a webrick server [default].') do
|
128
136
|
@server = :webrick
|
129
137
|
end
|
@@ -293,6 +301,10 @@ class Runner
|
|
293
301
|
def invoke_server(server)
|
294
302
|
spider_thread = nil
|
295
303
|
|
304
|
+
# FIXME refactor !
|
305
|
+
server.address = @server_address if @server_address
|
306
|
+
server.port = @server_port if @server_port
|
307
|
+
|
296
308
|
case @action
|
297
309
|
when :start
|
298
310
|
|
data/lib/nitro/session.rb
CHANGED
@@ -7,7 +7,6 @@ require 'facet/times'
|
|
7
7
|
require 'glue'
|
8
8
|
require 'glue/attribute'
|
9
9
|
require 'glue/configuration'
|
10
|
-
require 'glue/logger'
|
11
10
|
require 'glue/expirable'
|
12
11
|
|
13
12
|
require 'nitro/cgi/cookie'
|
@@ -31,7 +30,7 @@ module Nitro
|
|
31
30
|
#++
|
32
31
|
|
33
32
|
class Session < Hash
|
34
|
-
include Expirable
|
33
|
+
include Glue::Expirable
|
35
34
|
|
36
35
|
# Session id salt.
|
37
36
|
|
@@ -50,14 +49,6 @@ class Session < Hash
|
|
50
49
|
|
51
50
|
setting :keepalive, :default => 30.minutes, :doc => 'The session keepalive time'
|
52
51
|
|
53
|
-
# The address of the Session cache / store (if distibuted).
|
54
|
-
|
55
|
-
setting :cache_address, :default => '127.0.0.1', :doc => 'The address of the Session cache'
|
56
|
-
|
57
|
-
# The port of the Session DRb cache / store (if distributed).
|
58
|
-
|
59
|
-
setting :cache_port, :default => 9069, :doc => 'The port of the Session cache'
|
60
|
-
|
61
52
|
# The sessions cache (store).
|
62
53
|
|
63
54
|
cattr_accessor :cache
|
@@ -70,8 +61,8 @@ class Session < Hash
|
|
70
61
|
# * :memory [default]
|
71
62
|
# * :drb
|
72
63
|
# * :og
|
73
|
-
# * :file
|
74
|
-
# * :memcached
|
64
|
+
# * :file
|
65
|
+
# * :memcached
|
75
66
|
|
76
67
|
def cache_type=(cache_type)
|
77
68
|
# gmosx: RDoc friendly.
|
data/lib/nitro/session/drb.rb
CHANGED
@@ -3,12 +3,9 @@ require 'nitro/session'
|
|
3
3
|
|
4
4
|
module Nitro
|
5
5
|
|
6
|
-
Logger.debug "Using DRb sessions at #{
|
6
|
+
Logger.debug "Using DRb sessions at #{Glue::DrbCache.address}:#{Glue::DrbCache.port}." if defined?(Logger)
|
7
7
|
|
8
|
-
Session.cache = DrbCache.new
|
9
|
-
:address => Session.cache_address,
|
10
|
-
:port => Session.cache_port
|
11
|
-
)
|
8
|
+
Session.cache = Glue::DrbCache.new
|
12
9
|
|
13
10
|
end
|
14
11
|
|
data/lib/nitro/session/file.rb
CHANGED
@@ -5,9 +5,9 @@ module Nitro
|
|
5
5
|
|
6
6
|
# A Session manager that persists sessions on disk.
|
7
7
|
|
8
|
-
Logger.debug "Using File sessions."
|
8
|
+
Logger.debug "Using File sessions." if defined?(Logger)
|
9
9
|
|
10
|
-
Session.cache = FileCache.new("session_#{Session.cookie_name}", Session.keepalive)
|
10
|
+
Session.cache = Glue::FileCache.new("session_#{Session.cookie_name}", Session.keepalive)
|
11
11
|
|
12
12
|
end
|
13
13
|
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'glue/cache/memcached'
|
2
|
+
require 'nitro/session'
|
3
|
+
|
4
|
+
module Nitro
|
5
|
+
|
6
|
+
# A Session manager that persists sessions on disk.
|
7
|
+
|
8
|
+
Logger.debug "Using MemCached sessions." if defined?(Logger)
|
9
|
+
|
10
|
+
Session.cache = Glue::MemCached.new("session_#{Session.cookie_name}", Session.keepalive)
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
# * Guillaume Pierronnet <guillaume.pierronnet@gmail.com>
|
data/lib/nitro/session/memory.rb
CHANGED
@@ -1,36 +1,13 @@
|
|
1
1
|
require 'glue/cache/memory'
|
2
2
|
require 'nitro/session'
|
3
|
+
require 'glue/logger'
|
3
4
|
|
4
5
|
module Nitro
|
5
6
|
|
6
|
-
Logger.debug "Using Memory sessions."
|
7
|
+
Logger.debug "Using Memory sessions." if defined?(Logger)
|
7
8
|
|
8
|
-
Session.cache = MemoryCache.new
|
9
|
+
Session.cache = Glue::MemoryCache.new
|
9
10
|
|
10
11
|
end
|
11
12
|
|
12
13
|
# * George Moschovitis <gm@navel.gr>
|
13
|
-
|
14
|
-
=begin
|
15
|
-
|
16
|
-
module Nitro
|
17
|
-
|
18
|
-
class MemorySessionStore < SyncHash
|
19
|
-
|
20
|
-
# Perform session garbage collection. Typically this method
|
21
|
-
# is called from a cron like mechanism (for example using
|
22
|
-
# script/runner).
|
23
|
-
|
24
|
-
def gc!
|
25
|
-
delete_if { |key, s| s.expired? }
|
26
|
-
end
|
27
|
-
|
28
|
-
alias :all :values
|
29
|
-
end
|
30
|
-
|
31
|
-
Session.store = MemorySessionStore.new
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
# * George Moschovitis <gm@navel.gr>
|
36
|
-
=end
|
data/lib/nitro/session/og.rb
CHANGED
data/lib/nitro/test/context.rb
CHANGED
@@ -40,11 +40,17 @@ end
|
|
40
40
|
# to include methods useful for testing.
|
41
41
|
|
42
42
|
class Context
|
43
|
+
attr_writer :session, :cookies
|
44
|
+
|
43
45
|
def session
|
44
46
|
@session || @session = {}
|
45
|
-
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def cookies
|
50
|
+
@cookies || @cookies = {}
|
51
|
+
end
|
52
|
+
|
46
53
|
end
|
47
54
|
|
48
55
|
end
|
49
|
-
|
50
56
|
# * George Moschovitis <gm@navel.gr>
|
data/lib/nitro/test/testcase.rb
CHANGED
@@ -10,8 +10,11 @@ module Test::Unit
|
|
10
10
|
class TestCase
|
11
11
|
include Nitro
|
12
12
|
|
13
|
-
def
|
14
|
-
@
|
13
|
+
def reset_context
|
14
|
+
@context_config = OpenStruct.new(
|
15
|
+
:dispatcher => Nitro::Dispatcher.new(Nitro::Server.map)
|
16
|
+
)
|
17
|
+
@context = Nitro::Context.new(@context_config)
|
15
18
|
end
|
16
19
|
|
17
20
|
# Send a request to the controller. Alternatively you can use
|
@@ -29,17 +32,23 @@ class TestCase
|
|
29
32
|
uri = options[:uri]
|
30
33
|
uri = "/#{uri}" unless uri =~ /^\//
|
31
34
|
|
32
|
-
|
33
|
-
|
35
|
+
reset_context unless @context
|
36
|
+
context = @context
|
37
|
+
if @last_response_cookies
|
38
|
+
@last_response_cookies.each do |cookie|
|
39
|
+
context.cookies.merge! cookie.name => cookie.value
|
40
|
+
end
|
41
|
+
end
|
34
42
|
context.params = options[:params] || {}
|
35
43
|
context.headers = options[:headers] || options[:env] || {}
|
36
44
|
context.headers['REQUEST_URI'] = uri
|
37
45
|
context.headers['REQUEST_METHOD'] = options[:method].to_s.upcase
|
38
|
-
context.
|
39
|
-
context.
|
46
|
+
context.headers['REMOTE_ADDR'] ||= '127.0.0.1'
|
47
|
+
context.cookies.merge! options[:cookies] if options[:cookies]
|
48
|
+
context.session.merge! options[:session] if options[:session]
|
40
49
|
|
41
50
|
context.render(context.path)
|
42
|
-
|
51
|
+
@last_response_cookies = context.response_cookies
|
43
52
|
return context.body
|
44
53
|
end
|
45
54
|
|
data/proto/public/error.xhtml
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
<html>
|
2
2
|
<head>
|
3
|
+
<script lang="javascript" type="text/javascript">
|
4
|
+
// <!--
|
5
|
+
function toggleVisible(element) {
|
6
|
+
if (element.style.display == 'block') {
|
7
|
+
element.style.display = 'none';
|
8
|
+
} else {
|
9
|
+
element.style.display = 'block';
|
10
|
+
}
|
11
|
+
return false;
|
12
|
+
}
|
13
|
+
// -->
|
14
|
+
</script>
|
3
15
|
<title>Error</title>
|
4
16
|
<style>
|
5
17
|
.path {
|
@@ -38,27 +50,52 @@
|
|
38
50
|
<?r for error, path in @context.rendering_errors ?>
|
39
51
|
<div class="path"><strong>Path:</strong> #{path}</div>
|
40
52
|
<div class="error"><strong>#{CGI.escapeHTML(error.to_s)}</strong></div>
|
41
|
-
<div class="load">
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
<?r
|
60
|
-
|
61
|
-
|
53
|
+
<div class="load">
|
54
|
+
<strong><a href="#{request.uri}">Reload</a></strong> this page.
|
55
|
+
Go to the <strong><a href="#{request.referer}">referer</a></strong> or the <strong><a href="/">home page</a></strong>.
|
56
|
+
</div>
|
57
|
+
<div class="source">
|
58
|
+
<?r
|
59
|
+
extract = error.source_extract.split("\n")
|
60
|
+
?>
|
61
|
+
In file <b>'#{error.hot_file}'</b> #{error.hot_file =~ /\.xhtml$/ ? '(line numbering is aproximate due to template transformation)' : nil}:
|
62
|
+
<br /><br />
|
63
|
+
<?r
|
64
|
+
extract.each_with_index do |line, idx|
|
65
|
+
line = sanitize(line)
|
66
|
+
if 5 == idx
|
67
|
+
?>
|
68
|
+
<div style="background: #eee">#{line}</div>
|
69
|
+
<?r else ?>
|
70
|
+
<div>#{line}</div>
|
71
|
+
<?r
|
72
|
+
end
|
73
|
+
end
|
74
|
+
?>
|
75
|
+
</div>
|
76
|
+
<h2><a href="#" onclick="return toggleVisible(document.getElementById('trace'));">Stack Trace</a></h2>
|
77
|
+
<div id="trace" style="display: none;">
|
78
|
+
<?r error.backtrace.zip(error.source_for_backtrace).each_with_index do |step,step_idx| ?>
|
79
|
+
<div><a href="#" onclick="return toggleVisible(document.getElementById('trace_#{step_idx}'));">#{sanitize(step.first)}</a></div>
|
80
|
+
<div class="source" id="trace_#{step_idx}" style="display: none;">
|
81
|
+
<?r
|
82
|
+
extract = step.last.split("\n")
|
83
|
+
extract.each_with_index do |line, idx|
|
84
|
+
line = sanitize(line)
|
85
|
+
if 5 == idx
|
86
|
+
?>
|
87
|
+
<div style="background: #eee">#{line}</div>
|
88
|
+
<?r else ?>
|
89
|
+
<div>#{line}</div>
|
90
|
+
<?r
|
91
|
+
end
|
92
|
+
end
|
93
|
+
?>
|
94
|
+
</div>
|
95
|
+
|
96
|
+
|
97
|
+
<?r end ?>
|
98
|
+
</div>
|
62
99
|
<?r end ?>
|
63
100
|
|
64
101
|
<h2><a href="#" onclick="document.getElementById('request').style.display = 'block'; return false">Request</a></h2>
|
data/proto/public/js/controls.js
CHANGED
@@ -152,6 +152,12 @@ Autocompleter.Base.prototype = {
|
|
152
152
|
setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
|
153
153
|
},
|
154
154
|
|
155
|
+
activate: function() {
|
156
|
+
this.changed = false;
|
157
|
+
this.hasFocus = true;
|
158
|
+
this.getUpdatedChoices();
|
159
|
+
},
|
160
|
+
|
155
161
|
onHover: function(event) {
|
156
162
|
var element = Event.findElement(event, 'LI');
|
157
163
|
if(this.index != element.autocompleteIndex)
|
@@ -477,9 +483,10 @@ Ajax.InPlaceEditor.prototype = {
|
|
477
483
|
formClassName: 'inplaceeditor-form',
|
478
484
|
highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor,
|
479
485
|
highlightendcolor: "#FFFFFF",
|
480
|
-
externalControl:
|
486
|
+
externalControl: null,
|
481
487
|
submitOnBlur: false,
|
482
|
-
ajaxOptions: {}
|
488
|
+
ajaxOptions: {},
|
489
|
+
evalScripts: false
|
483
490
|
}, options || {});
|
484
491
|
|
485
492
|
if(!this.options.formId && this.element.id) {
|
@@ -548,6 +555,7 @@ Ajax.InPlaceEditor.prototype = {
|
|
548
555
|
okButton = document.createElement("input");
|
549
556
|
okButton.type = "submit";
|
550
557
|
okButton.value = this.options.okText;
|
558
|
+
okButton.className = 'editor_ok_button';
|
551
559
|
this.form.appendChild(okButton);
|
552
560
|
}
|
553
561
|
|
@@ -556,6 +564,7 @@ Ajax.InPlaceEditor.prototype = {
|
|
556
564
|
cancelLink.href = "#";
|
557
565
|
cancelLink.appendChild(document.createTextNode(this.options.cancelText));
|
558
566
|
cancelLink.onclick = this.onclickCancel.bind(this);
|
567
|
+
cancelLink.className = 'editor_cancel';
|
559
568
|
this.form.appendChild(cancelLink);
|
560
569
|
}
|
561
570
|
},
|
@@ -584,6 +593,7 @@ Ajax.InPlaceEditor.prototype = {
|
|
584
593
|
textField.name = "value";
|
585
594
|
textField.value = text;
|
586
595
|
textField.style.backgroundColor = this.options.highlightcolor;
|
596
|
+
textField.className = 'editor_field';
|
587
597
|
var size = this.options.size || this.options.cols || 0;
|
588
598
|
if (size != 0) textField.size = size;
|
589
599
|
if (this.options.submitOnBlur)
|
@@ -597,6 +607,7 @@ Ajax.InPlaceEditor.prototype = {
|
|
597
607
|
textArea.value = this.convertHTMLLineBreaks(text);
|
598
608
|
textArea.rows = this.options.rows;
|
599
609
|
textArea.cols = this.options.cols || 40;
|
610
|
+
textArea.className = 'editor_field';
|
600
611
|
if (this.options.submitOnBlur)
|
601
612
|
textArea.onblur = this.onSubmit.bind(this);
|
602
613
|
this.editField = textArea;
|
@@ -649,19 +660,26 @@ Ajax.InPlaceEditor.prototype = {
|
|
649
660
|
// to be displayed indefinitely
|
650
661
|
this.onLoading();
|
651
662
|
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
663
|
+
if (this.options.evalScripts) {
|
664
|
+
new Ajax.Request(
|
665
|
+
this.url, Object.extend({
|
666
|
+
parameters: this.options.callback(form, value),
|
667
|
+
onComplete: this.onComplete.bind(this),
|
668
|
+
onFailure: this.onFailure.bind(this),
|
669
|
+
asynchronous:true,
|
670
|
+
evalScripts:true
|
671
|
+
}, this.options.ajaxOptions));
|
672
|
+
} else {
|
673
|
+
new Ajax.Updater(
|
674
|
+
{ success: this.element,
|
675
|
+
// don't update on failure (this could be an option)
|
676
|
+
failure: null },
|
677
|
+
this.url, Object.extend({
|
678
|
+
parameters: this.options.callback(form, value),
|
679
|
+
onComplete: this.onComplete.bind(this),
|
680
|
+
onFailure: this.onFailure.bind(this)
|
681
|
+
}, this.options.ajaxOptions));
|
682
|
+
}
|
665
683
|
// stop the event to avoid a page refresh in Safari
|
666
684
|
if (arguments.length > 1) {
|
667
685
|
Event.stop(arguments[0]);
|
@@ -743,6 +761,33 @@ Ajax.InPlaceEditor.prototype = {
|
|
743
761
|
}
|
744
762
|
};
|
745
763
|
|
764
|
+
Ajax.InPlaceCollectionEditor = Class.create();
|
765
|
+
Object.extend(Ajax.InPlaceCollectionEditor.prototype, Ajax.InPlaceEditor.prototype);
|
766
|
+
Object.extend(Ajax.InPlaceCollectionEditor.prototype, {
|
767
|
+
createEditField: function() {
|
768
|
+
if (!this.cached_selectTag) {
|
769
|
+
var selectTag = document.createElement("select");
|
770
|
+
var collection = this.options.collection || [];
|
771
|
+
var optionTag;
|
772
|
+
collection.each(function(e,i) {
|
773
|
+
optionTag = document.createElement("option");
|
774
|
+
optionTag.value = (e instanceof Array) ? e[0] : e;
|
775
|
+
if(this.options.value==optionTag.value) optionTag.selected = true;
|
776
|
+
optionTag.appendChild(document.createTextNode((e instanceof Array) ? e[1] : e));
|
777
|
+
selectTag.appendChild(optionTag);
|
778
|
+
}.bind(this));
|
779
|
+
this.cached_selectTag = selectTag;
|
780
|
+
}
|
781
|
+
|
782
|
+
this.editField = this.cached_selectTag;
|
783
|
+
if(this.options.loadTextURL) this.loadExternalText();
|
784
|
+
this.form.appendChild(this.editField);
|
785
|
+
this.options.callback = function(form, value) {
|
786
|
+
return "value=" + encodeURIComponent(value);
|
787
|
+
}
|
788
|
+
}
|
789
|
+
});
|
790
|
+
|
746
791
|
// Delayed observer, like Form.Element.Observer,
|
747
792
|
// but waits for delay after last key input
|
748
793
|
// Ideal for live-search fields
|