Esempio n. 1
0
/*
 * call-seq:
 *   length()
 *
 * Returns the number of entries in the JavaScript array, or the number
 * of properties on the JavaScript object.
 */
static VALUE
length(VALUE self)
{
  RubyLandProxy* proxy;
  Data_Get_Struct(self, RubyLandProxy, proxy);
  JSContext * context = johnson_get_current_context(proxy->runtime);

  PREPARE_RUBY_JROOTS(context, 2);
  
  jsval proxy_value;
  JCHECK(get_jsval_for_proxy(proxy, &proxy_value));
  JROOT(proxy_value);

  JSObject* value = JSVAL_TO_OBJECT(proxy_value);
  JROOT(value);
  
  if (JS_IsArrayObject(context, value))
  {
    jsuint length;
    JCHECK(JS_GetArrayLength(context, value, &length));

    JRETURN_RUBY(INT2FIX(length));
  }
  else
  {
    JSIdArray* ids = JS_Enumerate(context, value);
    JCHECK(ids);
    VALUE length = INT2FIX(ids->length);
    
    JS_DestroyIdArray(context, ids);

    JRETURN_RUBY(length);
  }
}
Esempio n. 2
0
static void
add_multiopt(JSContext *cx, js_setting_t *jss, JSObject *optlist,
	     const char *vdef)
{
  JSIdArray *opts, *opt;
  int i;

  if((opts = JS_Enumerate(cx, optlist)) == NULL)
    return;
  
  for(i = 0; i < opts->length; i++) {
    jsval name, value;
    if(!JS_IdToValue(cx, opts->vector[i], &name) ||
       !JSVAL_IS_INT(name) ||
       !JS_GetElement(cx, optlist, JSVAL_TO_INT(name), &value) ||
       !JSVAL_IS_OBJECT(value) ||
       (opt = JS_Enumerate(cx, JSVAL_TO_OBJECT(value))) == NULL)
      continue;

    if(opt->length >= 2) {
    
      jsval id, title, def;
      
      if(JS_GetElement(cx, JSVAL_TO_OBJECT(value), 0, &id) &&
	 JS_GetElement(cx, JSVAL_TO_OBJECT(value), 1, &title)) {
	
	if(opt->length < 3 ||
	   !JS_GetElement(cx, JSVAL_TO_OBJECT(value), 2, &def))
	  def = JSVAL_FALSE;
	const char *k = JS_GetStringBytes(JS_ValueToString(cx, id));
	if(vdef)
	  def = !strcmp(k, vdef) ? JSVAL_TRUE : JSVAL_FALSE;
	
	settings_multiopt_add_opt_cstr(jss->jss_s, k,
				       JS_GetStringBytes(JS_ValueToString(cx, title)),
				       def == JSVAL_TRUE);
	
      }
    }
    JS_DestroyIdArray(cx, opt);
  }
  JS_DestroyIdArray(cx, opts);
}
Esempio n. 3
0
/**
 * Convert a JavaScript Object to a map
 *
 * @param cx the JavaScript context
 * @param t the JavaScript Object to convert
 * @return a new map containing the JavaScript Object
 */
