Created
April 4, 2013 06:29
-
-
Save smellman/5308299 to your computer and use it in GitHub Desktop.
svgmap diff
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git content/base/src/Makefile.in content/base/src/Makefile.in | |
index df6231c..2d076ca 100644 | |
--- content/base/src/Makefile.in | |
+++ content/base/src/Makefile.in | |
@@ -193,6 +193,7 @@ LOCAL_INCLUDES += \ | |
-I$(topsrcdir)/content/events/src \ | |
-I$(topsrcdir)/content/html/content/src \ | |
-I$(topsrcdir)/content/html/document/src \ | |
+ -I$(topsrcdir)/content/svg/content/src \ | |
-I$(topsrcdir)/content/xbl/src \ | |
-I$(topsrcdir)/content/xml/content/src \ | |
-I$(topsrcdir)/content/xml/document/src \ | |
diff --git content/base/src/nsFrameLoader.cpp content/base/src/nsFrameLoader.cpp | |
index 087feb3..08929f3 100644 | |
--- content/base/src/nsFrameLoader.cpp | |
+++ content/base/src/nsFrameLoader.cpp | |
@@ -44,6 +44,7 @@ | |
#include "nsIFrame.h" | |
#include "nsIScrollableFrame.h" | |
#include "nsSubDocumentFrame.h" | |
+#include "nsSVGIFrameFrame.h" | |
#include "nsError.h" | |
#include "nsGUIEvent.h" | |
#include "nsEventDispatcher.h" | |
@@ -51,6 +52,7 @@ | |
#include "nsISHistoryInternal.h" | |
#include "nsIDocShellHistory.h" | |
#include "nsIDOMHTMLDocument.h" | |
+#include "nsIDOMSVGDocument.h" | |
#include "nsIXULWindow.h" | |
#include "nsIEditor.h" | |
#include "nsIMozBrowserFrame.h" | |
@@ -87,6 +89,7 @@ | |
#include "jsapi.h" | |
#include "mozilla/dom/HTMLIFrameElement.h" | |
+#include "mozilla/dom/SVGIFrameElement.h" | |
#include "nsSandboxFlags.h" | |
#include "mozilla/dom/StructuredCloneUtils.h" | |
@@ -468,6 +471,22 @@ nsFrameLoader::ReallyStartLoadingInternal() | |
} | |
} | |
+ SVGIFrameElement *svgiframe = | |
+ SVGIFrameElement::FromContent(mOwnerContent); | |
+ | |
+ if (svgiframe) { | |
+ sandboxFlags = svgiframe->GetSandboxFlags(); | |
+ | |
+ uint32_t parentSandboxFlags = svgiframe->OwnerDoc()->GetSandboxFlags(); | |
+ | |
+ if (sandboxFlags || parentSandboxFlags) { | |
+ // The child can only add restrictions, not remove them. | |
+ sandboxFlags |= parentSandboxFlags; | |
+ | |
+ mDocShell->SetSandboxFlags(sandboxFlags); | |
+ } | |
+ } | |
+ | |
// If this is an <iframe> and it's sandboxed with respect to origin | |
// we will set it up with a null principal later in nsDocShell::DoURILoad. | |
// We do it there to correctly sandbox content that was loaded into | |
@@ -881,6 +900,126 @@ nsFrameLoader::Show(int32_t marginWidth, int32_t marginHeight, | |
return true; | |
} | |
+ | |
+/*bool | |
+nsFrameLoader::ShowSVG(int32_t marginWidth, int32_t marginHeight, | |
+ int32_t scrollbarPrefX, int32_t scrollbarPrefY, | |
+ nsSVGIFrameFrame* frame)*/ | |
+bool | |
+nsFrameLoader::ShowSVG(int32_t marginWidth, int32_t marginHeight, | |
+ nsSVGIFrameFrame* frame) | |
+{ | |
+ if (mInShow) { | |
+ return false; | |
+ } | |
+ // Reset mInShow if we exit early. | |
+ AutoResetInShow resetInShow(this); | |
+ mInShow = true; | |
+ | |
+ nsresult rv = MaybeCreateDocShell(); | |
+ if (NS_FAILED(rv)) { | |
+ return false; | |
+ } | |
+ | |
+ if (!mRemoteFrame) { | |
+ if (!mDocShell) | |
+ return false; | |
+ | |
+ mDocShell->SetMarginWidth(marginWidth); | |
+ mDocShell->SetMarginHeight(marginHeight); | |
+ /* | |
+ nsCOMPtr<nsIScrollable> sc = do_QueryInterface(mDocShell); | |
+ if (sc) { | |
+ sc->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X, | |
+ scrollbarPrefX); | |
+ sc->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y, | |
+ scrollbarPrefY); | |
+ } | |
+ */ | |
+ /* | |
+ nsCOMPtr<nsIPresShell> presShell = mDocShell->GetPresShell(); | |
+ if (presShell) { | |
+ // Ensure root scroll frame is reflowed in case scroll preferences or | |
+ // margins have changed | |
+ nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame(); | |
+ if (rootScrollFrame) { | |
+ presShell->FrameNeedsReflow(rootScrollFrame, nsIPresShell::eResize, | |
+ NS_FRAME_IS_DIRTY); | |
+ } | |
+ return true; | |
+ } | |
+ */ | |
+ } | |
+ | |
+ nsIntSize size = frame->GetSubdocumentSize(); | |
+ if (mRemoteFrame) { | |
+ return ShowRemoteFrame(size, frame); | |
+ } | |
+ | |
+ nsView* view = frame->EnsureInnerView(); | |
+ if (!view) | |
+ return false; | |
+ | |
+ nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(mDocShell); | |
+ NS_ASSERTION(baseWindow, "Found a nsIDocShell that isn't a nsIBaseWindow."); | |
+ baseWindow->InitWindow(nullptr, view->GetWidget(), 0, 0, | |
+ size.width, size.height); | |
+ // This is kinda whacky, this "Create()" call doesn't really | |
+ // create anything, one starts to wonder why this was named | |
+ // "Create"... | |
+ baseWindow->Create(); | |
+ baseWindow->SetVisibility(true); | |
+ | |
+ // Trigger editor re-initialization if midas is turned on in the | |
+ // sub-document. This shouldn't be necessary, but given the way our | |
+ // editor works, it is. See | |
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=284245 | |
+ nsCOMPtr<nsIPresShell> presShell = mDocShell->GetPresShell(); | |
+ if (presShell) { | |
+ nsCOMPtr<nsIDOMSVGDocument> doc = | |
+ do_QueryInterface(presShell->GetDocument()); | |
+ | |
+ if (doc) { | |
+ /* | |
+ nsAutoString designMode; | |
+ doc->GetDesignMode(designMode); | |
+ | |
+ if (designMode.EqualsLiteral("on")) { | |
+ // Hold on to the editor object to let the document reattach to the | |
+ // same editor object, instead of creating a new one. | |
+ nsCOMPtr<nsIEditor> editor; | |
+ nsresult rv = mDocShell->GetEditor(getter_AddRefs(editor)); | |
+ NS_ENSURE_SUCCESS(rv, false); | |
+ | |
+ doc->SetDesignMode(NS_LITERAL_STRING("off")); | |
+ doc->SetDesignMode(NS_LITERAL_STRING("on")); | |
+ } else { | |
+ // Re-initialize the presentation for contenteditable documents | |
+ bool editable = false, | |
+ hasEditingSession = false; | |
+ mDocShell->GetEditable(&editable); | |
+ mDocShell->GetHasEditingSession(&hasEditingSession); | |
+ nsCOMPtr<nsIEditor> editor; | |
+ mDocShell->GetEditor(getter_AddRefs(editor)); | |
+ if (editable && hasEditingSession && editor) { | |
+ editor->PostCreate(); | |
+ } | |
+ } | |
+ */ | |
+ } | |
+ } | |
+ | |
+ mInShow = false; | |
+ if (mHideCalled) { | |
+ mHideCalled = false; | |
+ Hide(); | |
+ return false; | |
+ } | |
+ return true; | |
+} | |
+ | |
+ | |
+ | |
void | |
nsFrameLoader::MarginsChanged(uint32_t aMarginWidth, | |
uint32_t aMarginHeight) | |
@@ -1563,7 +1702,7 @@ nsFrameLoader::MaybeCreateDocShell() | |
nsAutoString frameName; | |
int32_t namespaceID = mOwnerContent->GetNameSpaceID(); | |
- if (namespaceID == kNameSpaceID_XHTML && !mOwnerContent->IsInHTMLDocument()) { | |
+ if ((namespaceID == kNameSpaceID_XHTML || namespaceID == kNameSpaceID_SVG) && !mOwnerContent->IsInHTMLDocument()) { | |
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::id, frameName); | |
} else { | |
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::name, frameName); | |
diff --git content/base/src/nsFrameLoader.h content/base/src/nsFrameLoader.h | |
index 17ebf09..c2e1cf5 100644 | |
--- content/base/src/nsFrameLoader.h | |
+++ content/base/src/nsFrameLoader.h | |
@@ -26,6 +26,7 @@ | |
class nsIURI; | |
class nsSubDocumentFrame; | |
+class nsSVGIFrameFrame; | |
class nsView; | |
class nsIInProcessContentFrameMessageManager; | |
class AutoResetInShow; | |
@@ -200,6 +201,10 @@ public: | |
int32_t scrollbarPrefX, int32_t scrollbarPrefY, | |
nsSubDocumentFrame* frame); | |
+ bool ShowSVG(int32_t marginWidth, int32_t marginHeight, | |
+ nsSVGIFrameFrame* frame); | |
+ | |
+ | |
/** | |
* Called when the margin properties of the containing frame are changed. | |
*/ | |
diff --git content/base/src/nsGkAtomList.h content/base/src/nsGkAtomList.h | |
index 4b0e389..961f1ab 100644 | |
--- content/base/src/nsGkAtomList.h | |
+++ content/base/src/nsGkAtomList.h | |
@@ -388,6 +388,7 @@ GK_ATOM(from, "from") | |
GK_ATOM(functionAvailable, "function-available") | |
GK_ATOM(generateId, "generate-id") | |
GK_ATOM(getter, "getter") | |
+GK_ATOM(globalCoordinateSystem, "globalCoordinateSystem") | |
GK_ATOM(glyphchar, "glyphchar") | |
GK_ATOM(glyphid, "glyphid") | |
GK_ATOM(grid, "grid") | |
@@ -995,6 +996,7 @@ GK_ATOM(splitmenu, "splitmenu") | |
GK_ATOM(splitter, "splitter") | |
GK_ATOM(spring, "spring") | |
GK_ATOM(src, "src") | |
+GK_ATOM(srcdoc, "srcdoc") | |
GK_ATOM(srclang, "srclang") | |
GK_ATOM(stack, "stack") | |
GK_ATOM(standalone, "standalone") | |
@@ -1833,6 +1835,7 @@ GK_ATOM(svgGenericContainerFrame, "SVGGenericContainerFrame") | |
GK_ATOM(svgGFrame, "SVGGFrame") | |
GK_ATOM(svgGlyphFrame, "SVGGlyphFrame") | |
GK_ATOM(svgGradientFrame, "SVGGradientFrame") | |
+GK_ATOM(svgIFrameFrame, "SVGIFrameFrame") | |
GK_ATOM(svgImageFrame, "SVGImageFrame") | |
GK_ATOM(svgInnerSVGFrame, "SVGInnerSVGFrame") | |
GK_ATOM(svgLinearGradientFrame, "SVGLinearGradientFrame") | |
diff --git content/base/src/nsTreeSanitizer.cpp content/base/src/nsTreeSanitizer.cpp | |
index 78f3af8..48703d9 100644 | |
--- content/base/src/nsTreeSanitizer.cpp | |
+++ content/base/src/nsTreeSanitizer.cpp | |
@@ -353,6 +353,7 @@ nsIAtom** const kElementsSVG[] = { | |
&nsGkAtoms::glyph, // glyph | |
&nsGkAtoms::glyphRef, // glyphRef | |
&nsGkAtoms::hkern, // hkern | |
+ &nsGkAtoms::iframe, // iframe | |
&nsGkAtoms::image, // image | |
&nsGkAtoms::line, // line | |
&nsGkAtoms::linearGradient, // linearGradient | |
@@ -549,6 +550,7 @@ nsIAtom** const kAttributesSVG[] = { | |
&nsGkAtoms::specularConstant, // specularConstant | |
&nsGkAtoms::specularExponent, // specularExponent | |
&nsGkAtoms::spreadMethod, // spreadMethod | |
+ &nsGkAtoms::src, // src | |
&nsGkAtoms::startOffset, // startOffset | |
&nsGkAtoms::stdDeviation, // stdDeviation | |
// stemh | |
diff --git content/events/src/nsEventStateManager.cpp content/events/src/nsEventStateManager.cpp | |
index a243078..393fa3e 100644 | |
--- content/events/src/nsEventStateManager.cpp | |
+++ content/events/src/nsEventStateManager.cpp | |
@@ -1568,6 +1568,11 @@ nsEventStateManager::IsRemoteTarget(nsIContent* target) { | |
return !!TabParent::GetFrom(target); | |
} | |
+ // <iframe> from SVG | |
+ if (browserFrame && (target->Tag() == nsGkAtoms::iframe) && target->IsSVG()) { | |
+ return !!TabParent::GetFrom(target); | |
+ } | |
+ | |
return false; | |
} | |
diff --git content/svg/content/src/GenericSVGFrameElement.cpp content/svg/content/src/GenericSVGFrameElement.cpp | |
new file mode 100644 | |
index 0000000..f1b15ec | |
--- /dev/null | |
+++ content/svg/content/src/GenericSVGFrameElement.cpp | |
@@ -0,0 +1,425 @@ | |
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | |
+/* vim:set tw=80 expandtab softtabstop=2 ts=2 sw=2: */ | |
+ | |
+/* 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/. */ | |
+ | |
+#include "nsSVGElement.h" | |
+#include "GenericSVGFrameElement.h" | |
+#include "nsIInterfaceRequestorUtils.h" | |
+#include "nsContentUtils.h" | |
+#include "mozilla/Preferences.h" | |
+#include "nsIAppsService.h" | |
+#include "nsServiceManagerUtils.h" | |
+#include "nsIDOMApplicationRegistry.h" | |
+#include "nsIPermissionManager.h" | |
+ | |
+using namespace mozilla; | |
+using namespace mozilla::dom; | |
+ | |
+/* | |
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(GenericSVGFrameElement, | |
+ nsSVGElement) | |
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFrameLoader) | |
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END | |
+ | |
+NS_INTERFACE_TABLE_HEAD(GenericSVGFrameElement) | |
+ NS_INTERFACE_TABLE_INHERITED3(GenericSVGFrameElement, | |
+ nsIFrameLoaderOwner, | |
+ nsIDOMMozBrowserFrame, | |
+ nsIMozBrowserFrame) | |
+ NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(GenericSVGFrameElement) | |
+NS_INTERFACE_MAP_END_INHERITING(nsSVGElement) | |
+ | |
+NS_IMPL_BOOL_ATTR(GenericSVGFrameElement, Mozbrowser, mozbrowser) | |
+*/ | |
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(GenericSVGFrameElement, | |
+ nsSVGElement) | |
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFrameLoader) | |
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END | |
+NS_IMPL_ISUPPORTS_INHERITED1(GenericSVGFrameElement, GenericSVGFrameElementBase, | |
+ nsIFrameLoaderOwner) | |
+ // nsIDOMMozBrowserFrame, | |
+ //nsIMozBrowserFrame) | |
+//NS_IMPL_BOOL_ATTR(GenericSVGFrameElement, Mozbrowser, mozbrowser) | |
+ | |
+ | |
+//int32_t | |
+//GenericSVGFrameElement::TabIndexDefault() | |
+//{ | |
+// return 0; | |
+//} | |
+ | |
+GenericSVGFrameElement::~GenericSVGFrameElement() | |
+{ | |
+ if (mFrameLoader) { | |
+ mFrameLoader->Destroy(); | |
+ } | |
+} | |
+ | |
+nsresult | |
+GenericSVGFrameElement::GetContentDocument(nsIDOMDocument** aContentDocument) | |
+{ | |
+ NS_PRECONDITION(aContentDocument, "Null out param"); | |
+ nsCOMPtr<nsIDOMDocument> document = do_QueryInterface(GetContentDocument()); | |
+ document.forget(aContentDocument); | |
+ return NS_OK; | |
+} | |
+ | |
+nsIDocument* | |
+GenericSVGFrameElement::GetContentDocument() | |
+{ | |
+ nsCOMPtr<nsPIDOMWindow> win = GetContentWindow(); | |
+ if (!win) { | |
+ return nullptr; | |
+ } | |
+ | |
+ return win->GetDoc(); | |
+} | |
+ | |
+nsresult | |
+GenericSVGFrameElement::GetContentWindow(nsIDOMWindow** aContentWindow) | |
+{ | |
+ NS_PRECONDITION(aContentWindow, "Null out param"); | |
+ nsCOMPtr<nsPIDOMWindow> window = GetContentWindow(); | |
+ window.forget(aContentWindow); | |
+ return NS_OK; | |
+} | |
+ | |
+already_AddRefed<nsPIDOMWindow> | |
+GenericSVGFrameElement::GetContentWindow() | |
+{ | |
+ EnsureFrameLoader(); | |
+ | |
+ if (!mFrameLoader) { | |
+ return nullptr; | |
+ } | |
+ | |
+ bool depthTooGreat = false; | |
+ mFrameLoader->GetDepthTooGreat(&depthTooGreat); | |
+ if (depthTooGreat) { | |
+ // Claim to have no contentWindow | |
+ return nullptr; | |
+ } | |
+ | |
+ nsCOMPtr<nsIDocShell> doc_shell; | |
+ mFrameLoader->GetDocShell(getter_AddRefs(doc_shell)); | |
+ | |
+ nsCOMPtr<nsPIDOMWindow> win = do_GetInterface(doc_shell); | |
+ | |
+ if (!win) { | |
+ return nullptr; | |
+ } | |
+ | |
+ NS_ASSERTION(win->IsOuterWindow(), | |
+ "Uh, this window should always be an outer window!"); | |
+ | |
+ return win.forget(); | |
+} | |
+ | |
+nsresult | |
+GenericSVGFrameElement::EnsureFrameLoader() | |
+{ | |
+ if (!GetParent()) | |
+ NS_WARNING("can't get Parent"); | |
+ if (!IsInDoc()) | |
+ NS_WARNING("is not doc"); | |
+ | |
+ // if (!GetParent() || !IsInDoc() || mFrameLoader || mFrameLoaderCreationDisallowed) { | |
+ if (mFrameLoader || mFrameLoaderCreationDisallowed) { | |
+ // If frame loader is there, we just keep it around, cached | |
+ return NS_OK; | |
+ } | |
+ | |
+ mFrameLoader = nsFrameLoader::Create(this, mNetworkCreated); | |
+ if (!mFrameLoader) { | |
+ // Strangely enough, this method doesn't actually ensure that the | |
+ // frameloader exists. It's more of a best-effort kind of thing. | |
+ return NS_OK; | |
+ } | |
+ | |
+ return NS_OK; | |
+} | |
+/* | |
+nsresult | |
+GenericSVGFrameElement::CreateRemoteFrameLoader(nsITabParent* aTabParent) | |
+{ | |
+ MOZ_ASSERT(!mFrameLoader); | |
+ EnsureFrameLoader(); | |
+ NS_ENSURE_STATE(mFrameLoader); | |
+ mFrameLoader->SetRemoteBrowser(aTabParent); | |
+ return NS_OK; | |
+} | |
+*/ | |
+NS_IMETHODIMP | |
+GenericSVGFrameElement::GetFrameLoader(nsIFrameLoader **aFrameLoader) | |
+{ | |
+ NS_IF_ADDREF(*aFrameLoader = mFrameLoader); | |
+ return NS_OK; | |
+} | |
+ | |
+NS_IMETHODIMP_(already_AddRefed<nsFrameLoader>) | |
+GenericSVGFrameElement::GetFrameLoader() | |
+{ | |
+ nsRefPtr<nsFrameLoader> loader = mFrameLoader; | |
+ return loader.forget(); | |
+} | |
+ | |
+NS_IMETHODIMP | |
+GenericSVGFrameElement::SwapFrameLoaders(nsIFrameLoaderOwner* aOtherOwner) | |
+{ | |
+ // We don't support this yet | |
+ return NS_ERROR_NOT_IMPLEMENTED; | |
+} | |
+ | |
+nsresult | |
+GenericSVGFrameElement::LoadSrc() | |
+{ | |
+ nsresult rv = EnsureFrameLoader(); | |
+ NS_ENSURE_SUCCESS(rv, rv); | |
+ | |
+ if (!mFrameLoader) { | |
+ return NS_OK; | |
+ } | |
+ | |
+ rv = mFrameLoader->LoadFrame(); | |
+#ifdef DEBUG | |
+ if (NS_FAILED(rv)) { | |
+ NS_WARNING("failed to load URL"); | |
+ } | |
+#endif | |
+ | |
+ return rv; | |
+} | |
+ | |
+nsresult | |
+GenericSVGFrameElement::BindToTree(nsIDocument* aDocument, | |
+ nsIContent* aParent, | |
+ nsIContent* aBindingParent, | |
+ bool aCompileEventHandlers) | |
+{ | |
+ nsresult rv = nsSVGElement::BindToTree(aDocument, aParent, | |
+ aBindingParent, | |
+ aCompileEventHandlers); | |
+ NS_ENSURE_SUCCESS(rv, rv); | |
+ | |
+ if (aDocument) { | |
+ NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(), | |
+ "Missing a script blocker!"); | |
+ // We're in a document now. Kick off the frame load. | |
+ LoadSrc(); | |
+ } | |
+ | |
+ // We're now in document and scripts may move us, so clear | |
+ // the mNetworkCreated flag. | |
+ mNetworkCreated = false; | |
+ return rv; | |
+} | |
+ | |
+void | |
+GenericSVGFrameElement::UnbindFromTree(bool aDeep, bool aNullParent) | |
+{ | |
+ if (mFrameLoader) { | |
+ // This iframe is being taken out of the document, destroy the | |
+ // iframe's frame loader (doing that will tear down the window in | |
+ // this iframe). | |
+ // XXXbz we really want to only partially destroy the frame | |
+ // loader... we don't want to tear down the docshell. Food for | |
+ // later bug. | |
+ mFrameLoader->Destroy(); | |
+ mFrameLoader = nullptr; | |
+ } | |
+ | |
+ nsSVGElement::UnbindFromTree(aDeep, aNullParent); | |
+} | |
+ | |
+nsresult | |
+GenericSVGFrameElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName, | |
+ nsIAtom* aPrefix, const nsAString& aValue, | |
+ bool aNotify) | |
+{ | |
+ nsresult rv = nsSVGElement::SetAttr(aNameSpaceID, aName, aPrefix, | |
+ aValue, aNotify); | |
+ NS_ENSURE_SUCCESS(rv, rv); | |
+ | |
+ if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::src) { | |
+ // Don't propagate error here. The attribute was successfully set, that's | |
+ // what we should reflect. | |
+ LoadSrc(); | |
+ } | |
+ | |
+ return NS_OK; | |
+} | |
+ | |
+void | |
+GenericSVGFrameElement::DestroyContent() | |
+{ | |
+ if (mFrameLoader) { | |
+ mFrameLoader->Destroy(); | |
+ mFrameLoader = nullptr; | |
+ } | |
+ | |
+ nsSVGElement::DestroyContent(); | |
+} | |
+ | |
+nsresult | |
+GenericSVGFrameElement::CopyInnerTo(Element* aDest) | |
+{ | |
+ nsresult rv = nsSVGElement::CopyInnerTo(aDest); | |
+ NS_ENSURE_SUCCESS(rv, rv); | |
+ | |
+ nsIDocument* doc = aDest->OwnerDoc(); | |
+ if (doc->IsStaticDocument() && mFrameLoader) { | |
+ GenericSVGFrameElement* dest = | |
+ static_cast<GenericSVGFrameElement*>(aDest); | |
+ nsFrameLoader* fl = nsFrameLoader::Create(dest, false); | |
+ NS_ENSURE_STATE(fl); | |
+ dest->mFrameLoader = fl; | |
+ static_cast<nsFrameLoader*>(mFrameLoader.get())->CreateStaticClone(fl); | |
+ } | |
+ | |
+ return rv; | |
+} | |
+ | |
+//bool | |
+//GenericSVGFrameElement::IsHTMLFocusable(bool aWithMouse, | |
+// bool *aIsFocusable, | |
+// int32_t *aTabIndex) | |
+//{ | |
+// if (nsSVGElement::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex)) { | |
+// return true; | |
+// } | |
+// | |
+// *aIsFocusable = nsContentUtils::IsSubDocumentTabbable(this); | |
+// | |
+// if (!*aIsFocusable && aTabIndex) { | |
+// *aTabIndex = -1; | |
+// } | |
+// | |
+// return false; | |
+//} | |
+ | |
+/** | |
+ * Return true if this frame element really is a mozbrowser or mozapp. (It | |
+ * needs to have the right attributes, and its creator must have the right | |
+ * permissions.) | |
+ */ | |
+/* [infallible] */ | |
+/*nsresult | |
+GenericSVGFrameElement::GetReallyIsBrowserOrApp(bool *aOut) | |
+{ | |
+ *aOut = false; | |
+ | |
+ // Fail if browser frames are globally disabled. | |
+ //if (!Preferences::GetBool("dom.mozBrowserFramesEnabled")) { | |
+ // return NS_OK; | |
+ //} | |
+ | |
+ // // Fail if this frame doesn't have the mozbrowser attribute. | |
+ // bool hasMozbrowser = false; | |
+ // GetMozbrowser(&hasMozbrowser); | |
+ // if (!hasMozbrowser) { | |
+ // return NS_OK; | |
+ // } | |
+ | |
+ // Fail if the node principal isn't trusted. | |
+ nsIPrincipal *principal = NodePrincipal(); | |
+ nsCOMPtr<nsIPermissionManager> permMgr = | |
+ do_GetService(NS_PERMISSIONMANAGER_CONTRACTID); | |
+ NS_ENSURE_TRUE(permMgr, NS_OK); | |
+ | |
+ uint32_t permission = nsIPermissionManager::DENY_ACTION; | |
+ nsresult rv = permMgr->TestPermissionFromPrincipal(principal, "browser", &permission); | |
+ NS_ENSURE_SUCCESS(rv, NS_OK); | |
+ *aOut = permission == nsIPermissionManager::ALLOW_ACTION; | |
+ return NS_OK; | |
+} | |
+*/ | |
+/* [infallible] */ | |
+/* NS_IMETHODIMP | |
+GenericSVGFrameElement::GetReallyIsApp(bool *aOut) | |
+{ | |
+ nsAutoString manifestURL; | |
+ GetAppManifestURL(manifestURL); | |
+ | |
+ *aOut = !manifestURL.IsEmpty(); | |
+ return NS_OK; | |
+ }*/ | |
+ | |
+/* [infallible] */ | |
+/*NS_IMETHODIMP | |
+GenericSVGFrameElement::GetIsExpectingSystemMessage(bool *aOut) | |
+{ | |
+ *aOut = false; | |
+ | |
+ if (!nsIMozBrowserFrame::GetReallyIsApp()) { | |
+ return NS_OK; | |
+ } | |
+ | |
+ *aOut = HasAttr(kNameSpaceID_None, nsGkAtoms::expectingSystemMessage); | |
+ return NS_OK; | |
+ }*/ | |
+ | |
+/* | |
+NS_IMETHODIMP | |
+GenericSVGFrameElement::GetAppManifestURL(nsAString& aOut) | |
+{ | |
+ aOut.Truncate(); | |
+ | |
+ // At the moment, you can't be an app without being a browser. | |
+ if (!nsIMozBrowserFrame::GetReallyIsBrowserOrApp()) { | |
+ return NS_OK; | |
+ } | |
+ | |
+ // Check permission. | |
+ nsIPrincipal *principal = NodePrincipal(); | |
+ nsCOMPtr<nsIPermissionManager> permMgr = | |
+ do_GetService(NS_PERMISSIONMANAGER_CONTRACTID); | |
+ NS_ENSURE_TRUE(permMgr, NS_OK); | |
+ | |
+ uint32_t permission = nsIPermissionManager::DENY_ACTION; | |
+ nsresult rv = permMgr->TestPermissionFromPrincipal(principal, | |
+ "embed-apps", | |
+ &permission); | |
+ NS_ENSURE_SUCCESS(rv, NS_OK); | |
+ if (permission != nsIPermissionManager::ALLOW_ACTION) { | |
+ return NS_OK; | |
+ } | |
+ | |
+ nsAutoString manifestURL; | |
+ GetAttr(kNameSpaceID_None, nsGkAtoms::mozapp, manifestURL); | |
+ if (manifestURL.IsEmpty()) { | |
+ return NS_OK; | |
+ } | |
+ | |
+ nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID); | |
+ NS_ENSURE_TRUE(appsService, NS_OK); | |
+ | |
+ nsCOMPtr<mozIDOMApplication> app; | |
+ appsService->GetAppByManifestURL(manifestURL, getter_AddRefs(app)); | |
+ if (app) { | |
+ aOut.Assign(manifestURL); | |
+ } | |
+ | |
+ return NS_OK; | |
+ }*/ | |
+/* | |
+NS_IMETHODIMP | |
+GenericSVGFrameElement::DisallowCreateFrameLoader() | |
+{ | |
+ MOZ_ASSERT(!mFrameLoader); | |
+ MOZ_ASSERT(!mFrameLoaderCreationDisallowed); | |
+ mFrameLoaderCreationDisallowed = true; | |
+ return NS_OK; | |
+} | |
+ | |
+NS_IMETHODIMP | |
+GenericSVGFrameElement::AllowCreateFrameLoader() | |
+{ | |
+ MOZ_ASSERT(!mFrameLoader); | |
+ MOZ_ASSERT(mFrameLoaderCreationDisallowed); | |
+ mFrameLoaderCreationDisallowed = false; | |
+ return NS_OK; | |
+} | |
+*/ | |
diff --git content/svg/content/src/GenericSVGFrameElement.h content/svg/content/src/GenericSVGFrameElement.h | |
new file mode 100644 | |
index 0000000..2ae21e4 | |
--- /dev/null | |
+++ content/svg/content/src/GenericSVGFrameElement.h | |
@@ -0,0 +1,111 @@ | |
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | |
+/* vim:set tw=80 expandtab softtabstop=2 ts=2 sw=2: */ | |
+ | |
+/* 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/. */ | |
+ | |
+#include "nsMappedAttributeElement.h" | |
+#include "nsSVGElement.h" | |
+#include "nsIFrameLoader.h" | |
+//#include "nsIMozBrowserFrame.h" | |
+#include "nsIDOMEventListener.h" | |
+ | |
+#include "nsFrameLoader.h" | |
+ | |
+#include "mozilla/dom/SVGGraphicsElement.h" | |
+#include "mozilla/dom/FromParser.h" | |
+ | |
+typedef mozilla::dom::SVGGraphicsElement GenericSVGFrameElementBase; | |
+ | |
+/** | |
+ * A helper class for frame elements | |
+ */ | |
+class GenericSVGFrameElement : public GenericSVGFrameElementBase, | |
+ public nsIFrameLoaderOwner | |
+ // public nsIMozBrowserFrame | |
+{ | |
+public: | |
+ GenericSVGFrameElement(already_AddRefed<nsINodeInfo> aNodeInfo, | |
+ mozilla::dom::FromParser aFromParser) | |
+ : GenericSVGFrameElementBase(aNodeInfo) | |
+ , mNetworkCreated(aFromParser == mozilla::dom::FROM_PARSER_NETWORK) | |
+ , mBrowserFrameListenersRegistered(false) | |
+ , mFrameLoaderCreationDisallowed(false) | |
+ { | |
+ } | |
+ | |
+ virtual ~GenericSVGFrameElement(); | |
+ | |
+ NS_DECL_ISUPPORTS_INHERITED | |
+ // NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr); | |
+ NS_DECL_NSIFRAMELOADEROWNER | |
+ //NS_DECL_NSIDOMMOZBROWSERFRAME | |
+ //NS_DECL_NSIMOZBROWSERFRAME | |
+ | |
+ // nsIContent | |
+ //virtual bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, int32_t *aTabIndex); | |
+ virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent, | |
+ nsIContent* aBindingParent, | |
+ bool aCompileEventHandlers); | |
+ virtual void UnbindFromTree(bool aDeep = true, | |
+ bool aNullParent = true); | |
+ nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName, | |
+ const nsAString& aValue, bool aNotify) | |
+ { | |
+ return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify); | |
+ } | |
+ virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName, | |
+ nsIAtom* aPrefix, const nsAString& aValue, | |
+ bool aNotify); | |
+ virtual void DestroyContent(); | |
+ | |
+ nsresult CopyInnerTo(mozilla::dom::Element* aDest); | |
+ | |
+ //virtual int32_t TabIndexDefault() MOZ_OVERRIDE; | |
+ | |
+ NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(GenericSVGFrameElement, | |
+ nsSVGElement) | |
+ | |
+protected: | |
+ /** | |
+ * Listens to titlechanged events from the document inside the iframe and | |
+ * forwards them along to the iframe so it can fire a mozbrowsertitlechange | |
+ * event if appropriate. | |
+ */ | |
+ class TitleChangedListener MOZ_FINAL : public nsIDOMEventListener | |
+ { | |
+ public: | |
+ TitleChangedListener(GenericSVGFrameElement *aElement, | |
+ nsIDOMEventTarget *aChromeHandler); | |
+ | |
+ /* Unregister this listener. */ | |
+ void Unregister(); | |
+ | |
+ NS_DECL_ISUPPORTS | |
+ NS_DECL_NSIDOMEVENTLISTENER | |
+ | |
+ private: | |
+ nsWeakPtr mElement; /* nsGenericHTMLFrameElement */ | |
+ nsWeakPtr mChromeHandler; /* nsIDOMEventTarget */ | |
+ }; | |
+ | |
+ // This doesn't really ensure a frame loade in all cases, only when | |
+ // it makes sense. | |
+ nsresult EnsureFrameLoader(); | |
+ nsresult LoadSrc(); | |
+ nsIDocument* GetContentDocument(); | |
+ nsresult GetContentDocument(nsIDOMDocument** aContentDocument); | |
+ already_AddRefed<nsPIDOMWindow> GetContentWindow(); | |
+ nsresult GetContentWindow(nsIDOMWindow** aContentWindow); | |
+ | |
+ nsRefPtr<nsFrameLoader> mFrameLoader; | |
+ | |
+ // True when the element is created by the parser | |
+ // using NS_FROM_PARSER_NETWORK flag. | |
+ // If the element is modified, it may lose the flag. | |
+ bool mNetworkCreated; | |
+ | |
+ bool mBrowserFrameListenersRegistered; | |
+ bool mFrameLoaderCreationDisallowed; | |
+}; | |
diff --git content/svg/content/src/Makefile.in content/svg/content/src/Makefile.in | |
index 27cabb9..b77d2a4 100644 | |
--- content/svg/content/src/Makefile.in | |
+++ content/svg/content/src/Makefile.in | |
@@ -32,6 +32,7 @@ CPPSRCS = \ | |
DOMSVGStringList.cpp \ | |
DOMSVGTransform.cpp \ | |
DOMSVGTransformList.cpp \ | |
+ GenericSVGFrameElement.cpp \ | |
nsDOMSVGZoomEvent.cpp \ | |
nsDOMSVGEvent.cpp \ | |
nsISVGPoint.cpp \ | |
@@ -83,8 +84,10 @@ CPPSRCS = \ | |
SVGForeignObjectElement.cpp \ | |
SVGFragmentIdentifier.cpp \ | |
SVGGElement.cpp \ | |
+ SVGGlobalCoordinateSystemElement.cpp \ | |
SVGGradientElement.cpp \ | |
SVGGraphicsElement.cpp \ | |
+ SVGIFrameElement.cpp \ | |
SVGImageElement.cpp \ | |
SVGIntegerPairSMILType.cpp \ | |
SVGLength.cpp \ | |
@@ -146,6 +149,7 @@ include $(topsrcdir)/config/config.mk | |
FORCE_STATIC_LIB = 1 | |
EXPORTS = \ | |
+ GenericSVGFrameElement.h \ | |
nsSVGFeatures.h \ | |
nsSVGRect.h \ | |
SVGAttrValueWrapper.h \ | |
@@ -173,8 +177,10 @@ EXPORTS_mozilla/dom = \ | |
SVGFilterElement.h \ | |
SVGForeignObjectElement.h \ | |
SVGGElement.h \ | |
+ SVGGlobalCoordinateSystemElement.h \ | |
SVGGradientElement.h \ | |
SVGGraphicsElement.h \ | |
+ SVGIFrameElement.h \ | |
SVGImageElement.h \ | |
SVGLineElement.h \ | |
SVGMarkerElement.h \ | |
diff --git content/svg/content/src/SVGContentUtils.cpp content/svg/content/src/SVGContentUtils.cpp | |
index d94eddf..d1553f6 100644 | |
--- content/svg/content/src/SVGContentUtils.cpp | |
+++ content/svg/content/src/SVGContentUtils.cpp | |
@@ -30,7 +30,7 @@ SVGContentUtils::GetOuterSVGElement(nsSVGElement *aSVGElement) | |
nsIContent *ancestor = aSVGElement->GetFlattenedTreeParent(); | |
while (ancestor && ancestor->IsSVG() && | |
- ancestor->Tag() != nsGkAtoms::foreignObject) { | |
+ (ancestor->Tag() != nsGkAtoms::foreignObject || ancestor->Tag() != nsGkAtoms::iframe)) { | |
element = ancestor; | |
ancestor = element->GetFlattenedTreeParent(); | |
} | |
@@ -157,7 +157,8 @@ SVGContentUtils::EstablishesViewport(nsIContent *aContent) | |
return aContent && aContent->IsSVG() && | |
(aContent->Tag() == nsGkAtoms::svg || | |
aContent->Tag() == nsGkAtoms::foreignObject || | |
- aContent->Tag() == nsGkAtoms::symbol); | |
+ aContent->Tag() == nsGkAtoms::symbol || | |
+ aContent->Tag() == nsGkAtoms::iframe); | |
} | |
nsSVGElement* | |
@@ -167,7 +168,7 @@ SVGContentUtils::GetNearestViewportElement(nsIContent *aContent) | |
while (element && element->IsSVG()) { | |
if (EstablishesViewport(element)) { | |
- if (element->Tag() == nsGkAtoms::foreignObject) { | |
+ if ((element->Tag() == nsGkAtoms::foreignObject || element->Tag() == nsGkAtoms::iframe)) { | |
return nullptr; | |
} | |
return static_cast<nsSVGElement*>(element); | |
@@ -186,7 +187,7 @@ GetCTMInternal(nsSVGElement *aElement, bool aScreenCTM, bool aHaveRecursed) | |
nsIContent *ancestor = aElement->GetFlattenedTreeParent(); | |
while (ancestor && ancestor->IsSVG() && | |
- ancestor->Tag() != nsGkAtoms::foreignObject) { | |
+ (ancestor->Tag() != nsGkAtoms::foreignObject || ancestor->Tag() != nsGkAtoms::iframe)) { | |
element = static_cast<nsSVGElement*>(ancestor); | |
matrix *= element->PrependLocalTransformsTo(gfxMatrix()); // i.e. *A*ppend | |
if (!aScreenCTM && SVGContentUtils::EstablishesViewport(element)) { | |
diff --git content/svg/content/src/SVGGlobalCoordinateSystemElement.cpp content/svg/content/src/SVGGlobalCoordinateSystemElement.cpp | |
new file mode 100644 | |
index 0000000..68e9460 | |
--- /dev/null | |
+++ content/svg/content/src/SVGGlobalCoordinateSystemElement.cpp | |
@@ -0,0 +1,109 @@ | |
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | |
+/* 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/. */ | |
+ | |
+#include "mozilla/dom/SVGGlobalCoordinateSystemElement.h" | |
+ | |
+#include "DOMSVGAnimatedTransformList.h" | |
+#include "mozilla/dom/SVGGlobalCoordinateSystemElementBinding.h" | |
+#include "mozilla/Util.h" | |
+#include "nsCOMPtr.h" | |
+#include "nsGkAtoms.h" | |
+#include "nsIURI.h" | |
+#include "nsIDOMSVGURIReference.h" | |
+#include "nsSVGElement.h" | |
+ | |
+NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(GlobalCoordinateSystem) | |
+ | |
+namespace mozilla { | |
+namespace dom { | |
+ | |
+//--------------- GlobalCoordinateSystem ------------------ | |
+ | |
+JSObject* | |
+SVGGlobalCoordinateSystemElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap) | |
+{ | |
+ return SVGGlobalCoordinateSystemElementBinding::Wrap(aCx, aScope, this, aTriedToWrap); | |
+} | |
+ | |
+nsSVGElement::StringInfo SVGGlobalCoordinateSystemElement::sStringInfo[1] = | |
+{ | |
+ { &nsGkAtoms::href, kNameSpaceID_XLink, true } | |
+}; | |
+ | |
+//---------------------------------------------------------------------- | |
+// nsISupports methods | |
+ | |
+NS_IMPL_ISUPPORTS_INHERITED4(SVGGlobalCoordinateSystemElement, SVGGlobalCoordinateSystemElementBase, | |
+ nsIDOMNode, nsIDOMElement, | |
+ nsIDOMSVGElement, | |
+ nsIDOMSVGURIReference) | |
+ | |
+//---------------------------------------------------------------------- | |
+// Implementation | |
+ | |
+SVGGlobalCoordinateSystemElement::SVGGlobalCoordinateSystemElement(already_AddRefed<nsINodeInfo> aNodeInfo) | |
+ : SVGGlobalCoordinateSystemElementBase(aNodeInfo) | |
+{ | |
+ SetIsDOMBinding(); | |
+} | |
+ | |
+//---------------------------------------------------------------------- | |
+// nsIDOMNode methods | |
+ | |
+NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGGlobalCoordinateSystemElement) | |
+ | |
+//---------------------------------------------------------------------- | |
+// nsSVGElement methods | |
+ | |
+nsSVGElement::StringAttributesInfo | |
+SVGGlobalCoordinateSystemElement::GetStringInfo() | |
+{ | |
+ return StringAttributesInfo(mStringAttributes, sStringInfo, | |
+ ArrayLength(sStringInfo)); | |
+} | |
+ | |
+SVGAnimatedTransformList* | |
+SVGGlobalCoordinateSystemElement::GetAnimatedTransformList(uint32_t aFlags) | |
+{ | |
+ if (!mTransform && (aFlags & DO_ALLOCATE)) { | |
+ mTransform = new SVGAnimatedTransformList(); | |
+ } | |
+ return mTransform; | |
+} | |
+ | |
+//---------------------------------------------------------------------- | |
+ | |
+/* readonly attribute SVGAnimatedTransformList transform; */ | |
+already_AddRefed<DOMSVGAnimatedTransformList> | |
+SVGGlobalCoordinateSystemElement::Transform() | |
+{ | |
+ // We're creating a DOM wrapper, so we must tell GetAnimatedTransformList | |
+ // to allocate the SVGAnimatedTransformList if it hasn't already done so: | |
+ return DOMSVGAnimatedTransformList::GetDOMWrapper( | |
+ GetAnimatedTransformList(DO_ALLOCATE), this); | |
+} | |
+ | |
+//---------------------------------------------------------------------- | |
+// nsIDOMSVGURIReference methods: | |
+ | |
+/* readonly attribute nsIDOMSVGAnimatedString href; */ | |
+already_AddRefed<nsIDOMSVGAnimatedString> | |
+SVGGlobalCoordinateSystemElement::Href() | |
+{ | |
+ nsCOMPtr<nsIDOMSVGAnimatedString> href; | |
+ mStringAttributes[HREF].ToDOMAnimatedString(getter_AddRefs(href), this); | |
+ return href.forget(); | |
+} | |
+ | |
+NS_IMETHODIMP | |
+SVGGlobalCoordinateSystemElement::GetHref(nsIDOMSVGAnimatedString * *aHref) | |
+{ | |
+ *aHref = Href().get(); | |
+ return NS_OK; | |
+} | |
+ | |
+} // namespace dom | |
+} // namespace mozilla | |
+ | |
diff --git content/svg/content/src/SVGGlobalCoordinateSystemElement.h content/svg/content/src/SVGGlobalCoordinateSystemElement.h | |
new file mode 100644 | |
index 0000000..e273a08 | |
--- /dev/null | |
+++ content/svg/content/src/SVGGlobalCoordinateSystemElement.h | |
@@ -0,0 +1,79 @@ | |
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | |
+/* 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/. */ | |
+ | |
+#ifndef mozilla_dom_SVGGlobalCoordinateSystemElement_h | |
+#define mozilla_dom_SVGGlobalCoordinateSystemElement_h | |
+ | |
+#include "nsIDOMSVGURIReference.h" | |
+#include "nsSVGElement.h" | |
+#include "nsSVGString.h" | |
+#include "SVGAnimatedTransformList.h" | |
+ | |
+nsresult | |
+NS_NewSVGGlobalCoordinateSystemElement(nsIContent **aResult, | |
+ already_AddRefed<nsINodeInfo> aNodeInfo); | |
+ | |
+namespace mozilla { | |
+ | |
+class DOMSVGAnimatedTransformList; | |
+ | |
+namespace dom { | |
+ | |
+typedef nsSVGElement SVGGlobalCoordinateSystemElementBase; | |
+ | |
+class SVGGlobalCoordinateSystemElement : public SVGGlobalCoordinateSystemElementBase, | |
+ public nsIDOMSVGElement, | |
+ public nsIDOMSVGURIReference | |
+{ | |
+protected: | |
+ SVGGlobalCoordinateSystemElement(already_AddRefed<nsINodeInfo> aNodeInfo); | |
+ virtual JSObject* | |
+ WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap) MOZ_OVERRIDE; | |
+ friend nsresult | |
+ (::NS_NewSVGGlobalCoordinateSystemElement(nsIContent **aResult, | |
+ already_AddRefed<nsINodeInfo> aNodeInfo)); | |
+ | |
+public: | |
+ // interfaces: | |
+ NS_DECL_ISUPPORTS_INHERITED | |
+ | |
+ // URI Reference | |
+ NS_DECL_NSIDOMSVGURIREFERENCE | |
+ | |
+ // The GlobalCoordinateSystem Element base class implements these | |
+ NS_FORWARD_NSIDOMSVGELEMENT(SVGGlobalCoordinateSystemElementBase::) | |
+ | |
+ NS_FORWARD_NSIDOMNODE_TO_NSINODE | |
+ NS_FORWARD_NSIDOMELEMENT_TO_GENERIC | |
+ | |
+ virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const; | |
+ | |
+ virtual nsIDOMNode* AsDOMNode() { return this; } | |
+ | |
+ virtual SVGAnimatedTransformList* | |
+ GetAnimatedTransformList(uint32_t aFlags = 0); | |
+ virtual nsIAtom* GetTransformListAttrName() const { | |
+ return nsGkAtoms::transform; | |
+ } | |
+ | |
+ // WebIDL | |
+ already_AddRefed<DOMSVGAnimatedTransformList> Transform(); | |
+ already_AddRefed<nsIDOMSVGAnimatedString> Href(); | |
+ | |
+protected: | |
+ virtual StringAttributesInfo GetStringInfo(); | |
+ | |
+ enum { HREF }; | |
+ nsSVGString mStringAttributes[1]; | |
+ static StringInfo sStringInfo[1]; | |
+ | |
+ // SVGGlobalCoordinateSystemElement values | |
+ nsAutoPtr<SVGAnimatedTransformList> mTransform; | |
+}; | |
+ | |
+} // namespace dom | |
+} // namespace mozilla | |
+ | |
+#endif // mozilla_dom_SVGGlobalCoordinateSystemElement_h | |
diff --git content/svg/content/src/SVGIFrameElement.cpp content/svg/content/src/SVGIFrameElement.cpp | |
new file mode 100644 | |
index 0000000..bc06c81 | |
--- /dev/null | |
+++ content/svg/content/src/SVGIFrameElement.cpp | |
@@ -0,0 +1,517 @@ | |
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | |
+/* 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/. */ | |
+ | |
+#include "mozilla/Util.h" | |
+ | |
+#include "mozilla/dom/SVGIFrameElement.h" | |
+#include "nsCOMPtr.h" | |
+#include "nsGkAtoms.h" | |
+#include "nsIDOMSVGDocument.h" | |
+#include "mozilla/dom/SVGIFrameElementBinding.h" | |
+ | |
+//DOMCI_NODE_DATA(SVGIFrameElement, mozilla::dom::SVGIFrameElement) | |
+ | |
+NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT_CHECK_PARSER(IFrame) | |
+ | |
+namespace mozilla { | |
+namespace dom { | |
+ | |
+JSObject* | |
+SVGIFrameElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap) | |
+{ | |
+ return SVGIFrameElementBinding::Wrap(aCx, aScope, this, aTriedToWrap); | |
+} | |
+ | |
+ | |
+//--------------------- IFrame ------------------------ | |
+ | |
+nsSVGElement::LengthInfo SVGIFrameElement::sLengthInfo[4] = | |
+{ | |
+ { &nsGkAtoms::x, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::X }, | |
+ { &nsGkAtoms::y, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::Y }, | |
+ { &nsGkAtoms::width, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::X }, | |
+ { &nsGkAtoms::height, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::Y }, | |
+}; | |
+ | |
+nsSVGElement::StringInfo SVGIFrameElement::sStringInfo[5] = | |
+{ | |
+ { &nsGkAtoms::media, 0, true }, | |
+ { &nsGkAtoms::name, 0, true }, | |
+ { &nsGkAtoms::src, 0, true }, | |
+ { &nsGkAtoms::srcdoc, 0, true }, | |
+ { &nsGkAtoms::sandbox, 0, true }, | |
+}; | |
+ | |
+//---------------------------------------------------------------------- | |
+// nsISupports methods | |
+ | |
+/* | |
+NS_IMPL_ADDREF_INHERITED(SVGIFrameElement, nsSVGElement) | |
+NS_IMPL_RELEASE_INHERITED(SVGIFrameElement, nsSVGElement) | |
+ | |
+NS_INTERFACE_TABLE_HEAD(SVGIFrameElement) | |
+ NS_NODE_INTERFACE_TABLE4(SVGIFrameElement, nsIDOMNode, nsIDOMElement, | |
+ nsIDOMSVGElement, | |
+ nsIDOMGetSVGDocument) | |
+ NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGIFrameElement) | |
+NS_INTERFACE_MAP_END_INHERITING(SVGIFrameElementBase) | |
+*/ | |
+/* | |
+NS_IMPL_ADDREF_INHERITED(SVGIFrameElement, nsSVGElement) | |
+NS_IMPL_RELEASE_INHERITED(SVGIFrameElement, nsSVGElement) | |
+*/ | |
+NS_IMPL_ISUPPORTS_INHERITED3(SVGIFrameElement, SVGIFrameElementBase, | |
+ nsIDOMNode, nsIDOMElement, | |
+ nsIDOMSVGElement) | |
+ | |
+//---------------------------------------------------------------------- | |
+// Implementation | |
+ | |
+SVGIFrameElement::SVGIFrameElement(already_AddRefed<nsINodeInfo> aNodeInfo, | |
+ FromParser aFromParser) | |
+ : SVGIFrameElementBase(aNodeInfo, aFromParser) | |
+{ | |
+ SetIsDOMBinding(); | |
+} | |
+ | |
+SVGIFrameElement::~SVGIFrameElement() | |
+{ | |
+} | |
+ | |
+//---------------------------------------------------------------------- | |
+// nsSVGElement methods | |
+ | |
+/* virtual */ gfxMatrix | |
+SVGIFrameElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix, | |
+ TransformTypes aWhich) const | |
+{ | |
+ NS_ABORT_IF_FALSE(aWhich != eChildToUserSpace || aMatrix.IsIdentity(), | |
+ "Skipping eUserSpaceToParent transforms makes no sense"); | |
+ | |
+ // 'transform' attribute: | |
+ gfxMatrix fromUserSpace = | |
+ SVGGraphicsElement::PrependLocalTransformsTo(aMatrix, aWhich); | |
+ if (aWhich == eUserSpaceToParent) { | |
+ return fromUserSpace; | |
+ } | |
+ // our 'x' and 'y' attributes: | |
+ float x, y; | |
+ const_cast<SVGIFrameElement*>(this)-> | |
+ GetAnimatedLengthValues(&x, &y, nullptr); | |
+ gfxMatrix toUserSpace = gfxMatrix().Translate(gfxPoint(x, y)); | |
+ if (aWhich == eChildToUserSpace) { | |
+ return toUserSpace; | |
+ } | |
+ NS_ABORT_IF_FALSE(aWhich == eAllTransforms, "Unknown TransformTypes"); | |
+ return toUserSpace * fromUserSpace; | |
+} | |
+ | |
+ | |
+//---------------------------------------------------------------------- | |
+// nsIDOMNode methods | |
+ | |
+nsresult | |
+SVGIFrameElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const | |
+{ | |
+ *aResult = nullptr; | |
+ nsCOMPtr<nsINodeInfo> ni = aNodeInfo; | |
+ SVGIFrameElement *it = new SVGIFrameElement(ni.forget(), NOT_FROM_PARSER); | |
+ | |
+ nsCOMPtr<nsINode> kungFuDeathGrip = it; | |
+ nsresult rv1 = it->Init(); | |
+ nsresult rv2 = const_cast<SVGIFrameElement*>(this)->CopyInnerTo(it); | |
+ if (NS_SUCCEEDED(rv1) && NS_SUCCEEDED(rv2)) { | |
+ kungFuDeathGrip.swap(*aResult); | |
+ } | |
+ | |
+ return NS_FAILED(rv1) ? rv1 : rv2; | |
+} | |
+ | |
+//NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGIFrameElement) | |
+ | |
+//---------------------------------------------------------------------- | |
+// nsSVGElement methods | |
+ | |
+nsSVGElement::LengthAttributesInfo | |
+SVGIFrameElement::GetLengthInfo() | |
+{ | |
+ return LengthAttributesInfo(mLengthAttributes, sLengthInfo, | |
+ ArrayLength(sLengthInfo)); | |
+} | |
+ | |
+SVGAnimatedPreserveAspectRatio * | |
+SVGIFrameElement::GetPreserveAspectRatio() | |
+{ | |
+ return &mPreserveAspectRatio; | |
+} | |
+ | |
+nsSVGElement::StringAttributesInfo | |
+SVGIFrameElement::GetStringInfo() | |
+{ | |
+ return StringAttributesInfo(mStringAttributes, sStringInfo, | |
+ ArrayLength(sStringInfo)); | |
+} | |
+ | |
+//---------------------------------------------------------------------- | |
+// nsIDOMSVGIFrameElement methods: | |
+ | |
+/* readonly attribute nsIDOMSVGAnimatedLength x; */ | |
+/*NS_IMETHODIMP SVGIFrameElement::GetX(nsIDOMSVGAnimatedLength * *aX) | |
+{ | |
+ *aX = X().get(); | |
+ return NS_OK; | |
+}*/ | |
+ | |
+already_AddRefed<nsIDocument> | |
+SVGIFrameElement::GetContentDocument() | |
+{ | |
+ return SVGIFrameElementBase::GetContentDocument(); | |
+} | |
+ | |
+already_AddRefed<nsIDOMWindow> | |
+SVGIFrameElement::GetContentWindow() | |
+{ | |
+ return SVGIFrameElementBase::GetContentWindow(); | |
+} | |
+ | |
+already_AddRefed<SVGAnimatedLength> | |
+SVGIFrameElement::X() | |
+{ | |
+ return mLengthAttributes[ATTR_X].ToDOMAnimatedLength(this); | |
+} | |
+ | |
+/* readonly attribute nsIDOMSVGAnimatedLength y; */ | |
+/*NS_IMETHODIMP SVGIFrameElement::GetY(nsIDOMSVGAnimatedLength * *aY) | |
+{ | |
+ *aY = Y().get(); | |
+ return NS_OK; | |
+}*/ | |
+ | |
+already_AddRefed<SVGAnimatedLength> | |
+SVGIFrameElement::Y() | |
+{ | |
+ return mLengthAttributes[ATTR_Y].ToDOMAnimatedLength(this); | |
+} | |
+ | |
+/* readonly attribute nsIDOMSVGAnimatedLength width; */ | |
+/*NS_IMETHODIMP SVGIFrameElement::GetWidth(nsIDOMSVGAnimatedLength * *aWidth) | |
+{ | |
+ *aWidth = Width().get(); | |
+ return NS_OK; | |
+}*/ | |
+ | |
+already_AddRefed<SVGAnimatedLength> | |
+SVGIFrameElement::Width() | |
+{ | |
+ return mLengthAttributes[ATTR_WIDTH].ToDOMAnimatedLength(this); | |
+} | |
+ | |
+/* readonly attribute nsIDOMSVGAnimatedLength height; */ | |
+/*NS_IMETHODIMP SVGIFrameElement::GetHeight(nsIDOMSVGAnimatedLength * *aHeight) | |
+{ | |
+ *aHeight = Height().get(); | |
+ return NS_OK; | |
+}*/ | |
+ | |
+already_AddRefed<SVGAnimatedLength> | |
+SVGIFrameElement::Height() | |
+{ | |
+ return mLengthAttributes[ATTR_HEIGHT].ToDOMAnimatedLength(this); | |
+} | |
+ | |
+/* readonly attribute SVGPreserveAspectRatio preserveAspectRatio; */ | |
+/*NS_IMETHODIMP | |
+SVGIFrameElement::GetPreserveAspectRatio(nsISupports | |
+ **aPreserveAspectRatio) | |
+{ | |
+ *aPreserveAspectRatio = PreserveAspectRatio().get(); | |
+ return NS_OK; | |
+ }*/ | |
+ | |
+already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> | |
+SVGIFrameElement::PreserveAspectRatio() | |
+{ | |
+ nsRefPtr<DOMSVGAnimatedPreserveAspectRatio> ratio; | |
+ mPreserveAspectRatio.ToDOMAnimatedPreserveAspectRatio(getter_AddRefs(ratio), this); | |
+ return ratio.forget(); | |
+} | |
+ | |
+/* readonly attribute nsIDOMSVGAnimatedString media; */ | |
+/*NS_IMETHODIMP | |
+SVGIFrameElement::GetMedia(nsIDOMSVGAnimatedString * *aMedia) | |
+{ | |
+ *aMedia = Media().get(); | |
+ return NS_OK; | |
+}*/ | |
+ | |
+already_AddRefed<nsIDOMSVGAnimatedString> | |
+SVGIFrameElement::Media() | |
+{ | |
+ nsCOMPtr<nsIDOMSVGAnimatedString> media; | |
+ mStringAttributes[MEDIA].ToDOMAnimatedString(getter_AddRefs(media), this); | |
+ return media.forget(); | |
+} | |
+ | |
+/* readonly attribute nsIDOMSVGAnimatedString name; */ | |
+/*NS_IMETHODIMP | |
+SVGIFrameElement::GetName(nsIDOMSVGAnimatedString * *aName) | |
+{ | |
+ *aName = Name().get(); | |
+ return NS_OK; | |
+}*/ | |
+ | |
+already_AddRefed<nsIDOMSVGAnimatedString> | |
+SVGIFrameElement::Name() | |
+{ | |
+ nsCOMPtr<nsIDOMSVGAnimatedString> name; | |
+ mStringAttributes[NAME].ToDOMAnimatedString(getter_AddRefs(name), this); | |
+ return name.forget(); | |
+} | |
+ | |
+/* readonly attribute nsIDOMSVGAnimatedString src; */ | |
+/*NS_IMETHODIMP | |
+SVGIFrameElement::GetSrc(nsIDOMSVGAnimatedString * *aSrc) | |
+{ | |
+ *aSrc = Src().get(); | |
+ return NS_OK; | |
+}*/ | |
+ | |
+already_AddRefed<nsIDOMSVGAnimatedString> | |
+SVGIFrameElement::Src() | |
+{ | |
+ nsCOMPtr<nsIDOMSVGAnimatedString> src; | |
+ mStringAttributes[SRC].ToDOMAnimatedString(getter_AddRefs(src), this); | |
+ return src.forget(); | |
+} | |
+ | |
+/* readonly attribute nsIDOMSVGAnimatedString srcdoc; */ | |
+/*NS_IMETHODIMP | |
+SVGIFrameElement::GetSrcdoc(nsIDOMSVGAnimatedString * *aSrcdoc) | |
+{ | |
+ *aSrcdoc = Srcdoc().get(); | |
+ return NS_OK; | |
+}*/ | |
+ | |
+already_AddRefed<nsIDOMSVGAnimatedString> | |
+SVGIFrameElement::Srcdoc() | |
+{ | |
+ nsCOMPtr<nsIDOMSVGAnimatedString> srcdoc; | |
+ mStringAttributes[SRCDOC].ToDOMAnimatedString(getter_AddRefs(srcdoc), this); | |
+ return srcdoc.forget(); | |
+} | |
+ | |
+already_AddRefed<nsIDOMSVGAnimatedString> | |
+SVGIFrameElement::Sandbox() | |
+{ | |
+ nsCOMPtr<nsIDOMSVGAnimatedString> sandbox; | |
+ mStringAttributes[SANDBOX].ToDOMAnimatedString(getter_AddRefs(sandbox), this); | |
+ return sandbox.forget(); | |
+} | |
+ | |
+ | |
+/* attribute DOMString sandbox; */ | |
+//NS_IMPL_STRING_ATTR(SVGIFrameElement, Sandbox, sandbox) | |
+ | |
+void | |
+SVGIFrameElement::SetSandbox(const nsAString& aSandbox, ErrorResult& rv) | |
+{ | |
+ rv = SetAttr(kNameSpaceID_None, nsGkAtoms::sandbox, aSandbox, true); | |
+} | |
+ | |
+//void | |
+//SVGIFrameElement::GetItemValueText(nsAString& aValue) | |
+//{ | |
+// GetSrc(aValue); | |
+//} | |
+// | |
+//void | |
+//SVGIFrameElement::SetItemValueText(const nsAString& aValue) | |
+//{ | |
+// SetSrc(aValue); | |
+//} | |
+ | |
+/* | |
+NS_IMETHODIMP | |
+SVGIFrameElement::GetContentDocument(nsIDOMDocument** aContentDocument) | |
+{ | |
+ return GenericSVGFrameElement::GetContentDocument(aContentDocument); | |
+} | |
+ | |
+NS_IMETHODIMP | |
+SVGIFrameElement::GetContentWindow(nsIDOMWindow** aContentWindow) | |
+{ | |
+ return GenericSVGFrameElement::GetContentWindow(aContentWindow); | |
+} | |
+*/ | |
+NS_IMETHODIMP | |
+SVGIFrameElement::GetSVGDocument(nsIDOMDocument **aResult) | |
+{ | |
+ return SVGIFrameElementBase::GetContentDocument(aResult); | |
+} | |
+ | |
+//bool | |
+//SVGIFrameElement::ParseAttribute(int32_t aNamespaceID, | |
+// nsIAtom* aAttribute, | |
+// const nsAString& aValue, | |
+// nsAttrValue& aResult) | |
+//{ | |
+// if (aNamespaceID == kNameSpaceID_None) { | |
+// if (aAttribute == nsGkAtoms::marginwidth) { | |
+// return aResult.ParseSpecialIntValue(aValue); | |
+// } | |
+// if (aAttribute == nsGkAtoms::marginheight) { | |
+// return aResult.ParseSpecialIntValue(aValue); | |
+// } | |
+// if (aAttribute == nsGkAtoms::width) { | |
+// return aResult.ParseSpecialIntValue(aValue); | |
+// } | |
+// if (aAttribute == nsGkAtoms::height) { | |
+// return aResult.ParseSpecialIntValue(aValue); | |
+// } | |
+// if (aAttribute == nsGkAtoms::frameborder) { | |
+// return ParseFrameborderValue(aValue, aResult); | |
+// } | |
+// if (aAttribute == nsGkAtoms::scrolling) { | |
+// return ParseScrollingValue(aValue, aResult); | |
+// } | |
+// if (aAttribute == nsGkAtoms::align) { | |
+// return ParseAlignValue(aValue, aResult); | |
+// } | |
+// } | |
+// | |
+// return nsGenericSVGFrameElement::ParseAttribute(aNamespaceID, aAttribute, | |
+// aValue, aResult); | |
+//} | |
+ | |
+//static void | |
+//MapAttributesIntoRule(const nsMappedAttributes* aAttributes, | |
+// nsRuleData* aData) | |
+//{ | |
+// if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Border)) { | |
+// // frameborder: 0 | 1 (| NO | YES in quirks mode) | |
+// // If frameborder is 0 or No, set border to 0 | |
+// // else leave it as the value set in html.css | |
+// const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::frameborder); | |
+// if (value && value->Type() == nsAttrValue::eEnum) { | |
+// int32_t frameborder = value->GetEnumValue(); | |
+// if (NS_STYLE_FRAME_0 == frameborder || | |
+// NS_STYLE_FRAME_NO == frameborder || | |
+// NS_STYLE_FRAME_OFF == frameborder) { | |
+// nsCSSValue* borderLeftWidth = aData->ValueForBorderLeftWidthValue(); | |
+// if (borderLeftWidth->GetUnit() == eCSSUnit_Null) | |
+// borderLeftWidth->SetFloatValue(0.0f, eCSSUnit_Pixel); | |
+// nsCSSValue* borderRightWidth = aData->ValueForBorderRightWidthValue(); | |
+// if (borderRightWidth->GetUnit() == eCSSUnit_Null) | |
+// borderRightWidth->SetFloatValue(0.0f, eCSSUnit_Pixel); | |
+// nsCSSValue* borderTopWidth = aData->ValueForBorderTopWidth(); | |
+// if (borderTopWidth->GetUnit() == eCSSUnit_Null) | |
+// borderTopWidth->SetFloatValue(0.0f, eCSSUnit_Pixel); | |
+// nsCSSValue* borderBottomWidth = aData->ValueForBorderBottomWidth(); | |
+// if (borderBottomWidth->GetUnit() == eCSSUnit_Null) | |
+// borderBottomWidth->SetFloatValue(0.0f, eCSSUnit_Pixel); | |
+// } | |
+// } | |
+// } | |
+// if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Position)) { | |
+// // width: value | |
+// nsCSSValue* width = aData->ValueForWidth(); | |
+// if (width->GetUnit() == eCSSUnit_Null) { | |
+// const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::width); | |
+// if (value && value->Type() == nsAttrValue::eInteger) | |
+// width->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel); | |
+// else if (value && value->Type() == nsAttrValue::ePercent) | |
+// width->SetPercentValue(value->GetPercentValue()); | |
+// } | |
+// | |
+// // height: value | |
+// nsCSSValue* height = aData->ValueForHeight(); | |
+// if (height->GetUnit() == eCSSUnit_Null) { | |
+// const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::height); | |
+// if (value && value->Type() == nsAttrValue::eInteger) | |
+// height->SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel); | |
+// else if (value && value->Type() == nsAttrValue::ePercent) | |
+// height->SetPercentValue(value->GetPercentValue()); | |
+// } | |
+// } | |
+// | |
+// nsSVGElement::MapScrollingAttributeInto(aAttributes, aData); | |
+// nsSVGElement::MapImageAlignAttributeInto(aAttributes, aData); | |
+// nsSVGElement::MapCommonAttributesInto(aAttributes, aData); | |
+//} | |
+// | |
+//NS_IMETHODIMP_(bool) | |
+//SVGIFrameElement::IsAttributeMapped(const nsIAtom* aAttribute) const | |
+//{ | |
+// static const MappedAttributeEntry attributes[] = { | |
+// { &nsGkAtoms::width }, | |
+// { &nsGkAtoms::height }, | |
+// { &nsGkAtoms::frameborder }, | |
+// { nullptr }, | |
+// }; | |
+// | |
+// static const MappedAttributeEntry* const map[] = { | |
+// attributes, | |
+// sScrollingAttributeMap, | |
+// sImageAlignAttributeMap, | |
+// sCommonAttributeMap, | |
+// }; | |
+// | |
+// return FindAttributeDependence(aAttribute, map); | |
+//} | |
+ | |
+ | |
+ | |
+//nsMapRuleToAttributesFunc | |
+//SVGIFrameElement::GetAttributeMappingFunction() const | |
+//{ | |
+// return &MapAttributesIntoRule; | |
+//} | |
+ | |
+//nsresult | |
+//nsSVGIFrameElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, | |
+// const nsAttrValue* aValue, | |
+// bool aNotify) | |
+//{ | |
+// if (aName == nsGkAtoms::sandbox && aNameSpaceID == kNameSpaceID_None) { | |
+// // Parse the new value of the sandbox attribute, and if we have a docshell | |
+// // set its sandbox flags appropriately. | |
+// if (mFrameLoader) { | |
+// nsCOMPtr<nsIDocShell> docshell = mFrameLoader->GetExistingDocShell(); | |
+// | |
+// if (docshell) { | |
+// uint32_t newFlags = 0; | |
+// // If a NULL aValue is passed in, we want to clear the sandbox flags | |
+// // which we will do by setting them to 0. | |
+// if (aValue) { | |
+// nsAutoString strValue; | |
+// aValue->ToString(strValue); | |
+// newFlags = nsContentUtils::ParseSandboxAttributeToFlags( | |
+// strValue); | |
+// } | |
+// docshell->SetSandboxFlags(newFlags); | |
+// } | |
+// } | |
+// } | |
+// return nsSVGElement::AfterSetAttr(aNameSpaceID, aName, aValue, | |
+// aNotify); | |
+// | |
+//} | |
+ | |
+ | |
+uint32_t | |
+SVGIFrameElement::GetSandboxFlags() | |
+{ | |
+ nsAutoString sandboxAttr; | |
+ | |
+ if (GetAttr(kNameSpaceID_None, nsGkAtoms::sandbox, sandboxAttr)) { | |
+ return nsContentUtils::ParseSandboxAttributeToFlags(sandboxAttr); | |
+ } | |
+ | |
+ // No sandbox attribute, no sandbox flags. | |
+ return 0; | |
+} | |
+ | |
+} // namespace dom | |
+} // namespace mozilla | |
diff --git content/svg/content/src/SVGIFrameElement.h content/svg/content/src/SVGIFrameElement.h | |
new file mode 100644 | |
index 0000000..e2a7e07 | |
--- /dev/null | |
+++ content/svg/content/src/SVGIFrameElement.h | |
@@ -0,0 +1,123 @@ | |
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | |
+/* 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/. */ | |
+ | |
+#ifndef mozilla_dom_SVGIFrameElement_h | |
+#define mozilla_dom_SVGIFrameElement_h | |
+ | |
+#include "GenericSVGFrameElement.h" | |
+#include "nsIDOMGetSVGDocument.h" | |
+#include "nsContentUtils.h" | |
+#include "nsSVGLength2.h" | |
+#include "nsSVGString.h" | |
+#include "nsSVGElement.h" | |
+#include "SVGAnimatedPreserveAspectRatio.h" | |
+#include "nsIDocument.h" | |
+ | |
+nsresult NS_NewSVGIFrameElement(nsIContent **aResult, | |
+ already_AddRefed<nsINodeInfo> aNodeInfo, | |
+ mozilla::dom::FromParser aFromParser); | |
+ | |
+typedef GenericSVGFrameElement SVGIFrameElementBase; | |
+ | |
+class nsSVGIFrameFrame; | |
+ | |
+namespace mozilla { | |
+namespace dom { | |
+class DOMSVGAnimatedPreserveAspectRatio; | |
+ | |
+class SVGIFrameElement : public SVGIFrameElementBase | |
+ , public nsIDOMSVGElement | |
+ , public nsIDOMGetSVGDocument | |
+{ | |
+ friend class ::nsSVGIFrameFrame; | |
+ | |
+protected: | |
+ SVGIFrameElement(already_AddRefed<nsINodeInfo> aNodeInfo, | |
+ mozilla::dom::FromParser aFromParser); | |
+ virtual JSObject* WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap) MOZ_OVERRIDE; | |
+ virtual ~SVGIFrameElement(); | |
+ | |
+ friend nsresult (::NS_NewSVGIFrameElement(nsIContent **aResult, | |
+ already_AddRefed<nsINodeInfo> aNodeInfo, | |
+ mozilla::dom::FromParser aFromParser)); | |
+ | |
+public: | |
+ NS_IMPL_FROMCONTENT_WITH_TAG(SVGIFrameElement, kNameSpaceID_SVG, iframe) | |
+ | |
+ // nsISupports | |
+ NS_DECL_ISUPPORTS_INHERITED | |
+ | |
+ // nsIDOMNode | |
+ NS_FORWARD_NSIDOMNODE_TO_NSINODE | |
+ | |
+ // nsIDOMElement | |
+ NS_FORWARD_NSIDOMELEMENT_TO_GENERIC | |
+ | |
+ // nsIDOMSVGElement | |
+ NS_FORWARD_NSIDOMSVGELEMENT(SVGIFrameElementBase::) | |
+ | |
+ // nsIDOMGetSVGDocument | |
+ NS_DECL_NSIDOMGETSVGDOCUMENT | |
+ | |
+ | |
+ // nsSVGElement specializations: | |
+ virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix, | |
+ TransformTypes aWhich = eAllTransforms) const; | |
+ | |
+ // nsIContent | |
+ //virtual bool ParseAttribute(int32_t aNamespaceID, | |
+ // nsIAtom* aAttribute, | |
+ // const nsAString& aValue, | |
+ // nsAttrValue& aResult); | |
+ //NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const; | |
+ //virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const; | |
+ | |
+ virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const; | |
+ //virtual nsXPCClassInfo* GetClassInfo(); | |
+ virtual nsIDOMNode* AsDOMNode() { return this; } | |
+ | |
+ // WebIDL | |
+ already_AddRefed<SVGAnimatedLength> X(); | |
+ already_AddRefed<SVGAnimatedLength> Y(); | |
+ already_AddRefed<SVGAnimatedLength> Width(); | |
+ already_AddRefed<SVGAnimatedLength> Height(); | |
+ already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> PreserveAspectRatio(); | |
+ already_AddRefed<nsIDOMSVGAnimatedString> Media(); | |
+ already_AddRefed<nsIDOMSVGAnimatedString> Name(); | |
+ already_AddRefed<nsIDOMSVGAnimatedString> Src(); | |
+ already_AddRefed<nsIDOMSVGAnimatedString> Srcdoc(); | |
+ already_AddRefed<nsIDOMSVGAnimatedString> Sandbox(); | |
+ already_AddRefed<nsIDocument> GetContentDocument(); | |
+ already_AddRefed<nsIDOMWindow> GetContentWindow(); | |
+ void SetSandbox(const nsAString & aSandbox, ErrorResult& rv); | |
+ | |
+ //virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, | |
+ // const nsAttrValue* aValue, | |
+ // bool aNotify); | |
+ | |
+ uint32_t GetSandboxFlags(); | |
+ | |
+protected: | |
+ virtual LengthAttributesInfo GetLengthInfo(); | |
+ virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio(); | |
+ virtual StringAttributesInfo GetStringInfo(); | |
+ | |
+ enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT }; | |
+ nsSVGLength2 mLengthAttributes[4]; | |
+ static LengthInfo sLengthInfo[4]; | |
+ | |
+ SVGAnimatedPreserveAspectRatio mPreserveAspectRatio; | |
+ | |
+ enum { MEDIA, NAME, SRC, SRCDOC, SANDBOX }; | |
+ nsSVGString mStringAttributes[5]; | |
+ static StringInfo sStringInfo[5]; | |
+ | |
+ //virtual void GetItemValueText(nsAString& text); | |
+ //virtual void SetItemValueText(const nsAString& text); | |
+}; | |
+ | |
+} // namespace dom | |
+} // namespace mozilla | |
+#endif // mozilla_dom_SVGIFrameElement_h | |
diff --git content/svg/content/src/SVGSVGElement.cpp content/svg/content/src/SVGSVGElement.cpp | |
index fd89ede..7d26f26 100644 | |
--- content/svg/content/src/SVGSVGElement.cpp | |
+++ content/svg/content/src/SVGSVGElement.cpp | |
@@ -805,6 +805,9 @@ SVGSVGElement::WillBeOutermostSVG(nsIContent* aParent, | |
// SVG in a foreignObject must have its own <svg> (nsSVGOuterSVGFrame). | |
return false; | |
} | |
+ if (tag == nsGkAtoms::iframe) { | |
+ return false; | |
+ } | |
if (tag == nsGkAtoms::svg) { | |
return false; | |
} | |
diff --git content/svg/content/src/SVGSVGElement.h content/svg/content/src/SVGSVGElement.h | |
index 720682e..0fc0fd8 100644 | |
--- content/svg/content/src/SVGSVGElement.h | |
+++ content/svg/content/src/SVGSVGElement.h | |
@@ -299,7 +299,7 @@ private: | |
bool IsInner() const { | |
const nsIContent *parent = GetFlattenedTreeParent(); | |
return parent && parent->IsSVG() && | |
- parent->Tag() != nsGkAtoms::foreignObject; | |
+ (parent->Tag() != nsGkAtoms::foreignObject || parent->Tag() != nsGkAtoms::iframe); | |
} | |
/* | |
diff --git content/svg/content/src/SVGTagList.h content/svg/content/src/SVGTagList.h | |
index c0014ba..3a16c20 100644 | |
--- content/svg/content/src/SVGTagList.h | |
+++ content/svg/content/src/SVGTagList.h | |
@@ -64,6 +64,8 @@ SVG_TAG(feTurbulence, FETurbulence) | |
SVG_TAG(filter, Filter) | |
SVG_TAG(foreignObject, ForeignObject) | |
SVG_TAG(g, G) | |
+SVG_TAG(globalCoordinateSystem, GlobalCoordinateSystem) | |
+SVG_FROM_PARSER_TAG(iframe, IFrame) | |
SVG_TAG(image, Image) | |
SVG_TAG(line, Line) | |
SVG_TAG(linearGradient, LinearGradient) | |
diff --git content/svg/content/src/nsSVGElement.cpp content/svg/content/src/nsSVGElement.cpp | |
index 58ebe88..9c7b628 100644 | |
--- content/svg/content/src/nsSVGElement.cpp | |
+++ content/svg/content/src/nsSVGElement.cpp | |
@@ -1560,7 +1560,7 @@ nsSVGElement::GetCtx() const | |
while (ancestor && ancestor->IsSVG()) { | |
nsIAtom* tag = ancestor->Tag(); | |
- if (tag == nsGkAtoms::foreignObject) { | |
+ if ((tag == nsGkAtoms::foreignObject || tag == nsGkAtoms::iframe)) { | |
return nullptr; | |
} | |
if (tag == nsGkAtoms::svg) { | |
diff --git dom/bindings/Bindings.conf dom/bindings/Bindings.conf | |
index 1264bba..a867af6 100644 | |
--- dom/bindings/Bindings.conf | |
+++ dom/bindings/Bindings.conf | |
@@ -636,6 +636,10 @@ DOMInterfaces = { | |
'headerFile': 'mozilla/dom/SVGComponentTransferFunctionElement.h', | |
}, | |
+'SVGGlobalCoordinateSystemElement': { | |
+ 'headerFile': 'mozilla/dom/SVGGlobalCoordinateSystemElement.h', | |
+}, | |
+ | |
'SVGGraphicsElement': { | |
'concrete': False, | |
'resultNotAddRefed': ['nearestViewportElement', 'farthestViewportElement'] | |
@@ -645,6 +649,10 @@ DOMInterfaces = { | |
'concrete': False, | |
}, | |
+'SVGIFrameElement': { | |
+ 'headerFile': 'mozilla/dom/SVGIFrameElement.h', | |
+}, | |
+ | |
'SVGLengthList': { | |
'nativeType': 'mozilla::DOMSVGLengthList', | |
'headerFile': 'DOMSVGLengthList.h', | |
diff --git dom/webidl/SVGGlobalCoordinateSystemElement.webidl dom/webidl/SVGGlobalCoordinateSystemElement.webidl | |
new file mode 100644 | |
index 0000000..9c0f6bd | |
--- /dev/null | |
+++ dom/webidl/SVGGlobalCoordinateSystemElement.webidl | |
@@ -0,0 +1,17 @@ | |
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | |
+/* 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/. | |
+ * | |
+ * The origin of this IDL file is | |
+ * http://www.w3.org/Graphics/SVG/WG/wiki/Proposals/IFrame_Like_Syntax#7.13.1_The_.27globalCoordinateSystem.27_element | |
+ * (Currentry no IDL file) | |
+ * | |
+ * Copyright © 2013 KDDI, Inc. | |
+ */ | |
+ | |
+interface SVGGlobalCoordinateSystemElement : SVGElement { | |
+ readonly attribute SVGAnimatedTransformList transform; | |
+}; | |
+ | |
+SVGGlobalCoordinateSystemElement implements SVGURIReference; | |
diff --git dom/webidl/SVGIFrameElement.webidl dom/webidl/SVGIFrameElement.webidl | |
new file mode 100644 | |
index 0000000..3426b3d | |
--- /dev/null | |
+++ dom/webidl/SVGIFrameElement.webidl | |
@@ -0,0 +1,48 @@ | |
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | |
+/* 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/. | |
+ * | |
+ * The origin of this IDL file is | |
+ * http://www.w3.org/Graphics/SVG/WG/wiki/Proposals/IFrame_Like_Syntax#5.8_The_.27iframe.27_element | |
+ * but based | |
+ * http://www.whatwg.org/specs/web-apps/current-work/#the-iframe-element | |
+ * | |
+ * © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and | |
+ * Opera Software ASA. You are granted a license to use, reproduce | |
+ * and create derivative works of this document. | |
+ * Copyright © 2013 KDDI, Inc. | |
+ */ | |
+ | |
+interface SVGIFrameElement : SVGGraphicsElement { | |
+ [Constant] | |
+ readonly attribute SVGAnimatedLength x; | |
+ [Constant] | |
+ readonly attribute SVGAnimatedLength y; | |
+ [Constant] | |
+ readonly attribute SVGAnimatedLength width; | |
+ [Constant] | |
+ readonly attribute SVGAnimatedLength height; | |
+ [Constant] | |
+ readonly attribute SVGAnimatedPreserveAspectRatio preserveAspectRatio; | |
+ | |
+ [Constant] | |
+ readonly attribute SVGAnimatedString media; | |
+ [Constant] | |
+ readonly attribute SVGAnimatedString name; | |
+ [Constant] | |
+ readonly attribute SVGAnimatedString src; | |
+ [Constant] | |
+ readonly attribute SVGAnimatedString srcdoc; // maybe DOM String | |
+ // maybe to use DOMSettableTokenList | |
+ [Constant] | |
+ readonly attribute SVGAnimatedString sandbox; | |
+ | |
+ // not implement yet | |
+ //[Constant] | |
+ //readonly attribute SVGAnimatedBoolean seamless; | |
+ | |
+ readonly attribute Document? contentDocument; | |
+ readonly attribute WindowProxy? contentWindow; | |
+ | |
+}; | |
diff --git dom/webidl/WebIDL.mk dom/webidl/WebIDL.mk | |
index 2e7493b..d980acc 100644 | |
--- dom/webidl/WebIDL.mk | |
+++ dom/webidl/WebIDL.mk | |
@@ -166,8 +166,10 @@ webidl_files = \ | |
SVGFitToViewBox.webidl \ | |
SVGForeignObjectElement.webidl \ | |
SVGGElement.webidl \ | |
+ SVGGlobalCoordinateSystemElement.webidl \ | |
SVGGradientElement.webidl \ | |
SVGGraphicsElement.webidl \ | |
+ SVGIFrameElement.webidl \ | |
SVGImageElement.webidl \ | |
SVGLengthList.webidl \ | |
SVGLinearGradientElement.webidl \ | |
diff --git layout/base/nsCSSFrameConstructor.cpp layout/base/nsCSSFrameConstructor.cpp | |
index b2345d6..993ce59 100644 | |
--- layout/base/nsCSSFrameConstructor.cpp | |
+++ layout/base/nsCSSFrameConstructor.cpp | |
@@ -204,6 +204,8 @@ nsIFrame* | |
NS_NewSVGFEImageFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); | |
nsIFrame* | |
NS_NewSVGFEUnstyledLeafFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); | |
+nsIFrame* | |
+NS_NewSVGIFrameFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); | |
#include "nsIScrollable.h" | |
#include "nsINodeInfo.h" | |
@@ -5058,7 +5060,8 @@ nsCSSFrameConstructor::FindSVGData(Element* aElement, | |
SIMPLE_SVG_CREATE(feOffset, NS_NewSVGFELeafFrame), | |
SIMPLE_SVG_CREATE(feSpecularLighting, NS_NewSVGFEContainerFrame), | |
SIMPLE_SVG_CREATE(feTile, NS_NewSVGFELeafFrame), | |
- SIMPLE_SVG_CREATE(feTurbulence, NS_NewSVGFELeafFrame) | |
+ SIMPLE_SVG_CREATE(feTurbulence, NS_NewSVGFELeafFrame), | |
+ SIMPLE_SVG_CREATE(iframe, NS_NewSVGIFrameFrame) | |
}; | |
const FrameConstructionData* data = | |
diff --git layout/base/nsDocumentViewer.cpp layout/base/nsDocumentViewer.cpp | |
index c30b4d7b..b56996a 100644 | |
--- layout/base/nsDocumentViewer.cpp | |
+++ layout/base/nsDocumentViewer.cpp | |
@@ -2376,7 +2376,7 @@ nsDocumentViewer::FindContainerView() | |
// constructor can treat a <frame> as an inline in some XBL | |
// cases. Treat that as display:none, the document is not | |
// displayed. | |
- if (subdocFrame->GetType() == nsGkAtoms::subDocumentFrame) { | |
+ if (subdocFrame && subdocFrame->GetType() == nsGkAtoms::subDocumentFrame) { | |
NS_ASSERTION(subdocFrame->GetView(), "Subdoc frames must have views"); | |
nsView* innerView = | |
static_cast<nsSubDocumentFrame*>(subdocFrame)->EnsureInnerView(); | |
diff --git layout/generic/nsFrameIdList.h layout/generic/nsFrameIdList.h | |
index 958e561..73d253d 100644 | |
--- layout/generic/nsFrameIdList.h | |
+++ layout/generic/nsFrameIdList.h | |
@@ -140,6 +140,8 @@ FRAME_ID(nsSVGGeometryFrame) | |
FRAME_ID(nsSVGGFrame) | |
FRAME_ID(nsSVGGlyphFrame) | |
FRAME_ID(nsSVGGradientFrame) | |
+FRAME_ID(nsSVGIFrameForeignObjectFrame) | |
+FRAME_ID(nsSVGIFrameFrame) | |
FRAME_ID(nsSVGImageFrame) | |
FRAME_ID(nsSVGInnerSVGFrame) | |
FRAME_ID(nsSVGLinearGradientFrame) | |
diff --git layout/generic/nsSubDocumentFrame.h layout/generic/nsSubDocumentFrame.h | |
index 63cc8be..e8789f3 100644 | |
--- layout/generic/nsSubDocumentFrame.h | |
+++ layout/generic/nsSubDocumentFrame.h | |
@@ -88,7 +88,7 @@ public: | |
nsresult BeginSwapDocShells(nsIFrame* aOther); | |
void EndSwapDocShells(nsIFrame* aOther); | |
nsView* EnsureInnerView(); | |
- nsIFrame* GetSubdocumentRootFrame(); | |
+ virtual nsIFrame* GetSubdocumentRootFrame(); | |
nsIntSize GetSubdocumentSize(); | |
// nsIReflowCallback | |
diff --git layout/svg/Makefile.in layout/svg/Makefile.in | |
index f541947..cd2d83a 100644 | |
--- layout/svg/Makefile.in | |
+++ layout/svg/Makefile.in | |
@@ -35,6 +35,7 @@ CPPSRCS = \ | |
nsSVGGeometryFrame.cpp \ | |
nsSVGGlyphFrame.cpp \ | |
nsSVGGradientFrame.cpp \ | |
+ nsSVGIFrameFrame.cpp \ | |
nsSVGImageFrame.cpp \ | |
nsSVGInnerSVGFrame.cpp \ | |
nsSVGIntegrationUtils.cpp \ | |
diff --git layout/svg/nsSVGIFrameFrame.cpp layout/svg/nsSVGIFrameFrame.cpp | |
new file mode 100644 | |
index 0000000..23fcf48 | |
--- /dev/null | |
+++ layout/svg/nsSVGIFrameFrame.cpp | |
@@ -0,0 +1,1223 @@ | |
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | |
+/* 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/. */ | |
+ | |
+// Main header first: | |
+#include "nsSVGIFrameFrame.h" | |
+ | |
+// Keep others in (case-insensitive) order: | |
+#include "gfxContext.h" | |
+#include "gfxMatrix.h" | |
+#include "nsGkAtoms.h" | |
+#include "nsINameSpaceManager.h" | |
+#include "nsLayoutUtils.h" | |
+#include "nsRegion.h" | |
+#include "nsRenderingContext.h" | |
+#include "nsSubDocumentFrame.h" | |
+#include "nsSVGEffects.h" | |
+#include "mozilla/dom/SVGIFrameElement.h" | |
+#include "nsSVGIntegrationUtils.h" | |
+#include "nsSVGOuterSVGFrame.h" | |
+#include "nsSVGUtils.h" | |
+#include "mozilla/AutoRestore.h" | |
+#include "nsViewManager.h" | |
+#include "nsIDocShell.h" | |
+#include "nsIDocShellLoadInfo.h" | |
+#include "nsIDocShellTreeItem.h" | |
+#include "nsIDocShellTreeNode.h" | |
+#include "nsIDocShellTreeOwner.h" | |
+#include "nsIBaseWindow.h" | |
+#include "nsIContentViewer.h" | |
+#include "nsPresContext.h" | |
+ | |
+using namespace mozilla; | |
+using namespace mozilla::dom; | |
+ | |
+static nsIDocument* | |
+GetDocumentFromView(nsView* aView) | |
+{ | |
+ NS_PRECONDITION(aView, ""); | |
+ | |
+ nsIFrame* f = aView->GetFrame(); | |
+ nsIPresShell* ps = f ? f->PresContext()->PresShell() : nullptr; | |
+ return ps ? ps->GetDocument() : nullptr; | |
+} | |
+ | |
+ | |
+ | |
+class AsyncSVGFrameInit : public nsRunnable | |
+{ | |
+public: | |
+ AsyncSVGFrameInit(nsIFrame* aFrame) : mFrame(aFrame) {} | |
+ NS_IMETHOD Run() | |
+ { | |
+ if (mFrame.IsAlive()) { | |
+ static_cast<nsSVGIFrameFrame*>(mFrame.GetFrame())->ShowViewer(); | |
+ } | |
+ return NS_OK; | |
+ } | |
+private: | |
+ nsWeakFrame mFrame; | |
+}; | |
+ | |
+static void | |
+InsertViewsInReverseOrder(nsView* aSibling, nsView* aParent); | |
+ | |
+static void | |
+EndSwapDocShellsForViews(nsView* aView); | |
+ | |
+ | |
+//---------------------------------------------------------------------- | |
+// Implementation | |
+ | |
+nsIFrame* | |
+NS_NewSVGIFrameFrame(nsIPresShell *aPresShell, | |
+ nsStyleContext *aContext) | |
+{ | |
+ NS_WARNING("NS_NewSVGIFrameFrame is called"); | |
+ return new (aPresShell) nsSVGIFrameFrame(aContext); | |
+} | |
+ | |
+NS_IMPL_FRAMEARENA_HELPERS(nsSVGIFrameFrame) | |
+ | |
+nsSVGIFrameFrame::nsSVGIFrameFrame(nsStyleContext* aContext) | |
+ : nsSVGIFrameFrameBase(aContext), | |
+ mInReflow(false) | |
+{ | |
+ AddStateBits(NS_FRAME_REFLOW_ROOT | NS_FRAME_MAY_BE_TRANSFORMED | | |
+ NS_FRAME_SVG_LAYOUT); | |
+} | |
+ | |
+ | |
+//---------------------------------------------------------------------- | |
+// nsIFrame methods | |
+ | |
+NS_QUERYFRAME_HEAD(nsSVGIFrameFrame) | |
+ NS_QUERYFRAME_ENTRY(nsISVGChildFrame) | |
+NS_QUERYFRAME_TAIL_INHERITING(nsSVGIFrameFrameBase) | |
+ | |
+NS_IMETHODIMP | |
+nsSVGIFrameFrame::Init(nsIContent* aContent, | |
+ nsIFrame* aParent, | |
+ nsIFrame* aPrevInFlow) | |
+{ | |
+ NS_ASSERTION(aContent->IsSVG(nsGkAtoms::iframe), | |
+ "Content is not an SVG iframe!"); | |
+ | |
+ AddStateBits(aParent->GetStateBits() & | |
+ (NS_STATE_SVG_NONDISPLAY_CHILD | NS_STATE_SVG_CLIPPATH_CHILD)); | |
+ // nsresult rv = nsSVGIFrameFrameBase::Init(aContent, aParent, aPrevInFlow); | |
+ nsresult rv = nsLeafFrame::Init(aContent, aParent, aPrevInFlow); | |
+ if (NS_FAILED(rv)) | |
+ return rv; | |
+ | |
+ // We are going to create an inner view. If we need a view for the | |
+ // OuterFrame but we wait for the normal view creation path in | |
+ // nsCSSFrameConstructor, then we will lose because the inner view's | |
+ // parent will already have been set to some outer view (e.g., the | |
+ // canvas) when it really needs to have this frame's view as its | |
+ // parent. So, create this frame's view right away, whether we | |
+ // really need it or not, and the inner view will get it as the | |
+ // parent. | |
+ if (!HasView()) { | |
+ rv = nsContainerFrame::CreateViewForFrame(this, true); | |
+ NS_ENSURE_SUCCESS(rv, rv); | |
+ } | |
+ EnsureInnerView(); | |
+ | |
+ // Set the primary frame now so that nsDocumentViewer::FindContainerView | |
+ // called from within EndSwapDocShellsForViews below can find it if needed. | |
+ aContent->SetPrimaryFrame(this); | |
+ | |
+ // If we have a detached subdoc's root view on our frame loader, re-insert | |
+ // it into the view tree. This happens when we've been reframed, and | |
+ // ensures the presentation persists across reframes. If the frame element | |
+ // has changed documents however, we blow away the presentation. | |
+ nsRefPtr<nsFrameLoader> frameloader = FrameLoader(); | |
+ if (frameloader) { | |
+ nsCOMPtr<nsIDocument> oldContainerDoc; | |
+ nsView* detachedViews = | |
+ frameloader->GetDetachedSubdocView(getter_AddRefs(oldContainerDoc)); | |
+ if (detachedViews) { | |
+ if (oldContainerDoc == aContent->OwnerDoc()) { | |
+ // Restore stashed presentation. | |
+ ::InsertViewsInReverseOrder(detachedViews, mInnerView); | |
+ ::EndSwapDocShellsForViews(mInnerView->GetFirstChild()); | |
+ } else { | |
+ // Presentation is for a different document, don't restore it. | |
+ frameloader->Hide(); | |
+ } | |
+ } | |
+ frameloader->SetDetachedSubdocView(nullptr, nullptr); | |
+ } | |
+ | |
+ AddStateBits(NS_FRAME_FONT_INFLATION_CONTAINER | | |
+ NS_FRAME_FONT_INFLATION_FLOW_ROOT); | |
+ if (NS_SUCCEEDED(rv) && | |
+ !(mState & NS_STATE_SVG_NONDISPLAY_CHILD)) { | |
+ NS_WARNING("to register object"); | |
+ //nsSVGUtils::GetOuterSVGFrame(this)->RegisterForeignObject(this); | |
+ } | |
+ nsContentUtils::AddScriptRunner(new AsyncSVGFrameInit(this)); | |
+ | |
+ return rv; | |
+} | |
+ | |
+nsIFrame* | |
+nsSVGIFrameFrame::GetSubdocumentRootFrame() | |
+{ | |
+ if (!mInnerView) | |
+ return nullptr; | |
+ nsView* subdocView = mInnerView->GetFirstChild(); | |
+ return subdocView ? subdocView->GetFrame() : nullptr; | |
+} | |
+ | |
+ | |
+ | |
+static void | |
+InsertViewsInReverseOrder(nsView* aSibling, nsView* aParent) | |
+{ | |
+ NS_PRECONDITION(aParent, ""); | |
+ NS_PRECONDITION(!aParent->GetFirstChild(), "inserting into non-empty list"); | |
+ | |
+ nsViewManager* vm = aParent->GetViewManager(); | |
+ while (aSibling) { | |
+ nsView* next = aSibling->GetNextSibling(); | |
+ aSibling->SetNextSibling(nullptr); | |
+ // true means 'after' in document order which is 'before' in view order, | |
+ // so this call prepends the child, thus reversing the siblings as we go. | |
+ vm->InsertChild(aParent, aSibling, nullptr, true); | |
+ aSibling = next; | |
+ } | |
+} | |
+ | |
+static bool | |
+EndSwapDocShellsForDocument(nsIDocument* aDocument, void*) | |
+{ | |
+ NS_PRECONDITION(aDocument, ""); | |
+ | |
+ // Our docshell and view trees have been updated for the new hierarchy. | |
+ // Now also update all nsDeviceContext::mWidget to that of the | |
+ // container view in the new hierarchy. | |
+ nsCOMPtr<nsISupports> container = aDocument->GetContainer(); | |
+ nsCOMPtr<nsIDocShell> ds = do_QueryInterface(container); | |
+ if (ds) { | |
+ nsCOMPtr<nsIContentViewer> cv; | |
+ ds->GetContentViewer(getter_AddRefs(cv)); | |
+ while (cv) { | |
+ nsCOMPtr<nsPresContext> pc; | |
+ cv->GetPresContext(getter_AddRefs(pc)); | |
+ nsDeviceContext* dc = pc ? pc->DeviceContext() : nullptr; | |
+ if (dc) { | |
+ nsView* v = cv->FindContainerView(); | |
+ dc->Init(v ? v->GetNearestWidget(nullptr) : nullptr); | |
+ } | |
+ nsCOMPtr<nsIContentViewer> prev; | |
+ cv->GetPreviousViewer(getter_AddRefs(prev)); | |
+ cv = prev; | |
+ } | |
+ } | |
+ | |
+ /*aDocument->EnumerateFreezableElements( | |
+ nsObjectFrame::EndSwapDocShells, nullptr);*/ | |
+ aDocument->EnumerateSubDocuments(EndSwapDocShellsForDocument, nullptr); | |
+ return true; | |
+} | |
+ | |
+static void | |
+EndSwapDocShellsForViews(nsView* aSibling) | |
+{ | |
+ for ( ; aSibling; aSibling = aSibling->GetNextSibling()) { | |
+ nsIDocument* doc = ::GetDocumentFromView(aSibling); | |
+ if (doc) { | |
+ ::EndSwapDocShellsForDocument(doc, nullptr); | |
+ } | |
+ nsIFrame *frame = aSibling->GetFrame(); | |
+ if (frame) { | |
+ nsIFrame* parent = nsLayoutUtils::GetCrossDocParentFrame(frame); | |
+ if (parent->HasAnyStateBits(NS_FRAME_IN_POPUP)) { | |
+ nsIFrame::AddInPopupStateBitToDescendants(frame); | |
+ } else { | |
+ nsIFrame::RemoveInPopupStateBitFromDescendants(frame); | |
+ } | |
+ if (frame->HasInvalidFrameInSubtree()) { | |
+ while (parent && !parent->HasAnyStateBits(NS_FRAME_DESCENDANT_NEEDS_PAINT)) { | |
+ parent->AddStateBits(NS_FRAME_DESCENDANT_NEEDS_PAINT); | |
+ parent = nsLayoutUtils::GetCrossDocParentFrame(parent); | |
+ } | |
+ } | |
+ } | |
+ } | |
+} | |
+ | |
+ | |
+ | |
+NS_IMETHODIMP | |
+nsSVGIFrameFrame::SetInitialChildList(ChildListID aListID, | |
+ nsFrameList& aChildList) | |
+{ | |
+ nsresult result; | |
+ if (mFrames.NotEmpty()) { | |
+ // We already have child frames which means we've already been | |
+ // initialized | |
+ NS_NOTREACHED("unexpected second call to SetInitialChildList"); | |
+ result = NS_ERROR_UNEXPECTED; | |
+ } else if (aListID != kPrincipalList) { | |
+ // All we know about is the principal child list. | |
+ NS_NOTREACHED("unknown frame list"); | |
+ result = NS_ERROR_INVALID_ARG; | |
+ } else { | |
+#ifdef DEBUG | |
+ nsFrame::VerifyDirtyBitSet(aChildList); | |
+#endif | |
+ mFrames.SetFrames(aChildList); | |
+ result = NS_OK; | |
+ } | |
+ return result; | |
+} | |
+ | |
+NS_IMETHODIMP | |
+nsSVGIFrameFrame::AppendFrames(ChildListID aListID, | |
+ nsFrameList& aFrameList) | |
+{ | |
+ if (aListID != kPrincipalList) { | |
+#ifdef IBMBIDI | |
+ if (aListID != kNoReflowPrincipalList) | |
+#endif | |
+ { | |
+ NS_ERROR("unexpected child list"); | |
+ return NS_ERROR_INVALID_ARG; | |
+ } | |
+ } | |
+ if (aFrameList.NotEmpty()) { | |
+ mFrames.AppendFrames(this, aFrameList); | |
+ | |
+ // Ask the parent frame to reflow me. | |
+#ifdef IBMBIDI | |
+ if (aListID == kPrincipalList) | |
+#endif | |
+ { | |
+ PresContext()->PresShell()-> | |
+ FrameNeedsReflow(this, nsIPresShell::eTreeChange, | |
+ NS_FRAME_HAS_DIRTY_CHILDREN); | |
+ } | |
+ } | |
+ return NS_OK; | |
+} | |
+ | |
+NS_IMETHODIMP | |
+nsSVGIFrameFrame::InsertFrames(ChildListID aListID, | |
+ nsIFrame* aPrevFrame, | |
+ nsFrameList& aFrameList) | |
+{ | |
+ NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this, | |
+ "inserting after sibling frame with different parent"); | |
+ | |
+ if (aListID != kPrincipalList) { | |
+#ifdef IBMBIDI | |
+ if (aListID != kNoReflowPrincipalList) | |
+#endif | |
+ { | |
+ NS_ERROR("unexpected child list"); | |
+ return NS_ERROR_INVALID_ARG; | |
+ } | |
+ } | |
+ if (aFrameList.NotEmpty()) { | |
+ // Insert frames after aPrevFrame | |
+ mFrames.InsertFrames(this, aPrevFrame, aFrameList); | |
+ | |
+#ifdef IBMBIDI | |
+ if (aListID == kPrincipalList) | |
+#endif | |
+ { | |
+ PresContext()->PresShell()-> | |
+ FrameNeedsReflow(this, nsIPresShell::eTreeChange, | |
+ NS_FRAME_HAS_DIRTY_CHILDREN); | |
+ } | |
+ } | |
+ return NS_OK; | |
+} | |
+ | |
+NS_IMETHODIMP | |
+nsSVGIFrameFrame::RemoveFrame(ChildListID aListID, | |
+ nsIFrame* aOldFrame) | |
+{ | |
+ if (aListID != kPrincipalList) { | |
+#ifdef IBMBIDI | |
+ if (kNoReflowPrincipalList != aListID) | |
+#endif | |
+ { | |
+ NS_ERROR("unexpected child list"); | |
+ return NS_ERROR_INVALID_ARG; | |
+ } | |
+ } | |
+ | |
+ // Loop and destroy aOldFrame and all of its continuations. | |
+ // Request a reflow on the parent frames involved unless we were explicitly | |
+ // told not to (kNoReflowPrincipalList). | |
+ bool generateReflowCommand = true; | |
+#ifdef IBMBIDI | |
+ if (kNoReflowPrincipalList == aListID) { | |
+ generateReflowCommand = false; | |
+ } | |
+#endif | |
+ nsPresContext* pc = PresContext(); | |
+ nsContainerFrame* lastParent = nullptr; | |
+ while (aOldFrame) { | |
+ //XXXfr probably should use StealFrame here. I'm not sure if we need to | |
+ // check the overflow lists atm, but we'll need a prescontext lookup | |
+ // for overflow containers once we can split abspos elements with | |
+ // inline containing blocks. | |
+ nsIFrame* oldFrameNextContinuation = aOldFrame->GetNextContinuation(); | |
+ nsContainerFrame* parent = | |
+ static_cast<nsContainerFrame*>(aOldFrame->GetParent()); | |
+ parent->StealFrame(pc, aOldFrame, true); | |
+ aOldFrame->Destroy(); | |
+ aOldFrame = oldFrameNextContinuation; | |
+ if (parent != lastParent && generateReflowCommand) { | |
+ pc->PresShell()-> | |
+ FrameNeedsReflow(parent, nsIPresShell::eTreeChange, | |
+ NS_FRAME_HAS_DIRTY_CHILDREN); | |
+ lastParent = parent; | |
+ } | |
+ } | |
+ return NS_OK; | |
+} | |
+ | |
+ | |
+void nsSVGIFrameFrame::DestroyFrom(nsIFrame* aDestructRoot) | |
+{ | |
+ // Only unregister if we registered in the first place: | |
+ if (!(mState & NS_STATE_SVG_NONDISPLAY_CHILD)) { | |
+ NS_WARNING("to unregister object"); | |
+ //nsSVGUtils::GetOuterSVGFrame((nsSVGForeignObjectFrame *)this)->UnregisterForeignObject(this); | |
+ } | |
+ nsSVGIFrameFrameBase::DestroyFrom(aDestructRoot); | |
+} | |
+ | |
+ | |
+ | |
+ | |
+nsIAtom * | |
+nsSVGIFrameFrame::GetType() const | |
+{ | |
+ return nsGkAtoms::subDocumentFrame; | |
+} | |
+ | |
+NS_IMETHODIMP | |
+nsSVGIFrameFrame::AttributeChanged(int32_t aNameSpaceID, | |
+ nsIAtom *aAttribute, | |
+ int32_t aModType) | |
+{ | |
+ NS_WARNING("Attribute changed"); | |
+ | |
+ if (aNameSpaceID == kNameSpaceID_None) { | |
+ if (aAttribute == nsGkAtoms::width || | |
+ aAttribute == nsGkAtoms::height) { | |
+ nsSVGUtils::InvalidateBounds(this, false); | |
+ nsSVGUtils::ScheduleReflowSVG(this); | |
+ // XXXjwatt: why mark intrinsic widths dirty? can't we just use eResize? | |
+ RequestReflow(nsIPresShell::eStyleChange); | |
+ } else if (aAttribute == nsGkAtoms::x || | |
+ aAttribute == nsGkAtoms::y || | |
+ aAttribute == nsGkAtoms::transform) { | |
+ // make sure our cached transform matrix gets (lazily) updated | |
+ mCanvasTM = nullptr; | |
+ nsSVGUtils::InvalidateBounds(this, false); | |
+ nsSVGUtils::ScheduleReflowSVG(this); | |
+ } else if (aAttribute == nsGkAtoms::viewBox || | |
+ aAttribute == nsGkAtoms::preserveAspectRatio) { | |
+ nsSVGUtils::InvalidateBounds(this); | |
+ } else if (aAttribute == nsGkAtoms::src) { | |
+ //SVGIFrameElement *element = static_cast<SVGIFrameElement*>(mContent); | |
+ NS_WARNING("src changed"); | |
+ | |
+ } | |
+ } | |
+ | |
+ return NS_OK; | |
+} | |
+ | |
+/* virtual */ void | |
+nsSVGIFrameFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext) | |
+{ | |
+ nsSVGIFrameFrameBase::DidSetStyleContext(aOldStyleContext); | |
+ | |
+ // No need to invalidate before first reflow - that will happen elsewhere. | |
+ // Moreover we haven't been initialised properly yet so we may not have the | |
+ // right state bits. | |
+ if (!(GetStateBits() & NS_FRAME_FIRST_REFLOW)) { | |
+ // XXXperf: probably only need a bounds update if 'font-size' changed and | |
+ // we have em unit width/height. Or, once we map 'transform' into style, | |
+ // if some transform property changed. | |
+ nsSVGUtils::InvalidateBounds(this, false); | |
+ nsSVGUtils::ScheduleReflowSVG(this); | |
+ } | |
+} | |
+ | |
+NS_IMETHODIMP | |
+nsSVGIFrameFrame::Reflow(nsPresContext* aPresContext, | |
+ nsHTMLReflowMetrics& aDesiredSize, | |
+ const nsHTMLReflowState& aReflowState, | |
+ nsReflowStatus& aStatus) | |
+{ | |
+ NS_ABORT_IF_FALSE(!(GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD), | |
+ "Should not have been called"); | |
+ | |
+ // Only InvalidateAndScheduleBoundsUpdate marks us with NS_FRAME_IS_DIRTY, | |
+ // so if that bit is still set we still have a resize pending. If we hit | |
+ // this assertion, then we should get the presShell to skip reflow roots | |
+ // that have a dirty parent since a reflow is going to come via the | |
+ // reflow root's parent anyway. | |
+ NS_ASSERTION(!(GetStateBits() & NS_FRAME_IS_DIRTY), | |
+ "Reflowing while a resize is pending is wasteful"); | |
+ | |
+ // ReflowSVG makes sure mRect is up to date before we're called. | |
+ | |
+ NS_ASSERTION(!aReflowState.parentReflowState, | |
+ "should only get reflow from being reflow root"); | |
+ NS_ASSERTION(aReflowState.ComputedWidth() == GetSize().width && | |
+ aReflowState.ComputedHeight() == GetSize().height, | |
+ "reflow roots should be reflowed at existing size and " | |
+ "svg.css should ensure we have no padding/border/margin"); | |
+ | |
+ DoReflow(); | |
+ | |
+ aDesiredSize.width = aReflowState.ComputedWidth(); | |
+ aDesiredSize.height = aReflowState.ComputedHeight(); | |
+ aDesiredSize.SetOverflowAreasToDesiredBounds(); | |
+ aStatus = NS_FRAME_COMPLETE; | |
+ | |
+ return NS_OK; | |
+} | |
+ | |
+// void | |
+// nsSVGIFrameFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, | |
+// const nsRect& aDirtyRect, | |
+// const nsDisplayListSet& aLists) | |
+// { | |
+// if (!static_cast<const nsSVGElement*>(mContent)->HasValidDimensions()) { | |
+// return; | |
+// } | |
+// BuildDisplayListForNonBlockChildren(aBuilder, aDirtyRect, aLists); | |
+// } | |
+ | |
+void | |
+nsSVGIFrameFrame::BuildDisplayListForNonBlockChildren(nsDisplayListBuilder* aBuilder, | |
+ const nsRect& aDirtyRect, | |
+ const nsDisplayListSet& aLists, | |
+ uint32_t aFlags) | |
+{ | |
+ nsIFrame* kid = mFrames.FirstChild(); | |
+ // Put each child's background directly onto the content list | |
+ nsDisplayListSet set(aLists, aLists.Content()); | |
+ // The children should be in content order | |
+ while (kid) { | |
+ BuildDisplayListForChild(aBuilder, kid, aDirtyRect, set, aFlags); | |
+ kid = kid->GetNextSibling(); | |
+ } | |
+} | |
+ | |
+ | |
+bool | |
+nsSVGIFrameFrame::IsSVGTransformed(gfxMatrix *aOwnTransform, | |
+ gfxMatrix *aFromParentTransform) const | |
+{ | |
+ bool foundTransform = false; | |
+ | |
+ // Check if our parent has children-only transforms: | |
+ nsIFrame *parent = GetParent(); | |
+ if (parent && | |
+ parent->IsFrameOfType(nsIFrame::eSVG | nsIFrame::eSVGContainer)) { | |
+ foundTransform = static_cast<nsSVGContainerFrame*>(parent)-> | |
+ HasChildrenOnlyTransform(aFromParentTransform); | |
+ } | |
+ | |
+ nsSVGElement *content = static_cast<nsSVGElement*>(mContent); | |
+ if (content->GetAnimatedTransformList()) { | |
+ if (aOwnTransform) { | |
+ *aOwnTransform = content->PrependLocalTransformsTo(gfxMatrix(), | |
+ nsSVGElement::eUserSpaceToParent); | |
+ } | |
+ foundTransform = true; | |
+ } | |
+ return foundTransform; | |
+} | |
+ | |
+ | |
+/** | |
+ * Returns the app unit canvas bounds of a userspace rect. | |
+ * | |
+ * @param aToCanvas Transform from userspace to canvas device space. | |
+ */ | |
+static nsRect | |
+ToCanvasBounds(const gfxRect &aUserspaceRect, | |
+ const gfxMatrix &aToCanvas, | |
+ const nsPresContext *presContext) | |
+{ | |
+ return nsLayoutUtils::RoundGfxRectToAppRect( | |
+ aToCanvas.TransformBounds(aUserspaceRect), | |
+ presContext->AppUnitsPerDevPixel()); | |
+} | |
+ | |
+NS_IMETHODIMP | |
+nsSVGIFrameFrame::PaintSVG(nsRenderingContext *aContext, | |
+ const nsIntRect *aDirtyRect) | |
+{ | |
+ NS_ASSERTION(!NS_SVGDisplayListPaintingEnabled() || | |
+ (mState & NS_STATE_SVG_NONDISPLAY_CHILD), | |
+ "If display lists are enabled, only painting of non-display " | |
+ "SVG should take this code path"); | |
+ | |
+ if (IsDisabled()) | |
+ return NS_OK; | |
+ | |
+ nsIFrame* kid = GetFirstPrincipalChild(); | |
+ if (!kid) | |
+ return NS_OK; | |
+ | |
+ gfxMatrix canvasTM = GetCanvasTM(FOR_PAINTING); | |
+ | |
+ if (canvasTM.IsSingular()) { | |
+ NS_WARNING("Can't render foreignObject element!"); | |
+ return NS_ERROR_FAILURE; | |
+ } | |
+ | |
+ nsRect kidDirtyRect = kid->GetVisualOverflowRect(); | |
+ | |
+ /* Check if we need to draw anything. */ | |
+ if (aDirtyRect) { | |
+ NS_ASSERTION(!NS_SVGDisplayListPaintingEnabled() || | |
+ (mState & NS_STATE_SVG_NONDISPLAY_CHILD), | |
+ "Display lists handle dirty rect intersection test"); | |
+ // Transform the dirty rect into app units in our userspace. | |
+ gfxMatrix invmatrix = canvasTM; | |
+ invmatrix.Invert(); | |
+ NS_ASSERTION(!invmatrix.IsSingular(), | |
+ "inverse of non-singular matrix should be non-singular"); | |
+ | |
+ gfxRect transDirtyRect = gfxRect(aDirtyRect->x, aDirtyRect->y, | |
+ aDirtyRect->width, aDirtyRect->height); | |
+ transDirtyRect = invmatrix.TransformBounds(transDirtyRect); | |
+ | |
+ kidDirtyRect.IntersectRect(kidDirtyRect, | |
+ nsLayoutUtils::RoundGfxRectToAppRect(transDirtyRect, | |
+ PresContext()->AppUnitsPerCSSPixel())); | |
+ | |
+ // XXX after bug 614732 is fixed, we will compare mRect with aDirtyRect, | |
+ // not with kidDirtyRect. I.e. | |
+ // int32_t appUnitsPerDevPx = PresContext()->AppUnitsPerDevPixel(); | |
+ // mRect.ToOutsidePixels(appUnitsPerDevPx).Intersects(*aDirtyRect) | |
+ if (kidDirtyRect.IsEmpty()) | |
+ return NS_OK; | |
+ } | |
+ | |
+ gfxContext *gfx = aContext->ThebesContext(); | |
+ | |
+ gfx->Save(); | |
+ | |
+ if (StyleDisplay()->IsScrollableOverflow()) { | |
+ float x, y, width, height; | |
+ static_cast<nsSVGElement*>(mContent)-> | |
+ GetAnimatedLengthValues(&x, &y, &width, &height, nullptr); | |
+ | |
+ gfxRect clipRect = | |
+ nsSVGUtils::GetClipRectForFrame(this, 0.0f, 0.0f, width, height); | |
+ nsSVGUtils::SetClipRect(gfx, canvasTM, clipRect); | |
+ } | |
+ | |
+ // SVG paints in CSS px, but normally frames paint in dev pixels. Here we | |
+ // multiply a CSS-px-to-dev-pixel factor onto canvasTM so our children paint | |
+ // correctly. | |
+ float cssPxPerDevPx = PresContext()-> | |
+ AppUnitsToFloatCSSPixels(PresContext()->AppUnitsPerDevPixel()); | |
+ gfxMatrix canvasTMForChildren = canvasTM; | |
+ canvasTMForChildren.Scale(cssPxPerDevPx, cssPxPerDevPx); | |
+ | |
+ gfx->Multiply(canvasTMForChildren); | |
+ | |
+ uint32_t flags = nsLayoutUtils::PAINT_IN_TRANSFORM; | |
+ if (SVGAutoRenderState::IsPaintingToWindow(aContext)) { | |
+ flags |= nsLayoutUtils::PAINT_TO_WINDOW; | |
+ } | |
+ nsresult rv = nsLayoutUtils::PaintFrame(aContext, kid, nsRegion(kidDirtyRect), | |
+ NS_RGBA(0,0,0,0), flags); | |
+ | |
+ gfx->Restore(); | |
+ | |
+ return rv; | |
+} | |
+ | |
+NS_IMETHODIMP_(nsIFrame*) | |
+nsSVGIFrameFrame::GetFrameForPoint(const nsPoint &aPoint) | |
+{ | |
+ NS_ASSERTION(!NS_SVGDisplayListHitTestingEnabled() || | |
+ (mState & NS_STATE_SVG_NONDISPLAY_CHILD), | |
+ "If display lists are enabled, only hit-testing of a " | |
+ "clipPath's contents should take this code path"); | |
+ | |
+ if (IsDisabled() || (GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD)) | |
+ return nullptr; | |
+ | |
+ nsIFrame* kid = GetFirstPrincipalChild(); | |
+ if (!kid) | |
+ return nullptr; | |
+ | |
+ float x, y, width, height; | |
+ static_cast<nsSVGElement*>(mContent)-> | |
+ GetAnimatedLengthValues(&x, &y, &width, &height, nullptr); | |
+ | |
+ gfxMatrix tm = GetCanvasTM(FOR_HIT_TESTING).Invert(); | |
+ if (tm.IsSingular()) | |
+ return nullptr; | |
+ | |
+ // Convert aPoint from app units in canvas space to user space: | |
+ | |
+ gfxPoint pt = gfxPoint(aPoint.x, aPoint.y) / PresContext()->AppUnitsPerDevPixel(); | |
+ pt = tm.Transform(pt); | |
+ | |
+ if (!gfxRect(0.0f, 0.0f, width, height).Contains(pt)) | |
+ return nullptr; | |
+ | |
+ // Convert pt to app units in *local* space: | |
+ | |
+ pt = pt * nsPresContext::AppUnitsPerCSSPixel(); | |
+ nsPoint point = nsPoint(NSToIntRound(pt.x), NSToIntRound(pt.y)); | |
+ | |
+ nsIFrame *frame = nsLayoutUtils::GetFrameForPoint(kid, point); | |
+ if (frame && nsSVGUtils::HitTestClip(this, aPoint)) | |
+ return frame; | |
+ | |
+ return nullptr; | |
+} | |
+ | |
+NS_IMETHODIMP_(nsRect) | |
+nsSVGIFrameFrame::GetCoveredRegion() | |
+{ | |
+ float x, y, w, h; | |
+ static_cast<SVGIFrameElement*>(mContent)-> | |
+ GetAnimatedLengthValues(&x, &y, &w, &h, nullptr); | |
+ if (w < 0.0f) w = 0.0f; | |
+ if (h < 0.0f) h = 0.0f; | |
+ // GetCanvasTM includes the x,y translation | |
+ /* | |
+ return ToCanvasBounds(gfxRect(0.0, 0.0, w, h), GetCanvasTM(FOR_OUTERSVG_TM), | |
+ PresContext()); | |
+ */ | |
+ return nsSVGUtils::ToCanvasBounds(gfxRect(0.0, 0.0, w, h), GetCanvasTM(FOR_OUTERSVG_TM), | |
+ PresContext()); | |
+} | |
+ | |
+void | |
+nsSVGIFrameFrame::ReflowSVG() | |
+{ | |
+ NS_ASSERTION(nsSVGUtils::OuterSVGIsCallingReflowSVG(this), | |
+ "This call is probably a wasteful mistake"); | |
+ | |
+ NS_ABORT_IF_FALSE(!(GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD), | |
+ "ReflowSVG mechanism not designed for this"); | |
+ | |
+ if (!nsSVGUtils::NeedsReflowSVG(this)) { | |
+ return; | |
+ } | |
+ | |
+ // We update mRect before the DoReflow call so that DoReflow uses the | |
+ // correct dimensions: | |
+ | |
+ float x, y, w, h; | |
+ static_cast<SVGIFrameElement*>(mContent)-> | |
+ GetAnimatedLengthValues(&x, &y, &w, &h, nullptr); | |
+ | |
+ // If mRect's width or height are negative, reflow blows up! We must clamp! | |
+ if (w < 0.0f) w = 0.0f; | |
+ if (h < 0.0f) h = 0.0f; | |
+ | |
+ mRect = nsLayoutUtils::RoundGfxRectToAppRect( | |
+ gfxRect(x, y, w, h), | |
+ PresContext()->AppUnitsPerCSSPixel()); | |
+ | |
+ // Fully mark our kid dirty so that it gets resized if necessary | |
+ // (NS_FRAME_HAS_DIRTY_CHILDREN isn't enough in that case): | |
+ nsIFrame* kid = GetFirstPrincipalChild(); | |
+ if (kid) | |
+ kid->AddStateBits(NS_FRAME_IS_DIRTY); | |
+ | |
+ // Make sure to not allow interrupts if we're not being reflown as a root: | |
+ nsPresContext::InterruptPreventer noInterrupts(PresContext()); | |
+ | |
+ DoReflow(); | |
+ | |
+ if (mState & NS_FRAME_FIRST_REFLOW) { | |
+ // Make sure we have our filter property (if any) before calling | |
+ // FinishAndStoreOverflow (subsequent filter changes are handled off | |
+ // nsChangeHint_UpdateEffects): | |
+ nsSVGEffects::UpdateEffects(this); | |
+ } | |
+ | |
+ // TODO: once we support |overflow:visible| on foreignObject, then we will | |
+ // need to take account of our descendants here. | |
+ nsRect overflow = nsRect(nsPoint(0,0), mRect.Size()); | |
+ nsOverflowAreas overflowAreas(overflow, overflow); | |
+ FinishAndStoreOverflow(overflowAreas, mRect.Size()); | |
+ | |
+ // Now unset the various reflow bits: | |
+ mState &= ~(NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY | | |
+ NS_FRAME_HAS_DIRTY_CHILDREN); | |
+} | |
+ | |
+void | |
+nsSVGIFrameFrame::NotifySVGChanged(uint32_t aFlags) | |
+{ | |
+ NS_ABORT_IF_FALSE(aFlags & (TRANSFORM_CHANGED | COORD_CONTEXT_CHANGED), | |
+ "Invalidation logic may need adjusting"); | |
+ | |
+ bool needNewBounds = false; // i.e. mRect or visual overflow rect | |
+ bool needReflow = false; | |
+ bool needNewCanvasTM = false; | |
+ | |
+ //if (aFlags & COORD_CONTEXT_CHANGED) { | |
+ // SVGIFrameElement *fO = | |
+ // static_cast<SVGIFrameElement*>(mContent); | |
+ // // Coordinate context changes affect mCanvasTM if we have a | |
+ // // percentage 'x' or 'y' | |
+ // if (fO->mLengthAttributes[SVGIFrameElement::ATTR_X].IsPercentage() || | |
+ // fO->mLengthAttributes[SVGIFrameElement::ATTR_Y].IsPercentage()) { | |
+ // needNewBounds = true; | |
+ // needNewCanvasTM = true; | |
+ // } | |
+ // // Our coordinate context's width/height has changed. If we have a | |
+ // // percentage width/height our dimensions will change so we must reflow. | |
+ // if (fO->mLengthAttributes[SVGIFrameElement::ATTR_WIDTH].IsPercentage() || | |
+ // fO->mLengthAttributes[SVGIFrameElement::ATTR_HEIGHT].IsPercentage()) { | |
+ // needNewBounds = true; | |
+ // needReflow = true; | |
+ // } | |
+ //} | |
+ | |
+ if (aFlags & TRANSFORM_CHANGED) { | |
+ if (mCanvasTM && mCanvasTM->IsSingular()) { | |
+ needNewBounds = true; // old bounds are bogus | |
+ } | |
+ needNewCanvasTM = true; | |
+ // In an ideal world we would reflow when our CTM changes. This is because | |
+ // glyph metrics do not necessarily scale uniformly with change in scale | |
+ // and, as a result, CTM changes may require text to break at different | |
+ // points. The problem would be how to keep performance acceptable when | |
+ // e.g. the transform of an ancestor is animated. | |
+ // We also seem to get some sort of infinite loop post bug 421584 if we | |
+ // reflow. | |
+ } | |
+ | |
+ if (needNewBounds) { | |
+ // Ancestor changes can't affect how we render from the perspective of | |
+ // any rendering observers that we may have, so we don't need to | |
+ // invalidate them. We also don't need to invalidate ourself, since our | |
+ // changed ancestor will have invalidated its entire area, which includes | |
+ // our area. | |
+ nsSVGUtils::ScheduleReflowSVG(this); | |
+ } | |
+ | |
+ // If we're called while the PresShell is handling reflow events then we | |
+ // must have been called as a result of the NotifyViewportChange() call in | |
+ // our nsSVGOuterSVGFrame's Reflow() method. We must not call RequestReflow | |
+ // at this point (i.e. during reflow) because it could confuse the | |
+ // PresShell and prevent it from reflowing us properly in future. Besides | |
+ // that, nsSVGOuterSVGFrame::DidReflow will take care of reflowing us | |
+ // synchronously, so there's no need. | |
+ if (needReflow && !PresContext()->PresShell()->IsReflowLocked()) { | |
+ RequestReflow(nsIPresShell::eResize); | |
+ } | |
+ | |
+ if (needNewCanvasTM) { | |
+ // Do this after calling InvalidateAndScheduleBoundsUpdate in case we | |
+ // change the code and it needs to use it. | |
+ mCanvasTM = nullptr; | |
+ } | |
+} | |
+ | |
+SVGBBox | |
+nsSVGIFrameFrame::GetBBoxContribution(const gfxMatrix &aToBBoxUserspace, | |
+ uint32_t aFlags) | |
+{ | |
+ SVGIFrameElement *content = | |
+ static_cast<SVGIFrameElement*>(mContent); | |
+ | |
+ float x, y, w, h; | |
+ content->GetAnimatedLengthValues(&x, &y, &w, &h, nullptr); | |
+ | |
+ if (w < 0.0f) w = 0.0f; | |
+ if (h < 0.0f) h = 0.0f; | |
+ | |
+ if (aToBBoxUserspace.IsSingular()) { | |
+ // XXX ReportToConsole | |
+ return SVGBBox(); | |
+ } | |
+ return aToBBoxUserspace.TransformBounds(gfxRect(0.0, 0.0, w, h)); | |
+} | |
+ | |
+//---------------------------------------------------------------------- | |
+ | |
+gfxMatrix | |
+nsSVGIFrameFrame::GetCanvasTM(uint32_t aFor) | |
+{ | |
+ if (!(GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD)) { | |
+ if ((aFor == FOR_PAINTING && NS_SVGDisplayListPaintingEnabled()) || | |
+ (aFor == FOR_HIT_TESTING && NS_SVGDisplayListHitTestingEnabled())) { | |
+ return nsSVGIntegrationUtils::GetCSSPxToDevPxMatrix(this); | |
+ } | |
+ } | |
+ if (!mCanvasTM) { | |
+ NS_ASSERTION(mParent, "null parent"); | |
+ | |
+ //nsSVGContainerFrame *parent = static_cast<nsSVGContainerFrame*>(mParent); | |
+ //SVGForeignObjectElement *content = | |
+ // static_cast<SVGForeignObjectElement*>(mContent); | |
+ nsSVGContainerFrame *parent = static_cast<nsSVGContainerFrame*>(mParent); | |
+ SVGIFrameElement *content = static_cast<SVGIFrameElement*>(mContent); | |
+ | |
+ gfxMatrix tm = content->PrependLocalTransformsTo(parent->GetCanvasTM(aFor)); | |
+ | |
+ mCanvasTM = new gfxMatrix(tm); | |
+ } | |
+ return *mCanvasTM; | |
+} | |
+ | |
+//---------------------------------------------------------------------- | |
+// Implementation helpers | |
+ | |
+void nsSVGIFrameFrame::RequestReflow(nsIPresShell::IntrinsicDirty aType) | |
+{ | |
+ if (GetStateBits() & NS_FRAME_FIRST_REFLOW) | |
+ // If we haven't had a ReflowSVG() yet, nothing to do. | |
+ return; | |
+ | |
+ nsIFrame* kid = GetFirstPrincipalChild(); | |
+ if (!kid) | |
+ return; | |
+ | |
+ PresContext()->PresShell()->FrameNeedsReflow(kid, aType, NS_FRAME_IS_DIRTY); | |
+} | |
+ | |
+void | |
+nsSVGIFrameFrame::DoReflow() | |
+{ | |
+ // Skip reflow if we're zero-sized, unless this is our first reflow. | |
+ if (IsDisabled() && | |
+ !(GetStateBits() & NS_FRAME_FIRST_REFLOW)) | |
+ return; | |
+ | |
+ nsPresContext *presContext = PresContext(); | |
+ nsIFrame* kid = GetFirstPrincipalChild(); | |
+ if (!kid) | |
+ return; | |
+ | |
+ // initiate a synchronous reflow here and now: | |
+ nsIPresShell* presShell = presContext->PresShell(); | |
+ NS_ASSERTION(presShell, "null presShell"); | |
+ nsRefPtr<nsRenderingContext> renderingContext = | |
+ presShell->GetReferenceRenderingContext(); | |
+ if (!renderingContext) | |
+ return; | |
+ | |
+ mInReflow = true; | |
+ | |
+ nsHTMLReflowState reflowState(presContext, kid, | |
+ renderingContext, | |
+ nsSize(mRect.width, NS_UNCONSTRAINEDSIZE)); | |
+ nsHTMLReflowMetrics desiredSize; | |
+ nsReflowStatus status; | |
+ | |
+ // We don't use mRect.height above because that tells the child to do | |
+ // page/column breaking at that height. | |
+ NS_ASSERTION(reflowState.mComputedBorderPadding == nsMargin(0, 0, 0, 0) && | |
+ reflowState.mComputedMargin == nsMargin(0, 0, 0, 0), | |
+ "style system should ensure that :-moz-svg-foreign-content " | |
+ "does not get styled"); | |
+ NS_ASSERTION(reflowState.ComputedWidth() == mRect.width, | |
+ "reflow state made child wrong size"); | |
+ reflowState.SetComputedHeight(mRect.height); | |
+ | |
+ ReflowChild(kid, presContext, desiredSize, reflowState, 0, 0, | |
+ NS_FRAME_NO_MOVE_FRAME, status); | |
+ NS_ASSERTION(mRect.width == desiredSize.width && | |
+ mRect.height == desiredSize.height, "unexpected size"); | |
+ FinishReflowChild(kid, presContext, &reflowState, desiredSize, 0, 0, | |
+ NS_FRAME_NO_MOVE_FRAME); | |
+ | |
+ mInReflow = false; | |
+} | |
+ | |
+nsRect | |
+nsSVGIFrameFrame::GetInvalidRegion() | |
+{ | |
+ nsIFrame* kid = GetFirstPrincipalChild(); | |
+ if (kid->HasInvalidFrameInSubtree()) { | |
+ gfxRect r(mRect.x, mRect.y, mRect.width, mRect.height); | |
+ r.Scale(1.0 / nsPresContext::AppUnitsPerCSSPixel()); | |
+ nsRect rect = ToCanvasBounds(r, GetCanvasTM(FOR_PAINTING), PresContext()); | |
+ rect = nsSVGUtils::GetPostFilterVisualOverflowRect(this, rect); | |
+ return rect; | |
+ } | |
+ return nsRect(); | |
+} | |
+ | |
+ | |
+/* from nsContainerFrame */ | |
+/** | |
+ * Invokes the WillReflow() function, positions the frame and its view (if | |
+ * requested), and then calls Reflow(). If the reflow succeeds and the child | |
+ * frame is complete, deletes any next-in-flows using DeleteNextInFlowChild() | |
+ */ | |
+nsresult | |
+nsSVGIFrameFrame::ReflowChild(nsIFrame* aKidFrame, | |
+ nsPresContext* aPresContext, | |
+ nsHTMLReflowMetrics& aDesiredSize, | |
+ const nsHTMLReflowState& aReflowState, | |
+ nscoord aX, | |
+ nscoord aY, | |
+ uint32_t aFlags, | |
+ nsReflowStatus& aStatus, | |
+ nsOverflowContinuationTracker* aTracker) | |
+{ | |
+ NS_PRECONDITION(aReflowState.frame == aKidFrame, "bad reflow state"); | |
+ | |
+ nsresult result; | |
+ | |
+ // Send the WillReflow() notification, and position the child frame | |
+ // and its view if requested | |
+ aKidFrame->WillReflow(aPresContext); | |
+ | |
+ if (NS_FRAME_NO_MOVE_FRAME != (aFlags & NS_FRAME_NO_MOVE_FRAME)) { | |
+ aKidFrame->SetPosition(nsPoint(aX, aY)); | |
+ } | |
+ | |
+ if (0 == (aFlags & NS_FRAME_NO_MOVE_VIEW)) { | |
+ PositionFrameView(aKidFrame); | |
+ } | |
+ | |
+ // Reflow the child frame | |
+ result = aKidFrame->Reflow(aPresContext, aDesiredSize, aReflowState, | |
+ aStatus); | |
+ | |
+ // If the reflow was successful and the child frame is complete, delete any | |
+ // next-in-flows | |
+ if (NS_SUCCEEDED(result) && NS_FRAME_IS_FULLY_COMPLETE(aStatus)) { | |
+ nsIFrame* kidNextInFlow = aKidFrame->GetNextInFlow(); | |
+ if (nullptr != kidNextInFlow) { | |
+ // Remove all of the childs next-in-flows. Make sure that we ask | |
+ // the right parent to do the removal (it's possible that the | |
+ // parent is not this because we are executing pullup code) | |
+ if (aTracker) aTracker->Finish(aKidFrame); | |
+ static_cast<nsContainerFrame*>(kidNextInFlow->GetParent()) | |
+ ->DeleteNextInFlowChild(aPresContext, kidNextInFlow, true); | |
+ } | |
+ } | |
+ return result; | |
+} | |
+ | |
+ | |
+/** | |
+ * Position the views of |aFrame|'s descendants. A container frame | |
+ * should call this method if it moves a frame after |Reflow|. | |
+ */ | |
+void | |
+nsSVGIFrameFrame::PositionChildViews(nsIFrame* aFrame) | |
+{ | |
+ if (!(aFrame->GetStateBits() & NS_FRAME_HAS_CHILD_WITH_VIEW)) { | |
+ return; | |
+ } | |
+ | |
+ // Recursively walk aFrame's child frames. | |
+ // Process the additional child lists, but skip the popup list as the | |
+ // view for popups is managed by the parent. Currently only nsMenuFrame | |
+ // has a popupList and during layout will call nsMenuPopupFrame::AdjustView. | |
+ ChildListIterator lists(aFrame); | |
+ for (; !lists.IsDone(); lists.Next()) { | |
+ if (lists.CurrentID() == kPopupList) { | |
+ continue; | |
+ } | |
+ nsFrameList::Enumerator childFrames(lists.CurrentList()); | |
+ for (; !childFrames.AtEnd(); childFrames.Next()) { | |
+ // Position the frame's view (if it has one) otherwise recursively | |
+ // process its children | |
+ nsIFrame* childFrame = childFrames.get(); | |
+ if (childFrame->HasView()) { | |
+ PositionFrameView(childFrame); | |
+ } else { | |
+ PositionChildViews(childFrame); | |
+ } | |
+ } | |
+ } | |
+} | |
+ | |
+/** | |
+ * The second half of frame reflow. Does the following: | |
+ * - sets the frame's bounds | |
+ * - sizes and positions (if requested) the frame's view. If the frame's final | |
+ * position differs from the current position and the frame itself does not | |
+ * have a view, then any child frames with views are positioned so they stay | |
+ * in sync | |
+ * - sets the view's visibility, opacity, content transparency, and clip | |
+ * - invoked the DidReflow() function | |
+ * | |
+ * Flags: | |
+ * NS_FRAME_NO_MOVE_FRAME - don't move the frame. aX and aY are ignored in this | |
+ * case. Also implies NS_FRAME_NO_MOVE_VIEW | |
+ * NS_FRAME_NO_MOVE_VIEW - don't position the frame's view. Set this if you | |
+ * don't want to automatically sync the frame and view | |
+ * NS_FRAME_NO_SIZE_VIEW - don't size the frame's view | |
+ */ | |
+nsresult | |
+nsSVGIFrameFrame::FinishReflowChild(nsIFrame* aKidFrame, | |
+ nsPresContext* aPresContext, | |
+ const nsHTMLReflowState* aReflowState, | |
+ const nsHTMLReflowMetrics& aDesiredSize, | |
+ nscoord aX, | |
+ nscoord aY, | |
+ uint32_t aFlags) | |
+{ | |
+ nsPoint curOrigin = aKidFrame->GetPosition(); | |
+ nsRect bounds(aX, aY, aDesiredSize.width, aDesiredSize.height); | |
+ | |
+ aKidFrame->SetRect(bounds); | |
+ | |
+ if (aKidFrame->HasView()) { | |
+ nsView* view = aKidFrame->GetView(); | |
+ // Make sure the frame's view is properly sized and positioned and has | |
+ // things like opacity correct | |
+ SyncFrameViewAfterReflow(aPresContext, aKidFrame, view, | |
+ aDesiredSize.VisualOverflow(), aFlags); | |
+ } | |
+ | |
+ if (!(aFlags & NS_FRAME_NO_MOVE_VIEW) && | |
+ (curOrigin.x != aX || curOrigin.y != aY)) { | |
+ if (!aKidFrame->HasView()) { | |
+ // If the frame has moved, then we need to make sure any child views are | |
+ // correctly positioned | |
+ PositionChildViews(aKidFrame); | |
+ } | |
+ } | |
+ | |
+ return aKidFrame->DidReflow(aPresContext, aReflowState, nsDidReflowStatus::FINISHED); | |
+} | |
+ | |
+/** | |
+ * Position the view associated with |aKidFrame|, if there is one. A | |
+ * container frame should call this method after positioning a frame, | |
+ * but before |Reflow|. | |
+ */ | |
+void | |
+nsSVGIFrameFrame::PositionFrameView(nsIFrame* aKidFrame) | |
+{ | |
+ nsIFrame* parentFrame = aKidFrame->GetParent(); | |
+ if (!aKidFrame->HasView() || !parentFrame) | |
+ return; | |
+ | |
+ nsView* view = aKidFrame->GetView(); | |
+ nsViewManager* vm = view->GetViewManager(); | |
+ nsPoint pt; | |
+ nsView* ancestorView = parentFrame->GetClosestView(&pt); | |
+ | |
+ if (ancestorView != view->GetParent()) { | |
+ NS_ASSERTION(ancestorView == view->GetParent()->GetParent(), | |
+ "Allowed only one anonymous view between frames"); | |
+ // parentFrame is responsible for positioning aKidFrame's view | |
+ // explicitly | |
+ return; | |
+ } | |
+ | |
+ pt += aKidFrame->GetPosition(); | |
+ vm->MoveViewTo(view, pt.x, pt.y); | |
+} | |
+ | |
+void | |
+nsSVGIFrameFrame::SyncFrameViewAfterReflow(nsPresContext* aPresContext, | |
+ nsIFrame* aFrame, | |
+ nsView* aView, | |
+ const nsRect& aVisualOverflowArea, | |
+ uint32_t aFlags) | |
+{ | |
+ if (!aView) { | |
+ return; | |
+ } | |
+ | |
+ // Make sure the view is sized and positioned correctly | |
+ if (0 == (aFlags & NS_FRAME_NO_MOVE_VIEW)) { | |
+ PositionFrameView(aFrame); | |
+ } | |
+ | |
+ if (0 == (aFlags & NS_FRAME_NO_SIZE_VIEW)) { | |
+ nsViewManager* vm = aView->GetViewManager(); | |
+ | |
+ vm->ResizeView(aView, aVisualOverflowArea, true); | |
+ } | |
+} | |
+ | |
+const nsFrameList& | |
+nsSVGIFrameFrame::GetChildList(ChildListID aListID) const | |
+{ | |
+ // We only know about the principal child list and the overflow lists. | |
+ switch (aListID) { | |
+ case kPrincipalList: | |
+ return mFrames; | |
+ default: | |
+ return nsSubDocumentFrame::GetChildList(aListID); | |
+ } | |
+} | |
+ | |
+ | |
+void | |
+nsSVGIFrameFrame::GetChildLists(nsTArray<ChildList>* aLists) const | |
+{ | |
+ mFrames.AppendIfNonempty(aLists, kPrincipalList); | |
+ nsSubDocumentFrame::GetChildLists(aLists); | |
+} | |
+ | |
+static void AppendIfNonempty(const nsIFrame* aFrame, | |
+ FramePropertyTable* aPropTable, | |
+ const FramePropertyDescriptor* aProperty, | |
+ nsTArray<nsIFrame::ChildList>* aLists, | |
+ nsIFrame::ChildListID aListID) | |
+{ | |
+ nsFrameList* list = static_cast<nsFrameList*>( | |
+ aPropTable->Get(aFrame, aProperty)); | |
+ if (list) { | |
+ list->AppendIfNonempty(aLists, aListID); | |
+ } | |
+} | |
+ | |
+void | |
+nsSVGIFrameFrame::ShowViewer() | |
+{ | |
+ if (mCallingShow) { | |
+ return; | |
+ } | |
+ | |
+ if (!PresContext()->IsDynamic()) { | |
+ // We let the printing code take care of loading the document; just | |
+ // create the inner view for it to use. | |
+ (void) EnsureInnerView(); | |
+ } else { | |
+ nsRefPtr<nsFrameLoader> frameloader = FrameLoader(); | |
+ if (frameloader) { | |
+ nsIntSize margin = GetMarginAttributes(); | |
+ const nsStyleDisplay* disp = StyleDisplay(); | |
+ nsWeakFrame weakThis(this); | |
+ mCallingShow = true; | |
+ bool didCreateDoc = | |
+ frameloader->ShowSVG(margin.width, margin.height, | |
+ this); | |
+ /* frameloader->ShowSVG(margin.width, margin.height, | |
+ ConvertOverflow(disp->mOverflowX), | |
+ ConvertOverflow(disp->mOverflowY), | |
+ this); */ | |
+ if (!weakThis.IsAlive()) { | |
+ return; | |
+ } | |
+ mCallingShow = false; | |
+ mDidCreateDoc = didCreateDoc; | |
+ } | |
+ } | |
+} | |
+ | |
diff --git layout/svg/nsSVGIFrameFrame.h layout/svg/nsSVGIFrameFrame.h | |
new file mode 100644 | |
index 0000000..88c9f9f | |
--- /dev/null | |
+++ layout/svg/nsSVGIFrameFrame.h | |
@@ -0,0 +1,257 @@ | |
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | |
+/* 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/. */ | |
+ | |
+#ifndef NS_SVGIFRAMEFRAME_H | |
+#define NS_SVGIFRAMEFRAME_H | |
+ | |
+#include "mozilla/Attributes.h" | |
+#include "nsIPresShell.h" | |
+#include "nsISVGChildFrame.h" | |
+#include "nsRegion.h" | |
+#include "nsSubDocumentFrame.h" | |
+#include "nsSVGUtils.h" | |
+//#include "nsSVGIFrameForeignObjectFrame.h" | |
+#include "nsContainerFrame.h" | |
+ | |
+class nsRenderingContext; | |
+class nsSVGOuterSVGFrame; | |
+ | |
+typedef nsSubDocumentFrame nsSVGIFrameFrameBase; | |
+ | |
+class nsSVGIFrameFrame : public nsSVGIFrameFrameBase, | |
+ public nsISVGChildFrame | |
+{ | |
+ friend nsIFrame* | |
+ NS_NewSVGIFrameFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); | |
+protected: | |
+ nsSVGIFrameFrame(nsStyleContext* aContext); | |
+ | |
+public: | |
+ NS_DECL_QUERYFRAME | |
+ NS_DECL_FRAMEARENA_HELPERS | |
+ | |
+ // nsIFrame methods | |
+ NS_IMETHOD Init(nsIContent* aContent, | |
+ nsIFrame* aParent, | |
+ nsIFrame* aPrevInFlow); | |
+ NS_IMETHOD SetInitialChildList(ChildListID aListID, | |
+ nsFrameList& aChildList) MOZ_OVERRIDE; | |
+ NS_IMETHOD AppendFrames(ChildListID aListID, | |
+ nsFrameList& aFrameList); | |
+ NS_IMETHOD InsertFrames(ChildListID aListID, | |
+ nsIFrame* aPrevFrame, | |
+ nsFrameList& aFrameList); | |
+ NS_IMETHOD RemoveFrame(ChildListID aListID, | |
+ nsIFrame* aOldFrame) MOZ_OVERRIDE; | |
+ | |
+ | |
+ | |
+ virtual void DestroyFrom(nsIFrame* aDestructRoot); | |
+ | |
+ NS_IMETHOD AttributeChanged(int32_t aNameSpaceID, | |
+ nsIAtom* aAttribute, | |
+ int32_t aModType); | |
+ | |
+ virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE; | |
+ | |
+ /* | |
+ virtual nsIFrame* GetContentInsertionFrame() { | |
+ nsIFrame *frame = GetFirstPrincipalChild(); | |
+ if (!frame) | |
+ return nullptr; | |
+ return frame->GetContentInsertionFrame(); | |
+ }*/ | |
+ | |
+ virtual nsIFrame* GetSubdocumentRootFrame(); | |
+ | |
+ NS_IMETHOD Reflow(nsPresContext* aPresContext, | |
+ nsHTMLReflowMetrics& aDesiredSize, | |
+ const nsHTMLReflowState& aReflowState, | |
+ nsReflowStatus& aStatus); | |
+ | |
+ // void BuildDisplayList(nsDisplayListBuilder* aBuilder, | |
+ // const nsRect& aDirtyRect, | |
+ // const nsDisplayListSet& aLists); | |
+ | |
+ /** | |
+ * Get the "type" of the frame | |
+ * | |
+ * @see nsGkAtoms::svgIFrameFrame | |
+ */ | |
+ virtual nsIAtom* GetType() const; | |
+ | |
+ virtual bool IsFrameOfType(uint32_t aFlags) const | |
+ { | |
+ return nsSVGIFrameFrameBase::IsFrameOfType(aFlags & | |
+ ~(nsIFrame::eSVG | nsIFrame::eSVGForeignObject)); | |
+ } | |
+ | |
+ virtual bool IsSVGTransformed(gfxMatrix *aOwnTransform, | |
+ gfxMatrix *aFromParentTransform) const; | |
+ | |
+ /* from nsContainerFrame */ | |
+ virtual const nsFrameList& GetChildList(ChildListID aList) const MOZ_OVERRIDE; | |
+ virtual void GetChildLists(nsTArray<ChildList>* aLists) const MOZ_OVERRIDE; | |
+ | |
+ | |
+ /** | |
+ * Invokes the WillReflow() function, positions the frame and its view (if | |
+ * requested), and then calls Reflow(). If the reflow succeeds and the child | |
+ * frame is complete, deletes any next-in-flows using DeleteNextInFlowChild() | |
+ * | |
+ * Flags: | |
+ * NS_FRAME_NO_MOVE_VIEW - don't position the frame's view. Set this if you | |
+ * don't want to automatically sync the frame and view | |
+ * NS_FRAME_NO_MOVE_FRAME - don't move the frame. aX and aY are ignored in this | |
+ * case. Also implies NS_FRAME_NO_MOVE_VIEW | |
+ */ | |
+ nsresult ReflowChild(nsIFrame* aKidFrame, | |
+ nsPresContext* aPresContext, | |
+ nsHTMLReflowMetrics& aDesiredSize, | |
+ const nsHTMLReflowState& aReflowState, | |
+ nscoord aX, | |
+ nscoord aY, | |
+ uint32_t aFlags, | |
+ nsReflowStatus& aStatus, | |
+ nsOverflowContinuationTracker* aTracker = nullptr); | |
+ | |
+ /** | |
+ * The second half of frame reflow. Does the following: | |
+ * - sets the frame's bounds | |
+ * - sizes and positions (if requested) the frame's view. If the frame's final | |
+ * position differs from the current position and the frame itself does not | |
+ * have a view, then any child frames with views are positioned so they stay | |
+ * in sync | |
+ * - sets the view's visibility, opacity, content transparency, and clip | |
+ * - invoked the DidReflow() function | |
+ * | |
+ * Flags: | |
+ * NS_FRAME_NO_MOVE_FRAME - don't move the frame. aX and aY are ignored in this | |
+ * case. Also implies NS_FRAME_NO_MOVE_VIEW | |
+ * NS_FRAME_NO_MOVE_VIEW - don't position the frame's view. Set this if you | |
+ * don't want to automatically sync the frame and view | |
+ * NS_FRAME_NO_SIZE_VIEW - don't size the frame's view | |
+ */ | |
+ static nsresult FinishReflowChild(nsIFrame* aKidFrame, | |
+ nsPresContext* aPresContext, | |
+ const nsHTMLReflowState* aReflowState, | |
+ const nsHTMLReflowMetrics& aDesiredSize, | |
+ nscoord aX, | |
+ nscoord aY, | |
+ uint32_t aFlags); | |
+ | |
+ static void PositionChildViews(nsIFrame* aFrame); | |
+ | |
+ // Positions the frame's view based on the frame's origin | |
+ static void PositionFrameView(nsIFrame* aKidFrame); | |
+ | |
+ // Set the view's size and position after its frame has been reflowed. | |
+ // | |
+ // Flags: | |
+ // NS_FRAME_NO_MOVE_VIEW - don't position the frame's view. Set this if you | |
+ // don't want to automatically sync the frame and view | |
+ // NS_FRAME_NO_SIZE_VIEW - don't size the view | |
+ static void SyncFrameViewAfterReflow(nsPresContext* aPresContext, | |
+ nsIFrame* aFrame, | |
+ nsView* aView, | |
+ const nsRect& aVisualOverflowArea, | |
+ uint32_t aFlags = 0); | |
+ | |
+ // ========================================================================== | |
+ /* Overflow containers are continuation frames that hold overflow. They | |
+ * are created when the frame runs out of computed height, but still has | |
+ * too much content to fit in the availableHeight. The parent creates a | |
+ * continuation as usual, but marks it as NS_FRAME_IS_OVERFLOW_CONTAINER | |
+ * and adds it to its next-in-flow's overflow container list, either by | |
+ * adding it directly or by putting it in its own excess overflow containers | |
+ * list (to be drained by the next-in-flow when it calls | |
+ * ReflowOverflowContainerChildren). The parent continues reflow as if | |
+ * the frame was complete once it ran out of computed height, but returns | |
+ * either an NS_FRAME_NOT_COMPLETE or NS_FRAME_OVERFLOW_INCOMPLETE reflow | |
+ * status to request a next-in-flow. The parent's next-in-flow is then | |
+ * responsible for calling ReflowOverflowContainerChildren to (drain and) | |
+ * reflow these overflow continuations. Overflow containers do not affect | |
+ * other frames' size or position during reflow (but do affect their | |
+ * parent's overflow area). | |
+ * | |
+ * Overflow container continuations are different from normal continuations | |
+ * in that | |
+ * - more than one child of the frame can have its next-in-flow broken | |
+ * off and pushed into the frame's next-in-flow | |
+ * - new continuations may need to be spliced into the middle of the list | |
+ * or deleted continuations slipped out | |
+ * e.g. A, B, C are all fixed-size containers on one page, all have | |
+ * overflow beyond availableHeight, and content is dynamically added | |
+ * and removed from B | |
+ * As a result, it is not possible to simply prepend the new continuations | |
+ * to the old list as with the overflowProperty mechanism. To avoid | |
+ * complicated list splicing, the code assumes only one overflow containers | |
+ * list exists for a given frame: either its own overflowContainersProperty | |
+ * or its prev-in-flow's excessOverflowContainersProperty, not both. | |
+ * | |
+ * The nsOverflowContinuationTracker helper class should be used for tracking | |
+ * overflow containers and adding them to the appropriate list. | |
+ * See nsBlockFrame::Reflow for a sample implementation. | |
+ */ | |
+ | |
+ friend class nsOverflowContinuationTracker; | |
+ | |
+ | |
+#ifdef DEBUG | |
+ NS_IMETHOD GetFrameName(nsAString& aResult) const | |
+ { | |
+ return MakeFrameName(NS_LITERAL_STRING("SVGIFrame"), aResult); | |
+ } | |
+#endif | |
+ | |
+ // nsISVGChildFrame interface: | |
+ NS_IMETHOD PaintSVG(nsRenderingContext *aContext, | |
+ const nsIntRect *aDirtyRect); | |
+ NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint) MOZ_OVERRIDE; | |
+ NS_IMETHOD_(nsRect) GetCoveredRegion() MOZ_OVERRIDE; | |
+ virtual void ReflowSVG() MOZ_OVERRIDE; | |
+ virtual void NotifySVGChanged(uint32_t aFlags) MOZ_OVERRIDE; | |
+ virtual SVGBBox GetBBoxContribution(const gfxMatrix &aToBBoxUserspace, | |
+ uint32_t aFlags) MOZ_OVERRIDE; | |
+ NS_IMETHOD_(bool) IsDisplayContainer() MOZ_OVERRIDE { return true; } | |
+ | |
+ gfxMatrix GetCanvasTM(uint32_t aFor); | |
+ | |
+ nsRect GetInvalidRegion(); | |
+ | |
+protected: | |
+ friend class AsyncSVGFrameInit; | |
+ | |
+ | |
+ // implementation helpers: | |
+ void DoReflow(); | |
+ void RequestReflow(nsIPresShell::IntrinsicDirty aType); | |
+ | |
+ // If width or height is less than or equal to zero we must disable rendering | |
+ bool IsDisabled() const { return mRect.width <= 0 || mRect.height <= 0; } | |
+ | |
+ nsAutoPtr<gfxMatrix> mCanvasTM; | |
+ | |
+ bool mInReflow; | |
+ | |
+ // implementation from nsContainerFrame | |
+ void BuildDisplayListForNonBlockChildren(nsDisplayListBuilder* aBuilder, | |
+ const nsRect& aDirtyRect, | |
+ const nsDisplayListSet& aLists, | |
+ uint32_t aFlags = 0); | |
+ | |
+ nsFrameList mFrames; | |
+ | |
+ //nsSVGIFrameForeignObjectFrame* mForeignObject; | |
+ | |
+ // Show our document viewer. The document viewer is hidden via a script | |
+ // runner, so that we can save and restore the presentation if we're | |
+ // being reframed. | |
+ void ShowViewer(); | |
+ | |
+ | |
+}; | |
+ | |
+#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment