Bug 1173199 - Create preference to disable MathML. r=heycam, r=huseby, r=smaug

If the mathml.disabled preference is true, treat <math> and other MathML
elements as generic XML elements.

This patch disables the rendering code of MathML however preserves the
namespace so to reduce the breakage.

Original patch by: Kathy Brade <brade@pearlcrescent.com>

MozReview-Commit-ID: A2f2Q2b4eqR

--HG--
extra : rebase_source : 3c8530816727c01b68a831d560bfe16e7b02bd9d
This commit is contained in:
Jonathan Kingston 2016-06-28 15:24:48 +01:00
Родитель e53dd1c5f7
Коммит 556ed99119
39 изменённых файлов: 924 добавлений и 28 удалений

Просмотреть файл

@ -1258,7 +1258,8 @@ Element::GetAttributeNS(const nsAString& aNamespaceURI,
nsAString& aReturn)
{
int32_t nsid =
nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI);
nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI,
nsContentUtils::IsChromeDoc(OwnerDoc()));
if (nsid == kNameSpaceID_Unknown) {
// Unknown namespace means no attribute.
@ -1300,7 +1301,8 @@ Element::RemoveAttributeNS(const nsAString& aNamespaceURI,
{
nsCOMPtr<nsIAtom> name = NS_Atomize(aLocalName);
int32_t nsid =
nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI);
nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI,
nsContentUtils::IsChromeDoc(OwnerDoc()));
if (nsid == kNameSpaceID_Unknown) {
// If the namespace ID is unknown, it means there can't possibly be an
@ -1377,7 +1379,8 @@ Element::HasAttributeNS(const nsAString& aNamespaceURI,
const nsAString& aLocalName) const
{
int32_t nsid =
nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI);
nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI,
nsContentUtils::IsChromeDoc(OwnerDoc()));
if (nsid == kNameSpaceID_Unknown) {
// Unknown namespace means no attr...

Просмотреть файл

@ -23,6 +23,7 @@ static const int32_t kNameSpaceID_None = 0;
#define kNameSpaceID_RDF 8
#define kNameSpaceID_XUL 9
#define kNameSpaceID_SVG 10
#define kNameSpaceID_LastBuiltin 10 // last 'built-in' namespace
#define kNameSpaceID_disabled_MathML 11
#define kNameSpaceID_LastBuiltin 11 // last 'built-in' namespace
#endif // mozilla_dom_NameSpaceConstants_h__

Просмотреть файл

@ -197,7 +197,8 @@ bool
NodeInfo::NamespaceEquals(const nsAString& aNamespaceURI) const
{
int32_t nsid =
nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI);
nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI,
nsContentUtils::IsChromeDoc(mOwnerManager->GetDocument()));
return mozilla::dom::NodeInfo::NamespaceEquals(nsid);
}

Просмотреть файл

@ -2892,7 +2892,8 @@ nsContentUtils::SplitQName(const nsIContent* aNamespaceResolver,
nameSpace);
NS_ENSURE_SUCCESS(rv, rv);
*aNamespace = NameSpaceManager()->GetNameSpaceID(nameSpace);
*aNamespace = NameSpaceManager()->GetNameSpaceID(nameSpace,
nsContentUtils::IsChromeDoc(aNamespaceResolver->OwnerDoc()));
if (*aNamespace == kNameSpaceID_Unknown)
return NS_ERROR_FAILURE;

Просмотреть файл

