Example #1
0
	void HTTPClientBinding::Open(const ValueList& args, SharedValue result)
	{
		if (args.size()<2)
		{
			throw ValueException::FromString("invalid arguments");
		}
		this->method = args.at(0)->ToString();
		this->url = args.at(1)->ToString();
		if (args.size()>=3)
		{
			GET_BOOL_PROP(args.at(2),this->async)
		}
		if (args.size()>=4)
		{
			this->user = args.at(3)->ToString();
		}
		if (args.size()>4)
		{
			this->password = args.at(4)->ToString();
		}
		// assign it here (helps prevent deadlock)
		SharedValue v = this->Get("onreadystatechange");
		if (v->IsMethod())
		{
			this->readystate = v->ToMethod();
		}
		SharedValue vc = this->Get("onchange");
		if (vc->IsMethod())
		{
			this->onchange = vc->ToMethod();
		}
		this->ChangeState(1); // opened
	}
Example #2
0
HRESULT STDMETHODCALLTYPE
ScriptEvaluator::evaluate(BSTR mimeType, BSTR sourceCode, int *context)
{
	std::string type = BSTRToString(mimeType);
	std::string moduleName = GetModuleName(type);
	JSContextRef contextRef = reinterpret_cast<JSContextRef>(context);

	SharedKObject global = host->GetGlobalObject();

	SharedValue moduleValue = global->Get(moduleName.c_str());
	if (!moduleValue->IsNull()) {
		SharedValue evalValue = moduleValue->ToObject()->Get("evaluate");
		if (!evalValue->IsNull() && evalValue->IsMethod()) {
			ValueList args;
			SharedValue typeValue = Value::NewString(type);
			SharedValue sourceCodeValue = Value::NewString(BSTRToString(sourceCode));
			JSObjectRef globalObjectRef = JSContextGetGlobalObject(contextRef);
			SharedKObject contextObject = new KKJSObject(contextRef, globalObjectRef);
			SharedValue contextValue = Value::NewObject(contextObject);
			args.push_back(typeValue);
			args.push_back(sourceCodeValue);
			args.push_back(contextValue);

			evalValue->ToMethod()->Call(args);
		}
	}

	return S_OK;
}
	void WorkerContext::SendQueuedMessages()
	{
		Logger *logger = Logger::Get("WorkerContext");
		logger->Debug("SendQueuedMessages called");
		
		SharedValue onmessage = worker->Get("onmessage");
		Poco::ScopedLock<Poco::Mutex> lock(mutex);
		if (onmessage->IsMethod())
		{
			if (messages.size()>0)
			{
				std::list<SharedValue>::iterator i = messages.begin();
				while(i!=messages.end())
				{
					SharedValue v = (*i++);
					ValueList _args;
					string name = "worker.message";
					AutoPtr<KEventObject> target = this;
					this->duplicate();
					AutoPtr<Event> event = new Event(target, name);
					event->Set("message", v);
					_args.push_back(Value::NewObject(event));
					host->InvokeMethodOnMainThread(onmessage->ToMethod(),_args,false);
				}
				messages.clear();
			}
		}
	}
Example #4
0
	SharedKMethod KObject::GetMethod(const char* name, SharedKMethod defaultValue)
	{
		SharedValue prop = this->Get(name);
		if (prop->IsMethod())
		{
			return prop->ToMethod();
		}
		else
		{
			return defaultValue;
		}
	}
Example #5
0
	bool KKJSList::Remove(unsigned int index)
	{
		if (index >= 0 && index < this->Size())
		{
			SharedValue spliceMethod = this->kjs_bound_object->Get("splice");
			spliceMethod->ToMethod()->Call(
				Value::NewInt(index),
				Value::NewInt(1));
			return true;
		}
		return false;
	}
Example #6
0
void Win32Process::InvokeOnExit()
{
    SharedValue sv = this->Get("onexit");
    if (!sv->IsMethod())
    {
        return;
    }

    ValueList args(Value::NewInt(this->exitCode));
    SharedKMethod callback = sv->ToMethod();
    this->parent->GetHost()->InvokeMethodOnMainThread(
        callback, args, false);
}
Example #7
0
	SharedValue AccessorBoundList::Get(const char *name)
	{
		std::string getter_name = "get" + Capitalize(name);
		SharedValue v = this->RawGet(getter_name.c_str());
		if (v->IsMethod())
		{
			SharedKMethod m = v->ToMethod();
			return m->Call(ValueList());
		}
		else
		{
			return this->RawGet(name);
		}
	}
	// this method creates the native menu objects for *this* menu item
	Win32MenuItemImpl::NativeMenuItem* Win32MenuItemImpl::MakeNativeMenuItem(NativeMenuItem* parent_menu_item, bool is_menu_bar)
	{
		NativeMenuItem* menu_item = new NativeMenuItem();

		if(parent_menu_item)
		{
			menu_item->parent_menu = parent_menu_item->menu;
		}

		const char* label = this->GetLabel();
		const char* iconUrl = this->GetIconURL();
		SharedString iconPath = UIModule::GetResourcePath(iconUrl);
		SharedValue callbackVal = this->RawGet("callback");

		if (this->parent == NULL) // top-level
		{
			if (is_menu_bar)
				menu_item->menu = CreateMenu();
			else
				menu_item->menu = CreatePopupMenu();
		}
		else if(this->IsSeparator())
		{
			AppendMenu(menu_item->parent_menu, MF_SEPARATOR, 1, "Separator");
		}
		else if(this->IsItem())
		{
			menu_item->menuItemID = nextMenuUID();
			AppendMenu(menu_item->parent_menu, MF_STRING, menu_item->menuItemID, (LPCTSTR) label);

			if (callbackVal->IsMethod())
			{
				menu_item->callback = callbackVal->ToMethod();

				itemsWithCallbacks.push_back(menu_item);
			}
		}
		else if(this->IsSubMenu())
		{
			menu_item->menu = CreatePopupMenu();
			AppendMenu(menu_item->parent_menu, MF_STRING | MF_POPUP, (UINT_PTR) menu_item->menu, (LPCTSTR) label);
		}
		else
		{
			throw ValueException::FromString("Unknown menu item type requested");
		}

		return menu_item;
	}
Example #9
0
	// A :method_missing method for finding KObject properties in Ruby
	static VALUE RubyKObjectMethodMissing(int argc, VALUE *argv, VALUE self)
	{
		SharedValue* dval = NULL;
		Data_Get_Struct(self, SharedValue, dval);
		SharedKObject object = (*dval)->ToObject();

		// TODO: We should raise an exception instead
		if (object.isNull())
			return Qnil;

		// This is the same error that ruby throws
		if (argc == 0 || !SYMBOL_P(argv[0]))
		{
			rb_raise(rb_eArgError, "no id given");
		}

		// We need to determine the method that was invoked:
		// store the method name and arguments in separate variables
		VALUE r_name, args;
		rb_scan_args(argc, argv, "1*", &r_name, &args);
		const char* name = rb_id2name(SYM2ID(r_name));

		// Check if this is an assignment
		SharedValue value = object->Get(name);
		if (name[strlen(name) - 1] == '=' && argc > 1)
		{
			char* mod_name = strdup(name);
			mod_name[strlen(mod_name) - 1] = '\0';
			value = RubyUtils::ToKrollValue(argv[1]);
			object->Set(mod_name, value);
			free(mod_name);
			return argv[1];
		}
		else if (value->IsUndefined()) // raise a method missing error
		{
			VALUE selfString = rb_obj_as_string(self);
			rb_raise(rb_eNoMethodError, "undefined method `%s' for %s",
				name, RubyUtils::ToString(selfString));
		}
		else if (value->IsMethod()) // actually call a method
		{
			return RubyUtils::GenericKMethodCall(value->ToMethod(), args);
		}
		else // Plain old access
		{
			return RubyUtils::ToRubyValue(value);
		}
	}
Example #10
0
	VALUE RubyUtils::ToRubyValue(SharedValue value)
	{
		if (value->IsNull() || value->IsUndefined())
		{
			return Qnil;
		}
		if (value->IsBool())
		{
			return value->ToBool() ? Qtrue : Qfalse;
		}
		else if (value->IsNumber())
		{
			return rb_float_new(value->ToNumber());
		}
		else if (value->IsString())
		{
			return rb_str_new2(value->ToString());
		}
		else if (value->IsObject())
		{
			AutoPtr<KRubyObject> ro = value->ToObject().cast<KRubyObject>();
			if (!ro.isNull())
				return ro->ToRuby();

			AutoPtr<KRubyHash> rh = value->ToObject().cast<KRubyHash>();
			if (!rh.isNull())
				return rh->ToRuby();

			return RubyUtils::KObjectToRubyValue(value);
		}
		else if (value->IsMethod())
		{
			AutoPtr<KRubyMethod> rm = value->ToMethod().cast<KRubyMethod>();
			if (!rm.isNull())
				return rm->ToRuby();
			else
				return RubyUtils::KMethodToRubyValue(value);
		}
		else if (value->IsList())
		{
			AutoPtr<KRubyList> rl = value->ToList().cast<KRubyList>();
			if (!rl.isNull())
				return rl->ToRuby();
			else
				return RubyUtils::KListToRubyValue(value);
		}
		return Qnil;
	}
Example #11
0
	void AccessorBoundList::Set(const char *name, SharedValue value)
	{
		std::string setter_name = "set" + Capitalize(name);
		SharedValue v = this->RawGet(setter_name.c_str());
		if (v->IsMethod())
		{
			SharedKMethod m = v->ToMethod();
			ValueList args;
			args.push_back(value);
			m->Call(args);
		}
		else
		{
			this->RawSet(name, value);
		}
	}
