mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-26 03:35:33 +00:00
8ad99dd7fa
It's a sub-class of nsAtom, useful for cases where you know you are dealing exclusively with static atoms. The nice thing about it is that you can use raw nsStaticAtom pointers instead of RefPtr<>. (In fact, the AddRef/Release implementations ensure that we'll crash if we use RefPtr<nsStaticAtom>.) MozReview-Commit-ID: 4Q6QHX5h44V --HG-- extra : rebase_source : e4237f85b4821b684db0ef84d1f9c5e17cdee428
240 lines
7.2 KiB
C++
240 lines
7.2 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 {
|
|
|
|
nsStaticAtom** 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, IsInChromeDoc());
|
|
}
|
|
|
|
bool
|
|
SVGTests::IsConditionalProcessingAttribute(const nsAtom* aAttribute) const
|
|
{
|
|
for (uint32_t i = 0; i < ArrayLength(sStringListNames); i++) {
|
|
if (aAttribute == *sStringListNames[i]) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int32_t
|
|
SVGTests::GetBestLanguagePreferenceRank(const nsAString& 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 nsAString& 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 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], IsInChromeDoc())) {
|
|
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
|
|
nsAutoString acceptLangs;
|
|
if (aAcceptLangs) {
|
|
acceptLangs.Assign(*aAcceptLangs);
|
|
} else {
|
|
Preferences::GetLocalizedString("intl.accept_languages", acceptLangs);
|
|
}
|
|
|
|
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(nsAtom* 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 nsAtom* aAttribute)
|
|
{
|
|
for (uint32_t i = 0; i < ArrayLength(sStringListNames); i++) {
|
|
if (aAttribute == *sStringListNames[i]) {
|
|
mStringListAttributes[i].Clear();
|
|
MaybeInvalidate();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
nsAtom*
|
|
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
|