Created
July 3, 2022 01:08
-
-
Save abradley2/2cc10f7798851c76c792f39f3a1fe5da to your computer and use it in GitHub Desktop.
Intercept link clicks in PureScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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