Example #12
0
void Win32Process::InvokeOnRead(std::ostringstream& buffer, bool isErr)
{
    SharedValue sv = this->Get("onread");
    if (!sv->IsMethod())
    {
        return;
    }

    if (!buffer.str().empty())
    {
        ValueList args(
            Value::NewString(buffer.str()),
            Value::NewBool(isErr));
        SharedKMethod callback = sv->ToMethod();
        this->parent->GetHost()->InvokeMethodOnMainThread(
            callback, args, false);

        buffer.str("");
    }
}
Example #13
0
	void NetworkBinding::GetHostByAddress(const ValueList& args, SharedValue result)
	{
		if (args.at(0)->IsObject())
		{
			SharedKObject obj = args.at(0)->ToObject();
			SharedPtr<IPAddressBinding> b = obj.cast<IPAddressBinding>();
			if (!b.isNull())
			{
				// in this case, they've passed us an IPAddressBinding
				// object, which we can just retrieve the ipaddress
				// instance and resolving using it
				IPAddress addr(b->GetAddress()->toString());
				SharedPtr<HostBinding> binding = new HostBinding(addr);
				if (binding->IsInvalid())
				{
					throw ValueException::FromString("Could not resolve address");
				}
				result->SetObject(binding);
				return;
			}
			else
			{
				SharedValue bo = obj->Get("toString");
				if (bo->IsMethod())
				{
					SharedKMethod m = bo->ToMethod();
					ValueList args;
					SharedValue tostr = m->Call(args);
					this->_GetByHost(tostr->ToString(),result);
					return;
				}
				throw ValueException::FromString("Unknown object passed");
			}
		}
		else if (args.at(0)->IsString())
		{
			// in this case, they just passed in a string so resolve as
			// normal
			this->_GetByHost(args.at(0)->ToString(),result);
		}
	}
Example #14
0
	void Worker::Run()
	{
		Logger *logger = Logger::Get("Worker");
		
		bool error = false;
		JSGlobalContextRef context = NULL;
		
		try
		{
			// create a new global context
			this->global_object = KJSUtil::CreateNewGlobalContext(this->host);
			
			// bind the worker context properties
			KJSUtil::BindProperties(global_object,this->context);
			
			// evaluate the script
			context = KJSUtil::GetGlobalContext(global_object);
			KJSUtil::Evaluate(context, (char*)this->code.c_str());
		}
		catch(std::exception &e)
		{
			error = true;
			logger->Error("Error loading worker. Error = %s", e.what());
			SharedValue onerror = this->Get("onerror");
			if (onerror->IsMethod())
			{
				SharedKMethod method = onerror->ToMethod();
				ValueList args;
				args.push_back(Value::NewString(e.what()));
				this->host->InvokeMethodOnMainThread(method,args,false);
			}
		}
		
		if (!error)
		{
			// run this thread and wait for pending messages or to be 
			// woken up to stop
			for(;;)
			{
				bool wait = true;
				{
					Poco::ScopedLock<Poco::Mutex> lock(mutex);
					if (this->messages.size()>0)
					{
						wait=false;
					}
				}
				if (wait)
				{
					condmutex.lock(); // will unlock in wait
					condition.wait(condmutex);
				}
				// check to see if the worker wants to receive messages - we do this 
				// each time since they could define at any time
				SharedValue mv = KJSUtil::GetProperty(global_object,"onmessage");
				if (mv->IsMethod())
				{
					// we have to make a copy since calling the onmessage could be re-entrant
					// which would cause the postMessage to deadlock. we hold the lock to 
					// make a copy of the contents of the list and then iterate w/o lock
					std::list<SharedValue> copy;
					{
						// lock inside block only to make copy
						Poco::ScopedLock<Poco::Mutex> lock(mutex);
						if (this->messages.size()>0)
						{
							std::list<SharedValue>::iterator i = this->messages.begin();
							while (i!=this->messages.end())
							{
								SharedValue message = (*i++);
								copy.push_back(message);
							}
							this->messages.clear();
						}
					}
					if (copy.size()>0)
					{
						SharedKMethod onmessage = mv->ToMethod();
						std::list<SharedValue>::iterator i = copy.begin();
						while(i!=copy.end())
						{
							SharedValue message = (*i++);
						
							try
							{
								ValueList args;
								string name = "worker.message";
								AutoPtr<KEventObject> target = this;
								this->duplicate();
								AutoPtr<Event> event = new Event(target, name);
								event->Set("message", message);
								args.push_back(Value::NewObject(event));
								host->InvokeMethodOnMainThread(onmessage,args,false);
							}
							catch(std::exception &e)
							{
								logger->Error("Error dispatching worker message, exception = %s",e.what());
							}
						}
					}
				}
				if (stopped) break;
			}
		}
		
		// make sure we unregister our global so we don't leak
		if (global_object!=NULL)
		{
			KJSUtil::UnregisterGlobalContext(global_object);
		}
		
		this->global_object = NULL;
		this->stopped = true;
		
		logger->Debug("exiting Worker thread");
	}