Exemple #1
0
event_capturer_route_event(JSContext *cx, JSObject *obj,
			   uint argc, jsval *argv, jsval *rval)
{
    JSObject *eventObj;
    JSEvent *event;

    if (argc != 1)
	return JS_TRUE;

    if (!JSVAL_IS_OBJECT(argv[0]) &&
	!JS_ConvertValue(cx, argv[0], JSTYPE_OBJECT, &argv[0]))
	return JS_FALSE;

    eventObj = JSVAL_TO_OBJECT(argv[0]);
    if (!(event = JS_GetInstancePrivate (cx, eventObj, &lm_event_class, argv)))
	return JS_FALSE;

    /* Routing objects to themselves causes infinite recursion.
     * And that's a big no-no.
     */
    if (event->object == obj)
	return JS_TRUE;

    if (!event->object || !event->decoder || !event->decoder->window_context)
	return JS_TRUE;
    return lm_FindEventHandler(event->decoder->window_context,
			       event->object, eventObj, JSVAL_NULL,
			       rval);
}
Exemple #2
0
MAPID valueMap::addFunction(JS::HandleValue val)
{
    JS::RootedValue ns(g_cx);
    if (!JS_ConvertValue(g_cx, val, JSTYPE_FUNCTION, &ns))
        return 0;

    return add(ns, 8);
}
Exemple #3
0
loc_setProperty(JSContext *cx, JSObject *obj, jsval id,	jsval *vp)
{
    const char *url_string;
    JSString *str;
    jsval val;
    jsint slot;
    JSURL *url;

    if (!JSVAL_IS_INT(id))
	return JS_TRUE;

    slot = JSVAL_TO_INT(id);
    /* Setting these properties should not cause a FE_GetURL. */
    if (slot < 0 || slot == URL_TARGET)
        return url_setProperty(cx, obj, id, vp);

    /* Make sure vp is a string. */
    if (!JSVAL_IS_STRING(*vp) &&
	!JS_ConvertValue(cx, *vp, JSTYPE_STRING, vp)) {
	return JS_FALSE;
    }

    /* Two cases: setting href vs. setting a component property. */
    if (slot == URL_HREF || slot == URL_PROTOCOL) {
	/* Make sure the URL is absolute and sanity-check its protocol. */
	url_string = JS_GetStringBytes(JSVAL_TO_STRING(*vp));
	url_string = lm_CheckURL(cx, url_string, JS_TRUE);
	if (!url_string)
	    return JS_FALSE;
	str = JS_NewStringCopyZ(cx, url_string);
	XP_FREE((char *)url_string);
	if (!str)
	    return JS_FALSE;
	val = STRING_TO_JSVAL(str);
	vp = &val;
    } else {
	/* Get href from session history before setting a piece of it. */
	if (!loc_getProperty(cx, obj, INT_TO_JSVAL(URL_HREF), &val))
	    return JS_FALSE;
    }

    /* Set slot's property. */
    if (!url_setProperty(cx, obj, id, vp))
	return JS_FALSE;

    url = JS_GetPrivate(cx, obj);
    if (!url)
	return JS_TRUE;
    if (url->href)
        url_string = JS_GetStringBytes(url->href);
    else
	url_string = "";
    return url_load(cx, obj, url_string, NET_DONT_RELOAD);
}
Exemple #4
0
event_receiver_handle_event(JSContext *cx, JSObject *obj,
			    uint argc, jsval *argv, jsval *rval)
{
    JSObject *eventObj;

    if (argc != 1)
	return JS_TRUE;

    if (!JSVAL_IS_OBJECT(argv[0]) &&
	!JS_ConvertValue(cx, argv[0], JSTYPE_OBJECT, &argv[0]))
	return JS_FALSE;

    eventObj = JSVAL_TO_OBJECT(argv[0]);
    if (!JS_InstanceOf(cx, eventObj, &lm_event_class, argv))
	return JS_FALSE;

    return lm_HandleEvent(cx, obj, eventObj, JSVAL_NULL, rval);
}
Exemple #5
0
/*
 * Convert a JS value to a Java value of the given type signature.  The cost
 * variable is incremented if coercion is required, e.g. the source value is
 * a string, but the target type is a boolean.
 *
 * Returns JS_FALSE if no conversion is possible, either because the jsval has
 * a type that is wholly incompatible with the Java value, or because a scalar
 * jsval can't be represented in a variable of the target type without loss of
 * precision, e.g. the source value is "4.2" but the destination type is byte.
 * If conversion is not possible and java_value is non-NULL, the JS error
 * reporter is called with an appropriate message.
 */  
