2010-09-08 20:40:39 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2012-05-21 11:12:37 +00:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2010-09-08 20:40:39 +00:00
|
|
|
|
|
|
|
#include "SVGDocumentWrapper.h"
|
2011-10-15 07:33:26 +00:00
|
|
|
|
2010-09-08 20:40:39 +00:00
|
|
|
#include "mozilla/dom/Element.h"
|
|
|
|
#include "nsIAtom.h"
|
|
|
|
#include "nsICategoryManager.h"
|
|
|
|
#include "nsIChannel.h"
|
2011-10-15 07:33:26 +00:00
|
|
|
#include "nsIContentViewer.h"
|
2010-09-08 20:40:39 +00:00
|
|
|
#include "nsIDocument.h"
|
|
|
|
#include "nsIDocumentLoaderFactory.h"
|
|
|
|
#include "nsIDOMSVGAnimatedLength.h"
|
|
|
|
#include "nsIDOMSVGLength.h"
|
|
|
|
#include "nsIHttpChannel.h"
|
|
|
|
#include "nsIObserverService.h"
|
|
|
|
#include "nsIParser.h"
|
|
|
|
#include "nsIPresShell.h"
|
|
|
|
#include "nsIRequest.h"
|
|
|
|
#include "nsIStreamListener.h"
|
|
|
|
#include "nsIXMLContentSink.h"
|
|
|
|
#include "nsNetCID.h"
|
|
|
|
#include "nsComponentManagerUtils.h"
|
2012-08-06 12:02:08 +00:00
|
|
|
#include "nsSMILAnimationController.h"
|
2010-09-08 20:40:39 +00:00
|
|
|
#include "nsServiceManagerUtils.h"
|
|
|
|
#include "nsSize.h"
|
|
|
|
#include "gfxRect.h"
|
2013-01-09 23:02:45 +00:00
|
|
|
#include "mozilla/dom/SVGSVGElement.h"
|
2010-09-08 20:40:39 +00:00
|
|
|
#include "nsSVGLength2.h"
|
2010-11-16 18:35:59 +00:00
|
|
|
#include "nsSVGEffects.h"
|
2013-02-08 19:55:07 +00:00
|
|
|
#include "mozilla/dom/SVGAnimatedLength.h"
|
2010-09-08 20:40:39 +00:00
|
|
|
|
|
|
|
using namespace mozilla::dom;
|
|
|
|
|
|
|
|
namespace mozilla {
|
2012-01-06 16:02:27 +00:00
|
|
|
namespace image {
|
2010-09-08 20:40:39 +00:00
|
|
|
|
2010-11-08 17:45:18 +00:00
|
|
|
NS_IMPL_ISUPPORTS4(SVGDocumentWrapper,
|
2010-09-08 20:40:39 +00:00
|
|
|
nsIStreamListener,
|
|
|
|
nsIRequestObserver,
|
2010-11-08 17:45:18 +00:00
|
|
|
nsIObserver,
|
|
|
|
nsISupportsWeakReference)
|
2010-09-08 20:40:39 +00:00
|
|
|
|
|
|
|
SVGDocumentWrapper::SVGDocumentWrapper()
|
2011-10-17 14:59:28 +00:00
|
|
|
: mIgnoreInvalidation(false),
|
|
|
|
mRegisteredForXPCOMShutdown(false)
|
2010-09-08 20:40:39 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
SVGDocumentWrapper::~SVGDocumentWrapper()
|
|
|
|
{
|
|
|
|
DestroyViewer();
|
2010-11-08 17:45:18 +00:00
|
|
|
if (mRegisteredForXPCOMShutdown) {
|
|
|
|
UnregisterForXPCOMShutdown();
|
|
|
|
}
|
2010-09-08 20:40:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SVGDocumentWrapper::DestroyViewer()
|
|
|
|
{
|
|
|
|
if (mViewer) {
|
2012-07-30 14:20:58 +00:00
|
|
|
mViewer->GetDocument()->OnPageHide(false, nullptr);
|
|
|
|
mViewer->Close(nullptr);
|
2010-09-08 20:40:39 +00:00
|
|
|
mViewer->Destroy();
|
2012-07-30 14:20:58 +00:00
|
|
|
mViewer = nullptr;
|
2010-09-08 20:40:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-29 06:19:26 +00:00
|
|
|
bool
|
2010-09-08 20:40:39 +00:00
|
|
|
SVGDocumentWrapper::GetWidthOrHeight(Dimension aDimension,
|
2012-08-22 15:56:38 +00:00
|
|
|
int32_t& aResult)
|
2010-09-08 20:40:39 +00:00
|
|
|
{
|
2013-01-09 23:02:45 +00:00
|
|
|
SVGSVGElement* rootElem = GetRootSVGElem();
|
2010-09-08 20:40:39 +00:00
|
|
|
NS_ABORT_IF_FALSE(rootElem, "root elem missing or of wrong type");
|
|
|
|
|
|
|
|
// Get the width or height SVG object
|
2013-02-08 19:55:07 +00:00
|
|
|
nsRefPtr<SVGAnimatedLength> domAnimLength;
|
2010-09-08 20:40:39 +00:00
|
|
|
if (aDimension == eWidth) {
|
2013-02-08 19:55:07 +00:00
|
|
|
domAnimLength = rootElem->Width();
|
2010-09-08 20:40:39 +00:00
|
|
|
} else {
|
|
|
|
NS_ABORT_IF_FALSE(aDimension == eHeight, "invalid dimension");
|
2013-02-08 19:55:07 +00:00
|
|
|
domAnimLength = rootElem->Height();
|
2010-09-08 20:40:39 +00:00
|
|
|
}
|
2011-10-17 14:59:28 +00:00
|
|
|
NS_ENSURE_TRUE(domAnimLength, false);
|
2010-09-08 20:40:39 +00:00
|
|
|
|
|
|
|
// Get the animated value from the object
|
|
|
|
nsRefPtr<nsIDOMSVGLength> domLength;
|
2013-02-08 19:55:07 +00:00
|
|
|
nsresult rv = domAnimLength->GetAnimVal(getter_AddRefs(domLength));
|
2011-10-17 14:59:28 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, false);
|
|
|
|
NS_ENSURE_TRUE(domLength, false);
|
2010-09-08 20:40:39 +00:00
|
|
|
|
|
|
|
// Check if it's a percent value (and fail if so)
|
2012-08-22 15:56:38 +00:00
|
|
|
uint16_t unitType;
|
2010-09-08 20:40:39 +00:00
|
|
|
rv = domLength->GetUnitType(&unitType);
|
2011-10-17 14:59:28 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, false);
|
2010-09-08 20:40:39 +00:00
|
|
|
if (unitType == nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE) {
|
2011-10-17 14:59:28 +00:00
|
|
|
return false;
|
2010-09-08 20:40:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Non-percent value - woot! Grab it & return it.
|
|
|
|
float floatLength;
|
|
|
|
rv = domLength->GetValue(&floatLength);
|
2011-10-17 14:59:28 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, false);
|
2010-09-08 20:40:39 +00:00
|
|
|
|
|
|
|
aResult = nsSVGUtils::ClampToInt(floatLength);
|
|
|
|
|
2011-10-17 14:59:28 +00:00
|
|
|
return true;
|
2010-09-08 20:40:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsIFrame*
|
|
|
|
SVGDocumentWrapper::GetRootLayoutFrame()
|
|
|
|
{
|
|
|
|
Element* rootElem = GetRootSVGElem();
|
2012-07-30 14:20:58 +00:00
|
|
|
return rootElem ? rootElem->GetPrimaryFrame() : nullptr;
|
2010-09-08 20:40:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SVGDocumentWrapper::UpdateViewportBounds(const nsIntSize& aViewportSize)
|
|
|
|
{
|
2010-09-08 20:40:40 +00:00
|
|
|
NS_ABORT_IF_FALSE(!mIgnoreInvalidation, "shouldn't be reentrant");
|
2011-10-17 14:59:28 +00:00
|
|
|
mIgnoreInvalidation = true;
|
2012-11-08 19:54:47 +00:00
|
|
|
|
|
|
|
nsIntRect currentBounds;
|
|
|
|
mViewer->GetBounds(currentBounds);
|
|
|
|
|
|
|
|
// If the bounds have changed, we need to do a layout flush.
|
|
|
|
if (currentBounds.Size() != aViewportSize) {
|
|
|
|
mViewer->SetBounds(nsIntRect(nsIntPoint(0, 0), aViewportSize));
|
|
|
|
FlushLayout();
|
|
|
|
}
|
|
|
|
|
2011-10-17 14:59:28 +00:00
|
|
|
mIgnoreInvalidation = false;
|
2010-09-08 20:40:39 +00:00
|
|
|
}
|
|
|
|
|
2010-12-20 00:45:29 +00:00
|
|
|
void
|
2011-02-09 20:13:18 +00:00
|
|
|
SVGDocumentWrapper::FlushImageTransformInvalidation()
|
2010-12-20 00:45:29 +00:00
|
|
|
{
|
|
|
|
NS_ABORT_IF_FALSE(!mIgnoreInvalidation, "shouldn't be reentrant");
|
|
|
|
|
2013-01-09 23:02:45 +00:00
|
|
|
SVGSVGElement* svgElem = GetRootSVGElem();
|
2010-12-20 00:45:29 +00:00
|
|
|
if (!svgElem)
|
|
|
|
return;
|
|
|
|
|
2011-10-17 14:59:28 +00:00
|
|
|
mIgnoreInvalidation = true;
|
2011-02-09 20:13:18 +00:00
|
|
|
svgElem->FlushImageTransformInvalidation();
|
2010-12-20 00:45:29 +00:00
|
|
|
FlushLayout();
|
2011-10-17 14:59:28 +00:00
|
|
|
mIgnoreInvalidation = false;
|
2010-12-20 00:45:29 +00:00
|
|
|
}
|
|
|
|
|
2011-09-29 06:19:26 +00:00
|
|
|
bool
|
2010-09-08 20:40:39 +00:00
|
|
|
SVGDocumentWrapper::IsAnimated()
|
|
|
|
{
|
|
|
|
nsIDocument* doc = mViewer->GetDocument();
|
|
|
|
return doc && doc->HasAnimationController() &&
|
|
|
|
doc->GetAnimationController()->HasRegisteredAnimations();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SVGDocumentWrapper::StartAnimation()
|
|
|
|
{
|
2010-12-20 18:44:05 +00:00
|
|
|
// Can be called for animated images during shutdown, after we've
|
|
|
|
// already Observe()'d XPCOM shutdown and cleared out our mViewer pointer.
|
|
|
|
if (!mViewer)
|
|
|
|
return;
|
|
|
|
|
2010-11-06 19:13:01 +00:00
|
|
|
nsIDocument* doc = mViewer->GetDocument();
|
|
|
|
if (doc) {
|
2011-01-11 05:58:00 +00:00
|
|
|
nsSMILAnimationController* controller = doc->GetAnimationController();
|
|
|
|
if (controller) {
|
|
|
|
controller->Resume(nsSMILTimeContainer::PAUSE_IMAGE);
|
|
|
|
}
|
2011-10-17 14:59:28 +00:00
|
|
|
doc->SetImagesNeedAnimating(true);
|
2010-11-06 19:13:01 +00:00
|
|
|
}
|
2010-09-08 20:40:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SVGDocumentWrapper::StopAnimation()
|
|
|
|
{
|
2010-12-20 18:44:05 +00:00
|
|
|
// Can be called for animated images during shutdown, after we've
|
2010-09-08 20:40:39 +00:00
|
|
|
// already Observe()'d XPCOM shutdown and cleared out our mViewer pointer.
|
|
|
|
if (!mViewer)
|
|
|
|
return;
|
|
|
|
|
2010-11-06 19:13:01 +00:00
|
|
|
nsIDocument* doc = mViewer->GetDocument();
|
|
|
|
if (doc) {
|
2011-01-11 05:58:00 +00:00
|
|
|
nsSMILAnimationController* controller = doc->GetAnimationController();
|
|
|
|
if (controller) {
|
|
|
|
controller->Pause(nsSMILTimeContainer::PAUSE_IMAGE);
|
|
|
|
}
|
2011-10-17 14:59:28 +00:00
|
|
|
doc->SetImagesNeedAnimating(false);
|
2010-11-06 19:13:01 +00:00
|
|
|
}
|
2010-09-08 20:40:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SVGDocumentWrapper::ResetAnimation()
|
|
|
|
{
|
2013-01-09 23:02:45 +00:00
|
|
|
SVGSVGElement* svgElem = GetRootSVGElem();
|
2010-09-08 20:40:39 +00:00
|
|
|
if (!svgElem)
|
|
|
|
return;
|
|
|
|
|
2013-02-08 19:55:07 +00:00
|
|
|
svgElem->SetCurrentTime(0.0f);
|
2010-09-08 20:40:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** nsIStreamListener methods **/
|
|
|
|
|
|
|
|
/* void onDataAvailable (in nsIRequest request, in nsISupports ctxt,
|
|
|
|
in nsIInputStream inStr, in unsigned long sourceOffset,
|
|
|
|
in unsigned long count); */
|
|
|
|
NS_IMETHODIMP
|
|
|
|
SVGDocumentWrapper::OnDataAvailable(nsIRequest* aRequest, nsISupports* ctxt,
|
|
|
|
nsIInputStream* inStr,
|
2012-09-06 02:41:02 +00:00
|
|
|
uint64_t sourceOffset,
|
2012-08-22 15:56:38 +00:00
|
|
|
uint32_t count)
|
2010-09-08 20:40:39 +00:00
|
|
|
{
|
|
|
|
return mListener->OnDataAvailable(aRequest, ctxt, inStr,
|
|
|
|
sourceOffset, count);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** nsIRequestObserver methods **/
|
|
|
|
|
|
|
|
/* void onStartRequest (in nsIRequest request, in nsISupports ctxt); */
|
|
|
|
NS_IMETHODIMP
|
|
|
|
SVGDocumentWrapper::OnStartRequest(nsIRequest* aRequest, nsISupports* ctxt)
|
|
|
|
{
|
|
|
|
nsresult rv = SetupViewer(aRequest,
|
|
|
|
getter_AddRefs(mViewer),
|
|
|
|
getter_AddRefs(mLoadGroup));
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rv) &&
|
2012-07-30 14:20:58 +00:00
|
|
|
NS_SUCCEEDED(mListener->OnStartRequest(aRequest, nullptr))) {
|
2010-09-08 20:40:39 +00:00
|
|
|
mViewer->GetDocument()->SetIsBeingUsedAsImage();
|
2010-11-16 18:35:59 +00:00
|
|
|
StopAnimation(); // otherwise animations start automatically in helper doc
|
|
|
|
|
2012-07-30 14:20:58 +00:00
|
|
|
rv = mViewer->Init(nullptr, nsIntRect(0, 0, 0, 0));
|
2010-09-08 20:40:39 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2012-07-30 14:20:58 +00:00
|
|
|
rv = mViewer->Open(nullptr, nullptr);
|
2010-09-08 20:40:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* void onStopRequest (in nsIRequest request, in nsISupports ctxt,
|
|
|
|
in nsresult status); */
|
|
|
|
NS_IMETHODIMP
|
|
|
|
SVGDocumentWrapper::OnStopRequest(nsIRequest* aRequest, nsISupports* ctxt,
|
|
|
|
nsresult status)
|
|
|
|
{
|
|
|
|
if (mListener) {
|
2010-09-25 17:51:37 +00:00
|
|
|
mListener->OnStopRequest(aRequest, ctxt, status);
|
2010-09-08 20:40:39 +00:00
|
|
|
// A few levels up the stack, imgRequest::OnStopRequest is about to tell
|
|
|
|
// all of its observers that we know our size and are ready to paint. That
|
|
|
|
// might not be true at this point, though -- so here, we synchronously
|
|
|
|
// finish parsing & layout in our helper-document to make sure we can hold
|
|
|
|
// up to this promise.
|
|
|
|
nsCOMPtr<nsIParser> parser = do_QueryInterface(mListener);
|
2011-06-21 17:38:44 +00:00
|
|
|
while (!parser->IsComplete()) {
|
2011-10-14 18:19:18 +00:00
|
|
|
parser->CancelParsingEvents();
|
2010-09-25 17:51:37 +00:00
|
|
|
parser->ContinueInterruptedParsing();
|
|
|
|
}
|
2012-12-27 17:29:03 +00:00
|
|
|
// XXX flushing is wasteful if embedding frame hasn't had initial reflow
|
2010-09-08 20:40:39 +00:00
|
|
|
FlushLayout();
|
2012-07-30 14:20:58 +00:00
|
|
|
mListener = nullptr;
|
2010-09-08 20:40:39 +00:00
|
|
|
|
|
|
|
// In a normal document, this would be called by nsDocShell - but we don't
|
|
|
|
// have a nsDocShell. So we do it ourselves. (If we don't, painting will
|
|
|
|
// stay suppressed for a little while longer, for no good reason).
|
|
|
|
mViewer->LoadComplete(NS_OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** nsIObserver Methods **/
|
|
|
|
NS_IMETHODIMP
|
|
|
|
SVGDocumentWrapper::Observe(nsISupports* aSubject,
|
|
|
|
const char* aTopic,
|
|
|
|
const PRUnichar *aData)
|
|
|
|
{
|
|
|
|
if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
|
2010-11-16 18:35:59 +00:00
|
|
|
// Sever ties from rendering observers to helper-doc's root SVG node
|
2013-01-09 23:02:45 +00:00
|
|
|
SVGSVGElement* svgElem = GetRootSVGElem();
|
2010-11-16 18:35:59 +00:00
|
|
|
if (svgElem) {
|
|
|
|
nsSVGEffects::RemoveAllRenderingObservers(svgElem);
|
|
|
|
}
|
|
|
|
|
2010-09-08 20:40:39 +00:00
|
|
|
// Clean up at XPCOM shutdown time.
|
|
|
|
DestroyViewer();
|
|
|
|
if (mListener)
|
2012-07-30 14:20:58 +00:00
|
|
|
mListener = nullptr;
|
2010-09-08 20:40:39 +00:00
|
|
|
if (mLoadGroup)
|
2012-07-30 14:20:58 +00:00
|
|
|
mLoadGroup = nullptr;
|
2010-11-10 05:50:29 +00:00
|
|
|
|
|
|
|
// Turn off "registered" flag, or else we'll try to unregister when we die.
|
|
|
|
// (No need for that now, and the try would fail anyway -- it's too late.)
|
2011-10-17 14:59:28 +00:00
|
|
|
mRegisteredForXPCOMShutdown = false;
|
2010-09-08 20:40:39 +00:00
|
|
|
} else {
|
|
|
|
NS_ERROR("Unexpected observer topic.");
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Private helper methods **/
|
|
|
|
|
|
|
|
// This method is largely cribbed from
|
|
|
|
// nsExternalResourceMap::PendingLoad::SetupViewer.
|
|
|
|
nsresult
|
|
|
|
SVGDocumentWrapper::SetupViewer(nsIRequest* aRequest,
|
2011-10-15 07:33:26 +00:00
|
|
|
nsIContentViewer** aViewer,
|
2010-09-08 20:40:39 +00:00
|
|
|
nsILoadGroup** aLoadGroup)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIChannel> chan(do_QueryInterface(aRequest));
|
|
|
|
NS_ENSURE_TRUE(chan, NS_ERROR_UNEXPECTED);
|
|
|
|
|
|
|
|
// Check for HTTP error page
|
|
|
|
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aRequest));
|
|
|
|
if (httpChannel) {
|
2011-09-29 06:19:26 +00:00
|
|
|
bool requestSucceeded;
|
2010-09-08 20:40:39 +00:00
|
|
|
if (NS_FAILED(httpChannel->GetRequestSucceeded(&requestSucceeded)) ||
|
|
|
|
!requestSucceeded) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Give this document its own loadgroup
|
|
|
|
nsCOMPtr<nsILoadGroup> loadGroup;
|
|
|
|
chan->GetLoadGroup(getter_AddRefs(loadGroup));
|
|
|
|
|
|
|
|
nsCOMPtr<nsILoadGroup> newLoadGroup =
|
|
|
|
do_CreateInstance(NS_LOADGROUP_CONTRACTID);
|
|
|
|
NS_ENSURE_TRUE(newLoadGroup, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
newLoadGroup->SetLoadGroup(loadGroup);
|
|
|
|
|
|
|
|
nsCOMPtr<nsICategoryManager> catMan =
|
|
|
|
do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
|
|
|
|
NS_ENSURE_TRUE(catMan, NS_ERROR_NOT_AVAILABLE);
|
|
|
|
nsXPIDLCString contractId;
|
2013-01-08 21:40:47 +00:00
|
|
|
nsresult rv = catMan->GetCategoryEntry("Gecko-Content-Viewers", IMAGE_SVG_XML,
|
2010-09-08 20:40:39 +00:00
|
|
|
getter_Copies(contractId));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
nsCOMPtr<nsIDocumentLoaderFactory> docLoaderFactory =
|
|
|
|
do_GetService(contractId);
|
|
|
|
NS_ENSURE_TRUE(docLoaderFactory, NS_ERROR_NOT_AVAILABLE);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContentViewer> viewer;
|
|
|
|
nsCOMPtr<nsIStreamListener> listener;
|
|
|
|
rv = docLoaderFactory->CreateInstance("external-resource", chan,
|
|
|
|
newLoadGroup,
|
2013-01-08 21:40:47 +00:00
|
|
|
IMAGE_SVG_XML, nullptr, nullptr,
|
2010-09-08 20:40:39 +00:00
|
|
|
getter_AddRefs(listener),
|
|
|
|
getter_AddRefs(viewer));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2011-10-15 07:33:26 +00:00
|
|
|
NS_ENSURE_TRUE(viewer, NS_ERROR_UNEXPECTED);
|
2010-09-08 20:40:39 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIParser> parser = do_QueryInterface(listener);
|
|
|
|
NS_ENSURE_TRUE(parser, NS_ERROR_UNEXPECTED);
|
|
|
|
|
|
|
|
// XML-only, because this is for SVG content
|
|
|
|
nsIContentSink* sink = parser->GetContentSink();
|
|
|
|
nsCOMPtr<nsIXMLContentSink> xmlSink = do_QueryInterface(sink);
|
|
|
|
NS_ENSURE_TRUE(sink, NS_ERROR_UNEXPECTED);
|
|
|
|
|
|
|
|
listener.swap(mListener);
|
2011-10-15 07:33:26 +00:00
|
|
|
viewer.forget(aViewer);
|
|
|
|
newLoadGroup.forget(aLoadGroup);
|
2010-09-08 20:40:39 +00:00
|
|
|
|
|
|
|
RegisterForXPCOMShutdown();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SVGDocumentWrapper::RegisterForXPCOMShutdown()
|
|
|
|
{
|
2010-11-08 17:45:18 +00:00
|
|
|
NS_ABORT_IF_FALSE(!mRegisteredForXPCOMShutdown,
|
|
|
|
"re-registering for XPCOM shutdown");
|
2010-09-08 20:40:39 +00:00
|
|
|
// Listen for xpcom-shutdown so that we can drop references to our
|
|
|
|
// helper-document at that point. (Otherwise, we won't get cleaned up
|
|
|
|
// until imgLoader::Shutdown, which can happen after the JAR service
|
|
|
|
// and RDF service have been unregistered.)
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIObserverService> obsSvc = do_GetService(OBSERVER_SVC_CID, &rv);
|
|
|
|
if (NS_FAILED(rv) ||
|
|
|
|
NS_FAILED(obsSvc->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
|
2011-10-17 14:59:28 +00:00
|
|
|
true))) {
|
2010-09-08 20:40:39 +00:00
|
|
|
NS_WARNING("Failed to register as observer of XPCOM shutdown");
|
2010-11-08 17:45:18 +00:00
|
|
|
} else {
|
2011-10-17 14:59:28 +00:00
|
|
|
mRegisteredForXPCOMShutdown = true;
|
2010-11-08 17:45:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SVGDocumentWrapper::UnregisterForXPCOMShutdown()
|
|
|
|
{
|
|
|
|
NS_ABORT_IF_FALSE(mRegisteredForXPCOMShutdown,
|
|
|
|
"unregistering for XPCOM shutdown w/out being registered");
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIObserverService> obsSvc = do_GetService(OBSERVER_SVC_CID, &rv);
|
|
|
|
if (NS_FAILED(rv) ||
|
|
|
|
NS_FAILED(obsSvc->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID))) {
|
|
|
|
NS_WARNING("Failed to unregister as observer of XPCOM shutdown");
|
|
|
|
} else {
|
2011-10-17 14:59:28 +00:00
|
|
|
mRegisteredForXPCOMShutdown = false;
|
2010-09-08 20:40:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SVGDocumentWrapper::FlushLayout()
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
mViewer->GetPresShell(getter_AddRefs(presShell));
|
|
|
|
if (presShell) {
|
|
|
|
presShell->FlushPendingNotifications(Flush_Layout);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-09 23:02:45 +00:00
|
|
|
SVGSVGElement*
|
2010-09-08 20:40:39 +00:00
|
|
|
SVGDocumentWrapper::GetRootSVGElem()
|
|
|
|
{
|
2010-09-08 20:40:40 +00:00
|
|
|
if (!mViewer)
|
2012-07-30 14:20:58 +00:00
|
|
|
return nullptr; // Can happen during destruction
|
2010-09-08 20:40:40 +00:00
|
|
|
|
|
|
|
nsIDocument* doc = mViewer->GetDocument();
|
|
|
|
if (!doc)
|
2012-07-30 14:20:58 +00:00
|
|
|
return nullptr; // Can happen during destruction
|
2010-09-08 20:40:40 +00:00
|
|
|
|
2010-09-08 20:40:39 +00:00
|
|
|
Element* rootElem = mViewer->GetDocument()->GetRootElement();
|
2011-12-15 14:47:03 +00:00
|
|
|
if (!rootElem || !rootElem->IsSVG(nsGkAtoms::svg)) {
|
2012-07-30 14:20:58 +00:00
|
|
|
return nullptr;
|
2010-09-08 20:40:39 +00:00
|
|
|
}
|
|
|
|
|
2013-01-09 23:02:45 +00:00
|
|
|
return static_cast<SVGSVGElement*>(rootElem);
|
2010-09-08 20:40:39 +00:00
|
|
|
}
|
|
|
|
|
2012-01-06 16:02:27 +00:00
|
|
|
} // namespace image
|
2010-09-08 20:40:39 +00:00
|
|
|
} // namespace mozilla
|