diff options
author | bptato <nincsnevem662@gmail.com> | 2022-07-17 13:03:50 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2022-07-17 13:03:50 +0200 |
commit | 7cdb8c1b679431b1be52c9fbb19b67445a0bb588 (patch) | |
tree | 6baedc5ddd3a68ffd9825f76cb853a9940292b6e | |
parent | 2496c52449169f0caaba086ca3098b11708e5ba2 (diff) | |
download | chawan-7cdb8c1b679431b1be52c9fbb19b67445a0bb588.tar.gz |
Fix forms
-rw-r--r-- | src/css/cascade.nim | 56 | ||||
-rw-r--r-- | src/css/selectorparser.nim | 4 | ||||
-rw-r--r-- | src/html/dom.nim | 39 | ||||
-rw-r--r-- | src/html/htmlparser.nim | 2 | ||||
-rw-r--r-- | src/html/htmltokenizer.nim | 4 | ||||
-rw-r--r-- | src/io/buffer.nim | 1 | ||||
-rw-r--r-- | src/layout/engine.nim | 8 |
7 files changed, 45 insertions, 69 deletions
diff --git a/src/css/cascade.nim b/src/css/cascade.nim index cc7295ea..16e5664a 100644 --- a/src/css/cascade.nim +++ b/src/css/cascade.nim @@ -88,27 +88,6 @@ proc applyImportant(ares: var ApplyResult, decls: seq[CSSDeclaration]) = if decl.important: ares.important.add(decl) -proc checkRendered(element: Element, prev: CSSComputedValues, ppseudo: array[PSEUDO_BEFORE..PSEUDO_AFTER, CSSComputedValues]) = - if element.rendered: - for p in PSEUDO_BEFORE..PSEUDO_AFTER: - if ppseudo[p] != element.pseudo[p] and ppseudo[p] == nil: - if element.parentElement != nil: - element.parentElement.rendered = false - element.rendered = false - return - for t in CSSPropertyType: - if not element.css[t].equals(prev[t]): - if element.parentElement != nil: - element.parentElement.rendered = false - element.rendered = false - return - for p in PSEUDO_BEFORE..PSEUDO_AFTER: - if ppseudo[p] != nil: - for t in CSSPropertyType: - if not element.pseudo[p][t].equals(ppseudo[p][t]): - element.rendered = false - return - # Always returns a new styled node, with the passed declarations applied. proc applyDeclarations(elem: Element, parent: CSSComputedValues, ua, user: DeclarationList, author: seq[DeclarationList]): StyledNode = let pseudo = PSEUDO_NONE @@ -122,7 +101,7 @@ proc applyDeclarations(elem: Element, parent: CSSComputedValues, ua, user: Decla for rule in author: ares.applyImportant(rule[pseudo]) - let style = Element(elem).attr("style") + let style = elem.attr("style") if style.len > 0: let inline_rules = newStringStream(style).parseListOfDeclarations2() ares.applyNormal(inline_rules) @@ -167,15 +146,6 @@ func applyMediaQuery(ss: CSSStylesheet): CSSStylesheet = if mq.query.applies(): result.add(mq.children.applyMediaQuery()) -proc resetRules(elem: Element) = - elem.css = if elem.parentElement != nil: - elem.parentElement.css.inheritProperties() - else: - rootProperties() - - for pseudo in PSEUDO_BEFORE..PSEUDO_AFTER: - elem.pseudo[pseudo] = nil - func calcRules(elem: Element, ua, user: CSSStylesheet, author: seq[CSSStylesheet]): tuple[uadecls, userdecls: DeclarationList, authordecls: seq[DeclarationList]] = result.uadecls = calcRules(elem, ua) result.userdecls = calcRules(elem, user) @@ -221,9 +191,7 @@ proc applyRules(document: Document, ua, user: CSSStylesheet, cachedTree: StyledN if cachedChild.t == STYLED_ELEMENT: styledChild = StyledNode(t: STYLED_ELEMENT, pseudo: cachedChild.pseudo, computed: cachedChild.computed, node: cachedChild.node) if cachedChild.pseudo != PSEUDO_NONE: - let content = cachedChild.computed{"content"} - if content.len > 0: - styledChild.children.add(StyledNode(t: STYLED_TEXT, text: content)) + styledChild.children = cachedChild.children #TODO does this actually refresh pseudo elems when needed? else: # Text styledChild = StyledNode(t: STYLED_TEXT, text: cachedChild.text, node: cachedChild.node) @@ -235,12 +203,20 @@ proc applyRules(document: Document, ua, user: CSSStylesheet, cachedTree: StyledN else: if pseudo != PSEUDO_NONE: let (ua, user, authordecls) = Element(styledParent.node).calcRules(ua, user, author) - let styledPseudo = pseudo.applyDeclarations(styledParent.computed, ua, user, authordecls) - if styledPseudo != nil: - styledParent.children.add(styledPseudo) - let content = styledPseudo.computed{"content"} + case pseudo + of PSEUDO_BEFORE, PSEUDO_AFTER: + let styledPseudo = pseudo.applyDeclarations(styledParent.computed, ua, user, authordecls) + if styledPseudo != nil: + styledParent.children.add(styledPseudo) + let content = styledPseudo.computed{"content"} + if content.len > 0: + styledPseudo.children.add(StyledNode(t: STYLED_TEXT, text: content)) + of PSEUDO_INPUT_TEXT: + let content = HTMLInputElement(styledParent.node).inputString() if content.len > 0: - styledPseudo.children.add(StyledNode(t: STYLED_TEXT, text: content)) + styledChild = StyledNode(t: STYLED_TEXT, text: content) + styledParent.children.add(styledChild) + of PSEUDO_NONE: discard else: assert child != nil if styledParent != nil: @@ -295,6 +271,8 @@ proc applyRules(document: Document, ua, user: CSSStylesheet, cachedTree: StyledN for i in countdown(elem.childNodes.high, 0): stack_append styledChild, elem.childNodes[i] + if elem.tagType == TAG_INPUT: + stack_append styledChild, PSEUDO_INPUT_TEXT stack_append styledChild, PSEUDO_BEFORE proc applyStylesheets*(document: Document, uass, userss: CSSStylesheet, previousStyled: StyledNode): StyledNode = diff --git a/src/css/selectorparser.nim b/src/css/selectorparser.nim index d44d7168..d6302c24 100644 --- a/src/css/selectorparser.nim +++ b/src/css/selectorparser.nim @@ -15,7 +15,9 @@ type QUERY_NEXT_SIBLING_COMBINATOR, QUERY_SUBSEQ_SIBLING_COMBINATOR PseudoElem* = enum - PSEUDO_NONE, PSEUDO_BEFORE, PSEUDO_AFTER + PSEUDO_NONE, PSEUDO_BEFORE, PSEUDO_AFTER, + # internal + PSEUDO_INPUT_TEXT PseudoClass* = enum PSEUDO_FIRST_CHILD, PSEUDO_LAST_CHILD, PSEUDO_ONLY_CHILD, PSEUDO_HOVER, diff --git a/src/html/dom.nim b/src/html/dom.nim index 6dbfcc0f..5312dc8b 100644 --- a/src/html/dom.nim +++ b/src/html/dom.nim @@ -3,7 +3,6 @@ import options import streams import strutils -import css/values import css/sheet import html/tags import types/url @@ -40,7 +39,7 @@ type previousSibling*: Node parentNode*: Node parentElement*: Element - rootNode: Node + root: Node document*: Document Attr* = ref object of Node @@ -84,8 +83,6 @@ type id*: string classList*: seq[string] attributes*: Table[string, string] - css*: CSSComputedValues - pseudo*: array[PSEUDO_BEFORE..PSEUDO_AFTER, CSSComputedValues] hover*: bool cssapplied*: bool rendered*: bool @@ -279,8 +276,12 @@ func hasPreviousSibling(node: Node, nodeType: NodeType): bool = node = node.previousSibling return false +func rootNode*(node: Node): Node = + if node.root == nil: return node + return node.root + func inSameTree*(a, b: Node): bool = - a.rootNode == b.rootNode and (a.rootNode != nil or b.rootNode != nil) + a.rootNode == b.rootNode func children*(node: Node): seq[Element] = for child in node.children: @@ -398,8 +399,7 @@ func inputString*(input: HTMLInputElement): string = if input.checked: "*" else: " " of INPUT_SEARCH, INPUT_TEXT: - if input.size > 0: input.value.padToWidth(input.size) - else: input.value + input.value.padToWidth(input.size) of INPUT_PASSWORD: '*'.repeat(input.value.len).padToWidth(input.size) of INPUT_RESET: @@ -411,8 +411,7 @@ func inputString*(input: HTMLInputElement): string = of INPUT_FILE: if input.file.isnone: "".padToWidth(input.size) else: input.file.get.path.serialize_unicode().padToWidth(input.size) - else: - input.value + else: input.value return text func isButton*(element: Element): bool = @@ -504,20 +503,19 @@ func newText*(document: Document, data: string = ""): Text = result.nodeType = TEXT_NODE result.document = document result.data = data - result.rootNode = result #TODO apparently we shouldn't be doing this func newComment*(document: Document, data: string = ""): Comment = new(result) result.nodeType = COMMENT_NODE result.document = document result.data = data - result.rootNode = result #TODO apparently we shouldn't be doing this # note: we do not implement custom elements func newHTMLElement*(document: Document, tagType: TagType, namespace = Namespace.HTML, prefix = none[string]()): HTMLElement = case tagType of TAG_INPUT: result = new(HTMLInputElement) + HTMLInputElement(result).size = 20 of TAG_A: result = new(HTMLAnchorElement) of TAG_SELECT: @@ -558,10 +556,8 @@ func newHTMLElement*(document: Document, tagType: TagType, namespace = Namespace result.nodeType = ELEMENT_NODE result.tagType = tagType - result.css = rootProperties() result.namespace = namespace result.namespacePrefix = prefix - result.rootNode = result #TODO apparently we shouldn't be doing this result.document = document func newHTMLElement*(document: Document, localName: string, namespace = Namespace.HTML, prefix = none[string](), tagType = tagType(localName)): Element = @@ -572,7 +568,6 @@ func newHTMLElement*(document: Document, localName: string, namespace = Namespac func newDocument*(): Document = new(result) result.nodeType = DOCUMENT_NODE - result.rootNode = result #TODO apparently we shouldn't be doing this result.document = result func newDocumentType*(document: Document, name: string, publicId = "", systemId = ""): DocumentType = @@ -581,7 +576,6 @@ func newDocumentType*(document: Document, name: string, publicId = "", systemId result.name = name result.publicId = publicId result.systemId = systemId - result.rootNode = result #TODO apparently we shouldn't be doing this func newAttr*(parent: Element, key, value: string): Attr = new(result) @@ -590,7 +584,6 @@ func newAttr*(parent: Element, key, value: string): Attr = result.ownerElement = parent result.name = key result.value = value - result.rootNode = result #TODO apparently we shouldn't be doing this func getElementById*(document: Document, id: string): Element = if id.len == 0: @@ -714,6 +707,7 @@ proc remove*(node: Node) = oldNextSibling.previousSibling = oldPreviousSibling node.parentNode = nil node.parentElement = nil + node.root = nil #TODO assigned, shadow root, shadow root again, custom nodes, registered observers #TODO not surpress observers => queue tree mutation record @@ -724,10 +718,7 @@ proc adopt(document: Document, node: Node) = #TODO shadow root proc applyChildInsert(parent, child: Node, index: int) = - if parent.rootNode != nil: - child.rootNode = parent.rootNode - else: - child.rootNode = parent + child.root = parent.rootNode child.parentNode = parent if parent.nodeType == ELEMENT_NODE: child.parentElement = Element(parent) @@ -809,13 +800,15 @@ proc appendAttribute*(element: Element, k, v: string) = of "type": HTMLInputElement(element).inputType = inputType(v) of "size": var i = 20 - var fail = v.len > 0 + var fail = v.len == 0 for c in v: if not c.isDigit: fail = true break if not fail: i = parseInt(v) + if i <= 0: + i = 20 HTMLInputElement(element).size = i of "checked": HTMLInputElement(element).checked = true element.attributes[k] = v @@ -823,7 +816,9 @@ proc appendAttribute*(element: Element, k, v: string) = proc setForm*(element: Element, form: HTMLFormElement) = case element.tagType of TAG_INPUT: - HTMLInputElement(element).form = form + let input = HTMLInputElement(element) + input.form = form + form.inputs.add(input) of TAG_BUTTON, TAG_FIELDSET, TAG_OBJECT, TAG_OUTPUT, TAG_SELECT, TAG_TEXTAREA, TAG_IMG: discard #TODO else: assert false diff --git a/src/html/htmlparser.nim b/src/html/htmlparser.nim index dfd10589..cec952f6 100644 --- a/src/html/htmlparser.nim +++ b/src/html/htmlparser.nim @@ -201,7 +201,7 @@ func createElement(parser: HTML5Parser, token: Token, namespace: Namespace, inte if element.tagType in FormAssociatedElements and parser.form != nil and not parser.openElements.hasElement(TAG_TEMPLATE) and (element.tagType notin ListedElements or not element.attrb("form")) and - element.inSameTree(parser.form): + intendedParent.inSameTree(parser.form): element.setForm(parser.form) return element diff --git a/src/html/htmltokenizer.nim b/src/html/htmltokenizer.nim index 8738323f..4f81f6a6 100644 --- a/src/html/htmltokenizer.nim +++ b/src/html/htmltokenizer.nim @@ -848,7 +848,9 @@ iterator tokenize*(tokenizer: var Tokenizer): Token = case c of whitespace: switch_state BEFORE_ATTRIBUTE_NAME of '&': switch_state_return CHARACTER_REFERENCE - of '>': switch_state DATA + of '>': + switch_state DATA + emit_tok of null: parse_error unexpected_null_character append_to_current_attr_value Rune(0xFFFD) diff --git a/src/io/buffer.nim b/src/io/buffer.nim index 9fa23fe6..03de9988 100644 --- a/src/io/buffer.nim +++ b/src/io/buffer.nim @@ -1003,6 +1003,7 @@ proc click*(buffer: Buffer): Option[ClickAction] = input.rendered = false buffer.reshape = true if input.form != nil: + eprint "SEARCH", input.value let submitaction = submitForm(input.form, input) return submitaction of INPUT_TEXT, INPUT_PASSWORD: diff --git a/src/layout/engine.nim b/src/layout/engine.nim index 1596add2..a449f6a3 100644 --- a/src/layout/engine.nim +++ b/src/layout/engine.nim @@ -640,7 +640,7 @@ proc getListItemBox(computed: CSSComputedValues, listItemCounter: int): ListItem result.computed = computed.copyProperties() result.marker = getMarkerBox(computed, listItemCounter) -func getInputBox(parent: BoxBuilder, input: HTMLInputElement, viewport: Viewport): InlineBoxBuilder = +func getInputBox(parent: BoxBuilder, input: HTMLInputElement): InlineBoxBuilder = let textbox = parent.getTextBox() textbox.node = input textbox.text.add(input.inputString()) @@ -702,7 +702,6 @@ proc generateFromElem(box: BlockBoxBuilder, styledNode: StyledNode, blockgroup: proc generateInlineBoxes(box: BlockBoxBuilder, styledNode: StyledNode, blockgroup: var seq[BoxBuilder], viewport: Viewport) = var ibox: InlineBoxBuilder = nil - var listItemCounter = 1 # ordinal value of current list for child in styledNode.children: @@ -712,7 +711,7 @@ proc generateInlineBoxes(box: BlockBoxBuilder, styledNode: StyledNode, blockgrou of STYLED_TEXT: if ibox == nil: ibox = getTextBox(styledNode.computed) - ibox.node = child.node + ibox.node = styledNode.node ibox.text.add(child.text) flush_ibox @@ -722,7 +721,6 @@ proc generateBlockBox(styledNode: StyledNode, viewport: Viewport): BlockBoxBuild let box = getBlockBox(styledNode.computed) var blockgroup: seq[BoxBuilder] var ibox: InlineBoxBuilder = nil - var listItemCounter = 1 # ordinal value of current list for child in styledNode.children: @@ -734,7 +732,7 @@ proc generateBlockBox(styledNode: StyledNode, viewport: Viewport): BlockBoxBuild if canGenerateAnonymousInline(blockgroup, box.computed, child.text): if ibox == nil: ibox = getTextBox(styledNode.computed) - ibox.node = child.node + ibox.node = styledNode.node ibox.text.add(child.text) flush_ibox |