@ -446,7 +446,8 @@ nsDOMAttributeMap::GetAttrNodeInfo(const nsAString& aNamespaceURI,
if (!aNamespaceURI.IsEmpty()) {
nameSpaceID =
nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI);
nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI,
nsContentUtils::IsChromeDoc(mContent->OwnerDoc()));
if (nameSpaceID == kNameSpaceID_Unknown) {
return nullptr;

Просмотреть файл

@ -243,6 +243,12 @@ public:
*/
inline bool IsInHTMLDocument() const;
/**
* Returns true if in a chrome document
*/
virtual bool IsInChromeDocument();
/**
* Get the namespace that this element's tag is defined in
* @return the namespace

Просмотреть файл

@ -9,6 +9,7 @@
#include "nsIContent.h"
#include "nsIDocument.h"
#include "nsContentUtils.h"
inline bool
nsIContent::IsInHTMLDocument() const
@ -16,4 +17,10 @@ nsIContent::IsInHTMLDocument() const
return OwnerDoc()->IsHTMLDocument();
}
inline bool
nsIContent::IsInChromeDocument()
{
return nsContentUtils::IsChromeDoc(OwnerDoc());
}
#endif // nsIContentInlines_h

Просмотреть файл

@ -15,17 +15,25 @@
#include "mozilla/dom/NodeInfo.h"
#include "nsCOMArray.h"
#include "nsContentCreatorFunctions.h"
#include "nsContentUtils.h"
#include "nsGkAtoms.h"
#include "nsIDocument.h"
#include "nsString.h"
#include "mozilla/dom/NodeInfo.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/dom/XBLChildrenElement.h"
#include "mozilla/dom/Element.h"
#include "mozilla/Preferences.h"
using namespace mozilla;
using namespace mozilla::dom;
StaticAutoPtr<nsNameSpaceManager> nsNameSpaceManager::sInstance;
static const char* kPrefMathMLDisabled = "mathml.disabled";
static const char* kObservedPrefs[] = {
kPrefMathMLDisabled,
nullptr
};
StaticRefPtr<nsNameSpaceManager> nsNameSpaceManager::sInstance;
/* static */ nsNameSpaceManager*
nsNameSpaceManager::GetInstance() {
@ -49,6 +57,14 @@ bool nsNameSpaceManager::Init()
rv = AddNameSpace(dont_AddRef(uri), id); \
NS_ENSURE_SUCCESS(rv, false)
#define REGISTER_DISABLED_NAMESPACE(uri, id) \
rv = AddDisabledNameSpace(dont_AddRef(uri), id); \
NS_ENSURE_SUCCESS(rv, false)
mozilla::Preferences::AddStrongObservers(this, kObservedPrefs);
mMathMLDisabled = mozilla::Preferences::GetBool(kPrefMathMLDisabled);
// Need to be ordered according to ID.
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xmlns, kNameSpaceID_XMLNS);
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xml, kNameSpaceID_XML);
@ -60,8 +76,10 @@ bool nsNameSpaceManager::Init()
REGISTER_NAMESPACE(nsGkAtoms::nsuri_rdf, kNameSpaceID_RDF);
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xul, kNameSpaceID_XUL);
REGISTER_NAMESPACE(nsGkAtoms::nsuri_svg, kNameSpaceID_SVG);
REGISTER_DISABLED_NAMESPACE(nsGkAtoms::nsuri_mathml, kNameSpaceID_disabled_MathML);
#undef REGISTER_NAMESPACE
#undef REGISTER_DISABLED_NAMESPACE
return true;
}
@ -110,24 +128,32 @@ nsNameSpaceManager::GetNameSpaceURI(int32_t aNameSpaceID, nsAString& aURI)
}
int32_t
nsNameSpaceManager::GetNameSpaceID(const nsAString& aURI)
nsNameSpaceManager::GetNameSpaceID(const nsAString& aURI,
bool aInChromeDoc)
{
if (aURI.IsEmpty()) {
return kNameSpaceID_None; // xmlns="", see bug 75700 for details
}
nsCOMPtr<nsIAtom> atom = NS_Atomize(aURI);
return GetNameSpaceID(atom);
return GetNameSpaceID(atom, aInChromeDoc);
}
int32_t
nsNameSpaceManager::GetNameSpaceID(nsIAtom* aURI)
nsNameSpaceManager::GetNameSpaceID(nsIAtom* aURI,
bool aInChromeDoc)
{
if (aURI == nsGkAtoms::_empty) {
return kNameSpaceID_None; // xmlns="", see bug 75700 for details
}
int32_t nameSpaceID;
if (mMathMLDisabled &&
mDisabledURIToIDTable.Get(aURI, &nameSpaceID) &&
!aInChromeDoc) {
NS_POSTCONDITION(nameSpaceID >= 0, "Bogus namespace ID");
return nameSpaceID;
}
if (mURIToIDTable.Get(aURI, &nameSpaceID)) {
NS_POSTCONDITION(nameSpaceID >= 0, "Bogus namespace ID");
return nameSpaceID;
@ -153,7 +179,19 @@ NS_NewElement(Element** aResult,
}
#endif
if (ns == kNameSpaceID_MathML) {
return NS_NewMathMLElement(aResult, ni.forget());
// If the mathml.disabled pref. is true, convert all MathML nodes into
// disabled MathML nodes by swapping the namespace.
nsNameSpaceManager* nsmgr = nsNameSpaceManager::GetInstance();
if ((nsmgr && !nsmgr->mMathMLDisabled) ||
nsContentUtils::IsChromeDoc(ni->GetDocument())) {
return NS_NewMathMLElement(aResult, ni.forget());
}
RefPtr<mozilla::dom::NodeInfo> genericXMLNI =
ni->NodeInfoManager()->
GetNodeInfo(ni->NameAtom(), ni->GetPrefixAtom(),
kNameSpaceID_disabled_MathML, ni->NodeType(), ni->GetExtraName());
return NS_NewXMLElement(aResult, genericXMLNI.forget());
}
if (ns == kNameSpaceID_SVG) {
return NS_NewSVGElement(aResult, ni.forget(), aFromParser);
@ -195,3 +233,35 @@ nsresult nsNameSpaceManager::AddNameSpace(already_AddRefed<nsIAtom> aURI,
return NS_OK;
}
nsresult
nsNameSpaceManager::AddDisabledNameSpace(already_AddRefed<nsIAtom> aURI,
const int32_t aNameSpaceID)
{
nsCOMPtr<nsIAtom> uri = aURI;
if (aNameSpaceID < 0) {
// We've wrapped... Can't do anything else here; just bail.
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ASSERTION(aNameSpaceID - 1 == (int32_t) mURIArray.Length(),
"BAD! AddDisabledNameSpace not called in right order!");
mURIArray.AppendElement(uri.forget());
mDisabledURIToIDTable.Put(mURIArray.LastElement(), aNameSpaceID);
return NS_OK;
}
// nsISupports
NS_IMPL_ISUPPORTS(nsNameSpaceManager,
nsIObserver)
// nsIObserver
NS_IMETHODIMP
nsNameSpaceManager::Observe(nsISupports* aObject, const char* aTopic,
const char16_t* aMessage)
{
mMathMLDisabled = mozilla::Preferences::GetBool(kPrefMathMLDisabled);
return NS_OK;
}

Просмотреть файл

@ -10,6 +10,8 @@
#include "nsDataHashtable.h"
#include "nsHashKeys.h"
#include "nsIAtom.h"
#include "nsIDocument.h"
#include "nsIObserver.h"
#include "nsTArray.h"
#include "mozilla/StaticPtr.h"
@ -30,34 +32,42 @@ class nsAString;
*
*/
class nsNameSpaceManager final
class nsNameSpaceManager final : public nsIObserver
{
public:
~nsNameSpaceManager() {}
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
virtual nsresult RegisterNameSpace(const nsAString& aURI,
int32_t& aNameSpaceID);
nsresult RegisterNameSpace(const nsAString& aURI, int32_t& aNameSpaceID);
nsresult GetNameSpaceURI(int32_t aNameSpaceID, nsAString& aURI);
virtual nsresult GetNameSpaceURI(int32_t aNameSpaceID, nsAString& aURI);
nsIAtom* NameSpaceURIAtom(int32_t aNameSpaceID) {
MOZ_ASSERT(aNameSpaceID > 0 && (int64_t) aNameSpaceID <= (int64_t) mURIArray.Length());
return mURIArray.ElementAt(aNameSpaceID - 1); // id is index + 1
}
int32_t GetNameSpaceID(const nsAString& aURI);
int32_t GetNameSpaceID(nsIAtom* aURI);
int32_t GetNameSpaceID(const nsAString& aURI,
bool aInChromeDoc);
int32_t GetNameSpaceID(nsIAtom* aURI,
bool aInChromeDoc);
bool HasElementCreator(int32_t aNameSpaceID);
static nsNameSpaceManager* GetInstance();
bool mMathMLDisabled;
private:
bool Init();
nsresult AddNameSpace(already_AddRefed<nsIAtom> aURI, const int32_t aNameSpaceID);
nsresult AddDisabledNameSpace(already_AddRefed<nsIAtom> aURI, const int32_t aNameSpaceID);
~nsNameSpaceManager() {};
nsDataHashtable<nsISupportsHashKey, int32_t> mURIToIDTable;
nsDataHashtable<nsISupportsHashKey, int32_t> mDisabledURIToIDTable;
nsTArray<nsCOMPtr<nsIAtom>> mURIArray;
static mozilla::StaticAutoPtr<nsNameSpaceManager> sInstance;
static mozilla::StaticRefPtr<nsNameSpaceManager> sInstance;
};
#endif // nsNameSpaceManager_h___

Просмотреть файл

@ -348,6 +348,15 @@ SVGAnimationElement::IsNodeOfType(uint32_t aFlags) const
return !(aFlags & ~(eCONTENT | eANIMATION));
}
//----------------------------------------------------------------------
// SVGTests methods
bool
SVGAnimationElement::IsInChromeDoc() const
{
return nsContentUtils::IsChromeDoc(OwnerDoc());
}
//----------------------------------------------------------------------
// SVG utility methods

Просмотреть файл

@ -86,6 +86,10 @@ public:
void EndElement(ErrorResult& rv) { EndElementAt(0.f, rv); }
void EndElementAt(float offset, ErrorResult& rv);
// SVGTests
virtual bool IsInChromeDoc() const override;
protected:
// nsSVGElement overrides

Просмотреть файл

@ -31,5 +31,11 @@ SVGGraphicsElement::~SVGGraphicsElement()
{
}
bool
SVGGraphicsElement::IsInChromeDoc() const
{
return nsContentUtils::IsChromeDoc(OwnerDoc());
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -25,6 +25,8 @@ protected:
public:
// interfaces:
NS_DECL_ISUPPORTS_INHERITED
bool IsInChromeDoc() const override;
};
} // namespace dom

Просмотреть файл

@ -80,6 +80,16 @@ SVGSymbolElement::IsAttributeMapped(const nsIAtom* name) const
SVGSymbolElementBase::IsAttributeMapped(name);
}
//----------------------------------------------------------------------
// SVGTests methods
bool
SVGSymbolElement::IsInChromeDoc() const
{
return nsContentUtils::IsChromeDoc(OwnerDoc());
}
//----------------------------------------------------------------------
// nsSVGElement methods

Просмотреть файл

@ -44,6 +44,9 @@ public:
already_AddRefed<SVGAnimatedRect> ViewBox();
already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> PreserveAspectRatio();
// SVGTests
bool IsInChromeDoc() const override;
protected:
virtual nsSVGViewBox *GetViewBox() override;
virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio() override;

Просмотреть файл

@ -57,7 +57,7 @@ SVGTests::SystemLanguage()
bool
SVGTests::HasExtension(const nsAString& aExtension)
{
return nsSVGFeatures::HasExtension(aExtension);
return nsSVGFeatures::HasExtension(aExtension, IsInChromeDoc());
}
bool
@ -139,7 +139,7 @@ SVGTests::PassesConditionalProcessingTests(const nsString *aAcceptLangs) const
return false;
}
for (uint32_t i = 0; i < mStringListAttributes[EXTENSIONS].Length(); i++) {
if (!nsSVGFeatures::HasExtension(mStringListAttributes[EXTENSIONS][i])) {
if (!nsSVGFeatures::HasExtension(mStringListAttributes[EXTENSIONS][i], IsInChromeDoc())) {
return false;
}
}

Просмотреть файл

@ -95,6 +95,8 @@ public:
already_AddRefed<DOMSVGStringList> SystemLanguage();
bool HasExtension(const nsAString& aExtension);
virtual bool IsInChromeDoc() const = 0;
protected:
virtual ~SVGTests() {}

Просмотреть файл

@ -15,6 +15,7 @@
#include "nsSVGFeatures.h"
#include "nsIContent.h"
#include "nsIDocument.h"
#include "nsNameSpaceManager.h"
#include "mozilla/Preferences.h"
using namespace mozilla;
@ -42,11 +43,14 @@ nsSVGFeatures::HasFeature(nsISupports* aObject, const nsAString& aFeature)
}
/*static*/ bool
nsSVGFeatures::HasExtension(const nsAString& aExtension)
nsSVGFeatures::HasExtension(const nsAString& aExtension, const bool aIsInChrome)
{
#define SVG_SUPPORTED_EXTENSION(str) if (aExtension.EqualsLiteral(str)) return true;
SVG_SUPPORTED_EXTENSION("http://www.w3.org/1999/xhtml")
SVG_SUPPORTED_EXTENSION("http://www.w3.org/1998/Math/MathML")
nsNameSpaceManager* nameSpaceManager = nsNameSpaceManager::GetInstance();
if (aIsInChrome || !nameSpaceManager->mMathMLDisabled) {
SVG_SUPPORTED_EXTENSION("http://www.w3.org/1998/Math/MathML")
}
#undef SVG_SUPPORTED_EXTENSION
return false;

Просмотреть файл

@ -30,7 +30,7 @@ public:
* "http://www.w3.org/1999/xhtml" and "http://www.w3.org/1998/Math/MathML"
*/
static bool
HasExtension(const nsAString& aExtension);
HasExtension(const nsAString& aExtension, const bool aIsInChrome);
};
#endif // __NS_SVGFEATURES_H__

Просмотреть файл

@ -1599,7 +1599,8 @@ nsXBLPrototypeBinding::ResolveBaseBinding()
mBinding->LookupNamespaceURI(prefix, nameSpace);
if (!nameSpace.IsEmpty()) {
int32_t nameSpaceID =
nsContentUtils::NameSpaceManager()->GetNameSpaceID(nameSpace);
nsContentUtils::NameSpaceManager()->GetNameSpaceID(nameSpace,
nsContentUtils::IsChromeDoc(doc));
nsCOMPtr<nsIAtom> tagName = NS_Atomize(display);
// Check the white list

Просмотреть файл

@ -1049,6 +1049,9 @@ nsXMLContentSink::HandleEndElement(const char16_t *aName,
bool isTemplateElement = debugTagAtom == nsGkAtoms::_template &&
debugNameSpaceID == kNameSpaceID_XHTML;
NS_ASSERTION(content->NodeInfo()->Equals(debugTagAtom, debugNameSpaceID) ||
(debugNameSpaceID == kNameSpaceID_MathML &&
content->NodeInfo()->NamespaceID() == kNameSpaceID_disabled_MathML &&
content->NodeInfo()->Equals(debugTagAtom)) ||
isTemplateElement, "Wrong element being closed");
#endif

Просмотреть файл

@ -12,6 +12,9 @@ if CONFIG['ENABLE_TESTS']:
'imptests/mochitest.ini',
'tests/mochitest.ini',
]
MOCHITEST_CHROME_MANIFESTS += [
'tests/chrome.ini',
]
UNIFIED_SOURCES += [
'nsMathMLChar.cpp',

Просмотреть файл

@ -0,0 +1,6 @@
[DEFAULT]
support-files =
mathml_example_test.html
[test_disabled_chrome.html]

Просмотреть файл

@ -0,0 +1,28 @@
<math xmlns="http://www.w3.org/1998/Math/MathML">
<mstyle scriptsizemultiplier="2">
<msub>
<mtext>O</mtext>
<mtext>O</mtext>
</msub>
<msup>
<mtext>O</mtext>
<mtext>O</mtext>
</msup>
<msubsup>
<mtext>O</mtext>
<mtext>O</mtext>
<mtext>O</mtext>
</msubsup>
<mmultiscripts>
<mtext>O</mtext>
<mtext>O</mtext>
<mtext>O</mtext>
<mprescripts/>
<mtext>O</mtext>
<mtext>O</mtext>
</mmultiscripts>
</mstyle>
</math>
<svg id="svgel">
</svg>

Просмотреть файл

@ -6,6 +6,7 @@
[test_bug827713-2.html]
[test_bug827713.html]
[test_bug975681.html]
[test_disabled.html]
[test_opentype-axis-height.html]
[test_opentype-fraction.html]
[test_opentype-limits.html]

Просмотреть файл

@ -0,0 +1,47 @@
<!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": [["mathml.disabled", true]]}, doTest);
function doTest() {
let t = document.getElementById('testnodes');
t.innerHTML = null;
t.appendChild(document.createElementNS("http://www.w3.org/1998/Math/MathML", "math:math"));
t.firstChild.textContent = "<foo>";
is(t.innerHTML, "<math:math>&lt;foo&gt;</math:math>");
t.innerHTML = null;
t.appendChild(document.createElementNS("http://www.w3.org/1998/Math/MathML", "math"));
is(t.firstChild.namespaceURI, "http://www.w3.org/1998/Math/MathML");
t.firstChild.appendChild(document.createElementNS("http://www.w3.org/1998/Math/MathML", "script"));
is(t.firstChild.firstChild.namespaceURI, "http://www.w3.org/1998/Math/MathML");
t.firstChild.firstChild.textContent = "1&2<3>4\xA0";
is(t.innerHTML, '<math><script>1&amp;2&lt;3&gt;4&nbsp;\u003C/script></math>');
t.innerHTML = null;
t.appendChild(document.createElementNS("http://www.w3.org/1998/Math/MathML", "math"));
is(t.firstChild.namespaceURI, "http://www.w3.org/1998/Math/MathML");
t.firstChild.appendChild(document.createElementNS("http://www.w3.org/1998/Math/MathML", "style"));
is(t.firstChild.firstChild.namespaceURI, "http://www.w3.org/1998/Math/MathML");
t.firstChild.firstChild.textContent = "1&2<3>4\xA0";
is(t.innerHTML, '<math><style>1&amp;2&lt;3&gt;4&nbsp;\u003C/style></math>');
SimpleTest.finish();
}
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -0,0 +1,55 @@
<!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/EventUtils.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("mathml.disabled");
SpecialPowers.setBoolPref("mathml.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/mathml/tests/mathml_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/mathml/tests/mathml_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();
ok(chromeBR.height > contentBR.height, "Chrome content height should be bigger than content due to layout");
ok(!iframeEl.contentDocument.getElementById('svgel').hasExtension("http://www.w3.org/1998/Math/MathML"), 'SVG namespace support is disabled 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("mathml.disabled", initialPrefValue);
});
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -0,0 +1,129 @@
<!DOCTYPE html>
<html>
<head>
<title>scriptlevel</title>
<meta charset="utf-8"/>
</head>
<body>
<!-- Test scriptlevel on mstyle -->
<randomelement>
<mstyle scriptsizemultiplier="2">
<mtext>O</mtext>
<mstyle scriptlevel="1"><mtext>O</mtext></mstyle>
</mstyle>
</randomelement>
<!-- The mfrac element sets displaystyle to "false", or if it was already
false increments scriptlevel by 1, within numerator and denominator.
-->
<randomelement>
<mstyle scriptsizemultiplier="2">
<mstyle displaystyle="false">
<mfrac>
<mtext>O</mtext>
<mtext>O</mtext>
</mfrac>
</mstyle>
<mstyle displaystyle="true">
<mfrac>
<mtext>O</mtext>
<mtext>O</mtext>
</mfrac>
</mstyle>
</mstyle>
</randomelement>
<!-- The mroot element increments scriptlevel by 2, and sets
displaystyle to "false", within index, but leaves both attributes
unchanged within base.
The msqrt element leaves both attributes unchanged within its
argument. -->
<randomelement>
<mstyle scriptsizemultiplier="2">
<mroot>
<mtext>O</mtext>
<mtext>O</mtext>
</mroot>
<msqrt>
<mtext>O</mtext>
</msqrt>
</mstyle>
</randomelement>
<!--
The msub element [...] increments scriptlevel by 1, and sets displaystyle to
"false", within subscript, but leaves both attributes unchanged within base.
The msup element [...] increments scriptlevel by 1, and sets displaystyle to
"false", within superscript, but leaves both attributes unchanged within
base.
The msubsup element [...] increments scriptlevel by 1, and sets displaystyle
to "false", within subscript and superscript, but leaves both attributes
unchanged within base.
The mmultiscripts element increments scriptlevel by 1, and sets displaystyle
to "false", within each of its arguments except base, but leaves both
attributes unchanged within base.
-->
<randomelement>
<mstyle scriptsizemultiplier="2">
<msub>
<mtext>O</mtext>
<mtext>O</mtext>
</msub>
<msup>
<mtext>O</mtext>
<mtext>O</mtext>
</msup>
<msubsup>
<mtext>O</mtext>
<mtext>O</mtext>
<mtext>O</mtext>
</msubsup>
<mmultiscripts>
<mtext>O</mtext>
<mtext>O</mtext>
<mtext>O</mtext>
<mprescripts/>
<mtext>O</mtext>
<mtext>O</mtext>
</mmultiscripts>
</mstyle>
</randomelement>
<!--
The munder element [...] always sets displaystyle to "false" within the
underscript, but increments scriptlevel by 1 only when accentunder is
"false". Within base, it always leaves both attributes unchanged.
The mover element [...] always sets displaystyle to "false" within
overscript, but increments scriptlevel by 1 only when accent is "false".
Within base, it always leaves both attributes unchanged.
The munderover [..] always sets displaystyle to "false" within underscript
and overscript, but increments scriptlevel by 1 only when accentunder or
accent, respectively, are "false". Within base, it always leaves both
attributes unchanged.
-->
<randomelement>
<mstyle scriptsizemultiplier="2">
<munder>
<mtext>O</mtext>
<mtext>O</mtext>
</munder>
<mover>
<mtext>O</mtext>
<mtext>O</mtext>
</mover>
<munderover>
<mtext>O</mtext>
<mtext>O</mtext>
<mtext>O</mtext>
</munderover>
</mstyle>
</randomelement>
</body>
</html>

Просмотреть файл

@ -0,0 +1,133 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>scriptlevel</title>
<meta charset="utf-8"/>
<style>
h2 {
text-align:center;
}
</style>
</head>
<body>
<!-- Test scriptlevel on mstyle -->
<randomelement>
<mstyle scriptsizemultiplier="2">
<mtext>O</mtext>
<mstyle scriptlevel="1"><mtext>O</mtext></mstyle>
</mstyle>
</randomelement>
<!-- The mfrac element sets displaystyle to "false", or if it was already
false increments scriptlevel by 1, within numerator and denominator.
-->
<randomelement>
<mstyle scriptsizemultiplier="2">
<mstyle displaystyle="false">
<mfrac>
<mtext>O</mtext>
<mtext>O</mtext>
</mfrac>
</mstyle>
<mstyle displaystyle="true">
<mfrac>
<mtext>O</mtext>
<mtext>O</mtext>
</mfrac>
</mstyle>
</mstyle>
</randomelement>
<!-- The mroot element increments scriptlevel by 2, and sets
displaystyle to "false", within index, but leaves both attributes
unchanged within base.
The msqrt element leaves both attributes unchanged within its
argument. -->
<randomelement>
<mstyle scriptsizemultiplier="2">
<mroot>
<mtext>O</mtext>
<mtext>O</mtext>
</mroot>
<msqrt>
<mtext>O</mtext>
</msqrt>
</mstyle>
</randomelement>
<!--
The msub element [...] increments scriptlevel by 1, and sets displaystyle to
"false", within subscript, but leaves both attributes unchanged within base.
The msup element [...] increments scriptlevel by 1, and sets displaystyle to
"false", within superscript, but leaves both attributes unchanged within
base.
The msubsup element [...] increments scriptlevel by 1, and sets displaystyle
to "false", within subscript and superscript, but leaves both attributes
unchanged within base.
The mmultiscripts element increments scriptlevel by 1, and sets displaystyle
to "false", within each of its arguments except base, but leaves both
attributes unchanged within base.
-->
<randomelement>
<mstyle scriptsizemultiplier="2">
<msub>
<mtext>O</mtext>
<mtext>O</mtext>
</msub>
<msup>
<mtext>O</mtext>
<mtext>O</mtext>
</msup>
<msubsup>
<mtext>O</mtext>
<mtext>O</mtext>
<mtext>O</mtext>
</msubsup>
<mmultiscripts>
<mtext>O</mtext>
<mtext>O</mtext>
<mtext>O</mtext>
<mprescripts/>
<mtext>O</mtext>
<mtext>O</mtext>
</mmultiscripts>
</mstyle>
</randomelement>
<!--
The munder element [...] always sets displaystyle to "false" within the
underscript, but increments scriptlevel by 1 only when accentunder is
"false". Within base, it always leaves both attributes unchanged.
The mover element [...] always sets displaystyle to "false" within
overscript, but increments scriptlevel by 1 only when accent is "false".
Within base, it always leaves both attributes unchanged.
The munderover [..] always sets displaystyle to "false" within underscript
and overscript, but increments scriptlevel by 1 only when accentunder or
accent, respectively, are "false". Within base, it always leaves both
attributes unchanged.
-->
<randomelement>
<mstyle scriptsizemultiplier="2">
<munder>
<mtext>O</mtext>
<mtext>O</mtext>
</munder>
<mover>
<mtext>O</mtext>
<mtext>O</mtext>
</mover>
<munderover>
<mtext>O</mtext>
<mtext>O</mtext>
<mtext>O</mtext>
</munderover>
</mstyle>
</randomelement>
</body>
</html>

Просмотреть файл

@ -0,0 +1,129 @@
<!DOCTYPE html>
<html>
<head>
<title>scriptlevel</title>
<meta charset="utf-8"/>
</head>
<body>
<!-- Test scriptlevel on mstyle -->
<math>
<mstyle scriptsizemultiplier="2">
<mtext>O</mtext>
<mstyle scriptlevel="1"><mtext>O</mtext></mstyle>
</mstyle>
</math>
<!-- The mfrac element sets displaystyle to "false", or if it was already
false increments scriptlevel by 1, within numerator and denominator.
-->
<math>
<mstyle scriptsizemultiplier="2">
<mstyle displaystyle="false">
<mfrac>
<mtext>O</mtext>
<mtext>O</mtext>
</mfrac>
</mstyle>
<mstyle displaystyle="true">
<mfrac>
<mtext>O</mtext>
<mtext>O</mtext>
</mfrac>
</mstyle>
</mstyle>
</math>
<!-- The mroot element increments scriptlevel by 2, and sets
displaystyle to "false", within index, but leaves both attributes
unchanged within base.
The msqrt element leaves both attributes unchanged within its
argument. -->
<math>
<mstyle scriptsizemultiplier="2">
<mroot>
<mtext>O</mtext>
<mtext>O</mtext>
</mroot>
<msqrt>
<mtext>O</mtext>
</msqrt>
</mstyle>
</math>
<!--
The msub element [...] increments scriptlevel by 1, and sets displaystyle to
"false", within subscript, but leaves both attributes unchanged within base.
The msup element [...] increments scriptlevel by 1, and sets displaystyle to
"false", within superscript, but leaves both attributes unchanged within
base.
The msubsup element [...] increments scriptlevel by 1, and sets displaystyle
to "false", within subscript and superscript, but leaves both attributes
unchanged within base.
The mmultiscripts element increments scriptlevel by 1, and sets displaystyle
to "false", within each of its arguments except base, but leaves both
attributes unchanged within base.
-->
<math>
<mstyle scriptsizemultiplier="2">
<msub>
<mtext>O</mtext>
<mtext>O</mtext>
</msub>
<msup>
<mtext>O</mtext>
<mtext>O</mtext>
</msup>
<msubsup>
<mtext>O</mtext>
<mtext>O</mtext>
<mtext>O</mtext>
</msubsup>
<mmultiscripts>
<mtext>O</mtext>
<mtext>O</mtext>
<mtext>O</mtext>
<mprescripts/>
<mtext>O</mtext>
<mtext>O</mtext>
</mmultiscripts>
</mstyle>
</math>
<!--
The munder element [...] always sets displaystyle to "false" within the
underscript, but increments scriptlevel by 1 only when accentunder is
"false". Within base, it always leaves both attributes unchanged.
The mover element [...] always sets displaystyle to "false" within
overscript, but increments scriptlevel by 1 only when accent is "false".
Within base, it always leaves both attributes unchanged.
The munderover [..] always sets displaystyle to "false" within underscript
and overscript, but increments scriptlevel by 1 only when accentunder or
accent, respectively, are "false". Within base, it always leaves both
attributes unchanged.
-->
<math>
<mstyle scriptsizemultiplier="2">
<munder>
<mtext>O</mtext>
<mtext>O</mtext>
</munder>
<mover>
<mtext>O</mtext>
<mtext>O</mtext>
</mover>
<munderover>
<mtext>O</mtext>
<mtext>O</mtext>
<mtext>O</mtext>
</munderover>
</mstyle>
</math>
</body>
</html>

Просмотреть файл

@ -0,0 +1,133 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>scriptlevel</title>
<meta charset="utf-8"/>
<style>
h2 {
text-align:center;
}
</style>
</head>
<body>
<!-- Test scriptlevel on mstyle -->
<math xmlns="http://www.w3.org/1998/Math/MathML">
<mstyle scriptsizemultiplier="2">
<mtext>O</mtext>
<mstyle scriptlevel="1"><mtext>O</mtext></mstyle>
</mstyle>
</math>
<!-- The mfrac element sets displaystyle to "false", or if it was already
false increments scriptlevel by 1, within numerator and denominator.
-->
<math xmlns="http://www.w3.org/1998/Math/MathML">
<mstyle scriptsizemultiplier="2">
<mstyle displaystyle="false">
<mfrac>
<mtext>O</mtext>
<mtext>O</mtext>
</mfrac>
</mstyle>
<mstyle displaystyle="true">
<mfrac>
<mtext>O</mtext>
<mtext>O</mtext>
</mfrac>
</mstyle>
</mstyle>
</math>
<!-- The mroot element increments scriptlevel by 2, and sets
displaystyle to "false", within index, but leaves both attributes
unchanged within base.
The msqrt element leaves both attributes unchanged within its
argument. -->
<math xmlns="http://www.w3.org/1998/Math/MathML">
<mstyle scriptsizemultiplier="2">
<mroot>
<mtext>O</mtext>
<mtext>O</mtext>
</mroot>
<msqrt>
<mtext>O</mtext>
</msqrt>
</mstyle>
</math>
<!--
The msub element [...] increments scriptlevel by 1, and sets displaystyle to
"false", within subscript, but leaves both attributes unchanged within base.
The msup element [...] increments scriptlevel by 1, and sets displaystyle to
"false", within superscript, but leaves both attributes unchanged within
base.
The msubsup element [...] increments scriptlevel by 1, and sets displaystyle
to "false", within subscript and superscript, but leaves both attributes
unchanged within base.
The mmultiscripts element increments scriptlevel by 1, and sets displaystyle
to "false", within each of its arguments except base, but leaves both
attributes unchanged within base.
-->
<math xmlns="http://www.w3.org/1998/Math/MathML">
<mstyle scriptsizemultiplier="2">
<msub>
<mtext>O</mtext>
<mtext>O</mtext>
</msub>
<msup>
<mtext>O</mtext>
<mtext>O</mtext>
</msup>
<msubsup>
<mtext>O</mtext>
<mtext>O</mtext>
<mtext>O</mtext>
</msubsup>
<mmultiscripts>
<mtext>O</mtext>
<mtext>O</mtext>
<mtext>O</mtext>
<mprescripts/>
<mtext>O</mtext>
<mtext>O</mtext>
</mmultiscripts>
</mstyle>
</math>
<!--
The munder element [...] always sets displaystyle to "false" within the
underscript, but increments scriptlevel by 1 only when accentunder is
"false". Within base, it always leaves both attributes unchanged.
The mover element [...] always sets displaystyle to "false" within
overscript, but increments scriptlevel by 1 only when accent is "false".
Within base, it always leaves both attributes unchanged.
The munderover [..] always sets displaystyle to "false" within underscript
and overscript, but increments scriptlevel by 1 only when accentunder or
accent, respectively, are "false". Within base, it always leaves both
attributes unchanged.
-->
<math xmlns="http://www.w3.org/1998/Math/MathML">
<mstyle scriptsizemultiplier="2">
<munder>
<mtext>O</mtext>
<mtext>O</mtext>
</munder>
<mover>
<mtext>O</mtext>
<mtext>O</mtext>
</mover>
<munderover>
<mtext>O</mtext>
<mtext>O</mtext>
<mtext>O</mtext>
</munderover>
</mstyle>
</math>
</body>
</html>

Просмотреть файл

@ -11,6 +11,8 @@ fails == dir-9.html dir-9-ref.html # Bug 787215
== dir-10.html dir-10-ref.html
random-if((B2G&&browserIsRemote)||Mulet) == dir-11.html dir-11-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
== css-spacing-1.html css-spacing-1-ref.html
pref(mathml.disabled,true) == disabled-scriptlevel-1.html disabled-scriptlevel-1-ref.html
pref(mathml.disabled,true) == disabled-scriptlevel-1.xhtml disabled-scriptlevel-1-ref.xhtml
== displaystyle-1.html displaystyle-1-ref.html
== displaystyle-2.html displaystyle-2-ref.html
== displaystyle-3.html displaystyle-3-ref.html

Просмотреть файл

@ -232,7 +232,8 @@ static bool
DoMatch(Implementor* aElement, nsIAtom* aNS, nsIAtom* aName, MatchFn aMatch)
{
if (aNS) {
int32_t ns = nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNS);
int32_t ns = nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNS,
aElement->IsInChromeDocument());
NS_ENSURE_TRUE(ns != kNameSpaceID_Unknown, false);
const nsAttrValue* value = aElement->GetParsedAttr(aName, ns);
return value && aMatch(value);

Просмотреть файл

@ -7,6 +7,7 @@
#include "mozilla/ServoElementSnapshot.h"
#include "mozilla/dom/Element.h"
#include "nsIContentInlines.h"
#include "nsContentUtils.h"
namespace mozilla {
@ -18,6 +19,8 @@ ServoElementSnapshot::ServoElementSnapshot(Element* aElement)
{
mIsHTMLElementInHTMLDocument =
aElement->IsHTMLElement() && aElement->IsInHTMLDocument();
mIsInChromeDocument =
nsContentUtils::IsChromeDoc(aElement->OwnerDoc());
}
void

Просмотреть файл

@ -143,6 +143,11 @@ public:
return nullptr;
}
bool IsInChromeDocument()
{
return mIsInChromeDocument;
}
bool HasAny(Flags aFlags) { return bool(mContains & aFlags); }
private:
@ -156,6 +161,7 @@ private:
nsRestyleHint mExplicitRestyleHint;
nsChangeHint mExplicitChangeHint;
bool mIsHTMLElementInHTMLDocument;
bool mIsInChromeDocument;
};
} // namespace mozilla

