mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-03 18:47:53 +00:00
24979f464f
SVGTests is purely a mixin class for classes that get their nsISupports bits from someplace else. Having it implement nsISupports means that the classes which inherit from it wind up with multiple refcount members, which is a waste of space. By removing nsISupports implementation from SVGTests, we save a bit of space and potential confusion along the way.
251 lines
7.5 KiB
C++
251 lines
7.5 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* 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/dom/SVGTests.h"
|
|
#include "DOMSVGStringList.h"
|
|
#include "nsSVGFeatures.h"
|
|
#include "mozilla/dom/SVGSwitchElement.h"
|
|
#include "nsCharSeparatedTokenizer.h"
|
|
#include "nsStyleUtil.h"
|
|
#include "mozilla/Preferences.h"
|
|
|
|
namespace mozilla {
|
|
namespace dom {
|
|
|
|
nsIAtom** SVGTests::sStringListNames[3] =
|
|
{
|
|
&nsGkAtoms::requiredFeatures,
|
|
&nsGkAtoms::requiredExtensions,
|
|
&nsGkAtoms::systemLanguage,
|
|
};
|
|
|
|
SVGTests::SVGTests()
|
|
{
|
|
mStringListAttributes[LANGUAGE].SetIsCommaSeparated(true);
|
|
}
|
|
|
|
already_AddRefed<DOMSVGStringList>
|
|
SVGTests::RequiredFeatures()
|
|
{
|
|
nsCOMPtr<nsIDOMSVGElement> elem = do_QueryInterface(this);
|
|
nsSVGElement* element = static_cast<nsSVGElement*>(elem.get());
|
|
return DOMSVGStringList::GetDOMWrapper(
|
|
&mStringListAttributes[FEATURES], element, true, FEATURES);
|
|
}
|
|
|
|
already_AddRefed<DOMSVGStringList>
|
|
SVGTests::RequiredExtensions()
|
|
{
|
|
nsCOMPtr<nsIDOMSVGElement> elem = do_QueryInterface(this);
|
|
nsSVGElement* element = static_cast<nsSVGElement*>(elem.get());
|
|
return DOMSVGStringList::GetDOMWrapper(
|
|
&mStringListAttributes[EXTENSIONS], element, true, EXTENSIONS);
|
|
}
|
|
|
|
already_AddRefed<DOMSVGStringList>
|
|
SVGTests::SystemLanguage()
|
|
{
|
|
nsCOMPtr<nsIDOMSVGElement> elem = do_QueryInterface(this);
|
|
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);
|
|
}
|
|
|
|
bool
|
|
SVGTests::IsConditionalProcessingAttribute(const nsIAtom* aAttribute) const
|
|
{
|
|
for (uint32_t i = 0; i < ArrayLength(sStringListNames); i++) {
|
|
if (aAttribute == *sStringListNames[i]) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int32_t
|
|
SVGTests::GetBestLanguagePreferenceRank(const nsSubstring& aAcceptLangs) const
|
|
{
|
|
const nsDefaultStringComparator defaultComparator;
|
|
|
|
if (!mStringListAttributes[LANGUAGE].IsExplicitlySet()) {
|
|
return -2;
|
|
}
|
|
|
|
int32_t lowestRank = -1;
|
|
|
|
for (uint32_t i = 0; i < mStringListAttributes[LANGUAGE].Length(); i++) {
|
|
nsCharSeparatedTokenizer languageTokenizer(aAcceptLangs, ',');
|
|
int32_t index = 0;
|
|
while (languageTokenizer.hasMoreTokens()) {
|
|
const nsSubstring &languageToken = languageTokenizer.nextToken();
|
|
bool exactMatch = (languageToken == mStringListAttributes[LANGUAGE][i]);
|
|
bool prefixOnlyMatch =
|
|
!exactMatch &&
|
|
nsStyleUtil::DashMatchCompare(mStringListAttributes[LANGUAGE][i],
|
|
languageTokenizer.nextToken(),
|
|
defaultComparator);
|
|
if (index == 0 && exactMatch) {
|
|
// best possible match
|
|
return 0;
|
|
}
|
|
if ((exactMatch || prefixOnlyMatch) &&
|
|
(lowestRank == -1 || 2 * index + prefixOnlyMatch < lowestRank)) {
|
|
lowestRank = 2 * index + prefixOnlyMatch;
|
|
}
|
|
++index;
|
|
}
|
|
}
|
|
return lowestRank;
|
|
}
|
|
|
|
const nsString * const SVGTests::kIgnoreSystemLanguage = (nsString *) 0x01;
|
|
|
|
bool
|
|
SVGTests::PassesConditionalProcessingTests(const nsString *aAcceptLangs) const
|
|
{
|
|
// Required Features
|
|
if (mStringListAttributes[FEATURES].IsExplicitlySet()) {
|
|
if (mStringListAttributes[FEATURES].IsEmpty()) {
|
|
return false;
|
|
}
|
|
nsCOMPtr<nsIContent> content(
|
|
do_QueryInterface(const_cast<SVGTests*>(this)));
|
|
|
|
for (uint32_t i = 0; i < mStringListAttributes[FEATURES].Length(); i++) {
|
|
if (!nsSVGFeatures::HasFeature(content, mStringListAttributes[FEATURES][i])) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Required Extensions
|
|
//
|
|
// The requiredExtensions attribute defines a list of required language
|
|
// extensions. Language extensions are capabilities within a user agent that
|
|
// 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])) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (aAcceptLangs == kIgnoreSystemLanguage) {
|
|
return true;
|
|
}
|
|
|
|
// systemLanguage
|
|
//
|
|
// Evaluates to "true" if one of the languages indicated by user preferences
|
|
// exactly equals one of the languages given in the value of this parameter,
|
|
// or if one of the languages indicated by user preferences exactly equals a
|
|
// prefix of one of the languages given in the value of this parameter such
|
|
// that the first tag character following the prefix is "-".
|
|
if (mStringListAttributes[LANGUAGE].IsExplicitlySet()) {
|
|
if (mStringListAttributes[LANGUAGE].IsEmpty()) {
|
|
return false;
|
|
}
|
|
|
|
// Get our language preferences
|
|
const nsAutoString acceptLangs(aAcceptLangs ? *aAcceptLangs :
|
|
Preferences::GetLocalizedString("intl.accept_languages"));
|
|
|
|
if (acceptLangs.IsEmpty()) {
|
|
NS_WARNING("no default language specified for systemLanguage conditional test");
|
|
return false;
|
|
}
|
|
|
|
const nsDefaultStringComparator defaultComparator;
|
|
|
|
for (uint32_t i = 0; i < mStringListAttributes[LANGUAGE].Length(); i++) {
|
|
nsCharSeparatedTokenizer languageTokenizer(acceptLangs, ',');
|
|
while (languageTokenizer.hasMoreTokens()) {
|
|
if (nsStyleUtil::DashMatchCompare(mStringListAttributes[LANGUAGE][i],
|
|
languageTokenizer.nextToken(),
|
|
defaultComparator)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
SVGTests::ParseConditionalProcessingAttribute(nsIAtom* aAttribute,
|
|
const nsAString& aValue,
|
|
nsAttrValue& aResult)
|
|
{
|
|
for (uint32_t i = 0; i < ArrayLength(sStringListNames); i++) {
|
|
if (aAttribute == *sStringListNames[i]) {
|
|
nsresult rv = mStringListAttributes[i].SetValue(aValue);
|
|
if (NS_FAILED(rv)) {
|
|
mStringListAttributes[i].Clear();
|
|
}
|
|
MaybeInvalidate();
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void
|
|
SVGTests::UnsetAttr(const nsIAtom* aAttribute)
|
|
{
|
|
for (uint32_t i = 0; i < ArrayLength(sStringListNames); i++) {
|
|
if (aAttribute == *sStringListNames[i]) {
|
|
mStringListAttributes[i].Clear();
|
|
MaybeInvalidate();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
nsIAtom*
|
|
SVGTests::GetAttrName(uint8_t aAttrEnum) const
|
|
{
|
|
return *sStringListNames[aAttrEnum];
|
|
}
|
|
|
|
void
|
|
SVGTests::GetAttrValue(uint8_t aAttrEnum, nsAttrValue& aValue) const
|
|
{
|
|
MOZ_ASSERT(aAttrEnum < ArrayLength(sStringListNames),
|
|
"aAttrEnum out of range");
|
|
aValue.SetTo(mStringListAttributes[aAttrEnum], nullptr);
|
|
}
|
|
|
|
void
|
|
SVGTests::MaybeInvalidate()
|
|
{
|
|
nsCOMPtr<nsIDOMSVGElement> elem = do_QueryInterface(this);
|
|
nsSVGElement* element = static_cast<nsSVGElement*>(elem.get());
|
|
|
|
nsIContent* parent = element->GetFlattenedTreeParent();
|
|
|
|
if (parent &&
|
|
parent->NodeInfo()->Equals(nsGkAtoms::svgSwitch, kNameSpaceID_SVG)) {
|
|
static_cast<dom::SVGSwitchElement*>(parent)->MaybeInvalidate();
|
|
}
|
|
}
|
|
|
|
} // namespace dom
|
|
} // namespace mozilla
|