2023-09-29 05:14:09 +00:00
|
|
|
module Puppeteer.Page.Event
|
|
|
|
( once
|
|
|
|
, listen
|
|
|
|
, eventKey
|
|
|
|
, eventData
|
|
|
|
, class Event
|
|
|
|
, connectPageConsole
|
|
|
|
, defaultEventData
|
|
|
|
, FrameEvent(..)
|
|
|
|
, UnitEvent(..)
|
|
|
|
, ErrorEvent(..)
|
|
|
|
, NullablePageEvent(..)
|
|
|
|
, RequestEvent(..)
|
|
|
|
, ResponseEvent(..)
|
|
|
|
, DialogEvent(..)
|
|
|
|
, ConsoleMessageEvent(..)
|
|
|
|
) where
|
|
|
|
|
|
|
|
import Prelude
|
|
|
|
|
|
|
|
import Control.Monad.Error.Class (liftEither)
|
|
|
|
import Control.Monad.Except (runExcept)
|
|
|
|
import Data.Bifunctor (lmap)
|
|
|
|
import Data.Either (hush, note)
|
|
|
|
import Data.Maybe (Maybe)
|
|
|
|
import Data.Nullable (Nullable)
|
|
|
|
import Data.String as String
|
|
|
|
import Effect (Effect)
|
|
|
|
import Effect.Aff (Aff, launchAff_, makeAff)
|
|
|
|
import Effect.Class (liftEffect)
|
|
|
|
import Effect.Console as Console
|
|
|
|
import Effect.Exception (Error, error)
|
|
|
|
import Effect.Unsafe (unsafePerformEffect)
|
|
|
|
import Foreign (Foreign, unsafeFromForeign)
|
|
|
|
import Puppeteer.Base (Context(..), Frame, Page)
|
2023-09-29 22:32:24 +00:00
|
|
|
import Puppeteer.HTTP as HTTP
|
2023-09-29 05:14:09 +00:00
|
|
|
import Puppeteer.Page as Page
|
|
|
|
import Puppeteer.Page.Event.ConsoleMessage (ConsoleMessage, messageTypeString)
|
|
|
|
import Puppeteer.Page.Event.ConsoleMessage as ConsoleMessage
|
|
|
|
import Puppeteer.Page.Event.Dialog (Dialog)
|
|
|
|
import Simple.JSON (class ReadForeign, readImpl)
|
|
|
|
|
2023-10-07 16:28:24 +00:00
|
|
|
connectPageConsole :: Page -> Effect Unit
|
2023-09-29 18:23:27 +00:00
|
|
|
connectPageConsole p =
|
|
|
|
let
|
2023-10-07 16:28:24 +00:00
|
|
|
onmsg m = launchAff_ do
|
2023-09-29 05:14:09 +00:00
|
|
|
title <- Page.title p
|
|
|
|
let t = ConsoleMessage.messageType m
|
|
|
|
let textLevel = "[" <> String.toUpper (messageTypeString t) <> "]"
|
|
|
|
let textPrefix = "[Puppeteer.Page@\"" <> title <> "\"]"
|
|
|
|
let text = textLevel <> " " <> textPrefix <> " " <> ConsoleMessage.text m
|
|
|
|
liftEffect $ case t of
|
|
|
|
ConsoleMessage.Debug -> Console.debug text
|
|
|
|
ConsoleMessage.Error -> Console.error text
|
|
|
|
ConsoleMessage.Warning -> Console.warn text
|
|
|
|
_ -> Console.log text
|
|
|
|
in
|
|
|
|
void $ listen Console onmsg p
|
|
|
|
|
|
|
|
data UnitEvent
|
|
|
|
= Close
|
|
|
|
| DomContentLoaded
|
|
|
|
| Load
|
|
|
|
|
|
|
|
instance unitEvent :: Event UnitEvent Unit where
|
|
|
|
eventKey Close = "close"
|
|
|
|
eventKey DomContentLoaded = "domcontentloaded"
|
|
|
|
eventKey Load = "load"
|
|
|
|
eventData = const $ pure unit
|
|
|
|
|
|
|
|
data ErrorEvent
|
|
|
|
= Error
|
|
|
|
| PageError
|
|
|
|
|
|
|
|
instance errorEvent :: Event ErrorEvent Error where
|
|
|
|
eventKey Error = "error"
|
|
|
|
eventKey PageError = "pageerror"
|
|
|
|
eventData = pure <<< unsafeFromForeign
|
|
|
|
|
|
|
|
data FrameEvent
|
|
|
|
= FrameAttached
|
|
|
|
| FrameDetached
|
|
|
|
| FrameNavigated
|
|
|
|
|
|
|
|
instance frameEvent :: Event FrameEvent Frame where
|
|
|
|
eventKey FrameAttached = "frameattached"
|
|
|
|
eventKey FrameDetached = "framedetached"
|
|
|
|
eventKey FrameNavigated = "framenavigated"
|
|
|
|
eventData = defaultEventData
|
|
|
|
|
|
|
|
data ConsoleMessageEvent = Console
|
|
|
|
|
|
|
|
instance consoleEvent :: Event ConsoleMessageEvent ConsoleMessage where
|
|
|
|
eventKey Console = "console"
|
|
|
|
eventData = defaultEventData
|
|
|
|
|
|
|
|
data DialogEvent = Dialog
|
|
|
|
|
|
|
|
instance dialogEvent :: Event DialogEvent Dialog where
|
|
|
|
eventKey Dialog = "dialog"
|
|
|
|
eventData = defaultEventData
|
|
|
|
|
|
|
|
data NullablePageEvent = Popup
|
|
|
|
|
|
|
|
instance nullablePageEvent :: Event NullablePageEvent (Nullable Page) where
|
|
|
|
eventKey Popup = "popup"
|
|
|
|
eventData = defaultEventData
|
|
|
|
|
|
|
|
data ResponseEvent = Response
|
|
|
|
|
2023-09-29 22:32:24 +00:00
|
|
|
instance responseEvent :: Event ResponseEvent HTTP.Response where
|
2023-09-29 05:14:09 +00:00
|
|
|
eventKey Response = "response"
|
|
|
|
eventData = defaultEventData
|
|
|
|
|
|
|
|
data RequestEvent
|
|
|
|
= Request
|
|
|
|
| RequestFailed
|
|
|
|
| RequestFinished
|
|
|
|
| RequestServedFromCache
|
|
|
|
|
2023-09-29 22:32:24 +00:00
|
|
|
instance requestEvent :: Event RequestEvent HTTP.Request where
|
2023-09-29 05:14:09 +00:00
|
|
|
eventKey Request = "request"
|
|
|
|
eventKey RequestFailed = "requestfailed"
|
|
|
|
eventKey RequestFinished = "requestfinished"
|
|
|
|
eventKey RequestServedFromCache = "requestservedfromcache"
|
|
|
|
eventData = defaultEventData
|
|
|
|
|
|
|
|
class Event :: Type -> Type -> Constraint
|
|
|
|
class Event ev d | ev -> d, d -> ev where
|
|
|
|
eventKey :: ev -> String
|
|
|
|
eventData :: Foreign -> Maybe d
|
|
|
|
|
|
|
|
defaultEventData :: forall d. ReadForeign d => Foreign -> Maybe d
|
|
|
|
defaultEventData = hush <<< runExcept <<< readImpl
|
|
|
|
|
|
|
|
foreign import data ListenerToken :: Type
|
|
|
|
foreign import _once :: String -> (Foreign -> Unit) -> Page -> Effect Unit
|
|
|
|
foreign import _addListener :: String -> (Foreign -> Unit) -> Page -> Effect ListenerToken
|
|
|
|
foreign import _removeListener :: ListenerToken -> Page -> Effect Unit
|
|
|
|
|
|
|
|
once :: forall ev evd. Event ev evd => ev -> Page -> Aff evd
|
|
|
|
once ev p =
|
|
|
|
let
|
|
|
|
k = eventKey ev
|
|
|
|
f res = do
|
|
|
|
let cb = unsafePerformEffect <<< res <<< lmap error <<< note "parse failed" <<< eventData
|
|
|
|
_once k cb p
|
|
|
|
pure mempty
|
|
|
|
in
|
|
|
|
makeAff f
|
|
|
|
|
2023-10-07 16:28:24 +00:00
|
|
|
listen :: forall ev evd. Event ev evd => ev -> (evd -> Effect Unit) -> Page -> Effect (Context "event listener")
|
2023-09-29 05:14:09 +00:00
|
|
|
listen ev cb p =
|
|
|
|
let
|
|
|
|
cb' f = unsafePerformEffect $ do
|
|
|
|
evd <- liftEither $ lmap error $ note "parse failed" $ eventData f
|
2023-10-07 16:28:24 +00:00
|
|
|
cb evd
|
2023-09-29 05:14:09 +00:00
|
|
|
in
|
|
|
|
do
|
2023-10-07 16:28:24 +00:00
|
|
|
t <- _addListener (eventKey ev) cb' p
|
2023-09-29 05:14:09 +00:00
|
|
|
pure $ Context (\_ -> liftEffect $ _removeListener t p)
|