Skip to content

Instantly share code, notes, and snippets.

@abradley2
Created July 3, 2022 01:08
Show Gist options
  • Save abradley2/2cc10f7798851c76c792f39f3a1fe5da to your computer and use it in GitHub Desktop.
Save abradley2/2cc10f7798851c76c792f39f3a1fe5da to your computer and use it in GitHub Desktop.
Intercept link clicks in PureScript
import Prelude
import Control.Monad.Maybe.Trans (MaybeT(..), runMaybeT)
import Control.Monad.Trans.Class (lift)
import Data.Maybe (Maybe(..), maybe)
import Data.Maybe as Maybe
import Data.Newtype (wrap)
import Data.String as String
import Effect (Effect)
import Web.DOM.Node (Node)
import Web.DOM.Node as Node
import Web.Event.Event (Event)
import Web.Event.Event as Event
import Web.Event.EventTarget as EventTarget
import Web.HTML as HTML
import Web.HTML.HTMLDocument as HTMLDocument
import Web.HTML.HTMLLinkElement (HTMLLinkElement)
import Web.HTML.HTMLLinkElement as HTMLLinkElement
import Web.HTML.Window as Window
captureLinkClicks :: forall msg. (String -> Effect msg) -> Effect Unit
captureLinkClicks onLinkClicked = do
document <- HTML.window >>= Window.document
listener <- EventTarget.eventListener $ clickListener onLinkClicked >>> runMaybeT
EventTarget.addEventListener (wrap "click") listener true (HTMLDocument.toEventTarget document)
clickListener :: forall msg. (String -> Effect msg) -> Event -> MaybeT Effect Unit
clickListener onLinkClicked event = do
eventNode <- MaybeT <<< pure $ Event.target event >>= Node.fromEventTarget
linkElement <- MaybeT $ findLink eventNode
href <- lift $ HTMLLinkElement.href linkElement
crossOrigin <- lift $ isCrossOrigin linkElement
if crossOrigin == false then
lift
$ do
_ <- Event.preventDefault event
_ <- onLinkClicked href
pure unit
else
pure unit
findLink :: Node -> Effect (Maybe HTMLLinkElement)
findLink node = case HTMLDocument.fromNode node of
Just _ -> pure Nothing
Nothing -> case HTMLLinkElement.fromNode node of
Just linkElement -> pure $ Just linkElement
Nothing -> Node.parentNode node >>= maybe (pure Nothing) findLink
isCrossOrigin :: HTMLLinkElement -> Effect Boolean
isCrossOrigin = HTMLLinkElement.href >>> map (String.indexOf (wrap "://")) >>> map Maybe.isJust
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment