#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/MathAlgorithms.h"
#include "nsISVGChildFrame.h"
#include "nsStyleConsts.h"
#include "nsPresContext.h"
#include "nsIFrame.h"
@ -4806,8 +4807,13 @@ nsImageRenderer::PrepareImage()
mImageElementSurface =
nsLayoutUtils::SurfaceFromElement(property->GetReferencedElement());
if (!mImageElementSurface.GetSourceSurface()) {
mPaintServerFrame = property->GetReferencedFrame();
if (!mPaintServerFrame) {
nsIFrame* paintServerFrame = property->GetReferencedFrame();
// 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;
return false;
}

View File

@ -788,6 +788,15 @@ nsSVGIntegrationUtils::DrawableFromPaintServer(nsIFrame* aFrame,
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
// set up a drawing callback.
RefPtr<gfxDrawingCallback> cb =

View File

@ -371,6 +371,10 @@ function openTabPrompt(domWin, tabPrompt, args) {
.getInterface(Ci.nsIDOMWindowUtils);
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
// wait for this event loop to return... Otherwise the presence of other
// prompts on the call stack would in this dialog appearing unresponsive
@ -384,16 +388,25 @@ function openTabPrompt(domWin, tabPrompt, args) {
if (newPrompt)
tabPrompt.removePrompt(newPrompt);
domWin.removeEventListener("pagehide", pagehide);
frameMM.removeEventListener("pagehide", pagehide, true);
winUtils.leaveModalState();
PromptUtils.fireDialogEvent(domWin, "DOMModalDialogClosed");
}
domWin.addEventListener("pagehide", pagehide);
function pagehide() {
domWin.removeEventListener("pagehide", pagehide);
frameMM.addEventListener("pagehide", pagehide, true);
function pagehide(e) {
// 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) {
newPrompt.abortPrompt();
@ -442,6 +455,9 @@ function openRemotePrompt(domWin, args, tabPrompt) {
winUtils.enterModalState();
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
// prompts, but just in case, give our prompt an ID.
let id = "id" + Cc["@mozilla.org/uuid-generator;1"]
@ -453,7 +469,7 @@ function openRemotePrompt(domWin, args, tabPrompt) {
}
messageManager.removeMessageListener("Prompt:Close", listener);
domWin.removeEventListener("pagehide", pagehide);
frameMM.removeEventListener("pagehide", pagehide, true);
winUtils.leaveModalState();
PromptUtils.fireDialogEvent(domWin, "DOMModalDialogClosed");
@ -470,9 +486,18 @@ function openRemotePrompt(domWin, args, tabPrompt) {
closed = true;
});
domWin.addEventListener("pagehide", pagehide);
function pagehide() {
domWin.removeEventListener("pagehide", pagehide);
frameMM.addEventListener("pagehide", pagehide, true);
function pagehide(e) {
// 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 });
}