diff options
author | Dougal <d.maclaurin@gmail.com> | 2023-11-29 10:44:20 -0500 |
---|---|---|
committer | Dougal <d.maclaurin@gmail.com> | 2023-11-29 10:44:20 -0500 |
commit | a97a641ed83ba49303ea2b370f091ec997d2b8d4 (patch) | |
tree | f1d8337f5fef3ad2c8cf05a683c872ca88cb97f2 | |
parent | 9de972dc8115ff272ebd114746c8c51d3e151c5f (diff) |
Plumbing for adding textual information on hover.
-rw-r--r-- | src/lib/Live/Eval.hs | 12 | ||||
-rw-r--r-- | static/dynamic.html | 6 | ||||
-rw-r--r-- | static/index.js | 23 | ||||
-rw-r--r-- | static/style.css | 38 |
4 files changed, 46 insertions, 33 deletions
diff --git a/src/lib/Live/Eval.hs b/src/lib/Live/Eval.hs index fadbd02a..730c6092 100644 --- a/src/lib/Live/Eval.hs +++ b/src/lib/Live/Eval.hs @@ -17,6 +17,7 @@ import Control.Monad.Writer.Strict import qualified Data.Map.Strict as M import Data.Aeson (ToJSON, ToJSONKey, toJSON, Value) import Data.Functor ((<&>)) +import Data.Foldable (toList) import Data.Maybe (fromJust) import Data.Text (Text) import Prelude hiding (span) @@ -319,6 +320,7 @@ data SourceBlockJSONData = SourceBlockJSONData , jdLexemeList :: [SrcId] , jdFocusMap :: FocusMap , jdHighlightMap :: HighlightMap + , jdHoverInfoMap :: HoverInfoMap , jdHTML :: String } deriving (Generic) instance ToJSON SourceBlockJSONData @@ -330,6 +332,7 @@ instance ToJSON SourceBlockWithId where , jdLexemeList = unsnoc $ lexemeList $ sbLexemeInfo b' , jdFocusMap = computeFocus b' , jdHighlightMap = computeHighlights b' + , jdHoverInfoMap = computeHoverInfo b' , jdHTML = pprintHtml b } instance ToJSON Result where toJSON = toJSONViaHtml @@ -337,6 +340,15 @@ instance ToJSON Result where toJSON = toJSONViaHtml toJSONViaHtml :: ToMarkup a => a -> Value toJSONViaHtml x = toJSON $ pprintHtml x +-- === textual information on hover === + +type HoverInfo = String +newtype HoverInfoMap = HoverInfoMap (M.Map LexemeId HoverInfo) deriving (ToJSON, Semigroup, Monoid) + +computeHoverInfo :: SourceBlock -> HoverInfoMap +computeHoverInfo sb = HoverInfoMap $ + M.fromList $ toList (lexemeList (sbLexemeInfo sb)) <&> \srcId -> (srcId, show srcId) + -- === highlighting on hover === -- TODO: put this somewhere else, like RenderHtml or something diff --git a/static/dynamic.html b/static/dynamic.html index 5e636424..eb0111d1 100644 --- a/static/dynamic.html +++ b/static/dynamic.html @@ -21,8 +21,10 @@ </head> <body> -<main id="main-output"></main> - + <div id="hover-info"> + (hover over code for more information) + </div> + <main id="main-output"></main> <script src="/index.js""></script> </body> diff --git a/static/index.js b/static/index.js index 725cb7a8..842acc81 100644 --- a/static/index.js +++ b/static/index.js @@ -44,6 +44,7 @@ var RENDER_MODE = Object.freeze({ // mapping from server-provided NodeID to HTML id var cells = {}; var body = document.getElementById("main-output"); +var hoverInfoDiv = document.getElementById("hover-info"); /** * Renders the webpage. @@ -71,8 +72,23 @@ function render(renderMode) { function attachHovertip(cellCtx, srcId) { let span = selectSpan(cellCtx, srcId); - span.addEventListener("mouseover", (event) => toggleSpan(event, cellCtx, srcId)); - span.addEventListener("mouseout" , (event) => toggleSpan(event, cellCtx, srcId));} + span.addEventListener("mouseover", function (event) { + addHoverInfo(cellCtx, srcId); + toggleSpan(event, cellCtx, srcId);}) + span.addEventListener("mouseout" , function(event) { + removeHoverInfo(); + toggleSpan(event, cellCtx, srcId)}); +} + +function addHoverInfo(cellCtx, srcId) { + let [ , , , , hoverInfoMap] = cellCtx + s = hoverInfoMap[srcId.toString()] + hoverInfoDiv.innerHTML = s; +} + +function removeHoverInfo() { + hoverInfoDiv.innerHTML = ""; +} function selectSpan(cellCtx, srcId) { let [cell, blockId, , ] = cellCtx @@ -180,7 +196,8 @@ function processUpdate(msg) { let lexemeList = source["jdLexemeList"]; let focusMap = source["jdFocusMap"]; let highlightMap = source["jdHighlightMap"]; - cellCtx = [cell, blockId, focusMap, highlightMap]; + let hoverInfoMap = source["jdHoverInfoMap"]; + cellCtx = [cell, blockId, focusMap, highlightMap, hoverInfoMap]; lexemeList.map(function (lexemeId) {attachHovertip(cellCtx, lexemeId)}) } }); diff --git a/static/style.css b/static/style.css index 6132484d..5c83bb2c 100644 --- a/static/style.css +++ b/static/style.css @@ -11,42 +11,25 @@ body { display: flex; justify-content: space-between; overflow-x: hidden; - --main-width: 50rem; - --nav-width: 20rem; + padding-bottom:50vw; } -@media (max-width: 70rem) { - /*For narrow screens hide nav and enable horizontal scrolling */ - nav {display: none;} - body {overflow-x: auto;} -} - -nav {/* this actually just holds space for #navbar, which is fixed */ - min-width: var(--nav-width); - max-width: var(--nav-width); -} -#navbar { +#hover-info { position: fixed; - height: 100vh; - width: var(--nav-width); - overflow-y: scroll; - border-right: 1px solid firebrick; -} -#navbar:before { - content: "Contents"; - font-weight: bold; -} -nav ol { - list-style-type:none; - padding-left: 1rem; + height: 10rem; + bottom: 0em; + width: 100vw; + overflow: hidden; + background-color: white; + border-top: 1px solid firebrick; + font-family: monospace; + white-space: pre; } #main-output { - max-width: var(--main-width); margin: auto; } - .code-block { } @@ -128,7 +111,6 @@ code { text-align: right; } - .waiting-cell { border-left: 6px solid #AAAAFF; } |