summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorportix <portix@gmx.net>2013-05-21 19:04:02 +0200
committerportix <portix@gmx.net>2013-05-21 19:04:02 +0200
commitdc1e4d5605aa9a9e92105b0cda8da0fe11fbcd28 (patch)
treeda14093abbdaf98c0c6e00954563fbc9fb767f2e
parent29f75485ce1ead1d20067d3ca16dd7846f53cba4 (diff)
downloaddwb-dc1e4d5605aa9a9e92105b0cda8da0fe11fbcd28.zip
Define object 'archive' for script-archives.
-rw-r--r--src/dwb.c2
-rw-r--r--src/js.c8
-rw-r--r--src/js.h1
-rw-r--r--src/scripts.c79
-rw-r--r--src/scripts.h2
5 files changed, 68 insertions, 24 deletions
diff --git a/src/dwb.c b/src/dwb.c
index 0c77590e..d880f425 100644
--- a/src/dwb.c
+++ b/src/dwb.c
@@ -3625,7 +3625,7 @@ dwb_clean_up()
KeyMap *m = l->data;
if (m->map->prop & CP_SCRIPT)
{
- scripts_unbind(m->map->arg.p);
+ scripts_unprotect(m->map->arg.p);
g_free(m->map->n.first);
g_free(m->map->n.second);
}
diff --git a/src/js.c b/src/js.c
index e391abb4..eb0a118c 100644
--- a/src/js.c
+++ b/src/js.c
@@ -49,6 +49,14 @@ js_set_object_property(JSContextRef ctx, JSObjectRef arg, const char *name, cons
JSObjectSetProperty(ctx, arg, js_key, js_value, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly, exc);
JSStringRelease(js_key);
}
+gboolean
+js_object_has_property(JSContextRef ctx, JSObjectRef arg, const char *name)
+{
+ JSStringRef js_key = JSStringCreateWithUTF8CString(name);
+ gboolean result = JSObjectHasProperty(ctx, arg, js_key);
+ JSStringRelease(js_key);
+ return result;
+}
void
js_set_object_number_property(JSContextRef ctx, JSObjectRef arg, const char *name, gdouble value, JSValueRef *exc)
{
diff --git a/src/js.h b/src/js.h
index ff9160a2..50366c70 100644
--- a/src/js.h
+++ b/src/js.h
@@ -58,6 +58,7 @@ JSValueRef js_json_to_value(JSContextRef ctx, const char *text);
JSValueRef js_context_change(JSContextRef, JSContextRef, JSValueRef, JSValueRef *);
JSObjectRef js_value_to_function(JSContextRef, JSValueRef, JSValueRef *);
gboolean js_check_syntax(JSContextRef ctx, const char *script, const char *filename, int lineOffset);
+gboolean js_object_has_property(JSContextRef ctx, JSObjectRef arg, const char *name);
void js_array_iterator_init(JSContextRef ctx, js_array_iterator *iter, JSObjectRef object);
JSValueRef js_array_iterator_next(js_array_iterator *iter, JSValueRef *exc);
diff --git a/src/scripts.c b/src/scripts.c
index a7592f34..75027ab5 100644
--- a/src/scripts.c
+++ b/src/scripts.c
@@ -48,7 +48,7 @@
#define kJSDefaultAttributes (kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly )
#define SCRIPT_TEMPLATE_START "try{_initNewContext(this,arguments,'%s');const script=this;/*<dwb*/"
-#define SCRIPT_TEMPLATE_XSTART "try{_initNewContext(this,arguments,'%s');var xinclude=_xinclude.bind(this,this.path);const script=this;/*<dwb*/"
+#define SCRIPT_TEMPLATE_XSTART "try{var archive=arguments[0];_initNewContext(this,arguments,'%s');var xinclude=_xinclude.bind(this,this.path);const script=this;/*<dwb*/"
#define SCRIPT_TEMPLATE_END "%s/*dwb>*/}catch(e){script.debug(e);};"
@@ -184,6 +184,8 @@ static JSObjectRef s_soup_session;
static GSList *s_timers = NULL;
static GPtrArray *s_gobject_signals = NULL;
static gboolean s_debugging = false;
+static GHashTable *s_exports = NULL;
+
/* Only defined once */
static JSValueRef UNDEFINED, NIL;
@@ -1804,12 +1806,28 @@ do_include(JSContextRef ctx, const char *path, const char *script, gboolean glob
* });
* */
+static JSObjectRef
+get_exports(JSContextRef ctx, const char *path)
+{
+ JSObjectRef ret = g_hash_table_lookup(s_exports, path);
+ if (ret == NULL)
+ {
+ ret = JSObjectMake(ctx, NULL, NULL);
+ JSValueProtect(ctx, ret);
+ g_hash_table_insert(s_exports, g_strdup(path), ret);
+ }
+ return ret;
+}
+
+
static JSValueRef
global_include(JSContextRef ctx, JSObjectRef f, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef* exc)
{
JSValueRef ret = NIL;
gboolean global = false;
char *path = NULL, *content = NULL;
+ JSValueRef exports[1];
+ gboolean is_archive = false;
if (argc < 1)
return NIL;
@@ -1828,6 +1846,8 @@ global_include(JSContextRef ctx, JSObjectRef f, JSObjectRef this, size_t argc, c
js_make_exception(ctx, exc, EXCEPTION("include: main.js was not found in %s."), path);
goto error_out;
}
+ exports[0] = get_exports(ctx, path);
+ is_archive = true;
}
else if ( (content = util_get_file_content(path, NULL)) == NULL)
{
@@ -1843,7 +1863,8 @@ global_include(JSContextRef ctx, JSObjectRef f, JSObjectRef this, size_t argc, c
} while(*tmp && *tmp != '\n');
tmp++;
}
- ret = do_include(ctx, path, tmp, global, false, 0, NULL, exc);
+
+ ret = do_include(ctx, path, tmp, global, is_archive, is_archive ? 1 : 0, is_archive ? exports : NULL, exc);
error_out:
g_free(content);
@@ -1859,15 +1880,16 @@ error_out:
* possible to include scripts from an archive calling the internal function
* _xinclude which takes two parameters, the path of the archive and the path of
* the included file in the archive.
+ * All scripts in an archive share on object <b>archive</b> which can be used
+ * to share data between scripts in an archive.
+ *
* Unlike {@link include} included archive-scripts cannot be included into the
* global scope.
*
* @name xinclude
- * @param path {String}
+ * @function
+ * @param {String} path
* Path of the file in the archive
- * @param {...Object} {varargs}
- * Additional arguments passed to include, the arguments are accessible via
- * arguments
*
* @returns {Object}
* The object returned from the included file.
@@ -1880,22 +1902,17 @@ error_out:
* // content/bar.js
*
* // main.js
- * var foo = xinclude("content/foo.js");
- * var bar = xinclude("content/bar.js", foo);
+ * xinclude("content/foo.js");
+ * xinclude("content/bar.js");
*
* // content/foo.js
* function getFoo() {
* return 37;
* }
- * return {
- * getFoo : getFoo
- * };
+ * archive.getFoo = getFoo;
*
* // content/bar.js
- * var foo = arguments[0];
- *
- * var x = foo.getFoo();
- *
+ * var x = archive.getFoo();
*
* */
@@ -1915,7 +1932,10 @@ global_xinclude(JSContextRef ctx, JSObjectRef f, JSObjectRef thisObject, size_t
content = (char*)exar_extract(archive, path, &fs);
if (content != NULL)
- ret = do_include(ctx, archive, content, false, true, argc-2, argc > 2 ? &argv[2] : NULL, exc);
+ {
+ JSValueRef exports[] = { get_exports(ctx, archive) };
+ ret = do_include(ctx, archive, content, false, true, 1, exports, exc);
+ }
error_out:
g_free(archive);
@@ -5490,6 +5510,9 @@ apply_scripts()
{
int length = g_slist_length(s_script_list);
int i=0;
+ JSValueRef exports[1];
+ size_t argc = 0;
+ char *path;
// XXX Not needed?
JSObjectRef *objects = g_malloc(length * sizeof(JSObjectRef));
@@ -5507,7 +5530,15 @@ apply_scripts()
for (GSList *l = s_script_list; l; l=l->next)
{
- JSObjectCallAsFunction(s_global_context, l->data, l->data, 0, NULL, NULL);
+ argc = 0;
+ path = js_get_string_property(s_global_context, l->data, "path");
+ if (path != NULL)
+ {
+ exports[0] = get_exports(s_global_context, path);
+ argc = 1;
+ }
+
+ JSObjectCallAsFunction(s_global_context, l->data, l->data, argc, argc > 0 ? exports : NULL, NULL);
}
g_slist_free(s_script_list);
s_script_list = NULL;
@@ -5574,7 +5605,7 @@ scripts_remove_tab(JSObjectRef obj)
}/*}}}*/
void
-init_script(const char *path, const char *script, const char *template)
+init_script(const char *path, const char *script, gboolean is_archive, const char *template, int offset)
{
char *debug = NULL;
if (s_global_context == NULL)
@@ -5583,7 +5614,9 @@ init_script(const char *path, const char *script, const char *template)
if (js_check_syntax(s_global_context, script, path, 2))
{
debug = g_strdup_printf(template, path, script);
- JSObjectRef function = js_make_function(s_global_context, debug, path, 1);
+ JSObjectRef function = js_make_function(s_global_context, debug, path, offset);
+ if (is_archive)
+ js_set_object_property(s_global_context, function, "path", path, NULL);
if (function != NULL)
s_script_list = g_slist_prepend(s_script_list, function);
@@ -5595,13 +5628,13 @@ init_script(const char *path, const char *script, const char *template)
void
scripts_init_script(const char *path, const char *script)
{
- init_script(path, script, SCRIPT_TEMPLATE);
+ init_script(path, script, false, SCRIPT_TEMPLATE, 1);
}/*}}}*/
void
scripts_init_archive(const char *path, const char *script)
{
- init_script(path, script, SCRIPT_TEMPLATE_XINCLUDE);
+ init_script(path, script, true, SCRIPT_TEMPLATE_XINCLUDE, 0);
}
void
@@ -5659,6 +5692,7 @@ scripts_init(gboolean force)
return false;
}
s_gobject_signals = g_ptr_array_new();
+ s_exports = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)scripts_unprotect);
dwb.state.script_completion = NULL;
@@ -5706,7 +5740,7 @@ scripts_execute_one(const char *script)
return ret;
}
void
-scripts_unbind(JSObjectRef obj)
+scripts_unprotect(JSObjectRef obj)
{
if (!TRY_CONTEXT_LOCK)
return;
@@ -5773,6 +5807,7 @@ scripts_end()
}
g_ptr_array_free(s_gobject_signals, false);
s_gobject_signals = NULL;
+ g_hash_table_unref(s_exports);
for (int i=0; i<CONSTRUCTOR_LAST; i++)
diff --git a/src/scripts.h b/src/scripts.h
index d635f8b5..53571f99 100644
--- a/src/scripts.h
+++ b/src/scripts.h
@@ -72,7 +72,7 @@ void scripts_init_script(const char *, const char *);
void scripts_init_archive(const char *, const char *);
gboolean scripts_init(gboolean);
void scripts_reinit();
-void scripts_unbind(JSObjectRef);
+void scripts_unprotect(JSObjectRef);
DwbStatus scripts_eval_key(KeyMap *m, Arg *arg);
gboolean scripts_execute_one(const char *script);
void scripts_completion_activate(void);