map* mapFromJSObject(JSContext *cx,jsval t){
  map *res=NULL;
  JSIdArray *idp=JS_Enumerate(cx,JSVAL_TO_OBJECT(t));
#ifdef JS_DEBUG
  fprintf(stderr,"Properties %p\n",(void*)t);
#endif
  if(idp!=NULL) {
    int index;
    jsdouble argNum;
#ifdef JS_DEBUG
    fprintf(stderr,"Properties length :  %d \n",idp->length);
#endif
    for (index=0,argNum=idp->length;index<argNum;index++) { 
      jsval id = idp->vector[index];
      jsval vp;
      JS_IdToValue(cx,id,&vp);
      char *tmp, *tmp1;
      JSString *jsmsg,*jsmsg1;
      size_t len,len1;
      jsmsg = JS_ValueToString(cx,vp);
      len = JS_GetStringLength(jsmsg);
      jsval nvp;
      tmp=JS_EncodeString(cx,jsmsg);
      JS_GetProperty(cx, JSVAL_TO_OBJECT(t), tmp, &nvp);
      jsmsg1 = JS_ValueToString(cx,nvp);
      len1 = JS_GetStringLength(jsmsg1);
      tmp1=JS_EncodeString(cx,jsmsg1);
#ifdef JS_DEBUG
      fprintf(stderr,"Enumerate id : %d [ %s => %s ]\n",index,tmp,tmp1);
#endif
      if(strcasecmp(tmp,"child")!=0){
	if(res!=NULL){
#ifdef JS_DEBUG
	  fprintf(stderr,"%s - %s\n",tmp,tmp1);
#endif
	  addToMap(res,tmp,tmp1);
	}
	else{
	  res=createMap(tmp,tmp1);
	  res->next=NULL;
	}
      }
      free(tmp);
      free(tmp1);
#ifdef JS_DEBUG
      dumpMap(res);
#endif
    }
    JS_DestroyIdArray(cx,idp);
  }
#ifdef JS_DEBUG
  dumpMap(res);
#endif
  return res;
}
Esempio n. 4
0
    BSONObj toObject( JSObject * o , int depth = 0) {
        if ( ! o )
            return BSONObj();

        if ( JS_InstanceOf( _context , o , &bson_ro_class , 0 ) ) {
            BSONHolder * holder = GETHOLDER( _context , o );
            assert( holder );
            return holder->_obj.getOwned();
        }

        BSONObj orig;
        if ( JS_InstanceOf( _context , o , &bson_class , 0 ) ) {
            BSONHolder * holder = GETHOLDER(_context,o);
            assert( holder );
            if ( ! holder->_modified ) {
                return holder->_obj;
            }
            orig = holder->_obj;
        }

        BSONObjBuilder b;

        if ( ! appendSpecialDBObject( this , b , "value" , OBJECT_TO_JSVAL( o ) , o ) ) {

            if ( depth == 0 ) {
                jsval theid = getProperty( o , "_id" );
                if ( ! JSVAL_IS_VOID( theid ) ) {
                    append( b , "_id" , theid , EOO , depth + 1 );
                }
            }

            JSIdArray * properties = JS_Enumerate( _context , o );
            assert( properties );

            for ( jsint i=0; i<properties->length; i++ ) {
                jsid id = properties->vector[i];
                jsval nameval;
                assert( JS_IdToValue( _context ,id , &nameval ) );
                string name = toString( nameval );
                if ( depth == 0 && name == "_id" )
                    continue;

                append( b , name , getProperty( o , name.c_str() ) , orig[name].type() , depth + 1 );
            }

            JS_DestroyIdArray( _context , properties );
        }

        return b.obj();
    }
