<commit_before>module Html.Styled.Internal exposing (Classname, InternalHtml(..), getClassname, unstyle, unstyleKeyed)

import Css exposing (Style)
import Dict exposing (Dict)
import Hex
import Json.Encode
import Murmur3
import VirtualDom exposing (Node, Property)


type alias Classname =
    String


type InternalHtml msg
    = Element (Maybe ( Classname, List Style )) String (List (VirtualDom.Property msg)) (List (InternalHtml msg))
    | KeyedElement (Maybe ( Classname, List Style )) String (List (VirtualDom.Property msg)) (List ( String, InternalHtml msg ))
    | Unstyled (VirtualDom.Node msg)


getClassname : List Style -> Maybe String
getClassname styles =
    if List.isEmpty styles then
        Nothing
    else
        -- TODO Replace this comically inefficient implementation
        -- with crawling these union types and building up a hash along the way.
        styles
            |> Css.everything
            |> List.singleton
            |> Css.stylesheet
            |> List.singleton
            |> Css.compile
            |> .css
            |> Murmur3.hashString murmurSeed
            |> Hex.toString
            |> String.cons '_'
            |> Just


murmurSeed : Int
murmurSeed =
    15739


unstyle :
    String
    -> Maybe ( Classname, List Style )
    -> List (Property msg)
    -> List (InternalHtml msg)
    -> Node msg
unstyle =
    unstyleWith
        resolve
        VirtualDom.node
        toStyleNode


unstyleKeyed :
    String
    -> Maybe ( Classname, List Style )
    -> List (Property msg)
    -> List ( String, InternalHtml msg )
    -> Node msg
unstyleKeyed =
    unstyleWith
        resolveKeyed
        VirtualDom.keyedNode
        toKeyedStyleNode



-- INTERNAL --


toStyleNode :
    String
    -> Dict Classname (List Style)
    -> a
    -> Node msg
toStyleNode classname allStyles _ =
    getStyleNode classname allStyles


toKeyedStyleNode :
    String
    -> Dict Classname (List Style)
    -> List ( String, a )
    -> ( String, Node msg )
toKeyedStyleNode classname allStyles finalChildNodes =
    let
        styleNodeKey =
            getUnusedKey "_" finalChildNodes

        finalNode =
            getStyleNode classname allStyles
    in
    ( styleNodeKey, finalNode )


getStyleNode : String -> Dict Classname (List Style) -> Node msg
getStyleNode classname styles =
    -- this <style> node will be the first child of the requested one
    toDeclaration styles
        |> VirtualDom.text
        |> List.singleton
        |> VirtualDom.node "style" []



-- INTERNAL --


unstyleWith :
    (keyedOrHtml2 -> ( List keyedOrHtml, Dict Classname (List Style) ) -> ( List keyedOrHtml, Dict Classname (List Style) ))
    -> (String -> List (Property msg) -> List keyedOrHtml -> keyedOrHtml3)
    -> (String -> Dict Classname (List Style) -> List keyedOrHtml -> keyedOrHtml)
    -> String
    -> Maybe ( Classname, List Style )
    -> List (Property msg)
    -> List keyedOrHtml2
    -> keyedOrHtml3
unstyleWith resolver toNode createStyleNode elemType maybePair attributes children =
    let
        ( styles, finalAttributes, classname ) =
            case maybePair of
                Just ( classnameFromPair, style ) ->
                    ( Dict.singleton classnameFromPair style
                    , class classnameFromPair :: attributes
                    , classnameFromPair
                    )

                Nothing ->
                    ( Dict.empty
                    , attributes
                    , ""
                    )

        ( childNodes, allStyles ) =
            List.foldl resolver ( [], styles ) children

        finalChildNodes =
            List.reverse childNodes
    in
    if Dict.isEmpty allStyles then
        -- If we have no styles to speak of, don't emit a <style>
        toNode elemType finalAttributes finalChildNodes
    else
        let
            styleNode =
                createStyleNode classname allStyles finalChildNodes
        in
        toNode
            elemType
            attributes
            (styleNode :: finalChildNodes)


resolve :
    InternalHtml msg
    -> ( List (Node msg), Dict Classname (List Style) )
    -> ( List (Node msg), Dict Classname (List Style) )
resolve html ( nodes, styles ) =<commit_msg>Fix bug with top-level toUnstyled<commit_after>module Html.Styled.Internal exposing (Classname, InternalHtml(..), getClassname, unstyle, unstyleKeyed)

