Example #1
0
	void MonkeyBinding::Callback(const ValueList &args, SharedValue result)
	{
		SharedKObject event = args.at(1)->ToObject();
		std::string url_value = event->Get("url")->ToString();
		
		std::vector< std::pair< std::pair< VectorOfPatterns,VectorOfPatterns >,std::string> >::iterator iter = scripts.begin();
		while(iter!=scripts.end())
		{
			std::pair< std::pair< VectorOfPatterns,VectorOfPatterns >, std::string> e = (*iter++);
			VectorOfPatterns include = e.first.first;
			VectorOfPatterns exclude = e.first.second;

			if (Matches(exclude,url_value))
			{
				continue;
			}
			if (Matches(include,url_value))
			{
				// I got a castle in brooklyn, that's where i dwell 
				try
				{
					SharedKMethod eval = event->Get("scope")->ToObject()->Get("window")->ToObject()->Get("eval")->ToMethod();
#ifdef DEBUG
					std::cout << ">>> loading user script for " << url_value << std::endl;
#endif
					eval->Call(Value::NewString(e.second));
				}
				catch (ValueException &ex)
				{
					Logger* logger = Logger::Get("Monkey");
					SharedString ss = ex.DisplayString();
					int line = -1;

					if (ex.GetValue()->IsObject() &&
						ex.GetValue()->ToObject()->Get("line")->IsNumber())
					{
						line = ex.GetValue()->ToObject()->Get("line")->ToInt();
					}
					logger->Error(
						"Exception generated evaluating user script for %s "
						"(line %i): %s", url_value.c_str(), line, ss->c_str());
				}
				catch (std::exception &ex)
				{
					Logger* logger = Logger::Get("Monkey");
					logger->Error("Exception generated evaluating user script for %s, Exception: %s",url_value.c_str(),ex.what());
				}
			}
		}
	}
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 AppBinding::CreateProperties(const ValueList& args, SharedValue result)
	{
		AutoPtr<PropertiesBinding> properties = new PropertiesBinding();
		result->SetObject(properties);
		
		if (args.size() > 0 && args.at(0)->IsObject())
		{
			SharedKObject p = args.at(0)->ToObject();
			SharedStringList names = p->GetPropertyNames();
			for (size_t i = 0; i < names->size(); i++)
			{
				SharedValue value = p->Get(names->at(i));
				ValueList setterArgs;
				setterArgs.push_back(Value::NewString(names->at(i)));
				setterArgs.push_back(value);
				PropertiesBinding::Type type;
				
				if (value->IsList()) type = PropertiesBinding::List;
				else if (value->IsInt()) type = PropertiesBinding::Int;
				else if (value->IsDouble()) type = PropertiesBinding::Double;
				else if (value->IsBool()) type = PropertiesBinding::Bool;
				else type = PropertiesBinding::String;
				
				properties->Setter(setterArgs, type);
			}
		}
	}
Example #4
0
	void HTTPClientBinding::SendFile(const ValueList& args, SharedValue result)
	{
		if (this->Get("connected")->ToBool())
		{
			throw ValueException::FromString("already connected");
		}
		if (args.size()==1)
		{
			// can be a string of data or a file
			SharedValue v = args.at(0);
			if (v->IsObject())
			{
				// probably a file
				SharedKObject obj = v->ToObject();
				if (obj->Get("isFile")->IsMethod())
				{
					std::string file = obj->Get("toString")->ToMethod()->Call()->ToString();
					this->filestream = new Poco::FileInputStream(file);
					Poco::Path p(file);
					this->filename = p.getFileName();
				}
				else
				{
					this->datastream = obj->Get("toString")->ToMethod()->Call()->ToString();
				}
			}
			else if (v->IsString())
			{
				this->filestream = new Poco::FileInputStream(v->ToString());
			}
			else
			{
				throw ValueException::FromString("unknown data type");
			}
		}
		this->thread = new Poco::Thread();
		this->thread->start(&HTTPClientBinding::Run,(void*)this);
		if (!this->async)
		{
			PRINTD("Waiting on HTTP Client thread to finish");
			this->thread->join();
		}
	}
	void MonkeyBinding::EvaluateUserScript(
		SharedKObject event, std::string& url,
		SharedKObject windowObject, std::string& scriptSource)
	{
		static Logger *logger = Logger::Get("Monkey");
		// I got a castle in brooklyn, that's where i dwell
		// Word, brother.

		if (!windowObject->Get("eval")->IsMethod())
		{
			logger->Error("Found a window object without an "
				"eval function (%s) -- aborting", url.c_str());
			return;
		}

		SharedKObject target = event->GetObject("target");
		if (!windowObject->Get(GLOBAL_NS_VARNAME)->IsObject() &&
			!target.isNull() && target->Get("insertAPI")->IsMethod())
		{
			logger->Info("Forcing Titanium API into: %s\n", url.c_str());
			target->CallNS("insertAPI", Value::NewObject(windowObject));
		}

		SharedKMethod evalFunction = windowObject->GetMethod("eval");
		logger->Info("Loading userscript for %s\n", url.c_str());
		try
		{
			evalFunction->Call(Value::NewString(scriptSource));
		}
		catch (ValueException &ex)
		{
			SharedString ss = ex.DisplayString();
			int line = -1;
			if (ex.GetValue()->IsObject() &&
				ex.GetValue()->ToObject()->Get("line")->IsNumber())
			{
				line = ex.GetValue()->ToObject()->Get("line")->ToInt();
			}
			logger->Error(
				"Exception generated evaluating user script for %s "
				"(line %i): %s", url.c_str(), line, ss->c_str());
		}
	}