Esempio n. 5
0
int
js_prop_from_object(JSContext *cx, JSObject *obj, prop_t *p)
{
  JSIdArray *ida;
  int i, r = 0;
  const char *n;
  int array_zapped = 0;

  if((ida = JS_Enumerate(cx, obj)) == NULL)
    return -1;
  
  for(i = 0; i < ida->length; i++) {
    jsval name, value;

    if(!JS_IdToValue(cx, ida->vector[i], &name))
      continue;

    if(JSVAL_IS_STRING(name)) {
      n = JS_GetStringBytes(JSVAL_TO_STRING(name));
      if(!JS_GetProperty(cx, obj, n, &value))
	continue;
    } else if(JSVAL_IS_INT(name)) {
      if(!JS_GetElement(cx, obj, JSVAL_TO_INT(name), &value) ||
	 JSVAL_IS_VOID(value))
	continue;
      if(!array_zapped) {
	array_zapped = 1;
	prop_destroy_by_name(p, NULL);
      }
      n = NULL;
    } else {
      continue;
    }

    if(JSVAL_TO_OBJECT(value) == obj)
      continue;

    js_prop_set_from_jsval(cx, prop_create(p, n), value);
  }
  JS_DestroyIdArray(cx, ida);
  return r;
}
Esempio n. 6
0
static int
json_encode_from_object(JSContext *cx, JSObject *obj, htsbuf_queue_t *out)
{
  int objtype = 0;
  JSIdArray *ida;
  int i;
  const char *n;

  if((ida = JS_Enumerate(cx, obj)) == NULL)
    return -1;
  
  for(i = 0; i < ida->length; i++) {
    jsval name, value;

    if(!JS_IdToValue(cx, ida->vector[i], &name))
      continue;

    if(JSVAL_IS_STRING(name)) {
      JSString *str = JSVAL_TO_STRING(name);
      n = JS_GetStringBytes(str);
      if(!JS_GetProperty(cx, obj, n, &value))
	continue;

      if(objtype == 0) {
	htsbuf_append(out, "{", 1);
	objtype = OBJTYPE_MAP;
      } else if(objtype != OBJTYPE_MAP)
	continue;
      else
	htsbuf_append(out, ",", 1);
      htsbuf_append_and_escape_jsonstr(out, n);
      htsbuf_append(out, ":", 1);

    } else if(JSVAL_IS_INT(name)) {
      if(!JS_GetElement(cx, obj, JSVAL_TO_INT(name), &value) ||
	 JSVAL_IS_VOID(value))
	continue;

      if(objtype == 0) {
	htsbuf_append(out, "[", 1);
	objtype = OBJTYPE_LIST;
      } else if(objtype != OBJTYPE_LIST)
	continue;
      else
	htsbuf_append(out, ",", 1);
      
    } else {
      continue;
    }

    js_json_emit_jsval(cx, value, out);
  }
  JS_DestroyIdArray(cx, ida);

  switch(objtype) {
  case OBJTYPE_LIST:
    htsbuf_append(out, "]", 1);
    break;
  case OBJTYPE_MAP:
    htsbuf_append(out, "}", 1);
    break;
  default:
    return -1;
  }

  return 0;
}
Esempio n. 7
0
/**
 * Convert a JavaScript Object to a maps
 *
 * @param cx the JavaScript context
 * @param t the JavaScript Object to convert
 * @return a new maps containing the JavaScript Object
 */
