home *** CD-ROM | disk | FTP | other *** search
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * The contents of this file are subject to the Netscape Public License
- * Version 1.0 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
-
- /*
- * JS reflection of applets in the current document
- */
-
- /* Please leave outside of ifdef for windows precompiled headers */
- #include "lm.h"
-
- #ifdef JAVA
-
- #include "xp.h"
- #include "layout.h"
- #include "java.h"
- #include "lj.h" /* for LJ_InvokeMethod */
- #define IMPLEMENT_netscape_applet_MozillaAppletContext
- #define IMPLEMENT_netscape_applet_EmbeddedObjectNatives
- #ifdef XP_MAC
- #include "n_applet_MozillaAppletContext.h"
- #include "n_a_EmbeddedObjectNatives.h"
- #else
- #include "netscape_applet_MozillaAppletContext.h"
- #include "netscape_applet_EmbeddedObjectNatives.h"
- #endif
- #include "jsjava.h"
- #include "jsobj.h"
- #include "prlog.h"
-
- extern PRLogModuleInfo* Moja;
- #define debug PR_LOG_DEBUG
- #define warn PR_LOG_WARN
-
- JSClass *lm_java_clasp = NULL;
-
- enum applet_array_slot {
- APPLET_ARRAY_LENGTH = -1
- };
-
- static JSPropertySpec applet_array_props[] = {
- {lm_length_str, APPLET_ARRAY_LENGTH,
- JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT},
- {0}
- };
-
- extern JSClass lm_applet_array_class;
-
- PR_STATIC_CALLBACK(JSBool)
- applet_array_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
- {
- JSObjectArray *array;
- MochaDecoder *decoder;
- MWContext *context;
- jsint count, slot;
- LO_JavaAppStruct *applet_data;
- int32 active_layer_id;
-
- if (!JSVAL_IS_INT(id))
- return JS_TRUE;
-
- slot = JSVAL_TO_INT(id);
-
- array = JS_GetInstancePrivate(cx, obj, &lm_applet_array_class, NULL);
- if (!array)
- return JS_TRUE;
- decoder = array->decoder;
- context = decoder->window_context;
-
- if (!context)
- return JS_TRUE;
-
- if (LM_MOJA_OK != ET_InitMoja(context))
- return JS_FALSE;
-
- LO_LockLayout();
-
- switch (slot) {
- case APPLET_ARRAY_LENGTH:
- active_layer_id = LM_GetActiveLayer(context);
- LM_SetActiveLayer(context, array->layer_id);
- count = LO_EnumerateApplets(context, array->layer_id);
- LM_SetActiveLayer(context, active_layer_id);
- if (count > array->length)
- array->length = count;
- *vp = INT_TO_JSVAL(array->length);
- break;
-
- default:
- if (slot < 0) {
- /* Don't mess with user-defined or method properties. */
- LO_UnlockLayout();
- return JS_TRUE;
- }
- applet_data = LO_GetAppletByIndex(context, array->layer_id,
- (uint)slot);
- if (applet_data) {
- JSObject *mo = LM_ReflectApplet(context, applet_data, NULL,
- array->layer_id, (uint)slot);
-
- if (!mo) {
- JS_ReportError(cx,
- "unable to reflect applet \"%s\", index %d - not loaded yet?",
- applet_data->attr_name, (uint) slot);
- goto err;
- }
- *vp = OBJECT_TO_JSVAL(mo);
-
- if (slot >= array->length)
- array->length = slot + 1;
- } else {
- JS_ReportError(cx, "no applet with index %d\n");
- goto err;
- }
- break;
- }
- LO_UnlockLayout();
- return JS_TRUE;
- err:
- LO_UnlockLayout();
- return JS_FALSE;
- }
-
- PR_STATIC_CALLBACK(void)
- applet_array_finalize(JSContext *cx, JSObject *obj)
- {
- JSObjectArray *array;
-
- array = JS_GetPrivate(cx, obj);
- if (!array)
- return;
- DROP_BACK_COUNT(array->decoder);
- JS_free(cx, array);
- }
-
- JSClass lm_applet_array_class = {
- "AppletArray", JSCLASS_HAS_PRIVATE,
- JS_PropertyStub, JS_PropertyStub,
- applet_array_getProperty, applet_array_getProperty, JS_EnumerateStub,
- JS_ResolveStub, JS_ConvertStub, applet_array_finalize
- };
-
- JSObject *
- lm_GetAppletArray(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->applets;
- 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_applet_array_class, NULL, document);
- if (!obj || !JS_SetPrivate(cx, obj, array)) {
- JS_free(cx, array);
- return NULL;
- }
-
- if (!JS_DefineProperties(cx, obj, applet_array_props))
- return NULL;
-
- array->decoder = HOLD_BACK_COUNT(decoder);
- array->length = 0;
- array->layer_id = doc->layer_id;
- doc->applets = obj;
-
- return obj;
- }
-
- static JSObject *
- lm_ReallyReflectApplet(MWContext *context, LO_JavaAppStruct *lo_applet,
- int32 layer_id, uint32 index)
- {
- JSObject *obj;
- MochaDecoder *decoder;
- JSContext *cx;
- LJAppletData *ad;
- jref japplet;
- lo_TopState *top_state;
- PRHashTable *map;
-
- PR_LOG(Moja, debug, ("really reflect applet 0x%x\n", lo_applet));
-
- obj = lo_applet->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_APPLETS, layer_id, index));
-
- if (obj) {
- lo_applet->mocha_object = obj;
- return obj;
- }
- }
-
- /* set the element to something bad if we can't get the java obj */
- if (!JSJ_IsEnabled()) {
- PR_LOG(Moja, debug, ("reflected applet 0x%x as null\n",
- lo_applet));
- return lo_applet->mocha_object = lm_DummyObject;
- }
-
- ad = (LJAppletData *) lo_applet->session_data;
-
- if (ad) {
- /* MozillaAppletContext.reflectApplet gets the java applet
- * object out of a hash table given the AppletData pointer
- * as an integer */
- if (ad->selector_type != LO_JAVA_SELECTOR_APPLET)
- japplet = LJ_InvokeMethod(classEmbeddedObjectNatives,
- methodID_netscape_applet_EmbeddedObjectNatives_reflectObject,
- ad->docID, ad);
- else
- japplet = LJ_InvokeMethod(classMozillaAppletContext,
- methodID_netscape_applet_MozillaAppletContext_reflectApplet_1,
- ad->docID, ad);
-
- obj = js_ReflectJObjectToJSObject(decoder->js_context,
- (HObject *)japplet);
-
- map = lm_GetIdToObjectMap(decoder);
- if (map)
- PR_HashTableAdd(map,
- LM_GET_MAPPING_KEY(LM_APPLETS, layer_id, index),
- obj);
-
- /*
- lj_mozilla_ee->js_context = saved_context;
- */
-
- PR_LOG(Moja, debug, ("reflected applet 0x%x (java 0x%x) to 0x%x ok\n",
- lo_applet, japplet, obj));
-
- if (obj)
- lm_java_clasp = JS_GetClass(obj);
- return lo_applet->mocha_object = obj;
- } else {
- PR_LOG(Moja, warn, ("failed to reflect applet 0x%x\n", lo_applet));
- return NULL;
- }
- }
-
-
- /* XXX what happens if this is called before java starts up?
- * or if java is disabled? */
-
- JSObject *
- LM_ReflectApplet(MWContext *context, LO_JavaAppStruct *applet_data,
- PA_Tag * tag, int32 layer_id, uint index)
- {
- JSObject *obj, *array_obj, *outer_obj, *document;
- MochaDecoder *decoder;
- JSContext *cx;
- char *name;
-
- obj = applet_data->mocha_object;
- if (obj)
- return obj;
-
- decoder = LM_GetMochaDecoder(context);
- if (!decoder)
- return NULL;
- cx = decoder->js_context;
-
- /* get the name */
- if (applet_data->attr_name) {
- name = JS_strdup(cx, (char *) applet_data->attr_name);
- } else {
- name = 0;
- }
-
- /* Get the document object that will hold this applet */
- document = lm_GetDocumentFromLayerId(decoder, layer_id);
- if (!document)
- goto out;
-
- array_obj = lm_GetAppletArray(decoder, document);
- if (!array_obj) {
- obj = 0;
- goto out;
- }
-
- /* XXX should pass thru ReallyReflectApplet to whatever calls NewObject */
- outer_obj = lm_GetOuterObject(decoder);
-
- /* this function does the real work */
- obj = lm_ReallyReflectApplet(context, applet_data, layer_id, index);
-
- if (!obj)
- /* reflection failed. this usually means that javascript tried
- * to talk to the applet before it was ready. there's not much
- * we can do about it */
- goto out;
-
- /* put it in the applet array */
- if (!lm_AddObjectToArray(cx, array_obj, name, index, obj)) {
- obj = NULL;
- goto out;
- }
-
- /* put it in the document scope */
- if (name) {
- if (!JS_DefineProperty(cx, outer_obj, name, OBJECT_TO_JSVAL(obj),
- NULL, NULL,
- JSPROP_ENUMERATE | JSPROP_READONLY)) {
- PR_LOG(Moja, warn, ("failed to define applet 0x%x as %s\n",
- applet_data, name));
- /* XXX remove it altogether? */
- }
- JS_free(cx, name);
- }
-
- /* cache it in layout data structure XXX lm_ReallyReflectApplet did this */
- XP_ASSERT(applet_data->mocha_object == obj);
-
- out:
- LM_PutMochaDecoder(decoder);
- return obj;
- }
-
- PRIVATE JSObject *
- LM_ReflectNamedApplet(MWContext *context, lo_NameList *name_rec,
- int32 layer_id, uint index)
- {
- return NULL;
- }
-
- #else
-
- void *lm_java_clasp = NULL;
-
- #endif /* JAVA */
-