Skip to content

Commit ad44bf8

Browse files
authored
Fall back to Date.now() when performance is unavailable (#1627)
1 parent 3561331 commit ad44bf8

5 files changed

Lines changed: 34 additions & 1 deletion

File tree

ffi/ghc/Miso/DSL/FFI.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ freeJSVal_ffi _ = pure ()
119119
requestAnimationFrame :: JSVal -> IO Int
120120
requestAnimationFrame = undefined
121121
-----------------------------------------------------------------------------
122+
-- | High-resolution timestamp where one exists, wall clock where it does not.
123+
now_ffi :: IO Double
124+
now_ffi = undefined
125+
-----------------------------------------------------------------------------
122126
-- | Cancels a frame previously scheduled with 'requestAnimationFrame'.
123127
--
124128
-- @since 1.13.0.0

ffi/js/Miso/DSL/FFI.hs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ module Miso.DSL.FFI
99
( -- ** Types
1010
JSVal
1111
, JSString
12+
, now_ffi
1213
-- ** Serialization FFI
1314
-- *** ToJSVal
1415
, toJSVal_Char
@@ -467,3 +468,15 @@ foreign import javascript unsafe
467468
#endif
468469
toString_Word :: Word -> JSString
469470
-----------------------------------------------------------------------------
471+
-- | High-resolution timestamp where one exists, wall clock where it does not.
472+
--
473+
-- @performance@ is absent on Lynx's background-thread realm, so this cannot be
474+
-- a bare @performance.now()@; see 'Miso.FFI.Internal.now'.
475+
foreign import javascript unsafe
476+
#if GHCJS_NEW
477+
"(() => (typeof performance !== 'undefined' && performance && typeof performance.now === 'function') ? performance.now() : Date.now())"
478+
#else
479+
"$r = (typeof performance !== 'undefined' && performance && typeof performance.now === 'function') ? performance.now() : Date.now();"
480+
#endif
481+
now_ffi :: IO Double
482+
-----------------------------------------------------------------------------

ffi/wasm/Miso/DSL/FFI.hs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module Miso.DSL.FFI
1212
( -- ** Types
1313
JSVal
1414
, JSString (..)
15+
, now_ffi
1516
-- ** Serialization FFI
1617
-- *** ToJSVal
1718
, toJSVal_Char
@@ -447,6 +448,14 @@ foreign import javascript unsafe
447448
return requestAnimationFrame($1);
448449
""" requestAnimationFrame :: JSVal -> IO Int
449450
-----------------------------------------------------------------------------
451+
-- | High-resolution timestamp where one exists, wall clock where it does not.
452+
foreign import javascript unsafe
453+
"""
454+
return (typeof performance !== 'undefined' && performance && typeof performance.now === 'function')
455+
? performance.now()
456+
: Date.now();
457+
""" now_ffi :: IO Double
458+
-----------------------------------------------------------------------------
450459
foreign import javascript unsafe
451460
"""
452461
return cancelAnimationFrame($1);

src/Miso/DSL.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ module Miso.DSL
143143
, setProp
144144
, getProp
145145
, eval
146+
, now_ffi
146147
, requestAnimationFrame
147148
, cancelAnimationFrame
148149
, freeFunction

src/Miso/FFI/Internal.hs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,9 +376,15 @@ windowInnerWidth =
376376
-- | Retrieve high resolution time stamp
377377
--
378378
-- See <https://developer.mozilla.org/en-US/docs/Web/API/Performance/now>
379+
-- Lynx's *background* thread realm has no @performance@ global at all - only
380+
-- the main thread does - so the obvious @performance.now()@ throws
381+
-- @cannot read property 'now' of undefined@ there. Everything that timestamps
382+
-- from the BTS goes through here, including gesture handling like
383+
-- double-tap detection, so that throw took real features down rather than
384+
-- merely losing precision. Falls back to @Date.now()@, which every realm has.
379385
now :: IO Double
380386
{-# INLINABLE now #-}
381-
now = fromJSValUnchecked =<< (jsg "performance" # "now" $ ())
387+
now = now_ffi
382388
-----------------------------------------------------------------------------
383389
-- | Outputs a message to the web console
384390
--

0 commit comments

Comments
 (0)