Permalink
Browse files

js: Add support for page.reorderer callback

  • Loading branch information...
1 parent e394dea commit af0577d3105127a6c38b2e124a12108aaa5de84e @andoma committed Oct 2, 2012
Showing with 95 additions and 24 deletions.
  1. +95 −24 src/js/js_page.c
View
119 src/js/js_page.c
@@ -105,6 +105,7 @@ typedef struct js_model {
prop_sub_t *jm_eventsub;
jsval jm_paginator;
+ jsval jm_reorderer;
JSContext *jm_cx;
@@ -337,6 +338,7 @@ js_item_eventsub(void *opaque, prop_event_t event, ...)
ji->ji_eventsub = NULL;
ji->ji_model->jm_subs--;
JS_RemoveRoot(ji->ji_model->jm_cx, &ji->ji_this);
+ prop_tag_clear(ji->ji_root, ji->ji_model);
break;
case PROP_EXT_EVENT:
@@ -362,18 +364,6 @@ js_item_onEvent(JSContext *cx, JSObject *obj,
return JS_FALSE;
}
- if(ji->ji_eventsub == NULL) {
- ji->ji_eventsub =
- prop_subscribe(PROP_SUB_TRACK_DESTROY,
- PROP_TAG_CALLBACK, js_item_eventsub, ji,
- PROP_TAG_ROOT, ji->ji_root,
- PROP_TAG_COURIER, ji->ji_model->jm_pc,
- NULL);
- ji->ji_model->jm_subs++;
- ji->ji_this = OBJECT_TO_JSVAL(obj);
- JS_AddNamedRoot(cx, &ji->ji_this, "item_this");
- }
-
js_event_handler_create(cx, &ji->ji_event_handlers,
JSVAL_IS_STRING(argv[0]) ?
JS_GetStringBytes(JS_ValueToString(cx, argv[0])) :
@@ -409,7 +399,8 @@ js_item_moveBefore(JSContext *cx, JSObject *obj,
js_item_t *ji = JS_GetPrivate(cx, obj);
js_item_t *before;
- if(argc >= 1 && JSVAL_IS_OBJECT(argv[0]) &&
+ if(argc >= 1 && JSVAL_IS_OBJECT(argv[0]) &&
+ !JSVAL_IS_NULL(argv[0]) &&
JS_GetClass(cx, JSVAL_TO_OBJECT(argv[0])) == &item_class) {
before = JS_GetPrivate(cx, JSVAL_TO_OBJECT(argv[0]));
} else {
@@ -626,6 +617,17 @@ js_appendItem0(JSContext *cx, js_model_t *model, prop_t *parent,
LIST_INSERT_HEAD(&model->jm_items, ji, ji_link);
JS_SetPrivate(cx, robj, ji);
ji->ji_enable_set_property = 1;
+
+ ji->ji_eventsub =
+ prop_subscribe(PROP_SUB_TRACK_DESTROY,
+ PROP_TAG_CALLBACK, js_item_eventsub, ji,
+ PROP_TAG_ROOT, ji->ji_root,
+ PROP_TAG_COURIER, model->jm_pc,
+ NULL);
+ model->jm_subs++;
+ ji->ji_this = OBJECT_TO_JSVAL(robj);
+ JS_AddNamedRoot(cx, &ji->ji_this, "item_this");
+ prop_tag_set(ji->ji_root, model, ji);
}
return JS_TRUE;
}
@@ -990,6 +992,25 @@ js_model_fill(JSContext *cx, js_model_t *jm)
return JSVAL_IS_BOOLEAN(result) && JSVAL_TO_BOOLEAN(result);
}
+/**
+ *
+ */
+static void
+js_reorder(JSContext *cx, js_model_t *jm, js_item_t *ji, js_item_t *before)
+{
+ void *mark;
+ jsval *argv, result;
+
+ if(!jm->jm_reorderer)
+ return;
+
+ argv = JS_PushArguments(cx, &mark, "vv", ji->ji_this,
+ before ? before->ji_this : JSVAL_NULL);
+
+ JS_CallFunctionValue(cx, NULL, jm->jm_reorderer, 2, argv, &result);
+ JS_PopArguments(cx, mark);
+}
+
/**
*
@@ -999,20 +1020,31 @@ js_model_nodesub(void *opaque, prop_event_t event, ...)
{
js_model_t *jm = opaque;
va_list ap;
-
+ prop_t *p1, *p2;
va_start(ap, event);
switch(event) {
default:
break;
case PROP_DESTROYED:
- JS_RemoveRoot(jm->jm_cx, &jm->jm_paginator);
+ if(jm->jm_paginator)
+ JS_RemoveRoot(jm->jm_cx, &jm->jm_paginator);
+ if(jm->jm_reorderer)
+ JS_RemoveRoot(jm->jm_cx, &jm->jm_reorderer);
+
prop_unsubscribe(jm->jm_nodesub);
jm->jm_nodesub = NULL;
jm->jm_subs--;
break;
+ case PROP_REQ_MOVE_CHILD:
+ p1 = va_arg(ap, prop_t *);
+ p2 = va_arg(ap, prop_t *);
+ js_reorder(jm->jm_cx, jm, prop_tag_get(p1, jm),
+ p2 ? prop_tag_get(p2, jm) : NULL);
+ break;
+
case PROP_WANT_MORE_CHILDS:
if(js_model_fill(jm->jm_cx, jm))
prop_have_more_childs(jm->jm_nodes);
@@ -1021,6 +1053,26 @@ js_model_nodesub(void *opaque, prop_event_t event, ...)
va_end(ap);
}
+
+/**
+ *
+ */
+static void
+install_nodesub(js_model_t *jm)
+{
+ if(jm->jm_nodesub)
+ return;
+
+ jm->jm_subs++;
+ jm->jm_nodesub =
+ prop_subscribe(PROP_SUB_TRACK_DESTROY,
+ PROP_TAG_CALLBACK, js_model_nodesub, jm,
+ PROP_TAG_ROOT, jm->jm_nodes,
+ PROP_TAG_COURIER, jm->jm_pc,
+ NULL);
+}
+
+
/**
*
*/
@@ -1035,16 +1087,32 @@ js_setPaginator(JSContext *cx, JSObject *obj, jsval idval, jsval *vp)
return JS_FALSE;
}
- jm->jm_subs++;
- jm->jm_nodesub =
- prop_subscribe(PROP_SUB_TRACK_DESTROY,
- PROP_TAG_CALLBACK, js_model_nodesub, jm,
- PROP_TAG_ROOT, jm->jm_nodes,
- PROP_TAG_COURIER, jm->jm_pc,
- NULL);
-
+ install_nodesub(jm);
+ if(!jm->jm_paginator)
+ JS_AddNamedRoot(cx, &jm->jm_paginator, "paginator");
jm->jm_paginator = *vp;
- JS_AddNamedRoot(cx, &jm->jm_paginator, "paginator");
+ return JS_TRUE;
+}
+
+
+/**
+ *
+ */
+static JSBool
+js_setReorderer(JSContext *cx, JSObject *obj, jsval idval, jsval *vp)
+{
+ js_model_t *jm = JS_GetPrivate(cx, obj);
+
+ if(!JSVAL_IS_OBJECT(*vp) ||
+ !JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(*vp))) {
+ JS_ReportError(cx, "Argument is not a function");
+ return JS_FALSE;
+ }
+
+ install_nodesub(jm);
+ if(!jm->jm_reorderer)
+ JS_AddNamedRoot(cx, &jm->jm_reorderer, "reorderer");
+ jm->jm_reorderer = *vp;
return JS_TRUE;
}
@@ -1091,6 +1159,9 @@ make_model_object(JSContext *cx, js_model_t *jm, jsval *root)
JS_DefineProperty(cx, obj, "paginator", JSVAL_VOID,
NULL, js_setPaginator, JSPROP_PERMANENT);
+
+ JS_DefineProperty(cx, obj, "reorderer", JSVAL_VOID,
+ NULL, js_setReorderer, JSPROP_PERMANENT);
return obj;
}

0 comments on commit af0577d

Please sign in to comment.