kdom changes and tests for #42
This commit is contained in:
parent
7425568122
commit
9ad41a6066
7 changed files with 1197 additions and 41 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -1,2 +1,4 @@
|
|||
nimcache/
|
||||
/tests/tester
|
||||
/tests/tester
|
||||
/tools/karun
|
||||
*.code-workspace
|
||||
|
|
@ -85,7 +85,7 @@ proc wrapEvent(d: Node; n: VNode; k: EventKind;
|
|||
let action = action
|
||||
let n = n
|
||||
result = proc (ev: Event) =
|
||||
if ev.keyCode == 13: keyeventBody()
|
||||
if ((KeyboardEvent)ev).keyCode == 13: keyeventBody()
|
||||
|
||||
proc laterWrapper(): NativeEventHandler =
|
||||
let action = action
|
||||
|
|
|
|||
553
karax/kdom.nim
553
karax/kdom.nim
|
|
@ -37,6 +37,38 @@ type
|
|||
onsubmit*: 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
|
||||
WindowObj {.importc.} = object of EventTargetObj
|
||||
document*: Document
|
||||
|
|
@ -57,6 +89,7 @@ type
|
|||
status*: cstring
|
||||
toolbar*: ref ToolBar
|
||||
frames*: seq[Frame]
|
||||
screen*: Screen
|
||||
|
||||
Frame* = ref FrameObj
|
||||
FrameObj {.importc.} = object of WindowObj
|
||||
|
|
@ -131,6 +164,7 @@ type
|
|||
name*: cstring
|
||||
readOnly*: bool
|
||||
options*: seq[OptionElement]
|
||||
clientWidth*, clientHeight*: int
|
||||
|
||||
# https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement
|
||||
HtmlElement* = ref object of Element
|
||||
|
|
@ -284,52 +318,461 @@ type
|
|||
wordSpacing*: cstring
|
||||
zIndex*: int
|
||||
|
||||
# TODO: A lot of the fields in Event belong to a more specific type of event.
|
||||
# TODO: Should we clean this up?
|
||||
EventPhase* = enum
|
||||
None = 0,
|
||||
CapturingPhase,
|
||||
AtTarget,
|
||||
BubblingPhase
|
||||
|
||||
# https://developer.mozilla.org/en-US/docs/Web/API/Event
|
||||
Event* = ref EventObj
|
||||
EventObj {.importc.} = object of RootObj
|
||||
bubbles*: bool
|
||||
cancelBubble*: bool
|
||||
cancelable*: bool
|
||||
composed*: bool
|
||||
currentTarget*: Node
|
||||
defaultPrevented*: bool
|
||||
eventPhase*: int
|
||||
target*: Node
|
||||
altKey*, ctrlKey*, shiftKey*: bool
|
||||
button*: int
|
||||
clientX*, clientY*: int
|
||||
`type`*: cstring
|
||||
isTrusted*: bool
|
||||
|
||||
# https://developer.mozilla.org/en-US/docs/Web/API/UIEvent
|
||||
UIEvent* {.importc.} = ref object of Event
|
||||
detail*: int64
|
||||
view*: Window
|
||||
|
||||
# https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent
|
||||
KeyboardEvent* {.importc.} = ref object of UIEvent
|
||||
altKey*, ctrlKey*, metaKey*, shiftKey*: bool
|
||||
code*: cstring
|
||||
isComposing*: bool
|
||||
key*: cstring
|
||||
keyCode*: int
|
||||
layerX*, layerY*: int
|
||||
modifiers*: int
|
||||
ALT_MASK*, CONTROL_MASK*, SHIFT_MASK*, META_MASK*: int
|
||||
location*: 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* {.importc.} = ref object of UIEvent
|
||||
altKey*, ctrlKey*, metaKey*, shiftKey*: bool
|
||||
button*: int
|
||||
buttons*: int
|
||||
clientX*, clientY*: int
|
||||
movementX*, movementY*: int
|
||||
offsetX*, offsetY*: int
|
||||
pageX*, pageY*: int
|
||||
relatedTarget*: EventTarget
|
||||
#region*: cstring
|
||||
screenX*, screenY*: int
|
||||
which*: int
|
||||
`type`*: cstring
|
||||
x*, y*: int
|
||||
ABORT*: int
|
||||
BLUR*: int
|
||||
CHANGE*: int
|
||||
CLICK*: int
|
||||
DBLCLICK*: int
|
||||
DRAGDROP*: int
|
||||
ERROR*: int
|
||||
FOCUS*: int
|
||||
KEYDOWN*: int
|
||||
KEYPRESS*: int
|
||||
KEYUP*: int
|
||||
LOAD*: int
|
||||
MOUSEDOWN*: int
|
||||
MOUSEMOVE*: int
|
||||
MOUSEOUT*: int
|
||||
MOUSEOVER*: int
|
||||
MOUSEUP*: int
|
||||
MOVE*: int
|
||||
RESET*: int
|
||||
RESIZE*: int
|
||||
SELECT*: int
|
||||
SUBMIT*: int
|
||||
UNLOAD*: int
|
||||
|
||||
DataTransferItemKind* {.pure.} = enum
|
||||
File = "file",
|
||||
String = "string"
|
||||
|
||||
# https://developer.mozilla.org/en-US/docs/Web/API/DataTransferItem
|
||||
DataTransferItem* {.importc.} = ref object of RootObj
|
||||
kind*: cstring
|
||||
`type`*: cstring
|
||||
|
||||
# https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer
|
||||
DataTransfer* {.importc.} = ref object of RootObj
|
||||
dropEffect*: cstring
|
||||
effectAllowed*: cstring
|
||||
files*: seq[Element]
|
||||
items*: seq[DataTransferItem]
|
||||
types*: seq[cstring]
|
||||
|
||||
DataTransferDropEffect* {.pure.} = enum
|
||||
None = "none",
|
||||
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.} = ref object of MouseEvent
|
||||
dataTransfer*: DataTransfer
|
||||
|
||||
TouchList* {.importc.} = ref object of RootObj
|
||||
length*: int
|
||||
|
||||
TouchEvent* {.importc.} = ref object of Event
|
||||
TouchEvent* {.importc.} = ref object of UIEvent
|
||||
changedTouches*, targetTouches*, touches*: TouchList
|
||||
|
||||
Touch* {.importc.} = ref object of RootObj
|
||||
|
|
@ -397,6 +840,17 @@ type
|
|||
TimeOut* {.importc.} = ref object of RootObj
|
||||
Interval* {.importc.} = object of RootObj
|
||||
|
||||
AddEventListenerOptions* = object
|
||||
capture*: bool
|
||||
once*: bool
|
||||
passive*: bool
|
||||
|
||||
JFile* {.importc.} = ref object
|
||||
lastModified*: int
|
||||
name*: cstring
|
||||
size*: int
|
||||
`type`*: cstring
|
||||
|
||||
when defined(nodejs):
|
||||
# we provide a dummy DOM for nodejs for testing purposes
|
||||
proc len*(x: Node): int = x.childNodes.len
|
||||
|
|
@ -483,6 +937,7 @@ proc clearTimeout*(t: Timeout) {.importc, nodecl.}
|
|||
|
||||
# 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), options: AddEventListenerOptions)
|
||||
proc removeEventListener*(et: EventTarget; ev: cstring; cb: proc(ev: Event))
|
||||
|
||||
# Window "methods"
|
||||
|
|
@ -491,7 +946,7 @@ proc back*(w: Window)
|
|||
proc blur*(w: Window)
|
||||
proc captureEvents*(w: Window, eventMask: int) {.deprecated.}
|
||||
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 confirm*(w: Window, msg: cstring): bool
|
||||
proc disableExternalCapture*(w: Window)
|
||||
|
|
@ -500,6 +955,7 @@ proc find*(w: Window, text: cstring, caseSensitive = false,
|
|||
backwards = false)
|
||||
proc focus*(w: Window)
|
||||
proc forward*(w: Window)
|
||||
proc getComputedStyle*(w: Window, e: Node, pe:Node = nil): Style
|
||||
proc handleEvent*(w: Window, e: Event)
|
||||
proc home*(w: Window)
|
||||
proc moveBy*(w: Window, x, y: int)
|
||||
|
|
@ -516,7 +972,7 @@ proc scrollBy*(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, 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 stop*(w: Window)
|
||||
proc requestAnimationFrame*(w: Window, function: proc (time: float)): int
|
||||
|
|
@ -526,6 +982,7 @@ proc cancelAnimationFrame*(w: Window, id: int)
|
|||
proc appendData*(n: Node, data: cstring)
|
||||
proc cloneNode*(n: Node, copyContent: bool): Node
|
||||
proc deleteData*(n: Node, start, len: int)
|
||||
proc focus*(e: Node)
|
||||
proc getAttribute*(n: Node, attr: cstring): cstring
|
||||
proc getAttributeNode*(n: Node, attr: cstring): Node
|
||||
proc hasChildNodes*(n: Node): bool
|
||||
|
|
@ -550,11 +1007,13 @@ proc releaseEvents*(d: Document, eventMask: int) {.deprecated.}
|
|||
proc routeEvent*(d: Document, event: Event)
|
||||
proc write*(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"
|
||||
proc blur*(e: Element)
|
||||
proc click*(e: Element)
|
||||
proc focus*(e: Node)
|
||||
proc focus*(e: Element)
|
||||
proc handleEvent*(e: Element, event: Event)
|
||||
proc select*(e: Element)
|
||||
proc getElementsByTagName*(e: Element, name: cstring): seq[Element]
|
||||
|
|
@ -593,12 +1052,28 @@ proc setAttribute*(s: Style, attr, value: cstring, caseSensitive=false)
|
|||
|
||||
# Event "methods"
|
||||
proc preventDefault*(ev: Event)
|
||||
proc stopImmediatePropagation*(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"
|
||||
proc identifiedTouch*(list: TouchList): 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): JFile
|
||||
|
||||
{.pop.}
|
||||
|
||||
proc setAttr*(n: Node; key, val: cstring) {.importcpp: "#.setAttribute(@)".}
|
||||
|
|
@ -651,8 +1126,8 @@ proc clientWidth*(): int {.
|
|||
proc inViewport*(el: Node): bool =
|
||||
let rect = el.getBoundingClientRect()
|
||||
result = rect.top >= 0 and rect.left >= 0 and
|
||||
rect.bottom <= clientHeight().float and
|
||||
rect.right <= clientWidth().float
|
||||
rect.bottom <= clientHeight().float and
|
||||
rect.right <= clientWidth().float
|
||||
|
||||
proc scrollTop*(e: Node): int {.importcpp: "#.scrollTop", nodecl.}
|
||||
proc offsetHeight*(e: Node): int {.importcpp: "#.offsetHeight", nodecl.}
|
||||
|
|
|
|||
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.min.js" type="text/javascript"></script>
|
||||
</head>
|
||||
<body id="body">
|
||||
<div id="ROOT"></div>
|
||||
<script src="nimcache/domEventTests.js" type="text/javascript"></script>
|
||||
</body>
|
||||
</html>
|
||||
629
tests/domEventTests.nim
Normal file
629
tests/domEventTests.nim
Normal file
|
|
@ -0,0 +1,629 @@
|
|||
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 = ((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 = ((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()
|
||||
|
||||
dgev.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
|
||||
|
||||
dgev.preventDefault()
|
||||
|
||||
proc dragDivDrag(ev: kdom.Event) =
|
||||
dragEventsCompleted[Drag] = true
|
||||
var dgev = ((DragEvent)ev)
|
||||
dgev.preventDefault()
|
||||
|
||||
proc dragDivDragLeave(ev: kdom.Event) =
|
||||
dragEventsCompleted[DragLeave] = true
|
||||
var dgev = ((DragEvent)ev)
|
||||
if testRunning[0]:
|
||||
log "[dragLeave]"
|
||||
dgev.preventDefault()
|
||||
|
||||
proc dragDivDragExit(ev: kdom.Event) =
|
||||
dragEventsCompleted[DragExit] = true
|
||||
var dgev = ((DragEvent)ev)
|
||||
if testRunning[0]:
|
||||
log "[dragExit]"
|
||||
dgev.preventDefault()
|
||||
|
||||
proc dragDivDragEnd(ev: kdom.Event) =
|
||||
dragEventsCompleted[DragEnd] = true
|
||||
var dgev = ((DragEvent)ev)
|
||||
if testRunning[0]:
|
||||
log "[dragEnd]"
|
||||
dgev.preventDefault()
|
||||
|
||||
proc dragDivDragEnter(ev: kdom.Event) =
|
||||
dragEventsCompleted[DragEnter] = true
|
||||
if testRunning[0]:
|
||||
log "[dragEnter]"
|
||||
var dgev = ((DragEvent)ev)
|
||||
dgev.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()
|
||||
4
tests/jquery-3.2.1.min.js
vendored
Normal file
4
tests/jquery-3.2.1.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue