static JSObject * reflect_anchor_array(MochaDecoder *decoder, JSClass *clasp, JSNative constructor, JSObject *document) { JSContext *cx; JSObject *obj, *prototype; JSObjectArray *array; JSDocument *doc; cx = decoder->js_context; doc = JS_GetPrivate(cx, document); if (!doc) return NULL; prototype = JS_InitClass(cx, decoder->window_object, NULL, clasp, constructor, 0, anchor_array_props, NULL, NULL, NULL); if (!prototype) return NULL; array = JS_malloc(cx, sizeof *array); if (!array) return NULL; XP_BZERO(array, sizeof *array); obj = JS_NewObject(cx, clasp, prototype, document); if (!obj || !JS_SetPrivate(cx, obj, array)) { JS_free(cx, array); return NULL; } array->decoder = HOLD_BACK_COUNT(decoder); array->layer_id = doc->layer_id; return obj; }
JSObject* lm_DefineComponents(MochaDecoder *decoder) { JSObject *obj; JSComponentArray *array; JSContext *cx = decoder->js_context; JSPreDefComponent def_comps; JSComponent *component; jsint slot; obj = decoder->components; if (obj) return obj; array = JS_malloc(cx, sizeof(JSComponentArray)); if (!array) return NULL; XP_BZERO(array, sizeof *array); obj = JS_NewObject(cx, &lm_component_array_class, NULL, decoder->window_object); if (!obj || !JS_SetPrivate(cx, obj, array)) { JS_free(cx, array); return NULL; } if (!JS_DefineProperties(cx, obj, componentarray_props)) return NULL; array->decoder = HOLD_BACK_COUNT(decoder); array->obj = obj; /* Components can be added dynamically but some are predefined */ slot = 0; array->length = 0; def_comps = predef_components[slot]; while (def_comps.name) { component = JS_malloc(cx, sizeof(JSComponent)); if (!component) return NULL; if (ET_moz_VerifyComponentFunction(def_comps.func, &(component->active_callback), &(component->startup_callback))) { componentarray_create_component(cx, array, component, def_comps.name, array->length); } else { /*Component call failed somewhere.*/ JS_free(cx, component); } def_comps = predef_components[++slot]; } return obj; }
JSObject * lm_DefineLocation(MochaDecoder *decoder) { JSObject *obj; JSContext *cx; JSURL *url; obj = decoder->location; if (obj) return obj; cx = decoder->js_context; url = JS_malloc(cx, sizeof *url); if (!url) return NULL; XP_BZERO(url, sizeof *url); obj = JS_InitClass(cx, decoder->window_object, NULL, &lm_location_class, Location, 0, url_props, loc_methods, NULL, NULL); if (!obj || !JS_SetPrivate(cx, obj, url)) { JS_free(cx, url); return NULL; } /* XXX common subroutine this and above with lm_NewURL */ if (!JS_AddNamedRoot(cx, &url->href, "loc.text")) return NULL; if (!JS_AddNamedRoot(cx, &url->target, "loc.target")) return NULL; if (!JS_AddNamedRoot(cx, &url->text, "loc.text")) return NULL; if (!JS_DefineProperty(cx, decoder->window_object, lm_location_str, OBJECT_TO_JSVAL(obj), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY)) { return NULL; } if (!JS_DefineProperty(cx, decoder->document, lm_location_str, OBJECT_TO_JSVAL(obj), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY)) { return NULL; } /* Define the Location object (the current URL). */ url->url_decoder = HOLD_BACK_COUNT(decoder); url->url_type = FORM_TYPE_NONE; url->url_object = obj; url->index = URL_NOT_INDEXED; decoder->location = obj; return obj; }
static JSBool InitEventObject(JSContext *cx, JSObject *obj, JSEvent *pEvent) { MochaDecoder *decoder; XP_ASSERT(JS_InstanceOf(cx, obj, &lm_event_class, NULL)); if (!JS_SetPrivate(cx, obj, pEvent)) { JS_free(cx, pEvent); return JS_FALSE; } decoder = JS_GetPrivate(cx, JS_GetGlobalObject(cx)); pEvent->decoder = HOLD_BACK_COUNT(decoder); pEvent->saved = JS_TRUE; return JS_TRUE; }
/* Constructor method for a JSComponent object */ static JSComponent* component_create_self(JSContext *cx, MochaDecoder* decoder, JSComponent *component, const char *name) { JSObject *obj; /* JSComponent may be malloc'd previous to this to make it easier * to fill in the struct with data from the Mozilla thread */ if (!component) { component = JS_malloc(cx, sizeof(JSComponent)); if (!component) return NULL; } obj = JS_NewObject(cx, &lm_component_class, NULL, NULL); if (!obj || !JS_SetPrivate(cx, obj, component)) { JS_free(cx, component); return NULL; } if (!JS_DefineProperties(cx, obj, component_props)) return NULL; if (!JS_DefineFunctions(cx, obj, component_methods)) return NULL; /* Fill out static property fields */ component->decoder = HOLD_BACK_COUNT(decoder); component->obj = obj; component->name = JS_NewStringCopyZ(cx, name); if (!component->name || !JS_LockGCThing(cx, component->name)) return NULL; return component; }
JSObject * lm_GetEmbedArray(MochaDecoder *decoder, JSObject *document) { JSContext *cx = decoder->js_context; JSObject *obj; JSObjectArray *array; JSDocument *doc; doc = JS_GetPrivate(cx, document); if (!doc) return NULL; obj = doc->embeds; if (obj) return obj; array = JS_malloc(cx, sizeof *array); if (!array) return NULL; array->decoder = NULL; /* in case of error below */ obj = JS_NewObject(cx, &lm_embed_array_class, NULL, document); if (!obj || !JS_SetPrivate(cx, obj, array)) { JS_free(cx, array); return NULL; } if (!JS_DefineProperties(cx, obj, embed_array_props)) return NULL; array->decoder = HOLD_BACK_COUNT(decoder); array->length = 0; array->layer_id = doc->layer_id; doc->embeds = obj; return obj; }
JSURL * lm_NewURL(JSContext *cx, MochaDecoder *decoder, LO_AnchorData *anchor_data, JSObject *document) { JSObject *obj; JSURL *url; JSString *str; if (!decoder->url_prototype) { obj = JS_InitClass(cx, decoder->window_object, decoder->event_receiver_prototype, &lm_url_class, Url, 0, url_props, NULL, NULL, NULL); if (!obj) return NULL; decoder->url_prototype = obj; } url = JS_malloc(cx, sizeof *url); if (!url) return NULL; XP_BZERO(url, sizeof *url); obj = JS_NewObject(cx, &lm_url_class, decoder->url_prototype, lm_GetOuterObject(decoder)); if (!obj || !JS_SetPrivate(cx, obj, url)) { JS_free(cx, url); return NULL; } if (!JS_DefineFunctions(cx, obj, url_methods)) return NULL; url->url_decoder = HOLD_BACK_COUNT(decoder); url->url_type = FORM_TYPE_NONE; url->index = URL_NOT_INDEXED; url->url_object = obj; str = JS_NewStringCopyZ(cx, (char *) anchor_data->anchor); if (!str) return NULL; url->href = str; if (!JS_AddNamedRoot(cx, &url->href, "url.href")) return NULL; if (anchor_data->target) { str = JS_NewStringCopyZ(cx, (char *) anchor_data->target); if (!str) return NULL; url->target = str; } if (!JS_AddNamedRoot(cx, &url->target, "url.target")) return NULL; if (anchor_data->element && anchor_data->element->type == LO_TEXT) { str = lm_LocalEncodingToStr(decoder->window_context, (char *) anchor_data->element->lo_text.text); if (!str) return NULL; url->text = str; } if (!JS_AddNamedRoot(cx, &url->text, "url.text")) return NULL; return url; }
JSObject * LM_ReflectNamedAnchor(MWContext *context, lo_NameList *name_rec, PA_Tag * tag, int32 layer_id, uint index) { JSObject *obj, *array_obj, *document; MochaDecoder *decoder; JSContext *cx; JSObjectArray *array; JSAnchor *named_anchor; lo_TopState *top_state; PRHashTable *map; JSString *str; obj = name_rec->mocha_object; if (obj) return obj; decoder = LM_GetMochaDecoder(context); if (!decoder) return NULL; cx = decoder->js_context; top_state = lo_GetMochaTopState(context); if (top_state->resize_reload) { map = lm_GetIdToObjectMap(decoder); if (map) obj = (JSObject *)PR_HashTableLookup(map, LM_GET_MAPPING_KEY(LM_NAMEDANCHORS, layer_id, index)); if (obj) { name_rec->mocha_object = obj; LM_PutMochaDecoder(decoder); return obj; } } /* Get the document object that will hold this anchor */ document = lm_GetDocumentFromLayerId(decoder, layer_id); if (!document) { LM_PutMochaDecoder(decoder); return NULL; } array_obj = lm_GetNameArray(decoder, document); if (!array_obj) { LM_PutMochaDecoder(decoder); return NULL; } array = JS_GetPrivate(cx, array_obj); if (!array) { LM_PutMochaDecoder(decoder); return NULL; } named_anchor = JS_malloc(cx, sizeof *named_anchor); if (!named_anchor) { LM_PutMochaDecoder(decoder); return NULL; } XP_BZERO(named_anchor, sizeof *named_anchor); obj = JS_NewObject(cx, &lm_anchor_class, decoder->anchor_prototype, document); if (!obj || !JS_SetPrivate(cx, obj, named_anchor)) { JS_free(cx, named_anchor); LM_PutMochaDecoder(decoder); return NULL; } /* Put obj into the document.anchors array. */ JS_DefineProperty(cx, array_obj, (char *) name_rec->name, OBJECT_TO_JSVAL(obj), NULL, NULL, JSPROP_ENUMERATE|JSPROP_READONLY); JS_AliasElement(cx, array_obj, (char *) name_rec->name, index); /* Put it in the index to object hash table */ map = lm_GetIdToObjectMap(decoder); if (map) { PR_HashTableAdd(map, LM_GET_MAPPING_KEY(LM_NAMEDANCHORS, layer_id, index), obj); } if ((jsint) index >= array->length) array->length = index + 1; named_anchor->decoder = HOLD_BACK_COUNT(decoder); named_anchor->layer_id = layer_id; named_anchor->index = index; if (name_rec->element && name_rec->element->type == LO_TEXT) { str = lm_LocalEncodingToStr(context, (char *) name_rec->element->lo_text.text); if (!str || !JS_LockGCThing(cx, str)) { LM_PutMochaDecoder(decoder); return NULL; } named_anchor->text = str; } str = JS_NewStringCopyZ(cx, (char *) name_rec->name); if (!str || !JS_LockGCThing(cx, str)) { LM_PutMochaDecoder(decoder); return NULL; } named_anchor->name = str; name_rec->mocha_object = obj; /* see if there are any attributes for event handlers */ if(tag) { PA_Block onlocate, id; /* don't hold the layout lock across compiles */ LO_UnlockLayout(); onlocate = lo_FetchParamValue(context, tag, PARAM_ONLOCATE); id = lo_FetchParamValue(context, tag, PARAM_ID); if (onlocate) { (void) lm_CompileEventHandler(decoder, id, tag->data, tag->newline_count, obj, PARAM_ONLOCATE, onlocate); PA_FREE(onlocate); } if (id) PA_FREE(id); LO_LockLayout(); } LM_PutMochaDecoder(decoder); return obj; }