#416: M1365189 M1365875

This commit is contained in:
Cameron Kaiser 2017-07-23 11:49:56 -07:00
parent 61ec438893
commit d9876efcf1
3 changed files with 50 additions and 10 deletions

View File

@ -17,6 +17,7 @@
#include "mozilla/HashFunctions.h" #include "mozilla/HashFunctions.h"
#include "mozilla/MathAlgorithms.h" #include "mozilla/MathAlgorithms.h"
#include "nsISVGChildFrame.h"
#include "nsStyleConsts.h" #include "nsStyleConsts.h"
#include "nsPresContext.h" #include "nsPresContext.h"
#include "nsIFrame.h" #include "nsIFrame.h"
@ -4806,8 +4807,13 @@ nsImageRenderer::PrepareImage()
mImageElementSurface = mImageElementSurface =
nsLayoutUtils::SurfaceFromElement(property->GetReferencedElement()); nsLayoutUtils::SurfaceFromElement(property->GetReferencedElement());
if (!mImageElementSurface.GetSourceSurface()) { if (!mImageElementSurface.GetSourceSurface()) {
mPaintServerFrame = property->GetReferencedFrame(); nsIFrame* paintServerFrame = property->GetReferencedFrame();
if (!mPaintServerFrame) { // If there's no referenced frame, or the referenced frame is
// non-displayable SVG, then we have nothing valid to paint.
if (!paintServerFrame ||
(paintServerFrame->IsFrameOfType(nsIFrame::eSVG) &&
!paintServerFrame->IsFrameOfType(nsIFrame::eSVGPaintServer) &&
!static_cast<nsISVGChildFrame*>(do_QueryFrame(paintServerFrame)))) {
mPrepareResult = DrawResult::BAD_IMAGE; mPrepareResult = DrawResult::BAD_IMAGE;
return false; return false;
} }

View File

@ -788,6 +788,15 @@ nsSVGIntegrationUtils::DrawableFromPaintServer(nsIFrame* aFrame,
return drawable.forget(); return drawable.forget();
} }
#if DEBUG
if (aFrame->IsFrameOfType(nsIFrame::eSVG) &&
!static_cast<nsISVGChildFrame*>(do_QueryFrame(aFrame))) {
MOZ_ASSERT_UNREACHABLE("We should prevent painting of unpaintable SVG "
"before we get here");
return nullptr;
}
#endif
// We don't want to paint into a surface as long as we don't need to, so we // We don't want to paint into a surface as long as we don't need to, so we
// set up a drawing callback. // set up a drawing callback.
RefPtr<gfxDrawingCallback> cb = RefPtr<gfxDrawingCallback> cb =

View File

@ -371,6 +371,10 @@ function openTabPrompt(domWin, tabPrompt, args) {
.getInterface(Ci.nsIDOMWindowUtils); .getInterface(Ci.nsIDOMWindowUtils);
winUtils.enterModalState(); winUtils.enterModalState();
let frameMM = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIContentFrameMessageManager);
frameMM.QueryInterface(Ci.nsIDOMEventTarget);
// We provide a callback so the prompt can close itself. We don't want to // We provide a callback so the prompt can close itself. We don't want to
// wait for this event loop to return... Otherwise the presence of other // wait for this event loop to return... Otherwise the presence of other
// prompts on the call stack would in this dialog appearing unresponsive // prompts on the call stack would in this dialog appearing unresponsive
@ -384,16 +388,25 @@ function openTabPrompt(domWin, tabPrompt, args) {
if (newPrompt) if (newPrompt)
tabPrompt.removePrompt(newPrompt); tabPrompt.removePrompt(newPrompt);
domWin.removeEventListener("pagehide", pagehide); frameMM.removeEventListener("pagehide", pagehide, true);
winUtils.leaveModalState(); winUtils.leaveModalState();
PromptUtils.fireDialogEvent(domWin, "DOMModalDialogClosed"); PromptUtils.fireDialogEvent(domWin, "DOMModalDialogClosed");
} }
domWin.addEventListener("pagehide", pagehide); frameMM.addEventListener("pagehide", pagehide, true);
function pagehide() { function pagehide(e) {
domWin.removeEventListener("pagehide", pagehide); // Check whether the event relates to our window or its ancestors
let window = domWin;
let eventWindow = e.target.defaultView;
while (window != eventWindow && window.parent != window) {
window = window.parent;
}
if (window != eventWindow) {
return;
}
frameMM.removeEventListener("pagehide", pagehide, true);
if (newPrompt) { if (newPrompt) {
newPrompt.abortPrompt(); newPrompt.abortPrompt();
@ -442,6 +455,9 @@ function openRemotePrompt(domWin, args, tabPrompt) {
winUtils.enterModalState(); winUtils.enterModalState();
let closed = false; let closed = false;
let frameMM = docShell.getInterface(Ci.nsIContentFrameMessageManager);
frameMM.QueryInterface(Ci.nsIDOMEventTarget);
// It should be hard or impossible to cause a window to create multiple // It should be hard or impossible to cause a window to create multiple
// prompts, but just in case, give our prompt an ID. // prompts, but just in case, give our prompt an ID.
let id = "id" + Cc["@mozilla.org/uuid-generator;1"] let id = "id" + Cc["@mozilla.org/uuid-generator;1"]
@ -453,7 +469,7 @@ function openRemotePrompt(domWin, args, tabPrompt) {
} }
messageManager.removeMessageListener("Prompt:Close", listener); messageManager.removeMessageListener("Prompt:Close", listener);
domWin.removeEventListener("pagehide", pagehide); frameMM.removeEventListener("pagehide", pagehide, true);
winUtils.leaveModalState(); winUtils.leaveModalState();
PromptUtils.fireDialogEvent(domWin, "DOMModalDialogClosed"); PromptUtils.fireDialogEvent(domWin, "DOMModalDialogClosed");
@ -470,9 +486,18 @@ function openRemotePrompt(domWin, args, tabPrompt) {
closed = true; closed = true;
}); });
domWin.addEventListener("pagehide", pagehide); frameMM.addEventListener("pagehide", pagehide, true);
function pagehide() { function pagehide(e) {
domWin.removeEventListener("pagehide", pagehide); // Check whether the event relates to our window or its ancestors
let window = domWin;
let eventWindow = e.target.defaultView;
while (window != eventWindow && window.parent != window) {
window = window.parent;
}
if (window != eventWindow) {
return;
}
frameMM.removeEventListener("pagehide", pagehide, true);
messageManager.sendAsyncMessage("Prompt:ForceClose", { _remoteId: id }); messageManager.sendAsyncMessage("Prompt:ForceClose", { _remoteId: id });
} }