diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/html/dom.nim | 8 | ||||
-rw-r--r-- | src/local/container.nim | 14 | ||||
-rw-r--r-- | src/local/pager.nim | 3 | ||||
-rw-r--r-- | src/server/buffer.nim | 46 | ||||
-rw-r--r-- | src/types/urimethodmap.nim | 2 |
5 files changed, 63 insertions, 10 deletions
diff --git a/src/html/dom.nim b/src/html/dom.nim index 163e4a66..39083db2 100644 --- a/src/html/dom.nim +++ b/src/html/dom.nim @@ -3334,8 +3334,8 @@ proc insertNode(parent, node, before: Node) = insertionSteps(node) # WARNING ditto -proc insert*(parent, node, before: Node, suppressObservers = false) = - let nodes = if node of DocumentFragment: +proc insert*(parent, node, before: Node; suppressObservers = false) = + var nodes = if node of DocumentFragment: node.childList else: @[node] @@ -3381,7 +3381,7 @@ proc removeChild(parent, node: Node): DOMResult[Node] {.jsfunc.} = # doesn't match that # Note: the standard returns child if not err. We don't, it's just a # pointless copy. -proc replace(parent, child, node: Node): Err[DOMException] = +proc replace*(parent, child, node: Node): Err[DOMException] = ?checkParentValidity(parent) if node.isHostIncludingInclusiveAncestor(parent): return errDOMException("Parent must be an ancestor", @@ -4036,7 +4036,7 @@ proc toBlob(ctx: JSContext, this: HTMLCanvasElement, callback: JSValue, import html/chadombuilder # https://w3c.github.io/DOM-Parsing/#dfn-fragment-parsing-algorithm -proc fragmentParsingAlgorithm(element: Element, s: string): DocumentFragment = +proc fragmentParsingAlgorithm*(element: Element; s: string): DocumentFragment = #TODO xml let newChildren = parseHTMLFragment(element, s) let fragment = element.document.newDocumentFragment() diff --git a/src/local/container.nim b/src/local/container.nim index e722ccfd..d706b77c 100644 --- a/src/local/container.nim +++ b/src/local/container.nim @@ -149,6 +149,7 @@ type tailOnLoad*: bool cacheFile* {.jsget.}: string userRequested*: bool + mainConfig*: Config jsDestructor(Highlight) jsDestructor(Container) @@ -157,7 +158,7 @@ proc newContainer*(config: BufferConfig; loaderConfig: LoaderClientConfig; url: URL; request: Request; attrs: WindowAttributes; title: string; redirectDepth: int; canReinterpret: bool; contentType: Option[string]; charsetStack: seq[Charset]; cacheId: int; cacheFile: string; - userRequested: bool): Container = + userRequested: bool; mainConfig: Config): Container = return Container( url: url, request: request, @@ -176,7 +177,8 @@ proc newContainer*(config: BufferConfig; loaderConfig: LoaderClientConfig; cacheId: cacheId, cacheFile: cacheFile, process: -1, - userRequested: userRequested + userRequested: userRequested, + mainConfig: mainConfig ) func location(container: Container): URL {.jsfget.} = @@ -1344,6 +1346,14 @@ proc getSelectionText(container: Container, hl: Highlight = nil): return s ) +proc markURL(container: Container) {.jsfunc.} = + var schemes: seq[string] = @[] + for key in container.mainConfig.external.urimethodmap.map.keys: + schemes.add(key.until(':')) + container.iface.markURL(schemes).then(proc() = + container.needslines = true + ) + proc setLoadInfo(container: Container, msg: string) = container.loadinfo = msg container.triggerEvent(cetSetLoadInfo) diff --git a/src/local/pager.nim b/src/local/pager.nim index 627a7b08..e7d771c0 100644 --- a/src/local/pager.nim +++ b/src/local/pager.nim @@ -533,7 +533,8 @@ proc newContainer(pager: Pager; bufferConfig: BufferConfig; charsetStack, cacheId, cacheFile, - userRequested + userRequested, + pager.config ) pager.connectingContainers.add(ConnectingContainerItem( state: ccsBeforeResult, diff --git a/src/server/buffer.nim b/src/server/buffer.nim index 7bdd46d0..43b08b18 100644 --- a/src/server/buffer.nim +++ b/src/server/buffer.nim @@ -1,4 +1,4 @@ -from std/strutils import split, toUpperAscii +from std/strutils import split, toUpperAscii, find import std/macros import std/nativesockets @@ -11,6 +11,7 @@ import std/streams import std/tables import std/unicode +import bindings/libregexp import bindings/quickjs import config/config import css/cascade @@ -64,7 +65,7 @@ type bcReadSuccess, bcReadCanceled, bcClick, bcFindNextLink, bcFindPrevLink, bcFindNthLink, bcFindRevNthLink, bcFindNextMatch, bcFindPrevMatch, bcGetLines, bcUpdateHover, bcGotoAnchor, bcCancel, bcGetTitle, bcSelect, - bcClone, bcFindPrevParagraph, bcFindNextParagraph + bcClone, bcFindPrevParagraph, bcFindNextParagraph, bcMarkURL BufferState = enum bsLoadingPage, bsLoadingResources, bsLoaded @@ -1649,6 +1650,47 @@ proc getLines*(buffer: Buffer, w: Slice[int]): GetLinesResult {.proxy.} = result.numLines = buffer.lines.len result.bgcolor = buffer.bgcolor +proc markURL*(buffer: Buffer; schemes: seq[string]) {.proxy.} = + if buffer.document == nil or buffer.document.body == nil: + return + var buf = "(" + for i, scheme in schemes: + if i > 0: + buf &= '|' + buf &= scheme + buf &= r"):(//[\w%:.-]+)?[\w/@%:.~-]*\??[\w%:~.=&]*#?[\w:~.=-]*[\w/~=-]" + let regex = compileRegex(buf, {LRE_FLAG_GLOBAL}).get + # Dummy element for the fragment parsing algorithm. We can't just use parent + # there, because e.g. plaintext would not parse the text correctly. + let html = buffer.document.newHTMLElement(TAG_DIV) + var stack = @[buffer.document.body] + while stack.len > 0: + let element = stack.pop() + for i in countdown(element.childList.high, 0): + let node = element.childList[i] + if node of Text: + let text = Text(node) + var res = regex.exec(text.data) + if res.success: + var data = text.data + var offset = 0 + for cap in res.captures.mitems: + if cap.i != 0: + continue + cap.s += offset + cap.e += offset + let s = data[cap.s..<cap.e] + let news = "<a href=\"" & s & "\">" & s.htmlEscape() & "</a>" + data[cap.s..<cap.e] = news + offset += news.len - (cap.e - cap.s) + let replacement = html.fragmentParsingAlgorithm(data) + discard element.replace(text, replacement) + elif node of HTMLElement: + let element = HTMLElement(node) + if element.tagType notin {TAG_HEAD, TAG_SCRIPT, TAG_STYLE, TAG_A}: + stack.add(element) + buffer.do_reshape() + macro bufferDispatcher(funs: static ProxyMap, buffer: Buffer, cmd: BufferCommand, packetid: int) = let switch = newNimNode(nnkCaseStmt) diff --git a/src/types/urimethodmap.nim b/src/types/urimethodmap.nim index 464c9b69..41e887c6 100644 --- a/src/types/urimethodmap.nim +++ b/src/types/urimethodmap.nim @@ -8,7 +8,7 @@ import types/url import utils/twtstr type URIMethodMap* = object - map: Table[string, string] + map*: Table[string, string] func rewriteURL(pattern, surl: string): string = result = "" |