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()); } }
MonkeyBinding::MonkeyBinding(Host *host, SharedKObject global) : global(global), registration(0), logger(Logger::Get("Monkey")) { std::string resourcesPath = host->GetApplication()->GetResourcesPath(); std::string userscriptsPath = FileUtils::Join( resourcesPath.c_str(), "userscripts", NULL); if (FileUtils::IsDirectory(userscriptsPath)) { logger->Debug("Found userscripts directory at: %s\n", userscriptsPath.c_str()); std::vector<std::string> files; FileUtils::ListDir(userscriptsPath,files); if (files.size()>0) { std::vector<std::string>::iterator iter = files.begin(); while(iter!=files.end()) { std::string file = (*iter++); std::string fn = FileUtils::Join(userscriptsPath.c_str(),file.c_str(),NULL); Poco::Path path(fn); if (path.getExtension() == "js") { Poco::FileInputStream f(fn); std::string line; std::ostringstream str; bool found = false, start = false; VectorOfPatterns includes; VectorOfPatterns excludes; while (!f.eof()) { std::getline(f, line); if (line.find("// ==UserScript==") == 0) { found = true; } else if (found && !start) { std::string::size_type i = line.find("// @include"); if (i == 0) { std::string url = FileUtils::Trim(line.substr(i+12).c_str()); includes.push_back(PatternMatcher(url)); continue; } i = line.find("// @exclude"); if (i == 0) { std::string url = FileUtils::Trim(line.substr(i+12).c_str()); excludes.push_back(PatternMatcher(url)); } else if (line.find("// ==/UserScript==") == 0) { start = true; str << "(function(){\n"; } //TODO: @require } else if (start) { str << line << "\n"; } } if (found && start) { str << "\n})();"; try { std::pair<VectorOfPatterns,VectorOfPatterns> r(includes,excludes); scripts.push_back(std::pair<std::pair< VectorOfPatterns,VectorOfPatterns >,std::string>(r,str.str())); } catch(Poco::RegularExpressionException &e) { std::cerr << "Exception loading user script: " << fn << " Exception: " << e.what() << std::endl; } } } } if (scripts.size()>0) { this->SetMethod("callback",&MonkeyBinding::Callback); SharedValue v = global->CallNS("API.register",Value::NewString("ti.UI.window.page.load"),this->Get("callback")); this->registration = v->ToInt(); } } } }