--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -1253,17 +1253,18 @@ Element::RemoveAttributeNode(Attr& aAttr
}
void
Element::GetAttributeNS(const nsAString& aNamespaceURI,
const nsAString& aLocalName,
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.
SetDOMStringToNull(aReturn);
return;
}
nsCOMPtr<nsIAtom> name = NS_Atomize(aLocalName);
@@ -1295,17 +1296,18 @@ Element::SetAttributeNS(const nsAString&
void
Element::RemoveAttributeNS(const nsAString& aNamespaceURI,
const nsAString& aLocalName,
ErrorResult& aError)
{
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
// existing attribute. We would need a known namespace ID to pass into
// UnsetAttr, so we return early if we don't have one.
return;
}
@@ -1372,17 +1374,18 @@ Element::GetElementsByTagNameNS(const ns
return NS_OK;
}
bool
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...
return false;
}
nsCOMPtr<nsIAtom> name = NS_Atomize(aLocalName);
return HasAttr(nsid, name);
--- a/dom/base/NameSpaceConstants.h
+++ b/dom/base/NameSpaceConstants.h
@@ -18,11 +18,12 @@ static const int32_t kNameSpaceID_None =
#define kNameSpaceID_XHTML 3
#define kNameSpaceID_XLink 4
#define kNameSpaceID_XSLT 5
#define kNameSpaceID_XBL 6
#define kNameSpaceID_MathML 7
#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__
--- a/dom/base/NodeInfo.cpp
+++ b/dom/base/NodeInfo.cpp
@@ -192,17 +192,18 @@ NodeInfo::GetNamespaceURI(nsAString& aNa
SetDOMStringToNull(aNameSpaceURI);
}
}
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);
}
void
NodeInfo::DeleteCycleCollectable()
{
RefPtr<nsNodeInfoManager> kungFuDeathGrip = mOwnerManager;
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -2887,17 +2887,18 @@ nsContentUtils::SplitQName(const nsICont
const char16_t* end;
aQName.EndReading(end);
nsAutoString nameSpace;
rv = aNamespaceResolver->LookupNamespaceURIInternal(Substring(aQName.get(),
colon),
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;
*aLocalName = NS_Atomize(Substring(colon + 1, end)).take();
}
else {
*aNamespace = kNameSpaceID_None;
*aLocalName = NS_Atomize(aQName).take();
--- a/dom/base/nsDOMAttributeMap.cpp
+++ b/dom/base/nsDOMAttributeMap.cpp
@@ -441,17 +441,18 @@ nsDOMAttributeMap::GetAttrNodeInfo(const
if (!mContent) {
return nullptr;
}
int32_t nameSpaceID = kNameSpaceID_None;
if (!aNamespaceURI.IsEmpty()) {
nameSpaceID =
- nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI);
+ nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI,
+ nsContentUtils::IsChromeDoc(mContent->OwnerDoc()));
if (nameSpaceID == kNameSpaceID_Unknown) {
return nullptr;
}
}
uint32_t i, count = mContent->GetAttrCount();
for (i = 0; i < count; ++i) {
--- a/dom/base/nsIContent.h
+++ b/dom/base/nsIContent.h
@@ -238,16 +238,22 @@ public:
}
/**
* Return true iff this node is in an HTML document (in the HTML5 sense of
* the term, i.e. not in an XHTML/XML document).
*/
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
*/
inline int32_t GetNameSpaceID() const
{
return mNodeInfo->NamespaceID();
}
--- a/dom/base/nsIContentInlines.h
+++ b/dom/base/nsIContentInlines.h
@@ -4,16 +4,23 @@
* 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 nsIContentInlines_h
#define nsIContentInlines_h
#include "nsIContent.h"
#include "nsIDocument.h"
+#include "nsContentUtils.h"
inline bool
nsIContent::IsInHTMLDocument() const
{
return OwnerDoc()->IsHTMLDocument();
}
+inline bool
+nsIContent::IsInChromeDocument()
+{
+ return nsContentUtils::IsChromeDoc(OwnerDoc());
+}
+
#endif // nsIContentInlines_h
--- a/dom/base/nsNameSpaceManager.cpp
+++ b/dom/base/nsNameSpaceManager.cpp
@@ -10,27 +10,35 @@
*/
#include "nsNameSpaceManager.h"
#include "nscore.h"
#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() {
if (!sInstance) {
sInstance = new nsNameSpaceManager();
if (sInstance->Init()) {
ClearOnShutdown(&sInstance);
} else {
@@ -44,29 +52,39 @@ nsNameSpaceManager::GetInstance() {
bool nsNameSpaceManager::Init()
{
nsresult rv;
#define REGISTER_NAMESPACE(uri, id) \
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);
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xhtml, kNameSpaceID_XHTML);
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xlink, kNameSpaceID_XLink);
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xslt, kNameSpaceID_XSLT);
REGISTER_NAMESPACE(nsGkAtoms::nsuri_xbl, kNameSpaceID_XBL);
REGISTER_NAMESPACE(nsGkAtoms::nsuri_mathml, kNameSpaceID_MathML);
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;
}
nsresult
nsNameSpaceManager::RegisterNameSpace(const nsAString& aURI,
int32_t& aNameSpaceID)
{
@@ -105,34 +123,42 @@ nsNameSpaceManager::GetNameSpaceURI(int3
}
mURIArray.ElementAt(index)->ToString(aURI);
return NS_OK;
}
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;
}
return kNameSpaceID_Unknown;
}
@@ -148,17 +174,29 @@ NS_NewElement(Element** aResult,
return NS_NewHTMLElement(aResult, ni.forget(), aFromParser, aIs);
}
#ifdef MOZ_XUL
if (ns == kNameSpaceID_XUL) {
return NS_NewXULElement(aResult, ni.forget());
}
#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);
}
if (ns == kNameSpaceID_XBL && ni->Equals(nsGkAtoms::children)) {
NS_ADDREF(*aResult = new XBLChildrenElement(ni.forget()));
return NS_OK;
}
@@ -190,8 +228,40 @@ nsresult nsNameSpaceManager::AddNameSpac
NS_ASSERTION(aNameSpaceID - 1 == (int32_t) mURIArray.Length(),
"BAD! AddNameSpace not called in right order!");
mURIArray.AppendElement(uri.forget());
mURIToIDTable.Put(mURIArray.LastElement(), aNameSpaceID);
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;
+}
--- a/dom/base/nsNameSpaceManager.h
+++ b/dom/base/nsNameSpaceManager.h
@@ -5,16 +5,18 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsNameSpaceManager_h___
#define nsNameSpaceManager_h___
#include "nsDataHashtable.h"
#include "nsHashKeys.h"
#include "nsIAtom.h"
+#include "nsIDocument.h"
+#include "nsIObserver.h"
#include "nsTArray.h"
#include "mozilla/StaticPtr.h"
class nsAString;
/**
* The Name Space Manager tracks the association between a NameSpace
@@ -25,39 +27,47 @@ class nsAString;
* consistent accross the app. NameSpace IDs are only consistent at runtime
* ie: they are not guaranteed to be consistent accross app sessions.
*
* The nsNameSpaceManager needs to have a live reference for as long as
* the NameSpace IDs are needed.
*
*/
-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___
--- a/dom/svg/SVGAnimationElement.cpp
+++ b/dom/svg/SVGAnimationElement.cpp
@@ -344,16 +344,25 @@ SVGAnimationElement::UnsetAttr(int32_t a
bool
SVGAnimationElement::IsNodeOfType(uint32_t aFlags) const
{
return !(aFlags & ~(eCONTENT | eANIMATION));
}
//----------------------------------------------------------------------
+// SVGTests methods
+
+bool
+SVGAnimationElement::IsInChromeDoc() const
+{
+ return nsContentUtils::IsChromeDoc(OwnerDoc());
+}
+
+//----------------------------------------------------------------------
// SVG utility methods
void
SVGAnimationElement::ActivateByHyperlink()
{
FlushAnimations();
// The behavior for when the target is an animation element is defined in
--- a/dom/svg/SVGAnimationElement.h
+++ b/dom/svg/SVGAnimationElement.h
@@ -81,16 +81,20 @@ public:
float GetStartTime(ErrorResult& rv);
float GetCurrentTime();
float GetSimpleDuration(ErrorResult& rv);
void BeginElement(ErrorResult& rv) { BeginElementAt(0.f, rv); }
void BeginElementAt(float offset, ErrorResult& rv);
void EndElement(ErrorResult& rv) { EndElementAt(0.f, rv); }
void EndElementAt(float offset, ErrorResult& rv);
+ // SVGTests
+ virtual bool IsInChromeDoc() const override;
+
+
protected:
// nsSVGElement overrides
void UpdateHrefTarget(nsIContent* aNodeForContext,
const nsAString& aHrefStr);
void AnimationTargetChanged();
class TargetReference : public nsReferencedElement {
--- a/dom/svg/SVGGraphicsElement.cpp
+++ b/dom/svg/SVGGraphicsElement.cpp
@@ -26,10 +26,16 @@ SVGGraphicsElement::SVGGraphicsElement(a
: SVGGraphicsElementBase(aNodeInfo)
{
}
SVGGraphicsElement::~SVGGraphicsElement()
{
}
+bool
+SVGGraphicsElement::IsInChromeDoc() const
+{
+ return nsContentUtils::IsChromeDoc(OwnerDoc());
+}
+
} // namespace dom
} // namespace mozilla
--- a/dom/svg/SVGGraphicsElement.h
+++ b/dom/svg/SVGGraphicsElement.h
@@ -20,14 +20,16 @@ class SVGGraphicsElement : public SVGGra
{
protected:
explicit SVGGraphicsElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
~SVGGraphicsElement();
public:
// interfaces:
NS_DECL_ISUPPORTS_INHERITED
+
+ bool IsInChromeDoc() const override;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_SVGGraphicsElement_h
--- a/dom/svg/SVGSymbolElement.cpp
+++ b/dom/svg/SVGSymbolElement.cpp
@@ -76,16 +76,26 @@ SVGSymbolElement::IsAttributeMapped(cons
sViewportsMap
};
return FindAttributeDependence(name, map) ||
SVGSymbolElementBase::IsAttributeMapped(name);
}
//----------------------------------------------------------------------
+// SVGTests methods
+
+bool
+SVGSymbolElement::IsInChromeDoc() const
+{
+ return nsContentUtils::IsChromeDoc(OwnerDoc());
+}
+
+
+//----------------------------------------------------------------------
// nsSVGElement methods
nsSVGViewBox *
SVGSymbolElement::GetViewBox()
{
return &mViewBox;
}
--- a/dom/svg/SVGSymbolElement.h
+++ b/dom/svg/SVGSymbolElement.h
@@ -39,16 +39,19 @@ public:
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const override;
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;
// WebIDL
already_AddRefed<SVGAnimatedRect> ViewBox();
already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> PreserveAspectRatio();
+ // SVGTests
+ bool IsInChromeDoc() const override;
+
protected:
virtual nsSVGViewBox *GetViewBox() override;
virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio() override;
nsSVGViewBox mViewBox;
SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
};
--- a/dom/svg/SVGTests.cpp
+++ b/dom/svg/SVGTests.cpp
@@ -52,17 +52,17 @@ SVGTests::SystemLanguage()
nsSVGElement* element = static_cast<nsSVGElement*>(elem.get());
return DOMSVGStringList::GetDOMWrapper(
&mStringListAttributes[LANGUAGE], element, true, LANGUAGE);
}
bool
SVGTests::HasExtension(const nsAString& aExtension)
{
- return nsSVGFeatures::HasExtension(aExtension);
+ return nsSVGFeatures::HasExtension(aExtension, IsInChromeDoc());
}
bool
SVGTests::IsConditionalProcessingAttribute(const nsIAtom* aAttribute) const
{
for (uint32_t i = 0; i < ArrayLength(sStringListNames); i++) {
if (aAttribute == *sStringListNames[i]) {
return true;
@@ -134,17 +134,17 @@ SVGTests::PassesConditionalProcessingTes
// go beyond the feature set defined in the SVG specification.
// Each extension is identified by a URI reference.
// For now, claim that mozilla's SVG implementation supports XHTML and MathML.
if (mStringListAttributes[EXTENSIONS].IsExplicitlySet()) {
if (mStringListAttributes[EXTENSIONS].IsEmpty()) {
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;
}
}
}
if (aAcceptLangs == kIgnoreSystemLanguage) {
return true;
}
--- a/dom/svg/SVGTests.h
+++ b/dom/svg/SVGTests.h
@@ -90,16 +90,18 @@ public:
void MaybeInvalidate();
// WebIDL
already_AddRefed<DOMSVGStringList> RequiredFeatures();
already_AddRefed<DOMSVGStringList> RequiredExtensions();
already_AddRefed<DOMSVGStringList> SystemLanguage();
bool HasExtension(const nsAString& aExtension);
+ virtual bool IsInChromeDoc() const = 0;
+
protected:
virtual ~SVGTests() {}
private:
enum { FEATURES, EXTENSIONS, LANGUAGE };
SVGStringList mStringListAttributes[3];
static nsIAtom** sStringListNames[3];
};
--- a/dom/svg/nsSVGFeatures.cpp
+++ b/dom/svg/nsSVGFeatures.cpp
@@ -10,16 +10,17 @@
* requiredFeatures, requiredExtensions and systemLanguage attributes).
*
* http://www.w3.org/TR/SVG11/struct.html#ConditionalProcessing
*/
#include "nsSVGFeatures.h"
#include "nsIContent.h"
#include "nsIDocument.h"
+#include "nsNameSpaceManager.h"
#include "mozilla/Preferences.h"
using namespace mozilla;
/*static*/ bool
nsSVGFeatures::HasFeature(nsISupports* aObject, const nsAString& aFeature)
{
if (aFeature.EqualsLiteral("http://www.w3.org/TR/SVG11/feature#Script")) {
@@ -37,17 +38,20 @@ nsSVGFeatures::HasFeature(nsISupports* a
#define SVG_UNSUPPORTED_FEATURE(str)
#include "nsSVGFeaturesList.h"
#undef SVG_SUPPORTED_FEATURE
#undef SVG_UNSUPPORTED_FEATURE
return false;
}
/*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;
}
--- a/dom/svg/nsSVGFeatures.h
+++ b/dom/svg/nsSVGFeatures.h
@@ -25,12 +25,12 @@ public:
/**
* Check whether we support the given extension string.
*
* @param aExtension the URI of an extension. Known extensions are
* "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__
--- a/dom/xbl/nsXBLPrototypeBinding.cpp
+++ b/dom/xbl/nsXBLPrototypeBinding.cpp
@@ -1594,17 +1594,18 @@ nsXBLPrototypeBinding::ResolveBaseBindin
}
nsAutoString nameSpace;
if (!prefix.IsEmpty()) {
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
if (!CheckTagNameWhiteList(nameSpaceID, tagName)) {
const char16_t* params[] = { display.get() };
nsContentUtils::ReportToConsole(nsIScriptError::errorFlag,
NS_LITERAL_CSTRING("XBL"), nullptr,
nsContentUtils::eXBL_PROPERTIES,
--- a/dom/xml/nsXMLContentSink.cpp
+++ b/dom/xml/nsXMLContentSink.cpp
@@ -1044,16 +1044,19 @@ nsXMLContentSink::HandleEndElement(const
getter_AddRefs(debugTagAtom),
&debugNameSpaceID);
// Check if we are closing a template element because template
// elements do not get pushed on the stack, the template
// element content is pushed instead.
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
result = CloseElement(content);
if (mCurrentHead == content) {
mCurrentHead = nullptr;
}
--- a/layout/mathml/moz.build
+++ b/layout/mathml/moz.build
@@ -7,16 +7,19 @@
with Files('**'):
BUG_COMPONENT = ('Core', 'MathML')
if CONFIG['ENABLE_TESTS']:
MOCHITEST_MANIFESTS += [
'imptests/mochitest.ini',
'tests/mochitest.ini',
]
+ MOCHITEST_CHROME_MANIFESTS += [
+ 'tests/chrome.ini',
+]
UNIFIED_SOURCES += [
'nsMathMLChar.cpp',
'nsMathMLContainerFrame.cpp',
'nsMathMLFrame.cpp',
'nsMathMLmactionFrame.cpp',
'nsMathMLmencloseFrame.cpp',
'nsMathMLmfencedFrame.cpp',
new file mode 100644
--- /dev/null
+++ b/layout/mathml/tests/chrome.ini
@@ -0,0 +1,6 @@
+[DEFAULT]
+
+support-files =
+ mathml_example_test.html
+
+[test_disabled_chrome.html]
new file mode 100644
--- /dev/null
+++ b/layout/mathml/tests/mathml_example_test.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>
--- a/layout/mathml/tests/mochitest.ini
+++ b/layout/mathml/tests/mochitest.ini
@@ -1,16 +1,17 @@
[DEFAULT]
[test_bug330964.html]
[test_bug553917.html]
[test_bug706406.html]
[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]
skip-if = os == "win" # Fails on WinXP
[test_opentype-radical.html]
skip-if = os == "win" # Fails on WinXP
[test_opentype-scripts.html]
[test_opentype-stack.html]
new file mode 100644
--- /dev/null
+++ b/layout/mathml/tests/test_disabled.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><foo></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&2<3>4 \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&2<3>4 \u003C/style></math>');
+
+ SimpleTest.finish();
+ }
+</script>
+</pre>
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/layout/mathml/tests/test_disabled_chrome.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>
+
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/disabled-scriptlevel-1-ref.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>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/disabled-scriptlevel-1-ref.xhtml
@@ -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>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/disabled-scriptlevel-1.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>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/mathml/disabled-scriptlevel-1.xhtml
@@ -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>
--- a/layout/reftests/mathml/reftest.list
+++ b/layout/reftests/mathml/reftest.list
@@ -6,16 +6,18 @@
== dir-6.html dir-6-ref.html
== dir-6a.html dir-6a-ref.html
== dir-7.html dir-7-ref.html
fails == dir-8.html dir-8-ref.html
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
random-if((B2G&&browserIsRemote)||Mulet) == displaystyle-4.html displaystyle-4-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
skip-if((B2G&&browserIsRemote)||Mulet) random-if(smallScreen&&Android) fuzzy(255,200) == mirror-op-1.html mirror-op-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
!= mirror-op-2.html mirror-op-2-ref.html
!= mirror-op-3.html mirror-op-3-ref.html
!= mirror-op-4.html mirror-op-4-ref.html
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -227,17 +227,18 @@ AtomAttrValue(Implementor* aElement, nsI
return attr ? attr->GetAtomValue() : nullptr;
}
template <typename Implementor, typename MatchFn>
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);
}
// No namespace means any namespace - we have to check them all. :-(
BorrowedAttrInfo attrInfo;
for (uint32_t i = 0; (attrInfo = aElement->GetAttrInfoAt(i)); ++i) {
if (attrInfo.mName->LocalName() != aName) {
--- a/layout/style/ServoElementSnapshot.cpp
+++ b/layout/style/ServoElementSnapshot.cpp
@@ -2,27 +2,30 @@
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/ServoElementSnapshot.h"
#include "mozilla/dom/Element.h"
#include "nsIContentInlines.h"
+#include "nsContentUtils.h"
namespace mozilla {
ServoElementSnapshot::ServoElementSnapshot(Element* aElement)
: mContains(Flags(0))
, mState(0)
, mExplicitRestyleHint(nsRestyleHint(0))
, mExplicitChangeHint(nsChangeHint(0))
{
mIsHTMLElementInHTMLDocument =
aElement->IsHTMLElement() && aElement->IsInHTMLDocument();
+ mIsInChromeDocument =
+ nsContentUtils::IsChromeDoc(aElement->OwnerDoc());
}
void
ServoElementSnapshot::AddAttrs(Element* aElement)
{
MOZ_ASSERT(aElement);
if (!HasAny(Flags::Attributes)) {
--- a/layout/style/ServoElementSnapshot.h
+++ b/layout/style/ServoElementSnapshot.h
@@ -138,26 +138,32 @@ public:
if (mAttrs[i].mName.Equals(aLocalName, aNamespaceID)) {
return &mAttrs[i].mValue;
}
}
return nullptr;
}
+ bool IsInChromeDocument()
+ {
+ return mIsInChromeDocument;
+ }
+
bool HasAny(Flags aFlags) { return bool(mContains & aFlags); }
private:
// TODO: Profile, a 1 or 2 element AutoTArray could be worth it, given we know
// we're dealing with attribute changes when we take snapshots of attributes,
// though it can be wasted space if we deal with a lot of state-only
// snapshots.
Flags mContains;
nsTArray<ServoAttrSnapshot> mAttrs;
ServoStateType mState;
nsRestyleHint mExplicitRestyleHint;
nsChangeHint mExplicitChangeHint;
bool mIsHTMLElementInHTMLDocument;
+ bool mIsInChromeDocument;
};
} // namespace mozilla
#endif
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -275,16 +275,19 @@ pref("browser.chrome.image_icons.max_siz
pref("browser.triple_click_selects_paragraph", true);
// Print/Preview Shrink-To-Fit won't shrink below 20% for text-ish documents.
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);
// Media cache size in kilobytes
pref("media.cache_size", 512000);
// When a network connection is suspended, don't resume it until the
// amount of buffered data falls below this threshold (in seconds).
pref("media.cache_resume_threshold", 999999);
--- a/testing/web-platform/mozilla/meta/MANIFEST.json
+++ b/testing/web-platform/mozilla/meta/MANIFEST.json
@@ -4,16 +4,25 @@
"reftest": [],
"stub": [],
"testharness": [],
"wdspec": []
},
"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": {},
"rev": null,
"url_base": "/_mozilla/",
"version": 3
}
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/mozilla/meta/html/syntax/parsing/math-parse01.html.ini
@@ -0,0 +1,2 @@
+[math-parse01.html]
+ prefs: ["mathml.disabled:true"]
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/html/syntax/parsing/math-parse01.html
@@ -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">⟨⟩</div>
+<div id="d4">𝕂</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>