about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/html/dom.nim4
-rw-r--r--src/local/container.nim25
-rw-r--r--src/server/buffer.nim27
3 files changed, 35 insertions, 21 deletions
diff --git a/src/html/dom.nim b/src/html/dom.nim
index 39083db2..a452442a 100644
--- a/src/html/dom.nim
+++ b/src/html/dom.nim
@@ -2653,8 +2653,8 @@ func parseURL*(document: Document, s: string): Option[URL] =
 func media*[T: HTMLLinkElement|HTMLStyleElement](element: T): string =
   return element.attr(atMedia)
 
-func title*(document: Document): string =
-  for title in document.elements(TAG_TITLE):
+func title*(document: Document): string {.jsfget.} =
+  if (let title = document.findFirst(TAG_TITLE); title != nil):
     return title.childTextContent.stripAndCollapse()
   return ""
 
diff --git a/src/local/container.nim b/src/local/container.nim
index c44a9bc7..b5049edc 100644
--- a/src/local/container.nim
+++ b/src/local/container.nim
@@ -312,7 +312,7 @@ func maxScreenWidth(container: Container): int =
   for line in container.ilines(container.fromy..container.lastVisibleLine):
     result = max(line.str.width(), result)
 
-func getTitle*(container: Container): string {.jsfunc.} =
+func getTitle*(container: Container): string {.jsfget: "title".} =
   if container.title != "":
     return container.title
   return container.url.serialize(excludepassword = true)
@@ -1370,11 +1370,6 @@ proc onload*(container: Container, res: int) =
     container.setLoadInfo("")
     container.triggerEvent(cetStatus)
     container.triggerEvent(cetLoaded)
-    container.iface.getTitle().then(proc(title: string) =
-      if title != "":
-        container.title = title
-        container.triggerEvent(cetTitle)
-    )
     if cfHasStart notin container.flags and container.url.anchor != "":
       container.requestLines().then(proc(): Promise[Opt[tuple[x, y: int]]] =
         return container.iface.gotoAnchor()
@@ -1585,22 +1580,28 @@ proc handleCommand(container: Container) =
   container.iface.stream.sread(packetid)
   container.iface.resolve(packetid, len - slen(packetid))
 
+proc startLoad(container: Container) =
+  container.iface.load().then(proc(res: int) =
+    container.onload(res)
+  )
+  container.iface.getTitle().then(proc(title: string) =
+    if title != "":
+      container.title = title
+      container.triggerEvent(cetTitle)
+  )
+
 proc setStream*(container: Container; stream: SocketStream;
     registerFun: proc(fd: int)) =
   assert cfCloned notin container.flags
   container.iface = newBufferInterface(stream, registerFun)
-  discard container.iface.load().then(proc(res: int) =
-    container.onload(res)
-  )
+  container.startLoad()
 
 proc setCloneStream*(container: Container; stream: SocketStream;
     registerFun: proc(fd: int)) =
   assert cfCloned in container.flags
   container.iface = cloneInterface(stream, registerFun)
   # Maybe we have to resume loading. Let's try.
-  discard container.iface.load().then(proc(res: int) =
-    container.onload(res)
-  )
+  container.startLoad()
 
 proc onreadline(container: Container, w: Slice[int],
     handle: (proc(line: SimpleFlexibleLine)), res: GetLinesResult) =
diff --git a/src/server/buffer.nim b/src/server/buffer.nim
index ec2a8731..70b25aa9 100644
--- a/src/server/buffer.nim
+++ b/src/server/buffer.nim
@@ -1106,10 +1106,12 @@ proc load*(buffer: Buffer): int {.proxy, task.} =
     buffer.savetask = true
     return -2 # unused
 
-proc resolveTask[T](buffer: Buffer, cmd: BufferCommand, res: T) =
+proc hasTask(buffer: Buffer; cmd: BufferCommand): bool =
+  return buffer.tasks[cmd] != 0
+
+proc resolveTask[T](buffer: Buffer; cmd: BufferCommand; res: T) =
   let packetid = buffer.tasks[cmd]
-  if packetid == 0:
-    return # no task to resolve (TODO this is kind of inefficient)
+  assert packetid != 0
   let len = slen(buffer.tasks[cmd]) + slen(res)
   buffer.pstream.withWriter w:
     w.swrite(len)
@@ -1120,7 +1122,8 @@ proc resolveTask[T](buffer: Buffer, cmd: BufferCommand, res: T) =
 proc onload(buffer: Buffer) =
   case buffer.state
   of bsLoadingResources, bsLoaded:
-    buffer.resolveTask(bcLoad, -1)
+    if buffer.hasTask(bcLoad):
+      buffer.resolveTask(bcLoad, -1)
     return
   of bsLoadingPage:
     discard
@@ -1147,7 +1150,10 @@ proc onload(buffer: Buffer) =
           buffer.state = bsLoaded
           buffer.document.readyState = rsComplete
           buffer.dispatchLoadEvent()
-          buffer.resolveTask(bcLoad, -1)
+          if buffer.hasTask(bcGetTitle):
+            buffer.resolveTask(bcGetTitle, buffer.document.title)
+          if buffer.hasTask(bcLoad):
+            buffer.resolveTask(bcLoad, -1)
         )
         return # skip incr render
     except ErrorAgain:
@@ -1158,11 +1164,18 @@ proc onload(buffer: Buffer) =
     # only makes sense when not in dump mode (and the user has requested a load)
     buffer.do_reshape()
     buffer.reportedBytesRead = buffer.bytesRead
-    buffer.resolveTask(bcLoad, buffer.bytesRead)
+    if buffer.hasTask(bcGetTitle):
+      buffer.resolveTask(bcGetTitle, buffer.document.title)
+    if buffer.hasTask(bcLoad):
+      buffer.resolveTask(bcLoad, buffer.bytesRead)
 
 proc getTitle*(buffer: Buffer): string {.proxy.} =
   if buffer.document != nil:
-    return buffer.document.title
+    let title = buffer.document.findFirst(TAG_TITLE)
+    if title != nil:
+      return title.childTextContent.stripAndCollapse()
+  buffer.savetask = true
+  return ""
 
 proc forceRender*(buffer: Buffer) {.proxy.} =
   buffer.prevStyled = nil