Example #1
0
  static JSBool
  ChangeCase(JSContext* cx, JSString* src, jsval* rval,
             void(*changeCaseFnc)(const nsAString&, nsAString&))
  {
    nsDependentJSString depStr;
    if (!depStr.init(cx, src)) {
      return false;
    }

    nsAutoString result;
    changeCaseFnc(depStr, result);

    JSString *ucstr =
      JS_NewUCStringCopyN(cx, (jschar*)result.get(), result.Length());
    if (!ucstr) {
      return false;
    }

    *rval = STRING_TO_JSVAL(ucstr);

    return true;
  }
Example #2
0
/*
 * A utility routine to create a JavaScript Unicode string from a
 * java.lang.String (Unicode) string.
 */
JSString *
jsj_ConvertJavaStringToJSString(JSContext *cx, JNIEnv *jEnv, jstring java_str)
{
    JSString *js_str;
    jboolean is_copy;
    const jchar *ucs2_str;
    jsize ucs2_str_len;

    ucs2_str_len = (*jEnv)->GetStringLength(jEnv, java_str);
    ucs2_str = (*jEnv)->GetStringChars(jEnv, java_str, &is_copy);
    if (!ucs2_str) {
        jsj_UnexpectedJavaError(cx, jEnv,
                                "Unable to extract native Unicode from Java string");
        return NULL;
    }

    /* The string data passed into JS_NewUCString() is
       not copied, so make a copy of the Unicode character vector. */
    js_str = JS_NewUCStringCopyN(cx, ucs2_str, ucs2_str_len);

    (*jEnv)->ReleaseStringChars(jEnv, java_str, ucs2_str);
    return js_str;
}
Example #3
0
JSBool GetLastNetErrorMessage(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
{
	DWORD dwLastError = NERR_Success;
	HANDLE hModule = GetModuleHandle(NULL);
	if(argc < 1 || !JSVAL_IS_NUMBER(*argv))
	{
		JS_ReportError(cx, "Must provide valid error code to GetLastNetErrorMessage");
		return JS_FALSE;
	}

	JS_BeginRequest(cx);
	JS_ValueToECMAUint32(cx, *argv, &dwLastError);
	DWORD dwFormatFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_IGNORE_INSERTS |
        FORMAT_MESSAGE_FROM_SYSTEM ;

	if(dwLastError >= NERR_BASE && dwLastError <= MAX_NERR) 
	{
        hModule = LoadLibraryEx(TEXT("netmsg.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE);
        if(hModule != NULL)
            dwFormatFlags |= FORMAT_MESSAGE_FROM_HMODULE;
    }

	LPWSTR buffer = NULL;
	DWORD size = FormatMessage(dwFormatFlags, hModule, dwLastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&buffer, 0, NULL);
	if(size == 0)
	{
		*rval = JSVAL_FALSE;
		return JS_TRUE;
	}

	JSString * rString = JS_NewUCStringCopyN(cx, (jschar*)buffer, size);
	*rval = STRING_TO_JSVAL(rString);
	JS_EndRequest(cx);
	LocalFree(buffer);
	return JS_TRUE;
}
Example #4
0
void
EventSource::DispatchAllMessageEvents()
{
  if (mReadyState == CLOSED || mFrozen) {
    return;
  }

  mGoingToDispatchAllMessages = false;

  nsresult rv = CheckInnerWindowCorrectness();
  if (NS_FAILED(rv)) {
    return;
  }

  AutoJSAPI jsapi;
  if (NS_WARN_IF(!jsapi.Init(GetOwner()))) {
    return;
  }
  JSContext* cx = jsapi.cx();

  while (mMessagesToDispatch.GetSize() > 0) {
    nsAutoPtr<Message>
      message(static_cast<Message*>(mMessagesToDispatch.PopFront()));

    // Now we can turn our string into a jsval
    JS::Rooted<JS::Value> jsData(cx);
    {
      JSString* jsString;
      jsString = JS_NewUCStringCopyN(cx,
                                     message->mData.get(),
                                     message->mData.Length());
      NS_ENSURE_TRUE_VOID(jsString);

      jsData.setString(jsString);
    }

    // create an event that uses the MessageEvent interface,
    // which does not bubble, is not cancelable, and has no default action

    RefPtr<MessageEvent> event =
      NS_NewDOMMessageEvent(this, nullptr, nullptr);

    rv = event->InitMessageEvent(message->mEventName, false, false, jsData,
                                 mOrigin, message->mLastEventID, nullptr);
    if (NS_FAILED(rv)) {
      NS_WARNING("Failed to init the message event!!!");
      return;
    }

    event->SetTrusted(true);

    rv = DispatchDOMEvent(nullptr, static_cast<Event*>(event), nullptr,
                          nullptr);
    if (NS_FAILED(rv)) {
      NS_WARNING("Failed to dispatch the message event!!!");
      return;
    }

    mLastEventID.Assign(message->mLastEventID);
  }
}
Example #5
0
	// Clone a new value (and root it and add it to the mapping)
	jsval Clone(jsval val)
	{
		if (JSVAL_IS_DOUBLE(val))
		{
			jsval rval;
			CLONE_REQUIRE(JS_NewNumberValue(cxTo, JSVAL_TO_DOUBLE(val), &rval), L"JS_NewNumberValue");
			m_RooterTo.Push(rval);
			return rval;
		}

		if (JSVAL_IS_STRING(val))
		{
			size_t len;
			const jschar* chars = JS_GetStringCharsAndLength(cxFrom, JSVAL_TO_STRING(val), &len);
			CLONE_REQUIRE(chars, L"JS_GetStringCharsAndLength");
			JSString* str = JS_NewUCStringCopyN(cxTo, chars, len);
			CLONE_REQUIRE(str, L"JS_NewUCStringCopyN");
			jsval rval = STRING_TO_JSVAL(str);
			m_Mapping[JSVAL_TO_GCTHING(val)] = rval;
			m_RooterTo.Push(rval);
			return rval;
		}

		ENSURE(JSVAL_IS_OBJECT(val));

		JSObject* newObj;
		if (JS_IsArrayObject(cxFrom, JSVAL_TO_OBJECT(val)))
		{
			jsuint length;
			CLONE_REQUIRE(JS_GetArrayLength(cxFrom, JSVAL_TO_OBJECT(val), &length), L"JS_GetArrayLength");
			newObj = JS_NewArrayObject(cxTo, length, NULL);
			CLONE_REQUIRE(newObj, L"JS_NewArrayObject");
		}
		else
		{
			newObj = JS_NewObject(cxTo, NULL, NULL, NULL);
			CLONE_REQUIRE(newObj, L"JS_NewObject");
		}

		m_Mapping[JSVAL_TO_GCTHING(val)] = OBJECT_TO_JSVAL(newObj);
		m_RooterTo.Push(newObj);

		AutoJSIdArray ida (cxFrom, JS_Enumerate(cxFrom, JSVAL_TO_OBJECT(val)));
		CLONE_REQUIRE(ida.get(), L"JS_Enumerate");

		AutoGCRooter idaRooter(scriptInterfaceFrom);
		idaRooter.Push(ida.get());

		for (size_t i = 0; i < ida.length(); ++i)
		{
			jsid id = ida[i];
			jsval idval, propval;
			CLONE_REQUIRE(JS_IdToValue(cxFrom, id, &idval), L"JS_IdToValue");
			CLONE_REQUIRE(JS_GetPropertyById(cxFrom, JSVAL_TO_OBJECT(val), id, &propval), L"JS_GetPropertyById");
			jsval newPropval = GetOrClone(propval);

			if (JSVAL_IS_INT(idval))
			{
				// int jsids are portable across runtimes
				CLONE_REQUIRE(JS_SetPropertyById(cxTo, newObj, id, &newPropval), L"JS_SetPropertyById");
			}
			else if (JSVAL_IS_STRING(idval))
			{
				// string jsids are runtime-specific, so we need to copy the string content
				JSString* idstr = JS_ValueToString(cxFrom, idval);
				CLONE_REQUIRE(idstr, L"JS_ValueToString (id)");
				size_t len;
				const jschar* chars = JS_GetStringCharsAndLength(cxFrom, idstr, &len);
				CLONE_REQUIRE(idstr, L"JS_GetStringCharsAndLength (id)");
				CLONE_REQUIRE(JS_SetUCProperty(cxTo, newObj, chars, len, &newPropval), L"JS_SetUCProperty");
			}
			else
			{
				// this apparently could be an XML object; ignore it
			}
		}

		return OBJECT_TO_JSVAL(newObj);
	}
Example #6
0
/* implement toString() with an optional encoding arg */
static JSBool
to_string_func(JSContext *context,
               unsigned   argc,
               jsval     *vp)
{
    JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
    JSObject *object = JSVAL_TO_OBJECT(argv.thisv());
    ByteArrayInstance *priv;
    char *encoding;
    gboolean encoding_is_utf8;
    gchar *data;

    priv = priv_from_js(context, object);

    if (priv == NULL)
        return JS_TRUE; /* prototype, not instance */

    byte_array_ensure_array(priv);

    if (argc >= 1 &&
        JSVAL_IS_STRING(argv[0])) {
        if (!gjs_string_to_utf8(context, argv[0], &encoding))
            return JS_FALSE;

        /* maybe we should be smarter about utf8 synonyms here.
         * doesn't matter much though. encoding_is_utf8 is
         * just an optimization anyway.
         */
        if (strcmp(encoding, "UTF-8") == 0) {
            encoding_is_utf8 = TRUE;
            g_free(encoding);
            encoding = NULL;
        } else {
            encoding_is_utf8 = FALSE;
        }
    } else {
        encoding_is_utf8 = TRUE;
    }

    if (priv->array->len == 0)
        /* the internal data pointer could be NULL in this case */
        data = (gchar*)"";
    else
        data = (gchar*)priv->array->data;

    if (encoding_is_utf8) {
        /* optimization, avoids iconv overhead and runs
         * libmozjs hardwired utf8-to-utf16
         */
        jsval retval;
        JSBool ok;

        ok = gjs_string_from_utf8(context,
                                  data,
                                  priv->array->len,
                                  &retval);
        if (ok)
            argv.rval().set(retval);
        return ok;
    } else {
        JSBool ok = JS_FALSE;
        gsize bytes_written;
        GError *error;
        JSString *s;
        char *u16_str;

        error = NULL;
        u16_str = g_convert(data,
                           priv->array->len,
                           "UTF-16",
                           encoding,
                           NULL, /* bytes read */
                           &bytes_written,
                           &error);
        g_free(encoding);
        if (u16_str == NULL) {
            /* frees the GError */
            gjs_throw_g_error(context, error);
            return JS_FALSE;
        }

        /* bytes_written should be bytes in a UTF-16 string so
         * should be a multiple of 2
         */
        g_assert((bytes_written % 2) == 0);

        s = JS_NewUCStringCopyN(context,
                                (jschar*) u16_str,
                                bytes_written / 2);
        if (s != NULL) {
            ok = JS_TRUE;
            argv.rval().set(STRING_TO_JSVAL(s));
        }

        g_free(u16_str);
        return ok;
    }
}
nsresult
EventListenerManager::CompileEventHandlerInternal(Listener* aListener,
                                                  const nsAString* aBody,
                                                  Element* aElement)
{
  NS_PRECONDITION(aListener->GetJSListener(),
                  "Why do we not have a JS listener?");
  NS_PRECONDITION(aListener->mHandlerIsString,
                  "Why are we compiling a non-string JS listener?");

  nsresult result = NS_OK;

  nsIJSEventListener* jsListener = aListener->GetJSListener();
  NS_ASSERTION(!jsListener->GetHandler().HasEventHandler(),
               "What is there to compile?");

  nsCOMPtr<nsIDocument> doc;
  nsCOMPtr<nsIScriptGlobalObject> global =
    GetScriptGlobalAndDocument(getter_AddRefs(doc));
  NS_ENSURE_STATE(global);

  nsIScriptContext* context = global->GetScriptContext();
  NS_ENSURE_STATE(context);

  // Push a context to make sure exceptions are reported in the right place.
  AutoPushJSContext cx(context->GetNativeContext());
  JS::Rooted<JSObject*> handler(cx);

  JS::Rooted<JSObject*> scope(cx, jsListener->GetEventScope());

  nsCOMPtr<nsIAtom> typeAtom = aListener->mTypeAtom;
  nsIAtom* attrName = typeAtom;

  if (aListener->mHandlerIsString) {
    // OK, we didn't find an existing compiled event handler.  Flag us
    // as not a string so we don't keep trying to compile strings
    // which can't be compiled
    aListener->mHandlerIsString = false;

    // mTarget may not be an Element if it's a window and we're
    // getting an inline event listener forwarded from <html:body> or
    // <html:frameset> or <xul:window> or the like.
    // XXX I don't like that we have to reference content from
    // here. The alternative is to store the event handler string on
    // the nsIJSEventListener itself, and that still doesn't address
    // the arg names issue.
    nsCOMPtr<Element> element = do_QueryInterface(mTarget);
    MOZ_ASSERT(element || aBody, "Where will we get our body?");
    nsAutoString handlerBody;
    const nsAString* body = aBody;
    if (!aBody) {
      if (aListener->mTypeAtom == nsGkAtoms::onSVGLoad) {
        attrName = nsGkAtoms::onload;
      } else if (aListener->mTypeAtom == nsGkAtoms::onSVGUnload) {
        attrName = nsGkAtoms::onunload;
      } else if (aListener->mTypeAtom == nsGkAtoms::onSVGResize) {
        attrName = nsGkAtoms::onresize;
      } else if (aListener->mTypeAtom == nsGkAtoms::onSVGScroll) {
        attrName = nsGkAtoms::onscroll;
      } else if (aListener->mTypeAtom == nsGkAtoms::onSVGZoom) {
        attrName = nsGkAtoms::onzoom;
      } else if (aListener->mTypeAtom == nsGkAtoms::onbeginEvent) {
        attrName = nsGkAtoms::onbegin;
      } else if (aListener->mTypeAtom == nsGkAtoms::onrepeatEvent) {
        attrName = nsGkAtoms::onrepeat;
      } else if (aListener->mTypeAtom == nsGkAtoms::onendEvent) {
        attrName = nsGkAtoms::onend;
      }

      element->GetAttr(kNameSpaceID_None, attrName, handlerBody);
      body = &handlerBody;
      aElement = element;
    }
    aListener = nullptr;

    uint32_t lineNo = 0;
    nsAutoCString url (NS_LITERAL_CSTRING("-moz-evil:lying-event-listener"));
    MOZ_ASSERT(body);
    MOZ_ASSERT(aElement);
    nsIURI *uri = aElement->OwnerDoc()->GetDocumentURI();
    if (uri) {
      uri->GetSpec(url);
      lineNo = 1;
    }

    uint32_t argCount;
    const char **argNames;
    nsContentUtils::GetEventArgNames(aElement->GetNameSpaceID(),
                                     typeAtom,
                                     &argCount, &argNames);

    JSAutoCompartment ac(cx, context->GetWindowProxy());
    JS::CompileOptions options(cx);
    options.setIntroductionType("eventHandler")
           .setFileAndLine(url.get(), lineNo)
           .setVersion(SCRIPTVERSION_DEFAULT);

    JS::Rooted<JS::Value> targetVal(cx);
    // Go ahead and wrap into the current compartment of cx directly.
    JS::Rooted<JSObject*> wrapScope(cx, JS::CurrentGlobalOrNull(cx));
    if (WrapNewBindingObject(cx, wrapScope, aElement, &targetVal)) {
      MOZ_ASSERT(targetVal.isObject());

      nsDependentAtomString str(attrName);
      // Most of our names are short enough that we don't even have to malloc
      // the JS string stuff, so don't worry about playing games with
      // refcounting XPCOM stringbuffers.
      JS::Rooted<JSString*> jsStr(cx, JS_NewUCStringCopyN(cx,
                                                          str.BeginReading(),
                                                          str.Length()));
      NS_ENSURE_TRUE(jsStr, NS_ERROR_OUT_OF_MEMORY);

      options.setElement(&targetVal.toObject())
             .setElementAttributeName(jsStr);
    }

    JS::Rooted<JSObject*> handlerFun(cx);
    result = nsJSUtils::CompileFunction(cx, JS::NullPtr(), options,
                                        nsAtomCString(typeAtom),
                                        argCount, argNames, *body, handlerFun.address());
    NS_ENSURE_SUCCESS(result, result);
    handler = handlerFun;
    NS_ENSURE_TRUE(handler, NS_ERROR_FAILURE);
  } else {
    aListener = nullptr;
  }

  if (handler) {
    nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(mTarget);
    // Bind it
    JS::Rooted<JSObject*> boundHandler(cx);
    context->BindCompiledEventHandler(mTarget, scope, handler, &boundHandler);
    // Note - We pass null for aIncumbentGlobal below. We could also pass the
    // compilation global, but since the handler is guaranteed to be scripted,
    // there's no need to use an override, since the JS engine will always give
    // us the right answer.
    if (!boundHandler) {
      jsListener->ForgetHandler();
    } else if (jsListener->EventName() == nsGkAtoms::onerror && win) {
      nsRefPtr<OnErrorEventHandlerNonNull> handlerCallback =
        new OnErrorEventHandlerNonNull(boundHandler, /* aIncumbentGlobal = */ nullptr);
      jsListener->SetHandler(handlerCallback);
    } else if (jsListener->EventName() == nsGkAtoms::onbeforeunload && win) {
      nsRefPtr<OnBeforeUnloadEventHandlerNonNull> handlerCallback =
        new OnBeforeUnloadEventHandlerNonNull(boundHandler, /* aIncumbentGlobal = */ nullptr);
      jsListener->SetHandler(handlerCallback);
    } else {
      nsRefPtr<EventHandlerNonNull> handlerCallback =
        new EventHandlerNonNull(boundHandler, /* aIncumbentGlobal = */ nullptr);
      jsListener->SetHandler(handlerCallback);
    }
  }

  return result;
}
nsresult
EventListenerManager::CompileEventHandlerInternal(Listener* aListener,
                                                  const nsAString* aBody,
                                                  Element* aElement)
{
  MOZ_ASSERT(aListener->GetJSEventHandler());
  MOZ_ASSERT(aListener->mHandlerIsString, "Why are we compiling a non-string JS listener?");
  JSEventHandler* jsEventHandler = aListener->GetJSEventHandler();
  MOZ_ASSERT(!jsEventHandler->GetTypedEventHandler().HasEventHandler(),
             "What is there to compile?");

  nsresult result = NS_OK;
  nsCOMPtr<nsIDocument> doc;
  nsCOMPtr<nsIScriptGlobalObject> global =
    GetScriptGlobalAndDocument(getter_AddRefs(doc));
  NS_ENSURE_STATE(global);

  // Activate JSAPI, and make sure that exceptions are reported on the right
  // Window.
  AutoJSAPI jsapi;
  if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(global))) {
    return NS_ERROR_UNEXPECTED;
  }
  JSContext* cx = jsapi.cx();

  nsCOMPtr<nsIAtom> typeAtom = aListener->mTypeAtom;
  nsIAtom* attrName = typeAtom;

  // Flag us as not a string so we don't keep trying to compile strings which
  // can't be compiled.
  aListener->mHandlerIsString = false;

  // mTarget may not be an Element if it's a window and we're
  // getting an inline event listener forwarded from <html:body> or
  // <html:frameset> or <xul:window> or the like.
  // XXX I don't like that we have to reference content from
  // here. The alternative is to store the event handler string on
  // the JSEventHandler itself, and that still doesn't address
  // the arg names issue.
  nsCOMPtr<Element> element = do_QueryInterface(mTarget);
  MOZ_ASSERT(element || aBody, "Where will we get our body?");
  nsAutoString handlerBody;
  const nsAString* body = aBody;
  if (!aBody) {
    if (aListener->mTypeAtom == nsGkAtoms::onSVGLoad) {
      attrName = nsGkAtoms::onload;
    } else if (aListener->mTypeAtom == nsGkAtoms::onSVGUnload) {
      attrName = nsGkAtoms::onunload;
    } else if (aListener->mTypeAtom == nsGkAtoms::onSVGResize) {
      attrName = nsGkAtoms::onresize;
    } else if (aListener->mTypeAtom == nsGkAtoms::onSVGScroll) {
      attrName = nsGkAtoms::onscroll;
    } else if (aListener->mTypeAtom == nsGkAtoms::onSVGZoom) {
      attrName = nsGkAtoms::onzoom;
    } else if (aListener->mTypeAtom == nsGkAtoms::onbeginEvent) {
      attrName = nsGkAtoms::onbegin;
    } else if (aListener->mTypeAtom == nsGkAtoms::onrepeatEvent) {
      attrName = nsGkAtoms::onrepeat;
    } else if (aListener->mTypeAtom == nsGkAtoms::onendEvent) {
      attrName = nsGkAtoms::onend;
    }

    element->GetAttr(kNameSpaceID_None, attrName, handlerBody);
    body = &handlerBody;
    aElement = element;
  }
  aListener = nullptr;

  uint32_t lineNo = 0;
  nsAutoCString url (NS_LITERAL_CSTRING("-moz-evil:lying-event-listener"));
  MOZ_ASSERT(body);
  MOZ_ASSERT(aElement);
  nsIURI *uri = aElement->OwnerDoc()->GetDocumentURI();
  if (uri) {
    uri->GetSpec(url);
    lineNo = 1;
  }

  nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(mTarget);
  uint32_t argCount;
  const char **argNames;
  nsContentUtils::GetEventArgNames(aElement->GetNameSpaceID(),
                                   typeAtom, win,
                                   &argCount, &argNames);

  JSAddonId *addonId = MapURIToAddonID(uri);

  // Wrap the event target, so that we can use it as the scope for the event
  // handler. Note that mTarget is different from aElement in the <body> case,
  // where mTarget is a Window.
  //
  // The wrapScope doesn't really matter here, because the target will create
  // its reflector in the proper scope, and then we'll enter that compartment.
  JS::Rooted<JSObject*> wrapScope(cx, global->GetGlobalJSObject());
  JS::Rooted<JS::Value> v(cx);
  {
    JSAutoCompartment ac(cx, wrapScope);
    nsresult rv = nsContentUtils::WrapNative(cx, mTarget, &v,
                                             /* aAllowWrapping = */ false);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      return rv;
    }
  }
  if (addonId) {
    JS::Rooted<JSObject*> vObj(cx, &v.toObject());
    JS::Rooted<JSObject*> addonScope(cx, xpc::GetAddonScope(cx, vObj, addonId));
    if (!addonScope) {
      return NS_ERROR_FAILURE;
    }
    JSAutoCompartment ac(cx, addonScope);
    if (!JS_WrapValue(cx, &v)) {
      return NS_ERROR_FAILURE;
    }
  }
  JS::Rooted<JSObject*> target(cx, &v.toObject());
  JSAutoCompartment ac(cx, target);

  nsDependentAtomString str(attrName);
  // Most of our names are short enough that we don't even have to malloc
  // the JS string stuff, so don't worry about playing games with
  // refcounting XPCOM stringbuffers.
  JS::Rooted<JSString*> jsStr(cx, JS_NewUCStringCopyN(cx,
                                                      str.BeginReading(),
                                                      str.Length()));
  NS_ENSURE_TRUE(jsStr, NS_ERROR_OUT_OF_MEMORY);

  // Get the reflector for |aElement|, so that we can pass to setElement.
  if (NS_WARN_IF(!WrapNewBindingObject(cx, target, aElement, &v))) {
    return NS_ERROR_FAILURE;
  }
  JS::CompileOptions options(cx);
  options.setIntroductionType("eventHandler")
         .setFileAndLine(url.get(), lineNo)
         .setVersion(JSVERSION_DEFAULT)
         .setElement(&v.toObject())
         .setElementAttributeName(jsStr)
         .setDefineOnScope(false);

  JS::Rooted<JSObject*> handler(cx);
  result = nsJSUtils::CompileFunction(cx, target, options,
                                      nsAtomCString(typeAtom),
                                      argCount, argNames, *body, handler.address());
  NS_ENSURE_SUCCESS(result, result);
  NS_ENSURE_TRUE(handler, NS_ERROR_FAILURE);

  if (jsEventHandler->EventName() == nsGkAtoms::onerror && win) {
    nsRefPtr<OnErrorEventHandlerNonNull> handlerCallback =
      new OnErrorEventHandlerNonNull(handler, /* aIncumbentGlobal = */ nullptr);
    jsEventHandler->SetHandler(handlerCallback);
  } else if (jsEventHandler->EventName() == nsGkAtoms::onbeforeunload && win) {
    nsRefPtr<OnBeforeUnloadEventHandlerNonNull> handlerCallback =
      new OnBeforeUnloadEventHandlerNonNull(handler, /* aIncumbentGlobal = */ nullptr);
    jsEventHandler->SetHandler(handlerCallback);
  } else {
    nsRefPtr<EventHandlerNonNull> handlerCallback =
      new EventHandlerNonNull(handler, /* aIncumbentGlobal = */ nullptr);
    jsEventHandler->SetHandler(handlerCallback);
  }

  return result;
}
Example #9
0
/* Converts perl values to equivalent JS values */
JSBool
PJS_ReflectPerl2JS(
    pTHX_ 
    JSContext *cx,
    JSObject *pobj,
    SV *ref,
    jsval *rval
) {
    PJS_Context *pcx = PJS_GET_CONTEXT(cx);
    JSObject *newobj = NULL;

    if(++pcx->svconv % 2000 == 0) {
	JSErrorReporter older;
	ENTER; SAVETMPS; /* Scope for finalizers */
	older = JS_SetErrorReporter(cx, NULL);
	if(pcx->svconv > 10000) {
	    JS_GC(cx);
	    pcx->svconv = 0;
	} else JS_MaybeGC(cx);
	JS_SetErrorReporter(cx, older);
	FREETMPS; LEAVE;
    }
    if(SvROK(ref)) {
	MAGIC *mg;
	/* First check old jsvisitors */
	if((newobj = PJS_IsPerlVisitor(aTHX_ pcx, SvRV(ref)))) {
	    PJS_DEBUG("Old jsvisitor returns\n");
	    *rval = OBJECT_TO_JSVAL(newobj);
	    return JS_TRUE;
	}

	if(SvMAGICAL(SvRV(ref)) && (mg = mg_find(SvRV(ref), PERL_MAGIC_tied))
	   && mg->mg_obj && sv_derived_from(mg->mg_obj, PJS_BOXED_PACKAGE)) {
	    PJS_DEBUG1("A magical ref %s, shortcircuit!\n", SvPV_nolen((SV*)mg->mg_obj));
	    ref = mg->mg_obj;
	}

	if(sv_derived_from(ref, PJS_BOXED_PACKAGE)) {
	    SV **fref = av_fetch((AV *)SvRV(SvRV(ref)), 2, 0);
	    assert(sv_derived_from(*fref, PJS_RAW_JSVAL));
	    *rval = (jsval)SvIV(SvRV(*fref));
	    return JS_TRUE;
	}

	if(sv_derived_from(ref, PJS_BOOLEAN)) {
	    *rval = SvTRUE(SvRV(ref)) ? JSVAL_TRUE : JSVAL_FALSE;
	    return JS_TRUE;
	}
	
	if(sv_isobject(ref)) {
	    newobj = PJS_NewPerlObject(aTHX_ cx, pobj, ref); 
	    if(newobj) {
		*rval = OBJECT_TO_JSVAL(newobj);
		return JS_TRUE;
	    }
	    return JS_FALSE;
	}
    }

    SvGETMAGIC(ref);

    if(!SvOK(ref)) /* undef */
        *rval = JSVAL_VOID;
    else if(SvIOK(ref) || SvIOKp(ref)) {
        if(SvIV(ref) <= JSVAL_INT_MAX)
            *rval = INT_TO_JSVAL(SvIV(ref));
        else JS_NewDoubleValue(cx, (double) SvIV(ref), rval);
    }
    else if(SvNOK(ref)) 
        JS_NewDoubleValue(cx, SvNV(ref), rval);
    else if(SvPOK(ref) || SvPOKp(ref)) {
        STRLEN len;
        char *str;
	SV *temp=NULL;
	if(SvREADONLY(ref)) {
	    temp = newSVsv(ref);
	    str = PJS_SvPV(temp, len);
	} else str = PJS_SvPV(ref, len);
	JSString *jstr = ((int)len >= 0)
	    ? JS_NewStringCopyN(cx, str, len)
	    : JS_NewUCStringCopyN(cx, (jschar *)str, -(int)len);
	sv_free(temp);
	if(!jstr) return JS_FALSE;
        *rval = STRING_TO_JSVAL(jstr);
    }
    else if(SvROK(ref)) { /* Plain reference */
        I32 type = SvTYPE(SvRV(ref));

        if(type == SVt_PVHV)
	    newobj = PJS_NewPerlHash(aTHX_ cx, pobj, ref);
	else if(type == SVt_PVAV)
	    newobj = PJS_NewPerlArray(aTHX_ cx, pobj, ref);
        else if(type == SVt_PVCV)
            newobj = PJS_NewPerlSub(aTHX_ cx, pobj, ref);            
	else
	    newobj = PJS_NewPerlScalar(aTHX_ cx, pobj, ref);
	if(!newobj) return JS_FALSE;
	*rval = OBJECT_TO_JSVAL(newobj);
    }
    else {
        warn("I have no idea what perl send us (it's of type %i), I'll pretend it's undef", SvTYPE(ref));
        *rval = JSVAL_VOID;
    }

    return JS_TRUE;
}