maps* mapsFromJSObject(JSContext *cx,jsval t){
  maps *res=NULL;
  maps *tres=NULL;
  jsint oi=0;
  JSObject* tt=JSVAL_TO_OBJECT(t);
  if(JS_IsArrayObject(cx,tt)){
#ifdef JS_DEBUG
    fprintf(stderr,"Is finally an array !\n");
#endif
  }
  else{
#ifdef JS_DEBUG
    fprintf(stderr,"Is not an array !\n");
#endif
    JSIdArray *idp=JS_Enumerate(cx,tt);
    if(idp!=NULL) {
      int index;
      jsdouble argNum;
#ifdef JS_DEBUG
      fprintf(stderr,"Properties length :  %d \n",idp->length);
#endif
      
      for (index=0,argNum=idp->length;index<argNum;index++) { 
	jsval id = idp->vector[index];
	jsval vp;
	JS_IdToValue(cx,id,&vp);
	char *tmp;
	JSString *jsmsg;
	size_t len1;
	jsmsg = JS_ValueToString(cx,vp);
	len1 = JS_GetStringLength(jsmsg);
	
	tmp=JS_EncodeString(cx,jsmsg);
	tres=createMaps(tmp);

	jsval nvp=JSVAL_NULL;
	if((JS_GetProperty(cx, tt, tmp, &nvp)==JS_FALSE)){
#ifdef JS_DEBUG
	  fprintf(stderr,"Enumerate id : %d => %s => No more value\n",oi,tmp);
#endif
	}
	free(tmp);
	JSObject *nvp1=JSVAL_TO_OBJECT(JSVAL_NULL);
	JS_ValueToObject(cx,nvp,&nvp1);
	jsval nvp1j=OBJECT_TO_JSVAL(nvp1);
	if(JSVAL_IS_OBJECT(nvp1j)){
	  tres->content=mapFromJSObject(cx,nvp1j);
	}

	jsval nvp0=JSVAL_NULL;
	JSObject *nvp01=JSVAL_TO_OBJECT(JSVAL_NULL);
	if((JS_GetProperty(cx, nvp1, "child", &nvp0)==JS_FALSE)){
#ifdef JS_DEBUG
	  fprintf(stderr,"Enumerate id : %d => %s => No more value\n",oi,tmp);
#endif
	}
	JS_ValueToObject(cx,nvp0,&nvp01);
	jsval nvp01j=OBJECT_TO_JSVAL(nvp01);
	if(!JSVAL_IS_NULL(nvp01j)){
	  tres->child=mapsFromJSObject(cx,nvp01j);
	}

	if(res==NULL)
	  res=dupMaps(&tres);
	else
	  addMapsToMaps(&res,tres);
	freeMaps(&tres);
	free(tres);
	tres=NULL;
      }
      JS_DestroyIdArray(cx,idp);
    }
  }

  jsuint len;
  JSBool hasLen=JS_GetArrayLength(cx, tt, &len);
#ifdef JS_DEBUG
  if(hasLen==JS_FALSE){
    fprintf(stderr,"outputs array is empty\n");
  }
  fprintf(stderr,"outputs array length : %d\n",len);
#endif
  for(oi=0;hasLen && oi < len;oi++){
#ifdef JS_DEBUG
    fprintf(stderr,"outputs array length : %d step %d \n",len,oi);
#endif
    jsval tmp1;
    JSBool hasElement=JS_GetElement(cx,tt,oi,&tmp1);
    JSObject *otmp1=JSVAL_TO_OBJECT(tmp1);
    JSIdArray *idp=JS_Enumerate(cx,otmp1);
    if(idp!=NULL) {
      int index;
      jsdouble argNum;
#ifdef JS_DEBUG
      fprintf(stderr,"Properties length :  %d \n",idp->length);
#endif
      tres=(maps*)malloc(MAPS_SIZE);
      tres->name=NULL;
      tres->content=NULL;
      tres->next=NULL;

      for (index=0,argNum=idp->length;index<argNum;index++) { 
	jsval id = idp->vector[index];
	jsval vp;
	JS_IdToValue(cx,id,&vp);
	char *tmp;
	JSString *jsmsg;
	size_t len1;
	jsmsg = JS_ValueToString(cx,vp);
	len1 = JS_GetStringLength(jsmsg);
	tmp=JS_EncodeString(cx,jsmsg);
#ifdef JS_DEBUG
	fprintf(stderr,"Enumerate id : %d => %s\n",oi,tmp);
#endif
	jsval nvp=JSVAL_NULL;
	if((JS_GetProperty(cx, JSVAL_TO_OBJECT(tmp1), tmp, &nvp)==JS_FALSE)){
#ifdef JS_DEBUG
	  fprintf(stderr,"Enumerate id : %d => %s => No more value\n",oi,tmp);
#endif
	}
	free(tmp);
	if(JSVAL_IS_OBJECT(nvp)){
#ifdef JS_DEBUG
	  fprintf(stderr,"JSVAL NVP IS OBJECT\n");
#endif
	}

	JSObject *nvp1=JSVAL_TO_OBJECT(JSVAL_NULL);
	JS_ValueToObject(cx,nvp,&nvp1);
	jsval nvp1j=OBJECT_TO_JSVAL(nvp1);
	if(JSVAL_IS_OBJECT(nvp1j)){
	  JSString *jsmsg1;
	  char *tmp1, *tmp2;
	  JSObject *nvp2=JSVAL_TO_OBJECT(JSVAL_NULL);
	  jsmsg1 = JS_ValueToString(cx,nvp1j);
	  len1 = JS_GetStringLength(jsmsg1);
	  tmp1=JS_EncodeString(cx,jsmsg1);
	  tmp2=JS_EncodeString(cx,jsmsg);
#ifdef JS_DEBUG
	  fprintf(stderr,"JSVAL NVP1J IS OBJECT %s = %s\n",JS_EncodeString(cx,jsmsg),tmp1);
#endif
	  if(strcasecmp(tmp1,"[object Object]")==0){
	    tres->name=zStrdup(tmp2);
	    tres->content=mapFromJSObject(cx,nvp1j);
	  }
	  else
	    if(strcasecmp(tmp2,"name")==0){
	      tres->name=zStrdup(tmp1);
	    }
	    else{
	      if(tres->content==NULL)
		tres->content=createMap(tmp2,tmp1);
	      else
		addToMap(tres->content,tmp2,tmp1);
	    }
	  free(tmp1);
	  free(tmp2);
	}
#ifdef JS_DEBUG
	else
	  fprintf(stderr,"JSVAL NVP1J IS NOT OBJECT !!\n");
#endif
      }
#ifdef JS_DEBUG
      dumpMaps(tres);
#endif
      if(res==NULL)
	res=dupMaps(&tres);
      else
	addMapsToMaps(&res,tres);
      freeMaps(&tres);
      free(tres);
      tres=NULL;
      JS_DestroyIdArray(cx,idp);
    }
  }
#ifdef JS_DEBUG
  dumpMaps(res);
#endif
  return res;
}
Esempio n. 8
0
static JSBool 
js_createMultiOpt(JSContext *cx, JSObject *obj, uintN argc, 
		  jsval *argv, jsval *rval)
{
  js_setting_group_t *jsg = JS_GetPrivate(cx, obj);
  const char *id;
  const char *title;
  JSObject *func;
  JSObject *optlist;
  JSBool persistent = JS_FALSE;

  if(!JS_ConvertArguments(cx, argc, argv, "ssoo/b",
			  &id, &title, &optlist, &func, &persistent))
    return JS_FALSE;

  js_setting_t *jss = jss_create(cx, obj, id, rval, func, jsg, persistent);
  if(jss == NULL)
    return JS_FALSE;

  char **options = NULL;
  JSIdArray *opts, *opt;
  int i;

  char *defvalue = NULL;

  if((opts = JS_Enumerate(cx, optlist)) != NULL) {

    for(i = 0; i < opts->length; i++) {
      jsval name, value, id, title, def;
      if(!JS_IdToValue(cx, opts->vector[i], &name) ||
         !JSVAL_IS_INT(name) ||
         !JS_GetElement(cx, optlist, JSVAL_TO_INT(name), &value) ||
         !JSVAL_IS_OBJECT(value) ||
         (opt = JS_Enumerate(cx, JSVAL_TO_OBJECT(value))) == NULL)
        continue;

      if(opt->length >= 2 &&
         JS_GetElement(cx, JSVAL_TO_OBJECT(value), 0, &id) &&
         JS_GetElement(cx, JSVAL_TO_OBJECT(value), 1, &title)) {

        if(opt->length < 3 ||
           !JS_GetElement(cx, JSVAL_TO_OBJECT(value), 2, &def))
          def = JSVAL_FALSE;

        const char *k = JS_GetStringBytes(JS_ValueToString(cx, id));

        if(def == JSVAL_TRUE)
          mystrset(&defvalue, k);

        strvec_addp(&options, k);
        strvec_addp(&options, JS_GetStringBytes(JS_ValueToString(cx, title)));
      }
      JS_DestroyIdArray(cx, opt);
    }
    JS_DestroyIdArray(cx, opts);
  }

  rstr_t *r = NULL;
  if(persistent && jsg->jsg_kv_url)
    r = kv_url_opt_get_rstr(jsg->jsg_kv_url, KVSTORE_DOMAIN_PLUGIN, id);


  jss->jss_s =
    setting_create(SETTING_MULTIOPT, jsg->jsg_root,
                   SETTINGS_INITIAL_UPDATE | jsg->jsg_settings_flags,
                   SETTING_TITLE_CSTR(title),
                   SETTING_COURIER(js_global_pc),
                   SETTING_CALLBACK(js_store_update_string, jss),
                   SETTING_VALUE(r ? rstr_get(r) : defvalue),
                   SETTING_OPTION_LIST(options),
                   SETTING_HTSMSG_CUSTOM_SAVER(id, jsg->jsg_store,
                                               js_setting_group_save, jsg),
                   NULL);

  strvec_free(options);
  rstr_release(r);
  jss->jss_cx = NULL;
  return JS_TRUE;
}
Esempio n. 9
0
static void
destroy_id_array(JSContext* context, void* data)
{
  JS_DestroyIdArray(context, (JSIdArray*)data);
}
//
// Native method Install
//
static JSBool
InstallTriggerGlobalInstall(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
  nsIDOMInstallTriggerGlobal *nativeThis = getTriggerNative(cx, obj);
  if (!nativeThis)
    return JS_FALSE;

  *rval = JSVAL_FALSE;

  // make sure XPInstall is enabled, return false if not
  nsIScriptGlobalObject *globalObject = nsnull;
  nsIScriptContext *scriptContext = GetScriptContextFromJSContext(cx);
  if (scriptContext)
    globalObject = scriptContext->GetGlobalObject();

  if (!globalObject)
      return JS_TRUE;

  nsCOMPtr<nsIScriptSecurityManager> secman(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID));
  if (!secman)
  {
    JS_ReportError(cx, "Could not the script security manager service.");
    return JS_FALSE;
  }
  // get the principal.  if it doesn't exist, die.
  nsCOMPtr<nsIPrincipal> principal;
  secman->GetSubjectPrincipal(getter_AddRefs(principal));
  if (!principal)
  {
    JS_ReportError(cx, "Could not get the Subject Principal during InstallTrigger.Install()");
    return JS_FALSE;
  }

  // get window.location to construct relative URLs
  nsCOMPtr<nsIURI> baseURL;
  JSObject* global = JS_GetGlobalObject(cx);
  if (global)
  {
    jsval v;
    if (JS_GetProperty(cx,global,"location",&v))
    {
      nsAutoString location;
      ConvertJSValToStr( location, cx, v );
      NS_NewURI(getter_AddRefs(baseURL), location);
    }
  }

  PRBool abortLoad = PR_FALSE;

  // parse associative array of installs
  if ( argc >= 1 && JSVAL_IS_OBJECT(argv[0]) && JSVAL_TO_OBJECT(argv[0]) )
  {
    nsXPITriggerInfo *trigger = new nsXPITriggerInfo();
    if (!trigger)
      return JS_FALSE;

    trigger->SetPrincipal(principal);

    JSIdArray *ida = JS_Enumerate( cx, JSVAL_TO_OBJECT(argv[0]) );
    if ( ida )
    {
      jsval v;
      const PRUnichar *name, *URL;
      const PRUnichar *iconURL = nsnull;

      for (int i = 0; i < ida->length && !abortLoad; i++ )
      {
        JS_IdToValue( cx, ida->vector[i], &v );
        JSString * str = JS_ValueToString( cx, v );
        if (!str)
        {
          abortLoad = PR_TRUE;
          break;
        }

        name = reinterpret_cast<const PRUnichar*>(JS_GetStringChars( str ));

        URL = iconURL = nsnull;
        JSAutoByteString hash;
        JS_GetUCProperty( cx, JSVAL_TO_OBJECT(argv[0]), reinterpret_cast<const jschar*>(name), nsCRT::strlen(name), &v );
        if ( JSVAL_IS_OBJECT(v) && JSVAL_TO_OBJECT(v) )
        {
          jsval v2;
          if (JS_GetProperty( cx, JSVAL_TO_OBJECT(v), "URL", &v2 ) && !JSVAL_IS_VOID(v2)) {
            JSString *str = JS_ValueToString(cx, v2);
            if (!str) {
              abortLoad = PR_TRUE;
              break;
            }
            URL = reinterpret_cast<const PRUnichar*>(JS_GetStringChars(str));
          }

          if (JS_GetProperty( cx, JSVAL_TO_OBJECT(v), "IconURL", &v2 ) && !JSVAL_IS_VOID(v2)) {
            JSString *str = JS_ValueToString(cx, v2);
            if (!str) {
              abortLoad = PR_TRUE;
              break;
            }
            iconURL = reinterpret_cast<const PRUnichar*>(JS_GetStringChars(str));
          }

          if (JS_GetProperty( cx, JSVAL_TO_OBJECT(v), "Hash", &v2) && !JSVAL_IS_VOID(v2)) {
            JSString *str = JS_ValueToString(cx, v2);
            if (!str || !hash.encode(cx, str)) {
              abortLoad = PR_TRUE;
              break;
            }
          }
        }
        else
        {
          JSString *str = JS_ValueToString(cx, v);
          if (!str) {
            abortLoad = PR_TRUE;
            break;
          }
          URL = reinterpret_cast<const PRUnichar*>(JS_GetStringChars(str));
        }

        if ( URL )
        {
            // Get relative URL to load
            nsAutoString xpiURL(URL);
            if (baseURL)
            {
                nsCAutoString resolvedURL;
                baseURL->Resolve(NS_ConvertUTF16toUTF8(xpiURL), resolvedURL);
                xpiURL = NS_ConvertUTF8toUTF16(resolvedURL);
            }

            nsAutoString icon(iconURL);
            if (iconURL && baseURL)
            {
                nsCAutoString resolvedIcon;
                baseURL->Resolve(NS_ConvertUTF16toUTF8(icon), resolvedIcon);
                icon = NS_ConvertUTF8toUTF16(resolvedIcon);
            }

            // Make sure we're allowed to load this URL and the icon URL
            nsresult rv = InstallTriggerCheckLoadURIFromScript(cx, xpiURL);
            if (NS_FAILED(rv))
                abortLoad = PR_TRUE;

            if (!abortLoad && iconURL)
            {
                rv = InstallTriggerCheckLoadURIFromScript(cx, icon);
                if (NS_FAILED(rv))
                    abortLoad = PR_TRUE;
            }

            if (!abortLoad)
            {
                // Add the install item to the trigger collection
                nsXPITriggerItem *item =
                    new nsXPITriggerItem( name, xpiURL.get(), icon.get(), hash );
                if ( item )
                {
                    trigger->Add( item );
                }
                else
                    abortLoad = PR_TRUE;
            }
        }
        else
            abortLoad = PR_TRUE;
      }
      JS_DestroyIdArray( cx, ida );
    }


    // pass on only if good stuff found
    if (!abortLoad && trigger->Size() > 0)
    {
        nsCOMPtr<nsIURI> checkuri;
        nsresult rv = nativeThis->GetOriginatingURI(globalObject,
                                                    getter_AddRefs(checkuri));
        if (NS_SUCCEEDED(rv))
        {
            nsCOMPtr<nsIDOMWindowInternal> win(do_QueryInterface(globalObject));
            nsCOMPtr<nsIXPIInstallInfo> installInfo =
                new nsXPIInstallInfo(win, checkuri, trigger, 0);
            if (installInfo)
            {
                // installInfo now owns triggers
                PRBool enabled = PR_FALSE;
                nativeThis->UpdateEnabled(checkuri, XPI_WHITELIST, &enabled);
                if (!enabled)
                {
                    nsCOMPtr<nsIObserverService> os =
                      mozilla::services::GetObserverService();
                    if (os)
                        os->NotifyObservers(installInfo,
                                            "xpinstall-install-blocked",
                                            nsnull);
                }
                else
                {
                    // save callback function if any (ignore bad args for now)
                    if ( argc >= 2 && JS_TypeOfValue(cx,argv[1]) == JSTYPE_FUNCTION )
                    {
                        trigger->SaveCallback( cx, argv[1] );
                    }

                    PRBool result;
                    nativeThis->StartInstall(installInfo, &result);
                    *rval = BOOLEAN_TO_JSVAL(result);
                }
                return JS_TRUE;
            }
        }
    }
    // didn't pass it on so we must delete trigger
    delete trigger;
  }

  JS_ReportError(cx, "Incorrect arguments to InstallTrigger.Install()");
  return JS_FALSE;
}