Example #6
0
	// A :responds_to? method for finding KObject properties in Ruby
	static VALUE RubyKObjectRespondTo(int argc, VALUE *argv, VALUE self)
	{
		SharedValue* dval = NULL;
		Data_Get_Struct(self, SharedValue, dval);
		SharedKObject object = (*dval)->ToObject();
		VALUE mid, priv; // We ignore the priv argument

		rb_scan_args(argc, argv, "11", &mid, &priv);
		const char* name = rb_id2name(rb_to_id(mid));
		SharedValue value = object->Get(name);
		return value->IsUndefined() ? Qfalse : Qtrue;
	}
	void MonkeyBinding::Callback(const ValueList &args, SharedValue result)
	{
		SharedKObject event = args.at(0)->ToObject();
		if (!event->Get("url")->IsString() ||
			!event->Get("scope")->IsObject() ||
			!event->GetObject("scope")->Get("window"))
		{
			throw ValueException::FromString(
				"ti.Monkey could not find required components of PAGE_LOADED events");
		}

		std::string url = event->GetString("url");
		SharedKObject windowObject = event->GetObject("scope")->GetObject("window");
		vector<Script*>::iterator iter = scripts.begin();
		while (iter != scripts.end())
		{
			Script* script = (*iter++);
			if (script->Matches(url))
			{
				EvaluateUserScript(event, url, windowObject, script->source);
			}
		}
	}
Example #8
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 #9
0
HRESULT STDMETHODCALLTYPE
ScriptEvaluator::matchesMimeType(BSTR mimeType, BOOL *result)
{
	std::string moduleName = GetModuleName(BSTRToString(mimeType));
	SharedKObject global = host->GetGlobalObject();

	SharedValue moduleValue = global->Get(moduleName.c_str());
	*result = FALSE;
	if (!moduleValue->IsNull() && moduleValue->IsObject()) {
		if (!moduleValue->ToObject()->Get("evaluate")->IsNull()
				&& !moduleValue->ToObject()->Get("evaluate")->IsUndefined()
				&& moduleValue->ToObject()->Get("evaluate")->IsMethod()) {
			*result = TRUE;
		}
	}

	return S_OK;
}
Example #10
0
	void HTTPClientBinding::Send(const ValueList& args, SharedValue result)
	{
		if (this->Get("connected")->ToBool())
		{
			throw ValueException::FromString("already connected");
		}
		if (args.size()==1)
		{
			// can be a string of data or a file
			SharedValue v = args.at(0);
			if (v->IsObject())
			{
				// probably a file
				SharedKObject obj = v->ToObject();
				this->datastream = obj->Get("toString")->ToMethod()->Call()->ToString();
			}
			else if (v->IsString())
			{
				this->datastream = v->ToString();
			}
			else if (v->IsNull() || v->IsUndefined())
			{
				this->datastream = "";
			}
			else
			{
				throw ValueException::FromString("unknown data type");
			}
		}
		this->thread = new Poco::Thread();
		this->thread->start(&HTTPClientBinding::Run,(void*)this);
		if (!this->async)
		{
			PRINTD("Waiting on HTTP Client thread to finish (sync)");
			Poco::Stopwatch sw;
			sw.start();
			while (!this->shutdown && sw.elapsedSeconds() * 1000 < this->timeout)
			{
				this->thread->tryJoin(100);
			}
			PRINTD("HTTP Client thread finished (sync)");
		}
	}
Example #11
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 #12
0
	// A :method method for pulling methods off of KObjects in Ruby
	static VALUE RubyKObjectMethod(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;
		if (argc < 1)
			return Qnil;

		VALUE meth_name = argv[0];
		const char* name = rb_id2name(SYM2ID(meth_name));
		SharedValue v = object->Get(name);
		if (v->IsMethod())
		{
			return RubyUtils::ToRubyValue(v);
		}
		else
		{
			return Qnil;
		}
	}
