summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDougal <d.maclaurin@gmail.com>2023-11-29 10:44:20 -0500
committerDougal <d.maclaurin@gmail.com>2023-11-29 10:44:20 -0500
commita97a641ed83ba49303ea2b370f091ec997d2b8d4 (patch)
treef1d8337f5fef3ad2c8cf05a683c872ca88cb97f2
parent9de972dc8115ff272ebd114746c8c51d3e151c5f (diff)
Plumbing for adding textual information on hover.
-rw-r--r--src/lib/Live/Eval.hs12
-rw-r--r--static/dynamic.html6
-rw-r--r--static/index.js23
-rw-r--r--static/style.css38
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;
}