1
0
Fork 0
tooty/src/View/Formatter.elm

161 lines
4.5 KiB
Elm
Raw Normal View History

2017-06-02 12:11:50 +00:00
module View.Formatter exposing (formatContent, textContent)
import Dict
import Html exposing (..)
import Html.Attributes exposing (..)
import HtmlParser
2017-06-02 12:11:50 +00:00
import HtmlParser.Util as ParseUtil
import Http
2017-04-30 10:15:33 +00:00
import Mastodon.Model exposing (..)
import String.Extra exposing (replace, rightOf)
import Types exposing (..)
import View.Events exposing (..)
2022-03-30 04:48:56 +00:00
import Regex
import Json.Encode
2022-03-27 06:07:04 +00:00
formatContent : String -> List Mention -> List Emoji -> List (Html Msg)
formatContent content mentions emojis =
content
|> replace " ?" " ?"
|> replace " !" " !"
|> replace " :" " :"
|> HtmlParser.parse
2022-03-27 06:07:04 +00:00
|> toVirtualDom mentions emojis
2017-06-02 12:11:50 +00:00
textContent : String -> String
textContent html =
html |> HtmlParser.parse |> ParseUtil.textContent
{-| Converts nodes to virtual dom nodes.
-}
2022-03-27 06:07:04 +00:00
toVirtualDom : List Mention -> List Emoji-> List HtmlParser.Node -> List (Html Msg)
toVirtualDom mentions emojis nodes =
List.map (toVirtualDomEach mentions emojis) nodes
2017-05-29 14:28:01 +00:00
replaceHref : String -> List ( String, String ) -> List (Attribute Msg)
replaceHref newHref attrs =
attrs
|> List.map toAttribute
|> List.append [ onClickWithPreventAndStop <| Navigate newHref ]
2017-04-30 10:15:33 +00:00
createLinkNode : List ( String, String ) -> List HtmlParser.Node -> List Mention -> Html Msg
createLinkNode attrs children mentions =
2017-05-13 09:21:29 +00:00
case (getMentionForLink attrs mentions) of
Just mention ->
Html.node "a"
(replaceHref ("#account/" ++ mention.id) attrs)
2022-03-27 06:07:04 +00:00
(toVirtualDom mentions [] children)
2017-05-13 09:21:29 +00:00
Nothing ->
case getHashtagForLink attrs of
Just hashtag ->
Html.node "a"
2017-05-29 14:28:01 +00:00
(replaceHref ("#hashtag/" ++ hashtag) attrs)
2022-03-27 06:07:04 +00:00
(toVirtualDom mentions [] children)
Nothing ->
Html.node "a"
((List.map toAttribute attrs)
++ [ onClickWithStop NoOp, target "_blank" ]
)
2022-03-27 06:07:04 +00:00
(toVirtualDom mentions [] children)
getHrefLink : List ( String, String ) -> Maybe String
getHrefLink attrs =
attrs
2017-05-13 09:21:29 +00:00
|> List.filter (\( name, _ ) -> name == "href")
|> List.map (\( _, value ) -> value)
|> List.head
getHashtagForLink : List ( String, String ) -> Maybe String
getHashtagForLink attrs =
let
hashtag =
attrs
|> Dict.fromList
|> Dict.get "href"
|> Maybe.withDefault ""
|> rightOf "/tags/"
|> Http.decodeUri
|> Maybe.withDefault ""
in
if hashtag /= "" then
Just hashtag
else
Nothing
2017-04-30 10:15:33 +00:00
getMentionForLink : List ( String, String ) -> List Mention -> Maybe Mention
getMentionForLink attrs mentions =
case getHrefLink attrs of
Just href ->
mentions
|> List.filter (\m -> m.url == href)
|> List.head
Nothing ->
Nothing
2022-03-27 06:07:04 +00:00
toVirtualDomEach : List Mention -> List Emoji -> HtmlParser.Node -> Html Msg
toVirtualDomEach mentions emoji node =
case node of
HtmlParser.Element "a" attrs children ->
createLinkNode attrs children mentions
HtmlParser.Element name attrs children ->
2022-03-27 06:07:04 +00:00
Html.node name (List.map toAttribute attrs) (toVirtualDom mentions emoji children)
HtmlParser.Text s ->
2022-03-27 06:07:04 +00:00
handleEmoji s emoji
HtmlParser.Comment _ ->
text ""
2022-03-30 04:48:56 +00:00
-- VERY janky.
2022-03-27 06:07:04 +00:00
handleEmoji : String -> List Emoji -> Html Msg
2022-03-30 04:48:56 +00:00
handleEmoji s emojis =
span [ property "innerHTML" <| Json.Encode.string <| Regex.replace Regex.All shortcodeRegex (\{match} -> displayEmoji match emojis) <| simpleSanitize <| s ] []
simpleSanitize : String -> String
simpleSanitize content =
content
|> replace "<" "&lt;"
|> replace ">" "&gt;"
2022-03-30 04:48:56 +00:00
displayEmoji : String -> List Emoji -> String
displayEmoji s emojis =
case (lookupEmoji (String.slice 1 -1 s) emojis) of
Just emoji ->
"<img src=\""++emoji.url++"\" title=\""++s++"\" class=\"emoji-custom\">"
Nothing ->
s
lookupEmoji : String -> List Emoji -> Maybe Emoji
lookupEmoji shortcode emojis =
emojis
|> List.filter (\m -> m.shortcode == shortcode)
|> List.head
shortcodeRegex : Regex.Regex
shortcodeRegex =
Regex.regex ":[^:]*(?:::]*)*:"
2022-03-27 06:07:04 +00:00
toAttribute : ( String, String ) -> Attribute msg
toAttribute ( name, value ) =
attribute name value