js2 0.0.5 → 0.0.7

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