packages feed

web-rep 0.14.0.0 → 0.14.0.1

raw patch · 6 files changed

+43/−184 lines, 6 filesdep −doctest-paralleldep −string-interpolate

Dependencies removed: doctest-parallel, string-interpolate

Files

src/Web/Rep/Examples.hs view
@@ -1,7 +1,6 @@ {-# LANGUAGE ApplicativeDo #-} {-# LANGUAGE OverloadedLabels #-} {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE QuasiQuotes #-} {-# OPTIONS_GHC -Wno-name-shadowing #-}  -- | Some simple usage examples to get started with the library.@@ -20,7 +19,6 @@ where  import Data.ByteString (ByteString)-import Data.String.Interpolate import FlatParse.Basic (takeRest) import GHC.Generics import MarkupParse@@ -72,34 +70,30 @@ css1 :: Css css1 =   Css-    [i|-{-  font-size   : 10px;-  font-family : "Arial","Helvetica", sans-serif;-}--\#btnGo-{-  margin-top    : 20px;-  margin-bottom : 20px;-}--\#btnGo.on-{-  color : \#008000;-}-|]+    "{\n\+    \  font-size   : 10px;\n\+    \  font-family : \"Arial\",\"Helvetica\", sans-serif;\n\+    \}\n\+    \\n\+    \#btnGo\n\+    \{\n\+    \  margin-top    : 20px;\n\+    \  margin-bottom : 20px;\n\+    \}\n\+    \\n\+    \#btnGo.on\n\+    \{\n\+    \  color : #008000;\n\+    \}"  -- js click :: Js click =   Js-    [i|-$('\#btnGo').click( function() {-  $('\#btnGo').toggleClass('on');-  alert('bada bing!');-});-|]+    "$('#btnGo').click( function() {\n\+    \  $('#btnGo').toggleClass('on');\n\+    \  alert('bada bing!');\n\+    \});"  button1 :: Markup button1 =
src/Web/Rep/Page.hs view
@@ -1,6 +1,5 @@ {-# LANGUAGE OverloadedLabels #-} {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE QuasiQuotes #-} {-# OPTIONS_GHC -fno-warn-incomplete-patterns #-}  -- | Representations of a web page, covering Html, CSS & JS artifacts.@@ -23,7 +22,6 @@  import Data.ByteString (ByteString) import Data.ByteString.Char8 qualified as C-import Data.String.Interpolate import GHC.Generics import MarkupParse import Optics.Core@@ -137,26 +135,11 @@ cssColorScheme :: Css cssColorScheme =   Css-    [i|-{-  color-scheme: light dark;-}-{-  body {-    background-color: rgb(92%, 92%, 92%);-    color: rgb(5%, 5%, 5%);-  }-}-@media (prefers-color-scheme:dark) {-  body {-    background-color: rgb(5%, 5%, 5%);-    color: rgb(92%, 92%, 92%);-  }-}|]+    "{\n  color-scheme: light dark;\n}\n{\n  body {\n    background-color: rgb(92%, 92%, 92%);\n    color: rgb(5%, 5%, 5%);\n  }\n}\n@media (prefers-color-scheme:dark) {\n  body {\n    background-color: rgb(5%, 5%, 5%);\n    color: rgb(92%, 92%, 92%);\n  }\n}"  -- | Javascript as string newtype Js = Js {jsByteString :: ByteString} deriving (Eq, Show, Generic, Semigroup, Monoid)  -- | Add the windows.onload assignment onLoad :: Js -> Js-onLoad (Js t) = Js [i| window.onload=function(){#{t}};|]+onLoad (Js t) = Js (" window.onload=function(){" <> t <> "};")
src/Web/Rep/SharedReps.hs view
@@ -1,7 +1,6 @@ {-# LANGUAGE ApplicativeDo #-} {-# LANGUAGE OverloadedLabels #-} {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE QuasiQuotes #-} {-# OPTIONS_GHC -Wno-name-shadowing #-} {-# OPTIONS_GHC -Wno-x-partial #-} @@ -48,7 +47,6 @@ import Data.HashMap.Strict qualified as HashMap import Data.List qualified as List import Data.Maybe-import Data.String.Interpolate import FlatParse.Basic hiding (take) import MarkupParse import Optics.Core hiding (element)@@ -366,12 +364,15 @@   elementc     "script"     []-    [i|-$('\##{checkName}').on('change', (function(){-  var vis = this.checked ? "block" : "none";-  document.getElementById("#{toggleId}").style.display = vis;-}));-|]+    ( "$('#"+        <> checkName+        <> "').on('change', (function(){"+        <> "  var vis = this.checked ? \"block\" : \"none\";"+        <> "  document.getElementById(\""+        <> toggleId+        <> "\").style.display = vis;"+        <> "}));"+    )  -- | A (fixed-size) list represented in html as an accordion card -- A major restriction of the library is that a 'SharedRep' does not have a Monad instance. In practice, this means that the external representation of lists cannot have a dynamic size.
src/Web/Rep/Socket.hs view
@@ -1,6 +1,5 @@ {-# LANGUAGE OverloadedLabels #-} {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TemplateHaskell #-} {-# OPTIONS_GHC -Wno-name-shadowing #-} @@ -54,7 +53,6 @@ import Data.Functor.Contravariant import Data.HashMap.Strict as HashMap import Data.Profunctor-import Data.String.Interpolate import Data.Text (Text) import Data.Text.Encoding import FlatParse.Basic@@ -278,11 +276,11 @@ -- | {"event":{"element":"textid","value":"abcdees"}} parserJ :: Parser e (ByteString, ByteString) parserJ = do-  _ <- $(string [i|{"event":{"element":"|])+  _ <- $(string "{\"event\":{\"element\":\"")   e <- byteStringOf $ some (satisfy (/= '"'))-  _ <- $(string [i|","value":"|])+  _ <- $(string "\",\"value\":\"")   v <- byteStringOf $ some (satisfy (/= '"'))-  _ <- $(string [i|"}}|])+  _ <- $(string "\"}}")   pure (e, v)  -- * code hooks@@ -308,31 +306,21 @@  -- | write to the console console :: ByteString -> ByteString-console t = [i| console.log(#{t}) |]+console t = " console.log(" <> t <> ") "  -- | send arbitrary byestrings. val :: ByteString -> ByteString-val t = [i| jsb.ws.send(#{t}) |]+val t = " jsb.ws.send(" <> t <> ") "  -- | replace a container and run any embedded scripts replace :: ByteString -> ByteString -> ByteString replace d t =-  [i|-     var $container = document.getElementById('#{d}');-     $container.innerHTML = '#{clean t}';-     runScripts($container);-     refreshJsb();-     |]+  "\n     var $container = document.getElementById('" <> d <> "');\n     $container.innerHTML = '" <> clean t <> "';\n     runScripts($container);\n     refreshJsb();\n     "  -- | append to a container and run any embedded scripts append :: ByteString -> ByteString -> ByteString append d t =-  [i|-     var $container = document.getElementById('#{d}');-     $container.innerHTML += '#{clean t}';-     runScripts($container);-     refreshJsb();-     |]+  "\n     var $container = document.getElementById('" <> d <> "');\n     $container.innerHTML += '" <> clean t <> "';\n     runScripts($container);\n     refreshJsb();\n     "  -- | Double backslash newline and single quotes. clean :: ByteString -> ByteString@@ -348,15 +336,7 @@ webSocket :: Js webSocket =   Js-    [i|-window.jsb = {ws: new WebSocket('ws://' + location.host + '/')};-jsb.event = function(ev) {-    jsb.ws.send(JSON.stringify({event: ev}));-};-jsb.ws.onmessage = function(evt){ -    eval('(function(){' + evt.data + '})()');-};-|]+    "\nwindow.jsb = {ws: new WebSocket('ws://' + location.host + '/')};\njsb.event = function(ev) {\n    jsb.ws.send(JSON.stringify({event: ev}));\n};\njsb.ws.onmessage = function(evt){ \n    eval('(function(){' + evt.data + '})()');  \n};\n"  -- * scripts @@ -364,68 +344,13 @@ refreshJsbJs :: Js refreshJsbJs =   Js-    [i|-function refreshJsb () {-  $('.jsbClassEventInput').off('input');-  $('.jsbClassEventInput').on('input', (function(){-    jsb.event({ 'element': this.id, 'value': this.value});-  }));-  $('.jsbClassEventChange').off('change');-  $('.jsbClassEventChange').on('change', (function(){-    jsb.event({ 'element': this.id, 'value': this.value});-  }));-  $('.jsbClassEventFocusout').off('focusout');-  $('.jsbClassEventFocusout').on('focusout', (function(){-    jsb.event({ 'element': this.id, 'value': this.value});-  }));-  $('.jsbClassEventButton').off('click');-  $('.jsbClassEventButton').on('click', (function(){-    jsb.event({ 'element': this.id, 'value': this.value});-  }));-  $('.jsbClassEventToggle').off('click');-  $('.jsbClassEventToggle').on('click', (function(){-    jsb.event({ 'element': this.id, 'value': ('true' !== this.getAttribute('aria-pressed')).toString()});-  }));-  $('.jsbClassEventCheckbox').off('click');-  $('.jsbClassEventCheckbox').on('click', (function(){-    jsb.event({ 'element': this.id, 'value': this.checked.toString()});-  }));-  $('.jsbClassEventChooseFile').off('input');-  $('.jsbClassEventChooseFile').on('input', (function(){-    jsb.event({ 'element': this.id, 'value': this.files[0].name});-  }));-  $('.jsbClassEventShowSum').off('change');-  $('.jsbClassEventShowSum').on('change', (function(){-    var v = this.value;-    $(this).parent('.sumtype-group').siblings('.subtype').each(function(i) {-      if (this.dataset.sumtype === v) {-        this.style.display = 'block';-        } else {-        this.style.display = 'none';-      }-    })-  }));-  $('.jsbClassEventChangeMultiple').off('change');-  $('.jsbClassEventChangeMultiple').on('change', (function(){-    jsb.event({ 'element': this.id, 'value': [...this.options].filter(option => option.selected).map(option => option.value).join(',')});-  }));-};-|]+    "\nfunction refreshJsb () {\n  $('.jsbClassEventInput').off('input');\n  $('.jsbClassEventInput').on('input', (function(){\n    jsb.event({ 'element': this.id, 'value': this.value});\n  }));\n  $('.jsbClassEventChange').off('change');\n  $('.jsbClassEventChange').on('change', (function(){\n    jsb.event({ 'element': this.id, 'value': this.value});\n  }));\n  $('.jsbClassEventFocusout').off('focusout');\n  $('.jsbClassEventFocusout').on('focusout', (function(){\n    jsb.event({ 'element': this.id, 'value': this.value});\n  }));\n  $('.jsbClassEventButton').off('click');\n  $('.jsbClassEventButton').on('click', (function(){\n    jsb.event({ 'element': this.id, 'value': this.value});\n  }));\n  $('.jsbClassEventToggle').off('click');\n  $('.jsbClassEventToggle').on('click', (function(){\n    jsb.event({ 'element': this.id, 'value': ('true' !== this.getAttribute('aria-pressed')).toString()});\n  }));\n  $('.jsbClassEventCheckbox').off('click');\n  $('.jsbClassEventCheckbox').on('click', (function(){\n    jsb.event({ 'element': this.id, 'value': this.checked.toString()});\n  }));\n  $('.jsbClassEventChooseFile').off('input');\n  $('.jsbClassEventChooseFile').on('input', (function(){\n    jsb.event({ 'element': this.id, 'value': this.files[0].name});\n  }));\n  $('.jsbClassEventShowSum').off('change');\n  $('.jsbClassEventShowSum').on('change', (function(){\n    var v = this.value;\n    $(this).parent('.sumtype-group').siblings('.subtype').each(function(i) {\n      if (this.dataset.sumtype === v) {\n        this.style.display = 'block';\n        } else {\n        this.style.display = 'none';\n      }\n    })\n  }));\n  $('.jsbClassEventChangeMultiple').off('change');\n  $('.jsbClassEventChangeMultiple').on('change', (function(){\n    jsb.event({ 'element': this.id, 'value': [...this.options].filter(option => option.selected).map(option => option.value).join(',')});\n  }));\n};\n"  -- | prevent the Enter key from triggering an event preventEnter :: Js preventEnter =   Js-    [i|-window.addEventListener('keydown',function(e) {-  if(e.keyIdentifier=='U+000A' || e.keyIdentifier=='Enter' || e.keyCode==13) {-    if(e.target.nodeName=='INPUT' && e.target.type !== 'textarea') {-      e.preventDefault();-      return false;-    }-  }-}, true);-|]+    "\nwindow.addEventListener('keydown',function(e) {\n  if(e.keyIdentifier=='U+000A' || e.keyIdentifier=='Enter' || e.keyCode==13) {\n    if(e.target.nodeName=='INPUT' && e.target.type !== 'textarea') {\n      e.preventDefault();\n      return false;\n    }\n  }\n}, true);\n"  -- | script injection js. --@@ -433,33 +358,7 @@ runScriptJs :: Js runScriptJs =   Js-    [i|-function insertScript ($script) {-  var s = document.createElement('script')-  s.type = 'text/javascript'-  if ($script.src) {-    s.onload = callback-    s.onerror = callback-    s.src = $script.src-  } else {-    s.textContent = $script.innerText-  }--  // re-insert the script tag so it executes.-  document.head.appendChild(s)--  // clean-up-  $script.parentNode.removeChild($script)-}--function runScripts ($container) {-  // get scripts tags from a node-  var $scripts = $container.querySelectorAll('script')-  $scripts.forEach(function ($script) {-    insertScript($script)-  })-}-|]+    "\nfunction insertScript ($script) {\n  var s = document.createElement('script')\n  s.type = 'text/javascript'\n  if ($script.src) {\n    s.onload = callback\n    s.onerror = callback\n    s.src = $script.src\n  } else {\n    s.textContent = $script.innerText\n  }\n\n  // re-insert the script tag so it executes.\n  document.head.appendChild(s)\n\n  // clean-up\n  $script.parentNode.removeChild($script)\n}\n\nfunction runScripts ($container) {\n  // get scripts tags from a node\n  var $scripts = $container.querySelectorAll('script')\n  $scripts.forEach(function ($script) {\n    insertScript($script)\n  })\n}\n"  -- | Run a Parser, throwing away leftovers. Returns Left on 'Fail' or 'Err'. runParserEither :: Parser ByteString a -> ByteString -> Either ByteString a
− test/doctests.hs
@@ -1,8 +0,0 @@-module Main where--import System.Environment (getArgs)-import Test.DocTest (mainFromCabal)-import Prelude (IO, (=<<))--main :: IO ()-main = mainFromCabal "web-rep" =<< getArgs
web-rep.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: web-rep-version: 0.14.0.0+version: 0.14.0.1 license: BSD-3-Clause license-file: LICENSE copyright: Tony Day (c) 2015@@ -19,6 +19,7 @@   ghc ==9.8.4   ghc ==9.10.2   ghc ==9.12.2+  ghc ==9.14.1  extra-doc-files:   ChangeLog.md@@ -84,7 +85,6 @@     optics-extra >=0.4 && <0.5,     profunctors >=5.6.2 && <5.7,     scotty >=0.11.5 && <0.23,-    string-interpolate >=0.3 && <0.4,     text >=1.2 && <2.2,     transformers >=0.5.6 && <0.6.2,     unordered-containers >=0.2 && <0.3,@@ -120,13 +120,3 @@     optparse-applicative >=0.17 && <0.20,     web-rep, -test-suite doctests-  import: ghc2024-stanza-  main-is: doctests.hs-  hs-source-dirs: test-  build-depends:-    base >=4.14 && <5,-    doctest-parallel >=0.3 && <0.5,--  ghc-options: -threaded-  type: exitcode-stdio-1.0