From eb2e57c97eb67eec19f068e294a8f6d1375c82f5 Mon Sep 17 00:00:00 2001
From: bptato
Date: Mon, 28 Nov 2022 19:52:10 +0100
Subject: Add textarea
Editing is implemented using an external editor (like vi).
---
src/html/htmlparser.nim | 74 +++++++++++++++++++++++++++----------------------
1 file changed, 41 insertions(+), 33 deletions(-)
(limited to 'src/html/htmlparser.nim')
diff --git a/src/html/htmlparser.nim b/src/html/htmlparser.nim
index 2b48c59d..e1359201 100644
--- a/src/html/htmlparser.nim
+++ b/src/html/htmlparser.nim
@@ -16,11 +16,13 @@ import utils/twtstr
type
DOMParser = ref object # JS interface
+ OpenElements = seq[Element]
+
HTML5Parser = object
case fragment: bool
of true: ctx: Element
else: discard
- openElements: seq[Element]
+ openElements: OpenElements
insertionMode: InsertionMode
oldInsertionMode: InsertionMode
templateModes: seq[InsertionMode]
@@ -196,8 +198,9 @@ func createElement(parser: HTML5Parser, token: Token, namespace: Namespace, inte
let document = intendedParent.document
let localName = token.tagname
let element = document.newHTMLElement(localName, namespace, tagType = token.tagtype)
- for k, v in token.attrs:
- element.appendAttribute(k, v)
+ element.appendAttributes(token.attrs)
+ #for k, v in token.attrs:
+ # element.appendAttribute(k, v)
if element.isResettable():
element.resetElement()
@@ -450,18 +453,23 @@ proc genericRCDATAElementParsingAlgorithm(parser: var HTML5Parser, token: Token)
parser.oldInsertionMode = parser.insertionMode
parser.insertionMode = TEXT
+proc popElement(parser: var HTML5Parser): Element =
+ result = parser.openElements.pop()
+ if result.tagType == TAG_TEXTAREA:
+ result.resetElement()
+
# 13.2.6.3
proc generateImpliedEndTags(parser: var HTML5Parser) =
const tags = {TAG_DD, TAG_DT, TAG_LI, TAG_OPTGROUP, TAG_OPTION, TAG_P,
TAG_RB, TAG_RP, TAG_RT, TAG_RTC}
while parser.currentNode.tagType in tags:
- discard parser.openElements.pop()
+ discard parser.popElement()
proc generateImpliedEndTags(parser: var HTML5Parser, exclude: TagType) =
let tags = {TAG_DD, TAG_DT, TAG_LI, TAG_OPTGROUP, TAG_OPTION, TAG_P,
TAG_RB, TAG_RP, TAG_RT, TAG_RTC} - {exclude}
while parser.currentNode.tagType in tags:
- discard parser.openElements.pop()
+ discard parser.popElement()
proc generateImpliedEndTagsThoroughly(parser: var HTML5Parser) =
const tags = {TAG_CAPTION, TAG_COLGROUP, TAG_DD, TAG_DT, TAG_LI,
@@ -469,7 +477,7 @@ proc generateImpliedEndTagsThoroughly(parser: var HTML5Parser) =
TAG_RTC, TAG_TBODY, TAG_TD, TAG_TFOOT, TAG_TH, TAG_THEAD,
TAG_TR}
while parser.currentNode.tagType in tags:
- discard parser.openElements.pop()
+ discard parser.popElement()
# 13.2.4.3
proc pushOntoActiveFormatting(parser: var HTML5Parser, element: Element, token: Token) =
@@ -535,7 +543,7 @@ proc reconstructActiveFormatting(parser: var HTML5Parser) =
proc clearActiveFormattingTillMarker(parser: var HTML5Parser) =
while parser.activeFormatting.len > 0 and parser.activeFormatting.pop()[0] != nil: discard
-template pop_current_node = discard parser.openElements.pop()
+template pop_current_node = discard parser.popElement()
func isHTMLIntegrationPoint(node: Element): bool =
return false #TODO SVG (NOTE MathML not implemented)
@@ -849,7 +857,7 @@ proc processInHTMLContent(parser: var HTML5Parser, token: Token, insertionMode =
parser.generateImpliedEndTagsThoroughly()
if parser.currentNode.tagType != TAG_TEMPLATE:
parse_error
- while parser.openElements.pop().tagType != TAG_TEMPLATE: discard
+ while parser.popElement().tagType != TAG_TEMPLATE: discard
parser.clearActiveFormattingTillMarker()
discard parser.templateModes.pop()
parser.resetInsertionMode()
@@ -918,7 +926,7 @@ proc processInHTMLContent(parser: var HTML5Parser, token: Token, insertionMode =
proc closeP(parser: var HTML5Parser) =
parser.generateImpliedEndTags(TAG_P)
if parser.currentNode.tagType != TAG_P: parse_error
- while parser.openElements.pop().tagType != TAG_P: discard
+ while parser.popElement().tagType != TAG_P: discard
proc adoptionAgencyAlgorithm(parser: var HTML5Parser, token: Token): bool =
if parser.currentNode.tagType != TAG_UNKNOWN and parser.currentNode.tagtype == token.tagtype or parser.currentNode.localName == token.tagname:
@@ -965,7 +973,7 @@ proc processInHTMLContent(parser: var HTML5Parser, token: Token, insertionMode =
furthestBlockIndex = j
break
if furthestBlock == nil:
- while parser.openElements.pop() != formatting: discard
+ while parser.popElement() != formatting: discard
parser.activeFormatting.delete(formattingIndex)
return false
let commonAncestor = parser.openElements[stackIndex - 1]
@@ -1031,7 +1039,7 @@ proc processInHTMLContent(parser: var HTML5Parser, token: Token, insertionMode =
if node.tagType != TAG_UNKNOWN and node.tagType == token.tagtype or node.localName == token.tagname:
parser.generateImpliedEndTags(token.tagtype)
if node != parser.currentNode: parse_error
- while parser.openElements.pop() != node: discard
+ while parser.popElement() != node: discard
break
elif node.tagType in SpecialElements:
parse_error
@@ -1149,7 +1157,7 @@ proc processInHTMLContent(parser: var HTML5Parser, token: Token, insertionMode =
of TAG_LI:
parser.generateImpliedEndTags(TAG_LI)
if parser.currentNode.tagType != TAG_LI: parse_error
- while parser.openElements.pop().tagType != TAG_LI: discard
+ while parser.popElement().tagType != TAG_LI: discard
break
of SpecialElements - {TAG_ADDRESS, TAG_DIV, TAG_P, TAG_LI}:
break
@@ -1166,12 +1174,12 @@ proc processInHTMLContent(parser: var HTML5Parser, token: Token, insertionMode =
of TAG_DD:
parser.generateImpliedEndTags(TAG_DD)
if parser.currentNode.tagType != TAG_DD: parse_error
- while parser.openElements.pop().tagType != TAG_DD: discard
+ while parser.popElement().tagType != TAG_DD: discard
break
of TAG_DT:
parser.generateImpliedEndTags(TAG_DT)
if parser.currentNode.tagType != TAG_DT: parse_error
- while parser.openElements.pop().tagType != TAG_DT: discard
+ while parser.popElement().tagType != TAG_DT: discard
break
of SpecialElements - {TAG_ADDRESS, TAG_DIV, TAG_P, TAG_DD, TAG_DT}:
break
@@ -1190,7 +1198,7 @@ proc processInHTMLContent(parser: var HTML5Parser, token: Token, insertionMode =
if parser.openElements.hasElementInScope(TAG_BUTTON):
parse_error
parser.generateImpliedEndTags()
- while parser.openElements.pop().tagType != TAG_BUTTON: discard
+ while parser.popElement().tagType != TAG_BUTTON: discard
parser.reconstructActiveFormatting()
discard parser.insertHTMLElement(token)
parser.framesetOk = false
@@ -1205,7 +1213,7 @@ proc processInHTMLContent(parser: var HTML5Parser, token: Token, insertionMode =
else:
parser.generateImpliedEndTags()
if parser.currentNode.tagType != token.tagtype: parse_error
- while parser.openElements.pop().tagType != token.tagtype: discard
+ while parser.popElement().tagType != token.tagtype: discard
)
"" => (block:
if not parser.openElements.hasElement(TAG_TEMPLATE):
@@ -1223,7 +1231,7 @@ proc processInHTMLContent(parser: var HTML5Parser, token: Token, insertionMode =
return
parser.generateImpliedEndTags()
if parser.currentNode.tagType != TAG_FORM: parse_error
- while parser.openElements.pop().tagType != TAG_FORM: discard
+ while parser.popElement().tagType != TAG_FORM: discard
)
"
" => (block:
if not parser.openElements.hasElementInButtonScope(TAG_P):
@@ -1237,7 +1245,7 @@ proc processInHTMLContent(parser: var HTML5Parser, token: Token, insertionMode =
else:
parser.generateImpliedEndTags(TAG_LI)
if parser.currentNode.tagType != TAG_LI: parse_error
- while parser.openElements.pop().tagType != TAG_LI: discard
+ while parser.popElement().tagType != TAG_LI: discard
)
("", "") => (block:
if not parser.openElements.hasElementInScope(token.tagtype):
@@ -1245,7 +1253,7 @@ proc processInHTMLContent(parser: var HTML5Parser, token: Token, insertionMode =
else:
parser.generateImpliedEndTags(token.tagtype)
if parser.currentNode.tagType != token.tagtype: parse_error
- while parser.openElements.pop().tagType != token.tagtype: discard
+ while parser.popElement().tagType != token.tagtype: discard
)
("", "", "", "", "", "") => (block:
if not parser.openElements.hasElementInScope(HTagTypes):
@@ -1253,7 +1261,7 @@ proc processInHTMLContent(parser: var HTML5Parser, token: Token, insertionMode =
else:
parser.generateImpliedEndTags()
if parser.currentNode.tagType != token.tagtype: parse_error
- while parser.openElements.pop().tagType notin HTagTypes: discard
+ while parser.popElement().tagType notin HTagTypes: discard
)
"" => (block:
#*deep breath*
@@ -1321,7 +1329,7 @@ proc processInHTMLContent(parser: var HTML5Parser, token: Token, insertionMode =
else:
parser.generateImpliedEndTags()
if parser.currentNode.tagType != token.tagtype: parse_error
- while parser.openElements.pop().tagType != token.tagtype: discard
+ while parser.popElement().tagType != token.tagtype: discard
parser.clearActiveFormattingTillMarker()
)
"" => (block:
@@ -1504,7 +1512,7 @@ proc processInHTMLContent(parser: var HTML5Parser, token: Token, insertionMode =
if not parser.openElements.hasElementInScope(TAG_TABLE):
discard
else:
- while parser.openElements.pop().tagType != TAG_TABLE: discard
+ while parser.popElement().tagType != TAG_TABLE: discard
parser.resetInsertionMode()
reprocess token
)
@@ -1512,7 +1520,7 @@ proc processInHTMLContent(parser: var HTML5Parser, token: Token, insertionMode =
if not parser.openElements.hasElementInScope(TAG_TABLE):
parse_error
else:
- while parser.openElements.pop().tagType != TAG_TABLE: discard
+ while parser.popElement().tagType != TAG_TABLE: discard
parser.resetInsertionMode()
)
("