diff options
author | bptato <nincsnevem662@gmail.com> | 2024-11-15 17:06:53 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-11-15 17:06:53 +0100 |
commit | def4ceccfb77afd74b1dd1273b66d036b766fd5f (patch) | |
tree | 8fb976f0ebe632029afe2ee9542d31b88e4f23d1 /src/html | |
parent | fd10019d8b8a1b5dcb0026521fa8f5f072c3a10a (diff) | |
download | chawan-def4ceccfb77afd74b1dd1273b66d036b766fd5f.tar.gz |
js: reorganize modules, update docs
most of it has already been moved to monoucha, and the rest fits better in other directories. also, move urimethodmap to config
Diffstat (limited to 'src/html')
-rw-r--r-- | src/html/dom.nim | 6 | ||||
-rw-r--r-- | src/html/domexception.nim | 55 | ||||
-rw-r--r-- | src/html/env.nim | 10 | ||||
-rw-r--r-- | src/html/event.nim | 4 | ||||
-rw-r--r-- | src/html/formdata.nim | 2 | ||||
-rw-r--r-- | src/html/jsencoding.nim | 100 | ||||
-rw-r--r-- | src/html/jsintl.nim | 66 | ||||
-rw-r--r-- | src/html/xmlhttprequest.nim | 2 |
8 files changed, 233 insertions, 12 deletions
diff --git a/src/html/dom.nim b/src/html/dom.nim index c6b14c27..274d401f 100644 --- a/src/html/dom.nim +++ b/src/html/dom.nim @@ -16,15 +16,15 @@ import css/cssvalues import css/mediaquery import css/sheet import html/catom +import html/domexception import html/enums import html/event import html/script import io/bufwriter +import io/console import io/dynstream import io/promise -import js/console -import js/domexception -import js/timeout +import io/timeout import loader/headers import loader/loaderiface import loader/request diff --git a/src/html/domexception.nim b/src/html/domexception.nim new file mode 100644 index 00000000..d07e88f4 --- /dev/null +++ b/src/html/domexception.nim @@ -0,0 +1,55 @@ +import monoucha/javascript +import monoucha/jserror +import monoucha/quickjs +import types/opt + +const NamesTable = { + "IndexSizeError": 1u16, + "HierarchyRequestError": 3u16, + "WrongDocumentError": 4u16, + "InvalidCharacterError": 5u16, + "NoModificationAllowedError": 7u16, + "NotFoundError": 8u16, + "NotSupportedError": 9u16, + "InUseAttributeError": 10u16, + "InvalidStateError": 11u16, + "SyntaxError": 12u16, + "InvalidModificationError": 13u16, + "NamespaceError": 14u16, + "InvalidAccessError": 15u16, + "TypeMismatchError": 17u16, + "SecurityError": 18u16, + "NetworkError": 19u16, + "AbortError": 20u16, + "URLMismatchError": 21u16, + "QuotaExceededError": 22u16, + "TimeoutError": 23u16, + "InvalidNodeTypeError": 24u16, + "DataCloneError": 25u16 +} + +type + DOMException* = ref object of JSError + name* {.jsget.}: string + code {.jsget.}: uint16 + + DOMResult*[T] = Result[T, DOMException] + +jsDestructor(DOMException) + +proc newDOMException*(message = ""; name = "Error"): DOMException {.jsctor.} = + let ex = DOMException(e: jeDOMException, name: name, message: message) + for it in NamesTable: + if it[0] == name: + ex.code = it[1] + break + return ex + +template errDOMException*(message, name: string): untyped = + err(newDOMException(message, name)) + +func message0(this: DOMException): string {.jsfget: "message".} = + return this.message + +proc addDOMExceptionModule*(ctx: JSContext) = + ctx.registerType(DOMException, JS_CLASS_ERROR, errid = opt(jeDOMException)) diff --git a/src/html/env.nim b/src/html/env.nim index b8c4fc31..d0c77b46 100644 --- a/src/html/env.nim +++ b/src/html/env.nim @@ -3,17 +3,17 @@ import std/tables import html/catom import html/chadombuilder import html/dom +import html/domexception import html/event import html/formdata +import html/jsencoding +import html/jsintl import html/script import html/xmlhttprequest +import io/console import io/dynstream import io/promise -import js/console -import js/domexception -import js/encoding -import js/intl -import js/timeout +import io/timeout import loader/headers import loader/loaderiface import loader/request diff --git a/src/html/event.nim b/src/html/event.nim index 61885b57..40162a8e 100644 --- a/src/html/event.nim +++ b/src/html/event.nim @@ -2,9 +2,9 @@ import std/math import std/options import html/catom +import html/domexception import html/script -import js/domexception -import js/timeout +import io/timeout import monoucha/fromjs import monoucha/javascript import monoucha/jserror diff --git a/src/html/formdata.nim b/src/html/formdata.nim index 56d49df2..f6a7451b 100644 --- a/src/html/formdata.nim +++ b/src/html/formdata.nim @@ -1,9 +1,9 @@ import chame/tags import html/catom import html/dom +import html/domexception import html/enums import io/dynstream -import js/domexception import monoucha/fromjs import monoucha/javascript import monoucha/tojs diff --git a/src/html/jsencoding.nim b/src/html/jsencoding.nim new file mode 100644 index 00000000..7aae5eb2 --- /dev/null +++ b/src/html/jsencoding.nim @@ -0,0 +1,100 @@ +import chagashi/charset +import chagashi/decoder +import monoucha/javascript +import monoucha/jserror +import monoucha/jstypes +import monoucha/quickjs +import types/opt + +type + JSTextEncoder = ref object + + JSTextDecoder = ref object + encoding: Charset + ignoreBOM {.jsget.}: bool + errorMode: DecoderErrorMode + stream: bool + bomSeen: bool + tdctx: TextDecoderContext + +jsDestructor(JSTextDecoder) +jsDestructor(JSTextEncoder) + +type TextDecoderOptions = object of JSDict + fatal {.jsdefault.}: bool + ignoreBOM {.jsdefault.}: bool + +func newJSTextDecoder(label = "utf-8"; options = TextDecoderOptions()): + JSResult[JSTextDecoder] {.jsctor.} = + let encoding = getCharset(label) + if encoding in {CHARSET_UNKNOWN, CHARSET_REPLACEMENT}: + return errRangeError("Invalid encoding label") + let errorMode = if options.fatal: demFatal else: demReplacement + return ok(JSTextDecoder( + ignoreBOM: options.ignoreBOM, + errorMode: errorMode, + tdctx: initTextDecoderContext(encoding, errorMode), + encoding: encoding + )) + +func fatal(this: JSTextDecoder): bool {.jsfget.} = + return this.errorMode == demFatal + +type TextDecodeOptions = object of JSDict + stream {.jsdefault.}: bool + +#TODO AllowSharedBufferSource +proc decode(ctx: JSContext; this: JSTextDecoder; + input = none(JSArrayBufferView); options = TextDecodeOptions()): JSValue + {.jsfunc.} = + if not this.stream: + this.tdctx = initTextDecoderContext(this.encoding, this.errorMode) + this.bomSeen = false + this.stream = options.stream + if input.isSome: + let input = input.get + let H = int(input.abuf.len) - 1 + var oq = "" + let stream = this.stream + for chunk in this.tdctx.decode(input.abuf.p.toOpenArray(0, H), not stream): + oq &= chunk + if this.tdctx.failed: + this.tdctx.failed = false + return JS_ThrowTypeError(ctx, "failed to decode string") + return JS_NewStringLen(ctx, cstring(oq), csize_t(oq.len)) + return JS_NewString(ctx, "") + +func jencoding(this: JSTextDecoder): string {.jsfget: "encoding".} = + return $this.encoding + +func newTextEncoder(): JSTextEncoder {.jsctor.} = + return JSTextEncoder() + +func jencoding(this: JSTextEncoder): string {.jsfget: "encoding".} = + return "utf-8" + +proc dealloc_wrap(rt: JSRuntime; opaque, p: pointer) {.cdecl.} = + dealloc(p) + +proc encode(this: JSTextEncoder; input = ""): JSUint8Array {.jsfunc.} = + # we have to validate input first :/ + #TODO it is possible to do less copies here... + var input = input.toValidUTF8() + let buf = cast[ptr UncheckedArray[uint8]](alloc(input.len)) + copyMem(buf, addr input[0], input.len) + let abuf = JSArrayBuffer( + p: buf, + len: csize_t(input.len), + dealloc: dealloc_wrap + ) + return JSUint8Array( + abuf: abuf, + offset: 0, + nmemb: csize_t(input.len) + ) + +#TODO encodeInto + +proc addEncodingModule*(ctx: JSContext) = + ctx.registerType(JSTextDecoder, name = "TextDecoder") + ctx.registerType(JSTextEncoder, name = "TextEncoder") diff --git a/src/html/jsintl.nim b/src/html/jsintl.nim new file mode 100644 index 00000000..b980fb90 --- /dev/null +++ b/src/html/jsintl.nim @@ -0,0 +1,66 @@ +# Very minimal Intl module... TODO make it more complete + +import monoucha/javascript +import monoucha/jstypes +import monoucha/quickjs +import monoucha/tojs + +type + NumberFormat = ref object + + PluralRules = ref object + + PRResolvedOptions = object of JSDict + locale: string + +jsDestructor(NumberFormat) +jsDestructor(PluralRules) + +#TODO ...yeah +proc newNumberFormat(name: string = "en-US"; options = none(JSValue)): + NumberFormat {.jsctor.} = + return NumberFormat() + +#TODO +proc newPluralRules(): PluralRules {.jsctor.} = + return PluralRules() + +proc resolvedOptions(this: PluralRules): PRResolvedOptions {.jsfunc.} = + return PRResolvedOptions( + locale: "en-US" + ) + +#TODO: this should accept string/BigInt too +proc format(nf: NumberFormat; num: float64): string {.jsfunc.} = + let s = $num + var i = 0 + var L = s.len + for k in countdown(s.high, 0): + if s[k] == '.': + L = k + break + if L mod 3 != 0: + while i < L mod 3: + result &= s[i] + inc i + if i < L: + result &= ',' + let j = i + while i < L: + if j != i and i mod 3 == j: + result &= ',' + result &= s[i] + inc i + if i + 1 < s.len and s[i] == '.': + if not (s[i + 1] == '0' and s.len == i + 2): + while i < s.len: + result &= s[i] + inc i + +proc addIntlModule*(ctx: JSContext) = + let global = JS_GetGlobalObject(ctx) + let intl = JS_NewObject(ctx) + ctx.registerType(NumberFormat, namespace = intl) + ctx.registerType(PluralRules, namespace = intl) + ctx.defineProperty(global, "Intl", intl) + JS_FreeValue(ctx, global) diff --git a/src/html/xmlhttprequest.nim b/src/html/xmlhttprequest.nim index 50c963c1..0185e03a 100644 --- a/src/html/xmlhttprequest.nim +++ b/src/html/xmlhttprequest.nim @@ -7,11 +7,11 @@ import chagashi/decoder import html/catom import html/chadombuilder import html/dom +import html/domexception import html/event import html/script import io/dynstream import io/promise -import js/domexception import loader/headers import loader/loaderiface import loader/request |