about summary refs log tree commit diff stats
path: root/src/io
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2022-01-23 01:02:44 +0100
committerbptato <nincsnevem662@gmail.com>2022-01-23 01:02:44 +0100
commit010185f7c306f2465b691a82fcbfe1c76513f8fc (patch)
treeb755627c1ff776485cf04a469d3dcdeebe2639c8 /src/io
parent6ff61c5ad2ad2af36195b83582ed98be57b93f18 (diff)
downloadchawan-010185f7c306f2465b691a82fcbfe1c76513f8fc.tar.gz
Support external stylesheets
Diffstat (limited to 'src/io')
-rw-r--r--src/io/buffer.nim17
-rw-r--r--src/io/loader.nim33
2 files changed, 49 insertions, 1 deletions
diff --git a/src/io/buffer.nim b/src/io/buffer.nim
index f219fe2c..a082cfe3 100644
--- a/src/io/buffer.nim
+++ b/src/io/buffer.nim
@@ -8,8 +8,9 @@ import css/sheet
 import html/dom
 import html/tags
 import html/parser
-import io/term
 import io/cell
+import io/loader
+import io/term
 import layout/box
 import render/renderdocument
 import render/rendertext
@@ -49,6 +50,7 @@ type
     prev*: Buffer
     next* {.cursor.}: Buffer
     userstyle*: CSSStylesheet
+    loader*: FileLoader
 
 proc newBuffer*(): Buffer =
   new(result)
@@ -711,6 +713,17 @@ proc updateHover(buffer: Buffer) =
         elem.refreshStyle()
   buffer.prevnodes = nodes
 
+proc loadResources(buffer: Buffer, document: Document) =
+  for elem in document.head.children:
+    if elem.tagType == TAG_LINK:
+      let elem = HTMLLinkElement(elem)
+      if elem.rel == "stylesheet":
+        let url = parseUrl(elem.href, document.location.some)
+        if url.issome:
+          let res = buffer.loader.getPage(url.get)
+          if res.s != nil and res.contenttype == "text/css":
+            elem.s = res.s
+
 proc load*(buffer: Buffer) =
   case buffer.contenttype
   of "text/html":
@@ -723,6 +736,8 @@ proc load*(buffer: Buffer) =
       buffer.istream.close()
       buffer.streamclosed = true
     buffer.document = parseHtml(newStringStream(buffer.source))
+    buffer.document.location = buffer.location
+    buffer.loadResources(buffer.document)
   else:
     if not buffer.streamclosed:
       buffer.source = buffer.istream.readAll()
diff --git a/src/io/loader.nim b/src/io/loader.nim
new file mode 100644
index 00000000..3ef5320e
--- /dev/null
+++ b/src/io/loader.nim
@@ -0,0 +1,33 @@
+import httpclient
+import options
+import streams
+
+import types/mime
+import types/url
+import utils/twtstr
+
+type
+  FileLoader* = ref object
+    http: HttpClient
+
+  LoadResult* = object
+    s*: Stream
+    contenttype*: string
+
+proc newFileLoader*(): FileLoader =
+  new(result)
+  result.http = newHttpClient()
+
+proc getPage*(loader: FileLoader, url: Url): LoadResult =
+  if url.scheme == "file":
+    let path = url.path.serialize_unicode()
+    result.contenttype = guessContentType(path)
+    result.s = newFileStream(path, fmRead)
+  elif url.scheme == "http" or url.scheme == "https":
+    let resp = loader.http.get(url.serialize(true))
+    let ct = resp.contentType()
+    if ct != "":
+      result.contenttype = ct.until(';')
+    else:
+      result.contenttype = guessContentType(url.path.serialize())
+    result.s = resp.bodyStream