Example #13
0
void UserWindow::_SetBounds(const kroll::ValueList& args, kroll::SharedValue result)
{
	if (args.size() < 1 || !args.at(0)->IsObject())
	{
		throw ValueException::FromString("setBounds takes an object with x, y, width and height properties.");
		return;
	}

	SharedKObject o = args.at(0)->ToObject();
	if (!o->Get("x")->IsNumber()
		|| !o->Get("y")->IsNumber()
		|| !o->Get("width")->IsNumber()
		||!o->Get("height")->IsNumber())
	{
		throw ValueException::FromString("setBounds takes an object with x, y, width and height properties.");
		return;
	}

	double x = o->Get("x")->ToNumber();
	double y = o->Get("y")->ToNumber();
	double w = o->Get("width")->ToNumber();
	double h = o->Get("height")->ToNumber();
	w = UserWindow::Constrain(w, config->GetMinWidth(), config->GetMaxWidth());
	h = UserWindow::Constrain(h, config->GetMinHeight(), config->GetMaxHeight());

	this->config->SetX(x);
	this->config->SetY(y);
	this->config->SetWidth(w);
	this->config->SetHeight(h);

	if (this->active)
	{
		Bounds bounds;
		bounds.x = x;
		bounds.y = y;
		bounds.width = w;
		bounds.height = h;
		this->SetBounds(bounds);
	}
}
Example #14
0
void GtkUserWindow::Open()
{
	if (this->gtk_window == NULL)
	{
		WebKitWebView* web_view = WEBKIT_WEB_VIEW (webkit_web_view_new ());

		g_signal_connect(
			G_OBJECT(web_view), "window-object-cleared",
			G_CALLBACK(window_object_cleared_cb), this);
		g_signal_connect(
			G_OBJECT(web_view), "navigation-requested",
			G_CALLBACK(navigation_requested_cb), this);
		g_signal_connect(
			G_OBJECT(web_view), "new-window-navigation-requested",
			G_CALLBACK(new_window_navigation_requested_cb), this);
		g_signal_connect(
			G_OBJECT(web_view), "populate-popup",
			G_CALLBACK(populate_popup_cb), this);
		g_signal_connect(
			G_OBJECT(web_view), "load-finished",
			G_CALLBACK(load_finished_cb), this);

		// Tell Titanium what Webkit is using for a user-agent
		SharedKObject global = host->GetGlobalObject();
		if (global->Get("userAgent")->IsUndefined())
		{
			gchar* user_agent = webkit_web_view_get_user_agent(G_OBJECT(web_view));
			global->Set("userAgent", Value::NewString(user_agent));
			g_free(user_agent);
		}

		WebKitWebSettings* settings = webkit_web_settings_new();
		g_object_set(G_OBJECT(settings), "enable-developer-extras", TRUE, NULL);
		webkit_web_view_set_settings(WEBKIT_WEB_VIEW(web_view), settings);

		GtkWidget* view_container = NULL;
		if (this->IsUsingScrollbars())
		{
			/* web view scroller */
			GtkWidget* scrolled_window = gtk_scrolled_window_new (NULL, NULL);
			gtk_scrolled_window_set_policy(
				GTK_SCROLLED_WINDOW(scrolled_window),
				GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
			gtk_container_add(
				GTK_CONTAINER (scrolled_window), GTK_WIDGET (web_view));
			view_container = scrolled_window;
		}
		else // No scrollin' fer ya.
		{
			view_container = GTK_WIDGET(web_view);
		}

		/* main window vbox */
		this->vbox = gtk_vbox_new(FALSE, 0);
		gtk_box_pack_start(GTK_BOX (vbox),
		                   GTK_WIDGET(view_container),
		                   TRUE, TRUE, 0);

		/* main window */
		GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
		gtk_widget_set_name(window, this->config->GetTitle().c_str());
		gtk_window_set_title(GTK_WINDOW(window), this->config->GetTitle().c_str());

		this->destroy_cb_id = g_signal_connect(
			G_OBJECT(window), "destroy", G_CALLBACK(destroy_cb), this);
		g_signal_connect(G_OBJECT(window), "event",
		                 G_CALLBACK(event_cb), this);

		gtk_container_add(GTK_CONTAINER (window), vbox);

		webkit_web_view_register_url_scheme_as_local("app");
		webkit_web_view_register_url_scheme_as_local("ti");

		this->gtk_window = GTK_WINDOW(window);
		this->web_view = web_view;
		//this->SetupTransparency();

		gtk_widget_realize(window);
		this->SetupDecorations();
		this->SetupSize();
		this->SetupSizeLimits();
		this->SetupPosition();
		this->SetupMenu();
		this->SetupIcon();
		this->SetTopMost(config->IsTopMost());
		this->SetCloseable(config->IsCloseable());

		gtk_widget_grab_focus(GTK_WIDGET (web_view));
		webkit_web_view_open(web_view, this->config->GetURL().c_str());

		if (this->IsVisible())
		{
			gtk_widget_show_all(window);
		}

		if (this->config->IsFullScreen())
		{
			gtk_window_fullscreen(this->gtk_window);
		}

		UserWindow::Open();
		this->FireEvent(OPENED);
	}
	else
	{
		this->Show();
	}
}