static nsresult GetOperatingSystemVersion(nsPresContext* aPresContext, const nsMediaFeature* aFeature, nsCSSValue& aResult) { aResult.Reset(); if (ShouldResistFingerprinting(aPresContext)) { return NS_OK; } #ifdef XP_WIN int32_t metricResult; if (NS_SUCCEEDED( LookAndFeel::GetInt(LookAndFeel::eIntID_OperatingSystemVersionIdentifier, &metricResult))) { for (size_t i = 0; i < ArrayLength(osVersionStrings); ++i) { if (metricResult == osVersionStrings[i].id) { aResult.SetStringValue(nsDependentString(osVersionStrings[i].name), eCSSUnit_Ident); break; } } } #endif return NS_OK; }
bool FontFace::ParseDescriptor(nsCSSFontDesc aDescID, const nsAString& aString, nsCSSValue& aResult) { nsCSSParser parser; nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mParent); nsCOMPtr<nsIPrincipal> principal = global->PrincipalOrNull(); nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(mParent); nsCOMPtr<nsIURI> docURI = window->GetDocumentURI(); nsCOMPtr<nsIURI> base = window->GetDocBaseURI(); if (!parser.ParseFontFaceDescriptor(aDescID, aString, docURI, // aSheetURL base, principal, aResult)) { aResult.Reset(); return false; } return true; }
static nsresult GetWindowsTheme(nsPresContext* aPresContext, const nsMediaFeature* aFeature, nsCSSValue& aResult) { aResult.Reset(); if (ShouldResistFingerprinting(aPresContext)) { return NS_OK; } #ifdef XP_WIN uint8_t windowsThemeId = nsCSSRuleProcessor::GetWindowsThemeIdentifier(); // Classic mode should fail to match. if (windowsThemeId == LookAndFeel::eWindowsTheme_Classic) return NS_OK; // Look up the appropriate theme string for (size_t i = 0; i < ArrayLength(themeStrings); ++i) { if (windowsThemeId == themeStrings[i].id) { aResult.SetStringValue(nsDependentString(themeStrings[i].name), eCSSUnit_Ident); break; } } #endif return NS_OK; }
static void GetOperatingSystemVersion(nsIDocument* aDocument, const nsMediaFeature* aFeature, nsCSSValue& aResult) { aResult.Reset(); MOZ_ASSERT(aFeature->mReqFlags & nsMediaFeature::eUserAgentAndChromeOnly); if (nsContentUtils::ShouldResistFingerprinting(aDocument)) { return; } #ifdef XP_WIN int32_t metricResult; if (NS_SUCCEEDED( LookAndFeel::GetInt(LookAndFeel::eIntID_OperatingSystemVersionIdentifier, &metricResult))) { for (size_t i = 0; i < ArrayLength(osVersionStrings); ++i) { if (metricResult == osVersionStrings[i].id) { aResult.SetStringValue(nsDependentString(osVersionStrings[i].name), eCSSUnit_Ident); break; } } } #endif }
static void GetWindowsTheme(nsIDocument* aDocument, const nsMediaFeature* aFeature, nsCSSValue& aResult) { aResult.Reset(); MOZ_ASSERT(aFeature->mReqFlags & nsMediaFeature::eUserAgentAndChromeOnly); if (nsContentUtils::ShouldResistFingerprinting(aDocument)) { return; } #ifdef XP_WIN uint8_t windowsThemeId = GetWindowsThemeIdentifier(); // Classic mode should fail to match. if (windowsThemeId == LookAndFeel::eWindowsTheme_Classic) return; // Look up the appropriate theme string for (size_t i = 0; i < ArrayLength(themeStrings); ++i) { if (windowsThemeId == themeStrings[i].id) { aResult.SetStringValue(nsDependentString(themeStrings[i].name), eCSSUnit_Ident); break; } } #endif }
static void GetSystemMetric(nsIDocument* aDocument, const nsMediaFeature* aFeature, nsCSSValue& aResult) { aResult.Reset(); const bool isAccessibleFromContentPages = !(aFeature->mReqFlags & nsMediaFeature::eUserAgentAndChromeOnly); MOZ_ASSERT(!isAccessibleFromContentPages || *aFeature->mName == nsGkAtoms::_moz_touch_enabled); if (isAccessibleFromContentPages && nsContentUtils::ShouldResistFingerprinting(aDocument)) { // If "privacy.resistFingerprinting" is enabled, then we simply don't // return any system-backed media feature values. (No spoofed values // returned.) return; } MOZ_ASSERT(aFeature->mValueType == nsMediaFeature::eBoolInteger, "unexpected type"); nsAtom* metricAtom = *aFeature->mData.mMetric; bool hasMetric = HasSystemMetric(metricAtom); aResult.SetIntValue(hasMetric ? 1 : 0, eCSSUnit_Integer); }
static void GetScan(nsPresContext* aPresContext, const nsMediaFeature*, nsCSSValue& aResult) { // Since Gecko doesn't support the 'tv' media type, the 'scan' // feature is never present. aResult.Reset(); }
static void GetSystemMetric(nsPresContext* aPresContext, const nsMediaFeature* aFeature, nsCSSValue& aResult) { aResult.Reset(); if (ShouldResistFingerprinting(aPresContext)) { // If "privacy.resistFingerprinting" is enabled, then we simply don't // return any system-backed media feature values. (No spoofed values returned.) return; } MOZ_ASSERT(aFeature->mValueType == nsMediaFeature::eBoolInteger, "unexpected type"); nsIAtom *metricAtom = *aFeature->mData.mMetric; bool hasMetric = nsCSSRuleProcessor::HasSystemMetric(metricAtom); aResult.SetIntValue(hasMetric ? 1 : 0, eCSSUnit_Integer); }
// parse an input string in the following format (see bug 148326 for testcases): // [+|-] unsigned-number (% [pseudo-unit] | pseudo-unit | css-unit | namedspace) bool nsMathMLmpaddedFrame::ParseAttribute(nsString& aString, int32_t& aSign, nsCSSValue& aCSSValue, int32_t& aPseudoUnit) { aCSSValue.Reset(); aSign = NS_MATHML_SIGN_INVALID; aPseudoUnit = NS_MATHML_PSEUDO_UNIT_UNSPECIFIED; aString.CompressWhitespace(); // aString is not a const in this code int32_t stringLength = aString.Length(); if (!stringLength) return false; nsAutoString number, unit; ////////////////////// // see if the sign is there int32_t i = 0; if (aString[0] == '+') { aSign = NS_MATHML_SIGN_PLUS; i++; } else if (aString[0] == '-') { aSign = NS_MATHML_SIGN_MINUS; i++; } else aSign = NS_MATHML_SIGN_UNSPECIFIED; // get the number bool gotDot = false, gotPercent = false; for (; i < stringLength; i++) { PRUnichar c = aString[i]; if (gotDot && c == '.') { // error - two dots encountered aSign = NS_MATHML_SIGN_INVALID; return false; } if (c == '.') gotDot = true; else if (!nsCRT::IsAsciiDigit(c)) { break; } number.Append(c); } // catch error if we didn't enter the loop above... we could simply initialize // floatValue = 1, to cater for cases such as width="height", but that wouldn't // be in line with the spec which requires an explicit number if (number.IsEmpty()) { aSign = NS_MATHML_SIGN_INVALID; return false; } nsresult errorCode; float floatValue = number.ToFloat(&errorCode); if (NS_FAILED(errorCode)) { aSign = NS_MATHML_SIGN_INVALID; return false; } // see if this is a percentage-based value if (i < stringLength && aString[i] == '%') { i++; gotPercent = true; } // the remainder now should be a css-unit, or a pseudo-unit, or a named-space aString.Right(unit, stringLength - i); if (unit.IsEmpty()) { if (gotPercent) { // case ["+"|"-"] unsigned-number "%" aCSSValue.SetPercentValue(floatValue / 100.0f); aPseudoUnit = NS_MATHML_PSEUDO_UNIT_ITSELF; return true; } else { // case ["+"|"-"] unsigned-number // XXXfredw: should we allow non-zero unitless values? See bug 757703. if (!floatValue) { aCSSValue.SetFloatValue(floatValue, eCSSUnit_Number); aPseudoUnit = NS_MATHML_PSEUDO_UNIT_ITSELF; return true; } } } else if (unit.EqualsLiteral("width")) aPseudoUnit = NS_MATHML_PSEUDO_UNIT_WIDTH; else if (unit.EqualsLiteral("height")) aPseudoUnit = NS_MATHML_PSEUDO_UNIT_HEIGHT; else if (unit.EqualsLiteral("depth")) aPseudoUnit = NS_MATHML_PSEUDO_UNIT_DEPTH; else if (!gotPercent) { // percentage can only apply to a pseudo-unit // see if the unit is a named-space if (nsMathMLElement::ParseNamedSpaceValue(unit, aCSSValue, nsMathMLElement:: PARSE_ALLOW_NEGATIVE)) { // re-scale properly, and we know that the unit of the named-space is 'em' floatValue *= aCSSValue.GetFloatValue(); aCSSValue.SetFloatValue(floatValue, eCSSUnit_EM); aPseudoUnit = NS_MATHML_PSEUDO_UNIT_NAMEDSPACE; return true; } // see if the input was just a CSS value // We are not supposed to have a unitless, percent, negative or namedspace // value here. number.Append(unit); // leave the sign out if it was there if (nsMathMLElement::ParseNumericValue(number, aCSSValue, nsMathMLElement:: PARSE_SUPPRESS_WARNINGS, nullptr)) return true; } // if we enter here, we have a number that will act as a multiplier on a pseudo-unit if (aPseudoUnit != NS_MATHML_PSEUDO_UNIT_UNSPECIFIED) { if (gotPercent) aCSSValue.SetPercentValue(floatValue / 100.0f); else aCSSValue.SetFloatValue(floatValue, eCSSUnit_Number); return true; } #ifdef DEBUG printf("mpadded: attribute with bad numeric value: %s\n", NS_LossyConvertUTF16toASCII(aString).get()); #endif // if we reach here, it means we encounter an unexpected input aSign = NS_MATHML_SIGN_INVALID; return false; }
// parse an input string in the following format (see bug 148326 for testcases): // [+|-] unsigned-number (% [pseudo-unit] | pseudo-unit | css-unit | namedspace) PRBool nsMathMLmpaddedFrame::ParseAttribute(nsString& aString, PRInt32& aSign, nsCSSValue& aCSSValue, PRInt32& aPseudoUnit) { aCSSValue.Reset(); aSign = NS_MATHML_SIGN_INVALID; aPseudoUnit = NS_MATHML_PSEUDO_UNIT_UNSPECIFIED; aString.CompressWhitespace(); // aString is not a const in this code PRInt32 stringLength = aString.Length(); if (!stringLength) return PR_FALSE; nsAutoString number, unit; ////////////////////// // see if the sign is there PRInt32 i = 0; if (aString[0] == '+') { aSign = NS_MATHML_SIGN_PLUS; i++; } else if (aString[0] == '-') { aSign = NS_MATHML_SIGN_MINUS; i++; } else aSign = NS_MATHML_SIGN_UNSPECIFIED; // skip any space after the sign if (i < stringLength && nsCRT::IsAsciiSpace(aString[i])) i++; // get the number PRBool gotDot = PR_FALSE, gotPercent = PR_FALSE; for (; i < stringLength; i++) { PRUnichar c = aString[i]; if (gotDot && c == '.') { // error - two dots encountered aSign = NS_MATHML_SIGN_INVALID; return PR_FALSE; } if (c == '.') gotDot = PR_TRUE; else if (!nsCRT::IsAsciiDigit(c)) { break; } number.Append(c); } // catch error if we didn't enter the loop above... we could simply initialize // floatValue = 1, to cater for cases such as width="height", but that wouldn't // be in line with the spec which requires an explicit number if (number.IsEmpty()) { #ifdef NS_DEBUG printf("mpadded: attribute with bad numeric value: %s\n", NS_LossyConvertUTF16toASCII(aString).get()); #endif aSign = NS_MATHML_SIGN_INVALID; return PR_FALSE; } PRInt32 errorCode; float floatValue = number.ToFloat(&errorCode); if (errorCode) { aSign = NS_MATHML_SIGN_INVALID; return PR_FALSE; } // skip any space after the number if (i < stringLength && nsCRT::IsAsciiSpace(aString[i])) i++; // see if this is a percentage-based value if (i < stringLength && aString[i] == '%') { i++; gotPercent = PR_TRUE; // skip any space after the '%' sign if (i < stringLength && nsCRT::IsAsciiSpace(aString[i])) i++; } // the remainder now should be a css-unit, or a pseudo-unit, or a named-space aString.Right(unit, stringLength - i); if (unit.IsEmpty()) { // also cater for the edge case of "0" for which the unit is optional if (gotPercent || !floatValue) { aCSSValue.SetPercentValue(floatValue / 100.0f); aPseudoUnit = NS_MATHML_PSEUDO_UNIT_ITSELF; return PR_TRUE; } /* else { // no explicit CSS unit and no explicit pseudo-unit... // In this case, the MathML REC suggests taking ems for // h-unit (width, lspace) or exs for v-unit (height, depth). // Here, however, we explicitly request authors to specify // the unit. This is more in line with the CSS REC (and // it allows keeping the code simpler...) } */ } else if (unit.EqualsLiteral("width")) aPseudoUnit = NS_MATHML_PSEUDO_UNIT_WIDTH; else if (unit.EqualsLiteral("height")) aPseudoUnit = NS_MATHML_PSEUDO_UNIT_HEIGHT; else if (unit.EqualsLiteral("depth")) aPseudoUnit = NS_MATHML_PSEUDO_UNIT_DEPTH; else if (unit.EqualsLiteral("lspace")) aPseudoUnit = NS_MATHML_PSEUDO_UNIT_LSPACE; else if (!gotPercent) { // percentage can only apply to a pseudo-unit // see if the unit is a named-space // XXX nsnull in ParseNamedSpacedValue()? don't access mstyle? if (ParseNamedSpaceValue(nsnull, unit, aCSSValue)) { // re-scale properly, and we know that the unit of the named-space is 'em' floatValue *= aCSSValue.GetFloatValue(); aCSSValue.SetFloatValue(floatValue, eCSSUnit_EM); aPseudoUnit = NS_MATHML_PSEUDO_UNIT_NAMEDSPACE; return PR_TRUE; } // see if the input was just a CSS value number.Append(unit); // leave the sign out if it was there if (ParseNumericValue(number, aCSSValue)) return PR_TRUE; } // if we enter here, we have a number that will act as a multiplier on a pseudo-unit if (aPseudoUnit != NS_MATHML_PSEUDO_UNIT_UNSPECIFIED) { if (gotPercent) aCSSValue.SetPercentValue(floatValue / 100.0f); else aCSSValue.SetFloatValue(floatValue, eCSSUnit_Number); return PR_TRUE; } #ifdef NS_DEBUG printf("mpadded: attribute with bad numeric value: %s\n", NS_LossyConvertUTF16toASCII(aString).get()); #endif // if we reach here, it means we encounter an unexpected input aSign = NS_MATHML_SIGN_INVALID; return PR_FALSE; }
/* static */ PRBool nsMathMLFrame::ParseNamedSpaceValue(nsIFrame* aMathMLmstyleFrame, nsString& aString, nsCSSValue& aCSSValue) { aCSSValue.Reset(); aString.CompressWhitespace(); // aString is not a const in this code... if (!aString.Length()) return PR_FALSE; // See if it is one of the 'namedspace' (ranging 1/18em...7/18em) PRInt32 i = 0; nsIAtom* namedspaceAtom = nsnull; if (aString.EqualsLiteral("veryverythinmathspace")) { i = 1; namedspaceAtom = nsMathMLAtoms::veryverythinmathspace_; } else if (aString.EqualsLiteral("verythinmathspace")) { i = 2; namedspaceAtom = nsMathMLAtoms::verythinmathspace_; } else if (aString.EqualsLiteral("thinmathspace")) { i = 3; namedspaceAtom = nsMathMLAtoms::thinmathspace_; } else if (aString.EqualsLiteral("mediummathspace")) { i = 4; namedspaceAtom = nsMathMLAtoms::mediummathspace_; } else if (aString.EqualsLiteral("thickmathspace")) { i = 5; namedspaceAtom = nsMathMLAtoms::thickmathspace_; } else if (aString.EqualsLiteral("verythickmathspace")) { i = 6; namedspaceAtom = nsMathMLAtoms::verythickmathspace_; } else if (aString.EqualsLiteral("veryverythickmathspace")) { i = 7; namedspaceAtom = nsMathMLAtoms::veryverythickmathspace_; } if (0 != i) { if (aMathMLmstyleFrame) { // see if there is a <mstyle> that has overriden the default value // GetAttribute() will recurse all the way up into the <mstyle> hierarchy nsAutoString value; if (NS_CONTENT_ATTR_HAS_VALUE == GetAttribute(nsnull, aMathMLmstyleFrame, namedspaceAtom, value)) { if (ParseNumericValue(value, aCSSValue) && aCSSValue.IsLengthUnit()) { return PR_TRUE; } } } // fall back to the default value aCSSValue.SetFloatValue(float(i)/float(18), eCSSUnit_EM); return PR_TRUE; } return PR_FALSE; }
/* static */ PRBool nsMathMLFrame::ParseNumericValue(nsString& aString, nsCSSValue& aCSSValue) { aCSSValue.Reset(); aString.CompressWhitespace(); // aString is not a const in this code... PRInt32 stringLength = aString.Length(); if (!stringLength) return PR_FALSE; nsAutoString number, unit; // Gather up characters that make up the number PRBool gotDot = PR_FALSE; PRUnichar c; for (PRInt32 i = 0; i < stringLength; i++) { c = aString[i]; if (gotDot && c == '.') return PR_FALSE; // two dots encountered else if (c == '.') gotDot = PR_TRUE; else if (!nsCRT::IsAsciiDigit(c)) { aString.Right(unit, stringLength - i); unit.CompressWhitespace(); // some authors leave blanks before the unit break; } number.Append(c); } // on exit, also return a nicer string version of the value in case // the caller wants it (e.g., this removes whitespace before units) aString.Assign(number); aString.Append(unit); // Convert number to floating point PRInt32 errorCode; float floatValue = number.ToFloat(&errorCode); if (errorCode) return PR_FALSE; nsCSSUnit cssUnit; if (unit.IsEmpty()) { cssUnit = eCSSUnit_Number; // no explicit unit, this is a number that will act as a multiplier } else if (unit.EqualsLiteral("%")) { aCSSValue.SetPercentValue(floatValue / 100.0f); return PR_TRUE; } else if (unit.EqualsLiteral("em")) cssUnit = eCSSUnit_EM; else if (unit.EqualsLiteral("ex")) cssUnit = eCSSUnit_XHeight; else if (unit.EqualsLiteral("px")) cssUnit = eCSSUnit_Pixel; else if (unit.EqualsLiteral("in")) cssUnit = eCSSUnit_Inch; else if (unit.EqualsLiteral("cm")) cssUnit = eCSSUnit_Centimeter; else if (unit.EqualsLiteral("mm")) cssUnit = eCSSUnit_Millimeter; else if (unit.EqualsLiteral("pt")) cssUnit = eCSSUnit_Point; else if (unit.EqualsLiteral("pc")) cssUnit = eCSSUnit_Pica; else // unexpected unit return PR_FALSE; aCSSValue.SetFloatValue(floatValue, cssUnit); return PR_TRUE; }