diff options
author | bptato <nincsnevem662@gmail.com> | 2024-03-04 17:28:37 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-03-04 17:28:37 +0100 |
commit | a510b9494678edaa745e6662d649ef8eeb3f28a6 (patch) | |
tree | bcfe065361c3af4631cb4ee90f13640c230a0a66 /src/html | |
parent | c5dc63741f0d3a876c88b86d3e0374148fb6b3d0 (diff) | |
download | chawan-a510b9494678edaa745e6662d649ef8eeb3f28a6.tar.gz |
catom: merge TagType with AttrType
it's inefficient and pointless to treat them differently, so just derive a new enum from TagType with a macro
Diffstat (limited to 'src/html')
-rw-r--r-- | src/html/catom.nim | 128 | ||||
-rw-r--r-- | src/html/dom.nim | 52 | ||||
-rw-r--r-- | src/html/enums.nim | 61 |
3 files changed, 131 insertions, 110 deletions
diff --git a/src/html/catom.nim b/src/html/catom.nim index e908a5f4..1bb6cc8c 100644 --- a/src/html/catom.nim +++ b/src/html/catom.nim @@ -1,25 +1,112 @@ import std/hashes - -import html/enums +import std/macros +import std/sets +import std/strutils import chame/tags +# create a static enum compatible with chame/tags + +macro makeStaticAtom = + # declare inside the macro to avoid confusion with StaticAtom0 + type + StaticAtom0 = enum + atAcceptCharset = "accept-charset" + atAction = "action" + atAlign = "align" + atAlt = "alt" + atAsync = "async" + atBgcolor = "bgcolor" + atBlocking = "blocking" + atCharset = "charset" + atChecked = "checked" + atClass = "class" + atClassList + atColor = "color" + atCols = "cols" + atColspan = "colspan" + atCrossorigin = "crossorigin" + atDefer = "defer" + atDirname = "dirname" + atDisabled = "disabled" + atEnctype = "enctype" + atEvent = "event" + atFor = "for" + atForm = "form" + atFormaction = "formaction" + atFormenctype = "formenctype" + atFormmethod = "formmethod" + atHeight = "height" + atHref = "href" + atId = "id" + atIntegrity = "integrity" + atIsmap = "ismap" + atLanguage = "language" + atMedia = "media" + atMethod = "method" + atMultiple = "multiple" + atName = "name" + atNomodule = "nomodule" + atOnload = "onload" + atReferrerpolicy = "referrerpolicy" + atRel = "rel" + atRequired = "required" + atRows = "rows" + atRowspan = "rowspan" + atSelected = "selected" + atSize = "size" + atSizes = "sizes" + atSlot = "slot" + atSrc = "src" + atSrcset = "srcset" + atStyle = "style" + atStylesheet = "stylesheet" + atTarget = "target" + atText = "text" + atTitle = "title" + atType = "type" + atUsemap = "usemap" + atValign = "valign" + atValue = "value" + atWidth = "width" + let decl = quote do: + type StaticAtom* {.inject.} = enum + atUnknown = "" + let decl0 = decl[0][2] + var seen: HashSet[string] + for t in TagType: + if t == TAG_UNKNOWN: + continue + let tn = $t + var name = "at" + name &= tn[0].toUpperAscii() + name &= tn.substr(1) + if name == "atTr": + # Nim cries about this overlapping with the attr() procs :/ + name = "satTr" + seen.incl(tn) + decl0.add(newNimNode(nnkEnumFieldDef).add(ident(name), newStrLitNode(tn))) + for i, f in StaticAtom0.getType(): + if i == 0: + continue + let tn = $StaticAtom0(i - 1) + if tn in seen: + continue + decl0.add(newNimNode(nnkEnumFieldDef).add(ident(f.strVal), newStrLitNode(tn))) + decl + +makeStaticAtom + #TODO use a better hash map const CAtomFactoryStrMapLength = 1024 # must be a power of 2 static: doAssert (CAtomFactoryStrMapLength and (CAtomFactoryStrMapLength - 1)) == 0 -# Null atom + mapped tag types + mapped attr types -const AttrMapNum = 1 + ({TagType.low..TagType.high} - {TAG_UNKNOWN}).card + - ({AttrType.low..AttrType.high} - {atUnknown}).card - type CAtom* = distinct int CAtomFactoryInit = object obj: CAtomFactoryObj - attrToAtom: array[AttrType, CAtom] - atomToAttr: array[AttrMapNum, AttrType] CAtomFactoryObj = object strMap: array[CAtomFactoryStrMapLength, seq[CAtom]] @@ -53,14 +140,9 @@ const factoryInit = (func(): CAtomFactoryInit = var init = CAtomFactoryInit() # Null atom init.obj.atomMap.add("") - # TagType: 1..TagType.high - for tagType in TagType(1) .. TagType.high: - discard init.obj.toAtom($tagType) - # Attr: may overlap with TagType; exclude atUnknown - for attrType in AttrType(1) .. AttrType.high: - let atom = init.obj.toAtom($attrType) - init.attrToAtom[attrType] = atom - init.atomToAttr[int(atom)] = attrType + # StaticAtom includes TagType too. + for sa in StaticAtom(1) .. StaticAtom.high: + discard init.obj.toAtom($sa) return init )() @@ -76,21 +158,21 @@ func toAtom*(factory: CAtomFactory, tagType: TagType): CAtom = assert tagType != TAG_UNKNOWN return CAtom(tagType) -func toAtom*(factory: CAtomFactory, attrType: AttrType): CAtom = +func toAtom*(factory: CAtomFactory, attrType: StaticAtom): CAtom = assert attrType != atUnknown - return factoryInit.attrToAtom[attrType] + return CAtom(attrType) func toStr*(factory: CAtomFactory, atom: CAtom): string = return factory.atomMap[int(atom)] func toTagType*(factory: CAtomFactory, atom: CAtom): TagType = let i = int(atom) - if i in 1 .. int(TagType.high): - return TagType(atom) + if i <= int(TagType.high): + return TagType(i) return TAG_UNKNOWN -func toAttrType*(factory: CAtomFactory, atom: CAtom): AttrType = +func toStaticAtom*(factory: CAtomFactory, atom: CAtom): StaticAtom = let i = int(atom) - if i < factoryInit.atomToAttr.len: - return factoryInit.atomToAttr[i] + if i <= int(StaticAtom.high): + return StaticAtom(i) return atUnknown diff --git a/src/html/dom.nim b/src/html/dom.nim index d4e368d5..7909a876 100644 --- a/src/html/dom.nim +++ b/src/html/dom.nim @@ -709,7 +709,7 @@ type REFLECT_STR, REFLECT_BOOL, REFLECT_LONG, REFLECT_ULONG_GZ, REFLECT_ULONG ReflectEntry = object - attrname: AttrType + attrname: StaticAtom funcname: string tags: set[TagType] case t: ReflectType @@ -719,8 +719,8 @@ type u: uint32 else: discard -func attrType0(s: static string): AttrType = - return parseEnum[AttrType](s) +func attrType0(s: static string): StaticAtom = + return parseEnum[StaticAtom](s) template toset(ts: openarray[TagType]): set[TagType] = var tags: system.set[TagType] @@ -820,10 +820,10 @@ const ReflectTable0 = [ ] # Forward declarations -func attr*(element: Element, s: AttrType): string +func attr*(element: Element, s: StaticAtom): string func attrb*(element: Element, s: CAtom): bool proc attr*(element: Element, name: CAtom, value: string) -proc attr*(element: Element, name: AttrType, value: string) +proc attr*(element: Element, name: StaticAtom, value: string) func baseURL*(document: Document): URL proc delAttr(element: Element, i: int, keep = false) proc reflectAttrs(element: Element, name: CAtom, value: string) @@ -836,7 +836,7 @@ func document*(node: Node): Document = proc toAtom*(document: Document, s: string): CAtom = return document.factory.toAtom(s) -proc toAtom*(document: Document, at: AttrType): CAtom = +proc toAtom*(document: Document, at: StaticAtom): CAtom = return document.factory.toAtom(at) proc toStr(document: Document, atom: CAtom): string = @@ -845,8 +845,8 @@ proc toStr(document: Document, atom: CAtom): string = proc toTagType*(document: Document, atom: CAtom): TagType = return document.factory.toTagType(atom) -proc toAttrType(document: Document, atom: CAtom): AttrType = - return document.factory.toAttrType(atom) +proc toStaticAtom(document: Document, atom: CAtom): StaticAtom = + return document.factory.toStaticAtom(atom) proc toAtom*(document: Document, tagType: TagType): CAtom = return document.factory.toAtom(tagType) @@ -878,7 +878,7 @@ func findAttr(element: Element, qualifiedName: CAtom): int = return i return -1 -func findAttr(element: Element, qualifiedName: AttrType): int = +func findAttr(element: Element, qualifiedName: StaticAtom): int = return element.findAttr(element.document.toAtom(qualifiedName)) func findAttrNS(element: Element, namespace, qualifiedName: CAtom): int = @@ -1169,7 +1169,7 @@ func item(tokenList: DOMTokenList, i: int): Option[string] {.jsfunc.} = func contains*(tokenList: DOMTokenList, a: CAtom): bool = return a in tokenList.toks -func contains(tokenList: DOMTokenList, a: AttrType): bool = +func contains(tokenList: DOMTokenList, a: StaticAtom): bool = return tokenList.element.document.toAtom(a) in tokenList.toks func jsContains(tokenList: DOMTokenList, s: string): bool @@ -1260,7 +1260,7 @@ const SupportedTokensMap = { func supports(tokenList: DOMTokenList, token: string): JSResult[bool] {.jsfunc.} = - let localName = tokenList.element.document.toAttrType(tokenList.localName) + let localName = tokenList.element.document.toStaticAtom(tokenList.localName) if localName in SupportedTokensMap: let lowercase = token.toLowerAscii() return ok(lowercase in SupportedTokensMap[localName]) @@ -2052,19 +2052,19 @@ func attr*(element: Element, s: CAtom): string = return element.attrs[i].value return "" -func attr*(element: Element, s: AttrType): string = +func attr*(element: Element, s: StaticAtom): string = return element.attr(element.document.toAtom(s)) -func attrl*(element: Element, s: AttrType): Option[int32] = +func attrl*(element: Element, s: StaticAtom): Option[int32] = return parseInt32(element.attr(s)) -func attrulgz*(element: Element, s: AttrType): Option[uint32] = +func attrulgz*(element: Element, s: StaticAtom): Option[uint32] = let x = parseUInt32(element.attr(s)) if x.isSome and x.get > 0: return x return none(uint32) -func attrul*(element: Element, s: AttrType): Option[uint32] = +func attrul*(element: Element, s: StaticAtom): Option[uint32] = let x = parseUInt32(element.attr(s)) if x.isSome and x.get >= 0: return x @@ -2073,7 +2073,7 @@ func attrul*(element: Element, s: AttrType): Option[uint32] = func attrb*(element: Element, s: CAtom): bool = return element.findAttr(s) != -1 -func attrb*(element: Element, at: AttrType): bool = +func attrb*(element: Element, at: StaticAtom): bool = let atom = element.document.toAtom(at) return element.attrb(atom) @@ -2816,20 +2816,20 @@ proc loadResource(window: Window, image: HTMLImageElement) = window.loadingResourcePromises.add(p) proc reflectAttrs(element: Element, name: CAtom, value: string) = - let name = element.document.toAttrType(name) - template reflect_str(element: Element, n: AttrType, val: untyped) = + let name = element.document.toStaticAtom(name) + template reflect_str(element: Element, n: StaticAtom, val: untyped) = if name == n: element.val = value return - template reflect_atom(element: Element, n: AttrType, val: untyped) = + template reflect_atom(element: Element, n: StaticAtom, val: untyped) = if name == n: element.val = element.document.toAtom(value) return - template reflect_str(element: Element, n: AttrType, val, fun: untyped) = + template reflect_str(element: Element, n: StaticAtom, val, fun: untyped) = if name == n: element.val = fun(value) return - template reflect_bool(element: Element, n: AttrType, val: untyped) = + template reflect_bool(element: Element, n: StaticAtom, val: untyped) = if name == n: element.val = true return @@ -2840,7 +2840,7 @@ proc reflectAttrs(element: Element, name: CAtom, value: string) = let a = element.document.toAtom(x) if a notin element.val: element.val.toks.add(a) - template reflect_domtoklist(element: Element, n: AttrType, val: untyped) = + template reflect_domtoklist(element: Element, n: StaticAtom, val: untyped) = if name == n: element.reflect_domtoklist0 val return @@ -2931,7 +2931,7 @@ proc attr*(element: Element, name: CAtom, value: string) = )) element.reflectAttrs(name, value) -proc attr*(element: Element, name: AttrType, value: string) = +proc attr*(element: Element, name: StaticAtom, value: string) = element.attr(element.document.toAtom(name), value) proc attrns*(element: Element, localName: CAtom, prefix: NamespacePrefix, @@ -2965,13 +2965,13 @@ proc attrns*(element: Element, localName: CAtom, prefix: NamespacePrefix, )) element.reflectAttrs(qualifiedName, value) -proc attrl(element: Element, name: AttrType, value: int32) = +proc attrl(element: Element, name: StaticAtom, value: int32) = element.attr(name, $value) -proc attrul(element: Element, name: AttrType, value: uint32) = +proc attrul(element: Element, name: StaticAtom, value: uint32) = element.attr(name, $value) -proc attrulgz(element: Element, name: AttrType, value: uint32) = +proc attrulgz(element: Element, name: StaticAtom, value: uint32) = if value > 0: element.attrul(name, value) diff --git a/src/html/enums.nim b/src/html/enums.nim index 389210ba..856b7813 100644 --- a/src/html/enums.nim +++ b/src/html/enums.nim @@ -30,67 +30,6 @@ type DOCUMENT_FRAGMENT_NODE = 11, NOTATION_NODE = 12 - AttrType* = enum - atUnknown = "" - atAcceptCharset = "accept-charset" - atAction = "action" - atAlign = "align" - atAlt = "alt" - atAsync = "async" - atBgcolor = "bgcolor" - atBlocking = "blocking" - atCharset = "charset" - atChecked = "checked" - atClass = "class" - atClassList - atColor = "color" - atCols = "cols" - atColspan = "colspan" - atCrossorigin = "crossorigin" - atDefer = "defer" - atDirname = "dirname" - atDisabled = "disabled" - atEnctype = "enctype" - atEvent = "event" - atFor = "for" - atForm = "form" - atFormaction = "formaction" - atFormenctype = "formenctype" - atFormmethod = "formmethod" - atHeight = "height" - atHref = "href" - atId = "id" - atIntegrity = "integrity" - atIsmap = "ismap" - atLanguage = "language" - atMedia = "media" - atMethod = "method" - atMultiple = "multiple" - atName = "name" - atNomodule = "nomodule" - atOnload = "onload" - atReferrerpolicy = "referrerpolicy" - atRel = "rel" - atRequired = "required" - atRows = "rows" - atRowspan = "rowspan" - atSelected = "selected" - atSize = "size" - atSizes = "sizes" - atSlot = "slot" - atSrc = "src" - atSrcset = "srcset" - atStyle = "style" - atStylesheet = "stylesheet" - atTarget = "target" - atText = "text" - atTitle = "title" - atType = "type" - atUsemap = "usemap" - atValign = "valign" - atValue = "value" - atWidth = "width" - const InputTypeWithSize* = { INPUT_SEARCH, INPUT_TEXT, INPUT_EMAIL, INPUT_PASSWORD, INPUT_URL, INPUT_TEL } |