JSBool
jsj_ConvertJSValueToJavaValue(JSContext *cx, JNIEnv *jEnv, jsval v_arg,
                              JavaSignature *signature,
                              int *cost, jvalue *java_value, JSBool *is_local_refp)
{
    JavaSignatureChar type;
    jsval v;
    JSBool success = JS_FALSE;

    /* Initialize to default case, in which no new Java object is
       synthesized to perform the conversion and, therefore, no JNI local
       references are being held. */
    *is_local_refp = JS_FALSE;   
    
    type = signature->type;
    v = v_arg;
    switch (type) {
    case JAVA_SIGNATURE_BOOLEAN:
        if (!JSVAL_IS_BOOLEAN(v)) {
            if (!JS_ConvertValue(cx, v, JSTYPE_BOOLEAN, &v))
                goto conversion_error;
            if (JSVAL_IS_VOID(v))
                goto conversion_error;
            (*cost)++;
        }
        if (java_value)
            java_value->z = (jboolean)(JSVAL_TO_BOOLEAN(v) == JS_TRUE);
        break;

    case JAVA_SIGNATURE_SHORT:
        JSVAL_TO_INTEGRAL_JVALUE(short, s, jshort, v, java_value);
        break;

    case JAVA_SIGNATURE_BYTE:
        JSVAL_TO_INTEGRAL_JVALUE(byte, b, jbyte, v, java_value);
        break;

    case JAVA_SIGNATURE_CHAR:
        /* A one-character string can be converted into a character */
        if (JSVAL_IS_STRING(v) && (JS_GetStringLength(JSVAL_TO_STRING(v)) == 1)) {
            v = INT_TO_JSVAL(*JS_GetStringChars(JSVAL_TO_STRING(v)));
        }
        JSVAL_TO_INTEGRAL_JVALUE(char, c, jchar, v, java_value);
        break;

    case JAVA_SIGNATURE_INT:
        JSVAL_TO_INTEGRAL_JVALUE(int, i, jint, v, java_value);
        break;

    case JAVA_SIGNATURE_LONG:
#if defined(XP_MAC) || (defined(XP_OS2) && !defined(HAVE_LONG_LONG))
        JSVAL_TO_JLONG_JVALUE(j, jlong, v, java_value);
#else
        JSVAL_TO_INTEGRAL_JVALUE(long, j, jlong, v, java_value);
#endif
        break;
    
    case JAVA_SIGNATURE_FLOAT:
        if (!JSVAL_IS_NUMBER(v)) {
            if (!JS_ConvertValue(cx, v, JSTYPE_NUMBER, &v))
                goto conversion_error;
            (*cost)++;
        }
        if (java_value) {
            if (JSVAL_IS_INT(v))
                java_value->f = (jfloat) JSVAL_TO_INT(v);
            else
                java_value->f = (jfloat) *JSVAL_TO_DOUBLE(v);
        }
        break;

    case JAVA_SIGNATURE_DOUBLE:
        if (!JSVAL_IS_NUMBER(v)) {
            if (!JS_ConvertValue(cx, v, JSTYPE_NUMBER, &v))
                goto conversion_error;
            (*cost)++;
        }
        if (java_value) {
            if (JSVAL_IS_INT(v))
                java_value->d = (jdouble) JSVAL_TO_INT(v);
            else
                java_value->d = (jdouble) *JSVAL_TO_DOUBLE(v);
        }
        break;

    /* Non-primitive (reference) type */
    default:
        JS_ASSERT(IS_REFERENCE_TYPE(type));
        if (!jsj_ConvertJSValueToJavaObject(cx, jEnv, v, signature, cost,
            &java_value->l, is_local_refp))
            goto conversion_error;
        break;

    case JAVA_SIGNATURE_UNKNOWN:
    case JAVA_SIGNATURE_VOID:
        JS_ASSERT(0);
        return JS_FALSE;
    }

    /* Success */
    return JS_TRUE;

numeric_conversion_error:
    success = JS_TRUE;
    /* Fall through ... */

conversion_error:

    if (java_value) {
        const char *jsval_string;
        const char *class_name;
        JSString *jsstr;

        jsval_string = NULL;
        jsstr = JS_ValueToString(cx, v_arg);
        if (jsstr)
            jsval_string = JS_GetStringBytes(jsstr);
        if (!jsval_string)
            jsval_string = "";
        
        class_name = jsj_ConvertJavaSignatureToHRString(cx, signature);
        JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, 
                             JSJMSG_CANT_CONVERT_JS, jsval_string,
                             class_name);

        return JS_FALSE;
    }
    return success;
}
Exemple #6
0
/*
 * Convert a JS value to an instance of java.lang.Object or one of its subclasses, 
 * performing any necessary type coercion.  If non-trivial coercion is required,
 * the cost value is incremented.  If the java_value pass-by-reference argument
 * is non-NULL, the resulting Java value is stored there.
 *
 * Returns JS_TRUE if the conversion is possible, JS_FALSE otherwise
 */
