mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-07 18:04:46 +00:00
Bug 1216893 - Add in disabled namespace for SVG r=hsivonen,smaug
MozReview-Commit-ID: 7Gum6wazraS --HG-- extra : rebase_source : a2348710908e160cb09e48f15adfb50cd485f151
This commit is contained in:
parent
1a6470f3a1
commit
91e141995c
@ -24,6 +24,7 @@ static const int32_t kNameSpaceID_None = 0;
|
||||
#define kNameSpaceID_XUL 9
|
||||
#define kNameSpaceID_SVG 10
|
||||
#define kNameSpaceID_disabled_MathML 11
|
||||
#define kNameSpaceID_LastBuiltin 11 // last 'built-in' namespace
|
||||
#define kNameSpaceID_disabled_SVG 12
|
||||
#define kNameSpaceID_LastBuiltin 12 // last 'built-in' namespace
|
||||
|
||||
#endif // mozilla_dom_NameSpaceConstants_h__
|
||||
|
@ -28,9 +28,11 @@
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
static const char* kPrefSVGDisabled = "svg.disabled";
|
||||
static const char* kPrefMathMLDisabled = "mathml.disabled";
|
||||
static const char* kObservedPrefs[] = {
|
||||
kPrefMathMLDisabled,
|
||||
kPrefSVGDisabled,
|
||||
nullptr
|
||||
};
|
||||
StaticRefPtr<nsNameSpaceManager> nsNameSpaceManager::sInstance;
|
||||
@ -63,6 +65,7 @@ bool nsNameSpaceManager::Init()
|
||||
|
||||
mozilla::Preferences::AddStrongObservers(this, kObservedPrefs);
|
||||
mMathMLDisabled = mozilla::Preferences::GetBool(kPrefMathMLDisabled);
|
||||
mSVGDisabled = mozilla::Preferences::GetBool(kPrefSVGDisabled);
|
||||
|
||||
|
||||
// Need to be ordered according to ID.
|
||||
@ -79,6 +82,7 @@ bool nsNameSpaceManager::Init()
|
||||
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xul, kNameSpaceID_XUL);
|
||||
REGISTER_NAMESPACE(nsGkAtoms::nsuri_svg, kNameSpaceID_SVG);
|
||||
REGISTER_DISABLED_NAMESPACE(nsGkAtoms::nsuri_mathml, kNameSpaceID_disabled_MathML);
|
||||
REGISTER_DISABLED_NAMESPACE(nsGkAtoms::nsuri_svg, kNameSpaceID_disabled_SVG);
|
||||
|
||||
#undef REGISTER_NAMESPACE
|
||||
#undef REGISTER_DISABLED_NAMESPACE
|
||||
@ -151,9 +155,11 @@ nsNameSpaceManager::GetNameSpaceID(nsIAtom* aURI,
|
||||
}
|
||||
|
||||
int32_t nameSpaceID;
|
||||
if (mMathMLDisabled &&
|
||||
mDisabledURIToIDTable.Get(aURI, &nameSpaceID) &&
|
||||
!aInChromeDoc) {
|
||||
if (!aInChromeDoc
|
||||
&& (mMathMLDisabled || mSVGDisabled)
|
||||
&& mDisabledURIToIDTable.Get(aURI, &nameSpaceID)
|
||||
&& ((mMathMLDisabled && kNameSpaceID_disabled_MathML == nameSpaceID) ||
|
||||
(mSVGDisabled && kNameSpaceID_disabled_SVG == nameSpaceID))) {
|
||||
NS_POSTCONDITION(nameSpaceID >= 0, "Bogus namespace ID");
|
||||
return nameSpaceID;
|
||||
}
|
||||
@ -186,7 +192,7 @@ NS_NewElement(Element** aResult,
|
||||
// disabled MathML nodes by swapping the namespace.
|
||||
nsNameSpaceManager* nsmgr = nsNameSpaceManager::GetInstance();
|
||||
if ((nsmgr && !nsmgr->mMathMLDisabled) ||
|
||||
nsContentUtils::IsChromeDoc(ni->GetDocument())) {
|
||||
nsContentUtils::IsSystemPrincipal(ni->GetDocument()->NodePrincipal())) {
|
||||
return NS_NewMathMLElement(aResult, ni.forget());
|
||||
}
|
||||
|
||||
@ -197,7 +203,38 @@ NS_NewElement(Element** aResult,
|
||||
return NS_NewXMLElement(aResult, genericXMLNI.forget());
|
||||
}
|
||||
if (ns == kNameSpaceID_SVG) {
|
||||
return NS_NewSVGElement(aResult, ni.forget(), aFromParser);
|
||||
// If the svg.disabled pref. is true, convert all SVG nodes into
|
||||
// disabled SVG nodes by swapping the namespace.
|
||||
nsNameSpaceManager* nsmgr = nsNameSpaceManager::GetInstance();
|
||||
nsCOMPtr<nsILoadInfo> loadInfo;
|
||||
bool SVGEnabled = false;
|
||||
|
||||
if (nsmgr && !nsmgr->mSVGDisabled) {
|
||||
SVGEnabled = true;
|
||||
} else {
|
||||
nsCOMPtr<nsIChannel> channel = ni->GetDocument()->GetChannel();
|
||||
// We don't have a channel for SVGs constructed inside a SVG script
|
||||
if (channel) {
|
||||
loadInfo = channel->GetLoadInfo();
|
||||
}
|
||||
}
|
||||
if (SVGEnabled ||
|
||||
nsContentUtils::IsSystemPrincipal(ni->GetDocument()->NodePrincipal()) ||
|
||||
(loadInfo &&
|
||||
(loadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_IMAGE ||
|
||||
loadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_OTHER) &&
|
||||
(nsContentUtils::IsSystemPrincipal(loadInfo->LoadingPrincipal()) ||
|
||||
nsContentUtils::IsSystemPrincipal(loadInfo->TriggeringPrincipal())
|
||||
)
|
||||
)
|
||||
) {
|
||||
return NS_NewSVGElement(aResult, ni.forget(), aFromParser);
|
||||
}
|
||||
RefPtr<mozilla::dom::NodeInfo> genericXMLNI =
|
||||
ni->NodeInfoManager()->
|
||||
GetNodeInfo(ni->NameAtom(), ni->GetPrefixAtom(),
|
||||
kNameSpaceID_disabled_SVG, ni->NodeType(), ni->GetExtraName());
|
||||
return NS_NewXMLElement(aResult, genericXMLNI.forget());
|
||||
}
|
||||
if (ns == kNameSpaceID_XBL && ni->Equals(nsGkAtoms::children)) {
|
||||
NS_ADDREF(*aResult = new XBLChildrenElement(ni.forget()));
|
||||
@ -262,5 +299,6 @@ nsNameSpaceManager::Observe(nsISupports* aObject, const char* aTopic,
|
||||
const char16_t* aMessage)
|
||||
{
|
||||
mMathMLDisabled = mozilla::Preferences::GetBool(kPrefMathMLDisabled);
|
||||
mSVGDisabled = mozilla::Preferences::GetBool(kPrefSVGDisabled);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -66,6 +66,7 @@ public:
|
||||
|
||||
static nsNameSpaceManager* GetInstance();
|
||||
bool mMathMLDisabled;
|
||||
bool mSVGDisabled;
|
||||
|
||||
private:
|
||||
bool Init();
|
||||
|
@ -1059,6 +1059,9 @@ nsXMLContentSink::HandleEndElement(const char16_t *aName,
|
||||
(debugNameSpaceID == kNameSpaceID_MathML &&
|
||||
content->NodeInfo()->NamespaceID() == kNameSpaceID_disabled_MathML &&
|
||||
content->NodeInfo()->Equals(debugTagAtom)) ||
|
||||
(debugNameSpaceID == kNameSpaceID_SVG &&
|
||||
content->NodeInfo()->NamespaceID() == kNameSpaceID_disabled_SVG &&
|
||||
content->NodeInfo()->Equals(debugTagAtom)) ||
|
||||
isTemplateElement, "Wrong element being closed");
|
||||
#endif
|
||||
|
||||
|
@ -7,6 +7,14 @@
|
||||
with Files('**'):
|
||||
BUG_COMPONENT = ('Core', 'SVG')
|
||||
|
||||
if CONFIG['ENABLE_TESTS']:
|
||||
MOCHITEST_MANIFESTS += [
|
||||
'tests/mochitest.ini',
|
||||
]
|
||||
MOCHITEST_CHROME_MANIFESTS += [
|
||||
'tests/chrome.ini',
|
||||
]
|
||||
|
||||
EXPORTS += [
|
||||
'nsFilterInstance.h',
|
||||
'nsSVGEffects.h',
|
||||
|
6
layout/svg/tests/chrome.ini
Normal file
6
layout/svg/tests/chrome.ini
Normal file
@ -0,0 +1,6 @@
|
||||
[DEFAULT]
|
||||
|
||||
support-files =
|
||||
svg_example_test.html
|
||||
|
||||
[test_disabled_chrome.html]
|
3
layout/svg/tests/mochitest.ini
Normal file
3
layout/svg/tests/mochitest.ini
Normal file
@ -0,0 +1,3 @@
|
||||
[DEFAULT]
|
||||
|
||||
[test_disabled.html]
|
7
layout/svg/tests/svg_example_test.html
Normal file
7
layout/svg/tests/svg_example_test.html
Normal file
@ -0,0 +1,7 @@
|
||||
<svg id="layout" viewBox="0 0 120 120" version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="60" cy="60" r="50"/>
|
||||
</svg>
|
||||
|
||||
<svg id="svgel">
|
||||
</svg>
|
After Width: | Height: | Size: 158 B |
59
layout/svg/tests/test_disabled.html
Normal file
59
layout/svg/tests/test_disabled.html
Normal file
@ -0,0 +1,59 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Copied from
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=744830
|
||||
-->
|
||||
<head>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=166235">Mozilla Bug 166235</a>
|
||||
<div id="testnodes"><span>hi</span> there <!-- mon ami --></div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [["svg.disabled", true]]}, doTest);
|
||||
function doTest() {
|
||||
let t = document.getElementById('testnodes');
|
||||
t.innerHTML = null;
|
||||
t.appendChild(document.createElementNS("http://www.w3.org/2000/svg", "svg:svg"));
|
||||
t.firstChild.textContent = "<foo>";
|
||||
is(t.innerHTML, "<svg:svg><foo></svg:svg>");
|
||||
|
||||
// This test crashes if the style tags are not handled correctly
|
||||
t.innerHTML = `<svg version="1.1">
|
||||
<style>
|
||||
circle {
|
||||
fill: currentColor;
|
||||
}
|
||||
</style>
|
||||
<g><circle cx="25.8" cy="9.3" r="1.5"/></g>
|
||||
</svg>
|
||||
`;
|
||||
is(t.firstChild.tagName.toLowerCase(), 'svg');
|
||||
|
||||
t.innerHTML = null;
|
||||
t.appendChild(document.createElementNS("http://www.w3.org/2000/svg", "svg"));
|
||||
is(t.firstChild.namespaceURI, "http://www.w3.org/2000/svg");
|
||||
t.firstChild.appendChild(document.createElementNS("http://www.w3.org/2000/svg", "script"));
|
||||
is(t.firstChild.firstChild.namespaceURI, "http://www.w3.org/2000/svg");
|
||||
t.firstChild.firstChild.textContent = "1&2<3>4\xA0";
|
||||
is(t.innerHTML, '<svg><script>1&2<3>4 \u003C/script></svg>');
|
||||
|
||||
t.innerHTML = null;
|
||||
t.appendChild(document.createElementNS("http://www.w3.org/2000/svg", "svg"));
|
||||
is(t.firstChild.namespaceURI, "http://www.w3.org/2000/svg");
|
||||
t.firstChild.appendChild(document.createElementNS("http://www.w3.org/2000/svg", "style"));
|
||||
is(t.firstChild.firstChild.namespaceURI, "http://www.w3.org/2000/svg");
|
||||
t.firstChild.firstChild.textContent = "1&2<3>4\xA0";
|
||||
is(t.innerHTML, '<svg><style>1&2<3>4 \u003C/style></svg>');
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
53
layout/svg/tests/test_disabled_chrome.html
Normal file
53
layout/svg/tests/test_disabled_chrome.html
Normal file
@ -0,0 +1,53 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=744830
|
||||
-->
|
||||
<head>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=166235">Mozilla Bug 166235</a>
|
||||
<div id="testnodes"><span>hi</span> there <!-- mon ami --></div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
add_task(function* () {
|
||||
const initialPrefValue = SpecialPowers.getBoolPref("svg.disabled");
|
||||
SpecialPowers.setBoolPref("svg.disabled", true);
|
||||
const Cu = SpecialPowers.Components.utils;
|
||||
const { ContentTaskUtils } = Cu.import("resource://testing-common/ContentTaskUtils.jsm", {});
|
||||
let t = document.getElementById('testnodes');
|
||||
|
||||
let url = 'chrome://mochitests/content/chrome/layout/svg/tests/svg_example_test.html'
|
||||
const chromeIframeEl = document.createElement('iframe');
|
||||
let chromeLoadPromise = ContentTaskUtils.waitForEvent(chromeIframeEl, 'load', false);
|
||||
chromeIframeEl.src = url;
|
||||
t.appendChild(chromeIframeEl);
|
||||
|
||||
yield chromeLoadPromise;
|
||||
const chromeBR = chromeIframeEl.contentDocument.body.getBoundingClientRect();
|
||||
|
||||
url = "http://mochi.test:8888/chrome/layout/svg/tests/svg_example_test.html";
|
||||
const iframeEl = document.createElement('iframe');
|
||||
iframeEl.src = url;
|
||||
let loadPromise = ContentTaskUtils.waitForEvent(iframeEl, 'load', false);
|
||||
t.appendChild(iframeEl);
|
||||
yield loadPromise;
|
||||
|
||||
const contentBR = iframeEl.contentDocument.body.getBoundingClientRect();
|
||||
|
||||
yield new Promise(_ => setTimeout(_, 1000));
|
||||
ok(chromeBR.height > contentBR.height, "Chrome content height should be bigger than content due to layout");
|
||||
|
||||
ok(!("hasExtension" in iframeEl.contentDocument.getElementById('svgel')), 'SVG is disabled so no hasExtension support is available in content iframe');
|
||||
ok(chromeIframeEl.contentDocument.getElementById('svgel').hasExtension("http://www.w3.org/1998/Math/MathML"), 'SVG namespace support is enabled in chrome iframe');
|
||||
|
||||
SpecialPowers.setBoolPref("svg.disabled", initialPrefValue);
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -2879,6 +2879,9 @@ pref("dom.ipc.plugins.asyncdrawing.enabled", true);
|
||||
|
||||
pref("dom.ipc.processCount", 1);
|
||||
|
||||
// Disable support for SVG
|
||||
pref("svg.disabled", false);
|
||||
|
||||
// Override default dom.ipc.processCount for some remote content process types.
|
||||
pref("dom.ipc.processCount.webLargeAllocation", 2);
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "nsStyleLinkElement.h"
|
||||
#include "nsScriptLoader.h"
|
||||
#include "nsIHTMLDocument.h"
|
||||
#include "nsNameSpaceManager.h"
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(nsHtml5DocumentBuilder, nsContentSink,
|
||||
mOwnedElements)
|
||||
@ -57,6 +58,12 @@ nsHtml5DocumentBuilder::SetDocumentCharsetAndSource(nsACString& aCharset, int32_
|
||||
void
|
||||
nsHtml5DocumentBuilder::UpdateStyleSheet(nsIContent* aElement)
|
||||
{
|
||||
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(aElement));
|
||||
if (!ssle) {
|
||||
MOZ_ASSERT(nsNameSpaceManager::GetInstance()->mSVGDisabled, "Node didn't QI to style, but SVG wasn't disabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Break out of the doc update created by Flush() to zap a runnable
|
||||
// waiting to call UpdateStyleSheet without the right observer
|
||||
EndDocUpdate();
|
||||
@ -66,9 +73,6 @@ nsHtml5DocumentBuilder::UpdateStyleSheet(nsIContent* aElement)
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(aElement));
|
||||
NS_ASSERTION(ssle, "Node didn't QI to style.");
|
||||
|
||||
ssle->SetEnableUpdates(true);
|
||||
|
||||
bool willNotify;
|
||||
|
@ -824,8 +824,11 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
|
||||
case eTreeOpSetStyleLineNumber: {
|
||||
nsIContent* node = *(mOne.node);
|
||||
nsCOMPtr<nsIStyleSheetLinkingElement> ssle = do_QueryInterface(node);
|
||||
NS_ASSERTION(ssle, "Node didn't QI to style.");
|
||||
ssle->SetLineNumber(mFour.integer);
|
||||
if (ssle) {
|
||||
ssle->SetLineNumber(mFour.integer);
|
||||
} else {
|
||||
MOZ_ASSERT(nsNameSpaceManager::GetInstance()->mSVGDisabled, "Node didn't QI to style, but SVG wasn't disabled.");
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpSetScriptLineNumberAndFreeze: {
|
||||
|
@ -0,0 +1,71 @@
|
||||
"use strict";
|
||||
|
||||
do_get_profile();
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/ContextualIdentityService.jsm");
|
||||
|
||||
const TEST_STORE_FILE_NAME = "test-containers.json";
|
||||
|
||||
let cis;
|
||||
|
||||
// Basic tests
|
||||
add_task(function() {
|
||||
ok(!!ContextualIdentityService, "ContextualIdentityService exists");
|
||||
|
||||
cis = ContextualIdentityService.createNewInstanceForTesting(TEST_STORE_FILE_NAME);
|
||||
ok(!!cis, "We have our instance of ContextualIdentityService");
|
||||
|
||||
equal(cis.getIdentities().length, 4, "By default, 4 containers.");
|
||||
equal(cis.getIdentityFromId(0), null, "No identity with id 0");
|
||||
|
||||
ok(!!cis.getIdentityFromId(1), "Identity 1 exists");
|
||||
ok(!!cis.getIdentityFromId(2), "Identity 2 exists");
|
||||
ok(!!cis.getIdentityFromId(3), "Identity 3 exists");
|
||||
ok(!!cis.getIdentityFromId(4), "Identity 4 exists");
|
||||
});
|
||||
|
||||
// Create a new identity
|
||||
add_task(function() {
|
||||
equal(cis.getIdentities().length, 4, "By default, 4 containers.");
|
||||
|
||||
let identity = cis.create("New Container", "Icon", "Color");
|
||||
ok(!!identity, "New container created");
|
||||
equal(identity.name, "New Container", "Name matches");
|
||||
equal(identity.icon, "Icon", "Icon matches");
|
||||
equal(identity.color, "Color", "Color matches");
|
||||
|
||||
equal(cis.getIdentities().length, 5, "Expected 5 containers.");
|
||||
|
||||
ok(!!cis.getIdentityFromId(identity.userContextId), "Identity exists");
|
||||
equal(cis.getIdentityFromId(identity.userContextId).name, "New Container", "Identity name is OK");
|
||||
equal(cis.getIdentityFromId(identity.userContextId).icon, "Icon", "Identity icon is OK");
|
||||
equal(cis.getIdentityFromId(identity.userContextId).color, "Color", "Identity color is OK");
|
||||
equal(cis.getUserContextLabel(identity.userContextId), "New Container", "Identity label is OK");
|
||||
});
|
||||
|
||||
// Remove an identity
|
||||
add_task(function() {
|
||||
equal(cis.getIdentities().length, 5, "Expected 5 containers.");
|
||||
|
||||
equal(cis.remove(-1), false, "cis.remove() returns false if identity doesn't exist.");
|
||||
equal(cis.remove(1), true, "cis.remove() returns true if identity exists.");
|
||||
|
||||
equal(cis.getIdentities().length, 4, "Expected 4 containers.");
|
||||
});
|
||||
|
||||
// Update an identity
|
||||
add_task(function() {
|
||||
ok(!!cis.getIdentityFromId(2), "Identity 2 exists");
|
||||
|
||||
equal(cis.update(-1, "Container", "Icon", "Color"), false, "Update returns true if everything is OK");
|
||||
|
||||
equal(cis.update(2, "Container", "Icon", "Color"), true, "Update returns true if everything is OK");
|
||||
|
||||
ok(!!cis.getIdentityFromId(2), "Identity exists");
|
||||
equal(cis.getIdentityFromId(2).name, "Container", "Identity name is OK");
|
||||
equal(cis.getIdentityFromId(2).icon, "Icon", "Identity icon is OK");
|
||||
equal(cis.getIdentityFromId(2).color, "Color", "Identity color is OK");
|
||||
equal(cis.getUserContextLabel(2), "Container", "Identity label is OK");
|
||||
});
|
Loading…
Reference in New Issue
Block a user