@@ -100,14 +100,16 @@ Handle<Array> WatchableNamedPropertyEnumerator(
100100 const AccessorInfo& info
101101 ) {
102102 HandleScope scope;
103+ // printf("named enum\n");
103104 // Grab the value of the property
104105 Handle<Object> holder = info.Holder ();
105106 Handle<Object> map = Handle<Object>::Cast (
106107 holder->GetInternalField (0 )
107108 );
108109 // Default
109- Handle<Value> data = holder->GetInternalField (4 );
110+ Handle<Value> data = holder->GetInternalField (5 );
110111 if (data->IsNull ()) {
112+ // printf("defaulting indexed enum\n");
111113 return scope.Close (map->GetPropertyNames ());
112114 }
113115 Handle<Value> old_value;
@@ -124,10 +126,85 @@ Handle<Array> WatchableNamedPropertyEnumerator(
124126 return scope.Close (Handle<Array>::Cast (new_value));
125127 }
126128 else {
127- ThrowException (String::New (" Callback must return an Array." ));
129+ ThrowException (Exception::Error ( String::New (" Callback must return an Array." ) ));
128130 return scope.Close (Array::New ());
129131 }
130132}
133+ Handle<Boolean> WatchableNamedPropertyQuery (
134+ Local<String> property
135+ , const AccessorInfo& info
136+ ) {
137+ HandleScope scope;
138+
139+ // Grab the value
140+ Handle<Object> holder = info.Holder ();
141+ Handle<Object> map = Handle<Object>::Cast (
142+ holder->GetInternalField (0 )
143+ );
144+ // Default
145+ Handle<Value> data = holder->GetInternalField (3 );
146+ if (data->IsNull ()) {
147+ return scope.Close (Boolean::New (holder->Has (property)));
148+ }
149+ Handle<Value> value;
150+ Handle<Value> had_value;
151+
152+ if ( holder->Has (property) ) {
153+ value = map->Get (property);
154+ had_value = True ();
155+ }
156+ else {
157+ value = Undefined ();
158+ had_value = False ();
159+ }
160+ // Set up arguments
161+ Handle<Value> values[3 ] = {property,value,had_value};
162+
163+ // Grab function and call (property,value)
164+ Handle<Function> callback = Handle<Function>::Cast (data);
165+ Handle<Value> new_value = callback->Call (holder,3 ,values);
166+
167+ // Return value is the return of the function call
168+ return scope.Close (Boolean::New (new_value->IsTrue ()));
169+ }
170+
171+ Handle<Boolean> WatchableNamedPropertyDeleter (
172+ Local<String> property
173+ , const AccessorInfo& info
174+ ) {
175+ HandleScope scope;
176+
177+ // Grab the value
178+ Handle<Object> holder = info.Holder ();
179+ Handle<Object> map = Handle<Object>::Cast (
180+ holder->GetInternalField (0 )
181+ );
182+ // Default
183+ Handle<Value> data = holder->GetInternalField (4 );
184+ if (data->IsNull ()) {
185+ return scope.Close (Boolean::New (holder->Delete (property)));
186+ }
187+ Handle<Value> value;
188+ Handle<Value> had_value;
189+
190+ if ( holder->Has (property) ) {
191+ value = map->Get (property);
192+ had_value = True ();
193+ }
194+ else {
195+ value = Undefined ();
196+ had_value = False ();
197+ }
198+ // Set up arguments
199+ Handle<Value> values[3 ] = {property,value,had_value};
200+
201+ // Grab function and call (property,value)
202+ Handle<Function> callback = Handle<Function>::Cast (data);
203+ Handle<Value> new_value = callback->Call (holder,3 ,values);
204+
205+ // Return value is the return of the function call
206+ return scope.Close (Boolean::New (new_value->IsTrue ()));
207+ }
131208
132209Handle<Value> WatchableIndexedPropertyGetter (
133210 uint32_t index
@@ -168,6 +245,7 @@ Handle<Value> WatchableIndexedPropertyGetter(
168245 return scope.Close (new_value);
169246}
170247
248+
171249Handle<Value> WatchableIndexedPropertySetter (
172250 uint32_t index
173251 , Local<Value> value
@@ -221,7 +299,7 @@ Handle<Array> WatchableIndexedPropertyEnumerator(
221299 holder->GetInternalField (0 )
222300 );
223301 // Default
224- Handle<Value> data = holder->GetInternalField (2 );
302+ Handle<Value> data = holder->GetInternalField (5 );
225303 if (data->IsNull ()) {
226304 return scope.Close (map->GetPropertyNames ());
227305 }
@@ -240,7 +318,83 @@ Handle<Array> WatchableIndexedPropertyEnumerator(
240318 return scope.Close (Array::New ());
241319 }
242320}
321+ Handle<Boolean> WatchableIndexedPropertyQuery (
322+ uint32_t index
323+ , const AccessorInfo& info
324+ ) {
325+ HandleScope scope;
243326
327+ // Grab the value
328+ Handle<Object> holder = info.Holder ();
329+ Handle<Object> map = Handle<Object>::Cast (
330+ holder->GetInternalField (0 )
331+ );
332+ // Default
333+ Handle<Value> data = holder->GetInternalField (3 );
334+ if (data->IsNull ()) {
335+ return scope.Close (Boolean::New (holder->Has (index)));
336+ }
337+ Handle<Number> property = Integer::New (index);
338+ Handle<Value> value;
339+ Handle<Value> had_value;
340+
341+ if ( holder->Has (index) ) {
342+ value = map->Get (index);
343+ had_value = True ();
344+ }
345+ else {
346+ value = Undefined ();
347+ had_value = False ();
348+ }
349+ // Set up arguments
350+ Handle<Value> values[3 ] = {property,value,had_value};
351+
352+ // Grab function and call (property,value)
353+ Handle<Function> callback = Handle<Function>::Cast (data);
354+ Handle<Value> new_value = callback->Call (holder,3 ,values);
355+
356+ // Return value is the return of the function call
357+ return scope.Close (Boolean::New (new_value->IsTrue ()));
358+ }
359+
360+ Handle<Boolean> WatchableIndexedPropertyDeleter (
361+ uint32_t index
362+ , const AccessorInfo& info
363+ ) {
364+ HandleScope scope;
365+
366+ // Grab the value
367+ Handle<Object> holder = info.Holder ();
368+ Handle<Object> map = Handle<Object>::Cast (
369+ holder->GetInternalField (0 )
370+ );
371+ // Default
372+ Handle<Value> data = holder->GetInternalField (4 );
373+ if (data->IsNull ()) {
374+ return scope.Close (Boolean::New (holder->Delete (index)));
375+ }
376+ Handle<Number> property = Integer::New (index);
377+ Handle<Value> value;
378+ Handle<Value> had_value;
379+
380+ if ( holder->Has (index) ) {
381+ value = map->Get (index);
382+ had_value = True ();
383+ }
384+ else {
385+ value = Undefined ();
386+ had_value = False ();
387+ }
388+ // Set up arguments
389+ Handle<Value> values[3 ] = {property,value,had_value};
390+
391+ // Grab function and call (property,value)
392+ Handle<Function> callback = Handle<Function>::Cast (data);
393+ Handle<Value> new_value = callback->Call (holder,3 ,values);
394+
395+ // Return value is the return of the function call
396+ return scope.Close (Boolean::New (new_value->IsTrue ()));
397+ }
244398
245399Handle<Value> Watchable (const Arguments& args) {
246400 HandleScope scope;
@@ -253,7 +407,7 @@ Handle<Value> Watchable(const Arguments& args) {
253407 getter = Null ();
254408 }
255409 else {
256- return ThrowException (String::New (" Getter callback must be a function" ));
410+ return scope. Close ( ThrowException (Exception::Error ( String::New (" Getter callback must be a function" )) ));
257411 }
258412 Handle<Value> setter = args[1 ];
259413 if (setter->IsFunction ()) {
@@ -263,7 +417,7 @@ Handle<Value> Watchable(const Arguments& args) {
263417 setter = Null ();
264418 }
265419 else {
266- return ThrowException (String::New (" Getter callback must be a function" ));
420+ return scope. Close ( ThrowException (Exception::Error ( String::New (" Setter callback must be a function" )) ));
267421 }
268422 Handle<Value> enumerator = args[2 ];
269423 if (enumerator->IsFunction ()) {
@@ -273,22 +427,43 @@ Handle<Value> Watchable(const Arguments& args) {
273427 enumerator = Null ();
274428 }
275429 else {
276- return ThrowException (String::New (" Getter callback must be a function" ));
430+ return scope.Close (ThrowException (Exception::Error (String::New (" Enumerator callback must be a function" ))));
431+ }
432+ Handle<Value> query = args[3 ];
433+ if (query->IsFunction ()) {
434+ // Do nothing
435+ }
436+ else if (query->IsNull () || enumerator->IsUndefined ()) {
437+ query = Null ();
438+ }
439+ else {
440+ return scope.Close (ThrowException (Exception::Error (String::New (" Query callback must be a function" ))));
441+ }
442+ Handle<Value> deleter = args[4 ];
443+ if (deleter->IsFunction ()) {
444+ // Do nothing
445+ }
446+ else if (deleter->IsNull () || enumerator->IsUndefined ()) {
447+ deleter = Null ();
448+ }
449+ else {
450+ return scope.Close (ThrowException (Exception::Error (String::New (" Deleter callback must be a function" ))));
277451 }
452+
278453 Local<ObjectTemplate> object_template = ObjectTemplate::New ();
279454 object_template->SetNamedPropertyHandler (
280455 WatchableNamedPropertyGetter
281- ,WatchableNamedPropertySetter, 0 , 0
282- // ,WatchableNamedPropertyQuery
283- // ,WatchableNamedPropertyDeleter
456+ ,WatchableNamedPropertySetter
457+ ,WatchableNamedPropertyQuery
458+ ,WatchableNamedPropertyDeleter
284459 ,WatchableNamedPropertyEnumerator
285460 );
286461 object_template->SetIndexedPropertyHandler (
287462 WatchableIndexedPropertyGetter
288463 ,WatchableIndexedPropertySetter
289- ,0 , 0
290- // Is this ever used?
291- // ,WatchableIndexedPropertyEnumerator
464+ ,WatchableIndexedPropertyQuery
465+ ,WatchableIndexedPropertyDeleter
466+ ,WatchableIndexedPropertyEnumerator
292467 );
293468 // Every one with a different callback needs a different template
294469 // 0 - Holder object - aka the real one
@@ -297,20 +472,22 @@ Handle<Value> Watchable(const Arguments& args) {
297472 // 3 - Query
298473 // 4 - Deleter
299474 // 5 - Enumerator
300- object_template->SetInternalFieldCount (5 );
475+ object_template->SetInternalFieldCount (6 );
301476 Handle<Object> watchable = object_template->NewInstance ();
302477 watchable->SetInternalField (0 ,Object::New ());
303478 watchable->SetInternalField (1 ,getter);
304479 watchable->SetInternalField (2 ,setter);
305- watchable->SetInternalField (4 ,enumerator);
306- // printf("watchable created\n");
480+ watchable->SetInternalField (3 ,query);
481+ watchable->SetInternalField (4 ,deleter);
482+ watchable->SetInternalField (5 ,enumerator);
483+ // //printf("watchable created\n");
307484 return scope.Close (watchable);
308485}
309486
310487extern " C" void init (Handle<Object> target)
311488{
312489 HandleScope scope;
313- // printf("init\n");
490+ // // printf("init\n");
314491 Local<FunctionTemplate> watchable_template = FunctionTemplate::New (Watchable);
315492 Local<Function> watchable = watchable_template->GetFunction ();
316493 // Export
0 commit comments