packages feed

lucid 2.9.13 → 2.11.20260427

raw patch · 6 files changed

Files

CHANGELOG.md view
@@ -1,4 +1,30 @@-## 2.9.13+## Upcoming++## 2.11.20260427++* Support GHC 9.14++## 2.11.20250303++* Support GHC 9.12++## 2.11.20230408++* Don't expect Control.Monad to be re-exported from mtl anymore++## 2.11.1++* Use explicit imports for mtl, avoids the mtl-2.3 issue+* Added `minlength` attribute.+* Added `loading` attribute.++## 2.11.0++* Change internal attributes to `Seq Attribute`. This preserves+  ordering. Attributes are merged in a left-biased way, preserving the+  key order as first encountered.++## 2.10.0  * Change internal attributes representation from HashMap to Map. This   introduces stable ordering, at a negligible performance cost for
README.md view
@@ -3,9 +3,12 @@  Clear to write, read and edit DSL for writing HTML -[Documentation](http://chrisdone.github.io/lucid/)+**Table of Contents** -[lucid-from-html](https://github.com/dbaynard/lucid-from-html) will convert html to the `lucid` DSL, though it is experimental.+- [Introduction](#introduction)+- [Rendering](#rendering)+- [Good to know](#good-to-know)+- [Transforming](#transforming)  ## Introduction @@ -119,6 +122,11 @@  See the documentation for the `Lucid` module for information about using it as a monad transformer.++## Good to know++* Attributes are escaped, so you cannot write arbitrary JavaScript in attributes. Instead, do something like `onclick_ "foo()"`.+* Attributes are rendered in the order that they are written in your Haskell code.  ## Transforming 
lucid.cabal view
@@ -1,5 +1,5 @@ name:                lucid-version:             2.9.13+version:             2.11.20260427 synopsis:            Clear to write, read and edit DSL for HTML description:   Clear to write, read and edit DSL for HTML.@@ -15,13 +15,13 @@ license:             BSD3 license-file:        LICENSE author:              Chris Done-maintainer:          chrisdone@gmail.com, oleg.grenrus@iki.fi-copyright:           2014-2017 Chris Done+maintainer:          chrisdone@gmail.com+copyright:           2014-2021 Chris Done category:            Web build-type:          Simple cabal-version:       >=1.10 extra-source-files:  README.md, CHANGELOG.md-tested-with:         GHC==7.10.3,GHC==8.0.2,GHC==8.2.2,GHC==8.4.4,GHC==8.6.5,GHC==8.8.4,GHC==8.10.4,GHC==9.0.1+tested-with: GHC==7.10.3,GHC==8.0.2,GHC==8.2.2,GHC==8.4.4,GHC==8.6.5,GHC==8.8.4,GHC==8.10.7,GHC==9.0.1,GHC==9.2.1, GHC==9.4.1  library   default-language:  Haskell2010@@ -33,7 +33,7 @@                      Lucid.Bootstrap    -- GHC boot libraries-  build-depends:     base                   >=4.8      && <4.16+  build-depends:     base                   >=4.8      && <5                    , bytestring             >=0.10.6.0                    , containers             >=0.5.6.2                    , transformers           >=0.4.2.0@@ -50,7 +50,6 @@   build-depends:     blaze-builder         >=0.4.0.0                    , hashable              >=1.2.3.2                    , mmorph                >=1.0.3-                   , unordered-containers  >=0.2.5.1  source-repository head   type:     git
src/Lucid/Base.hs view
@@ -1,9 +1,10 @@ {-# LANGUAGE CPP #-}+{-# LANGUAGE BangPatterns #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE GADTs #-}-{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE TypeOperators #-}  -- Search for UndecidableInstances to see why this is needed {-# LANGUAGE UndecidableInstances #-}@@ -44,8 +45,11 @@ import qualified Blaze.ByteString.Builder.Html.Utf8 as Blaze import           Control.Applicative import           Control.Monad-import           Control.Monad.Morph-import           Control.Monad.Reader+import           Control.Monad.Morph (MFunctor(..))+import           Control.Monad.Reader (MonadReader(..))+import           Control.Monad.IO.Class (MonadIO(..))+import           Control.Monad.Fix (MonadFix(..))+import           Control.Monad.Trans (MonadTrans(..)) import           Control.Monad.Error.Class (MonadError(..)) import           Control.Monad.State.Class (MonadState(..)) import           Control.Monad.Writer.Class (MonadWriter(..))@@ -53,7 +57,6 @@ import qualified Data.ByteString.Lazy as L import qualified Data.ByteString as S import           Data.Functor.Identity-import           Data.Map.Strict (Map) import qualified Data.Map.Strict as M import           Data.Hashable (Hashable(..)) import           Data.Semigroup (Semigroup (..))@@ -63,15 +66,21 @@ import qualified Data.Text.Lazy as LT import qualified Data.Text.Lazy.Encoding as LT import qualified Data.Text.Encoding as T-import           Data.Typeable (Typeable) import           Prelude+import           Data.Maybe+import           Data.Sequence (Seq)+import qualified Data.Sequence as Seq+import           Data.Foldable (toList)+import qualified Data.Set as Set  -------------------------------------------------------------------------------- -- Types --- | A simple attribute. Don't use the constructor, use 'makeAttribute'.+-- | A simple attribute. Don't use the constructor, use+-- 'makeAttribute'.  Attributes are case sensitive, so if you want+-- attributes to be merged properly, use a single case representation. data Attribute = Attribute !Text !Text-  deriving (Show,Eq,Typeable)+  deriving (Show,Eq)  instance Hashable Attribute where   hashWithSalt salt (Attribute a b) = salt `hashWithSalt` a `hashWithSalt` b@@ -85,21 +94,16 @@  -- | A monad transformer that generates HTML. Use the simpler 'Html' -- type if you don't want to transform over some other monad.+--+-- Don't rely on the internal representation of this type. Use the+-- monad and functor classes. newtype HtmlT m a =-  HtmlT {runHtmlT :: m (Map Text Text -> Builder,a)+  HtmlT {runHtmlT :: m (Seq Attribute -> Builder,a)          -- ^ This is the low-level way to run the HTML transformer,          -- finally returning an element builder and a value. You can          -- pass 'mempty' for this argument for a top-level call. See          -- 'evalHtmlT' and 'execHtmlT' for easier to use functions.          }--- GHC 7.4 errors with---  Can't make a derived instance of `Typeable (HtmlT m a)':---    `HtmlT' must only have arguments of kind `*'--- GHC 7.6 errors with---    `HtmlT' must only have arguments of kind `*'-#if  __GLASGOW_HASKELL__ >= 707-  deriving (Typeable)-#endif  -- | @since 2.9.5 instance MFunctor HtmlT where@@ -112,7 +116,9 @@ -- | Monoid is right-associative, a la the 'Builder' in it. instance (a ~ (),Applicative m) => Monoid (HtmlT m a) where   mempty  = pure mempty+#if !MIN_VERSION_base(4,11,0)   mappend = liftA2 mappend+#endif  -- | Based on the monad instance. instance Applicative m => Applicative (HtmlT m) where@@ -140,21 +146,12 @@  -- | Basically acts like Writer. instance Monad m => Monad (HtmlT m) where-  return a = HtmlT (return (mempty,a))-  {-# INLINE return #-}-   m >>= f = HtmlT $ do     ~(g,a) <- runHtmlT m     ~(h,b) <- runHtmlT (f a)     return (g <> h,b)   {-# INLINE (>>=) #-} -  m >> n = HtmlT $ do-    ~(g, _) <- runHtmlT m-    ~(h, b) <- runHtmlT n-    return (g <> h, b)-  {-# INLINE (>>) #-}- -- | Used for 'lift'. instance MonadTrans HtmlT where   lift m =@@ -342,22 +339,16 @@ instance (Functor m) => With (HtmlT m a) where   with f = \attr -> HtmlT (mk attr <$> runHtmlT f)     where-      mk attr ~(f',a) = (\attr' -> f' (unionArgs (M.fromListWith (<>) (map toPair attr)) attr')+      mk attr ~(f',a) = (\attr' -> f' (attr' <> Seq.fromList attr)                         ,a)-      toPair (Attribute x y) = (x,y)  -- | For the contentful elements: 'Lucid.Html5.div_' instance (Functor m) => With (HtmlT m a -> HtmlT m a) where   with f = \attr inner -> HtmlT (mk attr <$> runHtmlT (f inner))     where-      mk attr ~(f',a) = (\attr' -> f' (unionArgs (M.fromListWith (<>) (map toPair attr)) attr')+      mk attr ~(f',a) = (\attr' -> f' (attr' <> Seq.fromList attr)                         ,a)-      toPair (Attribute x y) = (x,y) --- | Union two sets of arguments and append duplicate keys.-unionArgs :: Map Text Text -> Map Text Text -> Map Text Text-unionArgs = M.unionWith (<>)- -------------------------------------------------------------------------------- -- Running @@ -529,8 +520,27 @@      else s "=\"" <> Blaze.fromHtmlEscapedText val <> s "\""  -- | Folding and monoidally appending attributes.-foldlMapWithKey :: Monoid m => (k -> v -> m) -> Map k v -> m-foldlMapWithKey f = M.foldlWithKey' (\m k v -> m `mappend` f k v) mempty+foldlMapWithKey :: (Text -> Text -> Builder) -> Seq Attribute -> Builder+foldlMapWithKey f attributes =+  case nubOrdMaybe (map fst pairs) of+    Just keyList ->+      foldMap (\k -> fromMaybe mempty (fmap (f k) (M.lookup k values))) keyList+      where values = M.fromListWith (<>) pairs+    Nothing -> foldMap (\(Attribute k v) -> f k v) attributes+  where+    pairs = map (\(Attribute k v) -> (k,v)) (toList attributes)++-- | Do a nubOrd, but only return Maybe if it actually removes anything.+nubOrdMaybe :: Ord a => [a] -> Maybe [a]+nubOrdMaybe = go False Set.empty []+  where+    go (!removed) set acc (x:xs)+      | x `Set.member` set = go True set acc xs+      | otherwise = go removed (Set.insert x set) (x : acc) xs+    go removed _set acc [] =+      if removed+        then pure (reverse acc)+        else Nothing  -- | Convenience function for constructing builders. s :: String -> Builder
src/Lucid/Html5.hs view
@@ -679,6 +679,10 @@ list_ :: Text -> Attribute list_ = makeAttribute "list" +-- | The @loading@ attribute.+loading_ :: Text -> Attribute+loading_ = makeAttribute "loading"+ -- | The @loop@ attribute. loop_ :: Text -> Attribute loop_ = makeAttribute "loop"@@ -711,6 +715,10 @@ min_ :: Text -> Attribute min_ = makeAttribute "min" +-- | The @minlength@ attribute.+minlength_ :: Text -> Attribute+minlength_ = makeAttribute "minlength"+ -- | The @multiple@ attribute. multiple_ :: Text -> Attribute multiple_ = makeAttribute "multiple"@@ -998,6 +1006,10 @@ -- | The @placeholder@ attribute. placeholder_ :: Text -> Attribute placeholder_ = makeAttribute "placeholder"++-- | The @poster@ attribute.+poster_ :: Text -> Attribute+poster_ = makeAttribute "poster"  -- | The @preload@ attribute. preload_ :: Text -> Attribute
test/Main.hs view
@@ -11,6 +11,7 @@ import Lucid.Base import Lucid.Bootstrap +import Control.Monad import Control.Applicative import Control.Monad.State.Strict @@ -193,7 +194,7 @@          "<div class=\" container \">Foo!</div>")      it "bootstrap-attributes-extended" $         renderText (container_ [class_ "bar",id_ "zot"] "Foo!") ==?*-        [ "<div id=\"zot\" class=\" container bar\">Foo!</div>"+        [ "<div class=\" container bar\" id=\"zot\">Foo!</div>"         , "<div class=\" container bar\" id=\"zot\">Foo!</div>"         ]