h8 0.5.2 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c147d817635f52206f230a99f941ededb8bd21f5
4
- data.tar.gz: d771197accf297eab3aa8e9044c13ff410321a46
3
+ metadata.gz: 866cc21525fd34d68526f69d2439e6c92b851eb7
4
+ data.tar.gz: 15517b88b2bf5cc132e57f6313b923f03c71ae14
5
5
  SHA512:
6
- metadata.gz: 48336caaf28e4ed9eccd01585ae265a90b5f1de45ec27aa5b7901809aaee1856c7c5557cb2467cbc46a5e53c9d9c290fd894485b7264046c8e6aa6bc0f31d84e
7
- data.tar.gz: 23c4e7500daa48e91dbf043d7b293441c1a7bc054d451fded0b51d4a93579d7cab1822a551fbfc6a1497ad2d527552c5e87c2d30e69bc1996432adab4fc9e874
6
+ metadata.gz: 7e4bf6c5081483747ab4bf13bc4869701d6bb96831bec5b7e7419ba340fce4be8d038ae76f7b6c4e5da9152be8a48aa54f4600a6dad94495e74f3f65a430bc0a
7
+ data.tar.gz: bedab9933c97710834681624d5d97ffd571d986e61f4e8ad7cd3f41cd21bc91e99b05f8a364385949a9b4de40ab4464d864318d67796f8d2af54c2b77ab6b661
@@ -64,8 +64,8 @@ void h8::JsTimeoutError::raise() const {
64
64
  void h8::H8::SetupGateTemplate(const Local<ObjectTemplate>& templ) {
65
65
  templ->SetInternalFieldCount(2);
66
66
  templ->SetCallAsFunctionHandler(&RubyGate::ObjectCallback);
67
- templ->SetNamedPropertyHandler(RubyGate::mapGet, RubyGate::mapSet, 0, RubyGate::mapDelete);
68
- templ->SetIndexedPropertyHandler(RubyGate::indexGet, RubyGate::indexSet);
67
+ templ->SetIndexedPropertyHandler(RubyGate::indexGet, RubyGate::indexSet,0,0,RubyGate::indexEnumerate);
68
+ templ->SetNamedPropertyHandler(RubyGate::mapGet, RubyGate::mapSet, RubyGate::mapQuery, RubyGate::mapDelete, RubyGate::mapEnumerate);
69
69
  // templ->SetAccessor(String::NewFromUtf8(isolate, "prototype"),
70
70
  // prototype_cb);
71
71
  }
@@ -76,7 +76,7 @@ h8::RubyGate::RubyGate(H8* _context, Handle<Object> instance, VALUE object) :
76
76
  void h8::RubyGate::mapGet(Local<String> name,
77
77
  const PropertyCallbackInfo<Value> &info) {
78
78
  v8::String::Utf8Value val(name);
79
- if( strcmp(*val, "prototype") == 0 ) {
79
+ if (strcmp(*val, "prototype") == 0) {
80
80
  info.GetReturnValue().Set(info.This()->GetPrototype());
81
81
  return;
82
82
  }
@@ -105,6 +105,19 @@ void h8::RubyGate::mapDelete(Local<String> name,
105
105
  rg->deleteProperty(name, info);
106
106
  }
107
107
 
108
+ void h8::RubyGate::mapQuery(Local<String> name,
109
+ const PropertyCallbackInfo<Integer>& info) {
110
+ RubyGate *rg = RubyGate::unwrap(info.This());
111
+ assert(rg != 0);
112
+ rg->queryProperty(name, info);
113
+ }
114
+
115
+ void h8::RubyGate::mapEnumerate(const PropertyCallbackInfo<Array> &info) {
116
+ RubyGate *rg = RubyGate::unwrap(info.This());
117
+ assert(rg != 0);
118
+ rg->enumerateProperties(info);
119
+ }
120
+
108
121
  void h8::RubyGate::indexGet(uint32_t index,
109
122
  const PropertyCallbackInfo<Value> &info) {
110
123
  RubyGate *rg = RubyGate::unwrap(info.This());
@@ -119,6 +132,12 @@ void h8::RubyGate::indexSet(uint32_t index, Local<Value> value,
119
132
  rg->setIndex(index, value, info);
120
133
  }
121
134
 
135
+ void h8::RubyGate::indexEnumerate(const PropertyCallbackInfo<Array>& info) {
136
+ RubyGate *rg = RubyGate::unwrap(info.This());
137
+ assert(rg != 0);
138
+ rg->enumerateProperties(info);
139
+ }
140
+
122
141
  void h8::RubyGate::ObjectCallback(
123
142
  const v8::FunctionCallbackInfo<v8::Value>& args) {
124
143
  v8::HandleScope scope(args.GetIsolate());
@@ -250,6 +269,40 @@ void h8::RubyGate::deleteProperty(Local<String> name,
250
269
  });
251
270
  }
252
271
 
272
+ void h8::RubyGate::enumerateProperties(
273
+ const PropertyCallbackInfo<Array>& info) {
274
+ with_gvl(this,
275
+ [&] {
276
+ VALUE rb_args = rb_ary_new2(2);
277
+ rb_ary_push(rb_args, ruby_object);
278
+ rb_ary_push(rb_args, rb_str_new2("__js_enumerate"));
279
+ rescued_call(rb_args, secure_call, [&] (VALUE res) {
280
+ int len = (int) RARRAY_LEN(res);
281
+ v8::Handle<Array> a = v8::Array::New(context->getIsolate(), len);
282
+ for(int i=0; i<len; i++) {
283
+ a->Set(i, context->to_js(rb_ary_entry(res, i)));
284
+ }
285
+ info.GetReturnValue().Set(a);
286
+ });
287
+ });
288
+ }
289
+
290
+ void h8::RubyGate::queryProperty(Local<String> name,
291
+ const PropertyCallbackInfo<Integer>& info) {
292
+ with_gvl(this,
293
+ [&] {
294
+ VALUE rb_args = rb_ary_new2(2);
295
+ rb_ary_push(rb_args, context->to_ruby(name));
296
+ rb_ary_push(rb_args, ruby_object);
297
+ rb_ary_push(rb_args, rb_str_new2("!__js_has_property"));
298
+ rescued_call(rb_args, secure_call, [&] (VALUE res) {
299
+ if( res != Qnil && res != Qfalse) {
300
+ info.GetReturnValue().Set(Integer::New(context->getIsolate(), v8::None));
301
+ }
302
+ });
303
+ });
304
+ }
305
+
253
306
  void h8::RubyGate::getIndex(uint32_t index,
254
307
  const PropertyCallbackInfo<Value> &info) {
255
308
  with_gvl(this, [&] {
@@ -117,10 +117,14 @@ protected:
117
117
  const PropertyCallbackInfo<Value> &info);
118
118
  void setProperty(Local<String> name, Local<Value> value,
119
119
  const PropertyCallbackInfo<Value> &info);
120
+ void queryProperty(Local<String> name,
121
+ const PropertyCallbackInfo<Integer> &info);
120
122
 
121
123
  void deleteProperty(Local<String> name,
122
124
  const PropertyCallbackInfo<Boolean> &info);
123
125
 
126
+ void enumerateProperties(const PropertyCallbackInfo<Array>& info);
127
+
124
128
  void getIndex(uint32_t index, const PropertyCallbackInfo<Value> &info);
125
129
  void setIndex(uint32_t index, Local<Value> value,
126
130
  const PropertyCallbackInfo<Value> &info);
@@ -138,13 +142,17 @@ private:
138
142
  const PropertyCallbackInfo<Value> &info);
139
143
  static void mapSet(Local<String> name, Local<Value> value,
140
144
  const PropertyCallbackInfo<Value> &info);
145
+ static void mapQuery(Local<String> name,
146
+ const PropertyCallbackInfo<Integer> &info);
141
147
  static void mapDelete(Local<String> name,
142
148
  const PropertyCallbackInfo<Boolean> &info);
149
+ static void mapEnumerate(const PropertyCallbackInfo<Array>& info);
143
150
 
144
151
  static void indexGet(uint32_t index,
145
152
  const PropertyCallbackInfo<Value> &info);
146
153
  static void indexSet(uint32_t index, Local<Value> value,
147
154
  const PropertyCallbackInfo<Value> &info);
155
+ static void indexEnumerate(const PropertyCallbackInfo<Array>& info);
148
156
 
149
157
  void throw_js();
150
158
 
@@ -1,6 +1,8 @@
1
1
  require 'thread'
2
2
  require 'h8'
3
3
  require 'json'
4
+ require 'ostruct'
5
+ require 'hashie'
4
6
 
5
7
  class Array
6
8
  def _select_js callable
@@ -12,6 +14,12 @@ class Array
12
14
  def indexOf item
13
15
  index(item) || -1
14
16
  end
17
+
18
+ def splice(start, len, *replace)
19
+ ret = self[start, len]
20
+ self[start, len] = replace
21
+ ret
22
+ end
15
23
  end
16
24
 
17
25
  class String
@@ -20,10 +28,46 @@ class String
20
28
  end
21
29
  end
22
30
 
31
+ class OpenStruct
32
+
33
+ def __to_json
34
+ JSON.unparse to_h
35
+ end
36
+
37
+ def __js_enumerate
38
+ to_h.keys.map(&:to_s)
39
+ end
40
+
41
+ end
42
+
43
+ def Hashie::Mash
44
+ def __to_json
45
+ JSON.unparse self
46
+ end
47
+
48
+ def __js_enumerate
49
+ to_h.keys.map(&:to_s)
50
+ end
51
+
52
+ end
53
+
23
54
  class Object
24
55
  def __to_json
25
56
  JSON.unparse self
26
57
  end
58
+
59
+ def __js_has_property name
60
+ __js_enumerate.include?(name)
61
+ end
62
+
63
+ def __js_enumerate
64
+ if respond_to?(:keys)
65
+ self.keys.map(&:to_s)
66
+ else
67
+ []
68
+ end
69
+ end
70
+
27
71
  end
28
72
 
29
73
  module H8
@@ -102,12 +146,18 @@ module H8
102
146
  if instance.is_a?(Array)
103
147
  method == 'select' and method = '_select_js'
104
148
  end
149
+ immediate_call = if method[0] == '!'
150
+ method = method[1..-1]
151
+ true
152
+ else
153
+ false
154
+ end
105
155
  method = method.to_sym
106
156
  begin
107
157
  m = instance.public_method(method)
108
158
  owner = m.owner
109
159
  if can_access?(owner)
110
- return m.call(*args) if method[0] == '[' || method[-1] == '='
160
+ return m.call(*args) if method[0] == '[' || method[-1] == '=' || immediate_call
111
161
  if m.arity != 0
112
162
  return ProcGate.new( -> (*args) { m.call *args } )
113
163
  else
@@ -111,6 +111,10 @@ module H8
111
111
  each.reduce({}) { |all, kv| all[kv[0]] = kv[1].to_ruby depth; all }
112
112
  end
113
113
 
114
+ def to_json *params
115
+ __rb_to_js
116
+ end
117
+
114
118
  # Iterate over javascript object keys
115
119
  def each_key
116
120
  keys.each
@@ -1,3 +1,3 @@
1
1
  module H8
2
- VERSION = "0.5.2"
2
+ VERSION = "0.5.4"
3
3
  end
@@ -5,3 +5,6 @@
5
5
 
6
6
  RubyGate.prototype.toJSON = ->
7
7
  JSON.parse @__to_json
8
+
9
+ Object.prototype.__rb_to_js = ->
10
+ JSON.stringify @
@@ -394,16 +394,64 @@ describe 'ruby gate' do
394
394
  end
395
395
  end
396
396
 
397
+ it 'should enumerate hashes' do
398
+ begin
399
+ cxt = H8::Context.new
400
+ src = cxt[:h] = { "the" => "test", "value" => 121 }
401
+ res = cxt.coffee <<-End
402
+ res = {}
403
+ for own k,v of h
404
+ res[k] = v
405
+ return res
406
+ End
407
+ res.should == src
408
+ src1 = cxt[:h] = OpenStruct.new
409
+ src1.the = "test"
410
+ src1.value = 121
411
+ res = cxt.coffee <<-End
412
+ res = {}
413
+ for own k,v of h
414
+ res[k] = v
415
+ return res
416
+ End
417
+ res.should == src
418
+ cxt = H8::Context.new
419
+ src = cxt[:h] = Hashie::Mash.new "the" => "test", "value" => 121
420
+ res = cxt.coffee <<-End
421
+ res = {}
422
+ for own k,v of h
423
+ res[k] = v
424
+ return res
425
+ End
426
+ res.should == src
427
+ rescue H8::NestedError => e
428
+ puts e.ruby_error.backtrace.join("\n")
429
+ raise
430
+ end
431
+ end
432
+
433
+
397
434
  it 'should process to_json' do
398
435
  begin
399
436
  cxt = H8::Context.new
400
- src = cxt[:h] = { 'hello' => { 'my' => 'world', 'arr' => [1,2,'tre'] } }
437
+ src = cxt[:h] = { 'hello' => { 'my' => 'world', 'arr' => [1, 2, 'tre'] } }
401
438
  JSON[cxt.eval("JSON.stringify(h)")].should == src
439
+ src = cxt[:h] = [-1, -2, { 'hello' => { 'my' => 'world', 'arr' => [1, 2, 'tre'] } }]
440
+ JSON[cxt.eval("JSON.stringify(h)")].should == src
441
+
442
+ src = cxt[:h] = { 'one' => cxt.eval("[ 'hello', { wor: 'ld'} ]") }
443
+ JSON[cxt.eval("JSON.stringify(h)")].should == src
444
+
445
+ src = cxt[:h] = Hashie::Mash.new
446
+ res = cxt.coffee <<-End
447
+ h.arr = (c*10 for c in [-1, +1]);
448
+ return JSON.stringify(h)
449
+ End
450
+ res.should == "{\"arr\":[-10,10]}"
402
451
  rescue H8::NestedError => e
403
452
  puts e.ruby_error.backtrace.join("\n")
404
453
  raise
405
454
  end
406
-
407
455
  end
408
456
 
409
457
  it 'should pass varargs' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: h8
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - sergeych
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-01 00:00:00.000000000 Z
11
+ date: 2015-04-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler