You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2083 lines
56 KiB

/*
* Copyright (C) 2006 Dorian Boissonnade
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include "stdafx.h"
#include "BrowserWindow.h"
#include "BrowserImpl.h"
#include "MozUtils.h"
#include "PrintSetupDialog.h"
#include "PrintProgressDialog.h"
#include "SaveAsHandler.h"
#include "mfcembed.h"
#include "Utils.h"
#include "nsIBaseWindow.h"
#include "nsIWidget.h"
#include "nsISHistory.h"
#include "nsISHEntry.h"
#include "nsIDOMHTMLFrameSetElement.h"
#include "nsIDocShellTreeItem.h"
#include "nsIWebBrowserFocus.h"
#include "nsIContentViewer.h"
#include "nsIDocCharset.h"
#include "nsISelection.h"
#include "nsISHistoryInternal.h"
#include "nsIDOMText.h"
#include "nsIDOMNodeList.h"
#include "nsIDOMWindowCollection.h"
#include "nsIWebPageDescriptor.h"
#include "nsIDocShell.h"
#include "nsIDOMEventTarget.h"
#include "nsIScriptGlobalObject.h"
#include "nsISecureBrowserUI.h"
#include "nsISSLStatus.h"
#include "nsISSLStatusProvider.h"
#include "nsICertificateDialogs.h"
#include "nsIScriptSecurityManager.h"
#include "nsIDOMHTMLDocument.h"
#include "nsIDOMHTMLTextAreaElement.h"
#include "nsIDOMHTMLScriptElement.h"
#include "nsIDOMHTMLInputElement.h"
#include "nsIDOMHTMLEmbedElement.h"
#include "nsIDOMHTMLObjectElement.h"
#include "nsIDOMHTMLButtonElement.h"
#include "nsIDOMHTMLSelectElement.h"
#include "nsITypeAheadFind.h"
#include "nsIWebBrowserFind.h"
//#include "nsIFocusController.h"
//#include "nsIDOMNSHTMLDocument.h"
#include "nsIPrintSettingsService.h"
#include "nsCWebBrowserPersist.h"
#include "nsIDomLocation.h"
#include "nsIX509Cert.h"
/* For highlight only x_x */
#include "nsIFind.h"
#include "nsIDOMText.h"
#include "nsIDOMRange.h"
#include "nsISelection.h"
#include "nsIDOMNodeList.h"
//#include "nsIDOMDocumentRange.h"
#include "nsIDOMDocumentFragment.h"
#include "nsIDOMWindowCollection.h"
#include "nsPIDOMWindow.h"
#include "nsIFocusManager.h"
#include "nsIDocument.h"
#include "nsIPrintSettings.h"
#include "nsIScrollable.h"
static const PRUnichar kSpan[] = L"span";
static const PRUnichar kStyle[] = L"style";
static const PRUnichar kClass[] = L"class";
static const PRUnichar kHighlighClassName[] = L"km_hightlight_class";
static const PRUnichar kDefaultHighlightStyle[] = L"display: inline;font-size: inherit;padding: 0;color: black;background-color: yellow;";
/* */
CBrowserWrapper::CBrowserWrapper(void)
{
//mDomEventListener = nullptr;
mpBrowserImpl = nullptr;
mLastMouseActionNode = nullptr;
mpBrowserImpl = NULL;
mpBrowserFrameGlue = NULL;
mpBrowserGlue = NULL;
mChromeContent = FALSE;
mWndOwner = NULL;
BOOL mIsDocumentLoading = FALSE;
BOOL mIsDOMLoaded = FALSE;
}
CBrowserWrapper::~CBrowserWrapper(void)
{
}
void CBrowserWrapper::SetBrowserGlue(PBROWSERGLUE pBrowserGlue)
{
mpBrowserGlue = pBrowserGlue;
if (mpBrowserImpl)
mpBrowserImpl->Init(mpBrowserGlue, mWebBrowser);
}
void CBrowserWrapper::SetBrowserFrameGlue(PBROWSERFRAMEGLUE pBrowserFrameGlue)
{
mpBrowserFrameGlue = pBrowserFrameGlue;
// if (mpBrowserImpl)
// mpBrowserImpl->Init(pBrowserFrameGlue, mWebBrowser);
}
#include "nsIXPConnect.h"
#include "jsfriendapi.h"
#include "nsJSPrincipals.h"
BOOL CBrowserWrapper::CreateBrowser(CWnd* parent, uint32_t chromeFlags)
{
mChromeContent = chromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME;
mWndOwner = parent;
// Create web shell
nsresult rv;
mWebBrowser = do_CreateInstance(NS_WEBBROWSER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, FALSE);
// Save off the nsIWebNavigation interface pointer
// in the mWebNav member variable which we'll use
// later for web page navigation
mWebNav = do_QueryInterface(mWebBrowser, &rv);
NS_ENSURE_SUCCESS(rv, FALSE);
// Get the focus object
mWebBrowserFocus = do_QueryInterface(mWebBrowser, &rv);
NS_ENSURE_SUCCESS(rv, FALSE);
// Create the CBrowserImpl object - this is the object
// which implements the interfaces which are required
// by an app embedding mozilla i.e. these are the interfaces
// thru' which the *embedded* browser communicates with the
// *embedding* app
//
// The CBrowserImpl object will be passed in to the
// SetContainerWindow() call below
//
// Also note that we're passing the BrowserFrameGlue pointer
// and also the mWebBrowser interface pointer via CBrowserImpl::Init()
// of CBrowserImpl object.
// These pointers will be saved by the CBrowserImpl object.
// The CBrowserImpl object uses the BrowserFrameGlue pointer to
// call the methods on that interface to update the status/progress bars
// etc.
mpBrowserImpl = new CBrowserImpl();
NS_ENSURE_TRUE(mpBrowserImpl, FALSE);
// Pass along the mpBrowserFrameGlue pointer to the BrowserImpl object
// This is the interface thru' which the XP BrowserImpl code communicates
// with the platform specific code to update status bars etc.
mpBrowserImpl->Init(mpBrowserGlue, mWebBrowser);
mpBrowserImpl->SetChromeFlags(chromeFlags);
mpBrowserImpl->AddRef();
mWebBrowser->SetContainerWindow(static_cast<nsIWebBrowserChrome*>(mpBrowserImpl));
nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(mWebBrowser, &rv);
NS_ENSURE_SUCCESS(rv, FALSE);
// XXX Content and chrome dialog are currently the same type of window.
// Set the correct type depending if this window will host chrome or content.
dsti->SetItemType( chromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME ?
nsIDocShellTreeItem::typeChromeWrapper :
nsIDocShellTreeItem::typeContentWrapper);
// Create the real webbrowser window
// Note that we're passing the m_hWnd in the call below to InitWindow()
// (CBrowserView inherits the m_hWnd from CWnd)
// This m_hWnd will be used as the parent window by the embeddable browser
mBaseWindow = do_QueryInterface(mWebBrowser, &rv);
if (NS_FAILED(rv)) {
DestroyBrowser();
return FALSE;
}
CRect rect;
parent->GetClientRect(rect);
rv = mBaseWindow->InitWindow(nsNativeWidget(parent->GetSafeHwnd()), nullptr, 0, 0, rect.Width(), rect.Height());
rv = mBaseWindow->Create();
if (mChromeContent) {
// Eagerly create an about:blank content viewer with the right principal here,
// rather than letting it happening in the upcoming call to
// SetInitialPrincipalToSubject. This avoids creating the about:blank document
// and then blowing it away with a second one, which can cause problems for the
// top-level chrome window case. See bug 789773.
nsCOMPtr<nsIScriptSecurityManager> ssm =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
if (ssm) { // Sometimes this happens really early See bug 793370.
nsCOMPtr<nsIPrincipal> principal;
nsCOMPtr<nsIXPConnect> xpconnect = do_GetService("@mozilla.org/js/xpc/XPConnect;1");
JSContext* cx = xpconnect->GetCurrentJSContext();
if (cx) {
JSCompartment *compartment = js::GetContextCompartment(cx);
if (compartment) {
JSPrincipals *principals = JS_GetCompartmentPrincipals(compartment);
principal = static_cast<nsJSPrincipals *>(principals);
}
}
if (!principal && chromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME) {
ssm->GetSystemPrincipal(getter_AddRefs(principal));
}
rv = GetDocShell()->CreateAboutBlankContentViewer(principal);
NS_ENSURE_SUCCESS(rv, FALSE);
nsCOMPtr<nsIDocument> doc = do_GetInterface(GetDocShell());
NS_ENSURE_TRUE(!!doc, FALSE);
doc->SetIsInitialDocument(true);
}
}
// Register the BrowserImpl object to receive progress messages
// These callbacks will be used to update the status/progress bars
nsCOMPtr<nsIWeakReference> weak = do_GetWeakReference(static_cast<nsIWebProgressListener*>(mpBrowserImpl));
mWebBrowser->AddWebBrowserListener(weak, NS_GET_IID(nsIWebProgressListener));
// Add listeners for various events like popup-blocking, link added ...
AddListeners();
// Find again observer to know when a new search was triggered
/* nsCOMPtr<nsIObserverService> observerService =
do_GetService("@mozilla.org/observer-service;1", &rv);
if (NS_SUCCEEDED(rv))
observerService->AddObserver(mpBrowserImpl, "nsWebBrowserFind_FindAgain", PR_TRUE);*/
//History listener
/* nsWeakPtr weakling2(
do_GetWeakReference(NS_STATIC_CAST(nsISHistoryListener*, mpBrowserImpl)));
(void)mWebBrowser->AddWebBrowserListener(weakling2,
NS_GET_IID(nsISHistoryListener));*/
/*
nsCOMPtr<nsPIDOMWindow> piWin;
// get the content DOM window for that web browser
nsCOMPtr<nsIDOMWindow> domWindow;
mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
if (!domWindow)
return NS_ERROR_FAILURE;
// get the private DOM window
nsCOMPtr<nsPIDOMWindow> domWindowPrivate = do_QueryInterface(domWindow);
// and the root window for that DOM window
piWin = domWindowPrivate->GetPrivateRoot();
nsCOMPtr<nsIDOMEventReceiver> mEventReceiver = do_QueryInterface(piWin->GetChromeEventHandler());
rv = mEventReceiver->AddEventListenerByIID(mpBrowserImpl,
NS_GET_IID(nsIDOMMouseListener));
*/
// Finally, show the web browser window
mBaseWindow->SetVisibility(true);
return TRUE;
}
void CBrowserWrapper::ShowScrollbars(BOOL visible)
{
nsCOMPtr<nsIScrollable> scrollable(do_QueryInterface(GetDocShell()));
NS_ENSURE_TRUE(scrollable, );
if (!visible) {
scrollable->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X, nsIScrollable::Scrollbar_Never);
scrollable->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y, nsIScrollable::Scrollbar_Never);
}
}
BOOL CBrowserWrapper::DestroyBrowser()
{
/* nsresult rv;
nsCOMPtr<nsIObserverService> observerService =
do_GetService("@mozilla.org/observer-service;1", &rv);
if (NS_SUCCEEDED(rv))
observerService->RemoveObserver(mpBrowserImpl, "nsWebBrowserFind_FindAgain");*/
/*nsCOMPtr<nsIWebBrowserPrint> print;
nsIDocShell* shell = GetDocShell();
shell->GetPrintPreview(getter_AddRefs(print));
if (print) {
bool isPreview = false;
print->GetDoingPrintPreview(&isPreview);
if (isPreview)
print->ExitPrintPreview();
}*/
RemoveListeners();
if (mWebNav)
{
mWebNav->Stop(nsIWebNavigation::STOP_ALL);
mWebNav = nullptr;
}
if (mBaseWindow)
{
mBaseWindow->Destroy();
mBaseWindow = nullptr;
}
if (mpBrowserImpl)
{
mpBrowserImpl->Init(NULL, mWebBrowser);
mpBrowserImpl->Release();
mpBrowserImpl = nullptr;
}
return TRUE;
}
BOOL CBrowserWrapper::AddListeners(void)
{
nsresult rv;
rv = GetDOMEventTarget(mWebBrowser, (getter_AddRefs(mEventTarget)));
NS_ENSURE_TRUE(mEventTarget, FALSE);
mWebNav = do_QueryInterface(mWebBrowser);
NS_ENSURE_TRUE(mWebNav, FALSE);
mWebBrowserFocus = do_QueryInterface(mWebBrowser);
NS_ENSURE_TRUE(mWebBrowserFocus, FALSE);
/*mDomEventListener = new CDomEventListener();
if(mDomEventListener == nullptr) return FALSE;
mDomEventListener->Init(mpBrowserFrameGlue);
*/
if (!mChromeContent) {
rv = mEventTarget->AddEventListener(NS_LITERAL_STRING("click"),
mpBrowserImpl, true);
rv = mEventTarget->AddEventListener(NS_LITERAL_STRING("mousedown"),
mpBrowserImpl, true);
rv = mEventTarget->AddEventListener(NS_LITERAL_STRING("keypress"),
mpBrowserImpl, true);
rv = mEventTarget->AddEventListener(NS_LITERAL_STRING("DOMPopupBlocked"),
mpBrowserImpl, false);
rv = mEventTarget->AddEventListener(NS_LITERAL_STRING("DOMLinkAdded"),
mpBrowserImpl, false);
rv = mEventTarget->AddEventListener(NS_LITERAL_STRING("DOMContentLoaded"),
mpBrowserImpl, false);
rv = mEventTarget->AddEventListener(NS_LITERAL_STRING("flashblockCheckLoad"),
mpBrowserImpl, true, true, 2);
rv = mEventTarget->AddEventListener(NS_LITERAL_STRING("contextmenu"),
mpBrowserImpl, false, false);
/*rv = mEventTarget->AddEventListener(NS_LITERAL_STRING("mozfullscreenchange"),
mpBrowserImpl, false);
rv = mEventTarget->AddEventListener(NS_LITERAL_STRING("MozEnteredDomFullscreen"),
mpBrowserImpl, false); */
}
rv = mEventTarget->AddEventListener(NS_LITERAL_STRING("command"),
mpBrowserImpl, false);
return TRUE;
}
void CBrowserWrapper::RemoveListeners(void)
{
NS_ENSURE_TRUE(mEventTarget, );
if (!mChromeContent) {
mEventTarget->RemoveEventListener(NS_LITERAL_STRING("click"),
mpBrowserImpl, false);
mEventTarget->RemoveEventListener(NS_LITERAL_STRING("mousedown"),
mpBrowserImpl, true);
mEventTarget->RemoveEventListener(NS_LITERAL_STRING("keypress"),
mpBrowserImpl, true);
mEventTarget->RemoveEventListener(NS_LITERAL_STRING("DOMPopupBlocked"),
mpBrowserImpl, false);
mEventTarget->RemoveEventListener(NS_LITERAL_STRING("DOMLinkAdded"),
mpBrowserImpl, false);
mEventTarget->RemoveEventListener(NS_LITERAL_STRING("DOMContentLoaded"),
mpBrowserImpl, false);
mEventTarget->RemoveEventListener(NS_LITERAL_STRING("contextmenu"),
mpBrowserImpl, false);
}
mEventTarget->RemoveEventListener(NS_LITERAL_STRING("command"),
mpBrowserImpl, false);
}
BOOL CBrowserWrapper::LoadURL(LPCTSTR url, LPCTSTR referrer, BOOL allowFixup)
{
//ASSERT(url);
ASSERT(mWebNav);
NS_ENSURE_TRUE(url, FALSE);
NS_ENSURE_TRUE(mWebNav, FALSE);
if (!*url) return FALSE;
nsCOMPtr<nsIURI> referrerURI;
if (referrer)
#ifdef _UNICODE
NewURI(getter_AddRefs(referrerURI), nsDependentString(referrer));
#else
NewURI(getter_AddRefs(referrerURI), nsDependentCString(referrer));
#endif
nsresult rv = mWebNav->LoadURI(CStringToPRUnichar(url),
allowFixup ?
nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP :
nsIWebNavigation::LOAD_FLAGS_NONE,
referrerURI,
nullptr,
nullptr);
return NS_SUCCEEDED(rv);
}
BOOL CBrowserWrapper::LoadURL(LPCTSTR url, BOOL currentForRef, BOOL allowFixup)
{
ASSERT(url);
ASSERT(mWebNav);
NS_ENSURE_TRUE(url, FALSE);
NS_ENSURE_TRUE(mWebNav, FALSE);
nsCOMPtr<nsIURI> referrerURI;
if (currentForRef) mWebNav->GetCurrentURI(getter_AddRefs(referrerURI));
nsresult rv = mWebNav->LoadURI(CStringToPRUnichar(url),
allowFixup ?
nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP :
nsIWebNavigation::LOAD_FLAGS_NONE,
referrerURI,
nullptr,
nullptr);
return NS_SUCCEEDED(rv);
}
CString CBrowserWrapper::GetTitle()
{
NS_ENSURE_TRUE(mBaseWindow, _T(""));
PRUnichar *idlStrTitle = nullptr;
mBaseWindow->GetTitle(&idlStrTitle);
NS_ENSURE_TRUE(idlStrTitle, _T(""));
CString title = PRUnicharToCString(idlStrTitle);
nsMemory::Free(idlStrTitle);
return title;
}
CString CBrowserWrapper::GetURI(BOOL unescape)
{
NS_ENSURE_TRUE(mWebNav, _T(""));
nsCOMPtr<nsIURI> currentURI;
nsresult rv = mWebNav->GetCurrentURI(getter_AddRefs(currentURI));
if(NS_FAILED(rv) || !currentURI)
return _T("");
// Get the uri string associated with the nsIURI object
nsCString uriString;
rv = currentURI->GetSpec(uriString);
NS_ENSURE_SUCCESS(rv, _T(""));
if (unescape) {
char* temp = strdup(uriString.get());
uriString.Assign(nsUnescape(temp));
free(temp);
}
return NSUTF8StringToCString(uriString);
}
CString CBrowserWrapper::GetLang()
{
nsresult rv;
nsCOMPtr<nsIDOMWindow> domWindow;
rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
NS_ENSURE_SUCCESS(rv, L"");
nsCOMPtr<nsIDOMDocument> document;
rv = domWindow->GetDocument(getter_AddRefs(document));
NS_ENSURE_SUCCESS(rv, L"");
nsCOMPtr<nsIDOMElement> 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);
// Look for the forced charset
nsresult result;
nsCOMPtr<nsIDocShell> DocShell = GetDocShell();
NS_ENSURE_TRUE(DocShell, FALSE);
nsCOMPtr<nsIContentViewer> contentViewer;
result = DocShell->GetContentViewer (getter_AddRefs(contentViewer));
if (NS_FAILED(result) || !contentViewer)
return FALSE;
nsCString mCharset;
result = contentViewer->GetForceCharacterSet(mCharset);
if (NS_FAILED(result) || mCharset.IsEmpty() )
{
// If no forced charset look for the document charset
nsCString charset;
DocShell->GetCharset(charset);
if (charset.IsEmpty())
{
// If no document charset use default
result = contentViewer->GetHintCharacterSet(mCharset);
}
else
{
mCharset = charset;
}
}
strncpy(aCharset, mCharset.get(), 63);
aCharset[63] = 0;
return NS_SUCCEEDED(result);
}
BOOL CBrowserWrapper::ForceCharset(const char *aCharSet)
{
nsresult result;
nsCOMPtr<nsIDocShell> DocShell = GetDocShell();
NS_ENSURE_TRUE(DocShell, FALSE);
nsCOMPtr<nsIContentViewer> contentViewer;
result = DocShell->GetContentViewer (getter_AddRefs(contentViewer));
if (NS_FAILED(result) || !contentViewer)
return FALSE;
nsCString mCharset;
mCharset = aCharSet;
result = contentViewer->SetForceCharacterSet(mCharset);
if (NS_SUCCEEDED(result))
mWebNav->Reload(nsIWebNavigation::LOAD_FLAGS_CHARSET_CHANGE);
return NS_SUCCEEDED(result);
}
BOOL CBrowserWrapper::ScrollBy(int32_t dx, int32_t dy)
{
nsCOMPtr<nsIDOMWindow> dom;
mWebBrowserFocus->GetFocusedWindow(getter_AddRefs(dom));
if (!dom) {
nsCOMPtr<nsIDOMElement> element;
mWebBrowserFocus->GetFocusedElement(getter_AddRefs(element));
if (element) {
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(element));
}
mWebBrowser->GetContentDOMWindow(getter_AddRefs(dom));
}
NS_ENSURE_TRUE(dom, FALSE);
return NS_SUCCEEDED(dom->ScrollBy (dx, dy));
}
already_AddRefed<nsIContentViewer> CBrowserWrapper::GetContentViewer()
{
nsresult rv;
nsCOMPtr<nsIDocShell> docShell = GetDocShell();
NS_ENSURE_TRUE(docShell, NULL);
nsCOMPtr<nsIContentViewer> contentViewer;
rv = docShell->GetContentViewer(getter_AddRefs(contentViewer));
NS_ENSURE_SUCCESS(rv, NULL);
return contentViewer.forget();
}
BOOL CBrowserWrapper::SetFullZoom(float textzoom)
{
nsCOMPtr<nsIContentViewer> markupViewer = GetContentViewer();
NS_ENSURE_TRUE(markupViewer, FALSE);
nsresult rv = markupViewer->SetFullZoom(textzoom);
return NS_SUCCEEDED(rv);
}
float CBrowserWrapper::GetFullZoom()
{
nsCOMPtr<nsIContentViewer> markupViewer = GetContentViewer();
NS_ENSURE_TRUE(markupViewer, FALSE);
float textzoom;
nsresult rv = markupViewer->GetFullZoom(&textzoom);
return NS_SUCCEEDED(rv) ? textzoom : -1;
}
BOOL CBrowserWrapper::ChangeFullZoom(int change)
{
float textzoom = GetFullZoom();
if (textzoom == -1)
return FALSE;
textzoom = (textzoom*10 + (float)change) / 10;
if (textzoom <0.1 || textzoom > 4)
return FALSE;
SetFullZoom(textzoom);
CString status;
status.Format(IDS_FULL_ZOOM, textzoom*10);
mpBrowserImpl->SetStatus(0, CStringToPRUnichar(status));
return TRUE;
}
BOOL CBrowserWrapper::SetTextSize(float textzoom)
{
nsresult rv;
nsCOMPtr<nsIDOMWindow> domWindow;
rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
NS_ENSURE_SUCCESS(rv, FALSE);
rv = domWindow->SetTextZoom(textzoom);
return NS_SUCCEEDED(rv);
}
float CBrowserWrapper::GetTextSize()
{
nsresult rv;
nsCOMPtr<nsIDOMWindow> domWindow;
rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
NS_ENSURE_SUCCESS(rv, -1);
float textzoom;
rv = domWindow->GetTextZoom(&textzoom);
return NS_SUCCEEDED(rv) ? textzoom : -1;
}
BOOL CBrowserWrapper::ChangeTextSize(int change)
{
float textzoom = GetTextSize();
if (textzoom == -1)
return FALSE;
textzoom = (textzoom*10 + (float)change) / 10;
if (textzoom <=0 || textzoom > 4)
return FALSE;
SetTextSize(textzoom);
CString status;
status.Format(IDS_TEXT_ZOOM, textzoom*10);
mpBrowserImpl->SetStatus(0, CStringToPRUnichar(status));
return TRUE;
}
BOOL CBrowserWrapper::GetSHistory(nsISHistory **aSHistory)
{
// XXX: Prevent crash with message send when browser is closing
NS_ENSURE_TRUE(mWebNav, FALSE);
nsCOMPtr<nsISHistory> sHistory;
mWebNav->GetSessionHistory(getter_AddRefs(sHistory));
NS_ENSURE_TRUE(sHistory, FALSE);
*aSHistory = sHistory.get();
NS_IF_ADDREF(*aSHistory);
return TRUE;
}
BOOL CBrowserWrapper::CloneSHistory(CBrowserWrapper* newWebBrowser)
{
nsCOMPtr<nsISHistory> oldSH;
GetSHistory(getter_AddRefs(oldSH));
NS_ENSURE_TRUE(oldSH, FALSE);
PRInt32 count;
oldSH->GetCount(&count);
if (!count) {
newWebBrowser->LoadURL(_T("about:blank"));
return TRUE;
}
nsCOMPtr<nsISHistory> newSH;
newWebBrowser->GetSHistory(getter_AddRefs(newSH));
NS_ENSURE_TRUE(newSH, FALSE);
nsCOMPtr<nsISHistoryInternal> newSHInternal(do_QueryInterface(newSH));
NS_ENSURE_TRUE(newSHInternal, FALSE);
nsCOMPtr<nsISHEntry> she;
for (int i=0;i<count;i++)
{
oldSH->GetEntryAtIndex(i, PR_FALSE, getter_AddRefs(she));
if (she) {
nsCOMPtr<nsISHEntry> newSHEntry;
nsCOMPtr<nsISHEntry> shee(do_QueryInterface(she));
shee->Clone(getter_AddRefs(newSHEntry));
if (newSHEntry) newSHInternal->AddEntry(newSHEntry, PR_TRUE);
}
}
PRInt32 index;
oldSH->GetIndex(&index);
newWebBrowser->GotoHistoryIndex(index);
return TRUE;
}
BOOL CBrowserWrapper::GotoHistoryIndex(UINT index)
{
NS_ENSURE_TRUE(mWebNav, FALSE);
return NS_SUCCEEDED(mWebNav->GotoIndex (index));
}
BOOL CBrowserWrapper::GetSHistoryState(int& index, int& count)
{
NS_ENSURE_TRUE (mWebBrowser, FALSE);
nsCOMPtr<nsISHistory> sHistory;
mWebNav->GetSessionHistory(getter_AddRefs(sHistory));
NS_ENSURE_TRUE(sHistory, FALSE);
sHistory->GetCount(&count);
sHistory->GetIndex(&index);
return TRUE;
}
BOOL CBrowserWrapper::GetSHistoryInfoAt(PRInt32 index, CString& title, CString& url)
{
NS_ENSURE_TRUE(mWebBrowser, FALSE);
nsCOMPtr<nsISHistory> sHistory;
mWebNav->GetSessionHistory(getter_AddRefs(sHistory));
NS_ENSURE_TRUE(sHistory, FALSE);
nsCOMPtr<nsISHEntry> he;
sHistory->GetEntryAtIndex(index, PR_FALSE, getter_AddRefs(he));
if (!he) return false;
nsresult rv;
nsCString nsUrl;
PRUnichar* nsTitle;
rv = he->GetTitle(&nsTitle);
NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && title, FALSE);
title = PRUnicharToCString(nsTitle);
nsMemory::Free(nsTitle);
nsCOMPtr<nsIURI> uri;
he->GetURI(getter_AddRefs(uri));
NS_ENSURE_TRUE(uri, FALSE);
rv = uri->GetSpec(nsUrl);
url = NSUTF8StringToCString(nsUrl);
NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && url.GetLength(), FALSE);
return TRUE;
}
void CBrowserWrapper::PrintSetup()
{
if (!mPrintSettings) InitPrintSettings();
CPrintSetupDialog dlg(mWndOwner);
dlg.SetPrintSettings(mPrintSettings);
if (dlg.DoModal() != IDOK) return;
dlg.GetPrintSettings(mPrintSettings);
nsCOMPtr<nsIPrintSettingsService> psService =
do_GetService("@mozilla.org/gfx/printsettings-service;1");
NS_ENSURE_TRUE(psService, );
psService->SavePrintSettingsToPrefs(mPrintSettings, PR_FALSE, nsIPrintSettings::kInitSaveAll);
nsCOMPtr<nsIWebBrowserPrint> print(do_GetInterface(mWebBrowser));
NS_ENSURE_TRUE(print, );
bool isPreview = PR_FALSE;
nsresult rv = print->GetDoingPrintPreview(&isPreview);
NS_ENSURE_SUCCESS(rv, );
if (isPreview)
{
if (NS_SUCCEEDED(print->PrintPreview(mPrintSettings, nullptr, nullptr)))
{
// WORKAROUND - FIX ME: Why the print preview doesn't use all the width?
// So I'm forcing the window to reposition itself.
CRect rect;
mWndOwner->GetClientRect(rect);
mBaseWindow->SetPositionAndSize(0, 0, rect.right, rect.bottom, PR_TRUE);
}
}
}
BOOL CBrowserWrapper::Print()
{
NS_ENSURE_TRUE(mWebBrowser, FALSE);
nsCOMPtr<nsIWebBrowserPrint> print(do_GetInterface(mWebBrowser));
NS_ENSURE_TRUE(print, FALSE);
if (!mPrintSettings) InitPrintSettings();
mpBrowserImpl->mIsPrinting = true;
CPrintProgressDialog dlg(mWndOwner);
nsresult rv = print->Print(mPrintSettings, static_cast<nsIWebProgressListener*>(dlg.m_PrintListener.get()));
NS_ENSURE_SUCCESS(rv, FALSE);
mpBrowserImpl->mIsPrinting = false;
if (dlg.DoModal() != IDOK) {
print->Cancel();
return FALSE;
}
return TRUE;
}
BOOL CBrowserWrapper::InitPrintSettings()
{
nsCOMPtr<nsIPrintSettingsService> psService =
do_GetService("@mozilla.org/gfx/printsettings-service;1");
NS_ENSURE_TRUE(psService, FALSE);
nsresult rv;
if (theApp.preferences.GetBool("print.use_global_printsettings", false)) {
psService->GetGlobalPrintSettings(getter_AddRefs(mPrintSettings));
NS_ENSURE_TRUE(mPrintSettings, FALSE);
nsString name;
mPrintSettings->GetPrinterName(getter_Copies(name));
if (name.IsEmpty()) {
psService->GetDefaultPrinterName(getter_Copies(name));
mPrintSettings->SetPrinterName(name.get());
}
psService->InitPrintSettingsFromPrinter(name.get(), mPrintSettings);
rv = psService->InitPrintSettingsFromPrefs(mPrintSettings, true, nsIPrintSettings::kInitSaveAll);
} else
rv = psService->GetNewPrintSettings(getter_AddRefs(mPrintSettings));
return NS_SUCCEEDED(rv);
}
#include "BrowserFrm.h"
#include "BrowserView.h"
BOOL CBrowserWrapper::PrintPreview()
{
nsCOMPtr<nsIWebBrowserPrint> print;
if (!mPrintSettings) InitPrintSettings();
nsCOMPtr<nsIDOMWindow> dom;
nsresult rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(dom));
NS_ENSURE_SUCCESS(rv, FALSE);
CBrowserFrame* frm = theApp.CreateNewBrowserFrame(
nsIWebBrowserChrome::CHROME_DEFAULT, false,
CWnd::FromHandle(mpBrowserGlue->GetBrowserFrameNativeWnd()));
frm->GetActiveView()->OpenURL(L"about:blank");
nsIDocShell* shell = frm->GetActiveView()->GetBrowserWrapper()->GetDocShell();
if (shell) shell->GetPrintPreview(getter_AddRefs(print));
if (!print) {
frm->DestroyWindow();
return FALSE;
}
frm->ShowWindow(SW_SHOW);
rv = print->PrintPreview(mPrintSettings, dom, nullptr);
// WORKAROUND - FIX ME: Why the print preview doesn't use all the width?
// So I'm forcing the window to reposition itself.
CRect rect;
mWndOwner->GetClientRect(rect);
mBaseWindow->SetPositionAndSize(0, 0, rect.right, rect.bottom, PR_TRUE);
return NS_SUCCEEDED(rv);
}
BOOL CBrowserWrapper::_InjectCSS(nsIDOMWindow* dom, const wchar_t* userStyleSheet)
{
if (!dom) return FALSE;
nsresult rv;
nsCOMPtr<nsIDOMDocument> document;
rv = dom->GetDocument(getter_AddRefs(document));
NS_ENSURE_SUCCESS(rv, FALSE);
nsCOMPtr<nsIDOMElement> styleElement;
rv = document->CreateElement(nsDependentString(L"style"), getter_AddRefs(styleElement));
NS_ENSURE_SUCCESS(rv, FALSE);
nsCOMPtr<nsIDOMText> textStyle;
rv = document->CreateTextNode(nsDependentString(userStyleSheet), getter_AddRefs(textStyle));
NS_ENSURE_SUCCESS(rv, FALSE);
nsCOMPtr<nsIDOMNode> notused;
rv = styleElement->AppendChild(textStyle, getter_AddRefs(notused));
NS_ENSURE_SUCCESS(rv, FALSE);
nsCOMPtr<nsIDOMNodeList> headList;
rv = document->GetElementsByTagName(nsDependentString(L"head"), getter_AddRefs(headList));
if (headList)
{
nsCOMPtr<nsIDOMNode> headNode;
rv = headList->Item(0, getter_AddRefs(headNode));
NS_ENSURE_TRUE(headNode, FALSE);
rv = headNode->AppendChild(styleElement, getter_AddRefs(notused));
}
else
{
nsCOMPtr<nsIDOMElement> documentElement;
document->GetDocumentElement(getter_AddRefs(documentElement));
rv = documentElement->AppendChild(styleElement, getter_AddRefs(notused));
}
BOOL b = TRUE;
nsCOMPtr<nsIDOMWindowCollection> frames;
dom->GetFrames(getter_AddRefs(frames));
if (frames)
{
PRUint32 nbframes;
frames->GetLength(&nbframes);
if (nbframes>0)
{
nsCOMPtr<nsIDOMWindow> frame;
for (PRUint32 i = 0; i<nbframes; i++)
{
rv = frames->Item(i, getter_AddRefs(frame));
if (NS_FAILED(rv)) return FALSE;
b = b && _InjectCSS(frame, userStyleSheet);
}
}
}
return b && NS_SUCCEEDED(rv);
}
BOOL CBrowserWrapper::InjectCSS(const wchar_t* userStyleSheet)
{
nsresult rv;
nsCOMPtr<nsIDOMWindow> dom;
rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(dom));
NS_ENSURE_SUCCESS(rv, FALSE);
// Use a recursive function to inject the CSS in all frames.
return _InjectCSS(dom, userStyleSheet);
}
BOOL CBrowserWrapper::InjectJS(const wchar_t* userScript, CString& result, bool bTopWindow)
{
nsresult rv;
nsCOMPtr<nsIDOMWindow> dom;
if (!bTopWindow)
{
if (mLastMouseActionNode) {
nsCOMPtr<nsIDOMDocument> 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);
}
if (!dom) return FALSE;
return ::InjectJS(dom, userScript, result);
}
BOOL CBrowserWrapper::_GetSelection(nsIDOMWindow* dom, nsAString &aSelText)
{
nsCOMPtr<nsISelection> sel;
dom->GetSelection(getter_AddRefs(sel));
if (sel) {
nsString selText;
nsresult rv = sel->ToString(selText);
NS_ENSURE_SUCCESS(rv, FALSE);
aSelText = selText;
if (aSelText.Length()>0)
return TRUE;
}
BOOL ret = FALSE;
nsCOMPtr<nsIDOMWindowCollection> frames;
dom->GetFrames(getter_AddRefs(frames));
NS_ENSURE_TRUE(frames, FALSE);
PRUint32 nbframes;
frames->GetLength(&nbframes);
if (nbframes>0)
{
nsCOMPtr<nsIDOMWindow> frame;
for (PRUint32 i = 0; i<nbframes; i++)
{
frames->Item(i, getter_AddRefs(frame));
ret = ret || _GetSelection(frame, aSelText);
}
}
return ret;
}
BOOL CBrowserWrapper::GetSelectionInsideForm(nsIDOMElement *element, nsString &aSelText)
{
nsCOMPtr<nsIDOMHTMLInputElement> domnsinput = do_QueryInterface(element);
if (domnsinput)
{
PRInt32 start, end;
nsresult rv;
rv = domnsinput->GetSelectionStart(&start);
NS_ENSURE_SUCCESS(rv, FALSE);
rv = domnsinput->GetSelectionEnd(&end);
NS_ENSURE_SUCCESS(rv, FALSE);
if (start >= end) return FALSE;
nsCOMPtr<nsIDOMHTMLInputElement> dominput = do_QueryInterface(element);
if (!dominput) return FALSE;