Bug 1408308: Integrate Servo SourceSizeList in ResponsiveImageSelector. r=Manishearth

This needs to dumb down the parsing in order to match what we do in Gecko and
pass more tests.

The remaining tests are just because of calc() in media queries and "or" media
expressions.

MozReview-Commit-ID: CXGdYVbojBL
This commit is contained in:
Emilio Cobos Álvarez
2017-11-09 15:18:08 +01:00
parent 4b47ff7ad6
commit 3d7e848428
6 changed files with 68 additions and 28 deletions

View File

@@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/ResponsiveImageSelector.h"
#include "mozilla/ServoStyleSet.h"
#include "nsIURI.h"
#include "nsIDocument.h"
#include "nsContentUtils.h"
@@ -241,11 +242,18 @@ bool
ResponsiveImageSelector::SetSizesFromDescriptor(const nsAString & aSizes)
{
ClearSelectedCandidate();
mSizeQueries.Clear();
mSizeValues.Clear();
if (Document()->IsStyledByServo()) {
NS_ConvertUTF16toUTF8 sizes(aSizes);
mServoSourceSizeList.reset(Servo_SourceSizeList_Parse(&sizes));
return !!mServoSourceSizeList;
}
nsCSSParser cssParser;
mSizeQueries.Clear();
mSizeValues.Clear();
return cssParser.ParseSourceSizeList(aSizes, nullptr, 0,
mSizeQueries, mSizeValues);
}
@@ -364,11 +372,11 @@ ResponsiveImageSelector::SelectImage(bool aReselect)
}
nsIDocument* doc = Document();
nsIPresShell *shell = doc ? doc->GetShell() : nullptr;
nsPresContext *pctx = shell ? shell->GetPresContext() : nullptr;
nsCOMPtr<nsIURI> baseURI = mOwnerNode ? mOwnerNode->GetBaseURI() : nullptr;
nsIPresShell* shell = doc->GetShell();
nsPresContext* pctx = shell ? shell->GetPresContext() : nullptr;
nsCOMPtr<nsIURI> baseURI = mOwnerNode->GetBaseURI();
if (!pctx || !doc || !baseURI) {
if (!pctx || !baseURI) {
return oldBest != -1;
}
@@ -388,7 +396,7 @@ ResponsiveImageSelector::SelectImage(bool aReselect)
double computedWidth = -1;
for (int i = 0; i < numCandidates; i++) {
if (mCandidates[i].IsComputedFromWidth()) {
DebugOnly<bool> computeResult = \
DebugOnly<bool> computeResult =
ComputeFinalWidthForCurrentViewport(&computedWidth);
MOZ_ASSERT(computeResult,
"Computed candidates not allowed without sizes data");
@@ -439,34 +447,38 @@ ResponsiveImageSelector::GetSelectedCandidateIndex()
bool
ResponsiveImageSelector::ComputeFinalWidthForCurrentViewport(double *aWidth)
{
unsigned int numSizes = mSizeQueries.Length();
nsIDocument* doc = Document();
nsIPresShell *presShell = doc ? doc->GetShell() : nullptr;
nsPresContext *pctx = presShell ? presShell->GetPresContext() : nullptr;
nsIPresShell* presShell = doc->GetShell();
nsPresContext* pctx = presShell ? presShell->GetPresContext() : nullptr;
if (!pctx) {
return false;
}
MOZ_ASSERT(numSizes == mSizeValues.Length(),
"mSizeValues length differs from mSizeQueries");
unsigned int i;
for (i = 0; i < numSizes; i++) {
if (mSizeQueries[i]->Matches(pctx, nullptr)) {
break;
}
}
nscoord effectiveWidth;
if (i == numSizes) {
// No match defaults to 100% viewport
nsCSSValue defaultWidth(100.0f, eCSSUnit_ViewportWidth);
effectiveWidth = nsRuleNode::CalcLengthWithInitialFont(pctx,
defaultWidth);
if (doc->IsStyledByServo()) {
effectiveWidth = presShell->StyleSet()->AsServo()->EvaluateSourceSizeList(
mServoSourceSizeList.get());
} else {
effectiveWidth = nsRuleNode::CalcLengthWithInitialFont(pctx,
mSizeValues[i]);
unsigned int numSizes = mSizeQueries.Length();
MOZ_ASSERT(numSizes == mSizeValues.Length(),
"mSizeValues length differs from mSizeQueries");
unsigned int i;
for (i = 0; i < numSizes; i++) {
if (mSizeQueries[i]->Matches(pctx, nullptr)) {
break;
}
}
if (i == numSizes) {
// No match defaults to 100% viewport
nsCSSValue defaultWidth(100.0f, eCSSUnit_ViewportWidth);
effectiveWidth = nsRuleNode::CalcLengthWithInitialFont(pctx,
defaultWidth);
} else {
effectiveWidth = nsRuleNode::CalcLengthWithInitialFont(pctx,
mSizeValues[i]);
}
}
*aWidth = nsPresContext::AppUnitsToDoubleCSSPixels(std::max(effectiveWidth, 0));