WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch for landing
bug-236771-20220217181240.patch (text/plain), 22.69 KB, created by
Antti Koivisto
on 2022-02-17 08:12:42 PST
(
hide
)
Description:
Patch for landing
Filename:
MIME Type:
Creator:
Antti Koivisto
Created:
2022-02-17 08:12:42 PST
Size:
22.69 KB
patch
obsolete
>Subversion Revision: 289997 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 934c1c276ef826ba495046a4c9dcbc32389a980f..0ecdcd6535d518b9f8c1d720db3611c558861049 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,38 @@ >+2022-02-17 Antti Koivisto <antti@apple.com> >+ >+ [CSS Container Queries] Support full range notation in size queries >+ https://bugs.webkit.org/show_bug.cgi?id=236771 >+ >+ Reviewed by Dean Jackson. >+ >+ Parse and evaluate notations like (100px < width) and (100px < width < 200px). >+ >+ * css/ContainerQuery.h: >+ >+ There are now optional left and right comparisons. >+ >+ * css/ContainerQueryParser.cpp: >+ (WebCore::ContainerQueryParser::consumeSizeQuery): >+ (WebCore::ContainerQueryParser::consumeSizeFeature): >+ (WebCore::ContainerQueryParser::consumePlainSizeFeature): >+ >+ Evaluate the plain (foo: value) notation. >+ >+ (WebCore::ContainerQueryParser::consumeRangeSizeFeature): >+ >+ Evaluate range notation. >+ >+ (WebCore::ContainerQueryParser::consumeValue): >+ * css/ContainerQueryParser.h: >+ * style/ContainerQueryEvaluator.cpp: >+ (WebCore::Style::ContainerQueryEvaluator::evaluateSizeFeature const): >+ >+ Evaluate both comparisons if they exist. >+ >+ * style/ContainerQueryEvaluator.h: >+ (WebCore::Style::toEvaluationResult): >+ (WebCore::Style::operator|): >+ > 2022-02-16 Joonghun Park <jh718.park@samsung.com> > > Change the canonical unit for time category from ms to s. >diff --git a/Source/WebCore/css/ContainerQuery.h b/Source/WebCore/css/ContainerQuery.h >index adaadd064f44226dcbe111d248520b776c513d95..7d9a35973cc9efc82259a53cb8715b3a5c6a97e7 100644 >--- a/Source/WebCore/css/ContainerQuery.h >+++ b/Source/WebCore/css/ContainerQuery.h >@@ -42,7 +42,7 @@ using SizeQuery = std::variant<SizeCondition, SizeFeature>; > using ContainerQuery = std::variant<ContainerCondition, SizeQuery, UnknownQuery>; > > enum class LogicalOperator : uint8_t { And, Or, Not }; >-enum class ComparisonOperator : uint8_t { LessThan, LessThanOrEqual, Equal, GreaterThan, GreaterThanOrEqual, True }; >+enum class ComparisonOperator : uint8_t { LessThan, LessThanOrEqual, Equal, GreaterThan, GreaterThanOrEqual }; > > struct ContainerCondition { > LogicalOperator logicalOperator { LogicalOperator::And }; >@@ -54,10 +54,15 @@ struct SizeCondition { > Vector<SizeQuery> queries; > }; > >+struct Comparison { >+ ComparisonOperator op { ComparisonOperator::Equal }; >+ RefPtr<CSSValue> value; >+}; >+ > struct SizeFeature { >- ComparisonOperator comparisonOperator { ComparisonOperator::Equal }; > AtomString name; >- RefPtr<CSSValue> value; >+ std::optional<Comparison> leftComparison; >+ std::optional<Comparison> rightComparison; > }; > > namespace FeatureNames { >diff --git a/Source/WebCore/css/ContainerQueryParser.cpp b/Source/WebCore/css/ContainerQueryParser.cpp >index 14738b3511f790d9f82f000fdf0684717504ec07..6d3b4ecf665aa1a1669263c52d9c59c68f586887 100644 >--- a/Source/WebCore/css/ContainerQueryParser.cpp >+++ b/Source/WebCore/css/ContainerQueryParser.cpp >@@ -136,7 +136,7 @@ std::optional<ConditionType> ContainerQueryParser::consumeCondition(CSSParserTok > > std::optional<CQ::SizeQuery> ContainerQueryParser::consumeSizeQuery(CSSParserTokenRange& range) > { >- if (range.peek().type() != IdentToken || range.peek().id() == CSSValueNot) { >+ if (range.peek().type() == LeftParenthesisToken || (range.peek().type() == IdentToken && range.peek().id() == CSSValueNot)) { > auto sizeCondition = consumeCondition<CQ::SizeCondition>(range); > if (!sizeCondition) > return { }; >@@ -147,82 +147,142 @@ std::optional<CQ::SizeQuery> ContainerQueryParser::consumeSizeQuery(CSSParserTok > if (!sizeFeature) > return { }; > >- range.consumeWhitespace(); >- if (!range.atEnd()) >- return { }; >- > return { *sizeFeature }; > } > > std::optional<CQ::SizeFeature> ContainerQueryParser::consumeSizeFeature(CSSParserTokenRange& range) > { >- // FIXME: Support value-first (100px < width) and full range (100px < width < 200px) notations. >+ auto rangeCopy = range; >+ if (auto sizeFeature = consumePlainSizeFeature(range)) >+ return sizeFeature; >+ >+ range = rangeCopy; >+ return consumeRangeSizeFeature(range); >+} >+ >+std::optional<CQ::SizeFeature> ContainerQueryParser::consumePlainSizeFeature(CSSParserTokenRange& range) >+{ >+ auto consumePlainFeatureName = [&]() -> std::pair<AtomString, CQ::ComparisonOperator> { >+ if (range.peek().type() != IdentToken) >+ return { }; >+ auto token = range.consumeIncludingWhitespace(); >+ auto name = token.value(); >+ if (name.startsWith("min-")) >+ return { name.substring(4).toAtomString(), CQ::ComparisonOperator::GreaterThanOrEqual }; >+ if (name.startsWith("max-")) >+ return { name.substring(4).toAtomString(), CQ::ComparisonOperator::LessThanOrEqual }; >+ >+ return { name.toAtomString(), CQ::ComparisonOperator::Equal }; >+ }; >+ >+ auto [featureName, op] = consumePlainFeatureName(); >+ if (featureName.isEmpty()) >+ return { }; >+ >+ range.consumeWhitespace(); > >- auto nameToken = range.consumeIncludingWhitespace(); >- ASSERT(nameToken.type() == IdentToken); >+ if (range.atEnd()) { >+ if (op != CQ::ComparisonOperator::Equal) >+ return { }; >+ return CQ::SizeFeature { featureName, { }, { } }; >+ } > >- auto name = nameToken.value(); >+ if (range.peek().type() != ColonToken) >+ return { }; > >+ range.consumeIncludingWhitespace(); > if (range.atEnd()) >- return CQ::SizeFeature { CQ::ComparisonOperator::True, name.toAtomString(), { } }; >+ return { }; > >- auto consumeOperator = [&]() -> std::optional<CQ::ComparisonOperator> { >- auto opToken = range.consume(); >+ auto value = consumeValue(range); >+ >+ return CQ::SizeFeature { featureName, { }, CQ::Comparison { op, WTFMove(value) } }; >+} >+ >+std::optional<CQ::SizeFeature> ContainerQueryParser::consumeRangeSizeFeature(CSSParserTokenRange& range) >+{ >+ auto consumeFeatureName = [&]() -> AtomString { >+ if (range.peek().type() != IdentToken) >+ return { }; >+ return range.consumeIncludingWhitespace().value().toAtomString(); >+ }; >+ >+ auto consumeRangeOperator = [&]() -> std::optional<CQ::ComparisonOperator> { > if (range.atEnd()) > return { }; >- if (opToken.type() == ColonToken) { >- if (name.startsWith("min-")) { >- name = name.substring(4); >- return CQ::ComparisonOperator::GreaterThanOrEqual; >- } >- if (name.startsWith("max-")) { >- name = name.substring(4); >+ auto opToken = range.consume(); >+ if (range.atEnd() || opToken.type() != DelimiterToken) >+ return { }; >+ >+ switch (opToken.delimiter()) { >+ case '=': >+ range.consumeWhitespace(); >+ return CQ::ComparisonOperator::Equal; >+ case '<': >+ if (range.peek().type() == DelimiterToken && range.peek().delimiter() == '=') { >+ range.consumeIncludingWhitespace(); > return CQ::ComparisonOperator::LessThanOrEqual; > } >- return CQ::ComparisonOperator::Equal; >- } >- if (opToken.type() == DelimiterToken) { >- switch (opToken.delimiter()) { >- case '=': >- return CQ::ComparisonOperator::Equal; >- case '<': >- if (range.peek().type() == DelimiterToken && range.peek().delimiter() == '=') { >- range.consume(); >- return CQ::ComparisonOperator::LessThanOrEqual; >- } >- return CQ::ComparisonOperator::LessThan; >- case '>': >- if (range.peek().type() == DelimiterToken && range.peek().delimiter() == '=') { >- range.consume(); >- return CQ::ComparisonOperator::GreaterThanOrEqual; >- } >- return CQ::ComparisonOperator::GreaterThan; >- default: >- return { }; >+ range.consumeWhitespace(); >+ return CQ::ComparisonOperator::LessThan; >+ case '>': >+ if (range.peek().type() == DelimiterToken && range.peek().delimiter() == '=') { >+ range.consumeIncludingWhitespace(); >+ return CQ::ComparisonOperator::GreaterThanOrEqual; > } >+ range.consumeWhitespace(); >+ return CQ::ComparisonOperator::GreaterThan; >+ default: >+ return { }; > } >- return { }; > }; > >- auto op = consumeOperator(); >- if (!op) >- return { }; >+ auto consumeLeftComparison = [&]() -> std::optional<CQ::Comparison> { >+ if (range.peek().type() == IdentToken) >+ return { }; >+ auto value = consumeValue(range); >+ auto op = consumeRangeOperator(); >+ if (!op) >+ return { }; > >- range.consumeWhitespace(); >+ return CQ::Comparison { *op, WTFMove(value) }; >+ }; > >- auto featureName = name.toAtomString(); >+ auto consumeRightComparison = [&]() -> std::optional<CQ::Comparison> { >+ auto op = consumeRangeOperator(); >+ if (!op) >+ return { }; >+ auto value = consumeValue(range); > >- auto consumeValue = [&]() -> RefPtr<CSSValue> { >- if (featureName == CQ::FeatureNames::orientation()) >- return CSSPropertyParserHelpers::consumeIdent(range); >- if (featureName == CQ::FeatureNames::aspectRatio()) >- return CSSPropertyParserHelpers::consumeAspectRatioValue(range); >- return CSSPropertyParserHelpers::consumeLength(range, m_context.mode, ValueRange::All); >+ return CQ::Comparison { *op, WTFMove(value) }; > }; > >- auto value = consumeValue(); >+ auto leftComparison = consumeLeftComparison(); >+ >+ auto featureName = consumeFeatureName(); >+ if (featureName.isEmpty()) >+ return { }; >+ >+ auto rightComparison = consumeRightComparison(); > >- return CQ::SizeFeature { *op, WTFMove(featureName), WTFMove(value) }; >+ if (!leftComparison && !rightComparison) >+ return { }; >+ >+ return CQ::SizeFeature { WTFMove(featureName), WTFMove(leftComparison), WTFMove(rightComparison) }; >+} >+ >+RefPtr<CSSValue> ContainerQueryParser::consumeValue(CSSParserTokenRange& range) >+{ >+ if (range.atEnd()) >+ return nullptr; >+ if (auto value = CSSPropertyParserHelpers::consumeIdent(range)) >+ return value; >+ if (auto value = CSSPropertyParserHelpers::consumeLength(range, m_context.mode, ValueRange::All)) >+ return value; >+ if (auto value = CSSPropertyParserHelpers::consumeAspectRatioValue(range)) >+ return value; >+ range.consumeIncludingWhitespace(); >+ return nullptr; > } > > } >diff --git a/Source/WebCore/css/ContainerQueryParser.h b/Source/WebCore/css/ContainerQueryParser.h >index 52ed4bad810bf29956f8abf48bd43cdeb4a69d34..add3da3f445795c4eb8899a67d5e62f76df136a5 100644 >--- a/Source/WebCore/css/ContainerQueryParser.h >+++ b/Source/WebCore/css/ContainerQueryParser.h >@@ -41,6 +41,9 @@ private: > std::optional<CQ::SizeQuery> consumeSizeQuery(CSSParserTokenRange&); > template<typename ConditionType> std::optional<ConditionType> consumeCondition(CSSParserTokenRange&); > std::optional<CQ::SizeFeature> consumeSizeFeature(CSSParserTokenRange&); >+ std::optional<CQ::SizeFeature> consumePlainSizeFeature(CSSParserTokenRange&); >+ std::optional<CQ::SizeFeature> consumeRangeSizeFeature(CSSParserTokenRange&); >+ RefPtr<CSSValue> consumeValue(CSSParserTokenRange&); > > ContainerQueryParser(const CSSParserContext& context) > : m_context(context) { } >diff --git a/Source/WebCore/style/ContainerQueryEvaluator.cpp b/Source/WebCore/style/ContainerQueryEvaluator.cpp >index 6e14121499b52468c09bffa59197674b01bf0504..367e112d8a6ae3a7903d882ad3e6ddf5a2dc35ad 100644 >--- a/Source/WebCore/style/ContainerQueryEvaluator.cpp >+++ b/Source/WebCore/style/ContainerQueryEvaluator.cpp >@@ -76,7 +76,7 @@ bool ContainerQueryEvaluator::evaluate(const FilteredContainerQuery& filteredCon > > auto container = resolveContainer(); > if (!container) >- return { }; >+ return false; > > return evaluateQuery(filteredContainerQuery.query, *container) == EvaluationResult::True; > } >@@ -108,16 +108,8 @@ auto ContainerQueryEvaluator::evaluateCondition(const ConditionType& condition, > return EvaluationResult::Unknown; > > switch (condition.logicalOperator) { >- case CQ::LogicalOperator::Not: { >- switch (evaluateQuery(condition.queries.first(), container)) { >- case EvaluationResult::True: >- return EvaluationResult::False; >- case EvaluationResult::False: >- return EvaluationResult::True; >- case EvaluationResult::Unknown: >- return EvaluationResult::Unknown; >- } >- } >+ case CQ::LogicalOperator::Not: >+ return !evaluateQuery(condition.queries.first(), container); > case CQ::LogicalOperator::And: { > auto result = EvaluationResult::True; > for (auto query : condition.queries) { >@@ -162,12 +154,8 @@ static std::optional<LayoutUnit> computeSize(const CSSValue* value, const CSSToL > > auto ContainerQueryEvaluator::evaluateSizeFeature(const CQ::SizeFeature& sizeFeature, const ResolvedContainer& container) const -> EvaluationResult > { >- auto toEvaluationResult = [](bool boolean) { >- return boolean ? EvaluationResult::True : EvaluationResult::False; >- }; >- >- auto compare = [&](auto left, auto right) { >- switch (sizeFeature.comparisonOperator) { >+ auto compare = [](CQ::ComparisonOperator op, auto left, auto right) { >+ switch (op) { > case CQ::ComparisonOperator::LessThan: > return left < right; > case CQ::ComparisonOperator::GreaterThan: >@@ -178,21 +166,55 @@ auto ContainerQueryEvaluator::evaluateSizeFeature(const CQ::SizeFeature& sizeFea > return left >= right; > case CQ::ComparisonOperator::Equal: > return left == right; >- case CQ::ComparisonOperator::True: >- ASSERT_NOT_REACHED(); >- return false; > } > }; > >+ enum class Side : uint8_t { Left, Right }; >+ auto evaluateSizeComparison = [&](LayoutUnit size, const std::optional<CQ::Comparison>& comparison, Side side) { >+ if (!comparison) >+ return EvaluationResult::True; >+ auto expressionSize = computeSize(comparison->value.get(), container.conversionData); >+ if (!expressionSize) >+ return EvaluationResult::Unknown; >+ auto left = side == Side::Left ? *expressionSize : size; >+ auto right = side == Side::Left ? size : *expressionSize; >+ >+ return toEvaluationResult(compare(comparison->op, left, right)); >+ }; >+ > auto evaluateSize = [&](LayoutUnit size) { >- if (sizeFeature.comparisonOperator == CQ::ComparisonOperator::True) >+ if (!sizeFeature.leftComparison && !sizeFeature.rightComparison) > return toEvaluationResult(!!size); > >- auto expressionSize = computeSize(sizeFeature.value.get(), container.conversionData); >- if (!expressionSize) >+ auto leftResult = evaluateSizeComparison(size, sizeFeature.leftComparison, Side::Left); >+ auto rightResult = evaluateSizeComparison(size, sizeFeature.rightComparison, Side::Right); >+ >+ return leftResult & rightResult; >+ }; >+ >+ auto evaluateAspectRatioComparison = [&](double aspectRatio, const std::optional<CQ::Comparison>& comparison, Side side) { >+ if (!comparison) >+ return EvaluationResult::True; >+ >+ if (!is<CSSValueList>(comparison->value)) >+ return EvaluationResult::Unknown; >+ >+ auto& ratioList = downcast<CSSValueList>(*comparison->value); >+ if (ratioList.length() != 2) > return EvaluationResult::Unknown; > >- return toEvaluationResult(compare(size, *expressionSize)); >+ auto first = dynamicDowncast<CSSPrimitiveValue>(ratioList.item(0)); >+ auto second = dynamicDowncast<CSSPrimitiveValue>(ratioList.item(1)); >+ >+ if (!first || !second || !first->isNumberOrInteger() || !second->isNumberOrInteger()) >+ return EvaluationResult::Unknown; >+ >+ auto expressionRatio = first->doubleValue() / second->doubleValue(); >+ >+ auto left = side == Side::Left ? expressionRatio : aspectRatio; >+ auto right = side == Side::Left ? aspectRatio : expressionRatio; >+ >+ return toEvaluationResult(compare(comparison->op, left, right)); > }; > > enum class Axis : uint8_t { Both, Block, Inline, Width, Height }; >@@ -245,35 +267,29 @@ auto ContainerQueryEvaluator::evaluateSizeFeature(const CQ::SizeFeature& sizeFea > return EvaluationResult::Unknown; > > auto boxRatio = container.renderer.contentWidth().toDouble() / container.renderer.contentHeight().toDouble(); >- if (sizeFeature.comparisonOperator == CQ::ComparisonOperator::True) >+ >+ if (!sizeFeature.leftComparison && !sizeFeature.rightComparison) > return toEvaluationResult(!!boxRatio); > >- if (!is<CSSValueList>(sizeFeature.value)) >- return EvaluationResult::Unknown; >- >- auto& ratioList = downcast<CSSValueList>(*sizeFeature.value); >- if (ratioList.length() != 2) >- return EvaluationResult::Unknown; >- >- auto first = dynamicDowncast<CSSPrimitiveValue>(ratioList.item(0)); >- auto second = dynamicDowncast<CSSPrimitiveValue>(ratioList.item(1)); >- >- if (!first || !second || !first->isNumberOrInteger() || !second->isNumberOrInteger()) >- return EvaluationResult::Unknown; >- >- auto expressionRatio = first->doubleValue() / second->doubleValue(); >+ auto leftResult = evaluateAspectRatioComparison(boxRatio, sizeFeature.leftComparison, Side::Left); >+ auto rightResult = evaluateAspectRatioComparison(boxRatio, sizeFeature.rightComparison, Side::Right); > >- return toEvaluationResult(compare(boxRatio, expressionRatio)); >+ return leftResult & rightResult; > } > > if (sizeFeature.name == CQ::FeatureNames::orientation()) { > if (!containerSupportsRequiredAxis(Axis::Both)) > return EvaluationResult::Unknown; > >- if (!is<CSSPrimitiveValue>(sizeFeature.value) || sizeFeature.comparisonOperator != CQ::ComparisonOperator::Equal) >+ if (!sizeFeature.rightComparison) >+ return EvaluationResult::Unknown; >+ >+ auto& comparison = *sizeFeature.rightComparison; >+ >+ if (!is<CSSPrimitiveValue>(comparison.value) || comparison.op != CQ::ComparisonOperator::Equal) > return EvaluationResult::Unknown; > >- auto& value = downcast<CSSPrimitiveValue>(*sizeFeature.value); >+ auto& value = downcast<CSSPrimitiveValue>(*sizeFeature.rightComparison->value); > > bool isPortrait = container.renderer.contentHeight() >= container.renderer.contentWidth(); > if (value.valueID() == CSSValuePortrait) >diff --git a/Source/WebCore/style/ContainerQueryEvaluator.h b/Source/WebCore/style/ContainerQueryEvaluator.h >index cfe46ad03c3a65585c5eeaff5a6f75205b397e7a..a160f0c497f0ca79c2f2d868d9968202f271cff5 100644 >--- a/Source/WebCore/style/ContainerQueryEvaluator.h >+++ b/Source/WebCore/style/ContainerQueryEvaluator.h >@@ -33,6 +33,8 @@ class Element; > > namespace Style { > >+enum class EvaluationResult : uint8_t { False, True, Unknown }; >+ > class ContainerQueryEvaluator { > public: > ContainerQueryEvaluator(const Vector<Ref<const Element>>& containers); >@@ -41,7 +43,6 @@ public: > > private: > struct ResolvedContainer; >- enum class EvaluationResult : uint8_t { False, True, Unknown }; > > EvaluationResult evaluateQuery(const CQ::ContainerQuery&, const ResolvedContainer&) const; > EvaluationResult evaluateQuery(const CQ::SizeQuery&, const ResolvedContainer&) const; >@@ -51,5 +52,31 @@ private: > const Vector<Ref<const Element>>& m_containers; > }; > >+inline EvaluationResult toEvaluationResult(bool boolean) >+{ >+ return boolean ? EvaluationResult::True : EvaluationResult::False; >+}; >+ >+inline EvaluationResult operator&(EvaluationResult left, EvaluationResult right) >+{ >+ if (left == EvaluationResult::Unknown || right == EvaluationResult::Unknown) >+ return EvaluationResult::Unknown; >+ if (left == EvaluationResult::True && right == EvaluationResult::True) >+ return EvaluationResult::True; >+ return EvaluationResult::False; >+} >+ >+inline EvaluationResult operator!(EvaluationResult result) >+{ >+ switch (result) { >+ case EvaluationResult::True: >+ return EvaluationResult::False; >+ case EvaluationResult::False: >+ return EvaluationResult::True; >+ case EvaluationResult::Unknown: >+ return EvaluationResult::Unknown; >+ } >+} >+ > } > } >diff --git a/LayoutTests/imported/w3c/ChangeLog b/LayoutTests/imported/w3c/ChangeLog >index a1e290d7135298fda774bbee9286c620c69d1ed9..aa58756643e60051be2936bcda6091a8c4b81e1e 100644 >--- a/LayoutTests/imported/w3c/ChangeLog >+++ b/LayoutTests/imported/w3c/ChangeLog >@@ -1,3 +1,12 @@ >+2022-02-17 Antti Koivisto <antti@apple.com> >+ >+ [CSS Container Queries] Support full range notation in size queries >+ https://bugs.webkit.org/show_bug.cgi?id=236771 >+ >+ Reviewed by Dean Jackson. >+ >+ * web-platform-tests/css/css-contain/container-queries/at-container-parsing-expected.txt: >+ > 2022-02-16 Joonghun Park <jh718.park@samsung.com> > > Change the canonical unit for time category from ms to s. >diff --git a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/at-container-parsing-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/at-container-parsing-expected.txt >index 91214851a2b3844b7e553dc7b2380748c0cf51ff..0dfa306a51e47fa4049329286749ba35e784ac8e 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/at-container-parsing-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/at-container-parsing-expected.txt >@@ -21,16 +21,16 @@ PASS size(not (width: 100px)) > PASS size((width: 100px) and (height: 100px)) > PASS size((width: 50px) or (height: 100px)) > PASS size(width < 100px) >-FAIL size(100px < width) assert_equals: expected 2 but got 0 >-FAIL size(100px < width < 200px) assert_equals: expected 2 but got 0 >+PASS size(100px < width) >+PASS size(100px < width < 200px) > PASS foo(width) > PASS size(asdf) >-FAIL size(resolution > 100dpi) assert_equals: expected 2 but got 0 >-FAIL size(resolution: 150dpi) assert_equals: expected 2 but got 0 >+PASS size(resolution > 100dpi) >+PASS size(resolution: 150dpi) > PASS size(color) >-FAIL size(min-color: 1) assert_equals: expected 2 but got 0 >-FAIL size(color-index >= 1) assert_equals: expected 2 but got 0 >-FAIL (color-index >= 1) assert_equals: expected 2 but got 0 >+PASS size(min-color: 1) >+PASS size(color-index >= 1) >+PASS (color-index >= 1) > PASS size(grid) > PASS (grid) > PASS screen
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 236771
:
452353
| 452369