about summary refs log tree commit diff stats
path: root/src/buffer
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2022-12-16 20:58:48 +0100
committerbptato <nincsnevem662@gmail.com>2022-12-16 21:01:11 +0100
commita316ae2406bd4d0f1006cdcb572a06b772b10237 (patch)
treea342d673aaf18284103ef78279c8f22b9d8e55d6 /src/buffer
parentc1c5a64ebb7bcc6deace0dce6f6a530039302f7e (diff)
downloadchawan-a316ae2406bd4d0f1006cdcb572a06b772b10237.tar.gz
Allow cycling through hover-texts with u
Diffstat (limited to 'src/buffer')
-rw-r--r--src/buffer/buffer.nim53
-rw-r--r--src/buffer/container.nim34
2 files changed, 59 insertions, 28 deletions
diff --git a/src/buffer/buffer.nim b/src/buffer/buffer.nim
index 8bfd3f6e..f20804c7 100644
--- a/src/buffer/buffer.nim
+++ b/src/buffer/buffer.nim
@@ -51,6 +51,10 @@ type
     GET_SOURCE, GET_LINES, UPDATE_HOVER, PASS_FD, CONNECT, GOTO_ANCHOR, CANCEL,
     GET_TITLE
 
+  HoverType* = enum
+    HOVER_TITLE = "TITLE"
+    HOVER_LINK = "URL"
+
   BufferMatch* = object
     success*: bool
     x*: int
@@ -88,7 +92,7 @@ type
     timeouts: Table[int, (proc())]
     tasks: array[BufferCommand, int] #TODO this should have arguments
     savetask: bool
-    hovertext: string
+    hovertext: array[HoverType, string]
 
   # async, but worse
   EmptyPromise = ref object of RootObj
@@ -280,15 +284,6 @@ func getTitleAttr(node: StyledNode): string =
         return element.attr("title")
   #TODO pseudo-elements
 
-func getLink(node: StyledNode): HTMLAnchorElement =
-  if node == nil:
-    return nil
-  if node.t == STYLED_ELEMENT and node.node != nil and Element(node.node).tagType == TAG_A:
-    return HTMLAnchorElement(node.node)
-  if node.node != nil:
-    return HTMLAnchorElement(node.node.findAncestor({TAG_A}))
-  #TODO ::before links?
-
 const ClickableElements = {
   TAG_A, TAG_INPUT, TAG_OPTION, TAG_BUTTON, TAG_TEXTAREA
 }
@@ -302,6 +297,22 @@ func getClickable(styledNode: StyledNode): Element =
       return element
   styledNode.node.findAncestor(ClickableElements)
 
+func getClickHover(styledNode: StyledNode): string =
+  let clickable = styledNode.getClickable()
+  if clickable != nil:
+    case clickable.tagType
+    of TAG_A:
+      return HTMLAnchorElement(clickable).href
+    of TAG_INPUT:
+      return "<input>"
+    of TAG_OPTION:
+      return "<option>"
+    of TAG_BUTTON:
+      return "<button>"
+    of TAG_TEXTAREA:
+      return "<textarea>"
+    else: discard
+
 func getCursorClickable(buffer: Buffer, cursorx, cursory: int): Element =
   let i = buffer.lines[cursory].findFormatN(cursorx) - 1
   if i >= 0:
@@ -489,7 +500,8 @@ proc windowChange*(buffer: Buffer, attrs: WindowAttributes) {.proxy.} =
   buffer.height = buffer.attrs.height - 1
 
 type UpdateHoverResult* = object
-  hover*: Option[string]
+  link*: Option[string]
+  title*: Option[string]
   repaint*: bool
 
 proc updateHover*(buffer: Buffer, cursorx, cursory: int): UpdateHoverResult {.proxy.} =
@@ -508,19 +520,14 @@ proc updateHover*(buffer: Buffer, cursorx, cursory: int): UpdateHoverResult {.pr
           elem.hover = true
           result.repaint = true
 
-    var upd = false
     let title = thisnode.getTitleAttr()
-    if title != "":
-      upd = true
-      buffer.hovertext = title
-    elif (let link = thisnode.getLink(); link != nil):
-      upd = true
-      buffer.hovertext = link.href
-    else:
-      upd = buffer.hovertext != ""
-      buffer.hovertext = ""
-    if upd:
-      result.hover = some(buffer.hovertext)
+    if buffer.hovertext[HOVER_TITLE] != title:
+      result.title = some(title)
+      buffer.hovertext[HOVER_TITLE] = title
+    let click = thisnode.getClickHover()
+    if buffer.hovertext[HOVER_LINK] != click:
+      result.link = some(click)
+      buffer.hovertext[HOVER_LINK] = click
 
     for styledNode in prevnode.branch:
       if styledNode.t == STYLED_ELEMENT and styledNode.node != nil:
diff --git a/src/buffer/container.nim b/src/buffer/container.nim
index 80044b60..66ef2780 100644
--- a/src/buffer/container.nim
+++ b/src/buffer/container.nim
@@ -72,7 +72,8 @@ type
     height*: int
     contenttype*: Option[string]
     title*: string
-    hovertext*: string
+    hovertext*: array[HoverType, string]
+    lastpeek: HoverType
     source*: BufferSource
     pos: CursorPosition
     bpos: seq[CursorPosition]
@@ -257,6 +258,11 @@ func findHighlights*(container: Container, y: int): seq[Highlight] =
     if y in hl:
       result.add(hl)
 
+func getHoverText*(container: Container): string =
+  for t in HoverType:
+    if container.hovertext[t] != "":
+      return container.hovertext[t]
+
 proc triggerEvent(container: Container, event: ContainerEvent) =
   container.events.addLast(event)
 
@@ -291,8 +297,11 @@ proc redraw*(container: Container) {.jsfunc.} =
 
 proc sendCursorPosition(container: Container) =
   container.iface.updateHover(container.cursorx, container.cursory).then(proc(res: UpdateHoverResult) =
-    if res.hover.isSome:
-      container.hovertext = res.hover.get
+    if res.link.isSome:
+      container.hovertext[HOVER_LINK] = res.link.get
+    if res.title.isSome:
+      container.hovertext[HOVER_TITLE] = res.title.get
+    if res.link.isSome or res.title.isSome:
       container.triggerEvent(STATUS)
     if res.repaint:
       container.needslines = true)
@@ -754,9 +763,24 @@ proc windowChange*(container: Container, attrs: WindowAttributes) =
 proc peek*(container: Container) {.jsfunc.} =
   container.alert($container.source.location)
 
+proc clearHover*(container: Container) =
+  container.lastpeek = low(HoverType)
+
 proc peekCursor*(container: Container) {.jsfunc.} =
-  if container.hovertext != "":
-    container.alert(container.hovertext)
+  var p = container.lastpeek
+  while true:
+    if container.hovertext[p] != "":
+      container.alert($p & ": " & container.hovertext[p])
+      break
+    if p < high(HoverType):
+      inc p
+    else:
+      p = low(HoverType)
+    if p == container.lastpeek: break
+  if container.lastpeek < high(HoverType):
+    inc container.lastpeek
+  else:
+    container.lastpeek = low(HoverType)
 
 proc handleCommand(container: Container) =
   var packetid, len: int