lib/opal/native.rb in opal-native-0.0.2 vs lib/opal/native.rb in opal-native-0.0.3
- old
+ new
@@ -6,117 +6,25 @@
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
#
# 0. You just DO WHAT THE FUCK YOU WANT TO.
#++
-class Module
- %x{
- function define_attr_bridge (klass, target, name, getter, setter) {
- if (getter) {
- $opal.defn(klass, $opal.mid_to_jsid(name), function() {
- var real = target;
-
- if (#{Symbol == `target`}) {
- real = target[0] == '@' ? this[target.substr(1)] : this[$opal.mid_to_jsid(target)].apply(this);
- }
-
- var result = real[name];
-
- return result == null ? nil : result;
- });
- }
-
- if (setter) {
- $opal.defn(klass, $opal.mid_to_jsid(name + '='), function (block, val) {
- var real = target;
-
- if (#{Symbol === `target`}) {
- real = target[0] == '@' ? this[target.substr(1)] : this[$opal.mid_to_jsid(target)].apply(this);
- }
-
- return real[name] = val;
- });
- }
- }
- }
-
- def attr_accessor_bridge (target, *attrs)
- %x{
- for (var i = 0, length = attrs.length; i < length; i++) {
- define_attr_bridge(this, target, attrs[i], true, true);
- }
- }
-
- self
+module Native
+ def self.=== (other)
+ `#{other} == null || !#{other}.o$klass`
end
- def attr_reader_bridge (target, *attrs)
- %x{
- for (var i = 0, length = attrs.length; i < length; i++) {
- define_attr_bridge(this, target, attrs[i], true, false);
- }
- }
+ def self.send (object, name, *args, &block)
+ args << block if block
- self
- end
-
- def attr_writer_bridge (target, *attrs)
- %x{
- for (var i = 0, length = attrs.length; i < length; i++) {
- define_attr_bridge(this, target, attrs[i], false, true);
- }
+ args = args.map {|obj|
+ Native === obj ? obj : obj.to_native
}
- self
+ Kernel.Native(`object[name].apply(object, args)`)
end
- def attr_bridge (target, name, setter = false)
- `define_attr_bridge(this, target, name, true, setter)`
-
- self
- end
-
- def define_method_bridge (object, name, ali = nil)
- %x{
- var self = this;
-
- $opal.defn(self, $opal.mid_to_jsid(#{ali || name}), function () {
- var real = object;
-
- if (#{Symbol === object}) {
- real = object[0] == '@' ? self[object.substr(1)] : self[$opal.mid_to_jsid(object)].apply(self);
- }
-
- return real[name].apply(real, arguments);
- });
- }
-
- nil
- end
-end
-
-module Kernel
- def define_singleton_method_bridge (object, name, ali = nil)
- %x{
- var self = this;
-
- $opal.defs(this, $opal.mid_to_jsid(#{ali || name}), function () {
- var real = object;
-
- if (#{Symbol === object}) {
- real = object[0] == '@' ? self[object.substr(1)] : self[$opal.mid_to_jsid(object)].apply(self);
- }
-
- return real[name].apply(real, arguments);
- });
- }
-
- nil
- end
-end
-
-module Native
def self.included (klass)
class << klass
def from_native (object)
instance = allocate
instance.instance_variable_set :@native, object
@@ -132,14 +40,16 @@
def to_native
@native
end
- def native_send (name, *args)
- return method_missing(name, *args) unless Opal.function? `#@native[name]`
+ def native_send (name, *args, &block)
+ unless Proc === `#@native[name]`
+ raise NoMethodError, "undefined method `#{name}` for #{`#@native.toString()`}"
+ end
- `#@native[name].apply(#@native, args)`
+ Native.send(@native, name, *args, &block)
end
alias __native_send__ native_send
end
@@ -151,44 +61,30 @@
super
update!
end
- def update! (name = nil)
- unless name
- %x{
- for (var name in #@native) {
- #{update!(`name`)}
- }
- }
+ def [] (name)
+ Kernel.Native(`#@native[name]`)
+ end
- return
- end
+ def []= (name, value)
+ value = value.to_native unless Native === value
- if Opal.function? `#@native[name]`
- define_singleton_method_bridge @native, name
+ `#@native[name] = #{value}`
- if respond_to? "#{name}="
- singleton_class.undef_method "#{name}="
- end
- else
- define_singleton_method name do
- self[name]
- end
+ update!(name)
- define_singleton_method "#{name}=" do |value|
- self[name] = value
- end
- end
+ value
end
def each
return enum_for :each unless block_given?
%x{
for (var name in #@native) {
- #{yield Kernel.Object(`name`), Kernel.Object(`#@native[name]`)}
+ #{yield Kernel.Native(`name`), Kernel.Native(`#@native[name]`)}
}
}
self
end
@@ -196,11 +92,11 @@
def each_key
return enum_for :each_key unless block_given?
%x{
for (var name in #@native) {
- #{yield Kernel.Object(`name`)}
+ #{yield Kernel.Native(`name`)}
}
}
self
end
@@ -208,49 +104,75 @@
def each_value
return enum_for :each_value unless block_given?
%x{
for (var name in #@native) {
- #{yield Kernel.Object(`#@native[name]`)}
+ #{yield Kernel.Native(`#@native[name]`)}
}
}
end
- def [] (name)
- Kernel.Object(`#@native[name] || nil`)
+ def inspect
+ "#<Native: #{`#@native.toString()`}>"
end
- def []= (name, value)
- value = value.to_native unless Opal.native?(value)
-
- `#@native[name] = #{value}`
-
- update!(name)
-
- value
+ def keys
+ each_key.to_a
end
def nil?
`#@native === null || #@native === undefined`
end
- def inspect
- "#<Native: #{`#@native.toString()`}>"
- end
-
def to_s
`#@native.toString()`
end
def to_hash
Hash[to_a]
end
+
+ def values
+ each_value.to_a
+ end
+
+ def update! (name = nil)
+ unless name
+ %x{
+ for (var name in #@native) {
+ #{update!(`name`)}
+ }
+ }
+
+ return
+ end
+
+ if Proc === `#@native[name]`
+ define_singleton_method name do |*args, &block|
+ __native_send__(name, *args, &block)
+ end
+
+ if respond_to? "#{name}="
+ singleton_class.undef_method "#{name}="
+ end
+ else
+ define_singleton_method name do
+ self[name]
+ end
+
+ define_singleton_method "#{name}=" do |value|
+ self[name] = value
+ end
+ end
+ end
end
module Kernel
- def Object (object)
- Opal.native?(object) ? Native::Object.new(object) : object
+ def Native (object)
+ return if `object == null`
+
+ Native === object ? Native::Object.new(object) : object
end
end
class Object
def to_native
@@ -264,11 +186,11 @@
end
end
class Array
def to_native
- map { |obj| Opal.object?(obj) ? obj.to_native : obj }
+ map { |obj| Native === obj ? obj : obj.to_native }
end
end
class Hash
def to_native
@@ -278,11 +200,11 @@
for (var assoc in map) {
var key = map[assoc][0],
value = map[assoc][1];
- result[key] = #{Opal.native?(`value`)} ? value : #{`value`.to_native};
+ result[key] = #{Native === `value` ? `value` : `value`.to_native};
}
return result;
}
end
@@ -308,11 +230,13 @@
def to_native
%x{
var self = this;
return (function () {
- return self.apply(self.$S, arguments);
+ return self.apply(self.$S, [null].concat(#{
+ `$slice.call(arguments)`.map { |o| Kernel.Native(o) }
+ }));
});
}
end
end
@@ -325,5 +249,7 @@
class String
def to_native
`this.valueOf()`
end
end
+
+require 'native/bridge'