Merge branch 'master' of github.com:pragmagic/karax
This commit is contained in:
commit
b36380a48e
11 changed files with 11612 additions and 53 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -1,2 +1,5 @@
|
||||||
nimcache/
|
nimcache/
|
||||||
/tests/tester
|
/tests/tester
|
||||||
|
/tools/karun
|
||||||
|
*.code-workspace
|
||||||
|
*.exe
|
||||||
|
|
|
||||||
25
experiments/scrollapp_simple.nim
Normal file
25
experiments/scrollapp_simple.nim
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
## Example that shows how to accomplish an "infinitely scrolling" app.
|
||||||
|
|
||||||
|
include karax / prelude
|
||||||
|
import karax / [kdom, vstyles]
|
||||||
|
|
||||||
|
var entries: seq[cstring] = @[]
|
||||||
|
for i in 1..500:
|
||||||
|
entries.add(cstring("Entry ") & &i)
|
||||||
|
|
||||||
|
proc scrollEvent(ev: Event; n: VNode) =
|
||||||
|
let d = n.dom
|
||||||
|
if d != nil and inViewport(d.lastChild):
|
||||||
|
# "load" more data:
|
||||||
|
for i in 1..50:
|
||||||
|
entries.add(cstring("Loaded Entry ") & &i)
|
||||||
|
|
||||||
|
proc createDom(): VNode =
|
||||||
|
result = buildHtml():
|
||||||
|
tdiv(onscroll=scrollEvent, style=style(
|
||||||
|
(StyleAttr.height, cstring"400px"), (StyleAttr.overflow, cstring"scroll"))):
|
||||||
|
for x in entries:
|
||||||
|
tdiv:
|
||||||
|
text x
|
||||||
|
|
||||||
|
setRenderer createDom
|
||||||
|
|
@ -8,6 +8,8 @@ var
|
||||||
|
|
||||||
proc hasErrors*(): bool = gerrorCounter != 0
|
proc hasErrors*(): bool = gerrorCounter != 0
|
||||||
|
|
||||||
|
proc hasError*(field: cstring): bool = gerrorMsgs.contains(field) and len(gerrorMsgs[field]) > 0
|
||||||
|
|
||||||
proc disableOnError*(): cstring = toDisabled(hasErrors())
|
proc disableOnError*(): cstring = toDisabled(hasErrors())
|
||||||
|
|
||||||
proc getError*(field: cstring): cstring =
|
proc getError*(field: cstring): cstring =
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,12 @@
|
||||||
|
|
||||||
import karax
|
import karax
|
||||||
|
|
||||||
proc ajax(meth, url: cstring; headers: openarray[(cstring, cstring)];
|
proc ajax*(meth, url: cstring; headers: openarray[(cstring, cstring)];
|
||||||
data: cstring;
|
data: cstring;
|
||||||
cont: proc (httpStatus: int; response: cstring);
|
cont: proc (httpStatus: int; response: cstring);
|
||||||
kxi: KaraxInstance = kxi) =
|
kxi: KaraxInstance = kxi,
|
||||||
|
useBinary: bool = false,
|
||||||
|
blob: Blob = nil) =
|
||||||
proc contWrapper(httpStatus: int; response: cstring) =
|
proc contWrapper(httpStatus: int; response: cstring) =
|
||||||
cont(httpStatus, response)
|
cont(httpStatus, response)
|
||||||
redraw(kxi)
|
redraw(kxi)
|
||||||
|
|
@ -22,6 +24,7 @@ proc ajax(meth, url: cstring; headers: openarray[(cstring, cstring)];
|
||||||
proc setRequestHeader(r: HttpRequest; a, b: cstring) {.importcpp: "#.setRequestHeader(@)".}
|
proc setRequestHeader(r: HttpRequest; a, b: cstring) {.importcpp: "#.setRequestHeader(@)".}
|
||||||
proc statechange(r: HttpRequest; cb: proc()) {.importcpp: "#.onreadystatechange = #".}
|
proc statechange(r: HttpRequest; cb: proc()) {.importcpp: "#.onreadystatechange = #".}
|
||||||
proc send(r: HttpRequest; data: cstring) {.importcpp: "#.send(#)".}
|
proc send(r: HttpRequest; data: cstring) {.importcpp: "#.send(#)".}
|
||||||
|
proc send(r: HttpRequest, data: Blob) {.importcpp: "#.send(#)".}
|
||||||
proc open(r: HttpRequest; meth, url: cstring; async: bool) {.importcpp: "#.open(@)".}
|
proc open(r: HttpRequest; meth, url: cstring; async: bool) {.importcpp: "#.open(@)".}
|
||||||
proc newRequest(): HttpRequest {.importcpp: "new XMLHttpRequest(@)".}
|
proc newRequest(): HttpRequest {.importcpp: "new XMLHttpRequest(@)".}
|
||||||
|
|
||||||
|
|
@ -36,6 +39,9 @@ proc ajax(meth, url: cstring; headers: openarray[(cstring, cstring)];
|
||||||
contWrapper(this.status, this.responseText)
|
contWrapper(this.status, this.responseText)
|
||||||
else:
|
else:
|
||||||
contWrapper(this.status, this.statusText)
|
contWrapper(this.status, this.statusText)
|
||||||
|
if useBinary:
|
||||||
|
ajax.send(blob)
|
||||||
|
else:
|
||||||
ajax.send(data)
|
ajax.send(data)
|
||||||
|
|
||||||
proc ajaxPost*(url: cstring; headers: openarray[(cstring, cstring)];
|
proc ajaxPost*(url: cstring; headers: openarray[(cstring, cstring)];
|
||||||
|
|
@ -44,10 +50,28 @@ proc ajaxPost*(url: cstring; headers: openarray[(cstring, cstring)];
|
||||||
kxi: KaraxInstance = kxi) =
|
kxi: KaraxInstance = kxi) =
|
||||||
ajax("POST", url, headers, data, cont, kxi)
|
ajax("POST", url, headers, data, cont, kxi)
|
||||||
|
|
||||||
|
proc ajaxPost*(url: cstring; headers: openarray[(cstring, cstring)];
|
||||||
|
data: Blob;
|
||||||
|
cont: proc (httpStatus: int, response: cstring);
|
||||||
|
kxi: KaraxInstance = kxi) =
|
||||||
|
ajax("POST", url, headers, "", cont, kxi, true, data)
|
||||||
|
|
||||||
proc ajaxGet*(url: cstring; headers: openarray[(cstring, cstring)];
|
proc ajaxGet*(url: cstring; headers: openarray[(cstring, cstring)];
|
||||||
cont: proc (httpStatus: int, response: cstring);
|
cont: proc (httpStatus: int, response: cstring);
|
||||||
kxi: KaraxInstance = kxi) =
|
kxi: KaraxInstance = kxi) =
|
||||||
ajax("GET", url, headers, nil, cont, kxi)
|
ajax("GET", url, headers, nil, cont, kxi)
|
||||||
|
|
||||||
|
proc ajaxPut*(url: cstring; headers: openarray[(cstring, cstring)];
|
||||||
|
data: cstring;
|
||||||
|
cont: proc (httpStatus: int, response: cstring);
|
||||||
|
kxi: KaraxInstance = kxi) =
|
||||||
|
ajax("PUT", url, headers, data, cont, kxi)
|
||||||
|
|
||||||
|
proc ajaxDelete*(url: cstring; headers: openarray[(cstring, cstring)];
|
||||||
|
cont: proc (httpStatus: int, response: cstring);
|
||||||
|
kxi: KaraxInstance = kxi) =
|
||||||
|
ajax("DELETE", url, headers, nil, cont, kxi)
|
||||||
|
|
||||||
|
|
||||||
proc toJson*[T](data: T): cstring {.importc: "JSON.stringify".}
|
proc toJson*[T](data: T): cstring {.importc: "JSON.stringify".}
|
||||||
proc fromJson*[T](blob: cstring): T {.importc: "JSON.parse".}
|
proc fromJson*[T](blob: cstring): T {.importc: "JSON.parse".}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import kdom, vdom, jstrutils, compact, jdict, vstyles
|
import kdom, vdom, jstrutils, compact, jdict, vstyles
|
||||||
|
|
||||||
export kdom.Event
|
export kdom.Event, kdom.Blob
|
||||||
|
|
||||||
proc kout*[T](x: T) {.importc: "console.log", varargs, deprecated.}
|
proc kout*[T](x: T) {.importc: "console.log", varargs, deprecated.}
|
||||||
## the preferred way of debugging karax applications. Now deprecated,
|
## the preferred way of debugging karax applications. Now deprecated,
|
||||||
|
|
@ -86,7 +86,7 @@ proc wrapEvent(d: Node; n: VNode; k: EventKind;
|
||||||
let action = action
|
let action = action
|
||||||
let n = n
|
let n = n
|
||||||
result = proc (ev: Event) =
|
result = proc (ev: Event) =
|
||||||
if ev.keyCode == 13: keyeventBody()
|
if cast[KeyboardEvent](ev).keyCode == 13: keyeventBody()
|
||||||
|
|
||||||
proc laterWrapper(): NativeEventHandler =
|
proc laterWrapper(): NativeEventHandler =
|
||||||
let action = action
|
let action = action
|
||||||
|
|
@ -262,6 +262,7 @@ proc updateStyles(newNode, oldNode: VNode) =
|
||||||
if oldNode.dom != nil:
|
if oldNode.dom != nil:
|
||||||
if newNode.style != nil: applyStyle(oldNode.dom, newNode.style)
|
if newNode.style != nil: applyStyle(oldNode.dom, newNode.style)
|
||||||
else: oldNode.dom.style = Style()
|
else: oldNode.dom.style = Style()
|
||||||
|
oldNode.dom.class = newNode.class
|
||||||
oldNode.style = newNode.style
|
oldNode.style = newNode.style
|
||||||
oldNode.class = newNode.class
|
oldNode.class = newNode.class
|
||||||
|
|
||||||
|
|
|
||||||
665
karax/kdom.nim
665
karax/kdom.nim
|
|
@ -37,6 +37,38 @@ type
|
||||||
onsubmit*: proc (event: Event) {.nimcall.}
|
onsubmit*: proc (event: Event) {.nimcall.}
|
||||||
onunload*: proc (event: Event) {.nimcall.}
|
onunload*: proc (event: Event) {.nimcall.}
|
||||||
|
|
||||||
|
# https://developer.mozilla.org/en-US/docs/Web/Events
|
||||||
|
DomEvent* {.pure.} = enum
|
||||||
|
Abort = "abort",
|
||||||
|
BeforeInput = "beforeinput",
|
||||||
|
Blur = "blur",
|
||||||
|
Click = "click",
|
||||||
|
CompositionEnd = "compositionend",
|
||||||
|
CompositionStart = "compositionstart",
|
||||||
|
CompositionUpdate = "compositionupdate",
|
||||||
|
DblClick = "dblclick",
|
||||||
|
Error = "error",
|
||||||
|
Focus = "focus",
|
||||||
|
FocusIn = "focusin",
|
||||||
|
FocusOut = "focusout",
|
||||||
|
Input = "input",
|
||||||
|
KeyDown = "keydown",
|
||||||
|
KeyPress = "keypress",
|
||||||
|
KeyUp = "keyup",
|
||||||
|
Load = "load",
|
||||||
|
MouseDown = "mousedown",
|
||||||
|
MouseEnter = "mouseenter",
|
||||||
|
MouseLeave = "mouseleave",
|
||||||
|
MouseMove = "mousemove",
|
||||||
|
MouseOut = "mouseout",
|
||||||
|
MouseOver = "mouseover",
|
||||||
|
MouseUp = "mouseup",
|
||||||
|
Resize = "resize",
|
||||||
|
Scroll = "scroll",
|
||||||
|
Select = "select",
|
||||||
|
Unload = "unload",
|
||||||
|
Wheel = "wheel"
|
||||||
|
|
||||||
Window* = ref WindowObj
|
Window* = ref WindowObj
|
||||||
WindowObj {.importc.} = object of EventTargetObj
|
WindowObj {.importc.} = object of EventTargetObj
|
||||||
document*: Document
|
document*: Document
|
||||||
|
|
@ -57,6 +89,7 @@ type
|
||||||
status*: cstring
|
status*: cstring
|
||||||
toolbar*: ref ToolBar
|
toolbar*: ref ToolBar
|
||||||
frames*: seq[Frame]
|
frames*: seq[Frame]
|
||||||
|
screen*: Screen
|
||||||
|
|
||||||
Frame* = ref FrameObj
|
Frame* = ref FrameObj
|
||||||
FrameObj {.importc.} = object of WindowObj
|
FrameObj {.importc.} = object of WindowObj
|
||||||
|
|
@ -131,9 +164,8 @@ type
|
||||||
name*: cstring
|
name*: cstring
|
||||||
readOnly*: bool
|
readOnly*: bool
|
||||||
options*: seq[OptionElement]
|
options*: seq[OptionElement]
|
||||||
|
selectedOptions*: seq[OptionElement]
|
||||||
# https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement
|
clientWidth*, clientHeight*: int
|
||||||
HtmlElement* = ref object of Element
|
|
||||||
contentEditable*: string
|
contentEditable*: string
|
||||||
isContentEditable*: bool
|
isContentEditable*: bool
|
||||||
dir*: string
|
dir*: string
|
||||||
|
|
@ -142,6 +174,87 @@ type
|
||||||
offsetLeft*: int
|
offsetLeft*: int
|
||||||
offsetTop*: int
|
offsetTop*: int
|
||||||
|
|
||||||
|
# https://developer.mozilla.org/en-US/docs/Web/API/ValidityState
|
||||||
|
ValidityState* = ref ValidityStateObj
|
||||||
|
ValidityStateObj {.importc.} = object
|
||||||
|
badInput*: bool
|
||||||
|
customError*: bool
|
||||||
|
patternMismatch*: bool
|
||||||
|
rangeOverflow*: bool
|
||||||
|
rangeUnderflow*: bool
|
||||||
|
stepMismatch*: bool
|
||||||
|
tooLong*: bool
|
||||||
|
tooShort*: bool
|
||||||
|
typeMismatch*: bool
|
||||||
|
valid*: bool
|
||||||
|
valueMissing*: bool
|
||||||
|
|
||||||
|
# https://developer.mozilla.org/en-US/docs/Web/API/Blob
|
||||||
|
Blob* = ref BlobObj
|
||||||
|
BlobObj {.importc.} = object of RootObj
|
||||||
|
size*: int
|
||||||
|
`type`*: cstring
|
||||||
|
|
||||||
|
# https://developer.mozilla.org/en-US/docs/Web/API/File
|
||||||
|
File* = ref FileObj
|
||||||
|
FileObj {.importc.} = object of Blob
|
||||||
|
lastModified*: int
|
||||||
|
name*: cstring
|
||||||
|
|
||||||
|
# https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement
|
||||||
|
InputElement* = ref InputElementObj
|
||||||
|
InputElementObj {.importc.} = object of Element
|
||||||
|
# Properties related to the parent form
|
||||||
|
formAction*: cstring
|
||||||
|
formEncType*: cstring
|
||||||
|
formMethod*: cstring
|
||||||
|
formNoValidate*: bool
|
||||||
|
formTarget*: cstring
|
||||||
|
|
||||||
|
# Properties that apply to any type of input element that is not hidden
|
||||||
|
`type`*: cstring
|
||||||
|
autofocus*: bool
|
||||||
|
required*: bool
|
||||||
|
value*: cstring
|
||||||
|
validity*: ValidityState
|
||||||
|
validationMessage*: cstring
|
||||||
|
willValidate*: bool
|
||||||
|
|
||||||
|
# Properties that apply only to elements of type "checkbox" or "radio"
|
||||||
|
indeterminate*: bool
|
||||||
|
|
||||||
|
# Properties that apply only to elements of type "image"
|
||||||
|
alt*: cstring
|
||||||
|
height*: cstring
|
||||||
|
src*: cstring
|
||||||
|
width*: cstring
|
||||||
|
|
||||||
|
# Properties that apply only to elements of type "file"
|
||||||
|
accept*: cstring
|
||||||
|
files*: seq[Blob]
|
||||||
|
|
||||||
|
# Properties that apply only to text/number-containing or elements
|
||||||
|
autocomplete*: cstring
|
||||||
|
maxLength*: int
|
||||||
|
size*: int
|
||||||
|
pattern*: cstring
|
||||||
|
placeholder*: cstring
|
||||||
|
min*: cstring
|
||||||
|
max*: cstring
|
||||||
|
selectionStart*: int
|
||||||
|
selectionEnd*: int
|
||||||
|
selectionDirection*: cstring
|
||||||
|
|
||||||
|
# Properties not yet categorized
|
||||||
|
dirName*: cstring
|
||||||
|
accessKey*: cstring
|
||||||
|
list*: Element
|
||||||
|
multiple*: bool
|
||||||
|
labels*: seq[Element]
|
||||||
|
step*: cstring
|
||||||
|
valueAsDate*: cstring
|
||||||
|
valueAsNumber*: float
|
||||||
|
|
||||||
LinkElement* = ref LinkObj
|
LinkElement* = ref LinkObj
|
||||||
LinkObj {.importc.} = object of ElementObj
|
LinkObj {.importc.} = object of ElementObj
|
||||||
target*: cstring
|
target*: cstring
|
||||||
|
|
@ -171,13 +284,19 @@ type
|
||||||
text*: cstring
|
text*: cstring
|
||||||
value*: cstring
|
value*: cstring
|
||||||
|
|
||||||
|
# https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement
|
||||||
FormElement* = ref FormObj
|
FormElement* = ref FormObj
|
||||||
FormObj {.importc.} = object of ElementObj
|
FormObj {.importc.} = object of ElementObj
|
||||||
|
acceptCharset*: cstring
|
||||||
action*: cstring
|
action*: cstring
|
||||||
encoding*: cstring
|
autocomplete*: cstring
|
||||||
`method`*: cstring
|
|
||||||
target*: cstring
|
|
||||||
elements*: seq[Element]
|
elements*: seq[Element]
|
||||||
|
encoding*: cstring
|
||||||
|
enctype*: cstring
|
||||||
|
length*: int
|
||||||
|
`method`*: cstring
|
||||||
|
noValidate*: bool
|
||||||
|
target*: cstring
|
||||||
|
|
||||||
ImageElement* = ref ImageObj
|
ImageElement* = ref ImageObj
|
||||||
ImageObj {.importc.} = object of ElementObj
|
ImageObj {.importc.} = object of ElementObj
|
||||||
|
|
@ -284,55 +403,467 @@ type
|
||||||
wordSpacing*: cstring
|
wordSpacing*: cstring
|
||||||
zIndex*: int
|
zIndex*: int
|
||||||
|
|
||||||
# TODO: A lot of the fields in Event belong to a more specific type of event.
|
EventPhase* = enum
|
||||||
# TODO: Should we clean this up?
|
None = 0,
|
||||||
|
CapturingPhase,
|
||||||
|
AtTarget,
|
||||||
|
BubblingPhase
|
||||||
|
|
||||||
|
# https://developer.mozilla.org/en-US/docs/Web/API/Event
|
||||||
Event* = ref EventObj
|
Event* = ref EventObj
|
||||||
EventObj {.importc.} = object of RootObj
|
EventObj {.importc.} = object of RootObj
|
||||||
|
bubbles*: bool
|
||||||
|
cancelBubble*: bool
|
||||||
|
cancelable*: bool
|
||||||
|
composed*: bool
|
||||||
|
currentTarget*: Node
|
||||||
|
defaultPrevented*: bool
|
||||||
|
eventPhase*: int
|
||||||
target*: Node
|
target*: Node
|
||||||
altKey*, ctrlKey*, shiftKey*: bool
|
`type`*: cstring
|
||||||
button*: int
|
isTrusted*: bool
|
||||||
clientX*, clientY*: int
|
|
||||||
|
# https://developer.mozilla.org/en-US/docs/Web/API/UIEvent
|
||||||
|
UIEvent* = ref UIEventObj
|
||||||
|
UIEventObj {.importc.} = object of Event
|
||||||
|
detail*: int64
|
||||||
|
view*: Window
|
||||||
|
|
||||||
|
# https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent
|
||||||
|
KeyboardEvent* = ref KeyboardEventObj
|
||||||
|
KeyboardEventObj {.importc.} = object of UIEvent
|
||||||
|
altKey*, ctrlKey*, metaKey*, shiftKey*: bool
|
||||||
|
code*: cstring
|
||||||
|
isComposing*: bool
|
||||||
|
key*: cstring
|
||||||
keyCode*: int
|
keyCode*: int
|
||||||
layerX*, layerY*: int
|
location*: int
|
||||||
modifiers*: int
|
|
||||||
ALT_MASK*, CONTROL_MASK*, SHIFT_MASK*, META_MASK*: int
|
# https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values
|
||||||
|
KeyboardEventKey* {.pure.} = enum
|
||||||
|
# Modifier keys
|
||||||
|
Alt,
|
||||||
|
AltGraph,
|
||||||
|
CapsLock,
|
||||||
|
Control,
|
||||||
|
Fn,
|
||||||
|
FnLock,
|
||||||
|
Hyper,
|
||||||
|
Meta,
|
||||||
|
NumLock,
|
||||||
|
ScrollLock,
|
||||||
|
Shift,
|
||||||
|
Super,
|
||||||
|
Symbol,
|
||||||
|
SymbolLock,
|
||||||
|
|
||||||
|
# Whitespace keys
|
||||||
|
ArrowDown,
|
||||||
|
ArrowLeft,
|
||||||
|
ArrowRight,
|
||||||
|
ArrowUp,
|
||||||
|
End,
|
||||||
|
Home,
|
||||||
|
PageDown,
|
||||||
|
PageUp,
|
||||||
|
|
||||||
|
# Editing keys
|
||||||
|
Backspace,
|
||||||
|
Clear,
|
||||||
|
Copy,
|
||||||
|
CrSel,
|
||||||
|
Cut,
|
||||||
|
Delete,
|
||||||
|
EraseEof,
|
||||||
|
ExSel,
|
||||||
|
Insert,
|
||||||
|
Paste,
|
||||||
|
Redo,
|
||||||
|
Undo,
|
||||||
|
|
||||||
|
# UI keys
|
||||||
|
Accept,
|
||||||
|
Again,
|
||||||
|
Attn,
|
||||||
|
Cancel,
|
||||||
|
ContextMenu,
|
||||||
|
Escape,
|
||||||
|
Execute,
|
||||||
|
Find,
|
||||||
|
Finish,
|
||||||
|
Help,
|
||||||
|
Pause,
|
||||||
|
Play,
|
||||||
|
Props,
|
||||||
|
Select,
|
||||||
|
ZoomIn,
|
||||||
|
ZoomOut,
|
||||||
|
|
||||||
|
# Device keys
|
||||||
|
BrigtnessDown,
|
||||||
|
BrigtnessUp,
|
||||||
|
Eject,
|
||||||
|
LogOff,
|
||||||
|
Power,
|
||||||
|
PowerOff,
|
||||||
|
PrintScreen,
|
||||||
|
Hibernate,
|
||||||
|
Standby,
|
||||||
|
WakeUp,
|
||||||
|
|
||||||
|
# Common IME keys
|
||||||
|
AllCandidates,
|
||||||
|
Alphanumeric,
|
||||||
|
CodeInput,
|
||||||
|
Compose,
|
||||||
|
Convert,
|
||||||
|
Dead,
|
||||||
|
FinalMode,
|
||||||
|
GroupFirst,
|
||||||
|
GroupLast,
|
||||||
|
GroupNext,
|
||||||
|
GroupPrevious,
|
||||||
|
ModeChange,
|
||||||
|
NextCandidate,
|
||||||
|
NonConvert,
|
||||||
|
PreviousCandidate,
|
||||||
|
Process,
|
||||||
|
SingleCandidate,
|
||||||
|
|
||||||
|
# Korean keyboards only
|
||||||
|
HangulMode,
|
||||||
|
HanjaMode,
|
||||||
|
JunjaMode,
|
||||||
|
|
||||||
|
# Japanese keyboards only
|
||||||
|
Eisu,
|
||||||
|
Hankaku,
|
||||||
|
Hiragana,
|
||||||
|
HiraganaKatakana,
|
||||||
|
KanaMode,
|
||||||
|
KanjiMode,
|
||||||
|
Katakana,
|
||||||
|
Romaji,
|
||||||
|
Zenkaku,
|
||||||
|
ZenkakuHanaku,
|
||||||
|
|
||||||
|
# Function keys
|
||||||
|
F1,
|
||||||
|
F2,
|
||||||
|
F3,
|
||||||
|
F4,
|
||||||
|
F5,
|
||||||
|
F6,
|
||||||
|
F7,
|
||||||
|
F8,
|
||||||
|
F9,
|
||||||
|
F10,
|
||||||
|
F11,
|
||||||
|
F12,
|
||||||
|
F13,
|
||||||
|
F14,
|
||||||
|
F15,
|
||||||
|
F16,
|
||||||
|
F17,
|
||||||
|
F18,
|
||||||
|
F19,
|
||||||
|
F20,
|
||||||
|
Soft1,
|
||||||
|
Soft2,
|
||||||
|
Soft3,
|
||||||
|
Soft4,
|
||||||
|
|
||||||
|
# Phone keys
|
||||||
|
AppSwitch,
|
||||||
|
Call,
|
||||||
|
Camera,
|
||||||
|
CameraFocus,
|
||||||
|
EndCall,
|
||||||
|
GoBack,
|
||||||
|
GoHome,
|
||||||
|
HeadsetHook,
|
||||||
|
LastNumberRedial,
|
||||||
|
Notification,
|
||||||
|
MannerMode,
|
||||||
|
VoiceDial,
|
||||||
|
|
||||||
|
# Multimedia keys
|
||||||
|
ChannelDown,
|
||||||
|
ChannelUp,
|
||||||
|
MediaFastForward,
|
||||||
|
MediaPause,
|
||||||
|
MediaPlay,
|
||||||
|
MediaPlayPause,
|
||||||
|
MediaRecord,
|
||||||
|
MediaRewind,
|
||||||
|
MediaStop,
|
||||||
|
MediaTrackNext,
|
||||||
|
MediaTrackPrevious,
|
||||||
|
|
||||||
|
# Audio control keys
|
||||||
|
AudioBalanceLeft,
|
||||||
|
AudioBalanceRight,
|
||||||
|
AudioBassDown,
|
||||||
|
AudioBassBoostDown,
|
||||||
|
AudioBassBoostToggle,
|
||||||
|
AudioBassBoostUp,
|
||||||
|
AudioBassUp,
|
||||||
|
AudioFaderFront,
|
||||||
|
AudioFaderRear,
|
||||||
|
AudioSurroundModeNext,
|
||||||
|
AudioTrebleDown,
|
||||||
|
AudioTrebleUp,
|
||||||
|
AudioVolumeDown,
|
||||||
|
AUdioVolumeMute,
|
||||||
|
AudioVolumeUp,
|
||||||
|
MicrophoneToggle,
|
||||||
|
MicrophoneVolumeDown,
|
||||||
|
MicrophoneVolumeMute,
|
||||||
|
MicrophoneVolumeUp,
|
||||||
|
|
||||||
|
# TV control keys
|
||||||
|
TV,
|
||||||
|
TV3DMode,
|
||||||
|
TVAntennaCable,
|
||||||
|
TVAudioDescription,
|
||||||
|
TVAudioDescriptionMixDown,
|
||||||
|
TVAudioDescriptionMixUp,
|
||||||
|
TVContentsMenu,
|
||||||
|
TVDataService,
|
||||||
|
TVInput,
|
||||||
|
TVInputComponent1,
|
||||||
|
TVInputComponent2,
|
||||||
|
TVInputComposite1,
|
||||||
|
TVInputComposite2,
|
||||||
|
TVInputHDMI1,
|
||||||
|
TVInputHDMI2,
|
||||||
|
TVInputHDMI3,
|
||||||
|
TVInputHDMI4,
|
||||||
|
TVInputVGA1,
|
||||||
|
TVMediaContext,
|
||||||
|
TVNetwork,
|
||||||
|
TVNumberEntry,
|
||||||
|
TVPower,
|
||||||
|
TVRadioService,
|
||||||
|
TVSatellite,
|
||||||
|
TVSatelliteBS,
|
||||||
|
TVSatelliteCS,
|
||||||
|
TVSatelliteToggle,
|
||||||
|
TVTerrestrialAnalog,
|
||||||
|
TVTerrestrialDigital,
|
||||||
|
TVTimer,
|
||||||
|
|
||||||
|
# Media controller keys
|
||||||
|
AVRInput,
|
||||||
|
AVRPower,
|
||||||
|
ColorF0Red,
|
||||||
|
ColorF1Green,
|
||||||
|
ColorF2Yellow,
|
||||||
|
ColorF3Blue,
|
||||||
|
ColorF4Grey,
|
||||||
|
ColorF5Brown,
|
||||||
|
ClosedCaptionToggle,
|
||||||
|
Dimmer,
|
||||||
|
DisplaySwap,
|
||||||
|
DVR,
|
||||||
|
Exit,
|
||||||
|
FavoriteClear0,
|
||||||
|
FavoriteClear1,
|
||||||
|
FavoriteClear2,
|
||||||
|
FavoriteClear3,
|
||||||
|
FavoriteRecall0,
|
||||||
|
FavoriteRecall1,
|
||||||
|
FavoriteRecall2,
|
||||||
|
FavoriteRecall3,
|
||||||
|
FavoriteStore0,
|
||||||
|
FavoriteStore1,
|
||||||
|
FavoriteStore2,
|
||||||
|
FavoriteStore3,
|
||||||
|
Guide,
|
||||||
|
GuideNextDay,
|
||||||
|
GuidePreviousDay,
|
||||||
|
Info,
|
||||||
|
InstantReplay,
|
||||||
|
Link,
|
||||||
|
ListProgram,
|
||||||
|
LiveContent,
|
||||||
|
Lock,
|
||||||
|
MediaApps,
|
||||||
|
MediaAudioTrack,
|
||||||
|
MediaLast,
|
||||||
|
MediaSkipBackward,
|
||||||
|
MediaSkipForward,
|
||||||
|
MediaStepBackward,
|
||||||
|
MediaStepForward,
|
||||||
|
MediaTopMenu,
|
||||||
|
NavigateIn,
|
||||||
|
NavigateNext,
|
||||||
|
NavigateOut,
|
||||||
|
NavigatePrevious,
|
||||||
|
NextFavoriteChannel,
|
||||||
|
NextUserProfile,
|
||||||
|
OnDemand,
|
||||||
|
Pairing,
|
||||||
|
PinPDown,
|
||||||
|
PinPMove,
|
||||||
|
PinPUp,
|
||||||
|
PlaySpeedDown,
|
||||||
|
PlaySpeedReset,
|
||||||
|
PlaySpeedUp,
|
||||||
|
RandomToggle,
|
||||||
|
RcLowBattery,
|
||||||
|
RecordSpeedNext,
|
||||||
|
RfBypass,
|
||||||
|
ScanChannelsToggle,
|
||||||
|
ScreenModeNext,
|
||||||
|
Settings,
|
||||||
|
SplitScreenToggle,
|
||||||
|
STBInput,
|
||||||
|
STBPower,
|
||||||
|
Subtitle,
|
||||||
|
Teletext,
|
||||||
|
VideoModeNext,
|
||||||
|
Wink,
|
||||||
|
ZoomToggle,
|
||||||
|
|
||||||
|
# Speech recognition keys
|
||||||
|
SpeechCorrectionList,
|
||||||
|
SpeechInputToggle,
|
||||||
|
|
||||||
|
# Document keys
|
||||||
|
Close,
|
||||||
|
New,
|
||||||
|
Open,
|
||||||
|
Print,
|
||||||
|
Save,
|
||||||
|
SpellCheck,
|
||||||
|
MailForward,
|
||||||
|
MailReply,
|
||||||
|
MailSend,
|
||||||
|
|
||||||
|
# Application selector keys
|
||||||
|
LaunchCalculator,
|
||||||
|
LaunchCalendar,
|
||||||
|
LaunchContacts,
|
||||||
|
LaunchMail,
|
||||||
|
LaunchMediaPlayer,
|
||||||
|
LaunchMusicPlayer,
|
||||||
|
LaunchMyComputer,
|
||||||
|
LaunchPhone,
|
||||||
|
LaunchScreenSaver,
|
||||||
|
LaunchSpreadsheet,
|
||||||
|
LaunchWebBrowser,
|
||||||
|
LaunchWebCam,
|
||||||
|
LaunchWordProcessor,
|
||||||
|
LaunchApplication1,
|
||||||
|
LaunchApplication2,
|
||||||
|
LaunchApplication3,
|
||||||
|
LaunchApplication4,
|
||||||
|
LaunchApplication5,
|
||||||
|
LaunchApplication6,
|
||||||
|
LaunchApplication7,
|
||||||
|
LaunchApplication8,
|
||||||
|
LaunchApplication9,
|
||||||
|
LaunchApplication10,
|
||||||
|
LaunchApplication11,
|
||||||
|
LaunchApplication12,
|
||||||
|
LaunchApplication13,
|
||||||
|
LaunchApplication14,
|
||||||
|
LaunchApplication15,
|
||||||
|
LaunchApplication16,
|
||||||
|
|
||||||
|
# Browser control keys
|
||||||
|
BrowserBack,
|
||||||
|
BrowserFavorites,
|
||||||
|
BrowserForward,
|
||||||
|
BrowserHome,
|
||||||
|
BrowserRefresh,
|
||||||
|
BrowserSearch,
|
||||||
|
BrowserStop,
|
||||||
|
|
||||||
|
# Numeric keypad keys
|
||||||
|
Key11,
|
||||||
|
Key12,
|
||||||
|
Separator
|
||||||
|
|
||||||
|
MouseButtons* = enum
|
||||||
|
NoButton = 0,
|
||||||
|
PrimaryButton = 1,
|
||||||
|
SecondaryButton = 2,
|
||||||
|
AuxilaryButton = 4,
|
||||||
|
FourthButton = 8,
|
||||||
|
FifthButton = 16
|
||||||
|
|
||||||
|
# https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent
|
||||||
|
MouseEvent* = ref MouseEventObj
|
||||||
|
MouseEventObj {.importc.} = object of UIEvent
|
||||||
|
altKey*, ctrlKey*, metaKey*, shiftKey*: bool
|
||||||
|
button*: int
|
||||||
|
buttons*: int
|
||||||
|
clientX*, clientY*: int
|
||||||
|
movementX*, movementY*: int
|
||||||
offsetX*, offsetY*: int
|
offsetX*, offsetY*: int
|
||||||
pageX*, pageY*: int
|
pageX*, pageY*: int
|
||||||
|
relatedTarget*: EventTarget
|
||||||
|
#region*: cstring
|
||||||
screenX*, screenY*: int
|
screenX*, screenY*: int
|
||||||
which*: int
|
|
||||||
`type`*: cstring
|
|
||||||
x*, y*: int
|
x*, y*: int
|
||||||
ABORT*: int
|
|
||||||
BLUR*: int
|
DataTransferItemKind* {.pure.} = enum
|
||||||
CHANGE*: int
|
File = "file",
|
||||||
CLICK*: int
|
String = "string"
|
||||||
DBLCLICK*: int
|
|
||||||
DRAGDROP*: int
|
# https://developer.mozilla.org/en-US/docs/Web/API/DataTransferItem
|
||||||
ERROR*: int
|
DataTransferItem* = ref DataTransferItemObj
|
||||||
FOCUS*: int
|
DataTransferItemObj {.importc.} = object of RootObj
|
||||||
KEYDOWN*: int
|
kind*: cstring
|
||||||
KEYPRESS*: int
|
`type`*: cstring
|
||||||
KEYUP*: int
|
|
||||||
LOAD*: int
|
# https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer
|
||||||
MOUSEDOWN*: int
|
DataTransfer* = ref DataTransferObj
|
||||||
MOUSEMOVE*: int
|
DataTransferObj {.importc.} = object of RootObj
|
||||||
MOUSEOUT*: int
|
dropEffect*: cstring
|
||||||
MOUSEOVER*: int
|
effectAllowed*: cstring
|
||||||
MOUSEUP*: int
|
files*: seq[Element]
|
||||||
MOVE*: int
|
items*: seq[DataTransferItem]
|
||||||
RESET*: int
|
types*: seq[cstring]
|
||||||
RESIZE*: int
|
|
||||||
SELECT*: int
|
DataTransferDropEffect* {.pure.} = enum
|
||||||
SUBMIT*: int
|
None = "none",
|
||||||
UNLOAD*: int
|
Copy = "copy",
|
||||||
|
Link = "link",
|
||||||
|
Move = "move"
|
||||||
|
|
||||||
|
DataTransferEffectAllowed* {.pure.} = enum
|
||||||
|
None = "none",
|
||||||
|
Copy = "copy",
|
||||||
|
CopyLink = "copyLink",
|
||||||
|
CopyMove = "copyMove",
|
||||||
|
Link = "link",
|
||||||
|
LinkMove = "linkMove",
|
||||||
|
Move = "move",
|
||||||
|
All = "all",
|
||||||
|
Uninitialized = "uninitialized"
|
||||||
|
|
||||||
|
DragEventTypes* = enum
|
||||||
|
Drag = "drag",
|
||||||
|
DragEnd = "dragend",
|
||||||
|
DragEnter = "dragenter",
|
||||||
|
DragExit = "dragexit",
|
||||||
|
DragLeave = "dragleave",
|
||||||
|
DragOver = "dragover",
|
||||||
|
DragStart = "dragstart",
|
||||||
|
Drop = "drop"
|
||||||
|
|
||||||
|
# https://developer.mozilla.org/en-US/docs/Web/API/DragEvent
|
||||||
|
DragEvent* {.importc.} = object of MouseEvent
|
||||||
|
dataTransfer*: DataTransfer
|
||||||
|
|
||||||
TouchList* {.importc.} = ref object of RootObj
|
TouchList* {.importc.} = ref object of RootObj
|
||||||
length*: int
|
length*: int
|
||||||
|
|
||||||
TouchEvent* {.importc.} = ref object of Event
|
Touch* = ref TouchObj
|
||||||
changedTouches*, targetTouches*, touches*: TouchList
|
TouchObj {.importc.} = object of RootObj
|
||||||
|
|
||||||
Touch* {.importc.} = ref object of RootObj
|
|
||||||
identifier*: int
|
identifier*: int
|
||||||
screenX*, screenY*, clientX*, clientY*, pageX*, pageY*: int
|
screenX*, screenY*, clientX*, clientY*, pageX*, pageY*: int
|
||||||
target*: Element
|
target*: Element
|
||||||
|
|
@ -340,6 +871,10 @@ type
|
||||||
rotationAngle*: int
|
rotationAngle*: int
|
||||||
force*: float
|
force*: float
|
||||||
|
|
||||||
|
TouchEvent* = ref TouchEventObj
|
||||||
|
TouchEventObj {.importc.} = object of UIEvent
|
||||||
|
changedTouches*, targetTouches*, touches*: seq[Touch]
|
||||||
|
|
||||||
Location* = ref LocationObj
|
Location* = ref LocationObj
|
||||||
LocationObj {.importc.} = object of RootObj
|
LocationObj {.importc.} = object of RootObj
|
||||||
hash*: cstring
|
hash*: cstring
|
||||||
|
|
@ -397,6 +932,11 @@ type
|
||||||
TimeOut* {.importc.} = ref object of RootObj
|
TimeOut* {.importc.} = ref object of RootObj
|
||||||
Interval* {.importc.} = object of RootObj
|
Interval* {.importc.} = object of RootObj
|
||||||
|
|
||||||
|
AddEventListenerOptions* = object
|
||||||
|
capture*: bool
|
||||||
|
once*: bool
|
||||||
|
passive*: bool
|
||||||
|
|
||||||
when defined(nodejs):
|
when defined(nodejs):
|
||||||
# we provide a dummy DOM for nodejs for testing purposes
|
# we provide a dummy DOM for nodejs for testing purposes
|
||||||
proc len*(x: Node): int = x.childNodes.len
|
proc len*(x: Node): int = x.childNodes.len
|
||||||
|
|
@ -483,6 +1023,7 @@ proc clearTimeout*(t: Timeout) {.importc, nodecl.}
|
||||||
|
|
||||||
# EventTarget "methods"
|
# EventTarget "methods"
|
||||||
proc addEventListener*(et: EventTarget, ev: cstring, cb: proc(ev: Event), useCapture: bool = false)
|
proc addEventListener*(et: EventTarget, ev: cstring, cb: proc(ev: Event), useCapture: bool = false)
|
||||||
|
proc addEventListener*(et: EventTarget, ev: cstring, cb: proc(ev: Event), options: AddEventListenerOptions)
|
||||||
proc removeEventListener*(et: EventTarget; ev: cstring; cb: proc(ev: Event))
|
proc removeEventListener*(et: EventTarget; ev: cstring; cb: proc(ev: Event))
|
||||||
|
|
||||||
# Window "methods"
|
# Window "methods"
|
||||||
|
|
@ -491,7 +1032,7 @@ proc back*(w: Window)
|
||||||
proc blur*(w: Window)
|
proc blur*(w: Window)
|
||||||
proc captureEvents*(w: Window, eventMask: int) {.deprecated.}
|
proc captureEvents*(w: Window, eventMask: int) {.deprecated.}
|
||||||
proc clearInterval*(w: Window, interval: ref Interval)
|
proc clearInterval*(w: Window, interval: ref Interval)
|
||||||
proc clearTimeout*(w: Window, timeout: TimeOut)
|
proc clearTimeout*(w: Window, timeout: ref TimeOut)
|
||||||
proc close*(w: Window)
|
proc close*(w: Window)
|
||||||
proc confirm*(w: Window, msg: cstring): bool
|
proc confirm*(w: Window, msg: cstring): bool
|
||||||
proc disableExternalCapture*(w: Window)
|
proc disableExternalCapture*(w: Window)
|
||||||
|
|
@ -500,6 +1041,7 @@ proc find*(w: Window, text: cstring, caseSensitive = false,
|
||||||
backwards = false)
|
backwards = false)
|
||||||
proc focus*(w: Window)
|
proc focus*(w: Window)
|
||||||
proc forward*(w: Window)
|
proc forward*(w: Window)
|
||||||
|
proc getComputedStyle*(w: Window, e: Node, pe:Node = nil): Style
|
||||||
proc handleEvent*(w: Window, e: Event)
|
proc handleEvent*(w: Window, e: Event)
|
||||||
proc home*(w: Window)
|
proc home*(w: Window)
|
||||||
proc moveBy*(w: Window, x, y: int)
|
proc moveBy*(w: Window, x, y: int)
|
||||||
|
|
@ -516,7 +1058,7 @@ proc scrollBy*(w: Window, x, y: int)
|
||||||
proc scrollTo*(w: Window, x, y: int)
|
proc scrollTo*(w: Window, x, y: int)
|
||||||
proc setInterval*(w: Window, code: cstring, pause: int): ref Interval
|
proc setInterval*(w: Window, code: cstring, pause: int): ref Interval
|
||||||
proc setInterval*(w: Window, function: proc (), pause: int): ref Interval
|
proc setInterval*(w: Window, function: proc (), pause: int): ref Interval
|
||||||
proc setTimeout*(w: Window, code: cstring, pause: int): TimeOut
|
proc setTimeout*(w: Window, code: cstring, pause: int): ref TimeOut
|
||||||
proc setTimeout*(w: Window, function: proc (), pause: int): ref Interval
|
proc setTimeout*(w: Window, function: proc (), pause: int): ref Interval
|
||||||
proc stop*(w: Window)
|
proc stop*(w: Window)
|
||||||
proc requestAnimationFrame*(w: Window, function: proc (time: float)): int
|
proc requestAnimationFrame*(w: Window, function: proc (time: float)): int
|
||||||
|
|
@ -526,6 +1068,7 @@ proc cancelAnimationFrame*(w: Window, id: int)
|
||||||
proc appendData*(n: Node, data: cstring)
|
proc appendData*(n: Node, data: cstring)
|
||||||
proc cloneNode*(n: Node, copyContent: bool): Node
|
proc cloneNode*(n: Node, copyContent: bool): Node
|
||||||
proc deleteData*(n: Node, start, len: int)
|
proc deleteData*(n: Node, start, len: int)
|
||||||
|
proc focus*(e: Node)
|
||||||
proc getAttribute*(n: Node, attr: cstring): cstring
|
proc getAttribute*(n: Node, attr: cstring): cstring
|
||||||
proc getAttributeNode*(n: Node, attr: cstring): Node
|
proc getAttributeNode*(n: Node, attr: cstring): Node
|
||||||
proc hasChildNodes*(n: Node): bool
|
proc hasChildNodes*(n: Node): bool
|
||||||
|
|
@ -550,11 +1093,13 @@ proc releaseEvents*(d: Document, eventMask: int) {.deprecated.}
|
||||||
proc routeEvent*(d: Document, event: Event)
|
proc routeEvent*(d: Document, event: Event)
|
||||||
proc write*(d: Document, text: cstring)
|
proc write*(d: Document, text: cstring)
|
||||||
proc writeln*(d: Document, text: cstring)
|
proc writeln*(d: Document, text: cstring)
|
||||||
|
proc querySelector*(d: Document, selectors: cstring): Element
|
||||||
|
proc querySelectorAll*(d: Document, selectors: cstring): seq[Element]
|
||||||
|
|
||||||
# Element "methods"
|
# Element "methods"
|
||||||
proc blur*(e: Element)
|
proc blur*(e: Element)
|
||||||
proc click*(e: Element)
|
proc click*(e: Element)
|
||||||
proc focus*(e: Node)
|
proc focus*(e: Element)
|
||||||
proc handleEvent*(e: Element, event: Event)
|
proc handleEvent*(e: Element, event: Event)
|
||||||
proc select*(e: Element)
|
proc select*(e: Element)
|
||||||
proc getElementsByTagName*(e: Element, name: cstring): seq[Element]
|
proc getElementsByTagName*(e: Element, name: cstring): seq[Element]
|
||||||
|
|
@ -563,6 +1108,8 @@ proc getElementsByClassName*(e: Element, name: cstring): seq[Element]
|
||||||
# FormElement "methods"
|
# FormElement "methods"
|
||||||
proc reset*(f: FormElement)
|
proc reset*(f: FormElement)
|
||||||
proc submit*(f: FormElement)
|
proc submit*(f: FormElement)
|
||||||
|
proc checkValidity*(e: FormElement): bool
|
||||||
|
proc reportValidity*(e: FormElement): bool
|
||||||
|
|
||||||
# EmbedElement "methods"
|
# EmbedElement "methods"
|
||||||
proc play*(e: EmbedElement)
|
proc play*(e: EmbedElement)
|
||||||
|
|
@ -593,12 +1140,37 @@ proc setAttribute*(s: Style, attr, value: cstring, caseSensitive=false)
|
||||||
|
|
||||||
# Event "methods"
|
# Event "methods"
|
||||||
proc preventDefault*(ev: Event)
|
proc preventDefault*(ev: Event)
|
||||||
|
proc stopImmediatePropagation*(ev: Event)
|
||||||
proc stopPropagation*(ev: Event)
|
proc stopPropagation*(ev: Event)
|
||||||
|
|
||||||
|
# KeyboardEvent "methods"
|
||||||
|
proc getModifierState*(ev: KeyboardEvent, keyArg: cstring): bool
|
||||||
|
|
||||||
|
# MouseEvent "methods"
|
||||||
|
proc getModifierState*(ev: MouseEvent, keyArg: cstring): bool
|
||||||
|
|
||||||
# TouchEvent "methods"
|
# TouchEvent "methods"
|
||||||
proc identifiedTouch*(list: TouchList): Touch
|
proc identifiedTouch*(list: TouchList): Touch
|
||||||
proc item*(list: TouchList, i: int): Touch
|
proc item*(list: TouchList, i: int): Touch
|
||||||
|
|
||||||
|
# DataTransfer "methods"
|
||||||
|
proc clearData*(dt: DataTransfer, format: cstring)
|
||||||
|
proc getData*(dt: DataTransfer, format: cstring): cstring
|
||||||
|
proc setData*(dt: DataTransfer, format: cstring, data: cstring)
|
||||||
|
proc setDragImage*(dt: DataTransfer, img: Element, xOffset: int64, yOffset: int64)
|
||||||
|
|
||||||
|
# DataTransferItem "methods"
|
||||||
|
proc getAsFile*(dti: DataTransferItem): File
|
||||||
|
|
||||||
|
# InputElement "methods"
|
||||||
|
proc setSelectionRange*(e: InputElement, selectionStart: int, selectionEnd: int, selectionDirection: cstring = "none")
|
||||||
|
proc setRangeText*(e: InputElement, replacement: cstring, startindex: int = 0, endindex: int = 0, selectionMode: cstring = "preserve")
|
||||||
|
proc setCustomValidity*(e: InputElement, error: cstring)
|
||||||
|
proc checkValidity*(e: InputElement): bool
|
||||||
|
|
||||||
|
# Blob "methods"
|
||||||
|
proc slice*(e: Blob, startindex: int = 0, endindex: int = e.size, contentType: cstring = "")
|
||||||
|
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
||||||
proc setAttr*(n: Node; key, val: cstring) {.importcpp: "#.setAttribute(@)".}
|
proc setAttr*(n: Node; key, val: cstring) {.importcpp: "#.setAttribute(@)".}
|
||||||
|
|
@ -657,3 +1229,4 @@ proc inViewport*(el: Node): bool =
|
||||||
proc scrollTop*(e: Node): int {.importcpp: "#.scrollTop", nodecl.}
|
proc scrollTop*(e: Node): int {.importcpp: "#.scrollTop", nodecl.}
|
||||||
proc offsetHeight*(e: Node): int {.importcpp: "#.offsetHeight", nodecl.}
|
proc offsetHeight*(e: Node): int {.importcpp: "#.offsetHeight", nodecl.}
|
||||||
proc offsetTop*(e: Node): int {.importcpp: "#.offsetTop", nodecl.}
|
proc offsetTop*(e: Node): int {.importcpp: "#.offsetTop", nodecl.}
|
||||||
|
proc offsetLeft*(e: Node): int {.importcpp: "#.offsetLeft", nodecl.}
|
||||||
|
|
|
||||||
|
|
@ -423,3 +423,11 @@ proc `$`*(n: VNode): kstring =
|
||||||
else:
|
else:
|
||||||
result = ""
|
result = ""
|
||||||
add(result, n)
|
add(result, n)
|
||||||
|
|
||||||
|
proc getVNodeById*(n: VNode; id: cstring): VNode =
|
||||||
|
## Get the VNode that was marked with ``id``. Returns ``nil``
|
||||||
|
## if no node exists.
|
||||||
|
if n.id == id: return n
|
||||||
|
for i in 0..<n.len:
|
||||||
|
result = getVNodeById(n[i], id)
|
||||||
|
if result != nil: return result
|
||||||
|
|
|
||||||
33
tests/domEventTests.css
Normal file
33
tests/domEventTests.css
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
#dragDiv {
|
||||||
|
background-color: #0d1224;
|
||||||
|
width: 500px;
|
||||||
|
height: 100px;
|
||||||
|
position: absolute;
|
||||||
|
top: 500px;
|
||||||
|
left: 200px;
|
||||||
|
text-align: center;
|
||||||
|
cursor: move;
|
||||||
|
color: rgb(60, 201, 163);
|
||||||
|
}
|
||||||
|
|
||||||
|
#results {
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 10pt;
|
||||||
|
width: 100%;
|
||||||
|
height: 400px;
|
||||||
|
overflow: auto;
|
||||||
|
background-color: #000000;
|
||||||
|
color: forestgreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
#test10input1, #test10input2, #test11h3, #test12input {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#test11h3 {
|
||||||
|
color: gold;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: dimgrey;
|
||||||
|
}
|
||||||
13
tests/domEventTests.html
Normal file
13
tests/domEventTests.html
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>DOM Event Tests</title>
|
||||||
|
<link href="domEventTests.css" rel="stylesheet" />
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<script src="jquery-3.2.1.js" type="text/javascript"></script>
|
||||||
|
</head>
|
||||||
|
<body id="body">
|
||||||
|
<div id="ROOT"></div>
|
||||||
|
<script src="nimcache/domEventTests.js" type="text/javascript"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
624
tests/domEventTests.nim
Normal file
624
tests/domEventTests.nim
Normal file
|
|
@ -0,0 +1,624 @@
|
||||||
|
import times, jstrutils, strutils, kdom, karax, karaxdsl, vdom, tables
|
||||||
|
|
||||||
|
var
|
||||||
|
results: seq[cstring]
|
||||||
|
dragEventsCompleted = initTable[DragEventTypes, bool]()
|
||||||
|
testRunning: array[13, bool]
|
||||||
|
testCompleted: array[13, bool]
|
||||||
|
test2ImageDrop = false
|
||||||
|
dblClickCount = 0
|
||||||
|
test6ClickCount = 0
|
||||||
|
test8Failure = false
|
||||||
|
test10inputFocusCount = 0
|
||||||
|
test12Failure = false
|
||||||
|
|
||||||
|
proc getLogText(text: string): cstring =
|
||||||
|
result = "[$#]: $#" % [format(getLocalTime(getTime()), "HH:mm:ss"), $text]
|
||||||
|
|
||||||
|
proc log(text: string, clear: bool = false) =
|
||||||
|
if clear:
|
||||||
|
results = @[]
|
||||||
|
results.add getLogText(text)
|
||||||
|
echo text
|
||||||
|
redrawSync()
|
||||||
|
|
||||||
|
# Scroll to top after adding text using JQuery
|
||||||
|
discard window.setTimeout("$('#results').animate({ scrollTop: 0 }, 100);", 100)
|
||||||
|
|
||||||
|
proc check(cond: bool, msg: string) =
|
||||||
|
if not cond:
|
||||||
|
log "FAIL: " & msg
|
||||||
|
doAssert(cond, msg)
|
||||||
|
|
||||||
|
proc check(cond: bool, msg: string, warn: bool): bool =
|
||||||
|
if not cond:
|
||||||
|
if warn:
|
||||||
|
log "WARNING: " & msg
|
||||||
|
else:
|
||||||
|
log "FAIL: " & msg
|
||||||
|
doAssert(cond, msg)
|
||||||
|
result = cond
|
||||||
|
|
||||||
|
proc dragDivDragStart(ev: kdom.Event) =
|
||||||
|
dragEventsCompleted[DragStart] = true
|
||||||
|
var dgev = cast[DragEvent](ev)
|
||||||
|
var dragDiv = document.getElementById("dragDiv")
|
||||||
|
|
||||||
|
if dragDiv != nil:
|
||||||
|
var style = window.getComputedStyle(dgev.target)
|
||||||
|
var dataX = $(parseInt(style.left) - dgev.clientX)
|
||||||
|
var dataY = $(parseInt(style.top) - dgev.clientY)
|
||||||
|
dgev.dataTransfer.setData("text/plain", dataX & "," & dataY)
|
||||||
|
var img = (ImageElement)document.createElement("img")
|
||||||
|
img.src ="https://nim-lang.org/assets/img/logo.svg"
|
||||||
|
dgev.dataTransfer.setDragImage(img, 0, 0)
|
||||||
|
|
||||||
|
proc dragDivDragOver(ev: kdom.Event) =
|
||||||
|
dragEventsCompleted[DragOver] = true
|
||||||
|
ev.preventDefault()
|
||||||
|
|
||||||
|
proc checkAllTests() =
|
||||||
|
var allTestsPassed = true
|
||||||
|
for a in testCompleted:
|
||||||
|
if not a:
|
||||||
|
allTestsPassed = false
|
||||||
|
break
|
||||||
|
|
||||||
|
if allTestsPassed:
|
||||||
|
log "All tests completed successfully!"
|
||||||
|
else:
|
||||||
|
log "Some tests failed. Check the log."
|
||||||
|
|
||||||
|
proc completeTest13() =
|
||||||
|
testRunning[12] = false
|
||||||
|
testCompleted[12] = true
|
||||||
|
log "Test 13 completed successfully."
|
||||||
|
checkAllTests()
|
||||||
|
|
||||||
|
proc test13() =
|
||||||
|
testRunning[12] = true
|
||||||
|
log "Test 13 started."
|
||||||
|
log "This test verifies KeyboardEvent getModifierState functionality."
|
||||||
|
log "To continue, press the left CTRL key."
|
||||||
|
|
||||||
|
proc test12focus1(ev: kdom.Event) =
|
||||||
|
ev.stopImmediatePropagation()
|
||||||
|
|
||||||
|
proc test12focus2(ev: kdom.Event) =
|
||||||
|
test12Failure = true
|
||||||
|
check false, "Unexpected listener invocation."
|
||||||
|
|
||||||
|
proc test12focus3(ev: kdom.Event) =
|
||||||
|
test12Failure = true
|
||||||
|
check false, "Unexpected listener invocation."
|
||||||
|
|
||||||
|
proc completeTest12() =
|
||||||
|
if not test12Failure:
|
||||||
|
var elmt = document.getElementById("test12input")
|
||||||
|
elmt.style.visibility = "hidden"
|
||||||
|
testRunning[11] = false
|
||||||
|
testCompleted[11] = true
|
||||||
|
log "Test 12 completed successfully."
|
||||||
|
test13()
|
||||||
|
|
||||||
|
proc test12() =
|
||||||
|
testRunning[11] = true
|
||||||
|
log "Test 12 started."
|
||||||
|
log "This test verifies stopImmediatePropagation functionality."
|
||||||
|
|
||||||
|
var elmt = document.getElementById("test12input")
|
||||||
|
elmt.style.visibility = "visible"
|
||||||
|
elmt.addEventListener($Focus, test12focus1)
|
||||||
|
elmt.addEventListener($Focus, test12focus2)
|
||||||
|
elmt.addEventListener($Focus, test12focus3)
|
||||||
|
elmt.focus()
|
||||||
|
discard setTimeout(completeTest12, 500)
|
||||||
|
|
||||||
|
proc completeTest11() =
|
||||||
|
document.querySelector("h3").style.visibility = "hidden"
|
||||||
|
|
||||||
|
testRunning[10] = false
|
||||||
|
testCompleted[10] = true
|
||||||
|
log "Test 11 completed."
|
||||||
|
test12()
|
||||||
|
|
||||||
|
proc test11() =
|
||||||
|
testRunning[10] = true
|
||||||
|
log "Test 11 started."
|
||||||
|
log "This test checks querySelector and querySelectorAll."
|
||||||
|
|
||||||
|
document.getElementById("test11h3").style.visibility = "visible"
|
||||||
|
|
||||||
|
var elmt = document.querySelector("h3")
|
||||||
|
check elmt != nil, "querySelector returned nil."
|
||||||
|
log "text: " & $elmt.innerHTML
|
||||||
|
check $elmt.innerHTML == "test 11", "Unexpected h3 value."
|
||||||
|
|
||||||
|
var elmts = document.querySelectorAll("h3")
|
||||||
|
log "elmts len: " & $elmts.len
|
||||||
|
check elmts.len == 1, "Unexpected elmts len."
|
||||||
|
|
||||||
|
log "text: " & $elmts[0].innerHTML
|
||||||
|
check $elmts[0].innerHTML == "test 11", "Unexpected h3 value."
|
||||||
|
|
||||||
|
discard setTimeout(completeTest11, 500)
|
||||||
|
|
||||||
|
proc completeTest10() =
|
||||||
|
testRunning[9] = false
|
||||||
|
testCompleted[9] = true
|
||||||
|
var test10input1 = document.getElementById("test10input1")
|
||||||
|
var test10input2 = document.getElementById("test10input2")
|
||||||
|
test10input1.style.visibility = "hidden"
|
||||||
|
test10input2.style.visibility = "hidden"
|
||||||
|
log "Test 10 completed."
|
||||||
|
test11()
|
||||||
|
|
||||||
|
proc test10inputOnfocus(ev: kdom.Event) =
|
||||||
|
if testRunning[9]:
|
||||||
|
inc test10inputFocusCount
|
||||||
|
if test10inputFocusCount > 3:
|
||||||
|
discard setTimeout(completeTest10, 500)
|
||||||
|
|
||||||
|
proc test10() =
|
||||||
|
log "Test 10 started."
|
||||||
|
log "This test checks element.focus()."
|
||||||
|
testRunning[9] = true
|
||||||
|
var test10input1 = document.getElementById("test10input1")
|
||||||
|
var test10input2 = document.getElementById("test10input2")
|
||||||
|
test10input1.style.visibility = "visible"
|
||||||
|
test10input2.style.visibility = "visible"
|
||||||
|
test10input1.addEventListener($DomEvent.Focus, test10inputOnfocus)
|
||||||
|
test10input2.addEventListener($DomEvent.Focus, test10inputOnfocus)
|
||||||
|
test10input1.focus()
|
||||||
|
test10input2.focus()
|
||||||
|
test10input1.focus()
|
||||||
|
test10input2.focus()
|
||||||
|
|
||||||
|
proc completeTest9() =
|
||||||
|
var test9Value = $document.getElementById("test9value").value
|
||||||
|
doAssert(test9Value == "[test9]", "Unexpected test9 value.")
|
||||||
|
testRunning[8] = false
|
||||||
|
testCompleted[8] = true
|
||||||
|
test10()
|
||||||
|
|
||||||
|
proc test9() =
|
||||||
|
log "Test 9 started."
|
||||||
|
log "This tests the setTimeout(w: Window, code: cstring, pause: int) proc."
|
||||||
|
testRunning[8] = true
|
||||||
|
|
||||||
|
discard window.setTimeout("document.getElementById('test9value').value = '[test9]';", 500)
|
||||||
|
discard window.setTimeout(completeTest9, 1000)
|
||||||
|
|
||||||
|
proc completeTest8() =
|
||||||
|
if not test8Failure:
|
||||||
|
log "Test 8 completed successfully."
|
||||||
|
testRunning[7] = false
|
||||||
|
testCompleted[7] = true
|
||||||
|
test9()
|
||||||
|
else:
|
||||||
|
log "Test 8 failed."
|
||||||
|
|
||||||
|
proc failTest8() =
|
||||||
|
test8Failure = true
|
||||||
|
check(false, "ClearTimeout failed.")
|
||||||
|
|
||||||
|
proc test8() =
|
||||||
|
log "Test 8 started."
|
||||||
|
log "This test checks that clearTimeout() works correctly."
|
||||||
|
testRunning[7] = true
|
||||||
|
var timeout = setTimeout(failTest8, 1000)
|
||||||
|
clearTimeout(timeout)
|
||||||
|
discard setTimeout(completeTest8, 1200)
|
||||||
|
|
||||||
|
proc test7() =
|
||||||
|
log "Test 7 started."
|
||||||
|
log "This test ensures that mouse events correctly pass button and key modifier information."
|
||||||
|
log "To continue, right-click while holding SHIFT."
|
||||||
|
testRunning[6] = true
|
||||||
|
|
||||||
|
# A mouseMove handler is needed (even if empty) so mouseDown will have a value for movementX and movementY
|
||||||
|
proc mouseMove(ev: kdom.Event) =
|
||||||
|
discard
|
||||||
|
|
||||||
|
proc mouseDown(ev: kdom.Event) =
|
||||||
|
var me = (MouseEvent)ev
|
||||||
|
if testRunning[5]:
|
||||||
|
log "[ME] button: " & $me.button
|
||||||
|
log "[ME] buttons: " & $me.buttons
|
||||||
|
log "[ME] altKey: " & $me.altKey
|
||||||
|
log "[ME] ctrlKey: " & $me.ctrlKey
|
||||||
|
log "[ME] metaKey: " & $me.metaKey
|
||||||
|
log "[ME] shiftKey: " & $me.shiftKey
|
||||||
|
|
||||||
|
log "[ME] clientX: " & $me.clientX
|
||||||
|
check me.clientX > 0, "Unexpected clientX value."
|
||||||
|
|
||||||
|
log "[ME] clientY: " & $me.clientY
|
||||||
|
check me.clientY > 0, "Unexpected clientY value."
|
||||||
|
|
||||||
|
log "[ME] movementX: " & $me.movementX
|
||||||
|
check me.movementX > 0, "Unexpected movementX value."
|
||||||
|
|
||||||
|
log "[ME] movementY: " & $me.movementY
|
||||||
|
check me.movementY > 0, "Unexpected movementY value."
|
||||||
|
|
||||||
|
log "[ME] offsetX: " & $me.offsetX
|
||||||
|
check me.offsetX > 0, "Unexpected offsetX value."
|
||||||
|
|
||||||
|
log "[ME] offsetY: " & $me.offsetY
|
||||||
|
check me.offsetY > 0, "Unexpected offsetY value."
|
||||||
|
|
||||||
|
log "[ME] pageX: " & $me.pageX
|
||||||
|
check me.pageX > 0, "Unexpected pageX value."
|
||||||
|
|
||||||
|
log "[ME] pageY: " & $me.pageY
|
||||||
|
check me.pageY > 0, "Unexpected pageY value."
|
||||||
|
|
||||||
|
log "[ME] relatedTarget == nil: " & $(me.relatedTarget == nil)
|
||||||
|
|
||||||
|
log "[ME] screenX: " & $me.screenX
|
||||||
|
check me.screenX > 0, "Unexpected screenX value."
|
||||||
|
|
||||||
|
log "[ME] screenY: " & $me.screenY
|
||||||
|
check me.screenY > 0, "Unexpected screenY value."
|
||||||
|
|
||||||
|
log "[ME] x: " & $me.x
|
||||||
|
check me.x > 0, "Unexpected x value."
|
||||||
|
|
||||||
|
log "[ME] y: " & $me.y
|
||||||
|
check me.y > 0, "Unexpected y value."
|
||||||
|
|
||||||
|
if dblClickCount == 1:
|
||||||
|
inc test6ClickCount
|
||||||
|
|
||||||
|
if test6ClickCount > 1:
|
||||||
|
testRunning[5] = false
|
||||||
|
testCompleted[5] = true
|
||||||
|
log "Test 6 completed successfully."
|
||||||
|
test7()
|
||||||
|
elif testRunning[6]:
|
||||||
|
log "[ME] buttons: " & $me.buttons
|
||||||
|
var passed = check(me.buttons == (int)SecondaryButton, "Unexpected buttons value.", true)
|
||||||
|
|
||||||
|
log "[ME] shiftKey: " & $me.shiftKey
|
||||||
|
passed = passed and check(me.shiftKey, "Unexpected shiftKey value.", true)
|
||||||
|
|
||||||
|
var isShiftPressed = me.getModifierState($KeyboardEventKey.Shift)
|
||||||
|
log "[ME] getModifierState shift result: " & $isShiftPressed
|
||||||
|
passed = passed and check(isShiftPressed, "Unexpected getModifierState shift result.", true)
|
||||||
|
|
||||||
|
if passed:
|
||||||
|
log "Test 7 completed successfully."
|
||||||
|
testRunning[6] = false
|
||||||
|
testCompleted[6] = true
|
||||||
|
|
||||||
|
ev.preventDefault()
|
||||||
|
|
||||||
|
if testCompleted[6]:
|
||||||
|
test8()
|
||||||
|
|
||||||
|
proc dblClick(ev: kdom.Event) =
|
||||||
|
inc dblClickCount
|
||||||
|
check dblClickCount == 1, "Unexpected double-click event invocation."
|
||||||
|
log "Try double-clicking again."
|
||||||
|
|
||||||
|
proc test6() =
|
||||||
|
log "Test 6 started."
|
||||||
|
log "This test validates that addEventListener can be called by passing AddEventListenerOptions, and the options work correctly."
|
||||||
|
log "To continue, try double-clicking the mouse."
|
||||||
|
var options = AddEventListenerOptions(once:true)
|
||||||
|
document.addEventListener($DomEvent.DblClick, dblClick, options)
|
||||||
|
testRunning[5] = true
|
||||||
|
|
||||||
|
proc test5() =
|
||||||
|
log "Test 5 started."
|
||||||
|
log "This test validates the newly added properties: window.screen.width, window.scren.height, element.clientWidth, and element.clientHeight."
|
||||||
|
log "window.screen.width: " & $window.screen.width
|
||||||
|
check(window.screen.width > 0, "Unexpected value for window.screen.width.")
|
||||||
|
|
||||||
|
log "window.screen.height: " & $window.screen.height
|
||||||
|
check(window.screen.height > 0, "Unexpected value for window.screen.height.")
|
||||||
|
|
||||||
|
var elem = document.getElementById("results")
|
||||||
|
log "results div clientWidth: " & $elem.clientWidth
|
||||||
|
check(elem.clientWidth > 0, "Unexpected value for clientWidth.")
|
||||||
|
|
||||||
|
log "results div clientHeight: " & $elem.clientHeight
|
||||||
|
check(elem.clientHeight > 0, "Unexpected value for clientHeight.")
|
||||||
|
|
||||||
|
testRunning[4] = false
|
||||||
|
testCompleted[4] = true
|
||||||
|
|
||||||
|
log "Test 5 completed successfully."
|
||||||
|
test6()
|
||||||
|
|
||||||
|
proc keyDown(ev: kdom.Event) =
|
||||||
|
var kbev = ((KeyboardEvent)ev)
|
||||||
|
if testRunning[2]:
|
||||||
|
log "[KB] altKey: " & $kbev.altKey
|
||||||
|
log "[KB] ctrlKey: " & $kbev.ctrlKey
|
||||||
|
log "[KB] metaKey: " & $kbev.metaKey
|
||||||
|
log "[KB] shiftKey: " & $kbev.shiftKey
|
||||||
|
log "[KB] code: " & $kbev.code
|
||||||
|
log "[KB] isComposing: " & $kbev.isComposing
|
||||||
|
log "[KB] key: " & $kbev.key
|
||||||
|
log "[KB] keyCode: " & $kbev.keyCode
|
||||||
|
log "[KB] location: " & $kbev.location
|
||||||
|
|
||||||
|
log "Test 3 completed successfully."
|
||||||
|
testRunning[2] = false
|
||||||
|
testCompleted[2] = true
|
||||||
|
|
||||||
|
testRunning[3] = true
|
||||||
|
log "Test 4 started."
|
||||||
|
log "This test ensures the child events have access to base event settings."
|
||||||
|
|
||||||
|
log "[KB] event.bubbles: " & $kbev.bubbles
|
||||||
|
check kbev.bubbles, "Unexpected event.bubbles value."
|
||||||
|
|
||||||
|
log "[KB] event.cancelBubble: " & $kbev.cancelBubble
|
||||||
|
check kbev.cancelBubble == false, "Unexpected event.cancelBubble value."
|
||||||
|
|
||||||
|
log "[KB] event.cancelable: " & $kbev.cancelable
|
||||||
|
check kbev.cancelable, "Unexpected event.cancelable value."
|
||||||
|
|
||||||
|
log "[KB] event.composed: " & $kbev.composed
|
||||||
|
check kbev.composed, "Unexpected event.composed value."
|
||||||
|
|
||||||
|
log "[KB] event.currentTarget.nodeName: " & $kbev.currentTarget.nodeName
|
||||||
|
check kbev.currentTarget.nodeName == "#document", "Unexpected event.currentTarget.nodeName value."
|
||||||
|
|
||||||
|
log "[KB] event.defaultPrevented: " & $kbev.defaultPrevented
|
||||||
|
check kbev.defaultPrevented == false, "Unexpected event.defaultPrevented value."
|
||||||
|
|
||||||
|
log "[KB] event.eventPhase: " & $kbev.eventPhase
|
||||||
|
check EventPhase(kbev.eventPhase) == BubblingPhase, "Unexpected event.eventPhase value."
|
||||||
|
|
||||||
|
log "[KB] event.isTrusted: " & $kbev.isTrusted
|
||||||
|
check kbev.isTrusted, "Unexpected event.isTrusted value."
|
||||||
|
|
||||||
|
log "[UI] kbev.detail: " & $kbev.detail
|
||||||
|
|
||||||
|
log "[UI] kbev.view.outerHeight: " & $kbev.view.outerHeight
|
||||||
|
check kbev.view.outerHeight > 0, "Unexpected view.outerHeight value."
|
||||||
|
|
||||||
|
log "[UI] kbev.view.outerWidth: " & $kbev.view.outerWidth
|
||||||
|
check kbev.view.outerWidth > 0, "Unexpected view.outerWidth value."
|
||||||
|
|
||||||
|
testRunning[3] = false
|
||||||
|
testCompleted[3] = true
|
||||||
|
log "Test 4 completed."
|
||||||
|
test5()
|
||||||
|
elif testRunning[12]:
|
||||||
|
if kbev.code == "ControlLeft":
|
||||||
|
log "[KB] altKey: " & $kbev.altKey
|
||||||
|
log "[KB] ctrlKey: " & $kbev.ctrlKey
|
||||||
|
log "[KB] metaKey: " & $kbev.metaKey
|
||||||
|
log "[KB] shiftKey: " & $kbev.shiftKey
|
||||||
|
log "[KB] code: " & $kbev.code
|
||||||
|
log "[KB] isComposing: " & $kbev.isComposing
|
||||||
|
log "[KB] key: " & $kbev.key
|
||||||
|
log "[KB] keyCode: " & $kbev.keyCode
|
||||||
|
log "[KB] location: " & $kbev.location
|
||||||
|
var isControl = kbev.getModifierState($KeyboardEventKey.Control)
|
||||||
|
log "[KB] getModifierState result: " & $isControl
|
||||||
|
check isControl, "Unexpected getModifierState return value."
|
||||||
|
completeTest13()
|
||||||
|
|
||||||
|
proc test3() =
|
||||||
|
log "Test 3 started."
|
||||||
|
log "This test validates KeyboardEvent handling."
|
||||||
|
log "Click on the browser to focus, and then press any key."
|
||||||
|
testRunning[2] = true
|
||||||
|
|
||||||
|
proc dragDivDrop(ev: kdom.Event) =
|
||||||
|
dragEventsCompleted[Drop] = true
|
||||||
|
var dgev = cast[DragEvent](ev)
|
||||||
|
var dragDiv = document.getElementById("dragDiv")
|
||||||
|
var data = $dgev.dataTransfer.getData("text/plain")
|
||||||
|
var dt = dgev.dataTransfer
|
||||||
|
|
||||||
|
if not test2ImageDrop:
|
||||||
|
var offset = data.split(",")
|
||||||
|
var newLeft = dgev.clientX + parseInt(offset[0])
|
||||||
|
var newTop = dgev.clientY + parseInt(offset[1])
|
||||||
|
|
||||||
|
if newLeft < 0: newLeft = 0
|
||||||
|
if newTop < 0: newTop = 0
|
||||||
|
if newLeft + dragDiv.clientWidth > window.outerWidth: newLeft = window.outerWidth - dragDiv.clientWidth
|
||||||
|
if newTop + dragDiv.clientHeight > window.outerHeight: newTop = window.outerHeight - dragDiv.clientHeight
|
||||||
|
|
||||||
|
dragDiv.style.left = $newLeft & "px"
|
||||||
|
dragDiv.style.top = $newTop & "px"
|
||||||
|
|
||||||
|
if testRunning[0]:
|
||||||
|
log "[drop] Drop coords: $#, $#" % [$newLeft, $newTop]
|
||||||
|
|
||||||
|
if testCompleted[0] and not testCompleted[1] and not testRunning[1]:
|
||||||
|
testRunning[1] = true
|
||||||
|
log "Test 2 started."
|
||||||
|
log "This test validates the DataTransfer and DataTransferItem objects passed as part of the drag events."
|
||||||
|
var isChrome = ($navigator.userAgent).contains("Chrome")
|
||||||
|
|
||||||
|
log "[DT] effectAllowed: " & $dt.effectAllowed
|
||||||
|
var expectedEffectAllowed = $Uninitialized
|
||||||
|
if isChrome:
|
||||||
|
expectedEffectAllowed = if test2ImageDrop: $DataTransferEffectAllowed.Copy else: $DataTransferEffectAllowed.All
|
||||||
|
check(dt.effectAllowed == $expectedEffectAllowed, "Unexpected effectAllowed value.")
|
||||||
|
|
||||||
|
if not test2ImageDrop:
|
||||||
|
log "[DT] dropEffect: " & $dt.dropEffect
|
||||||
|
var expectedDropEffect = if isChrome: $DataTransferDropEffect.None else: $DataTransferDropEffect.Move
|
||||||
|
check(dt.dropEffect == $expectedDropEffect, "Unexpected dropEffect value.")
|
||||||
|
|
||||||
|
var expectedFilesLen = if test2ImageDrop: 1 else: 0
|
||||||
|
log "[DT] files len: " & $dt.files.len
|
||||||
|
check(dt.files.len == expectedFilesLen, "Unexpected files length.")
|
||||||
|
|
||||||
|
var expectedItemsLen = 1
|
||||||
|
log "[DT] items len: " & $dt.items.len
|
||||||
|
check(dt.items.len == expectedItemsLen, "Unexpected items length.")
|
||||||
|
|
||||||
|
var expectedItemKind = if test2ImageDrop: $DataTransferItemKind.File else: $DataTransferItemKind.String
|
||||||
|
log "[DT] items[0].kind: " & $dt.items[0].kind
|
||||||
|
check(dt.items[0].kind == expectedItemKind, "Unexpected item kind.")
|
||||||
|
|
||||||
|
var expectedItemType = if test2ImageDrop: "image/png" else: "text/plain"
|
||||||
|
log "[DT] items[0].type: " & $dt.items[0].`type`
|
||||||
|
check(dt.items[0].`type` == expectedItemType, "Unexpected item type.")
|
||||||
|
|
||||||
|
var expectedTypesLen = if not isChrome and test2ImageDrop: 2 else: 1
|
||||||
|
log "[DT] types len: " & $dt.types.len
|
||||||
|
check(dt.types.len == expectedTypesLen, "Unexpected types length.")
|
||||||
|
|
||||||
|
if test2ImageDrop:
|
||||||
|
log "[DT] types[0]: " & $dt.types[0]
|
||||||
|
if isChrome:
|
||||||
|
check(dt.types[0] == "Files", "Unexpected type value.")
|
||||||
|
else:
|
||||||
|
log "[DT] types[1]: " & $dt.types[1]
|
||||||
|
check(dt.types[0] == "application/x-moz-file", "Unexpected type value.")
|
||||||
|
check(dt.types[1] == "Files", "Unexpected type value.")
|
||||||
|
|
||||||
|
if test2ImageDrop:
|
||||||
|
test2ImageDrop = false
|
||||||
|
|
||||||
|
# TODO: Determine why getAsString() does invoke callback
|
||||||
|
# proc getAsString*(dti: DataTransferItem, callback: proc(data: cstring))
|
||||||
|
|
||||||
|
var jfile = dt.items[0].getAsFile()
|
||||||
|
log "[DT] file name: " & $jfile.name
|
||||||
|
check(jfile.name.len > 0, "Unexpected file name length.")
|
||||||
|
|
||||||
|
testCompleted[1] = true
|
||||||
|
testRunning[1] = false
|
||||||
|
log "Test 2 completed successfully."
|
||||||
|
test3()
|
||||||
|
|
||||||
|
ev.preventDefault()
|
||||||
|
return
|
||||||
|
|
||||||
|
document.getElementById("dragDiv").style.visibility = "hidden"
|
||||||
|
log "To continue, drag a .PNG file (file type matters) anywhere on this page."
|
||||||
|
log "NOTE: If the browser redirects to the image, then consider this test as failed."
|
||||||
|
test2ImageDrop = true
|
||||||
|
testRunning[1] = false
|
||||||
|
|
||||||
|
ev.preventDefault()
|
||||||
|
|
||||||
|
proc dragDivDrag(ev: kdom.Event) =
|
||||||
|
dragEventsCompleted[Drag] = true
|
||||||
|
ev.preventDefault()
|
||||||
|
|
||||||
|
proc dragDivDragLeave(ev: kdom.Event) =
|
||||||
|
dragEventsCompleted[DragLeave] = true
|
||||||
|
if testRunning[0]:
|
||||||
|
log "[dragLeave]"
|
||||||
|
ev.preventDefault()
|
||||||
|
|
||||||
|
proc dragDivDragExit(ev: kdom.Event) =
|
||||||
|
dragEventsCompleted[DragExit] = true
|
||||||
|
if testRunning[0]:
|
||||||
|
log "[dragExit]"
|
||||||
|
ev.preventDefault()
|
||||||
|
|
||||||
|
proc dragDivDragEnd(ev: kdom.Event) =
|
||||||
|
dragEventsCompleted[DragEnd] = true
|
||||||
|
if testRunning[0]:
|
||||||
|
log "[dragEnd]"
|
||||||
|
ev.preventDefault()
|
||||||
|
|
||||||
|
proc dragDivDragEnter(ev: kdom.Event) =
|
||||||
|
dragEventsCompleted[DragEnter] = true
|
||||||
|
if testRunning[0]:
|
||||||
|
log "[dragEnter]"
|
||||||
|
ev.preventDefault()
|
||||||
|
|
||||||
|
proc initDragEvents() =
|
||||||
|
log "Drag event initialization started."
|
||||||
|
var dragDiv = document.getElementById("dragDiv")
|
||||||
|
document.addEventListener($DragEventTypes.DragOver, dragDivDragOver, false)
|
||||||
|
document.addEventListener($DragEventTypes.Drop, dragDivDrop, false)
|
||||||
|
document.addEventListener($DragEventTypes.Drag, dragDivDrag, false)
|
||||||
|
dragDiv.addEventListener($DragEventTypes.DragStart, dragDivDragStart, false)
|
||||||
|
dragDiv.addEventListener($DragEventTypes.DragExit, dragDivDragExit, false)
|
||||||
|
dragDiv.addEventListener($DragEventTypes.DragLeave, dragDivDragLeave, false)
|
||||||
|
dragDiv.addEventListener($DragEventTypes.DragEnd, dragDivDragEnd, false)
|
||||||
|
dragDiv.addEventListener($DragEventTypes.DragEnter, dragDivDragEnter, false)
|
||||||
|
log "Drag event initialization complete."
|
||||||
|
log "Drag the div to continue the test. Make sure you drag the div over another element."
|
||||||
|
log "Then click the \"Check test 1 status\" button."
|
||||||
|
|
||||||
|
proc initMouseEvents() =
|
||||||
|
log "Mouse event initialization started."
|
||||||
|
document.addEventListener($DomEvent.MouseDown, mouseDown, false)
|
||||||
|
document.addEventListener($DomEvent.MouseMove, mouseMove, false)
|
||||||
|
log "Mouse event initialization complete."
|
||||||
|
|
||||||
|
proc initKbEvents() =
|
||||||
|
log "KB event initialization started."
|
||||||
|
document.addEventListener($DomEvent.KeyDown, keyDown, false)
|
||||||
|
log "KB event initialization complete."
|
||||||
|
|
||||||
|
proc startTests() =
|
||||||
|
log "[Disclaimer: these tests have been tested successfully on Linux with Firefox and Chromium. Your results may vary.]"
|
||||||
|
log "Note: these tests require some manual steps, which will be shown here."
|
||||||
|
log "Note: new entries appear in this text area at the top, so read in this direction."
|
||||||
|
log " | | | | | | | | | | | | | | | | | | | | | |"
|
||||||
|
log " / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\"
|
||||||
|
log "Test 1 started."
|
||||||
|
log "This test checks that drag events are fired."
|
||||||
|
testRunning[0] = true
|
||||||
|
for evt in [Drag, DragEnd, DragEnter, DragExit, DragLeave, DragOver, DragStart, Drop]:
|
||||||
|
dragEventsCompleted.add(evt, false)
|
||||||
|
initKbEvents()
|
||||||
|
initMouseEvents()
|
||||||
|
initDragEvents()
|
||||||
|
|
||||||
|
proc checkTest1Status() =
|
||||||
|
var evtsCompleted = true
|
||||||
|
|
||||||
|
# Chrome doesn't seem to send DragExit, so ignore this
|
||||||
|
if (($navigator.userAgent).contains("Chrome")):
|
||||||
|
dragEventsCompleted[DragExit] = true
|
||||||
|
|
||||||
|
for evt, completed in dragEventsCompleted:
|
||||||
|
if not completed:
|
||||||
|
evtsCompleted = false
|
||||||
|
break
|
||||||
|
|
||||||
|
if evtsCompleted:
|
||||||
|
testRunning[0] = false
|
||||||
|
log "Test 1 completed successfully. Drag the div anywhere to start the next test."
|
||||||
|
testCompleted[0] = true
|
||||||
|
document.getElementById("checkTest1").style.visibility = "hidden"
|
||||||
|
else:
|
||||||
|
log "Test 1 has not completed yet. Make sure you drag the div over another element."
|
||||||
|
log "Status:"
|
||||||
|
for evt, completed in dragEventsCompleted:
|
||||||
|
log $evt & ": " & $completed
|
||||||
|
|
||||||
|
proc createDom(): VNode =
|
||||||
|
result = buildHtml(tdiv()):
|
||||||
|
tdiv(id="dragDiv", draggable="true"):
|
||||||
|
tdiv(class="divcontent"):
|
||||||
|
text "draggable div"
|
||||||
|
tdiv(id="results"):
|
||||||
|
for i in countdown(results.len - 1, 0):
|
||||||
|
tdiv:
|
||||||
|
text $results[i]
|
||||||
|
tdiv(id="checkTest1"):
|
||||||
|
button(onclick=checkTest1Status):
|
||||||
|
text "Check test 1 status"
|
||||||
|
input(`type`="hidden", id="test9value")
|
||||||
|
input(`type`="text", id="test10input1")
|
||||||
|
input(`type`="text", id="test10input2")
|
||||||
|
h3(id="test11h3"):
|
||||||
|
text "test 11"
|
||||||
|
input(`type`="text", id="test12input")
|
||||||
|
|
||||||
|
proc onload() =
|
||||||
|
startTests()
|
||||||
|
|
||||||
|
setRenderer createDom
|
||||||
|
onload()
|
||||||
10253
tests/jquery-3.2.1.js
vendored
Normal file
10253
tests/jquery-3.2.1.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue