1
0

Switched to new method for nickel_extras:web_browser and implemented url/css options (closes #49) (#50)

* Switched to new method for nickel_extras:web_browser.
* Added support for fw versions less than 4.11.11911 for nickel_extras:web_browser action.
* Added modal, URL, and CSS options to nickel_extras:web_browser.
This commit is contained in:
Patrick Gaskin
2020-06-20 15:08:12 -04:00
committed by GitHub
parent 50c7374fcf
commit 7de21b827c
2 changed files with 69 additions and 28 deletions

View File

@@ -52,7 +52,12 @@
# screenshots - toggles FeatureSettings.Screenshots
# force_wifi - toggles DeveloperSettings.ForceWifiOn (note: the setting doesn't apply until you toggle WiFi)
# nickel_extras - the mimetype of the plugin, or one of:
# web_browser
# web_browser - opens the web browser to the default homepage
# web_browser:<url> - opens the web browser to the specified URL
# web_browser:<url> <css> - opens the web browser to the specified URL and injects the specified CSS (which can contain spaces and colons) into all pages
# web_browser:modal - opens the web browser to the default homepage as a pop-up window
# web_browser:modal:<url> - see above
# web_browser:modal:<url> <css> - see above
# unblock_it
# sketch_pad
# solitaire

View File

@@ -295,43 +295,79 @@ NM_ACTION_(nickel_setting) {
NM_ACTION_(nickel_extras) {
#define NM_ERR_RET nullptr
if (!strncmp(arg, "web_browser", 11)) {
bool modal;
QUrl *url;
QString *css;
if (!strcmp(arg, "web_browser")) {
//libnickel 4.6 * _ZN26N3SettingsExtrasControllerC2Ev
void (*N3SettingsExtrasController_N3SettingsExtrasController)(N3SettingsExtrasController*);
reinterpret_cast<void*&>(N3SettingsExtrasController_N3SettingsExtrasController) = dlsym(RTLD_DEFAULT, "_ZN26N3SettingsExtrasControllerC2Ev");
NM_ASSERT(N3SettingsExtrasController_N3SettingsExtrasController, "could not dlsym N3SettingsExtrasController constructor");
modal = false;
url = new QUrl();
css = new QString("");
} else {
char *tmp1 = strdupa(arg); // strsep and strtrim will modify it
char *arg1 = strtrim(strsep(&tmp1, ":"));
char *arg2 = strtrim(tmp1);
//libnickel 4.6 * _ZN26N3SettingsExtrasControllerD1Ev
void (*N3SettingsExtrasController_N3SettingsExtrasControllerD)(N3SettingsExtrasController*);
reinterpret_cast<void*&>(N3SettingsExtrasController_N3SettingsExtrasControllerD) = dlsym(RTLD_DEFAULT, "_ZN26N3SettingsExtrasControllerD1Ev");
NM_ASSERT(N3SettingsExtrasController_N3SettingsExtrasControllerD, "could not dlsym N3SettingsExtrasController destructor");
if (!arg2 || strcmp(arg1, "web_browser"))
NM_RETURN_ERR("unknown beta feature name or plugin mimetype '%s' (split: '%s')", arg, arg1);
//libnickel 4.6 * _ZN26N3SettingsExtrasController11openBrowserEv
void (*N3SettingsExtrasController_openBrowser)(N3SettingsExtrasController*);
reinterpret_cast<void*&>(N3SettingsExtrasController_openBrowser) = dlsym(RTLD_DEFAULT, "_ZN26N3SettingsExtrasController11openBrowserEv");
NM_ASSERT(N3SettingsExtrasController_openBrowser, "could not dlsym BrowserWorkflowManager::openBrowser");
QString tmp = QString::fromUtf8(arg2).trimmed();
N3SettingsExtrasController *nse = alloca(128); // as of 4.20.14622, it's actually 48 bytes, but we're going to stay on the safe side
N3SettingsExtrasController_N3SettingsExtrasController(nse);
N3SettingsExtrasController_openBrowser(nse);
N3SettingsExtrasController_N3SettingsExtrasControllerD(nse);
if (tmp.section(':', 0, 0).trimmed() == "modal") {
modal = true;
tmp = tmp.section(':', 1).trimmed();
} else {
modal = false;
}
// the QObject is only used to pass events to it, but there's something I'm missing here which leads to it segfaulting after connecting to WiFi if it isn't already connected
/*
//libnickel 4.11.11911 * _ZN22BrowserWorkflowManagerC1EP7QObject
void (*BrowserWorkflowManager_BrowserWorkflowManager)(BrowserWorkflowManager*, QObject*);
if (tmp.contains(' ')) {
css = new QString(tmp.section(' ', 1).trimmed());
url = new QUrl(tmp.section(' ', 0, 0).trimmed(), QUrl::ParsingMode::StrictMode);
if (!url->isValid() || url->isRelative())
NM_RETURN_ERR("invalid url '%s' (argument: '%s') (note: if your url has spaces, they need to be escaped)", qPrintable(tmp.section(' ', 0, 0)), arg);
} else if (tmp.length()) {
url = new QUrl(tmp, QUrl::ParsingMode::StrictMode);
css = new QString("");
if (!url->isValid() || url->isRelative())
NM_RETURN_ERR("invalid url '%s' (argument: '%s') (note: if your url has spaces, they need to be escaped)", qPrintable(tmp.section(' ', 0, 0)), arg);
} else {
url = new QUrl();
css = new QString("");
}
}
NM_LOG("web browser '%s' (modal=%d, url='%s', css='%s')", arg, modal, url->isValid() ? qPrintable(url->toString()) : "(home)", qPrintable(*css));
//libnickel 4.6 * _ZN22BrowserWorkflowManager14sharedInstanceEv _ZN22BrowserWorkflowManagerC1EP7QObject
BrowserWorkflowManager *(*BrowserWorkflowManager_sharedInstance)();
void (*BrowserWorkflowManager_BrowserWorkflowManager)(BrowserWorkflowManager*, QObject*); // 4.11.11911+
reinterpret_cast<void*&>(BrowserWorkflowManager_sharedInstance) = dlsym(RTLD_DEFAULT, "_ZN22BrowserWorkflowManager14sharedInstanceEv");
reinterpret_cast<void*&>(BrowserWorkflowManager_BrowserWorkflowManager) = dlsym(RTLD_DEFAULT, "_ZN22BrowserWorkflowManagerC1EP7QObject");
NM_ASSERT(BrowserWorkflowManager_BrowserWorkflowManager, "could not dlsym BrowserWorkflowManager constructor");
NM_ASSERT(BrowserWorkflowManager_sharedInstance || BrowserWorkflowManager_BrowserWorkflowManager, "could not dlsym BrowserWorkflowManager constructor (4.11.11911+) or sharedInstance");
//libnickel 4.6 * _ZN22BrowserWorkflowManager11openBrowserEbRK4QUrlRK7QString
void (*BrowserWorkflowManager_openBrowser)(BrowserWorkflowManager*, bool, QUrl const&, QString const&); // the bool is whether to open it as a modal, the string is CSS to inject
void (*BrowserWorkflowManager_openBrowser)(BrowserWorkflowManager*, bool, QUrl*, QString*); // the bool is whether to open it as a modal, the QUrl is the URL to load(if !QUrl::isValid(), it loads the homepage), the string is CSS to inject
reinterpret_cast<void*&>(BrowserWorkflowManager_openBrowser) = dlsym(RTLD_DEFAULT, "_ZN22BrowserWorkflowManager11openBrowserEbRK4QUrlRK7QString");
NM_ASSERT(BrowserWorkflowManager_openBrowser, "could not dlsym BrowserWorkflowManager::openBrowser");
BrowserWorkflowManager *bwm = alloca(128); // as of 4.20.14622, it's actually 20 bytes, but we're going to stay on the safe side
BrowserWorkflowManager_BrowserWorkflowManager(bwm, new QObject());
BrowserWorkflowManager_openBrowser(bwm, false, QUrl(), QStringLiteral("")); // if !QUrl::isValid(), it loads the homepage
*/
// note: everything must be on the heap since if it isn't connected, it
// passes it as-is to the connected signal, which will be used
// after this action returns.
BrowserWorkflowManager *bwm;
if (BrowserWorkflowManager_BrowserWorkflowManager) {
bwm = calloc(1, 128); // as of 4.20.14622, it's actually 20 bytes, but we're going to stay on the safe side
NM_ASSERT(bwm, "could not allocate memory for BrowserWorkflowManager");
BrowserWorkflowManager_BrowserWorkflowManager(bwm, nullptr);
} else {
bwm = BrowserWorkflowManager_sharedInstance();
NM_ASSERT(bwm, "could not get shared browser workflow manager pointer");
}
BrowserWorkflowManager_openBrowser(bwm, modal, url, css);
NM_RETURN_OK(nm_action_result_silent());
}