JSBool
jsj_ConvertJSValueToJavaObject(JSContext *cx, JNIEnv *jEnv, jsval v, JavaSignature *signature,
                               int *cost, jobject *java_value, JSBool *is_local_refp)
{
    JSString *jsstr;
    jclass target_java_class;
    
    JS_ASSERT(IS_REFERENCE_TYPE(signature->type));

    /* Initialize to default case, in which no new Java object is
       synthesized to perform the conversion and, therefore, no JNI local
       references are being held. */
    *is_local_refp = JS_FALSE;

    /* Get the Java type of the target value */
    target_java_class = signature->java_class;
    
    if (JSVAL_IS_OBJECT(v)) {
        JSObject *js_obj = JSVAL_TO_OBJECT(v);
        
        /* JS null is always assignable to a Java object */
        if (!js_obj) {
            if (java_value)
                *java_value = NULL;
            return JS_TRUE;
        }
        
        if (JS_InstanceOf(cx, js_obj, &JavaObject_class, 0) ||
            JS_InstanceOf(cx, js_obj, &JavaArray_class, 0)) {
            
            /* The source value is a Java object wrapped inside a JavaScript
               object.  Unwrap the JS object and return the original Java
               object if it's class makes it assignment-compatible with the
               target class using Java's assignability rules. */
            JavaObjectWrapper *java_wrapper = JS_GetPrivate(cx, js_obj);
            jobject java_obj = java_wrapper->java_obj;
            
            if ((*jEnv)->IsInstanceOf(jEnv, java_obj, target_java_class)) {
                if (java_value)
                    *java_value = java_obj;
                return JS_TRUE;
            }
            
            /* Fall through, to attempt conversion to a Java string */
            
        } else if (JS_InstanceOf(cx, js_obj, &JavaClass_class, 0)) {
            /* We're dealing with the reflection of a Java class */
            JavaClassDescriptor *java_class_descriptor = JS_GetPrivate(cx, js_obj);
            
            /* Check if target type is java.lang.Class class */
            if ((*jEnv)->IsAssignableFrom(jEnv, jlClass, target_java_class)) {
                if (java_value)
                    *java_value = java_class_descriptor->java_class;
                return JS_TRUE;
            }
            
            /* Check if target type is netscape.javascript.JSObject wrapper class */
            if (convert_js_obj_to_JSObject_wrapper(cx, jEnv, js_obj, signature, cost, java_value)) {
                if (java_value && *java_value)
                    *is_local_refp = JS_TRUE;
                return JS_TRUE;
            }
            
            /* Fall through, to attempt conversion to a Java string */
            
        } else if (JS_InstanceOf(cx, js_obj, &JavaMember_class, 0)) {

            if (!JS_ConvertValue(cx, v, JSTYPE_OBJECT, &v))
                return JS_FALSE;
            return jsj_ConvertJSValueToJavaObject(cx, jEnv, v, signature, cost,
                                                  java_value, is_local_refp);

        /* JS Arrays are converted, element by element, to Java arrays */
        } else if (JS_IsArrayObject(cx, js_obj) && (signature->type == JAVA_SIGNATURE_ARRAY)) {
            if (convert_js_array_to_java_array(cx, jEnv, js_obj, signature, java_value)) {
                if (java_value && *java_value)
                    *is_local_refp = JS_TRUE;
                return JS_TRUE;
            }
            return JS_FALSE;

        } else {
            /* Otherwise, see if the target type is the  netscape.javascript.JSObject
               wrapper class or one of its subclasses, in which case a
               reference is passed to the original JS object by wrapping it
               inside an instance of netscape.javascript.JSObject */
            if (convert_js_obj_to_JSObject_wrapper(cx, jEnv, js_obj, signature, cost, java_value))             {
                if (java_value && *java_value)
                    *is_local_refp = JS_TRUE;
                return JS_TRUE;
            }
            
            /* Fall through, to attempt conversion to a Java string */
        }
        
    } else if (JSVAL_IS_NUMBER(v)) {
        /* JS numbers, integral or not, can be converted to instances of java.lang.Double */
        if ((*jEnv)->IsAssignableFrom(jEnv, jlDouble, target_java_class)) {
            if (java_value) {
                jsdouble d;
                if (!JS_ValueToNumber(cx, v, &d))
                    goto conversion_error;
                *java_value = (*jEnv)->NewObject(jEnv, jlDouble, jlDouble_Double, d);
                if (*java_value) {
                    *is_local_refp = JS_TRUE;
                } else {
                    jsj_UnexpectedJavaError(cx, jEnv,
                        "Couldn't construct instance of java.lang.Double");
                    return JS_FALSE;
                }
            }

            return JS_TRUE;
        }
        /* Fall through, to attempt conversion to a java.lang.String ... */
        
    } else if (JSVAL_IS_BOOLEAN(v)) {
        /* JS boolean values can be converted to instances of java.lang.Boolean */
        if ((*jEnv)->IsAssignableFrom(jEnv, jlBoolean, target_java_class)) {
            if (java_value) {
                JSBool b;
                if (!JS_ValueToBoolean(cx, v, &b))
                    goto conversion_error;
                *java_value =
                    (*jEnv)->NewObject(jEnv, jlBoolean, jlBoolean_Boolean, b);
                if (*java_value) {
                    *is_local_refp = JS_TRUE;
                } else {
                    jsj_UnexpectedJavaError(cx, jEnv, "Couldn't construct instance " 
                        "of java.lang.Boolean");
                    return JS_FALSE;
                }
            }

            return JS_TRUE;
        }
        /* Fall through, to attempt conversion to a java.lang.String ... */
    }
    
    /* If the source JS type is either a string or undefined, or if no conversion
       is possible from a number, boolean or JS object, see if the target type is
       java.lang.String */
    if ((*jEnv)->IsAssignableFrom(jEnv, jlString, target_java_class)) {
        
        /* Convert to JS string, if necessary, and then to a Java Unicode string */
        jsstr = JS_ValueToString(cx, v);
        if (jsstr) {
            if (java_value) {
                *java_value = jsj_ConvertJSStringToJavaString(cx, jEnv, jsstr);
                if (*java_value) {
                    *is_local_refp = JS_TRUE;
                } else {
                    return JS_FALSE;
                }
            }

            return JS_TRUE;
        }
    }
    
conversion_error:
    return JS_FALSE;
}
Exemple #7
0
url_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
    JSURL *url;
    const char *href, *name, *checked_href;
    char *new_href, *prop_name;
    JSBool free_href;
    jsval tmp;
    JSString *str;
    MWContext *context;
    LO_AnchorData *anchor_data;
    JSBool ok;
    jsint slot;

    url = JS_GetInstancePrivate(cx, obj, &lm_url_class, NULL);
    if (!url) {
	url = JS_GetInstancePrivate(cx, obj, &lm_location_class, NULL);
	if (!url)
	    return JS_TRUE;
    }

    /* If the property is setting an event handler we find out now so
     * that we can tell the front end to send the event.
     */
    if (JSVAL_IS_STRING(id)) {
	prop_name = JS_GetStringBytes(JSVAL_TO_STRING(id));
	if (XP_STRCASECMP(prop_name, lm_onClick_str) == 0 ||
	    XP_STRCASECMP(prop_name, lm_onMouseDown_str) == 0 ||
	    XP_STRCASECMP(prop_name, lm_onMouseOver_str) == 0 ||
	    XP_STRCASECMP(prop_name, lm_onMouseOut_str) == 0 ||
	    XP_STRCASECMP(prop_name, lm_onMouseUp_str) == 0) {
	    context = url->url_decoder->window_context;
	    if (context) {
		anchor_data = LO_GetLinkByIndex(context, url->layer_id,
						url->index);
		if (anchor_data)
		    anchor_data->event_handler_present = TRUE;
	    }
	}
	return JS_TRUE;
    }
	
    XP_ASSERT(JSVAL_IS_INT(id));
    slot = JSVAL_TO_INT(id);

    if (slot < 0) {
	/* Don't mess with user-defined or method properties. */
	return JS_TRUE;
    }

    if (!JSVAL_IS_STRING(*vp) &&
	!JS_ConvertValue(cx, *vp, JSTYPE_STRING, vp)) {
	return JS_FALSE;
    }

    ok = JS_TRUE;

    switch (slot) {
      case URL_HREF:
	url->href = JSVAL_TO_STRING(*vp);
	href = JS_GetStringBytes(url->href);
	free_href = JS_FALSE;
	break;

      case URL_PROTOCOL:
      case URL_HOST:
      case URL_HOSTNAME:
      case URL_PORT:
      case URL_PATHNAME:
      case URL_HASH:
      case URL_SEARCH:
	/* a component property changed -- recompute href. */
	new_href = NULL;

#define GET_SLOT(aslot, ptmp) {                                               \
    if (aslot == slot) {                                                      \
	*(ptmp) = *vp;                                                        \
    } else {                                                                  \
	if (!JS_GetElement(cx, obj, aslot, ptmp)) {                           \
	    if (new_href) XP_FREE(new_href);                                  \
	    return JS_FALSE;                                               \
	}                                                                     \
    }                                                                         \
}

