{-# LANGUAGE OverloadedStrings #-}
module Text.HTML.Form.Query(
renderQueryString, renderQueryString', renderQuery', applyQuery) where
import Text.HTML.Form (Form(..), Input(..), OptionGroup(..), Option(..))
import Network.URI (escapeURIString, isUnescapedInURIComponent)
import Data.List (intercalate)
import Data.Text (unpack)
import qualified Data.Text as Txt
renderQueryString :: Form -> String
renderQueryString = renderQueryString' . renderQuery'
renderQueryString' :: [(String, String)] -> String
renderQueryString' query = intercalate "&" [
escape key ++ '=':escape val | (key, val) <- query
]
renderQuery' :: Form -> [(String, String)]
renderQuery' form = concatMap renderInput' $ inputs form
renderInput' :: Input -> [(String, String)]
renderInput' Input { inputType = inputType' }
| inputType' `elem` ["submit", "reset", "button", "file"] = []
renderInput' Input { checked = False, inputType = inputType' }
| inputType' `elem` ["radio", "checkbox"] = []
renderInput' Input { inputType = "<select>",
inputName = k, value = "", list = opts, multiple = False
} | val:_ <- [optValue opt | grp <- opts, opt <- subopts grp, optSelected opt]
= [(unpack k, unpack val)]
| otherwise = []
renderInput' Input { inputType = "<select>",
inputName = k, list = opts, multiple = True
} = [(unpack k, unpack $ optValue opt) |
grp <- opts, opt <- subopts grp, optSelected opt]
renderInput' Input { inputName = k, value = v } = [(unpack k, unpack v)]
escape :: String -> String
escape = escapeURIString isUnescapedInURIComponent
applyQuery :: Input -> [(String, String)] -> Input
applyQuery input@Input { inputName = n } qs
| inputType input `notElem` ["submit", "reset", "button", "checkbox", "radio"],
Just val' <- unpack n `lookup` qs = input { value = Txt.pack val' }
| otherwise = input