зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1486971 - Test for dynamically change of the prefers-reduced-motion setting on MacOSX. r=froydnj,mstange
The framework to simulate the setting change works as following; - nsIDOMWindowUtils.setPrefersReducedMotion() calls an IPC function which ends up calling nsChildView::SetPrefersReducedMotion() in the parent process - nsChildView::SetPrefersReducedMotion() sets the given value into nsLookAndFeel::mPrefersReducedMotionCached just like we set the value queried via NSWorkspace.accessibilityDisplayShouldReduceMotion in the parent process and send a notification which is the same notification MacOSX sends when the system setting changed - Normally the cached value is cleared before quering new values since the cache value is stale, but in this case the value is up-to-date one, so nsChildView::SetPrefersReducedMotion() tells that we don't need to clear the cache, and nsIDOMWindowUtils.resetPrefersReducedMotion() resets that state of 'we don't need to clear the cache' There are two test cases with the framework in this commit, one is just setting the value and checking the value queried by window.matchMedia. The other one is receiving 'change' event and checking the value of the event target. Note that to make this test works the patch for bug 1478212 is necessary since the test runs in an iframe. Depends on D5003 Differential Revision: https://phabricator.services.mozilla.com/D5004 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
1683335036
Коммит
5f958f80c7
|
@ -4361,6 +4361,28 @@ nsDOMWindowUtils::EnsureDirtyRootFrame()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::SetPrefersReducedMotionOverrideForTest(bool aValue)
|
||||
{
|
||||
nsIWidget* widget = GetWidget();
|
||||
if (!widget) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return widget->SetPrefersReducedMotionOverrideForTest(aValue);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::ResetPrefersReducedMotionOverrideForTest()
|
||||
{
|
||||
nsIWidget* widget = GetWidget();
|
||||
if (!widget) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return widget->ResetPrefersReducedMotionOverrideForTest();
|
||||
}
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsTranslationNodeList)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_ENTRY(nsITranslationNodeList)
|
||||
|
|
|
@ -1940,6 +1940,19 @@ interface nsIDOMWindowUtils : nsISupports {
|
|||
*/
|
||||
attribute ACString systemFont;
|
||||
|
||||
|
||||
/**
|
||||
* Simulate the system setting corresponding to 'prefers-reduced-motion'
|
||||
* media queries feature is changed to 'on' or 'off'.
|
||||
*
|
||||
* Currently this function is available only on MacOSX.
|
||||
*/
|
||||
void setPrefersReducedMotionOverrideForTest(in boolean aValue);
|
||||
/**
|
||||
* Reset the internal state to be used for above setPrefersReducedMotion.
|
||||
*/
|
||||
void resetPrefersReducedMotionOverrideForTest();
|
||||
|
||||
// These consts are only for testing purposes.
|
||||
const long DEFAULT_MOUSE_POINTER_ID = 0;
|
||||
const long DEFAULT_PEN_POINTER_ID = 1;
|
||||
|
|
|
@ -579,6 +579,9 @@ parent:
|
|||
sync SetSystemFont(nsCString aFontName);
|
||||
sync GetSystemFont() returns (nsCString retval);
|
||||
|
||||
sync SetPrefersReducedMotionOverrideForTest(bool aValue);
|
||||
sync ResetPrefersReducedMotionOverrideForTest();
|
||||
|
||||
child:
|
||||
/**
|
||||
* Notify the remote browser that it has been Show()n on this
|
||||
|
|
|
@ -1567,6 +1567,26 @@ TabParent::RecvClearNativeTouchSequence(const uint64_t& aObserverId)
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabParent::RecvSetPrefersReducedMotionOverrideForTest(const bool& aValue)
|
||||
{
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (widget) {
|
||||
widget->SetPrefersReducedMotionOverrideForTest(aValue);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabParent::RecvResetPrefersReducedMotionOverrideForTest()
|
||||
{
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (widget) {
|
||||
widget->ResetPrefersReducedMotionOverrideForTest();
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void
|
||||
TabParent::SendRealKeyEvent(WidgetKeyboardEvent& aEvent)
|
||||
{
|
||||
|
|
|
@ -417,6 +417,11 @@ public:
|
|||
virtual mozilla::ipc::IPCResult
|
||||
RecvClearNativeTouchSequence(const uint64_t& aObserverId) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvSetPrefersReducedMotionOverrideForTest(const bool& aValue) override;
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvResetPrefersReducedMotionOverrideForTest() override;
|
||||
|
||||
void SendMouseEvent(const nsAString& aType, float aX, float aY,
|
||||
int32_t aButton, int32_t aClickCount,
|
||||
int32_t aModifiers, bool aIgnoreRootScrollFrame);
|
||||
|
|
|
@ -842,6 +842,10 @@ description =
|
|||
description = test only
|
||||
[PBrowser::GetSystemFont]
|
||||
description = test only
|
||||
[PBrowser::SetPrefersReducedMotionOverrideForTest]
|
||||
description = test only
|
||||
[PBrowser::ResetPrefersReducedMotionOverrideForTest]
|
||||
description = test only
|
||||
[PContent::SyncMessage]
|
||||
description =
|
||||
[PContent::CreateChildProcess]
|
||||
|
|
|
@ -259,6 +259,8 @@ skip-if = android_version == '18' #debug-only failure; timed out #Android 4.3 aw
|
|||
[test_media_query_serialization.html]
|
||||
[test_mq_any_hover_and_any_pointer.html]
|
||||
[test_mq_hover_and_pointer.html]
|
||||
[test_mq_prefers_reduced_motion_dynamic.html]
|
||||
run-if = os == 'mac' # Currently the test works on only MacOSX
|
||||
[test_moz_device_pixel_ratio.html]
|
||||
[test_namespace_rule.html]
|
||||
[test_non_content_accessible_properties.html]
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1486971
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 1478519</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script src="/tests/SimpleTest/AddTask.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1486971">Mozilla Bug 1486971</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
async function waitForFrame() {
|
||||
return new Promise(resolve => {
|
||||
window.requestAnimationFrame(resolve);
|
||||
});
|
||||
}
|
||||
|
||||
// Returns a Promise which will be resolved when the 'change' event is received
|
||||
// for the given media query string.
|
||||
async function promiseForChange(mediaQuery) {
|
||||
return new Promise(resolve => {
|
||||
window.matchMedia(mediaQuery).addEventListener('change', event => {
|
||||
resolve(event.matches);
|
||||
}, { once: true });
|
||||
});
|
||||
}
|
||||
|
||||
add_task(async () => {
|
||||
SpecialPowers.DOMWindowUtils.setPrefersReducedMotionOverrideForTest(false);
|
||||
|
||||
// Need to wait a frame since MediaQuery changes are asynchronously processed.
|
||||
await waitForFrame();
|
||||
|
||||
ok(!window.matchMedia('(prefers-reduced-motion: reduce)').matches,
|
||||
'Does not matches prefers-reduced-motion: reduced) when the system sets ' +
|
||||
'prefers-reduced-motion false');
|
||||
ok(!window.matchMedia('(prefers-reduced-motion)').matches,
|
||||
'Does not matches (prefers-reduced-motion) when the system sets ' +
|
||||
'prefers-reduced-motion false');
|
||||
ok(window.matchMedia('(prefers-reduced-motion: no-preference)').matches,
|
||||
'Matches (prefers-reduced-motion: no-preference) when the system sets ' +
|
||||
'prefers-reduced-motion false');
|
||||
});
|
||||
|
||||
add_task(async () => {
|
||||
const reduce = promiseForChange('(prefers-reduced-motion: reduce)');
|
||||
const booleanContext = promiseForChange('(prefers-reduced-motion)');
|
||||
const noPreference = promiseForChange('(prefers-reduced-motion: no-preference)');
|
||||
|
||||
SpecialPowers.DOMWindowUtils.setPrefersReducedMotionOverrideForTest(true);
|
||||
|
||||
const [ reduceResult, booleanContextResult, noPreferenceResult ] =
|
||||
await Promise.all([ reduce, booleanContext, noPreference ]);
|
||||
|
||||
ok(reduceResult,
|
||||
'Matches (prefers-reduced-motion: reduced) when the system sets ' +
|
||||
'prefers-reduced-motion true');
|
||||
ok(booleanContextResult,
|
||||
'Matches (prefers-reduced-motion) when the system sets ' +
|
||||
'prefers-reduced-motion true');
|
||||
ok(!noPreferenceResult,
|
||||
'Does not matches (prefers-reduced-motion: no-preference) when the ' +
|
||||
'system sets prefers-reduced-motion true');
|
||||
|
||||
SpecialPowers.DOMWindowUtils.resetPrefersReducedMotionOverrideForTest();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -687,6 +687,11 @@ public:
|
|||
*/
|
||||
static nsTArray<LookAndFeelInt> GetIntCache();
|
||||
static void SetIntCache(const nsTArray<LookAndFeelInt>& aLookAndFeelIntCache);
|
||||
/**
|
||||
* Set a flag indicating whether the cache should be cleared in RefreshImpl()
|
||||
* or not.
|
||||
*/
|
||||
static void SetShouldRetainCacheForTest(bool aValue);
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -1568,5 +1568,27 @@ PuppetWidget::GetSystemFont(nsCString& aFontName)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PuppetWidget::SetPrefersReducedMotionOverrideForTest(bool aValue)
|
||||
{
|
||||
if (!mTabChild) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mTabChild->SendSetPrefersReducedMotionOverrideForTest(aValue);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PuppetWidget::ResetPrefersReducedMotionOverrideForTest()
|
||||
{
|
||||
if (!mTabChild) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mTabChild->SendResetPrefersReducedMotionOverrideForTest();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -314,6 +314,9 @@ public:
|
|||
nsresult SetSystemFont(const nsCString& aFontName) override;
|
||||
nsresult GetSystemFont(nsCString& aFontName) override;
|
||||
|
||||
nsresult SetPrefersReducedMotionOverrideForTest(bool aValue) override;
|
||||
nsresult ResetPrefersReducedMotionOverrideForTest() override;
|
||||
|
||||
// TextEventDispatcherListener
|
||||
using nsBaseWidget::NotifyIME;
|
||||
NS_IMETHOD NotifyIME(TextEventDispatcher* aTextEventDispatcher,
|
||||
|
|
|
@ -549,6 +549,9 @@ public:
|
|||
|
||||
void SwipeFinished();
|
||||
|
||||
nsresult SetPrefersReducedMotionOverrideForTest(bool aValue) override;
|
||||
nsresult ResetPrefersReducedMotionOverrideForTest() override;
|
||||
|
||||
protected:
|
||||
virtual ~nsChildView();
|
||||
|
||||
|
|
|
@ -3097,6 +3097,42 @@ nsChildView::LookUpDictionary(
|
|||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsChildView::SetPrefersReducedMotionOverrideForTest(bool aValue)
|
||||
{
|
||||
// Tell that the cache value we are going to set isn't cleared via
|
||||
// nsPresContext::ThemeChangedInternal which is called right before
|
||||
// we queue the media feature value change for this prefers-reduced-motion
|
||||
// change.
|
||||
LookAndFeel::SetShouldRetainCacheForTest(true);
|
||||
|
||||
LookAndFeelInt prefersReducedMotion;
|
||||
prefersReducedMotion.id = LookAndFeel::eIntID_PrefersReducedMotion;
|
||||
prefersReducedMotion.value = aValue ? 1 : 0;
|
||||
|
||||
AutoTArray<LookAndFeelInt, 1> lookAndFeelCache;
|
||||
lookAndFeelCache.AppendElement(prefersReducedMotion);
|
||||
|
||||
// If we could have a way to modify
|
||||
// NSWorkspace.accessibilityDisplayShouldReduceMotion, we could use it, but
|
||||
// unfortunately there is no way, so we change the cache value instead as if
|
||||
// it's set in the parent process.
|
||||
LookAndFeel::SetIntCache(lookAndFeelCache);
|
||||
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
postNotificationName: NSWorkspaceAccessibilityDisplayOptionsDidChangeNotification
|
||||
object:nil];
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsChildView::ResetPrefersReducedMotionOverrideForTest()
|
||||
{
|
||||
LookAndFeel::SetShouldRetainCacheForTest(false);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
already_AddRefed<a11y::Accessible>
|
||||
nsChildView::GetDocumentAccessible()
|
||||
|
|
|
@ -113,6 +113,10 @@ nsLookAndFeel::NativeInit()
|
|||
void
|
||||
nsLookAndFeel::RefreshImpl()
|
||||
{
|
||||
if (mShouldRetainCacheForTest) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsXPLookAndFeel::RefreshImpl();
|
||||
|
||||
// We should only clear the cache if we're in the main browser process.
|
||||
|
|
|
@ -1713,6 +1713,15 @@ class nsIWidget : public nsISupports
|
|||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
virtual nsresult SetPrefersReducedMotionOverrideForTest(bool aValue)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
virtual nsresult ResetPrefersReducedMotionOverrideForTest()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
private:
|
||||
class LongTapInfo
|
||||
{
|
||||
|
|
|
@ -317,7 +317,9 @@ nsXPLookAndFeel::Shutdown()
|
|||
sInstance = nullptr;
|
||||
}
|
||||
|
||||
nsXPLookAndFeel::nsXPLookAndFeel() : LookAndFeel()
|
||||
nsXPLookAndFeel::nsXPLookAndFeel()
|
||||
: LookAndFeel()
|
||||
, mShouldRetainCacheForTest(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1063,4 +1065,11 @@ LookAndFeel::SetIntCache(const nsTArray<LookAndFeelInt>& aLookAndFeelIntCache)
|
|||
return nsLookAndFeel::GetInstance()->SetIntCacheImpl(aLookAndFeelIntCache);
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
LookAndFeel::SetShouldRetainCacheForTest(bool aValue)
|
||||
{
|
||||
nsLookAndFeel::GetInstance()->SetShouldRetainCacheImplForTest(aValue);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -83,6 +83,10 @@ public:
|
|||
|
||||
virtual nsTArray<LookAndFeelInt> GetIntCacheImpl();
|
||||
virtual void SetIntCacheImpl(const nsTArray<LookAndFeelInt>& aLookAndFeelIntCache) {}
|
||||
void SetShouldRetainCacheImplForTest(bool aValue)
|
||||
{
|
||||
mShouldRetainCacheForTest = aValue;
|
||||
}
|
||||
|
||||
virtual void NativeInit() = 0;
|
||||
|
||||
|
@ -117,6 +121,10 @@ protected:
|
|||
|
||||
static nsXPLookAndFeel* sInstance;
|
||||
static bool sShutdown;
|
||||
|
||||
// True if we shouldn't clear the cache value in RefreshImpl().
|
||||
// NOTE: This should be used only for testing.
|
||||
bool mShouldRetainCacheForTest;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче