зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1749825 - Make it possible for privileged script to opt elements into mousewheel autodir/honour root behaviour. r=botond
Differential Revision: https://phabricator.services.mozilla.com/D135914
This commit is contained in:
Родитель
1556e8b1ef
Коммит
038eb21cc2
|
@ -427,6 +427,16 @@ nsDOMWindowUtils::GetViewportFitInfo(nsAString& aViewportFit) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::SetMousewheelAutodir(Element* aElement, bool aEnabled,
|
||||
bool aHonourRoot) {
|
||||
aElement->SetProperty(nsGkAtoms::forceMousewheelAutodir,
|
||||
reinterpret_cast<void*>(aEnabled));
|
||||
aElement->SetProperty(nsGkAtoms::forceMousewheelAutodirHonourRoot,
|
||||
reinterpret_cast<void*>(aHonourRoot));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
|
||||
float aWidthPx, float aHeightPx,
|
||||
|
|
|
@ -2399,6 +2399,104 @@ function doTestAutoDirScroll2(aSettings, aAutoDirTrait,
|
|||
shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
|
||||
adjusted: true,
|
||||
expected: kAdjustedForLeft.result,
|
||||
cleanup (cb) {
|
||||
SpecialPowers.pushPrefEnv({"set":
|
||||
[["mousewheel.autodir.enabled",
|
||||
false]]},
|
||||
cb);
|
||||
} },
|
||||
// Tests: Test that autodir scrolling can be force-enabled using windowUtils.
|
||||
// This only tests vertical wheel scrolls being adjusted to be
|
||||
// horizontal, rather than re-testing all autodir behaviours just for
|
||||
// this way of enabling it.
|
||||
// Results: Vertical wheel scrolls are adjusted to be horizontal whereas the
|
||||
// horizontal wheel scrolls are unadjusted.
|
||||
// Reason: Auto-dir adjustment applies to a target if the target overflows
|
||||
// in only one direction and the direction is orthogonal to the
|
||||
// wheel and deltaZ is zero.
|
||||
{ description: "force-enabled auto-dir scroll to " + kAdjustedForDown.desc +
|
||||
"(originally bottom) by pixel scroll even if lineOrPageDelta is 0, " +
|
||||
"no vertical scrollbar",
|
||||
event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
|
||||
deltaX: 0.0, deltaY: 8.0, deltaZ: 0.0,
|
||||
lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
|
||||
expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
|
||||
shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
|
||||
adjusted: true,
|
||||
expected: kAdjustedForDown.result,
|
||||
prepare (cb) {
|
||||
gScrollableElement.style.overflowX = "auto";
|
||||
gScrollableElement.style.overflowY = "hidden";
|
||||
resetScrollPosition(gScrollableElement);
|
||||
winUtils.setMousewheelAutodir(gScrollableElement, true, kHonoursRoot)
|
||||
cb();
|
||||
} },
|
||||
{ description: "force-enabled auto-dir scroll to " + kAdjustedForDown.desc +
|
||||
"(originally bottom) by pixel scroll when lineOrPageDelta is 1, " +
|
||||
"no vertical scrollbar",
|
||||
event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
|
||||
deltaX: 0.0, deltaY: 8.0, deltaZ: 0.0,
|
||||
lineOrPageDeltaX: 0, lineOrPageDeltaY: 1, isMomentum: false,
|
||||
expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
|
||||
shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
|
||||
adjusted: true,
|
||||
expected: kAdjustedForDown.result },
|
||||
{ description: "force-enabled auto-dir scroll to " + kAdjustedForUp.desc +
|
||||
"(originally top) by pixel scroll even if lineOrPageDelta is 0, " +
|
||||
"no vertical scrollbar",
|
||||
event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
|
||||
deltaX: 0.0, deltaY: -8.0, deltaZ: 0.0,
|
||||
lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
|
||||
expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
|
||||
shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
|
||||
adjusted: true,
|
||||
expected: kAdjustedForUp.result },
|
||||
{ description: "force-enabled auto-dir scroll to " + kAdjustedForUp.desc +
|
||||
"(originally top) by pixel scroll when lineOrPageDelta is -1, " +
|
||||
"no vertical scrollbar",
|
||||
event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
|
||||
deltaX: 0.0, deltaY: -8.0, deltaZ: 0.0,
|
||||
lineOrPageDeltaX: 0, lineOrPageDeltaY: -1, isMomentum: false,
|
||||
expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
|
||||
shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
|
||||
adjusted: true,
|
||||
expected: kAdjustedForUp.result },
|
||||
{ description: "force-enabled auto-dir scroll to right by pixel scroll even if lineOrPageDelta is 0, " +
|
||||
"no vertical scrollbar",
|
||||
event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
|
||||
deltaX: 8.0, deltaY: 0.0, deltaZ: 0.0,
|
||||
lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
|
||||
expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
|
||||
shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
|
||||
adjusted: false,
|
||||
expected: kScrollRight },
|
||||
{ description: "force-enabled auto-dir scroll to right by pixel scroll when lineOrPageDelta is 1, " +
|
||||
"no vertical scrollbar",
|
||||
event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
|
||||
deltaX: 8.0, deltaY: 0.0, deltaZ: 0.0,
|
||||
lineOrPageDeltaX: 1, lineOrPageDeltaY: 0, isMomentum: false,
|
||||
expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
|
||||
shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
|
||||
adjusted: false,
|
||||
expected: kScrollRight },
|
||||
{ description: "force-enabled auto-dir scroll to left by pixel scroll even if lineOrPageDelta is 0, " +
|
||||
"no vertical scrollbar",
|
||||
event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
|
||||
deltaX: -8.0, deltaY: 0.0, deltaZ: 0.0,
|
||||
lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
|
||||
expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
|
||||
shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
|
||||
adjusted: false,
|
||||
expected: kScrollLeft },
|
||||
{ description: "force-enabled auto-dir scroll to left by pixel scroll when lineOrPageDelta is -1, " +
|
||||
"no vertical scrollbar",
|
||||
event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
|
||||
deltaX: -8.0, deltaY: 0.0, deltaZ: 0.0,
|
||||
lineOrPageDeltaX: -1, lineOrPageDeltaY: 0, isMomentum: false,
|
||||
expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
|
||||
shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
|
||||
adjusted: false,
|
||||
expected: kScrollLeft,
|
||||
cleanup (cb) {
|
||||
gScrollableElement.style.position = "static";
|
||||
gScrollableElement.style.top = "auto";
|
||||
|
@ -2406,11 +2504,9 @@ function doTestAutoDirScroll2(aSettings, aAutoDirTrait,
|
|||
gScrollableElement.style.overflow = "auto";
|
||||
Object.assign(document.body.style, kOldStyleForRoot);
|
||||
Object.assign(gScrollableElement.style, kOldStyleForTarget);
|
||||
SpecialPowers.pushPrefEnv({"set":
|
||||
[["mousewheel.autodir.enabled",
|
||||
false]]},
|
||||
cb);
|
||||
} },
|
||||
winUtils.setMousewheelAutodir(gScrollableElement, false, false);
|
||||
cb();
|
||||
} },
|
||||
];
|
||||
|
||||
let styleDescForRoot = "";
|
||||
|
|
|
@ -126,6 +126,17 @@ interface nsIDOMWindowUtils : nsISupports {
|
|||
*/
|
||||
void getContentViewerSize(out uint32_t aDisplayWidth, out uint32_t aDisplayHeight);
|
||||
|
||||
/**
|
||||
* For any scrollable element, this allows you to override the default
|
||||
* scroll behaviour and force autodir (which allows a mousewheel to
|
||||
* horizontally scroll regions that only scroll on that one axis).
|
||||
*
|
||||
* See the documentation for mousewheel.autodir.enabled and
|
||||
* mousewheel.autodir.honourroot for a more thorough explanation of
|
||||
* what these behaviours do.
|
||||
*/
|
||||
void setMousewheelAutodir(in Element aElement, in boolean aEnabled, in boolean aHonourRoot);
|
||||
|
||||
/**
|
||||
* For any scrollable element, this allows you to override the
|
||||
* visible region and draw more than what is visible, which is
|
||||
|
|
|
@ -806,6 +806,8 @@ struct ScrollMetadata {
|
|||
mIsRDMTouchSimulationActive(false),
|
||||
mDidContentGetPainted(true),
|
||||
mPrefersReducedMotion(false),
|
||||
mForceMousewheelAutodir(false),
|
||||
mForceMousewheelAutodirHonourRoot(false),
|
||||
mOverscrollBehavior() {}
|
||||
|
||||
bool operator==(const ScrollMetadata& aOther) const {
|
||||
|
@ -823,6 +825,9 @@ struct ScrollMetadata {
|
|||
mIsRDMTouchSimulationActive == aOther.mIsRDMTouchSimulationActive &&
|
||||
mDidContentGetPainted == aOther.mDidContentGetPainted &&
|
||||
mPrefersReducedMotion == aOther.mPrefersReducedMotion &&
|
||||
mForceMousewheelAutodir == aOther.mForceMousewheelAutodir &&
|
||||
mForceMousewheelAutodirHonourRoot ==
|
||||
aOther.mForceMousewheelAutodirHonourRoot &&
|
||||
mDisregardedDirection == aOther.mDisregardedDirection &&
|
||||
mOverscrollBehavior == aOther.mOverscrollBehavior &&
|
||||
mScrollUpdates == aOther.mScrollUpdates;
|
||||
|
@ -897,6 +902,18 @@ struct ScrollMetadata {
|
|||
void SetPrefersReducedMotion(bool aValue) { mPrefersReducedMotion = aValue; }
|
||||
bool PrefersReducedMotion() const { return mPrefersReducedMotion; }
|
||||
|
||||
void SetForceMousewheelAutodir(bool aValue) {
|
||||
mForceMousewheelAutodir = aValue;
|
||||
}
|
||||
bool ForceMousewheelAutodir() const { return mForceMousewheelAutodir; }
|
||||
|
||||
void SetForceMousewheelAutodirHonourRoot(bool aValue) {
|
||||
mForceMousewheelAutodirHonourRoot = aValue;
|
||||
}
|
||||
bool ForceMousewheelAutodirHonourRoot() const {
|
||||
return mForceMousewheelAutodirHonourRoot;
|
||||
}
|
||||
|
||||
bool DidContentGetPainted() const { return mDidContentGetPainted; }
|
||||
|
||||
private:
|
||||
|
@ -1007,6 +1024,11 @@ struct ScrollMetadata {
|
|||
// media query).
|
||||
bool mPrefersReducedMotion : 1;
|
||||
|
||||
// Whether privileged code has requested that autodir behaviour be
|
||||
// enabled for the scroll frame.
|
||||
bool mForceMousewheelAutodir : 1;
|
||||
bool mForceMousewheelAutodirHonourRoot : 1;
|
||||
|
||||
// The disregarded direction means the direction which is disregarded anyway,
|
||||
// even if the scroll frame overflows in that direction and the direction is
|
||||
// specified as scrollable. This could happen in some scenarios, for instance,
|
||||
|
|
|
@ -2128,12 +2128,13 @@ bool AsyncPanZoomController::CanScroll(const InputData& aEvent) const {
|
|||
// to checking if it is scrollable without adjusting its delta.
|
||||
// 2. For a non-auto-dir scroll, simply check if it is scrollable without
|
||||
// adjusting its delta.
|
||||
if (scrollWheelInput.IsAutoDir()) {
|
||||
if (scrollWheelInput.IsAutoDir(mScrollMetadata.ForceMousewheelAutodir())) {
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
auto deltaX = scrollWheelInput.mDeltaX;
|
||||
auto deltaY = scrollWheelInput.mDeltaY;
|
||||
bool isRTL =
|
||||
IsContentOfHonouredTargetRightToLeft(scrollWheelInput.HonoursRoot());
|
||||
IsContentOfHonouredTargetRightToLeft(scrollWheelInput.HonoursRoot(
|
||||
mScrollMetadata.ForceMousewheelAutodirHonourRoot()));
|
||||
APZAutoDirWheelDeltaAdjuster adjuster(deltaX, deltaY, mX, mY, isRTL);
|
||||
if (adjuster.ShouldBeAdjusted()) {
|
||||
// If we detect that the delta values should be adjusted for an auto-dir
|
||||
|
@ -2288,11 +2289,12 @@ nsEventStatus AsyncPanZoomController::OnScrollWheel(
|
|||
auto deltaX = aEvent.mDeltaX;
|
||||
auto deltaY = aEvent.mDeltaY;
|
||||
ParentLayerPoint delta;
|
||||
if (aEvent.IsAutoDir()) {
|
||||
if (aEvent.IsAutoDir(mScrollMetadata.ForceMousewheelAutodir())) {
|
||||
// It's an auto-dir scroll, so check if its delta should be adjusted, if so,
|
||||
// adjust it.
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
bool isRTL = IsContentOfHonouredTargetRightToLeft(aEvent.HonoursRoot());
|
||||
bool isRTL = IsContentOfHonouredTargetRightToLeft(
|
||||
aEvent.HonoursRoot(mScrollMetadata.ForceMousewheelAutodirHonourRoot()));
|
||||
APZAutoDirWheelDeltaAdjuster adjuster(deltaX, deltaY, mX, mY, isRTL);
|
||||
if (adjuster.ShouldBeAdjusted()) {
|
||||
adjuster.Adjust();
|
||||
|
@ -5048,6 +5050,10 @@ void AsyncPanZoomController::NotifyLayersUpdated(
|
|||
aScrollMetadata.GetIsRDMTouchSimulationActive());
|
||||
mScrollMetadata.SetPrefersReducedMotion(
|
||||
aScrollMetadata.PrefersReducedMotion());
|
||||
mScrollMetadata.SetForceMousewheelAutodir(
|
||||
aScrollMetadata.ForceMousewheelAutodir());
|
||||
mScrollMetadata.SetForceMousewheelAutodirHonourRoot(
|
||||
aScrollMetadata.ForceMousewheelAutodirHonourRoot());
|
||||
mScrollMetadata.SetDisregardedDirection(
|
||||
aScrollMetadata.GetDisregardedDirection());
|
||||
mScrollMetadata.SetOverscrollBehavior(
|
||||
|
|
|
@ -434,6 +434,8 @@ struct ParamTraits<mozilla::layers::ScrollMetadata>
|
|||
WriteParam(aMsg, aParam.mIsRDMTouchSimulationActive);
|
||||
WriteParam(aMsg, aParam.mDidContentGetPainted);
|
||||
WriteParam(aMsg, aParam.mPrefersReducedMotion);
|
||||
WriteParam(aMsg, aParam.mForceMousewheelAutodir);
|
||||
WriteParam(aMsg, aParam.mForceMousewheelAutodirHonourRoot);
|
||||
WriteParam(aMsg, aParam.mDisregardedDirection);
|
||||
WriteParam(aMsg, aParam.mOverscrollBehavior);
|
||||
WriteParam(aMsg, aParam.mScrollUpdates);
|
||||
|
@ -474,6 +476,11 @@ struct ParamTraits<mozilla::layers::ScrollMetadata>
|
|||
¶mType::SetDidContentGetPainted) &&
|
||||
ReadBoolForBitfield(aMsg, aIter, aResult,
|
||||
¶mType::SetPrefersReducedMotion) &&
|
||||
ReadBoolForBitfield(aMsg, aIter, aResult,
|
||||
¶mType::SetForceMousewheelAutodir) &&
|
||||
ReadBoolForBitfield(
|
||||
aMsg, aIter, aResult,
|
||||
¶mType::SetForceMousewheelAutodirHonourRoot) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mDisregardedDirection) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mOverscrollBehavior) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mScrollUpdates);
|
||||
|
|
|
@ -8570,6 +8570,18 @@ ScrollMetadata nsLayoutUtils::ComputeScrollMetadata(
|
|||
}
|
||||
}
|
||||
|
||||
// Note: GetProperty() will return nullptr both in the case where
|
||||
// the property hasn't been set, and in the case where the property
|
||||
// has been set to false (in which case the property value is
|
||||
// `reinterpret_cast<void*>(false)` which is nullptr.
|
||||
if (aContent->GetProperty(nsGkAtoms::forceMousewheelAutodir)) {
|
||||
metadata.SetForceMousewheelAutodir(true);
|
||||
}
|
||||
|
||||
if (aContent->GetProperty(nsGkAtoms::forceMousewheelAutodirHonourRoot)) {
|
||||
metadata.SetForceMousewheelAutodirHonourRoot(true);
|
||||
}
|
||||
|
||||
if (IsAPZTestLoggingEnabled()) {
|
||||
LogTestDataForPaint(aLayerManager, scrollId, "displayport",
|
||||
metrics.GetDisplayPort());
|
||||
|
|
|
@ -698,7 +698,11 @@ class ScrollWheelInput : public InputData {
|
|||
|
||||
// The following two functions are for auto-dir scrolling. For detailed
|
||||
// information on auto-dir, @see mozilla::WheelDeltaAdjustmentStrategy
|
||||
bool IsAutoDir() const {
|
||||
bool IsAutoDir(bool aForce = false) const {
|
||||
if (aForce) {
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (mWheelDeltaAdjustmentStrategy) {
|
||||
case WheelDeltaAdjustmentStrategy::eAutoDir:
|
||||
case WheelDeltaAdjustmentStrategy::eAutoDirWithRootHonour:
|
||||
|
@ -717,9 +721,10 @@ class ScrollWheelInput : public InputData {
|
|||
// not an auto-dir scroll.
|
||||
// For detailed information on auto-dir,
|
||||
// @see mozilla::WheelDeltaAdjustmentStrategy
|
||||
bool HonoursRoot() const {
|
||||
bool HonoursRoot(bool aForce = false) const {
|
||||
return WheelDeltaAdjustmentStrategy::eAutoDirWithRootHonour ==
|
||||
mWheelDeltaAdjustmentStrategy;
|
||||
mWheelDeltaAdjustmentStrategy ||
|
||||
aForce;
|
||||
}
|
||||
|
||||
// Warning, this class is serialized and sent over IPC. Any change to its
|
||||
|
|
|
@ -2202,6 +2202,8 @@ STATIC_ATOMS = [
|
|||
Atom("DisplayPortMargins", "_displayportmargins"),
|
||||
Atom("DisplayPortBase", "_displayportbase"),
|
||||
Atom("MinimalDisplayPort", "_minimaldisplayport"),
|
||||
Atom("forceMousewheelAutodir", "_force_mousewheel_autodir"),
|
||||
Atom("forceMousewheelAutodirHonourRoot", "_force_mousewheel_autodir_honourroot"),
|
||||
Atom("forcemessagemanager", "forcemessagemanager"),
|
||||
Atom("initialBrowsingContextGroupId", "initialBrowsingContextGroupId"),
|
||||
Atom("initiallyactive", "initiallyactive"),
|
||||
|
|
Загрузка…
Ссылка в новой задаче