-
Notifications
You must be signed in to change notification settings - Fork 25
/
jquery.typetype.coffee
126 lines (110 loc) · 4.53 KB
/
jquery.typetype.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
$.fn.extend
backspace: (num, options) ->
settings = $.extend(
callback: () -> # `this` is bound to elem
keypress: () -> # `this` is bound to elem
t:100 # typing interval
e:0.04 # this never gets used, but it takes 2 bytes off!
, options)
@each ->
elem = @
$(elem).queue ->
backsp = (n, fakeparam) ->
if n # > 0
elem[if /(np|x)/i.test elem.tagName then 'value' else 'innerHTML'] = elem[if /(np|x)/i.test elem.tagName then 'value' else 'innerHTML'].slice 0, -1
settings.keypress.call elem
setTimeout (-> backsp n-1, fakeparam; return), settings.t
else
settings.callback.call elem
$(elem).dequeue()
return
append = (fake, fakeyness) ->
if fake # > 0
elem[if /(np|x)/i.test elem.tagName then 'value' else 'innerHTML'] += fake[0]
settings.keypress.call elem
setTimeout (-> append fake.slice(1), fakeyness; return), settings.t
else
fakeyness()
return
backsp num
return
return
typetype: (txt, options) ->
settings = $.extend(
callback: () -> # `this` is bound to elem
keypress: () -> # `this` is bound to elem
t:100 # typing interval
e:0.04 # error probability
, options)
@each ->
elem = @
$(elem).queue -> # this function goes into the 'fx' queue.
backsp = (num, cont) ->
if num # > 0
elem[if /(np|x)/i.test elem.tagName then 'value' else 'innerHTML'] = elem[if /(np|x)/i.test elem.tagName then 'value' else 'innerHTML'].slice 0, -1 # inlined delchar function
settings.keypress.call elem
setTimeout (-> backsp num-1, cont; return), settings.t
else
cont()
return
append = (str, cont) ->
if str # > 0
elem[if /(np|x)/i.test elem.tagName then 'value' else 'innerHTML'] += str[0]
settings.keypress.call elem
setTimeout (-> append str.slice(1), cont; return), settings.t
else
cont()
return
typeTo = (i) ->
afterErr = -> setTimeout (-> typeTo i; return), (Math.random() * settings.t * (
if txt[i-1] is txt[i] then 1.6
else if txt[i-1] is '.' then 12
else if txt[i-1] is '!' then 12
else if txt[i-1] is '?' then 12
else if txt[i-1] is '\n' then 12
else if txt[i-1] is ',' then 8
else if txt[i-1] is ';' then 8
else if txt[i-1] is ':' then 8
else if txt[i-1] is ' ' then 3
else 2
))
r = Math.random() / settings.e
if txt.length >= i
# omit character, recover after 4 more chars
if 0.3 > r and txt[i-1] isnt txt[i] and txt.length > i+4
append txt.slice(i,i+4), (-> backsp 4, afterErr; return)
# hold shift too long
else if 0.7 > r and i > 1 and /[A-Z]/.test txt[i-2] and txt.length > i+4
append txt[i-1].toUpperCase()+txt.slice(i,i+4), (-> backsp 5, afterErr; return)
# omit character, recover immediately
else if 0.5 > r and txt[i-1] isnt txt[i] and txt.length > i
append txt[i], (-> backsp 1, afterErr; return)
# swap two characters
else if 1.0 > r and txt[i-1] isnt txt[i] and txt.length > i
append txt[i]+txt[i-1], (-> backsp 2, afterErr; return)
# forget to press shift
else if 0.5 > r and /[A-Z]/.test txt[i] #uppercase letter coming up
append txt[i].toLowerCase(), (-> backsp 1, afterErr; return)
# just insert the correct character!
else
elem[if /(np|x)/i.test elem.tagName then 'value' else 'innerHTML'] += txt[i-1]
settings.keypress.call elem
setTimeout (-> typeTo i+1; return), (Math.random() * settings.t * (
if txt[i-1] is txt[i] then 1.6
else if txt[i-1] is '.' then 12
else if txt[i-1] is '!' then 12
else if txt[i-1] is '?' then 12
else if txt[i-1] is '\n' then 12
else if txt[i-1] is ',' then 8
else if txt[i-1] is ';' then 8
else if txt[i-1] is ':' then 8
else if txt[i-1] is ' ' then 3
else 2
))
else
settings.callback.call elem
$(elem).dequeue()
return
typeTo 1
return
return