123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785 |
- /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* 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 "nsStyleUtil.h"
- #include "nsStyleConsts.h"
- #include "nsIContent.h"
- #include "nsCSSProps.h"
- #include "nsContentUtils.h"
- #include "nsRuleNode.h"
- #include "nsROCSSPrimitiveValue.h"
- #include "nsStyleStruct.h"
- #include "nsIContentPolicy.h"
- #include "nsIContentSecurityPolicy.h"
- #include "nsIURI.h"
- #include "nsPrintfCString.h"
- using namespace mozilla;
- //------------------------------------------------------------------------------
- // Font Algorithm Code
- //------------------------------------------------------------------------------
- // Compare two language strings
- bool nsStyleUtil::DashMatchCompare(const nsAString& aAttributeValue,
- const nsAString& aSelectorValue,
- const nsStringComparator& aComparator)
- {
- bool result;
- uint32_t selectorLen = aSelectorValue.Length();
- uint32_t attributeLen = aAttributeValue.Length();
- if (selectorLen > attributeLen) {
- result = false;
- }
- else {
- nsAString::const_iterator iter;
- if (selectorLen != attributeLen &&
- *aAttributeValue.BeginReading(iter).advance(selectorLen) !=
- char16_t('-')) {
- // to match, the aAttributeValue must have a dash after the end of
- // the aSelectorValue's text (unless the aSelectorValue and the
- // aAttributeValue have the same text)
- result = false;
- }
- else {
- result = StringBeginsWith(aAttributeValue, aSelectorValue, aComparator);
- }
- }
- return result;
- }
- bool
- nsStyleUtil::ValueIncludes(const nsSubstring& aValueList,
- const nsSubstring& aValue,
- const nsStringComparator& aComparator)
- {
- const char16_t *p = aValueList.BeginReading(),
- *p_end = aValueList.EndReading();
- while (p < p_end) {
- // skip leading space
- while (p != p_end && nsContentUtils::IsHTMLWhitespace(*p))
- ++p;
- const char16_t *val_start = p;
- // look for space or end
- while (p != p_end && !nsContentUtils::IsHTMLWhitespace(*p))
- ++p;
- const char16_t *val_end = p;
- if (val_start < val_end &&
- aValue.Equals(Substring(val_start, val_end), aComparator))
- return true;
- ++p; // we know the next character is not whitespace
- }
- return false;
- }
- void nsStyleUtil::AppendEscapedCSSString(const nsAString& aString,
- nsAString& aReturn,
- char16_t quoteChar)
- {
- NS_PRECONDITION(quoteChar == '\'' || quoteChar == '"',
- "CSS strings must be quoted with ' or \"");
- aReturn.Append(quoteChar);
- const char16_t* in = aString.BeginReading();
- const char16_t* const end = aString.EndReading();
- for (; in != end; in++) {
- if (*in < 0x20 || (*in >= 0x7F && *in < 0xA0)) {
- // Escape U+0000 through U+001F and U+007F through U+009F numerically.
- aReturn.AppendPrintf("\\%hx ", *in);
- } else {
- if (*in == '"' || *in == '\'' || *in == '\\') {
- // Escape backslash and quote characters symbolically.
- // It's not technically necessary to escape the quote
- // character that isn't being used to delimit the string,
- // but we do it anyway because that makes testing simpler.
- aReturn.Append(char16_t('\\'));
- }
- aReturn.Append(*in);
- }
- }
- aReturn.Append(quoteChar);
- }
- /* static */ void
- nsStyleUtil::AppendEscapedCSSIdent(const nsAString& aIdent, nsAString& aReturn)
- {
- // The relevant parts of the CSS grammar are:
- // ident ([-]?{nmstart}|[-][-]){nmchar}*
- // nmstart [_a-z]|{nonascii}|{escape}
- // nmchar [_a-z0-9-]|{nonascii}|{escape}
- // nonascii [^\0-\177]
- // escape {unicode}|\\[^\n\r\f0-9a-f]
- // unicode \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
- // from http://www.w3.org/TR/CSS21/syndata.html#tokenization but
- // modified for idents by
- // http://dev.w3.org/csswg/cssom/#serialize-an-identifier and
- // http://dev.w3.org/csswg/css-syntax/#would-start-an-identifier
- const char16_t* in = aIdent.BeginReading();
- const char16_t* const end = aIdent.EndReading();
- if (in == end)
- return;
- // A leading dash does not need to be escaped as long as it is not the
- // *only* character in the identifier.
- if (*in == '-') {
- if (in + 1 == end) {
- aReturn.Append(char16_t('\\'));
- aReturn.Append(char16_t('-'));
- return;
- }
- aReturn.Append(char16_t('-'));
- ++in;
- }
- // Escape a digit at the start (including after a dash),
- // numerically. If we didn't escape it numerically, it would get
- // interpreted as a numeric escape for the wrong character.
- if (in != end && ('0' <= *in && *in <= '9')) {
- aReturn.AppendPrintf("\\%hx ", *in);
- ++in;
- }
- for (; in != end; ++in) {
- char16_t ch = *in;
- if (ch == 0x00) {
- aReturn.Append(char16_t(0xFFFD));
- } else if (ch < 0x20 || (0x7F <= ch && ch < 0xA0)) {
- // Escape U+0000 through U+001F and U+007F through U+009F numerically.
- aReturn.AppendPrintf("\\%hx ", *in);
- } else {
- // Escape ASCII non-identifier printables as a backslash plus
- // the character.
- if (ch < 0x7F &&
- ch != '_' && ch != '-' &&
- (ch < '0' || '9' < ch) &&
- (ch < 'A' || 'Z' < ch) &&
- (ch < 'a' || 'z' < ch)) {
- aReturn.Append(char16_t('\\'));
- }
- aReturn.Append(ch);
- }
- }
- }
- // unquoted family names must be a sequence of idents
- // so escape any parts that require escaping
- static void
- AppendUnquotedFamilyName(const nsAString& aFamilyName, nsAString& aResult)
- {
- const char16_t *p, *p_end;
- aFamilyName.BeginReading(p);
- aFamilyName.EndReading(p_end);
- bool moreThanOne = false;
- while (p < p_end) {
- const char16_t* identStart = p;
- while (++p != p_end && *p != ' ')
- /* nothing */ ;
- nsDependentSubstring ident(identStart, p);
- if (!ident.IsEmpty()) {
- if (moreThanOne) {
- aResult.Append(' ');
- }
- nsStyleUtil::AppendEscapedCSSIdent(ident, aResult);
- moreThanOne = true;
- }
- ++p;
- }
- }
- /* static */ void
- nsStyleUtil::AppendEscapedCSSFontFamilyList(
- const mozilla::FontFamilyList& aFamilyList,
- nsAString& aResult)
- {
- const nsTArray<FontFamilyName>& fontlist = aFamilyList.GetFontlist();
- size_t i, len = fontlist.Length();
- for (i = 0; i < len; i++) {
- if (i != 0) {
- aResult.Append(',');
- }
- const FontFamilyName& name = fontlist[i];
- switch (name.mType) {
- case eFamily_named:
- AppendUnquotedFamilyName(name.mName, aResult);
- break;
- case eFamily_named_quoted:
- AppendEscapedCSSString(name.mName, aResult);
- break;
- default:
- name.AppendToString(aResult);
- }
- }
- }
- /* static */ void
- nsStyleUtil::AppendBitmaskCSSValue(nsCSSPropertyID aProperty,
- int32_t aMaskedValue,
- int32_t aFirstMask,
- int32_t aLastMask,
- nsAString& aResult)
- {
- for (int32_t mask = aFirstMask; mask <= aLastMask; mask <<= 1) {
- if (mask & aMaskedValue) {
- AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, mask),
- aResult);
- aMaskedValue &= ~mask;
- if (aMaskedValue) { // more left
- aResult.Append(char16_t(' '));
- }
- }
- }
- MOZ_ASSERT(aMaskedValue == 0, "unexpected bit remaining in bitfield");
- }
- /* static */ void
- nsStyleUtil::AppendAngleValue(const nsStyleCoord& aAngle, nsAString& aResult)
- {
- MOZ_ASSERT(aAngle.IsAngleValue(), "Should have angle value");
- // Append number.
- AppendCSSNumber(aAngle.GetAngleValue(), aResult);
- // Append unit.
- switch (aAngle.GetUnit()) {
- case eStyleUnit_Degree: aResult.AppendLiteral("deg"); break;
- case eStyleUnit_Grad: aResult.AppendLiteral("grad"); break;
- case eStyleUnit_Radian: aResult.AppendLiteral("rad"); break;
- case eStyleUnit_Turn: aResult.AppendLiteral("turn"); break;
- default: NS_NOTREACHED("unrecognized angle unit");
- }
- }
- /* static */ void
- nsStyleUtil::AppendPaintOrderValue(uint8_t aValue,
- nsAString& aResult)
- {
- static_assert
- (NS_STYLE_PAINT_ORDER_BITWIDTH * NS_STYLE_PAINT_ORDER_LAST_VALUE <= 8,
- "SVGStyleStruct::mPaintOrder and local variables not big enough");
- if (aValue == NS_STYLE_PAINT_ORDER_NORMAL) {
- aResult.AppendLiteral("normal");
- return;
- }
- // Append the minimal value necessary for the given paint order.
- static_assert(NS_STYLE_PAINT_ORDER_LAST_VALUE == 3,
- "paint-order values added; check serialization");
- // The following relies on the default order being the order of the
- // constant values.
- const uint8_t MASK = (1 << NS_STYLE_PAINT_ORDER_BITWIDTH) - 1;
- uint32_t lastPositionToSerialize = 0;
- for (uint32_t position = NS_STYLE_PAINT_ORDER_LAST_VALUE - 1;
- position > 0;
- position--) {
- uint8_t component =
- (aValue >> (position * NS_STYLE_PAINT_ORDER_BITWIDTH)) & MASK;
- uint8_t earlierComponent =
- (aValue >> ((position - 1) * NS_STYLE_PAINT_ORDER_BITWIDTH)) & MASK;
- if (component < earlierComponent) {
- lastPositionToSerialize = position - 1;
- break;
- }
- }
- for (uint32_t position = 0; position <= lastPositionToSerialize; position++) {
- if (position > 0) {
- aResult.Append(' ');
- }
- uint8_t component = aValue & MASK;
- switch (component) {
- case NS_STYLE_PAINT_ORDER_FILL:
- aResult.AppendLiteral("fill");
- break;
- case NS_STYLE_PAINT_ORDER_STROKE:
- aResult.AppendLiteral("stroke");
- break;
- case NS_STYLE_PAINT_ORDER_MARKERS:
- aResult.AppendLiteral("markers");
- break;
- default:
- NS_NOTREACHED("unexpected paint-order component value");
- }
- aValue >>= NS_STYLE_PAINT_ORDER_BITWIDTH;
- }
- }
- /* static */ void
- nsStyleUtil::AppendFontFeatureSettings(const nsTArray<gfxFontFeature>& aFeatures,
- nsAString& aResult)
- {
- for (uint32_t i = 0, numFeat = aFeatures.Length(); i < numFeat; i++) {
- const gfxFontFeature& feat = aFeatures[i];
- if (i != 0) {
- aResult.AppendLiteral(", ");
- }
- // output tag
- char tag[7];
- tag[0] = '"';
- tag[1] = (feat.mTag >> 24) & 0xff;
- tag[2] = (feat.mTag >> 16) & 0xff;
- tag[3] = (feat.mTag >> 8) & 0xff;
- tag[4] = feat.mTag & 0xff;
- tag[5] = '"';
- tag[6] = 0;
- aResult.AppendASCII(tag);
- // output value, if necessary
- if (feat.mValue == 0) {
- // 0 ==> off
- aResult.AppendLiteral(" off");
- } else if (feat.mValue > 1) {
- aResult.Append(' ');
- aResult.AppendInt(feat.mValue);
- }
- // else, omit value if 1, implied by default
- }
- }
- /* static */ void
- nsStyleUtil::AppendFontFeatureSettings(const nsCSSValue& aSrc,
- nsAString& aResult)
- {
- nsCSSUnit unit = aSrc.GetUnit();
- if (unit == eCSSUnit_Normal) {
- aResult.AppendLiteral("normal");
- return;
- }
- NS_PRECONDITION(unit == eCSSUnit_PairList || unit == eCSSUnit_PairListDep,
- "improper value unit for font-feature-settings:");
- nsTArray<gfxFontFeature> featureSettings;
- nsRuleNode::ComputeFontFeatures(aSrc.GetPairListValue(), featureSettings);
- AppendFontFeatureSettings(featureSettings, aResult);
- }
- /* static */ void
- nsStyleUtil::GetFunctionalAlternatesName(int32_t aFeature,
- nsAString& aFeatureName)
- {
- aFeatureName.Truncate();
- nsCSSKeyword key =
- nsCSSProps::ValueToKeywordEnum(aFeature,
- nsCSSProps::kFontVariantAlternatesFuncsKTable);
- NS_ASSERTION(key != eCSSKeyword_UNKNOWN, "bad alternate feature type");
- AppendUTF8toUTF16(nsCSSKeywords::GetStringValue(key), aFeatureName);
- }
- /* static */ void
- nsStyleUtil::SerializeFunctionalAlternates(
- const nsTArray<gfxAlternateValue>& aAlternates,
- nsAString& aResult)
- {
- nsAutoString funcName, funcParams;
- uint32_t numValues = aAlternates.Length();
- uint32_t feature = 0;
- for (uint32_t i = 0; i < numValues; i++) {
- const gfxAlternateValue& v = aAlternates.ElementAt(i);
- if (feature != v.alternate) {
- feature = v.alternate;
- if (!funcName.IsEmpty() && !funcParams.IsEmpty()) {
- if (!aResult.IsEmpty()) {
- aResult.Append(char16_t(' '));
- }
- // append the previous functional value
- aResult.Append(funcName);
- aResult.Append(char16_t('('));
- aResult.Append(funcParams);
- aResult.Append(char16_t(')'));
- }
- // function name
- GetFunctionalAlternatesName(v.alternate, funcName);
- NS_ASSERTION(!funcName.IsEmpty(), "unknown property value name");
- // function params
- funcParams.Truncate();
- AppendEscapedCSSIdent(v.value, funcParams);
- } else {
- if (!funcParams.IsEmpty()) {
- funcParams.AppendLiteral(", ");
- }
- AppendEscapedCSSIdent(v.value, funcParams);
- }
- }
- // append the previous functional value
- if (!funcName.IsEmpty() && !funcParams.IsEmpty()) {
- if (!aResult.IsEmpty()) {
- aResult.Append(char16_t(' '));
- }
- aResult.Append(funcName);
- aResult.Append(char16_t('('));
- aResult.Append(funcParams);
- aResult.Append(char16_t(')'));
- }
- }
- /* static */ void
- nsStyleUtil::ComputeFunctionalAlternates(const nsCSSValueList* aList,
- nsTArray<gfxAlternateValue>& aAlternateValues)
- {
- gfxAlternateValue v;
- aAlternateValues.Clear();
- for (const nsCSSValueList* curr = aList; curr != nullptr; curr = curr->mNext) {
- // list contains function units
- if (curr->mValue.GetUnit() != eCSSUnit_Function) {
- continue;
- }
- // element 0 is the propval in ident form
- const nsCSSValue::Array *func = curr->mValue.GetArrayValue();
- // lookup propval
- nsCSSKeyword key = func->Item(0).GetKeywordValue();
- NS_ASSERTION(key != eCSSKeyword_UNKNOWN, "unknown alternate property value");
- int32_t alternate;
- if (key == eCSSKeyword_UNKNOWN ||
- !nsCSSProps::FindKeyword(key,
- nsCSSProps::kFontVariantAlternatesFuncsKTable,
- alternate)) {
- NS_NOTREACHED("keyword not a font-variant-alternates value");
- continue;
- }
- v.alternate = alternate;
- // other elements are the idents associated with the propval
- // append one alternate value for each one
- uint32_t numElems = func->Count();
- for (uint32_t i = 1; i < numElems; i++) {
- const nsCSSValue& value = func->Item(i);
- NS_ASSERTION(value.GetUnit() == eCSSUnit_Ident,
- "weird unit found in variant alternate");
- if (value.GetUnit() != eCSSUnit_Ident) {
- continue;
- }
- value.GetStringValue(v.value);
- aAlternateValues.AppendElement(v);
- }
- }
- }
- static void
- AppendSerializedUnicodePoint(uint32_t aCode, nsACString& aBuf)
- {
- aBuf.Append(nsPrintfCString("%0X", aCode));
- }
- // A unicode-range: descriptor is represented as an array of integers,
- // to be interpreted as a sequence of pairs: min max min max ...
- // It is in source order. (Possibly it should be sorted and overlaps
- // consolidated, but right now we don't do that.)
- /* static */ void
- nsStyleUtil::AppendUnicodeRange(const nsCSSValue& aValue, nsAString& aResult)
- {
- NS_PRECONDITION(aValue.GetUnit() == eCSSUnit_Null ||
- aValue.GetUnit() == eCSSUnit_Array,
- "improper value unit for unicode-range:");
- aResult.Truncate();
- if (aValue.GetUnit() != eCSSUnit_Array)
- return;
- nsCSSValue::Array const & sources = *aValue.GetArrayValue();
- nsAutoCString buf;
- MOZ_ASSERT(sources.Count() % 2 == 0,
- "odd number of entries in a unicode-range: array");
- for (uint32_t i = 0; i < sources.Count(); i += 2) {
- uint32_t min = sources[i].GetIntValue();
- uint32_t max = sources[i+1].GetIntValue();
- // We don't try to replicate the U+XX?? notation.
- buf.AppendLiteral("U+");
- AppendSerializedUnicodePoint(min, buf);
- if (min != max) {
- buf.Append('-');
- AppendSerializedUnicodePoint(max, buf);
- }
- buf.AppendLiteral(", ");
- }
- buf.Truncate(buf.Length() - 2); // remove the last comma-space
- CopyASCIItoUTF16(buf, aResult);
- }
- /* static */ void
- nsStyleUtil::AppendSerializedFontSrc(const nsCSSValue& aValue,
- nsAString& aResult)
- {
- // A src: descriptor is represented as an array value; each entry in
- // the array can be eCSSUnit_URL, eCSSUnit_Local_Font, or
- // eCSSUnit_Font_Format. Blocks of eCSSUnit_Font_Format may appear
- // only after one of the first two. (css3-fonts only contemplates
- // annotating URLs with formats, but we handle the general case.)
- NS_PRECONDITION(aValue.GetUnit() == eCSSUnit_Array,
- "improper value unit for src:");
- const nsCSSValue::Array& sources = *aValue.GetArrayValue();
- size_t i = 0;
- while (i < sources.Count()) {
- nsAutoString formats;
- if (sources[i].GetUnit() == eCSSUnit_URL) {
- aResult.AppendLiteral("url(");
- nsDependentString url(sources[i].GetOriginalURLValue());
- nsStyleUtil::AppendEscapedCSSString(url, aResult);
- aResult.Append(')');
- } else if (sources[i].GetUnit() == eCSSUnit_Local_Font) {
- aResult.AppendLiteral("local(");
- nsDependentString local(sources[i].GetStringBufferValue());
- nsStyleUtil::AppendEscapedCSSString(local, aResult);
- aResult.Append(')');
- } else {
- NS_NOTREACHED("entry in src: descriptor with improper unit");
- i++;
- continue;
- }
- i++;
- formats.Truncate();
- while (i < sources.Count() &&
- sources[i].GetUnit() == eCSSUnit_Font_Format) {
- formats.Append('"');
- formats.Append(sources[i].GetStringBufferValue());
- formats.AppendLiteral("\", ");
- i++;
- }
- if (formats.Length() > 0) {
- formats.Truncate(formats.Length() - 2); // remove the last comma
- aResult.AppendLiteral(" format(");
- aResult.Append(formats);
- aResult.Append(')');
- }
- aResult.AppendLiteral(", ");
- }
- aResult.Truncate(aResult.Length() - 2); // remove the last comma-space
- }
- /* static */ void
- nsStyleUtil::AppendStepsTimingFunction(nsTimingFunction::Type aType,
- uint32_t aSteps,
- nsAString& aResult)
- {
- MOZ_ASSERT(aType == nsTimingFunction::Type::StepStart ||
- aType == nsTimingFunction::Type::StepEnd);
- aResult.AppendLiteral("steps(");
- aResult.AppendInt(aSteps);
- if (aType == nsTimingFunction::Type::StepStart) {
- aResult.AppendLiteral(", start)");
- } else {
- aResult.AppendLiteral(")");
- }
- }
- /* static */ void
- nsStyleUtil::AppendCubicBezierTimingFunction(float aX1, float aY1,
- float aX2, float aY2,
- nsAString& aResult)
- {
- // set the value from the cubic-bezier control points
- // (We could try to regenerate the keywords if we want.)
- aResult.AppendLiteral("cubic-bezier(");
- aResult.AppendFloat(aX1);
- aResult.AppendLiteral(", ");
- aResult.AppendFloat(aY1);
- aResult.AppendLiteral(", ");
- aResult.AppendFloat(aX2);
- aResult.AppendLiteral(", ");
- aResult.AppendFloat(aY2);
- aResult.Append(')');
- }
- /* static */ void
- nsStyleUtil::AppendCubicBezierKeywordTimingFunction(
- nsTimingFunction::Type aType,
- nsAString& aResult)
- {
- switch (aType) {
- case nsTimingFunction::Type::Ease:
- case nsTimingFunction::Type::Linear:
- case nsTimingFunction::Type::EaseIn:
- case nsTimingFunction::Type::EaseOut:
- case nsTimingFunction::Type::EaseInOut: {
- nsCSSKeyword keyword = nsCSSProps::ValueToKeywordEnum(
- static_cast<int32_t>(aType),
- nsCSSProps::kTransitionTimingFunctionKTable);
- AppendASCIItoUTF16(nsCSSKeywords::GetStringValue(keyword),
- aResult);
- break;
- }
- default:
- MOZ_ASSERT_UNREACHABLE("unexpected aType");
- break;
- }
- }
- /* static */ float
- nsStyleUtil::ColorComponentToFloat(uint8_t aAlpha)
- {
- // Alpha values are expressed as decimals, so we should convert
- // back, using as few decimal places as possible for
- // round-tripping.
- // First try two decimal places:
- float rounded = NS_roundf(float(aAlpha) * 100.0f / 255.0f) / 100.0f;
- if (FloatToColorComponent(rounded) != aAlpha) {
- // Use three decimal places.
- rounded = NS_roundf(float(aAlpha) * 1000.0f / 255.0f) / 1000.0f;
- }
- return rounded;
- }
- /* static */ bool
- nsStyleUtil::IsSignificantChild(nsIContent* aChild, bool aTextIsSignificant,
- bool aWhitespaceIsSignificant)
- {
- NS_ASSERTION(!aWhitespaceIsSignificant || aTextIsSignificant,
- "Nonsensical arguments");
- bool isText = aChild->IsNodeOfType(nsINode::eTEXT);
- if (!isText && !aChild->IsNodeOfType(nsINode::eCOMMENT) &&
- !aChild->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION)) {
- return true;
- }
- return aTextIsSignificant && isText && aChild->TextLength() != 0 &&
- (aWhitespaceIsSignificant ||
- !aChild->TextIsOnlyWhitespace());
- }
- // For a replaced element whose concrete object size is no larger than the
- // element's content-box, this method checks whether the given
- // "object-position" coordinate might cause overflow in its dimension.
- static bool
- ObjectPositionCoordMightCauseOverflow(const Position::Coord& aCoord)
- {
- // Any nonzero length in "object-position" can push us to overflow
- // (particularly if our concrete object size is exactly the same size as the
- // replaced element's content-box).
- if (aCoord.mLength != 0) {
- return true;
- }
- // Percentages are interpreted as a fraction of the extra space. So,
- // percentages in the 0-100% range are safe, but values outside of that
- // range could cause overflow.
- if (aCoord.mHasPercent &&
- (aCoord.mPercent < 0.0f || aCoord.mPercent > 1.0f)) {
- return true;
- }
- return false;
- }
- /* static */ bool
- nsStyleUtil::ObjectPropsMightCauseOverflow(const nsStylePosition* aStylePos)
- {
- auto objectFit = aStylePos->mObjectFit;
- // "object-fit: cover" & "object-fit: none" can give us a render rect that's
- // larger than our container element's content-box.
- if (objectFit == NS_STYLE_OBJECT_FIT_COVER ||
- objectFit == NS_STYLE_OBJECT_FIT_NONE) {
- return true;
- }
- // (All other object-fit values produce a concrete object size that's no larger
- // than the constraint region.)
- // Check each of our "object-position" coords to see if it could cause
- // overflow in its dimension:
- const Position& objectPosistion = aStylePos->mObjectPosition;
- if (ObjectPositionCoordMightCauseOverflow(objectPosistion.mXPosition) ||
- ObjectPositionCoordMightCauseOverflow(objectPosistion.mYPosition)) {
- return true;
- }
- return false;
- }
- /* static */ bool
- nsStyleUtil::CSPAllowsInlineStyle(nsIContent* aContent,
- nsIPrincipal* aPrincipal,
- nsIURI* aSourceURI,
- uint32_t aLineNumber,
- const nsSubstring& aStyleText,
- nsresult* aRv)
- {
- nsresult rv;
- if (aRv) {
- *aRv = NS_OK;
- }
- MOZ_ASSERT(!aContent || aContent->NodeInfo()->NameAtom() == nsGkAtoms::style,
- "aContent passed to CSPAllowsInlineStyle "
- "for an element that is not <style>");
- nsCOMPtr<nsIContentSecurityPolicy> csp;
- rv = aPrincipal->GetCsp(getter_AddRefs(csp));
- if (NS_FAILED(rv)) {
- if (aRv)
- *aRv = rv;
- return false;
- }
- if (!csp) {
- // No CSP --> the style is allowed
- return true;
- }
- // query the nonce
- nsAutoString nonce;
- if (aContent) {
- aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::nonce, nonce);
- }
- bool allowInlineStyle = true;
- rv = csp->GetAllowsInline(nsIContentPolicy::TYPE_STYLESHEET,
- nonce,
- false, // aParserCreated only applies to scripts
- aStyleText, aLineNumber,
- &allowInlineStyle);
- NS_ENSURE_SUCCESS(rv, false);
- return allowInlineStyle;
- }
|