markdown
markdown copied to clipboard
Links in markdown do not trigger onUrlRequest in Browser.application
Hi @evancz! Thanks for great work with 0.19 - community was waiting for this for a long time, you know.
However, I've got an unexpected behaviour of interaction between Browser.application
and Markdown
. The problem is Markdown's links don't work like external links in case when they are linked with internal routes ("/"
for example). Furthermore clicks to the links don't trigger neither onUrlRequest
nor onUrlChange
- browser just load a page from scratch.
I guess it happens because the module insert links as is and without handling of click event.
I've made an Ellie example but it won't work inside of the sandbox so you should run it locally thru elm reactor
.
Can you get the example down to something smaller? When you do that, please share it directly in the thread, not in an Ellie link. It is easier when it's included directly.
@evancz no problem:
module Main exposing (main)
import Browser
import Browser.Navigation as Navigation
import Html exposing (Html, a, br, div, h2, text)
import Html.Attributes exposing (href)
import Html.Events exposing (onClick)
import Markdown
import Url exposing (Url)
import Url.Parser exposing (s, top)
type Route
= ToHome
| ToMarkdown
| ToNotFound
matchRoute : Url -> Route
matchRoute url =
Url.Parser.parse
(Url.Parser.oneOf
[ Url.Parser.map ToHome top
, Url.Parser.map ToMarkdown (s "markdown")
]
)
url
|> Maybe.withDefault ToNotFound
type alias Model =
{ route : Route
, key : Navigation.Key
}
init : Url -> Navigation.Key -> ( Model, Cmd Msg )
init url key =
( Model (matchRoute url) key
, Cmd.none
)
type Msg
= UrlChanged Url
| UrlRequested Browser.UrlRequest
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
UrlChanged url ->
( { model | route = matchRoute url }
, Cmd.none
)
UrlRequested (Browser.Internal url) ->
( model
, Navigation.pushUrl model.key (Url.toString url)
)
UrlRequested (Browser.External uri) ->
( model
, Navigation.load uri
)
view : Model -> Browser.Document Msg
view model =
case model.route of
ToHome ->
Browser.Document "Home"
[ a [ href "/markdown" ] [ text "Link from Home to Markdown" ]
]
ToMarkdown ->
Browser.Document "Markdown"
[ h2 [] [ text "Markdown" ]
, Markdown.toHtml [] """[Link from Markdown to Home](/)."""
, h2 [] [ text "Elm Html" ]
, a [ href "/" ] [ text "Link from Markdown to Home" ]
]
ToNotFound ->
Browser.Document "404"
[ a [ href "/" ] [ text "Link from 404 to Home" ]
, br [] []
, a [ href "/markdown" ] [ text "Link from 404 to Markdown" ]
]
main : Program () Model Msg
main =
Browser.application
{ init = always init
, view = view
, update = update
, subscriptions = always Sub.none
, onUrlRequest = UrlRequested
, onUrlChange = UrlChanged
}
For completeness sake: It's not working right on package.elm-lang.org right now. Go to this page https://package.elm-lang.org/packages/elm/browser/latest/Browser-Navigation and click on the first link to Browser.application
and watch the page do a full reload.
This is also an issue for me. My use case is to add support for markdown links to modules functions/values/types in elm-doc-preview, see https://github.com/dmy/elm-doc-preview/issues/1.
Here is a slightly smaller SSCCE:
module Main exposing (main)
import Browser exposing (UrlRequest(..))
import Browser.Navigation exposing (Key)
import Html exposing (Html, a, div, h4, text)
import Html.Attributes exposing (href)
import Markdown
import Url exposing (Url)
type alias Urls =
List String
type Msg
= UrlRequested UrlRequest
| UrlChanged Url
body : Urls -> List (Html msg)
body urls =
[ a [ href "/standard" ] [ text "standard anchor link" ]
, Markdown.toHtml [] "[markdown link](markdown)"
, div [] <| List.map (\u -> div [] [ text u ]) urls
]
update : Msg -> Urls -> ( Urls, Cmd Msg )
update msg model =
case msg of
UrlRequested request ->
case request of
Internal url ->
( Url.toString url :: model, Cmd.none )
External string ->
( string :: model, Cmd.none )
UrlChanged _ ->
( model, Cmd.none )
main : Program () Urls Msg
main =
Browser.application
{ init = \_ url key -> ( [], Cmd.none )
, view = \model -> { title = "", body = body model }
, update = update
, subscriptions = always Sub.none
, onUrlRequest = UrlRequested
, onUrlChange = UrlChanged
}
Clicking the first standard a
link add the url to the list of requested ones, clicking the markdown one reloads the page.