import Css exposing (Style)
import Dict exposing (Dict)
import Hex
import Json.Encode
import Murmur3
import VirtualDom exposing (Node, Property)


type alias Classname =
    String


type InternalHtml msg
    = Element (Maybe ( Classname, List Style )) String (List (VirtualDom.Property msg)) (List (InternalHtml msg))
    | KeyedElement (Maybe ( Classname, List Style )) String (List (VirtualDom.Property msg)) (List ( String, InternalHtml msg ))
    | Unstyled (VirtualDom.Node msg)


getClassname : List Style -> Maybe String
getClassname styles =
    if List.isEmpty styles then
        Nothing
    else
        -- TODO Replace this comically inefficient implementation
        -- with crawling these union types and building up a hash along the way.
        styles
            |> Css.everything
            |> List.singleton
            |> Css.stylesheet
            |> List.singleton
            |> Css.compile
            |> .css
            |> Murmur3.hashString murmurSeed
            |> Hex.toString
            |> String.cons '_'
            |> Just


murmurSeed : Int
murmurSeed =
    15739


unstyle :
    String
    -> Maybe ( Classname, List Style )
    -> List (Property msg)
    -> List (InternalHtml msg)
    -> Node msg
unstyle =
    unstyleWith
        resolve
        VirtualDom.node
        toStyleNode


unstyleKeyed :
    String
    -> Maybe ( Classname, List Style )
    -> List (Property msg)
    -> List ( String, InternalHtml msg )
    -> Node msg
unstyleKeyed =
    unstyleWith
        resolveKeyed
        VirtualDom.keyedNode
        toKeyedStyleNode



-- INTERNAL --


toStyleNode :
    String
    -> Dict Classname (List Style)
    -> a
    -> Node msg
toStyleNode classname allStyles _ =
    getStyleNode classname allStyles


toKeyedStyleNode :
    String
    -> Dict Classname (List Style)
    -> List ( String, a )
    -> ( String, Node msg )
toKeyedStyleNode classname allStyles finalChildNodes =
    let
        styleNodeKey =
            getUnusedKey "_" finalChildNodes

        finalNode =
            getStyleNode classname allStyles
    in
    ( styleNodeKey, finalNode )


getStyleNode : String -> Dict Classname (List Style) -> Node msg
getStyleNode classname styles =
    -- this <style> node will be the first child of the requested one
    toDeclaration styles
        |> VirtualDom.text
        |> List.singleton
        |> VirtualDom.node "style" []



-- INTERNAL --


unstyleWith :
    (keyedOrHtml2 -> ( List keyedOrHtml, Dict Classname (List Style) ) -> ( List keyedOrHtml, Dict Classname (List Style) ))
    -> (String -> List (Property msg) -> List keyedOrHtml -> keyedOrHtml3)
    -> (String -> Dict Classname (List Style) -> List keyedOrHtml -> keyedOrHtml)
    -> String
    -> Maybe ( Classname, List Style )
    -> List (Property msg)
    -> List keyedOrHtml2
    -> keyedOrHtml3
unstyleWith resolver toNode createStyleNode elemType maybePair attributes children =
    let
        ( styles, finalAttributes, classname ) =
            case maybePair of
                Just ( classnameFromPair, style ) ->
                    ( Dict.singleton classnameFromPair style
                    , class classnameFromPair :: attributes
                    , classnameFromPair
                    )

                Nothing ->
                    ( Dict.empty
                    , attributes
                    , ""
                    )

        ( childNodes, allStyles ) =
            List.foldl resolver ( [], styles ) children

        finalChildNodes =
            List.reverse childNodes
    in
    if Dict.isEmpty allStyles then
        -- If we have no styles to speak of, don't emit a <style>
        toNode elemType finalAttributes finalChildNodes
    else
        let
            styleNode =
                createStyleNode classname allStyles finalChildNodes
        in
        toNode
            elemType
            finalAttributes
            (styleNode :: finalChildNodes)


resolve :
    InternalHtml msg
    -> ( List (Node msg), Dict Classname (List Style) )
    -> ( List (Node msg), Dict Classname (List Style) )
resolve html ( nodes, styles ) =
{'fraction_non_alphanumeric': 0.07876511327620613, 'fraction_numerical': 0.002582462730367414, 'mean_word_length': 1.9978888106966926, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 105, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5368430', 'n_tokens_mistral': 2375, 'n_tokens_neox': 2264, 'n_words': 712}