js2 0.0.5 → 0.0.7

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 CHANGED
@@ -1,3 +1,13 @@
1
+ == 0.0.7 2009-12-23
2
+ * Added Observable.js
3
+ * Added JS2.App Class
4
+ * Added JS2.App.JQuery Class
5
+ * Added yml support for templating classes for applications
6
+ * Added compiliations for applications
7
+
8
+ == 0.0.6 2009-12-08
9
+ * removing deprecated classes file
10
+
1
11
  == 0.0.5 2009-12-04
2
12
  * added bootstrap
3
13
 
data/Manifest.txt CHANGED
@@ -10,9 +10,8 @@ Rakefile
10
10
  examples/js2.yml
11
11
  examples/test.yml
12
12
  lib/javascript/sel_marker.js2
13
- lib/javascript/bootstrap.js
14
- lib/javascript/observer.js2
15
13
  lib/javascript/test.js2
14
+ lib/js2bootstrap.js2
16
15
  lib/js2.rb
17
16
  lib/js2/ast/class_node.rb
18
17
  lib/js2/ast/comment_node.rb
@@ -102,6 +102,16 @@ class JS2.SelMarker {
102
102
  this.normalized = true;
103
103
  }
104
104
 
105
+ function getRealClassScope (klass) {
106
+ if (klass.main && klass.main.factoryId) {
107
+ var namespace = klass.main._klass.replace(/\.\w+$/, '');
108
+ var classname = klass._klass.match(/\.\w+$/)[0];
109
+ return namespace + classname;
110
+ } else {
111
+ return klass._klass;
112
+ }
113
+ }
114
+
105
115
  private
106
116
 
