diff options
author | bptato <nincsnevem662@gmail.com> | 2022-09-13 20:44:55 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2022-09-13 20:44:55 +0200 |
commit | 51d83224320b8bd4e81332802bb62158ae6deec5 (patch) | |
tree | 4bfb320d7960f78a68de857f26d43ff2f59bea57 /src/html | |
parent | 51ea622d58bfca19212fac1800cfb033bb85ec39 (diff) | |
download | chawan-51d83224320b8bd4e81332802bb62158ae6deec5.tar.gz |
More JS bindings
Diffstat (limited to 'src/html')
-rw-r--r-- | src/html/dom.nim | 75 | ||||
-rw-r--r-- | src/html/htmlparser.nim | 22 | ||||
-rw-r--r-- | src/html/htmltokenizer.nim | 2 |
3 files changed, 84 insertions, 15 deletions
diff --git a/src/html/dom.nim b/src/html/dom.nim index 4bf73302..9c0f0a59 100644 --- a/src/html/dom.nim +++ b/src/html/dom.nim @@ -5,6 +5,7 @@ import tables import css/sheet import html/tags +import js/javascript import types/url import utils/twtstr @@ -34,7 +35,7 @@ type Node* = ref object of EventTarget nodeType*: NodeType - childNodes*: seq[Node] + childNodes* {.jsget.}: seq[Node] nextSibling*: Node previousSibling*: Node parentNode*: Node @@ -83,7 +84,7 @@ type id*: string classList*: seq[string] - attributes*: Table[string, string] + attributes* {.jsget, jsset.}: Table[string, string] hover*: bool invalid*: bool @@ -97,7 +98,7 @@ type inputType*: InputType autofocus*: bool required*: bool - value*: string + value* {.jsget.}: string size*: int checked*: bool xcoord*: int @@ -129,7 +130,7 @@ type start*: Option[int] HTMLLIElement* = ref object of HTMLElement - value*: Option[int] + value* {.jsget.}: Option[int] HTMLStyleElement* = ref object of HTMLElement sheet*: CSSStylesheet @@ -199,6 +200,11 @@ iterator children_rev*(node: Node): Element {.inline.} = if child.nodeType == ELEMENT_NODE: yield Element(child) +#TODO TODO TODO this should return a live view instead +proc children*(node: Node): seq[Element] {.jsget.} = + for child in node.children: + result.add(child) + # Returns the node's ancestors iterator ancestors*(node: Node): Element {.inline.} = var element = node.parentElement @@ -415,7 +421,7 @@ func attrb*(element: Element, s: string): bool = return true return false -func textContent*(node: Node): string = +func textContent*(node: Node): string {.jsget.} = case node.nodeType of DOCUMENT_NODE, DOCUMENT_TYPE_NODE: return "" #TODO null @@ -533,7 +539,7 @@ func formmethod*(element: Element): FormMethod = return FORM_METHOD_GET -func target*(element: Element): string = +func target*(element: Element): string {.jsfunc.} = if element.attrb("target"): return element.attr("target") for base in element.document.elements(TAG_BASE): @@ -547,13 +553,13 @@ func findAncestor*(node: Node, tagTypes: set[TagType]): Element = return element return nil -func newText*(document: Document, data: string = ""): Text = +func newText*(document: Document, data: string = ""): Text {.jsctor.} = new(result) result.nodeType = TEXT_NODE result.document = document result.data = data -func newComment*(document: Document, data: string = ""): Comment = +func newComment*(document: Document = nil, data: string = ""): Comment {.jsctor.} = new(result) result.nodeType = COMMENT_NODE result.document = document @@ -617,12 +623,12 @@ func newHTMLElement*(document: Document, localName: string, namespace = Namespac if tagType == TAG_UNKNOWN: result.localName = localName -func newDocument*(): Document = +func newDocument*(): Document {.jsctor.} = new(result) result.nodeType = DOCUMENT_NODE result.document = result -func newDocumentType*(document: Document, name: string, publicId = "", systemId = ""): DocumentType = +func newDocumentType*(document: Document, name: string, publicId = "", systemId = ""): DocumentType {.jsctor.} = new(result) result.document = document result.name = name @@ -637,13 +643,20 @@ func newAttr*(parent: Element, key, value: string): Attr = result.name = key result.value = value -func getElementById*(node: Node, id: string): Element = +func getElementById*(node: Node, id: string): Element {.jsfunc.} = if id.len == 0: return nil for child in node.elements: if child.id == id: return child +func getElementById2*(node: Node, id: string): pointer = + if id.len == 0: + return nil + for child in node.elements: + if child.id == id: + return cast[pointer](child) + func getElementsByTag*(document: Document, tag: TagType): seq[Element] = for element in document.elements(tag): result.add(element) @@ -709,7 +722,7 @@ func text*(option: HTMLOptionElement): string = if child.parentElement.tagType != TAG_SCRIPT: #TODO svg result &= child.data.stripAndCollapse() -func value*(option: HTMLOptionElement): string = +func value*(option: HTMLOptionElement): string {.jsget.} = if option.attrb("value"): return option.attr("value") return option.childTextContent.stripAndCollapse() @@ -960,3 +973,41 @@ proc appendAttribute*(element: Element, k, v: string) = select.size = 4 else: discard element.attributes[k] = v + +var doqsa*: proc (node: Node, q: string): seq[Element] +var doqs*: proc (node: Node, q: string): Element + +proc querySelectorAll*(node: Node, q: string): seq[Element] {.jsfunc.} = + return doqsa(node, q) + +proc querySelector*(node: Node, q: string): Element {.jsfunc.} = + return doqs(node, q) + +proc addDOMModule*(ctx: JSContext) = + let eventTargetCID = ctx.registerType(EventTarget) + let nodeCID = ctx.registerType(Node, parent = eventTargetCID) + ctx.registerType(Document, parent = nodeCID) + let characterDataCID = ctx.registerType(CharacterData, parent = nodeCID) + ctx.registerType(Comment, parent = characterDataCID) + ctx.registerType(Text, parent = characterDataCID) + ctx.registerType(DocumentType, parent = nodeCID) + let elementCID = ctx.registerType(Element, parent = nodeCID) + let htmlElementCID = ctx.registerType(HTMLElement, parent = elementCID) + ctx.registerType(HTMLInputElement, parent = htmlElementCID) + ctx.registerType(HTMLAnchorElement, parent = htmlElementCID) + ctx.registerType(HTMLSelectElement, parent = htmlElementCID) + ctx.registerType(HTMLSpanElement, parent = htmlElementCID) + ctx.registerType(HTMLOptGroupElement, parent = htmlElementCID) + ctx.registerType(HTMLOptionElement, parent = htmlElementCID) + ctx.registerType(HTMLHeadingElement, parent = htmlElementCID) + ctx.registerType(HTMLBRElement, parent = htmlElementCID) + ctx.registerType(HTMLMenuElement, parent = htmlElementCID) + ctx.registerType(HTMLUListElement, parent = htmlElementCID) + ctx.registerType(HTMLOListElement, parent = htmlElementCID) + ctx.registerType(HTMLLIElement, parent = htmlElementCID) + ctx.registerType(HTMLStyleElement, parent = htmlElementCID) + ctx.registerType(HTMLLinkElement, parent = htmlElementCID) + ctx.registerType(HTMLFormElement, parent = htmlElementCID) + ctx.registerType(HTMLTemplateElement, parent = htmlElementCID) + ctx.registerType(HTMLUnknownElement, parent = htmlElementCID) + ctx.registerType(HTMLScriptElement, parent = htmlElementCID) diff --git a/src/html/htmlparser.nim b/src/html/htmlparser.nim index a8ea5458..f28cd300 100644 --- a/src/html/htmlparser.nim +++ b/src/html/htmlparser.nim @@ -6,13 +6,16 @@ import strformat import tables import unicode -import utils/twtstr +import css/sheet import html/dom import html/tags import html/htmltokenizer -import css/sheet +import js/javascript +import utils/twtstr type + DOMParser = ref object # JS interface + HTML5Parser = object case fragment: bool of true: ctx: Element @@ -2085,3 +2088,18 @@ proc parseHTML5*(inputStream: Stream): Document = parser.document = newDocument() parser.tokenizer = inputStream.newTokenizer() return parser.constructTree() + +proc newDOMParser*(): DOMParser {.jsctor.} = + new(result) + +proc parseFromString*(parser: DOMParser, str: string, t: string): Document {.jserr, jsfunc.} = + case t + of "text/html": + return parseHTML5(newStringStream(str)) + of "text/xml", "application/xml", "application/xhtml+xml", "image/svg+xml": + JS_THROW JS_InternalError, "XML parsing is not supported yet" + else: + JS_THROW JS_TypeError, "Invalid mime type" + +proc addHTMLModule*(ctx: JSContext) = + ctx.registerType(DOMParser) diff --git a/src/html/htmltokenizer.nim b/src/html/htmltokenizer.nim index a1c894c8..c8f96144 100644 --- a/src/html/htmltokenizer.nim +++ b/src/html/htmltokenizer.nim @@ -227,7 +227,7 @@ iterator tokenize*(tokenizer: var Tokenizer): Token = template emit_tmp() = var i = 0 while i < tokenizer.tmp.len: - if tokenizer.tmp[i].isAscii(): + if tokenizer.tmp[i] in Ascii: emit tokenizer.tmp[i] inc i else: |