зеркало из https://github.com/mozilla/pjs.git
Bug 51470 - [E10s] The tab browser should inform the chrome process during navigation. r=smaug,
sr=bsmedberg
This commit is contained in:
Родитель
5cfc06daae
Коммит
d4d15556ad
|
@ -41,6 +41,7 @@
|
|||
|
||||
interface nsIDocShell;
|
||||
interface nsIURI;
|
||||
interface nsIWebProgress;
|
||||
interface nsIFrame;
|
||||
interface nsIChromeFrameMessageManager;
|
||||
interface nsIVariant;
|
||||
|
@ -53,6 +54,11 @@ interface nsIFrameLoader : nsISupports
|
|||
*/
|
||||
readonly attribute nsIDocShell docShell;
|
||||
|
||||
/**
|
||||
* Get the nsIWebProgress from the frame loader, allowing listener registration.
|
||||
*/
|
||||
readonly attribute nsIWebProgress webProgress;
|
||||
|
||||
/**
|
||||
* Start loading the frame. This method figures out what to load
|
||||
* from the owner content in the frame loader.
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
#include "nsIDOMWindow.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsIWebProgress.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIDocShellTreeNode.h"
|
||||
|
@ -408,6 +409,34 @@ nsFrameLoader::GetDocShell(nsIDocShell **aDocShell)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameLoader::GetWebProgress(nsIWebProgress **aWebProgress)
|
||||
{
|
||||
nsresult rv;
|
||||
*aWebProgress = nsnull;
|
||||
#ifdef MOZ_IPC
|
||||
if (mRemoteFrame) {
|
||||
if (!mChildProcess) {
|
||||
TryNewProcess();
|
||||
}
|
||||
if (!mChildProcess) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
*aWebProgress = mChildProcess;
|
||||
NS_ADDREF(*aWebProgress);
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIDocShell> shell;
|
||||
rv = GetDocShell(getter_AddRefs(shell));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIWebProgress> progress(do_QueryInterface(shell));
|
||||
progress.swap(*aWebProgress);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsFrameLoader::Finalize()
|
||||
{
|
||||
|
@ -683,7 +712,10 @@ nsFrameLoader::ShowRemoteFrame(nsIFrameFrame* frame, nsIView* view)
|
|||
{
|
||||
NS_ASSERTION(mRemoteFrame, "ShowRemote only makes sense on remote frames.");
|
||||
|
||||
TryNewProcess();
|
||||
if (!mChildProcess) {
|
||||
TryNewProcess();
|
||||
}
|
||||
|
||||
if (!mChildProcess) {
|
||||
NS_ERROR("Couldn't create child process.");
|
||||
return false;
|
||||
|
|
|
@ -45,6 +45,7 @@ include $(topsrcdir)/config/rules.mk
|
|||
|
||||
_TEST_FILES = \
|
||||
bug421622-referer.sjs \
|
||||
bug514705.html \
|
||||
$(NULL)
|
||||
|
||||
_CHROME_FILES = \
|
||||
|
@ -53,6 +54,8 @@ _CHROME_FILES = \
|
|||
test_bug429785.xul \
|
||||
test_bug430050.xul \
|
||||
test_bug467123.xul \
|
||||
test_bug514705.xul \
|
||||
bug514705_helper.xul \
|
||||
test_title.xul \
|
||||
title_window.xul \
|
||||
$(NULL)
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>bug514705.html</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
bug514705.html
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,90 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Bug514705 helper"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="RunTest();">
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
var Ci = Components.interfaces;
|
||||
var imports = [ "SimpleTest", "is", "isnot", "ok" ];
|
||||
for each (var import in imports) {
|
||||
window[import] = window.opener.wrappedJSObject[import];
|
||||
}
|
||||
var locationChanged = false;
|
||||
var progressChanged = false;
|
||||
var refreshAttempted = false;
|
||||
|
||||
var listener = {
|
||||
onLocationChange: function(webProgress, request, location) {
|
||||
locationChanged = true;
|
||||
},
|
||||
onProgressChange: function(webProgress, request, curSelfProgress,
|
||||
maxSelfProgress, curTotalProgress,
|
||||
maxTotalProgress) {
|
||||
},
|
||||
onSecurityChange: function(webProgress, request, state) {
|
||||
},
|
||||
onStateChange: function(webProgress, request, stateFlags, status) {
|
||||
|
||||
if ((stateFlags & Ci.nsIWebProgressListener.STATE_STOP) &&
|
||||
(stateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW)) {
|
||||
var test = SimpleTest;
|
||||
ok (locationChanged, "onLocationChanged was called.");
|
||||
ok (progressChanged, "onProgressChanged64 was called.");
|
||||
ok (refreshAttempted, "onRefreshAttempted was called.");
|
||||
ok (true, "onStateChange was called.");
|
||||
window.close();
|
||||
test.finish();
|
||||
}
|
||||
},
|
||||
onStatusChange: function(webProgress, request, status, message) {
|
||||
},
|
||||
onProgressChange64 : function(webProgress, request, curSelfProgress,
|
||||
maxSelfProgress, curTotalProgress,
|
||||
maxTotalProgress) {
|
||||
|
||||
progressChanged = true;
|
||||
},
|
||||
onRefreshAttempted : function(webProgress, uri, millis, sameURI)
|
||||
{
|
||||
refreshAttempted = true;
|
||||
return true;
|
||||
},
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Components.interfaces.nsIWebProgressListener) ||
|
||||
iid.equals(Components.interfaces.nsIWebProgressListener2) ||
|
||||
iid.equals(Components.interfaces.nsISupportsWeakReference)) {
|
||||
return this;
|
||||
}
|
||||
throw Components.results.NS_NOINTERFACE;
|
||||
}
|
||||
}
|
||||
function EndTest() {
|
||||
var test = SimpleTest;
|
||||
window.close();
|
||||
test.finish();
|
||||
}
|
||||
function RunTest()
|
||||
{
|
||||
var browser = document.getElementById('page');
|
||||
var flags = Ci.nsIWebProgress.NOTIFY_ALL;
|
||||
|
||||
browser.webProgress.addProgressListener(listener, flags);
|
||||
|
||||
var script = "refreshURI = docShell.QueryInterface(Components.interfaces.nsIRefreshURI);"
|
||||
+ "var ioServ = Components.classes['@mozilla.org/network/io-service;1'].getService(Components.interfaces.nsIIOService);"
|
||||
+ "var uri = ioServ.newURI('http://localhost:8888/tests/content/base/test/chrome/bug514705.html', null, null);"
|
||||
+ "refreshURI.refreshURI(uri, 100, false, false);";
|
||||
messageManager.loadFrameScript("data:," + script, true);
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
|
||||
<browser type="content" flex="1" id="page" remote="true"/>
|
||||
|
||||
</window>
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window title="Bug 514705"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="RunTest();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"/>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=421622"
|
||||
target="_blank">Mozilla Bug 421622</a>
|
||||
</body>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function RunTest()
|
||||
{
|
||||
window.open("bug514705_helper.xul", "bug514705",
|
||||
"chrome,width=100,height=100");
|
||||
}
|
||||
]]>
|
||||
</script>
|
||||
</window>
|
|
@ -176,13 +176,18 @@ ContentProcessParent::Observe(nsISupports* aSubject,
|
|||
PIFrameEmbeddingParent*
|
||||
ContentProcessParent::AllocPIFrameEmbedding()
|
||||
{
|
||||
return new TabParent();
|
||||
TabParent* parent = new TabParent();
|
||||
if (parent){
|
||||
NS_ADDREF(parent);
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentProcessParent::DeallocPIFrameEmbedding(PIFrameEmbeddingParent* frame)
|
||||
{
|
||||
delete frame;
|
||||
TabParent* parent = static_cast<TabParent*>(frame);
|
||||
NS_RELEASE(parent);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,6 +72,24 @@ parent:
|
|||
|
||||
sendEvent(RemoteDOMEvent aEvent);
|
||||
|
||||
notifyStateChange(PRUint32 stateFlags, nsresult status);
|
||||
|
||||
notifyProgressChange(PRInt64 curSelfProgress,
|
||||
PRInt64 maxSelfProgress,
|
||||
PRInt64 curTotalProgress,
|
||||
PRInt64 maxTotalProgress);
|
||||
|
||||
notifyLocationChange(nsCString uri);
|
||||
|
||||
notifyStatusChange(nsresult status,
|
||||
nsString message);
|
||||
|
||||
notifySecurityChange(PRUint32 aState);
|
||||
|
||||
sync refreshAttempted(nsCString uri, PRInt32 millis,
|
||||
bool sameURI) returns (bool retval);
|
||||
|
||||
|
||||
rpc createWindow() returns (PIFrameEmbedding window);
|
||||
|
||||
PContextWrapper();
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIDOMWindowUtils.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIWebBrowserFocus.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIPrivateDOMEvent.h"
|
||||
|
@ -72,6 +73,7 @@
|
|||
#include "nsPresContext.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_QT
|
||||
#include <QX11EmbedWidget>
|
||||
|
@ -118,6 +120,9 @@ TabChild::Init()
|
|||
}
|
||||
|
||||
webBrowser->SetContainerWindow(this);
|
||||
nsCOMPtr<nsIWeakReference> weak =
|
||||
do_GetWeakReference(static_cast<nsSupportsWeakReference*>(this));
|
||||
webBrowser->AddWebBrowserListener(weak, NS_GET_IID(nsIWebProgressListener));
|
||||
|
||||
mWebNav = do_QueryInterface(webBrowser);
|
||||
NS_ASSERTION(mWebNav, "nsWebBrowser doesn't implement nsIWebNavigation?");
|
||||
|
@ -127,10 +132,11 @@ TabChild::Init()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS7(TabChild, nsIWebBrowserChrome, nsIWebBrowserChrome2,
|
||||
nsIEmbeddingSiteWindow, nsIEmbeddingSiteWindow2,
|
||||
nsIWebBrowserChromeFocus, nsIInterfaceRequestor,
|
||||
nsIWindowProvider)
|
||||
NS_IMPL_ISUPPORTS10(TabChild, nsIWebBrowserChrome, nsIWebBrowserChrome2,
|
||||
nsIEmbeddingSiteWindow, nsIEmbeddingSiteWindow2,
|
||||
nsIWebBrowserChromeFocus, nsIInterfaceRequestor,
|
||||
nsIWindowProvider, nsIWebProgressListener,
|
||||
nsIWebProgressListener2, nsSupportsWeakReference)
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabChild::SetStatus(PRUint32 aStatusType, const PRUnichar* aStatus)
|
||||
|
@ -369,6 +375,94 @@ TabChild::~TabChild()
|
|||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabChild::OnStateChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRUint32 aStateFlags,
|
||||
nsresult aStatus)
|
||||
{
|
||||
SendnotifyStateChange(aStateFlags, aStatus);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Only one of OnProgressChange / OnProgressChange64 will be called.
|
||||
// According to interface, it should be OnProgressChange64, but looks
|
||||
// like docLoader only sends the former.
|
||||
NS_IMETHODIMP
|
||||
TabChild::OnProgressChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt32 aCurSelfProgress,
|
||||
PRInt32 aMaxSelfProgress,
|
||||
PRInt32 aCurTotalProgress,
|
||||
PRInt32 aMaxTotalProgress)
|
||||
{
|
||||
SendnotifyProgressChange(aCurSelfProgress, aMaxSelfProgress,
|
||||
aCurTotalProgress, aMaxTotalProgress);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabChild::OnStatusChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsresult aStatus,
|
||||
const PRUnichar* aMessage)
|
||||
{
|
||||
nsDependentString message(aMessage);
|
||||
SendnotifyStatusChange(aStatus, message);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabChild::OnSecurityChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRUint32 aState)
|
||||
{
|
||||
SendnotifySecurityChange(aState);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabChild::OnLocationChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsIURI *aLocation)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aLocation);
|
||||
nsCString uri;
|
||||
aLocation->GetSpec(uri);
|
||||
SendnotifyLocationChange(uri);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabChild::OnProgressChange64(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt64 aCurSelfProgress,
|
||||
PRInt64 aMaxSelfProgress,
|
||||
PRInt64 aCurTotalProgress,
|
||||
PRInt64 aMaxTotalProgress)
|
||||
{
|
||||
SendnotifyProgressChange(aCurSelfProgress, aMaxSelfProgress,
|
||||
aCurTotalProgress, aMaxTotalProgress);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabChild::OnRefreshAttempted(nsIWebProgress *aWebProgress,
|
||||
nsIURI *aURI, PRInt32 aMillis,
|
||||
PRBool aSameURL, PRBool *aRefreshAllowed)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aURI);
|
||||
nsCString uri;
|
||||
aURI->GetSpec(uri);
|
||||
bool sameURL = aSameURL;
|
||||
bool refreshAllowed;
|
||||
SendrefreshAttempted(uri, aMillis, sameURL, &refreshAllowed);
|
||||
*aRefreshAllowed = refreshAllowed;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
TabChild::RecvloadURL(const nsCString& uri)
|
||||
{
|
||||
|
|
|
@ -48,6 +48,8 @@
|
|||
#include "nsIWebBrowserChrome2.h"
|
||||
#include "nsIEmbeddingSiteWindow2.h"
|
||||
#include "nsIWebBrowserChromeFocus.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsIWebProgressListener2.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
|
@ -65,6 +67,7 @@
|
|||
#include "nsIPrincipal.h"
|
||||
#include "nsIScriptObjectPrincipal.h"
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
class gfxMatrix;
|
||||
|
||||
|
@ -138,11 +141,13 @@ protected:
|
|||
};
|
||||
|
||||
class TabChild : public PIFrameEmbeddingChild,
|
||||
public nsIWebProgressListener2,
|
||||
public nsIWebBrowserChrome2,
|
||||
public nsIEmbeddingSiteWindow2,
|
||||
public nsIWebBrowserChromeFocus,
|
||||
public nsIInterfaceRequestor,
|
||||
public nsIWindowProvider
|
||||
public nsIWindowProvider,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
TabChild();
|
||||
|
@ -151,6 +156,8 @@ public:
|
|||
nsresult Init();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER2
|
||||
NS_DECL_NSIWEBBROWSERCHROME
|
||||
NS_DECL_NSIWEBBROWSERCHROME2
|
||||
NS_DECL_NSIEMBEDDINGSITEWINDOW
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*- */
|
||||
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8; -*- */
|
||||
/* vim: set sw=4 ts=8 et tw=80 : */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
|
@ -52,7 +52,9 @@
|
|||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIPrivateDOMEvent.h"
|
||||
#include "nsIWebProgressListener2.h"
|
||||
#include "nsFrameLoader.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
using mozilla::ipc::DocumentRendererParent;
|
||||
using mozilla::ipc::DocumentRendererShmemParent;
|
||||
|
@ -60,9 +62,15 @@ using mozilla::dom::ContentProcessParent;
|
|||
using mozilla::jsipc::PContextWrapperParent;
|
||||
using mozilla::jsipc::ContextWrapperParent;
|
||||
|
||||
// The flags passed by the webProgress notifications are 16 bits shifted
|
||||
// from the ones registered by webProgressListeners.
|
||||
#define NOTIFY_FLAG_SHIFT 16
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_ISUPPORTS1(TabParent, nsIWebProgress)
|
||||
|
||||
TabParent::TabParent()
|
||||
{
|
||||
}
|
||||
|
@ -99,6 +107,240 @@ TabParent::RecvsendEvent(const RemoteDOMEvent& aEvent)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvnotifyProgressChange(const PRInt64& aProgress,
|
||||
const PRInt64& aProgressMax,
|
||||
const PRInt64& aTotalProgress,
|
||||
const PRInt64& aMaxTotalProgress)
|
||||
{
|
||||
/*
|
||||
* First notify any listeners of the new progress info...
|
||||
*
|
||||
* Operate the elements from back to front so that if items get
|
||||
* get removed from the list it won't affect our iteration
|
||||
*/
|
||||
nsCOMPtr<nsIWebProgressListener> listener;
|
||||
PRUint32 count = mListenerInfoList.Length();
|
||||
|
||||
while (count-- > 0) {
|
||||
TabParentListenerInfo *info = &mListenerInfoList[count];
|
||||
if (!(info->mNotifyMask & nsIWebProgress::NOTIFY_PROGRESS)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
listener = do_QueryReferent(info->mWeakListener);
|
||||
if (!listener) {
|
||||
// the listener went away. gracefully pull it out of the list.
|
||||
mListenerInfoList.RemoveElementAt(count);
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWebProgressListener2> listener2 =
|
||||
do_QueryReferent(info->mWeakListener);
|
||||
if (listener2) {
|
||||
listener2->OnProgressChange64(this, nsnull, aProgress, aProgressMax,
|
||||
aTotalProgress, aMaxTotalProgress);
|
||||
} else {
|
||||
listener->OnProgressChange(this, nsnull, PRInt32(aProgress),
|
||||
PRInt32(aProgressMax),
|
||||
PRInt32(aTotalProgress),
|
||||
PRInt32(aMaxTotalProgress));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvnotifyStateChange(const PRUint32& aStateFlags,
|
||||
const nsresult& aStatus)
|
||||
{
|
||||
/*
|
||||
* First notify any listeners of the new state info...
|
||||
*
|
||||
* Operate the elements from back to front so that if items get
|
||||
* get removed from the list it won't affect our iteration
|
||||
*/
|
||||
nsCOMPtr<nsIWebProgressListener> listener;
|
||||
PRUint32 count = mListenerInfoList.Length();
|
||||
|
||||
while (count-- > 0) {
|
||||
TabParentListenerInfo *info = &mListenerInfoList[count];
|
||||
|
||||
// The flags used in listener registration are shifted over
|
||||
// 16 bits from the ones sent in the notification, so we shift
|
||||
// to see if the listener is interested in this change.
|
||||
// Note that the flags are not changed in the notification we
|
||||
// send along. Flags are defined in nsIWebProgressListener and
|
||||
// nsIWebProgress.
|
||||
// See nsDocLoader for another example of this.
|
||||
if (!(info->mNotifyMask & (aStateFlags >> NOTIFY_FLAG_SHIFT))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
listener = do_QueryReferent(info->mWeakListener);
|
||||
if (!listener) {
|
||||
// the listener went away. gracefully pull it out of the list.
|
||||
mListenerInfoList.RemoveElementAt(count);
|
||||
continue;
|
||||
}
|
||||
|
||||
listener->OnStateChange(this, nsnull, aStateFlags, aStatus);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvnotifyLocationChange(const nsCString& aUri)
|
||||
{
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), aUri);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* First notify any listeners of the new state info...
|
||||
*
|
||||
* Operate the elements from back to front so that if items get
|
||||
* get removed from the list it won't affect our iteration
|
||||
*/
|
||||
nsCOMPtr<nsIWebProgressListener> listener;
|
||||
PRUint32 count = mListenerInfoList.Length();
|
||||
|
||||
while (count-- > 0) {
|
||||
TabParentListenerInfo *info = &mListenerInfoList[count];
|
||||
if (!(info->mNotifyMask & nsIWebProgress::NOTIFY_LOCATION)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
listener = do_QueryReferent(info->mWeakListener);
|
||||
if (!listener) {
|
||||
// the listener went away. gracefully pull it out of the list.
|
||||
mListenerInfoList.RemoveElementAt(count);
|
||||
continue;
|
||||
}
|
||||
|
||||
listener->OnLocationChange(this, nsnull, uri);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvnotifyStatusChange(const nsresult& status,
|
||||
const nsString& message)
|
||||
{
|
||||
/*
|
||||
* First notify any listeners of the new state info...
|
||||
*
|
||||
* Operate the elements from back to front so that if items get
|
||||
* get removed from the list it won't affect our iteration
|
||||
*/
|
||||
nsCOMPtr<nsIWebProgressListener> listener;
|
||||
PRUint32 count = mListenerInfoList.Length();
|
||||
|
||||
while (count-- > 0) {
|
||||
TabParentListenerInfo *info = &mListenerInfoList[count];
|
||||
if (!(info->mNotifyMask & nsIWebProgress::NOTIFY_STATUS)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
listener = do_QueryReferent(info->mWeakListener);
|
||||
if (!listener) {
|
||||
// the listener went away. gracefully pull it out of the list.
|
||||
mListenerInfoList.RemoveElementAt(count);
|
||||
continue;
|
||||
}
|
||||
|
||||
listener->OnStatusChange(this, nsnull, status, message.BeginReading());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvnotifySecurityChange(const PRUint32& aState)
|
||||
{
|
||||
/*
|
||||
* First notify any listeners of the new state info...
|
||||
*
|
||||
* Operate the elements from back to front so that if items get
|
||||
* get removed from the list it won't affect our iteration
|
||||
*/
|
||||
|
||||
nsCOMPtr<nsIWebProgressListener> listener;
|
||||
PRUint32 count = mListenerInfoList.Length();
|
||||
|
||||
while (count-- > 0) {
|
||||
TabParentListenerInfo *info = &mListenerInfoList[count];
|
||||
if (!(info->mNotifyMask & nsIWebProgress::NOTIFY_SECURITY)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
listener = do_QueryReferent(info->mWeakListener);
|
||||
if (!listener) {
|
||||
// the listener went away. gracefully pull it out of the list.
|
||||
mListenerInfoList.RemoveElementAt(count);
|
||||
continue;
|
||||
}
|
||||
|
||||
listener->OnSecurityChange(this, nsnull, aState);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvrefreshAttempted(const nsCString& aURI, const PRInt32& aMillis,
|
||||
const bool& aSameURI, bool* refreshAllowed)
|
||||
{
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), aURI);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
* First notify any listeners of the new state info...
|
||||
*
|
||||
* Operate the elements from back to front so that if items get
|
||||
* get removed from the list it won't affect our iteration
|
||||
*/
|
||||
|
||||
nsCOMPtr<nsIWebProgressListener> listener;
|
||||
PRUint32 count = mListenerInfoList.Length();
|
||||
|
||||
*refreshAllowed = true;
|
||||
while (count-- > 0) {
|
||||
TabParentListenerInfo *info = &mListenerInfoList[count];
|
||||
if (!(info->mNotifyMask & nsIWebProgress::NOTIFY_REFRESH)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
listener = do_QueryReferent(info->mWeakListener);
|
||||
if (!listener) {
|
||||
// the listener went away. gracefully pull it out of the list.
|
||||
mListenerInfoList.RemoveElementAt(count);
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWebProgressListener2> listener2 =
|
||||
do_QueryReferent(info->mWeakListener);
|
||||
if (!listener2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// some listeners don't seem to set this at all...
|
||||
PRBool allowed = true;
|
||||
listener2->OnRefreshAttempted(this, uri,
|
||||
aMillis, aSameURI, &allowed);
|
||||
*refreshAllowed = allowed && *refreshAllowed;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::AnswercreateWindow(PIFrameEmbeddingParent** retval)
|
||||
{
|
||||
|
@ -266,5 +508,77 @@ TabParent::RecvsendAsyncMessageToParent(const nsString& aMessage,
|
|||
return true;
|
||||
}
|
||||
|
||||
// nsIWebProgress
|
||||
nsresult
|
||||
TabParent::AddProgressListener(nsIWebProgressListener* aListener,
|
||||
PRUint32 aNotifyMask)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
TabParentListenerInfo* info = GetListenerInfo(aListener);
|
||||
if (info) {
|
||||
// The listener is already registered!
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsWeakPtr listener = do_GetWeakReference(aListener);
|
||||
if (!listener) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
info = new TabParentListenerInfo(listener, aNotifyMask);
|
||||
if (!info) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
rv = mListenerInfoList.AppendElement(*info) ? NS_OK : NS_ERROR_FAILURE;
|
||||
if (NS_FAILED(rv)) {
|
||||
delete info;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabParent::RemoveProgressListener(nsIWebProgressListener *aListener)
|
||||
{
|
||||
nsAutoPtr<TabParentListenerInfo> info(GetListenerInfo(aListener));
|
||||
|
||||
return info && mListenerInfoList.RemoveElement(*info) ?
|
||||
NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
TabParentListenerInfo *
|
||||
TabParent::GetListenerInfo(nsIWebProgressListener *aListener)
|
||||
{
|
||||
PRUint32 i, count;
|
||||
TabParentListenerInfo *info;
|
||||
|
||||
nsCOMPtr<nsISupports> listener1 = do_QueryInterface(aListener);
|
||||
count = mListenerInfoList.Length();
|
||||
for (i = 0; i < count; ++i) {
|
||||
info = &mListenerInfoList[i];
|
||||
|
||||
if (info) {
|
||||
nsCOMPtr<nsISupports> listener2 = do_QueryReferent(info->mWeakListener);
|
||||
if (listener1 == listener2) {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabParent::GetDOMWindow(nsIDOMWindow **aResult)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabParent::GetIsLoadingDocument(PRBool *aIsLoadingDocument)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
} // namespace tabs
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -45,6 +45,9 @@
|
|||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIBrowserDOMWindow.h"
|
||||
#include "nsIWebProgress.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
class nsIURI;
|
||||
class nsIDOMElement;
|
||||
|
@ -60,8 +63,30 @@ class PContextWrapperParent;
|
|||
}
|
||||
|
||||
namespace dom {
|
||||
struct TabParentListenerInfo
|
||||
{
|
||||
TabParentListenerInfo(nsIWeakReference *aListener, unsigned long aNotifyMask)
|
||||
: mWeakListener(aListener), mNotifyMask(aNotifyMask)
|
||||
{
|
||||
}
|
||||
|
||||
class TabParent : public PIFrameEmbeddingParent
|
||||
TabParentListenerInfo(const TabParentListenerInfo& obj)
|
||||
: mWeakListener(obj.mWeakListener), mNotifyMask(obj.mNotifyMask)
|
||||
{
|
||||
}
|
||||
|
||||
nsWeakPtr mWeakListener;
|
||||
|
||||
PRUint32 mNotifyMask;
|
||||
};
|
||||
|
||||
inline
|
||||
bool operator==(const TabParentListenerInfo& lhs, const TabParentListenerInfo& rhs)
|
||||
{
|
||||
return &lhs == &rhs;
|
||||
}
|
||||
|
||||
class TabParent : public PIFrameEmbeddingParent, public nsIWebProgress
|
||||
{
|
||||
public:
|
||||
TabParent();
|
||||
|
@ -73,6 +98,21 @@ public:
|
|||
|
||||
virtual bool RecvmoveFocus(const bool& aForward);
|
||||
virtual bool RecvsendEvent(const RemoteDOMEvent& aEvent);
|
||||
virtual bool RecvnotifyProgressChange(const PRInt64& aProgress,
|
||||
const PRInt64& aProgressMax,
|
||||
const PRInt64& aTotalProgress,
|
||||
const PRInt64& aMaxTotalProgress);
|
||||
virtual bool RecvnotifyStateChange(const PRUint32& aStateFlags,
|
||||
const nsresult& aStatus);
|
||||
virtual bool RecvnotifyLocationChange(const nsCString& aUri);
|
||||
virtual bool RecvnotifyStatusChange(const nsresult& status,
|
||||
const nsString& message);
|
||||
virtual bool RecvnotifySecurityChange(const PRUint32& aState);
|
||||
virtual bool RecvrefreshAttempted(const nsCString& aURI,
|
||||
const PRInt32& aMillis,
|
||||
const bool& aSameURI,
|
||||
bool* aAllowRefresh);
|
||||
|
||||
virtual bool AnswercreateWindow(PIFrameEmbeddingParent** retval);
|
||||
virtual bool RecvsendSyncMessageToParent(const nsString& aMessage,
|
||||
const nsString& aJSON,
|
||||
|
@ -119,9 +159,16 @@ public:
|
|||
|
||||
bool GetGlobalJSObject(JSContext* cx, JSObject** globalp);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBPROGRESS
|
||||
|
||||
protected:
|
||||
TabParentListenerInfo* GetListenerInfo(nsIWebProgressListener *aListener);
|
||||
|
||||
nsIDOMElement* mFrameElement;
|
||||
nsCOMPtr<nsIBrowserDOMWindow> mBrowserDOMWindow;
|
||||
|
||||
nsTArray<TabParentListenerInfo> mListenerInfoList;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -312,7 +312,7 @@
|
|||
|
||||
<property name="webProgress"
|
||||
readonly="true"
|
||||
onget="return this.docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebProgress);"/>
|
||||
onget="return this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader.webProgress;"/>
|
||||
|
||||
<field name="_contentWindow">null</field>
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче