/* @bookmark_class.getProperty */ static JSBool bookmark_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) { struct bookmark *bookmark; /* This can be called if @obj if not itself an instance of the * appropriate class but has one in its prototype chain. Fail * such calls. */ if (!JS_InstanceOf(ctx, obj, (JSClass *) &bookmark_class, NULL)) return JS_FALSE; bookmark = JS_GetInstancePrivate(ctx, obj, (JSClass *) &bookmark_class, NULL); if (!bookmark) return JS_FALSE; undef_to_jsval(ctx, vp); if (!JSID_IS_INT(id)) return JS_FALSE; switch (JSID_TO_INT(id)) { case BOOKMARK_TITLE: return bookmark_string_to_jsval(ctx, bookmark->title, vp); case BOOKMARK_URL: return bookmark_string_to_jsval(ctx, bookmark->url, vp); case BOOKMARK_CHILDREN: *vp = OBJECT_TO_JSVAL(smjs_get_bookmark_folder_object(bookmark)); return JS_TRUE; default: /* Unrecognized integer property ID; someone is using * the object as an array. SMJS builtin classes (e.g. * js_RegExpClass) just return JS_TRUE in this case * and leave *@vp unchanged. Do the same here. * (Actually not quite the same, as we already used * @undef_to_jsval.) */ return JS_TRUE; } }
/* @location_class.getProperty */ static JSBool location_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) { JSObject *parent_win; /* instance of @window_class */ struct view_state *vs; /* This can be called if @obj if not itself an instance of the * appropriate class but has one in its prototype chain. Fail * such calls. */ if (!JS_InstanceOf(ctx, obj, (JSClass *) &location_class, NULL)) return JS_FALSE; parent_win = JS_GetParent(ctx, obj); assert(JS_InstanceOf(ctx, parent_win, (JSClass *) &window_class, NULL)); if_assert_failed return JS_FALSE; vs = (struct view_state *)JS_GetInstancePrivate(ctx, parent_win, (JSClass *) &window_class, NULL); if (!JSID_IS_INT(id)) return JS_TRUE; undef_to_jsval(ctx, vp); switch (JSID_TO_INT(id)) { case JSP_LOC_HREF: astring_to_jsval(ctx, vp, get_uri_string(vs->uri, URI_ORIGINAL)); break; default: /* Unrecognized integer property ID; someone is using * the object as an array. SMJS builtin classes (e.g. * js_RegExpClass) just return JS_TRUE in this case * and leave *@vp unchanged. Do the same here. * (Actually not quite the same, as we already used * @undef_to_jsval.) */ break; } return JS_TRUE; }
/* @cache_entry_class.getProperty */ static JSBool cache_entry_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) { struct cache_entry *cached; JSBool ret; /* This can be called if @obj if not itself an instance of the * appropriate class but has one in its prototype chain. Fail * such calls. */ if (!JS_InstanceOf(ctx, obj, (JSClass *) &cache_entry_class, NULL)) return JS_FALSE; cached = JS_GetInstancePrivate(ctx, obj, (JSClass *) &cache_entry_class, NULL); if (!cached) return JS_FALSE; /* already detached */ assert(cache_entry_is_valid(cached)); if_assert_failed return JS_FALSE; /* Get a strong reference to the cache entry to prevent it * from being deleted if some function called below decides to * collect garbage. After this, all code paths must * eventually unlock the object. */ object_lock(cached); undef_to_jsval(ctx, vp); if (!JSID_IS_INT(id)) ret = JS_FALSE; else switch (JSID_TO_INT(id)) { case CACHE_ENTRY_CONTENT: { struct fragment *fragment = get_cache_fragment(cached); if (!fragment) { ret = JS_FALSE; break; } *vp = STRING_TO_JSVAL(JS_NewStringCopyN(smjs_ctx, fragment->data, fragment->length)); ret = JS_TRUE; break; } case CACHE_ENTRY_TYPE: *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx, cached->content_type)); ret = JS_TRUE; break; case CACHE_ENTRY_HEAD: *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx, cached->head)); ret = JS_TRUE; break; case CACHE_ENTRY_LENGTH: *vp = INT_TO_JSVAL(cached->length); ret = JS_TRUE; break; case CACHE_ENTRY_URI: *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx, struri(cached->uri))); ret = JS_TRUE; break; default: /* Unrecognized integer property ID; someone is using * the object as an array. SMJS builtin classes (e.g. * js_RegExpClass) just return JS_TRUE in this case * and leave *@vp unchanged. Do the same here. * (Actually not quite the same, as we already used * @undef_to_jsval.) */ ret = JS_TRUE; break; } object_unlock(cached); return ret; }
/* @smjs_globhist_item_class.getProperty */ static JSBool smjs_globhist_item_get_property(JSContext *ctx, JSObject *obj, jsid id, jsval *vp) { struct global_history_item *history_item; /* This can be called if @obj if not itself an instance of the * appropriate class but has one in its prototype chain. Fail * such calls. */ if (!JS_InstanceOf(ctx, obj, (JSClass *) &smjs_globhist_item_class, NULL)) return JS_FALSE; history_item = JS_GetInstancePrivate(ctx, obj, (JSClass *) &smjs_globhist_item_class, NULL); if (!history_item) return JS_FALSE; undef_to_jsval(ctx, vp); if (!JSID_IS_INT(id)) return JS_FALSE; switch (JSID_TO_INT(id)) { case GLOBHIST_TITLE: *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx, history_item->title)); return JS_TRUE; case GLOBHIST_URL: *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(smjs_ctx, history_item->url)); return JS_TRUE; case GLOBHIST_LAST_VISIT: /* TODO: I'd rather return a date object, but that introduces * synchronisation issues: * * - How do we cause a change to that date object to affect * the actual global history item? * - How do we get a change to that global history item * to affect all date objects? * * The biggest obstacle is that we have no way to trigger code * when one messes with the date object. * * -- Miciah */ /* XXX: Currently, ECMAScript gets seconds since the epoch. * Since the Date object uses milliseconds since the epoch, * I'd rather export that, but SpiderMonkey doesn't provide * a suitable type. -- Miciah */ JS_NewNumberValue(smjs_ctx, history_item->last_visit, vp); return JS_TRUE; default: /* Unrecognized integer property ID; someone is using * the object as an array. SMJS builtin classes (e.g. * js_RegExpClass) just return JS_TRUE in this case * and leave *@vp unchanged. Do the same here. * (Actually not quite the same, as we already used * @undef_to_jsval.) */ return JS_TRUE; } }