Просмотреть файл

@ -280,6 +280,9 @@ pref("print.shrink-to-fit.scale-limit-percent", 20);
// Whether we should display simplify page checkbox on print preview UI
pref("print.use_simplify_page", false);
// Disable support for MathML
pref("mathml.disabled", false);
// Enable scale transform for stretchy MathML operators. See bug 414277.
pref("mathml.scale_stretchy_operators.enabled", true);

Просмотреть файл

@ -9,7 +9,16 @@
"local_changes": {
"deleted": [],
"deleted_reftests": {},
"items": {},
"items": {
"testharness": {
"html/syntax/parsing/math-parse01.html": [
{
"path": "html/syntax/parsing/math-parse01.html",
"url": "/html/syntax/parsing/math-parse01.html"
}
]
}
},
"reftest_nodes": {}
},
"reftest_nodes": {},

Просмотреть файл

@ -0,0 +1,2 @@
[math-parse01.html]
prefs: ["mathml.disabled:true"]

Просмотреть файл

@ -0,0 +1,62 @@
<!DOCTYPE html>
<html>
<head>
<title>math in html: parsing</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<h1>math in html: parsing</h1>
<div id="log" style="display:block"></div>
<div style="display:none">
<div><math id="m1"><mtext/></math></div>
<div id="d1"><math><mrow/><mi/></math></div>
<div id="d2"><math><mrow><mrow><mn>1</mn></mrow><mi>a</mi></mrow></math></div>
<div id="d3">&lang;&rang;</div>
<div id="d4">&Kopf;</div>
<div id="d5"><math><semantics><mi>a</mi><annotation-xml><foo/><bar/></annotation-xml></semantics></math></div>
<div id="d6"><math><semantics><mi>a</mi><annotation-xml encoding="text/html"><div></div></annotation-xml></semantics><mn/></math>
</div>
<script>
test(function() {
assert_equals(document.getElementById("m1"),document.getElementsByTagName("math")[0]);
},"The id attribute should be recognised on math elements");
test(function() {
assert_equals(document.getElementById("d1").firstChild.nodeName,"math")
},"The node name should be math");
test(function() {
assert_equals(document.getElementById("d1").firstChild.namespaceURI ,"http://www.w3.org/1998/Math/MathML")
},"math should be in MathML Namespace");
test(function() {
assert_equals(document.getElementById("d1").firstChild.childNodes.length ,2)
},"Math has 2 children (empty tag syntax)");
test(function() {
assert_equals(document.getElementById("d2").firstChild.childNodes.length ,1)
},"Nested mrow elements should be parsed correctly");
test(function() {
assert_equals(document.getElementById("d3").firstChild.nodeValue ,"\u27E8\u27E9")
},"Testing rang and lang entity code points");
test(function() {
assert_equals(document.getElementById("d4").firstChild.nodeValue ,"\uD835\uDD42")
},"Testing Kopf (Plane 1) entity code point");
test(function() {
assert_equals(document.getElementById("d5").firstChild.firstChild.childNodes[1].childNodes.length ,2)
},"Empty element tags in annotation-xml parsed as per XML.");
test(function() {
assert_equals(document.getElementById("d6").firstChild.childNodes.length ,2)
},"html tags allowed in annotation-xml/@encoding='text/html'.");
</script>