#define ADD_SLOT(aslot, separator) {                                          \
    GET_SLOT(aslot, &tmp);                                                    \
    name = JS_GetStringBytes(JSVAL_TO_STRING(tmp));                           \
    if (*name) {                                                              \
	if (separator) StrAllocCat(new_href, separator);                      \
	StrAllocCat(new_href, name);                                          \
    }                                                                         \
}

	GET_SLOT(URL_PROTOCOL, &tmp);
	StrAllocCopy(new_href, JS_GetStringBytes(JSVAL_TO_STRING(tmp)));
	if (slot == URL_HOST) {
	    ADD_SLOT(URL_HOST, "//");
	} else {
	    ADD_SLOT(URL_HOSTNAME, "//");
	    ADD_SLOT(URL_PORT, ":");
	}
	ADD_SLOT(URL_PATHNAME, NULL);
	ADD_SLOT(URL_HASH, NULL);
	ADD_SLOT(URL_SEARCH, NULL);

	if (!new_href) {
	    JS_ReportOutOfMemory(cx);
	    return JS_FALSE;
	}

	free_href = JS_TRUE;
	href = new_href;
	str = JS_NewStringCopyZ(cx, href);
	if (!str) {
	    ok = JS_FALSE;
	    goto out;
	}
	url->href = str;
	break;

      case URL_TARGET:
	url->target = JSVAL_TO_STRING(*vp);
	if (url->index != URL_NOT_INDEXED) {
	    context = url->url_decoder->window_context;
	    if (context) {
		anchor_data = LO_GetLinkByIndex(context, url->layer_id,
                                                url->index);
		if (anchor_data) {
		    name = JS_GetStringBytes(url->target);
		    if (!lm_CheckWindowName(cx, name))
			return JS_FALSE;
		    if (!lm_SaveParamString(cx, &anchor_data->target, name))
			return JS_FALSE;
		}
	    }
	}
	/* Note early return, to bypass href update and freeing. */
	return JS_TRUE;

      default:
	/* Don't mess with a user-defined property. */
	return ok;
    }

    if (url->index != URL_NOT_INDEXED) {
	context = url->url_decoder->window_context;
	if (context) {
	    anchor_data = LO_GetLinkByIndex(context, url->layer_id, 
                                            url->index);
	    if (anchor_data) {
		checked_href = lm_CheckURL(cx, href, JS_FALSE);
		if (!checked_href ||
		    !lm_SaveParamString(cx, &anchor_data->anchor,
					checked_href)) {
		    ok = JS_FALSE;
		    goto out;
		}
		XP_FREE((char *)checked_href);
	    }
	}
    }

out:
    if (free_href && href)
	XP_FREE((char *)href);
    return ok;
}