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:
@@ -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;
|
||||
nsIPresShell* shell = doc->GetShell();
|
||||
nsPresContext* pctx = shell ? shell->GetPresContext() : nullptr;
|
||||
nsCOMPtr<nsIURI> baseURI = mOwnerNode ? mOwnerNode->GetBaseURI() : 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,15 +447,19 @@ ResponsiveImageSelector::GetSelectedCandidateIndex()
|
||||
bool
|
||||
ResponsiveImageSelector::ComputeFinalWidthForCurrentViewport(double *aWidth)
|
||||
{
|
||||
unsigned int numSizes = mSizeQueries.Length();
|
||||
nsIDocument* doc = Document();
|
||||
nsIPresShell *presShell = doc ? doc->GetShell() : nullptr;
|
||||
nsIPresShell* presShell = doc->GetShell();
|
||||
nsPresContext* pctx = presShell ? presShell->GetPresContext() : nullptr;
|
||||
|
||||
if (!pctx) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nscoord effectiveWidth;
|
||||
if (doc->IsStyledByServo()) {
|
||||
effectiveWidth = presShell->StyleSet()->AsServo()->EvaluateSourceSizeList(
|
||||
mServoSourceSizeList.get());
|
||||
} else {
|
||||
unsigned int numSizes = mSizeQueries.Length();
|
||||
MOZ_ASSERT(numSizes == mSizeValues.Length(),
|
||||
"mSizeValues length differs from mSizeQueries");
|
||||
|
||||
@@ -458,7 +470,6 @@ ResponsiveImageSelector::ComputeFinalWidthForCurrentViewport(double *aWidth)
|
||||
}
|
||||
}
|
||||
|
||||
nscoord effectiveWidth;
|
||||
if (i == numSizes) {
|
||||
// No match defaults to 100% viewport
|
||||
nsCSSValue defaultWidth(100.0f, eCSSUnit_ViewportWidth);
|
||||
@@ -468,6 +479,7 @@ ResponsiveImageSelector::ComputeFinalWidthForCurrentViewport(double *aWidth)
|
||||
effectiveWidth = nsRuleNode::CalcLengthWithInitialFont(pctx,
|
||||
mSizeValues[i]);
|
||||
}
|
||||
}
|
||||
|
||||
*aWidth = nsPresContext::AppUnitsToDoubleCSSPixels(std::max(effectiveWidth, 0));
|
||||
return true;
|
||||
|
||||
@@ -120,6 +120,10 @@ private:
|
||||
// resolve the absolute URL at selection time
|
||||
nsCOMPtr<nsIURI> mSelectedCandidateURL;
|
||||
|
||||
// Servo bits.
|
||||
UniquePtr<RawServoSourceSizeList> mServoSourceSizeList;
|
||||
|
||||
// Gecko bits.
|
||||
nsTArray< nsAutoPtr<nsMediaQuery> > mSizeQueries;
|
||||
nsTArray<nsCSSValue> mSizeValues;
|
||||
};
|
||||
|
||||
@@ -134,6 +134,13 @@ SERVO_BINDING_FUNC(Servo_SelectorList_Drop, void,
|
||||
SERVO_BINDING_FUNC(Servo_SelectorList_Parse,
|
||||
RawServoSelectorList*,
|
||||
const nsACString* selector_list)
|
||||
SERVO_BINDING_FUNC(Servo_SourceSizeList_Parse,
|
||||
RawServoSourceSizeList*,
|
||||
const nsACString* value)
|
||||
SERVO_BINDING_FUNC(Servo_SourceSizeList_Evaluate,
|
||||
int32_t,
|
||||
RawServoStyleSetBorrowed set,
|
||||
RawServoSourceSizeListBorrowedOrNull)
|
||||
SERVO_BINDING_FUNC(Servo_SelectorList_Matches, bool,
|
||||
RawGeckoElementBorrowed, RawServoSelectorListBorrowed)
|
||||
SERVO_BINDING_FUNC(Servo_SelectorList_Closest, const RawGeckoElement*,
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
struct RawServoStyleSet;
|
||||
struct RawServoSelectorList;
|
||||
struct RawServoSourceSizeList;
|
||||
struct RawServoAnimationValueMap;
|
||||
struct RustString;
|
||||
|
||||
@@ -182,6 +183,9 @@ DECL_BORROWED_REF_TYPE_FOR(nsXBLBinding)
|
||||
DECL_BORROWED_MUT_REF_TYPE_FOR(RawGeckoStyleChildrenIterator)
|
||||
DECL_OWNED_REF_TYPE_FOR(RawServoSelectorList)
|
||||
DECL_BORROWED_REF_TYPE_FOR(RawServoSelectorList)
|
||||
DECL_OWNED_REF_TYPE_FOR(RawServoSourceSizeList)
|
||||
DECL_BORROWED_REF_TYPE_FOR(RawServoSourceSizeList)
|
||||
DECL_NULLABLE_BORROWED_REF_TYPE_FOR(RawServoSourceSizeList)
|
||||
|
||||
#undef DECL_ARC_REF_TYPE_FOR
|
||||
#undef DECL_OWNED_REF_TYPE_FOR
|
||||
@@ -225,6 +229,7 @@ DECL_BORROWED_REF_TYPE_FOR(RawServoSelectorList)
|
||||
|
||||
DEFINE_BOXED_TYPE(StyleSet, RawServoStyleSet);
|
||||
DEFINE_BOXED_TYPE(SelectorList, RawServoSelectorList);
|
||||
DEFINE_BOXED_TYPE(SourceSizeList, RawServoSourceSizeList);
|
||||
|
||||
#undef DEFINE_BOXED_TYPE
|
||||
|
||||
|
||||
@@ -495,6 +495,7 @@ structs-types = [
|
||||
"RawGeckoURLExtraData",
|
||||
"RawGeckoXBLBinding",
|
||||
"RawServoSelectorList",
|
||||
"RawServoSourceSizeList",
|
||||
"RefPtr",
|
||||
"RustString",
|
||||
"CSSPseudoClassType",
|
||||
@@ -608,6 +609,7 @@ array-types = [
|
||||
servo-owned-types = [
|
||||
{ name = "RawServoStyleSet", opaque = true },
|
||||
{ name = "RawServoSelectorList", opaque = false },
|
||||
{ name = "RawServoSourceSizeList", opaque = false },
|
||||
{ name = "ServoElementSnapshot", opaque = false },
|
||||
{ name = "RawServoAnimationValueMap", opaque = true },
|
||||
]
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "mozilla/PostTraversalTask.h"
|
||||
#include "mozilla/ServoBindingTypes.h"
|
||||
#include "mozilla/ServoElementSnapshot.h"
|
||||
#include "mozilla/ServoBindings.h"
|
||||
#include "mozilla/ServoUtils.h"
|
||||
#include "mozilla/StyleSheetInlines.h"
|
||||
#include "mozilla/SheetType.h"
|
||||
@@ -150,6 +151,15 @@ public:
|
||||
|
||||
nsRestyleHint MediumFeaturesChanged(bool aViewportChanged);
|
||||
|
||||
// Evaluates a given SourceSizeList, returning the optimal viewport width in
|
||||
// app units.
|
||||
//
|
||||
// The SourceSizeList parameter can be null, in which case it will return
|
||||
// 100vw.
|
||||
nscoord EvaluateSourceSizeList(const RawServoSourceSizeList* aSourceSizeList) const {
|
||||
return Servo_SourceSizeList_Evaluate(mRawSet.get(), aSourceSizeList);
|
||||
}
|
||||
|
||||
// aViewportChanged outputs whether any viewport units is used.
|
||||
bool MediumFeaturesChangedRules(bool* aViewportUnitsUsed);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user