зеркало из https://github.com/mozilla/pjs.git
Bug 449778. Don't fire pageshow in the new place on viewer swap if it's about to fire anyway. Do fire it in the old spot in that case, though. r+sr=jst
This commit is contained in:
Родитель
fbf7f59473
Коммит
a7080c05c8
|
@ -97,8 +97,8 @@ class nsFrameLoader;
|
|||
|
||||
// IID for the nsIDocument interface
|
||||
#define NS_IDOCUMENT_IID \
|
||||
{ 0x92b19d1c, 0x8f37, 0x4d4b, \
|
||||
{ 0xa3, 0x42, 0xb5, 0xc6, 0x8b, 0x54, 0xde, 0x6c } }
|
||||
{ 0x29f7a5d7, 0xb217, 0x4ea2, \
|
||||
{0x95, 0x40, 0x46, 0x41, 0xb9, 0xf5, 0x99, 0xd9 } }
|
||||
|
||||
// Flag for AddStyleSheet().
|
||||
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
|
||||
|
@ -1097,6 +1097,13 @@ public:
|
|||
*/
|
||||
virtual void EnumerateExternalResources(nsSubDocEnumFunc aCallback,
|
||||
void* aData) = 0;
|
||||
|
||||
/**
|
||||
* Return whether the document is currently showing (in the sense of
|
||||
* OnPageShow() having been called already and OnPageHide() not having been
|
||||
* called yet.
|
||||
*/
|
||||
PRBool IsShowing() { return mIsShowing; }
|
||||
|
||||
protected:
|
||||
~nsIDocument()
|
||||
|
@ -1171,6 +1178,9 @@ protected:
|
|||
// True iff we've ever fired a DOMTitleChanged event for this document
|
||||
PRPackedBool mHaveFiredTitleChange;
|
||||
|
||||
// True iff IsShowing() should be returning true
|
||||
PRPackedBool mIsShowing;
|
||||
|
||||
// The bidi options for this document. What this bitfield means is
|
||||
// defined in nsBidiUtils.h
|
||||
PRUint32 mBidiOptions;
|
||||
|
|
|
@ -7095,6 +7095,10 @@ nsDocument::OnPageShow(PRBool aPersisted)
|
|||
}
|
||||
}
|
||||
|
||||
// Set mIsShowing before firing events, in case those event handlers
|
||||
// move us around.
|
||||
mIsShowing = PR_TRUE;
|
||||
|
||||
nsPageTransitionEvent event(PR_TRUE, NS_PAGE_SHOW, aPersisted);
|
||||
DispatchEventToWindow(&event);
|
||||
}
|
||||
|
@ -7121,6 +7125,10 @@ nsDocument::OnPageHide(PRBool aPersisted)
|
|||
}
|
||||
}
|
||||
|
||||
// Set mIsShowing before firing events, in case those event handlers
|
||||
// move us around.
|
||||
mIsShowing = PR_FALSE;
|
||||
|
||||
// Now send out a PageHide event.
|
||||
nsPageTransitionEvent event(PR_TRUE, NS_PAGE_HIDE, aPersisted);
|
||||
DispatchEventToWindow(&event);
|
||||
|
|
|
@ -313,9 +313,14 @@ FirePageHideEvent(nsIDocShellTreeItem* aItem,
|
|||
}
|
||||
}
|
||||
|
||||
// The pageshow event is fired for a given document only if IsShowing() returns
|
||||
// the same thing as aFireIfShowing. This gives us a way to fire pageshow only
|
||||
// on documents that are still loading or only on documents that are already
|
||||
// loaded.
|
||||
static void
|
||||
FirePageShowEvent(nsIDocShellTreeItem* aItem,
|
||||
nsIDOMEventTarget* aChromeEventHandler)
|
||||
nsIDOMEventTarget* aChromeEventHandler,
|
||||
PRBool aFireIfShowing)
|
||||
{
|
||||
PRInt32 childCount = 0;
|
||||
aItem->GetChildCount(&childCount);
|
||||
|
@ -327,14 +332,18 @@ FirePageShowEvent(nsIDocShellTreeItem* aItem,
|
|||
|
||||
for (PRUint32 i = 0; i < kids.Length(); ++i) {
|
||||
if (kids[i]) {
|
||||
FirePageShowEvent(kids[i], aChromeEventHandler);
|
||||
FirePageShowEvent(kids[i], aChromeEventHandler, aFireIfShowing);
|
||||
}
|
||||
}
|
||||
|
||||
nsPageTransitionEvent event(PR_TRUE, NS_PAGE_SHOW, PR_TRUE);
|
||||
nsCOMPtr<nsIDOMDocument> doc = do_GetInterface(aItem);
|
||||
event.target = do_QueryInterface(doc);
|
||||
nsEventDispatcher::Dispatch(aChromeEventHandler, nsnull, &event);
|
||||
nsCOMPtr<nsIDocument> internalDoc = do_QueryInterface(doc);
|
||||
NS_ASSERTION(internalDoc, "What happened here?");
|
||||
if (internalDoc->IsShowing() == aFireIfShowing) {
|
||||
nsPageTransitionEvent event(PR_TRUE, NS_PAGE_SHOW, PR_TRUE);
|
||||
event.target = do_QueryInterface(doc);
|
||||
nsEventDispatcher::Dispatch(aChromeEventHandler, nsnull, &event);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -609,8 +618,11 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
|||
}
|
||||
mInSwap = aOther->mInSwap = PR_TRUE;
|
||||
|
||||
// Fire pagehide events. Note that we do NOT fire these in the normal way,
|
||||
// but just fire them on the chrome event handlers.
|
||||
// Fire pageshow events on still-loading pages, and then fire pagehide
|
||||
// events. Note that we do NOT fire these in the normal way, but just fire
|
||||
// them on the chrome event handlers.
|
||||
FirePageShowEvent(ourTreeItem, ourChromeEventHandler, PR_FALSE);
|
||||
FirePageShowEvent(otherTreeItem, otherChromeEventHandler, PR_FALSE);
|
||||
FirePageHideEvent(ourTreeItem, ourChromeEventHandler);
|
||||
FirePageHideEvent(otherTreeItem, otherChromeEventHandler);
|
||||
|
||||
|
@ -618,8 +630,8 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
|||
nsIFrame* otherFrame = otherShell->GetPrimaryFrameFor(otherContent);
|
||||
if (!ourFrame || !otherFrame) {
|
||||
mInSwap = aOther->mInSwap = PR_FALSE;
|
||||
FirePageShowEvent(ourTreeItem, ourChromeEventHandler);
|
||||
FirePageShowEvent(otherTreeItem, otherChromeEventHandler);
|
||||
FirePageShowEvent(ourTreeItem, ourChromeEventHandler, PR_TRUE);
|
||||
FirePageShowEvent(otherTreeItem, otherChromeEventHandler, PR_TRUE);
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
@ -627,8 +639,8 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
|||
CallQueryInterface(ourFrame, &ourFrameFrame);
|
||||
if (!ourFrameFrame) {
|
||||
mInSwap = aOther->mInSwap = PR_FALSE;
|
||||
FirePageShowEvent(ourTreeItem, ourChromeEventHandler);
|
||||
FirePageShowEvent(otherTreeItem, otherChromeEventHandler);
|
||||
FirePageShowEvent(ourTreeItem, ourChromeEventHandler, PR_TRUE);
|
||||
FirePageShowEvent(otherTreeItem, otherChromeEventHandler, PR_TRUE);
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
@ -636,8 +648,8 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
|||
rv = ourFrameFrame->BeginSwapDocShells(otherFrame);
|
||||
if (NS_FAILED(rv)) {
|
||||
mInSwap = aOther->mInSwap = PR_FALSE;
|
||||
FirePageShowEvent(ourTreeItem, ourChromeEventHandler);
|
||||
FirePageShowEvent(otherTreeItem, otherChromeEventHandler);
|
||||
FirePageShowEvent(ourTreeItem, ourChromeEventHandler, PR_TRUE);
|
||||
FirePageShowEvent(otherTreeItem, otherChromeEventHandler, PR_TRUE);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -690,8 +702,8 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
|||
ourParentDocument->FlushPendingNotifications(Flush_Layout);
|
||||
otherParentDocument->FlushPendingNotifications(Flush_Layout);
|
||||
|
||||
FirePageShowEvent(ourTreeItem, otherChromeEventHandler);
|
||||
FirePageShowEvent(otherTreeItem, ourChromeEventHandler);
|
||||
FirePageShowEvent(ourTreeItem, otherChromeEventHandler, PR_TRUE);
|
||||
FirePageShowEvent(otherTreeItem, ourChromeEventHandler, PR_TRUE);
|
||||
|
||||
mInSwap = aOther->mInSwap = PR_FALSE;
|
||||
return NS_OK;
|
||||
|
|
|
@ -69,6 +69,8 @@ _TEST_FILES = \
|
|||
test_bug396519.xul \
|
||||
bug396519_window.xul \
|
||||
test_bug428288.html \
|
||||
test_bug449778.xul \
|
||||
bug449778_window.xul \
|
||||
test_bug454235.xul \
|
||||
bug454235-subframe.xul \
|
||||
test_bug456980.xul \
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<window title="Mozilla Bug 449778" onload="doTheTest()"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<hbox id="parent">
|
||||
</hbox>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript"><![CDATA[
|
||||
var imports = [ "SimpleTest", "is", "isnot", "ok", "snapshotWindow",
|
||||
"compareSnapshots", "onerror" ];
|
||||
for each (var import in imports) {
|
||||
window[import] = window.opener.wrappedJSObject[import];
|
||||
}
|
||||
|
||||
function $(id) {
|
||||
return document.getElementById(id);
|
||||
}
|
||||
|
||||
function addBrowser(parent, id, width, height) {
|
||||
var b =
|
||||
document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "browser");
|
||||
b.setAttribute("type", "content");
|
||||
b.setAttribute("id", id);
|
||||
b.setAttribute("width", width);
|
||||
b.setAttribute("height", height);
|
||||
$(parent).appendChild(b);
|
||||
}
|
||||
addBrowser("parent", "f1", 300, 200);
|
||||
addBrowser("parent", "f2", 300, 200);
|
||||
|
||||
/** Test for Bug 449778 **/
|
||||
var doc1 = "data:text/html,<html><body>This is a test</body></html>";
|
||||
var doc2 = "data:text/html,<html><body>This is a second test</body></html>";
|
||||
var doc3 = "data:text/html,<html><body>This is a <script>var evt = document.createEvent('Events'); evt.initEvent('testEvt', true, true); document.dispatchEvent(evt);</script>third test</body></html>";
|
||||
|
||||
|
||||
$("f1").setAttribute("src", doc1);
|
||||
$("f2").setAttribute("src", doc2);
|
||||
|
||||
function doTheTest() {
|
||||
var strs = { "f1": "", "f2" : "" };
|
||||
function attachListener(node, type) {
|
||||
var listener = function(e) {
|
||||
if (strs[node.id]) strs[node.id] += " ";
|
||||
strs[node.id] += node.id + ".page" + type;
|
||||
}
|
||||
node.addEventListener("page" + type, listener, false);
|
||||
|
||||
listener.detach = function() {
|
||||
node.removeEventListener("page" + type, listener, false);
|
||||
}
|
||||
return listener;
|
||||
}
|
||||
|
||||
var l1 = attachListener($("f1"), "show");
|
||||
var l2 = attachListener($("f1"), "hide");
|
||||
var l3 = attachListener($("f2"), "show");
|
||||
var l4 = attachListener($("f2"), "hide");
|
||||
|
||||
$("f1").swapDocShells($("f2"));
|
||||
|
||||
is(strs["f1"], "f1.pagehide f1.pageshow",
|
||||
"Expected hide then show on first loaded page");
|
||||
is(strs["f2"], "f2.pagehide f2.pageshow",
|
||||
"Expected hide then show on second loaded page");
|
||||
|
||||
function listener2() {
|
||||
$("f2").removeEventListener("testEvt", listener2, false);
|
||||
|
||||
strs = { "f1": "", "f2" : "" };
|
||||
|
||||
$("f1").swapDocShells($("f2"));
|
||||
is(strs["f1"], "f1.pagehide",
|
||||
"Expected hide on already-loaded page, then nothing");
|
||||
is(strs["f2"], "f2.pageshow f2.pagehide f2.pageshow",
|
||||
"Expected show on still-loading page, then hide on it, then show " +
|
||||
"on already-loaded page");
|
||||
|
||||
strs = { "f1": "", "f2" : "" };
|
||||
|
||||
$("f1").addEventListener("pageshow", listener3, false);
|
||||
}
|
||||
|
||||
function listener3() {
|
||||
$("f1").removeEventListener("pageshow", listener3, false);
|
||||
|
||||
is(strs["f1"], "f1.pageshow",
|
||||
"Expected show as our page finishes loading");
|
||||
is(strs["f2"], "", "Expected no more events here.");
|
||||
|
||||
l1.detach();
|
||||
l2.detach();
|
||||
l3.detach();
|
||||
l4.detach();
|
||||
|
||||
window.close();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
$("f2").addEventListener("testEvt", listener2, false, true);
|
||||
$("f2").setAttribute("src", doc3);
|
||||
}
|
||||
|
||||
]]></script>
|
||||
</window>
|
|
@ -0,0 +1,33 @@
|
|||
<?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"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=449778
|
||||
-->
|
||||
<window title="Mozilla Bug 449778"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script>
|
||||
|
||||
<!-- 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=449778"
|
||||
target="_blank">Mozilla Bug 396519</a>
|
||||
</body>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript"><![CDATA[
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
addLoadEvent(function() {
|
||||
window.open("bug449778_window.xul", "bug449778",
|
||||
"chrome,width=800,height=800");
|
||||
});
|
||||
|
||||
]]></script>
|
||||
</window>
|
Загрузка…
Ссылка в новой задаче