From a08031bdda6f4bfffe30e3e59a5e49b687ecda3d Mon Sep 17 00:00:00 2001 From: boisso Date: Wed, 4 Mar 2015 00:42:07 +0000 Subject: [PATCH] Run JS in hidden window --- k-meleon/BrowserWindow.cpp | 127 +++++++++++------------------------ k-meleon/BrowserWindow.h | 1 + k-meleon/MozUtils.cpp | 79 ++++++++++++++++++++++ k-meleon/MozUtils.h | 3 +- k-meleon/Plugins.cpp | 53 +++++++++++---- k-meleon/kmeleon_plugin.h | 2 + k-meleon/macros2/functions.h | 10 ++- 7 files changed, 171 insertions(+), 104 deletions(-) diff --git a/k-meleon/BrowserWindow.cpp b/k-meleon/BrowserWindow.cpp index fcdee598..9f6a1616 100644 --- a/k-meleon/BrowserWindow.cpp +++ b/k-meleon/BrowserWindow.cpp @@ -467,6 +467,30 @@ CString CBrowserWrapper::GetURI(BOOL unescape) return NSUTF8StringToCString(uriString); } +CString CBrowserWrapper::GetLang() +{ + nsresult rv; + + nsCOMPtr domWindow; + rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); + NS_ENSURE_SUCCESS(rv, L""); + + nsCOMPtr document; + rv = domWindow->GetDocument(getter_AddRefs(document)); + NS_ENSURE_SUCCESS(rv, L""); + + nsCOMPtr element; + document->GetDocumentElement(getter_AddRefs(element)); + NS_ENSURE_TRUE(element, L""); + + nsString nsLang; + element->GetAttribute(NS_LITERAL_STRING("lang"), nsLang); + if (!nsLang.Length()) { + element->GetAttribute(NS_LITERAL_STRING("xml:lang"), nsLang); + } + return NSStringToCString(nsLang); +} + BOOL CBrowserWrapper::GetCharset(char* aCharset) { NS_ENSURE_TRUE(mWebBrowser, FALSE); @@ -487,7 +511,7 @@ BOOL CBrowserWrapper::GetCharset(char* aCharset) nsCString mCharset; result = mdv->GetForceCharacterSet(mCharset); - + if (NS_FAILED(result) || mCharset.IsEmpty() ) { @@ -955,98 +979,25 @@ BOOL CBrowserWrapper::InjectCSS(const wchar_t* userStyleSheet) BOOL CBrowserWrapper::InjectJS(const wchar_t* userScript, CString& result, bool bTopWindow) { nsresult rv; - nsCOMPtr document; - nsCOMPtr cs = do_GetService("@mozilla.org/js/xpc/XPConnect;1"); - if (!cs) { - // No more running JS from C++ - bool jsEnabled = PR_TRUE; - nsCOMPtr prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); - if (prefs) { - prefs->GetBoolPref("javascript.enabled", &jsEnabled); - prefs->SetBoolPref("javascript.enabled", PR_TRUE); - } - - if (!bTopWindow) - { - if (mLastMouseActionNode) - rv = mLastMouseActionNode->GetOwnerDocument(getter_AddRefs(document)); - else - { - nsCOMPtr dom; - mWebBrowserFocus->GetFocusedWindow(getter_AddRefs(dom)); - if (dom) - rv = dom->GetDocument(getter_AddRefs(document)); - } - } - - if (!document) - { - nsCOMPtr dom; - rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(dom)); - NS_ENSURE_SUCCESS(rv, FALSE); - - rv = dom->GetDocument(getter_AddRefs(document)); + + nsCOMPtr dom; + if (!bTopWindow) + { + if (mLastMouseActionNode) { + nsCOMPtr document; + rv = mLastMouseActionNode->GetOwnerDocument(getter_AddRefs(document)); + document->GetDefaultView(getter_AddRefs(dom)); } + if (!dom) mWebBrowserFocus->GetFocusedWindow(getter_AddRefs(dom)); + } + if (!dom) { + rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(dom)); NS_ENSURE_SUCCESS(rv, FALSE); - - nsCOMPtr body; - rv = document->GetDocumentElement (getter_AddRefs(body)); - NS_ENSURE_SUCCESS(rv, FALSE); - - nsCOMPtr scriptElement; - rv = document->CreateElement(nsDependentString(L"script"), getter_AddRefs(scriptElement)); - NS_ENSURE_SUCCESS(rv, FALSE); - - nsCOMPtr scriptTag = do_QueryInterface(scriptElement); - NS_ENSURE_TRUE(scriptTag, FALSE); - - scriptTag->SetText(nsDependentString(userScript)); - scriptTag->SetType(nsDependentString(L"text/javascript")); - - nsCOMPtr notused, node = do_QueryInterface(scriptTag); - rv = body->AppendChild(node, getter_AddRefs(notused)); - BOOL ret = NS_SUCCEEDED(rv); - body->RemoveChild(node, getter_AddRefs(notused)); - if (prefs) prefs->SetBoolPref("javascript.enabled", jsEnabled); - - return ret; } - - nsCOMPtr dom; - rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(dom)); - NS_ENSURE_SUCCESS(rv, FALSE); - - nsCOMPtr global = GetDocShell()->GetScriptGlobalObject(); - NS_ENSURE_TRUE(global, FALSE); - - nsCOMPtr sgo = do_GetInterface(mWebBrowser); - - nsCOMPtr win = do_QueryInterface(global); - nsPIDOMWindow *innerWin = win->GetCurrentInnerWindow(); - nsCOMPtr innerGlobal = do_QueryInterface(innerWin); - nsCOMPtr domWindow(do_QueryInterface(global, &rv)); - NS_ENSURE_SUCCESS(rv, FALSE); - nsCOMPtr scriptContext = global->GetContext(); - NS_ENSURE_TRUE(scriptContext, FALSE); - - JSContext* cx = scriptContext->GetNativeContext(); - if (!cx) return FALSE; - - //XPCJSContextStack *stack = XPCJSRuntime::Get()->GetJSContextStack(); - //stack->Push(cx); - - NS_ENSURE_SUCCESS(cs->Push(cx), FALSE); - JSAutoRequest ar(cx); - JSAutoCompartment ac(cx, scriptContext->GetWindowProxy()); - JS::Rooted globalJSObject(cx, innerGlobal->GetGlobalJSObject()); - JS::Rooted v (cx, JS::UndefinedValue()); - JS_EvaluateScript(cx, globalJSObject, CW2A(userScript), wcslen(userScript), "", 0, &v); - if (v.isString() && !v.isObject()) - result = NSStringToCString(nsString(JS_GetStringCharsZ(cx, v.toString()))); - cs->Pop(nullptr); - return TRUE; + if (!dom) return FALSE; + return ::InjectJS(dom, userScript, result); } BOOL CBrowserWrapper::_GetSelection(nsIDOMWindow* dom, nsAString &aSelText) diff --git a/k-meleon/BrowserWindow.h b/k-meleon/BrowserWindow.h index e04312d2..518f1f7d 100644 --- a/k-meleon/BrowserWindow.h +++ b/k-meleon/BrowserWindow.h @@ -323,6 +323,7 @@ public: BOOL GetCharset(char* aCharset); BOOL ForceCharset(const char *aCharSet); + CString GetLang(); BOOL Print(); BOOL PrintPreview(); diff --git a/k-meleon/MozUtils.cpp b/k-meleon/MozUtils.cpp index 27ef5fa5..57ded1b7 100644 --- a/k-meleon/MozUtils.cpp +++ b/k-meleon/MozUtils.cpp @@ -657,3 +657,82 @@ bool ZipExtractFiles(nsIFile* zipFile, nsIFile* folder) zipReader->Close(); return true; } + +#include "nsIDOMHTMLScriptElement.h" +#include "nsAppShellCID.h" +#include "nsIAppShellService.h" +#include "nsIScriptObjectPrincipal.h" +#include "nsIScriptContext.h" +#include "nsIScriptGlobalObject.h" +#include "mozilla/dom/ScriptSettings.h" +#include "nsIJSContextStack.h" +#include "jsapi.h" + +bool InjectJS(nsIDOMWindow* dom, const wchar_t* userScript, CString& result) +{ + nsresult rv; + nsCOMPtr cs = do_GetService("@mozilla.org/js/xpc/XPConnect;1"); + if (!cs) { + nsCOMPtr document; + dom->GetDocument(getter_AddRefs(document)); + NS_ENSURE_TRUE(document, false); + + nsCOMPtr body; + rv = document->GetDocumentElement (getter_AddRefs(body)); + NS_ENSURE_SUCCESS(rv, FALSE); + + nsCOMPtr scriptElement; + rv = document->CreateElement(nsDependentString(L"script"), getter_AddRefs(scriptElement)); + NS_ENSURE_SUCCESS(rv, FALSE); + + nsCOMPtr scriptTag = do_QueryInterface(scriptElement); + NS_ENSURE_TRUE(scriptTag, FALSE); + + scriptTag->SetText(nsDependentString(userScript)); + scriptTag->SetType(nsDependentString(L"text/javascript")); + + nsCOMPtr notused, node = do_QueryInterface(scriptTag); + rv = body->AppendChild(node, getter_AddRefs(notused)); + BOOL ret = NS_SUCCEEDED(rv); + body->RemoveChild(node, getter_AddRefs(notused)); + return ret; + } + + nsCOMPtr piWin(do_QueryInterface(dom)); + if (!piWin) return false; + nsIDocShell* docShell = piWin->GetDocShell(); + if (!docShell) return false; + + nsCOMPtr global = docShell->GetScriptGlobalObject(); + NS_ENSURE_TRUE(global, FALSE); + + nsPIDOMWindow *innerWin = piWin->GetCurrentInnerWindow(); + nsCOMPtr innerGlobal = do_QueryInterface(innerWin); + nsCOMPtr scriptContext = global->GetContext(); + NS_ENSURE_TRUE(scriptContext, FALSE); + + JSContext* cx = scriptContext->GetNativeContext(); + if (!cx) return FALSE; + + NS_ENSURE_SUCCESS(cs->Push(cx), FALSE); + JSAutoRequest ar(cx); + JSAutoCompartment ac(cx, scriptContext->GetWindowProxy()); + JS::Rooted globalJSObject(cx, innerGlobal->GetGlobalJSObject()); + JS::Rooted v (cx, JS::UndefinedValue()); + JS_EvaluateUCScript(cx, globalJSObject, userScript, wcslen(userScript), "", 0, &v); + + if (v.isString() && !v.isObject()) + result = NSStringToCString(nsString(JS_GetStringCharsZ(cx, v.toString()))); + cs->Pop(nullptr); + return TRUE; +} + +bool RunJS(const wchar_t* userScript, CString& result) +{ + nsCOMPtr appShellService(do_GetService(NS_APPSHELLSERVICE_CONTRACTID)); + NS_ENSURE_TRUE(appShellService, false); + nsCOMPtr win; + appShellService->GetHiddenDOMWindow(getter_AddRefs(win)); + NS_ENSURE_TRUE(win, false); + return InjectJS(win, userScript, result); +} diff --git a/k-meleon/MozUtils.h b/k-meleon/MozUtils.h index 0f9ec737..e5725359 100644 --- a/k-meleon/MozUtils.h +++ b/k-meleon/MozUtils.h @@ -37,7 +37,8 @@ BOOL IsContentEditable(nsIDOMNode* node); CString GetSearchURL(LPCTSTR query); bool GetFrameURL(nsIWebBrowser* aWebBrowser, nsIDOMNode* aNode, nsString& url); - +bool RunJS(const wchar_t* userScript, CString& result); +bool InjectJS(nsIDOMWindow* dom, const wchar_t* userScript, CString& result); BOOL LogMessage(const char* category, const char* message, const char* file, uint line, uint flags); #endif \ No newline at end of file diff --git a/k-meleon/Plugins.cpp b/k-meleon/Plugins.cpp index 5b37c550..f9e9c949 100644 --- a/k-meleon/Plugins.cpp +++ b/k-meleon/Plugins.cpp @@ -994,6 +994,14 @@ UINT GetWindowVar(HWND hWnd, WindowVarType type, void* ret) break; } + case Window_Lang: { + USES_CONVERSION; + const char* lang = T2CA(browser->GetLang()); + retLen = strlen(lang) + 1; + if (ret) strcpy((char*)ret, lang); + break; + } + default: retLen = 0; } @@ -1132,6 +1140,22 @@ UINT GetWindowVarUTF8(HWND hWnd, WindowVarType type, void* ret) return 1; } + case Search_URL: { + CString _url = GetSearchURL(_T("__query__")); + char* url = EncodeUTF8(_url); + retLen = strlen(url) + 1; + if (ret) strcpy((char*)ret, url); + break; + } + + case Window_Lang: { + USES_CONVERSION; + const char* lang = T2CA(browser->GetLang()); + retLen = strlen(lang) + 1; + if (ret) strcpy((char*)ret, lang); + break; + } + default: retLen = 0; } @@ -1614,23 +1638,28 @@ void RemoveStatusBarIcon(HWND hWnd, int id) BOOL InjectJS2(const char* js, int bTopWindow, char *result, unsigned size, HWND hWnd) { - PLUGIN_HEADER(hWnd, FALSE); - nsString js2; + CString csresult; NS_CStringToUTF16(nsDependentCString(js), NS_CSTRING_ENCODING_UTF8, js2); - CString csresult; - if (bTopWindow == 2 && frame->IsKindOf(RUNTIME_CLASS(CBrowserFrmTab))) - { - BOOL ret = TRUE; - CBrowserFrmTab* frameTab = (CBrowserFrmTab*)frame; - int tabCount = frameTab->GetTabCount(); - for (int i=0;iGetTabIndex(i)->GetBrowserWrapper()->InjectJS(js2.get(), csresult); - return ret; + BOOL success = FALSE; + if (bTopWindow == -1) { + success = ::RunJS(js2.get(), csresult); + } + else { + PLUGIN_HEADER(hWnd, FALSE); + if (bTopWindow == 2 && frame->IsKindOf(RUNTIME_CLASS(CBrowserFrmTab))) + { + BOOL ret = TRUE; + CBrowserFrmTab* frameTab = (CBrowserFrmTab*)frame; + int tabCount = frameTab->GetTabCount(); + for (int i=0;iGetTabIndex(i)->GetBrowserWrapper()->InjectJS(js2.get(), csresult); + return ret; + } + success = browser->InjectJS(js2.get(), csresult, bTopWindow==1); } - BOOL success = browser->InjectJS(js2.get(), csresult, bTopWindow==1); if (success && result) { char* c = EncodeUTF8(T2W(csresult.GetBuffer(0))); strncpy(result, c, size); diff --git a/k-meleon/kmeleon_plugin.h b/k-meleon/kmeleon_plugin.h index abc211cc..0210bc53 100644 --- a/k-meleon/kmeleon_plugin.h +++ b/k-meleon/kmeleon_plugin.h @@ -95,6 +95,7 @@ enum WindowVarType { Window_ImageURL = 102, // char* Window_FrameURL = 103, // char* Window_LinkTitle = 104, // char* + Window_Lang = 105, // char* Window_Icon = 110, // int Search_URL = 120 // char* @@ -385,6 +386,7 @@ typedef struct { int (*SetCmdIcon)(const char* name, const char* icon, const LPRECT region, const char* hot, const LPRECT hotregion, const char* dead, const LPRECT deadregion); int (*SetButtonIcon)(const char* toolbar, UINT id, const char* icon, const LPRECT region, const char* hot, const LPRECT hotregion, const char* dead, const LPRECT deadregion); bool (*AddPermission)(const char* url, const char* type, const char* perm, bool sessionOnly); + } kmeleonFunctions; /* diff --git a/k-meleon/macros2/functions.h b/k-meleon/macros2/functions.h index e3751076..67224948 100644 --- a/k-meleon/macros2/functions.h +++ b/k-meleon/macros2/functions.h @@ -1007,6 +1007,8 @@ bTopWindow = 0; else if (strcmp(data->getstr(2), "alltabs")==0) bTopWindow = 2; + else if (strcmp(data->getstr(2), "hidden")==0) + bTopWindow = -1; else bTopWindow = 1; @@ -1414,6 +1416,8 @@ type = Search_URL; else if (name == "CommandLine") return CT_to_UTF8(::GetCommandLine()); + else if (name == "LANG") + type = Window_Lang; else return ""; int l = kPlugin.kFuncs->GetWindowVar(data->c.hWnd, type, NULL); @@ -1504,7 +1508,7 @@ return Value(); } - Value setbuttonicon(FunctionData* data) + Value setbuttonimg(FunctionData* data) { checkArgs(__FUNCTION__, data, 2,6); MString name = data->getstr(1); @@ -1573,7 +1577,7 @@ b.checked = data->getbool(2); return kPlugin.kFuncs->SetButton(data->getstr(1), kPlugin.kFuncs->GetID(data->getstr(2)), &b); } - + /* Value setbuttonimg(FunctionData* data) { checkArgs(__FUNCTION__, data, 2,7); @@ -1592,7 +1596,7 @@ b.iconHeight = data->getint(7); return kPlugin.kFuncs->SetButton(data->getstr(1), kPlugin.kFuncs->GetID(data->getstr(2)), &b); - } + }*/ #define MAX_TIMERS 10 #define OFFSET_TIMERS 1000