mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 16:55:40 +00:00
Bug 1423017 - Add a telemetry for out-of-reach overflowing on root. r=botond
MozReview-Commit-ID: 2CyZTVBFP59 --HG-- extra : rebase_source : 69792750af013f33ca9efd01c1d19013b0b26456
This commit is contained in:
parent
8c597aa3d1
commit
51044f283f
@ -1497,6 +1497,7 @@ nsIDocument::nsIDocument()
|
|||||||
mStackRefCnt(0),
|
mStackRefCnt(0),
|
||||||
mUpdateNestLevel(0),
|
mUpdateNestLevel(0),
|
||||||
mViewportType(Unknown),
|
mViewportType(Unknown),
|
||||||
|
mViewportOverflowType(ViewportOverflowType::NoOverflow),
|
||||||
mSubDocuments(nullptr),
|
mSubDocuments(nullptr),
|
||||||
mHeaderData(nullptr),
|
mHeaderData(nullptr),
|
||||||
mFlashClassification(FlashClassification::Unclassified),
|
mFlashClassification(FlashClassification::Unclassified),
|
||||||
@ -3690,6 +3691,7 @@ nsIDocument::SetHeaderData(nsAtom* aHeaderField, const nsAString& aData)
|
|||||||
aHeaderField == nsGkAtoms::viewport_width ||
|
aHeaderField == nsGkAtoms::viewport_width ||
|
||||||
aHeaderField == nsGkAtoms::viewport_user_scalable) {
|
aHeaderField == nsGkAtoms::viewport_user_scalable) {
|
||||||
mViewportType = Unknown;
|
mViewportType = Unknown;
|
||||||
|
mViewportOverflowType = ViewportOverflowType::NoOverflow;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Referrer policy spec says to ignore any empty referrer policies.
|
// Referrer policy spec says to ignore any empty referrer policies.
|
||||||
@ -7237,6 +7239,7 @@ nsIDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
|
|||||||
mValidMaxScale = !maxScaleStr.IsEmpty() && NS_SUCCEEDED(scaleMaxErrorCode);
|
mValidMaxScale = !maxScaleStr.IsEmpty() && NS_SUCCEEDED(scaleMaxErrorCode);
|
||||||
|
|
||||||
mViewportType = Specified;
|
mViewportType = Specified;
|
||||||
|
mViewportOverflowType = ViewportOverflowType::NoOverflow;
|
||||||
MOZ_FALLTHROUGH;
|
MOZ_FALLTHROUGH;
|
||||||
}
|
}
|
||||||
case Specified:
|
case Specified:
|
||||||
@ -7318,6 +7321,54 @@ nsIDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsIDocument::UpdateViewportOverflowType(nscoord aScrolledWidth,
|
||||||
|
nscoord aScrollportWidth)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
MOZ_ASSERT(mPresShell);
|
||||||
|
nsPresContext* pc = GetPresContext();
|
||||||
|
MOZ_ASSERT(pc->GetViewportScrollbarStylesOverride().mHorizontal ==
|
||||||
|
NS_STYLE_OVERFLOW_HIDDEN,
|
||||||
|
"Should only be called when viewport has overflow-x: hidden");
|
||||||
|
MOZ_ASSERT(aScrolledWidth > aScrollportWidth,
|
||||||
|
"Should only be called when viewport is overflowed");
|
||||||
|
MOZ_ASSERT(IsTopLevelContentDocument(),
|
||||||
|
"Should only be called for top-level content document");
|
||||||
|
#endif // DEBUG
|
||||||
|
|
||||||
|
if (!gfxPrefs::MetaViewportEnabled() ||
|
||||||
|
(GetWindow() && GetWindow()->IsDesktopModeViewport())) {
|
||||||
|
mViewportOverflowType = ViewportOverflowType::Desktop;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const LayoutDeviceToScreenScale
|
||||||
|
kBlinkDefaultMinScale = LayoutDeviceToScreenScale(0.25f);
|
||||||
|
LayoutDeviceToScreenScale minScale;
|
||||||
|
if (mViewportType == DisplayWidthHeight) {
|
||||||
|
minScale = kBlinkDefaultMinScale;
|
||||||
|
} else {
|
||||||
|
MOZ_ASSERT(mViewportType == Specified,
|
||||||
|
"Viewport information should have been initialized");
|
||||||
|
if (mScaleMinFloat == kViewportMinScale) {
|
||||||
|
minScale = kBlinkDefaultMinScale;
|
||||||
|
} else {
|
||||||
|
minScale = mScaleMinFloat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the content has overflowed with minimum scale applied, don't
|
||||||
|
// change it, otherwise update the overflow type.
|
||||||
|
if (mViewportOverflowType != ViewportOverflowType::MinScaleSize) {
|
||||||
|
if (aScrolledWidth * minScale.scale < aScrollportWidth) {
|
||||||
|
mViewportOverflowType = ViewportOverflowType::ButNotMinScaleSize;
|
||||||
|
} else {
|
||||||
|
mViewportOverflowType = ViewportOverflowType::MinScaleSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EventListenerManager*
|
EventListenerManager*
|
||||||
nsDocument::GetOrCreateListenerManager()
|
nsDocument::GetOrCreateListenerManager()
|
||||||
{
|
{
|
||||||
@ -12132,6 +12183,23 @@ nsIDocument::ReportUseCounters(UseCounterReportKind aKind)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsTopLevelContentDocument() && !IsResourceDoc()) {
|
||||||
|
using mozilla::Telemetry::LABELS_HIDDEN_VIEWPORT_OVERFLOW_TYPE;
|
||||||
|
LABELS_HIDDEN_VIEWPORT_OVERFLOW_TYPE label;
|
||||||
|
switch (mViewportOverflowType) {
|
||||||
|
#define CASE_OVERFLOW_TYPE(t_) \
|
||||||
|
case ViewportOverflowType::t_: \
|
||||||
|
label = LABELS_HIDDEN_VIEWPORT_OVERFLOW_TYPE::t_; \
|
||||||
|
break;
|
||||||
|
CASE_OVERFLOW_TYPE(NoOverflow)
|
||||||
|
CASE_OVERFLOW_TYPE(Desktop)
|
||||||
|
CASE_OVERFLOW_TYPE(ButNotMinScaleSize)
|
||||||
|
CASE_OVERFLOW_TYPE(MinScaleSize)
|
||||||
|
#undef CASE_OVERFLOW_TYPE
|
||||||
|
}
|
||||||
|
Telemetry::AccumulateCategorical(label);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1199,6 +1199,17 @@ public:
|
|||||||
*/
|
*/
|
||||||
nsViewportInfo GetViewportInfo(const mozilla::ScreenIntSize& aDisplaySize);
|
nsViewportInfo GetViewportInfo(const mozilla::ScreenIntSize& aDisplaySize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* It updates the viewport overflow type with the given two widths
|
||||||
|
* and the viewport setting of the document.
|
||||||
|
* This should only be called when there is out-of-reach overflow
|
||||||
|
* happens on the viewport, i.e. the viewport should be using
|
||||||
|
* `overflow: hidden`. And it should only be called on a top level
|
||||||
|
* content document.
|
||||||
|
*/
|
||||||
|
void UpdateViewportOverflowType(nscoord aScrolledWidth,
|
||||||
|
nscoord aScrollportWidth);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True iff this doc will ignore manual character encoding overrides.
|
* True iff this doc will ignore manual character encoding overrides.
|
||||||
*/
|
*/
|
||||||
@ -4271,7 +4282,7 @@ protected:
|
|||||||
// Our update nesting level
|
// Our update nesting level
|
||||||
uint32_t mUpdateNestLevel;
|
uint32_t mUpdateNestLevel;
|
||||||
|
|
||||||
enum ViewportType {
|
enum ViewportType : uint8_t {
|
||||||
DisplayWidthHeight,
|
DisplayWidthHeight,
|
||||||
Specified,
|
Specified,
|
||||||
Unknown
|
Unknown
|
||||||
@ -4279,6 +4290,30 @@ protected:
|
|||||||
|
|
||||||
ViewportType mViewportType;
|
ViewportType mViewportType;
|
||||||
|
|
||||||
|
// Enum for how content in this document overflows viewport causing
|
||||||
|
// out-of-reach issue. Currently it only takes horizontal overflow
|
||||||
|
// into consideration. This enum and the corresponding field is only
|
||||||
|
// set and read on a top level content document.
|
||||||
|
enum class ViewportOverflowType : uint8_t {
|
||||||
|
// Viewport doesn't have out-of-reach overflow content, either
|
||||||
|
// because the content doesn't overflow, or the viewport doesn't
|
||||||
|
// have "overflow: hidden".
|
||||||
|
NoOverflow,
|
||||||
|
|
||||||
|
// All following items indicates that the content overflows the
|
||||||
|
// scroll port which causing out-of-reach content.
|
||||||
|
|
||||||
|
// Meta viewport is disabled or the document is in desktop mode.
|
||||||
|
Desktop,
|
||||||
|
// The content does not overflow the minimum-scale size. When there
|
||||||
|
// is no minimum scale specified, the default value used by Blink,
|
||||||
|
// 0.25, is used for this matter.
|
||||||
|
ButNotMinScaleSize,
|
||||||
|
// The content overflows the minimum-scale size.
|
||||||
|
MinScaleSize,
|
||||||
|
};
|
||||||
|
ViewportOverflowType mViewportOverflowType;
|
||||||
|
|
||||||
PLDHashTable* mSubDocuments;
|
PLDHashTable* mSubDocuments;
|
||||||
|
|
||||||
nsDocHeaderData* mHeaderData;
|
nsDocHeaderData* mHeaderData;
|
||||||
|
@ -395,12 +395,12 @@ nsHTMLScrollFrame::TryLayout(ScrollReflowInput* aState,
|
|||||||
std::max(0, compositionSize.height - hScrollbarDesiredHeight));
|
std::max(0, compositionSize.height - hScrollbarDesiredHeight));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!aForce) {
|
nsRect scrolledRect =
|
||||||
nsRect scrolledRect =
|
mHelper.GetUnsnappedScrolledRectInternal(aState->mContentsOverflowAreas.ScrollableOverflow(),
|
||||||
mHelper.GetUnsnappedScrolledRectInternal(aState->mContentsOverflowAreas.ScrollableOverflow(),
|
scrollPortSize);
|
||||||
scrollPortSize);
|
nscoord oneDevPixel = aState->mBoxState.PresContext()->DevPixelsToAppUnits(1);
|
||||||
nscoord oneDevPixel = aState->mBoxState.PresContext()->DevPixelsToAppUnits(1);
|
|
||||||
|
|
||||||
|
if (!aForce) {
|
||||||
// If the style is HIDDEN then we already know that aAssumeHScroll is false
|
// If the style is HIDDEN then we already know that aAssumeHScroll is false
|
||||||
if (aState->mStyles.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN) {
|
if (aState->mStyles.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN) {
|
||||||
bool wantHScrollbar =
|
bool wantHScrollbar =
|
||||||
@ -426,6 +426,31 @@ nsHTMLScrollFrame::TryLayout(ScrollReflowInput* aState,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (!mHelper.mIsRoot) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Check whether there is actually any overflow.
|
||||||
|
nscoord scrolledWidth = scrolledRect.width + oneDevPixel;
|
||||||
|
if (scrolledWidth <= scrollPortSize.width) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Viewport scrollbar style is used below instead of aState->mStyles
|
||||||
|
// because the latter can be affected by various factors, while we
|
||||||
|
// only care about what the page itself specifies.
|
||||||
|
nsPresContext* pc = PresContext();
|
||||||
|
ScrollbarStyles styles = pc->GetViewportScrollbarStylesOverride();
|
||||||
|
if (styles.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Only top level content document is considered.
|
||||||
|
nsIDocument* doc = pc->Document();
|
||||||
|
if (!doc->IsTopLevelContentDocument()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
doc->UpdateViewportOverflowType(scrolledWidth, scrollPortSize.width);
|
||||||
|
} while (false);
|
||||||
|
|
||||||
nscoord vScrollbarActualWidth = aState->mInsideBorderSize.width - scrollPortSize.width;
|
nscoord vScrollbarActualWidth = aState->mInsideBorderSize.width - scrollPortSize.width;
|
||||||
|
|
||||||
aState->mShowHScrollbar = aAssumeHScroll;
|
aState->mShowHScrollbar = aAssumeHScroll;
|
||||||
|
@ -13804,5 +13804,14 @@
|
|||||||
"high": 50,
|
"high": 50,
|
||||||
"n_buckets": 20,
|
"n_buckets": 20,
|
||||||
"description": "Total number of doc groups per tab group, including docgroups fully in bfcache. Collected at the point when the top level document of the tab group is unloaded."
|
"description": "Total number of doc groups per tab group, including docgroups fully in bfcache. Collected at the point when the top level document of the tab group is unloaded."
|
||||||
|
},
|
||||||
|
"HIDDEN_VIEWPORT_OVERFLOW_TYPE": {
|
||||||
|
"record_in_processes": ["content"],
|
||||||
|
"alert_emails": ["xquan@mozilla.com", "botond@mozilla.com"],
|
||||||
|
"bug_numbers": [1423013, 1423017],
|
||||||
|
"expires_in_version": "65",
|
||||||
|
"kind": "categorical",
|
||||||
|
"labels": ["NoOverflow", "Desktop", "ButNotMinScaleSize", "MinScaleSize"],
|
||||||
|
"description": "How common are different types of out-of-reach viewport overflow?"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user