107
117
  function normalizeVal (val) {
@@ -12,7 +12,7 @@ class JS2::Decorator::Cleanser
12
12
  # TODO foreach:key (var key in hash)
13
13
  #
14
14
  # SUPPORTED foreach (var item:i in items)
15
- if m = str.match(%r|foreach\s*(:([^\s]))?\s*\(\s*var\s+([^\s\:]+)\s*(:?([^\s]))?\s+in\s+([^\s]+)\s*\)|)
15
+ if m = str.match(%r|foreach\s*(:([^\s]))?\s*\(\s*var\s+([^\s\:]+)\s*(:?([^\s]+))?\s+in\s+([^\s]+)\s*\)|)
16
16
  type = m[2]
17
17
  decl = m[3]
18
18
  it = m[5] || ('it_' + (@@enum += 1).to_s)
@@ -14,14 +14,10 @@ class JS2::Decorator::Standard
14
14
  return str
15
15
  end
16
16
 
17
- def draw_bootstrap ()
18
- return File.read(File.dirname(__FILE__) + '/../../javascript/bootstrap.js')
19
- end
20
-
21
17
  private
22
18
 
23
19
  def draw_method (node)
24
- return %{ // #{node.filename}:#{node.line_number}
20
+ return %{
25
21
  #{node.name}:function #{node.text}}
26
22
  end
27
23
 
@@ -51,7 +47,7 @@ class JS2::Decorator::Standard
51
47
  return draw_comment(node)
52
48
  end
53
49
 
54
- return %{ // #{node.filename}:#{node.line_number}
50
+ return %{
55
51
  #{node.name}:#{node.text}}
56
52
  end
57
53
 
@@ -89,7 +85,7 @@ class JS2::Decorator::Standard
89
85
  end
90
86
 
91
87
  return <<-END
92
- // #{node.filename}:#{node.line_number}
88
+
93
89
  JS2.createClass("#{node.name}");
94
90
  #{node.name}.prototype={#{meta}
95
91
  #{member_js.join(",\n") }
@@ -115,7 +115,7 @@ class JS2::Decorator::Test < JS2::Decorator::Standard
115
115
  (@references[@scope] ||= {})[key] = comment
116
116
  scope =
117
117
  if @in_class
118
- "this._klass"
118
+ "TMP_SEL_MARKER.getRealClassScope(this)"
119
119
  else
120
120
  @scope.to_json
121
121
  end
@@ -4,6 +4,7 @@ class JS2::Process::FileHandler
4
4
  @write_dir = params[:write_dir]
5
5
  @haml_dir = params[:haml_dir]
6
6
  @view_dir = params[:view_dir]
7
+ @yml_dir = params[:read_dir]
7
8
 
8
9
  @mtimes = Hash.new
9
10
  end
@@ -13,10 +14,6 @@ class JS2::Process::FileHandler
13
14
  return @write_dir + '/classes.js'
14
15
  end
15
16
 
16
- def bootstrap_file
17
- return @write_dir + '/js2bootstrap.js'
18
- end
19
-
20
17
  def get_view_files
21
18
  return [] unless @view_dir
22
19
  return Dir.glob(@view_dir + '/**/*.haml')
@@ -27,56 +24,53 @@ class JS2::Process::FileHandler
27
24
  return Dir.glob(@haml_dir + '/**/*/*.js2.haml') + Dir.glob(@haml_dir + '/*.js2.haml')
28
25
  end
29
26
 
27
+ def get_yml_files
28
+ return [] unless @haml_dir
29
+ return Dir.glob(@haml_dir + '/**/*/*.js2.yml') + Dir.glob(@haml_dir + '/*.js2.yml')
30
+ end
31
+
30
32
  def get_files
31
- return Dir.glob(@read_dir + '/**/*/*.js2') + Dir.glob(@read_dir + '/*.js2')
33
+ return Dir.glob(@read_dir + '/**/*/*.js2') + Dir.glob(@read_dir + '/*.js2')
32
34
  end
33
35
 
34
36
  def write_file (filename, str)
35
- to_write = filename.sub(/^#{@read_dir}/, @write_dir).sub(/\.js2$/, '.js')
37
+ to_write = nil
38
+
39
+ # hack just for bootstrap so that its written in the root dir
40
+ if filename.match(/js2bootstrap.js2$/)
41
+ to_write = @write_dir + '/js2bootstrap.js'
42
+ else
43
+ to_write = filename.sub(/^#{@read_dir}/, @write_dir).sub(/\.js2$/, '.js')
44
+ end
45
+
36
46
  FileUtils.mkpath(File.dirname(to_write))
37
47
  File.open(to_write, 'w') do |f|
38
48
  f << str
39
49
  end
40
50
  end
41
51
 
42
- def write_class_file (str)
43
- FileUtils.mkpath(File.dirname(class_file))
44
- File.open(class_file, 'w') do |f|
45
- f << "alert('classes.js is deprecated, please include js2bootstrap.js instead.');"
46
- f << str
52
+ def write_compilation (filename, compilation)
53
+ to_write = filename.sub(/^#{@read_dir}/, @write_dir).sub(/\.js2$/, '.comp.js')
54
+ str = ""
55
+
56
+ compilation.each do |f|
57
+ read_file = f.sub(/^#{@read_dir}/, @write_dir).sub(/\.js2$/, '.js')
58
+ str << File.read(read_file) + "\n"
47
59
  end
48
- end
49
60
 
50
- def write_bootstrap_file (str)
51
- FileUtils.mkpath(File.dirname(bootstrap_file))
52
- File.open(bootstrap_file, 'w') do |f|
61
+ FileUtils.mkpath(File.dirname(to_write))
62
+ File.open(to_write, 'w') do |f|
53
63
  f << str
54
64
  end
55
65
  end
56
66
 
57
-
58
67
  def need_update!
59
68
  ret = false
60
69
  did = Hash.new
61
- self.get_files.each do |file|
62
- mtime = File.mtime(file)
63
- if @mtimes[file] != mtime
64
- @mtimes[file] = mtime
65
- ret = true
66
- end
67
- did[file] = mtime
68
- end
69
70
 
70
- self.get_haml_files.each do |file|
71
- mtime = File.mtime(file)
72
- if @mtimes[file] != mtime
73
- @mtimes[file] = mtime
74
- ret = true
75
- end
76
- did[file] = mtime
77
- end
71
+ files = self.get_files + self.get_haml_files + self.get_yml_files
78
72
 
79
- self.get_view_files.each do |file|
73
+ files.each do |file|
80
74
  mtime = File.mtime(file)
81
75
  if @mtimes[file] != mtime
82
76
  @mtimes[file] = mtime
@@ -1,9 +1,13 @@
1
1
  class JS2::Process::Universe
2
+ attr_accessor :compilations
3
+
2
4
  def initialize
3
5
  @class_lookup = Hash.new
4
6
  @haml_lookup = Hash.new
5
7
  @node_containers = Array.new
6
8
  @mod_lookup = Hash.new
9
+
10
+ @compilations = Hash.new
7
11
  end
8
12
 
9
13
  def add_nodes (nodes)
@@ -18,6 +22,34 @@ class JS2::Process::Universe
18
22
  @node_containers << nodes
19
23
  end
20
24
 
25
+ def add_yml (yml, filename)
26
+ yml.each_pair do |klass_name, config|
27
+ template = config['template']
28
+ next unless template
29
+
30
+ str = " function getTemplate () { return #{template.to_json} }"
31
+ node = JS2::AST::MethodNode.new(filename, 0, str)
32
+ k = @class_lookup[klass_name]
33
+ k.members << node
34
+ k.mem_hash['getTemplate'] = node
35
+
36
+ if config['make_compilation']
37
+ compilation = [ k.filename ]
38
+
39
+ if config['include']
40
+ compilation += config['include'].collect { |name| @class_lookup[name].filename }
41
+ end
42
+
43
+ template.each do |t|
44
+ klass_name = t['class']
45
+ klass = @class_lookup[klass_name]
46
+ compilation << klass.filename
47
+ end
48
+ @compilations[k.filename] = compilation
49
+ end
50
+ end
51
+ end
52
+
21
53
  def node_containers
22
54
  return @node_containers
23
55
  end
data/lib/js2/processor.rb CHANGED
@@ -106,19 +106,31 @@ class JS2::Processor
106
106
  end
107
107
 
108
108
  def write_files
109
- universe = JS2::Process::Universe.new()
110
-
111
109
  parser ||= JS2::Parser::Fast.new()
112
110
  haml_parser ||= JS2::Parser::Haml.new(@haml_engine)
113
111
  universe = JS2::Process::Universe.new
114
112
 
115
113
  decorator = @decorator_klass.new
116
114
 
115
+ bootstrap_file = File.dirname(__FILE__) + "/../js2bootstrap.js2"
116
+ bootstrap_nodes = parser.parse(bootstrap_file)
117
+ universe.add_nodes(bootstrap_nodes)
118
+
117
119
  @fh.get_files.each do |filename|
118
120
  nodes = parser.parse(filename)
119
121
  universe.add_nodes(nodes)
120
122
  end
121
123
 
124
+ @fh.get_yml_files.each do |filename|
125
+ begin
126
+ yml = YAML.load_file(filename)
127
+ universe.add_yml(yml, filename)
128
+ rescue Exception => e
129
+ puts "YAML Error in #{filename}:"
130
+ puts e.to_s
131
+ end
132
+ end
133
+
122
134
  @fh.get_haml_files.each do |filename|
123
135
  hash = haml_parser.parse(filename)
124
136
  universe.add_haml_hash(hash)
@@ -131,11 +143,6 @@ class JS2::Processor
131
143
  @fh.write_file(nc.filename, str)
132
144
  end
133
145
 
134
- str = decorator.draw_bootstrap()
135
-
136
- @fh.write_class_file(str)
137
- @fh.write_bootstrap_file(str)
138
-
139
146
  if @test_mode
140
147
  decorator.write_references(@reference_dir)
141
148
  end
@@ -147,6 +154,10 @@ class JS2::Processor
147
154
  decorator.draw_nodes(nodes)
148
155
  decorator.write_references(@reference_dir)
149
156
  end
157
+
158
+ universe.compilations.each_pair do |filename, hash|
159
+ @fh.write_compilation(filename, hash)
160
+ end
150
161
  end
151
162
 
152
163
  end
@@ -27,11 +27,10 @@ class JS2::Test::Selenium < Selenium::Client::Driver
27
27
 
28
28
  reference_dir = config['reference_dir'] || './spec/js2refs'
29
29
  config = config['selenium']
30
-
31
30
  ret = self.new( :host => config['host'] || 'localhost',
32
31
  :port => config['port'] || 4444,
33
32
  :browser => config['browser'] || '*firefox',
34
- :url => config['url'] || 'http://google.com',
33
+ :url => config['url'] || 'http://www.factual.com',
35
34
 
36
35
  :timeout_in_second => config[:timeout] || 60,
37
36
  :highlight_located_element => config['highlight'] || false,
@@ -40,7 +39,6 @@ class JS2::Test::Selenium < Selenium::Client::Driver
40
39
  # hack to get an instance var in.
41
40
  ret.reference_dir = reference_dir
42
41
  ret.child_selector = nil
43
-
44
42
  return ret
45
43
  end
46
44
  end
@@ -150,6 +150,10 @@ class JS2::Test::SeleniumElement
150
150
  @sel.mouse_out(get_ele())
151
151
  end
152
152
 
153
+ def key_down(value)
154
+ @sel.key_down(get_ele(), value)
155
+ end
156
+
153
157
  def type (*params)
154
158
  elem = get_ele()
155
159
  @sel.type(elem, *params)
data/lib/js2.rb CHANGED
@@ -2,7 +2,7 @@ $:.unshift(File.dirname(__FILE__)) unless
2
2
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
3
 
4
4
  module Js2
5
- VERSION = '0.0.5'
5
+ VERSION = '0.0.7'
6
6
  end
7
7
 
8
8
  module JS2
@@ -0,0 +1,274 @@
1
+ var JS2 = {};
2
+ JS2.createClass = function (name) {
3
+ var splitName = name.split('.');
4
+ var namespace = window;
5
+ while (splitName.length) {
6
+ var subName = splitName.shift();
7
+ if (! namespace[subName]) {
8
+ namespace =
9
+ namespace[subName] =
10
+ function () { if (this.initialize) this.initialize.apply(this, arguments) };
11
+ } else {
12
+ namespace = namespace[subName];
13
+ }
14
+ }
15
+ }
16
+
17
+ JS2.getClass = function (name) {
18
+ var splitName = name.split('.');
19
+ var namespace = window;
20
+
21
+ while (splitName.length) {
22
+ var subName = splitName.shift();
23
+ if (namespace[subName]) {
24
+ namespace = namespace[subName];
25
+ } else {
26
+ return null;
27
+ }
28
+ }
29
+
30
+ return namespace;
31
+ }
32
+
33
+ function _super () {
34
+ var method = arguments.callee.caller._super;
35
+ if (! method) return;
36
+ var self = arguments[0];
37
+ var args = [];
38
+ for (var i=1,len=arguments.length;i<len;i++) {
39
+ args.push(arguments[i]);
40
+ }
41
+ return method.apply(self, args);
42
+ }
43
+
44
+
45
+ class JS2.Observer {
46
+ function initialize (owner) {
47
+ this.lookupBefore = {};
48
+ this.lookupAfter = {};
49
+
50
+ this.replaced = {};
51
+ this.replacedValues = {};
52
+ }
53
+
54
+ function replaceFunction (owner, eventName) {
55
+ if (this.replaced[eventName]) return;
56
+
57
+ this.replacedValues[eventName] = owner[eventName];
58
+ this.replaced[eventName] = true;
59
+ owner[eventName] = this.getTrigger(eventName);
60
+ }
61
+
62
+ function trigger (owner, eventName, args) {
63
+ var beforeChain = this.lookupBefore[eventName];
64
+ if (beforeChain) this.executeChain(beforeChain, args);
65
+
66
+ var funct = this.replacedValues[eventName];
67
+ if (funct) funct.apply(owner, args);
68
+
69
+ var afterChain = this.lookupAfter[eventName];
70
+ if (afterChain) this.executeChain(afterChain, args);
71
+ }
72
+
73
+ function addListener (eventName, funct, before) {
74
+ var lookup = before ? this.lookupBefore : this.lookupAfter;
75
+
76
+ var chain = lookup[eventName] = lookup[eventName] || [];
77
+ chain.push(funct);
78
+ }
79
+
80
+ private
81
+
82
+ function getTrigger (eventName) {
83
+ return function () { this.__observer.trigger(this, eventName, arguments); };
84
+ }
85
+
86
+ function executeChain (chain, args) {
87
+ foreach (var f:i in chain) if (f) f.apply(this, args);
88
+ }
89
+ }
90
+
91
+ module JS2.Observable {
92
+ function addListener (eventName, funct, before) {
93
+ if (! this.__observer) this.__observer = new Factual.Core.Observer();
94
+
95
+ var id = this.__observer.addListener(eventName, funct, before);
96
+ this.__observer.replaceFunction(this, eventName);
97
+ return id;
98
+ }
99
+
100
+ function triggerEvent (eventName, args) {
101
+ if (this.__observer) this.__observer.trigger(this, eventName, args);
102
+ }
103
+ }
104
+
105
+
106
+ class JS2.App.Notifier {
107
+ var autoInc = 1;
108
+
109
+ function initialize () {
110
+ this.chains = {};
111
+ this.autoInc = 1;
112
+ this.id = this['class'].prototype.autoInc;
113
+ this['class'].prototype.autoInc++;
114
+ }
115
+
116
+ function register (comp) {
117
+ if (! comp.__notifier_ids) {
118
+ comp.__notifier_ids = {};
119
+ }
120
+
121
+ if (! comp.__notifier_ids[this.id]) {
122
+ comp.__notifier_ids[this.id] = this.autoInc;
123
+ this.autoInc++;
124
+ }
125
+
126
+ for (var key in comp) {
127
+ if (key.indexOf('e_') == 0) {
128
+ var eventType = key.substr(2);
129
+ if (! this.chains[eventType]) this.chains[eventType] = [];
130
+ this.chains[eventType].push([ comp, comp[key] ]);
131
+ }
132
+ }
133
+
134
+ comp.notify = curry with (this) {
135
+ self.notify.apply(self, arguments);
136
+ };
137
+ }
138
+
139
+ function remove (comp) {
140
+ var id = comp.__notifier_id;
141
+ for (var key in this.chains) {
142
+ var newChain = [];
143
+ foreach (var ele:j in chain) {
144
+ if (ele[0].__notifier_id[this.id] != id) {
145
+ newChain.push(ele);
146
+ }
147
+ }
148
+
149
+ this.chains[key] = newChain;
150
+ }
151
+ }
152
+
153
+ function registerListener (listener) {
154
+ for (var key in listener) {
155
+ var funct = listener[key];
156
+ if (typeof funct != 'function') continue;
157
+ if (! this.chains[key]) this.chains[key] = [];
158
+ this.chains[key].push([ listener, funct ]);
159
+ }
160
+ }
161
+
162
+ function notify () {
163
+ var eventType = arguments[0];
164
+ var args;
165
+
166
+ // optimize for 1 argument
167
+ if (arguments.length == 2) {
168
+ args = [ arguments[1] ];
169
+ } else {
170
+ args = [];
171
+ for (var i=1; i<=arguments.length; i++) args.push(arguments[i]);
172
+ }
173
+
174
+ var chain = this.chains[eventType];
175
+ if (chain) {
176
+ for (var i=0,pair; pair=chain[i++];) {
177
+ pair[1].apply(pair[0], args);
178
+ }
179
+ }
180
+ }
181
+ }
182
+
183
+
184
+
185
+ class JS2.App {
186
+ include JS2.Observer;
187
+
188
+ function start () {
189
+ // hack to get notifier
190
+ this.getNotifier();
191
+
192
+ this.build();
193
+ this.notify('initHTML');
194
+ this.notify('registerEvents');
195
+ this.notify('finalize');
196
+ }
197
+
198
+
199
+ function register (comp) {
200
+ this.getNotifier().register(comp);
201
+ }
202
+
203
+ function getNotifier () {
204
+ if (! this._notifier) {
205
+ this._notifier = new JS2.App.Notifier();
206
+ this._notifier.register(this);
207
+ }
208
+
209
+ return this._notifier;
210
+ }
211
+
212
+ function build () {
213
+ var components = {};
214
+ var template = this.getTemplate();
215
+
216
+ // instantiate all components
217
+ foreach (var config:i in template) {
218
+ if (!config['class']) alert("Invalid class defined for " + name + ':' + config['class']);
219
+ var klass = JS2.getClass(config['class']);
220
+
221
+ components[config.name] = new klass();
222
+ this.register(components[config.name]);
223
+ }
224
+
225
+ foreach (var config:i in template) {
226
+ var name = config.name;
227
+ var comp = components[name];
228
+
229
+ // inject set dependencies as an array
230
+ if (config.dependencies instanceof Array) {
231
+ foreach (var dep:j in config.dependencies) {
232
+ comp[dep] = components[dep];
233
+ }
234
+ }
235
+
236
+ // as a hash... for use when nickname is not the dependency name
237
+ else if (config.dependencies instanceof Object) {
238
+ for (var key in config.dependencies) {
239
+ comp[key] = components[config.dependencies[key]];
240
+ }
241
+ }
242
+ }
243
+
244
+ this.notify('initBaseHTML');
245
+
246
+ // handle selectors as root elements
247
+ foreach (var config:i in template) {
248
+ var name = config.name;
249
+ var comp = components[name];
250
+
251
+ if (config.selector) comp.$root = this.htmlSelect(this.$root, config.selector);
252
+ if (config.globalSelector) comp.$root = this.htmlSelect(config.globalSelector);
253
+ }
254
+ }
255
+
256
+ function htmlSelect (root, text) {
257
+ alert('html selector not implemented');
258
+ }
259
+
260
+ function getTemplate () {
261
+ return {};
262
+ }
263
+ }
264
+
265
+ class JS2.App.JQuery extends JS2.App {
266
+ function htmlSelect ($root, text) {
267
+ if (text) {
268
+ return $root.find(text);
269
+ } else {
270
+ return $(root);
271
+ }
272
+ }
273
+ }
274
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: js2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Su
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-04 00:00:00 -08:00
12
+ date: 2009-12-23 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -68,9 +68,8 @@ files:
68
68
  - examples/js2.yml
69
69
  - examples/test.yml
70
70
  - lib/javascript/sel_marker.js2
71
- - lib/javascript/bootstrap.js
72
- - lib/javascript/observer.js2
73
71
  - lib/javascript/test.js2
72
+ - lib/js2bootstrap.js2
74
73
  - lib/js2.rb
75
74
  - lib/js2/ast/class_node.rb
76
75
  - lib/js2/ast/comment_node.rb
@@ -1,42 +0,0 @@
1
- var JS2 = {};
2
- JS2.createClass = function (name) {
3
- var splitName = name.split('.');
4
- var namespace = window;
5
- while (splitName.length) {
6
- var subName = splitName.shift();
7
- if (! namespace[subName]) {
8
- namespace =
9
- namespace[subName] =
10
- function () { if (this.initialize) this.initialize.apply(this, arguments) };
11
- } else {
12
- namespace = namespace[subName];
13
- }
14
- }
15
- }
16
-
17
- JS2.getClass = function (name) {
18
- var splitName = name.split('.');
19
- var namespace = window;
20
-
21
- while (splitName.length) {
22
- var subName = splitName.shift();
23
- if (namespace[subName]) {
24
- namespace = namespace[subName];
25
- } else {
26
- return null;
27
- }
28
- }
29
-
30
- return namespace;
31
- }
32
-
33
- function _super () {
34
- var method = arguments.callee.caller._super;
35
- if (! method) return;
36
- var self = arguments[0];
37
- var args = [];
38
- for (var i=1,len=arguments.length;i<len;i++) {
39
- args.push(arguments[i]);
40
- }
41
- return method.apply(self, args);
42
- }
@@ -1,59 +0,0 @@
1
- class JS2.Observer {
2
- function initialize (owner) {
3
- this.lookupBefore = {};
4
- this.lookupAfter = {};
5
-
6
- this.replaced = {};
7
- this.replacedValues = {};
8
- }
9
-
10
- function replaceFunction (owner, eventName) {
11
- if (this.replaced[eventName]) return;
12
-
13
- this.replacedValues[eventName] = owner[eventName];
14
- this.replaced[eventName] = true;
15
- owner[eventName] = this.getTrigger(eventName);
16
- }
17
-
18
- function trigger (owner, eventName, args) {
19
- var beforeChain = this.lookupBefore[eventName];
20
- if (beforeChain) this.executeChain(beforeChain, args);
21
-
22
- var funct = this.replacedValues[eventName];
23
- if (funct) funct.apply(owner, args);
24
-
25
- var afterChain = this.lookupAfter[eventName];
26
- if (afterChain) this.executeChain(afterChain, args);
27
- }
28
-
29
- function addListener (eventName, funct, before) {
30
- var lookup = before ? this.lookupBefore : this.lookupAfter;
31
-
32
- var chain = lookup[eventName] = lookup[eventName] || [];
33
- chain.push(funct);
34
- }
35
-
36
- private
37
-
38
- function getTrigger (eventName) {
39
- return function () { this.__observer.trigger(this, eventName, arguments); };
40
- }
41
-
42
- function executeChain (chain, args) {
43
- foreach (var f:i in chain) if (f) f.apply(this, args);
44
- }
45
- }
46
-
47
- module JS2.Observable {
48
- function addListener (eventName, funct, before) {
49
- if (! this.__observer) this.__observer = new Factual.Core.Observer();
50
-
51
- var id = this.__observer.addListener(eventName, funct, before);
52
- this.__observer.replaceFunction(this, eventName);
53
- return id;
54
- }
55
-
56
- function triggerEvent (eventName, args) {
57
- if (this.__observer) this.__observer.trigger(this, eventName, args);
58
- }
59
- }