h8 0.5.2 → 0.5.4

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.
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