1*1ef15e30SBram Moolenaar" Vim completion script
2*1ef15e30SBram Moolenaar" Language:	Java Script
3*1ef15e30SBram Moolenaar" Maintainer:	Mikolaj Machowski ( mikmach AT wp DOT pl )
4*1ef15e30SBram Moolenaar" Last Change:	2006 Jan 30
5*1ef15e30SBram Moolenaar
6*1ef15e30SBram Moolenaarfunction! javascriptcomplete#CompleteJS(findstart, base)
7*1ef15e30SBram Moolenaar  if a:findstart
8*1ef15e30SBram Moolenaar    " locate the start of the word
9*1ef15e30SBram Moolenaar    let line = getline('.')
10*1ef15e30SBram Moolenaar    let start = col('.') - 1
11*1ef15e30SBram Moolenaar	let curline = line('.')
12*1ef15e30SBram Moolenaar	let compl_begin = col('.') - 2
13*1ef15e30SBram Moolenaar	" Bit risky but JS is rather limited language and local chars shouldn't
14*1ef15e30SBram Moolenaar	" fint way into names
15*1ef15e30SBram Moolenaar    while start >= 0 && line[start - 1] =~ '\w'
16*1ef15e30SBram Moolenaar		let start -= 1
17*1ef15e30SBram Moolenaar    endwhile
18*1ef15e30SBram Moolenaar	let b:compl_context = getline('.')[0:compl_begin]
19*1ef15e30SBram Moolenaar    return start
20*1ef15e30SBram Moolenaar  else
21*1ef15e30SBram Moolenaar	" Initialize base return lists
22*1ef15e30SBram Moolenaar    let res = []
23*1ef15e30SBram Moolenaar    let res2 = []
24*1ef15e30SBram Moolenaar	" a:base is very short - we need context
25*1ef15e30SBram Moolenaar	let context = b:compl_context
26*1ef15e30SBram Moolenaar	" Shortcontext is context without a:base, useful for checking if we are
27*1ef15e30SBram Moolenaar	" looking for objects
28*1ef15e30SBram Moolenaar	let shortcontext = substitute(context, a:base.'$', '', '')
29*1ef15e30SBram Moolenaar	unlet! b:compl_context
30*1ef15e30SBram Moolenaar
31*1ef15e30SBram Moolenaar	if shortcontext =~ '\.$'
32*1ef15e30SBram Moolenaar		" Complete methods and properties for objects
33*1ef15e30SBram Moolenaar		" DOM separate
34*1ef15e30SBram Moolenaar		let doms = ['style.']
35*1ef15e30SBram Moolenaar		" Arrays
36*1ef15e30SBram Moolenaar		let arrayprop = ['constructor', 'index', 'input', 'length', 'prototype']
37*1ef15e30SBram Moolenaar		let arraymeth = ['concat', 'join', 'pop', 'push', 'reverse', 'shift',
38*1ef15e30SBram Moolenaar					\ 'splice', 'sort', 'toSource', 'toString', 'unshift', 'valueOf',
39*1ef15e30SBram Moolenaar					\ 'watch', 'unwatch']
40*1ef15e30SBram Moolenaar		call map(arraymeth, 'v:val."("')
41*1ef15e30SBram Moolenaar		let arrays = arrayprop + arraymeth
42*1ef15e30SBram Moolenaar
43*1ef15e30SBram Moolenaar		" Boolean - complete subset of array values
44*1ef15e30SBram Moolenaar		" properties - constructor, prototype
45*1ef15e30SBram Moolenaar		" methods    - toSource, toString, valueOf
46*1ef15e30SBram Moolenaar
47*1ef15e30SBram Moolenaar		" Date
48*1ef15e30SBram Moolenaar		" properties - constructor, prototype
49*1ef15e30SBram Moolenaar		let datemeth = ['getDate', 'getDay', 'getFullYear', 'getHours', 'getMilliseconds',
50*1ef15e30SBram Moolenaar					\ 'getMinutes', 'getMonth', 'getSeconds', 'getTime', 'getTimezoneOffset',
51*1ef15e30SBram Moolenaar					\ 'getUTCDate', 'getUTCDay', 'getUTCFullYear', 'getUTCHours', 'getUTCMilliseconds',
52*1ef15e30SBram Moolenaar					\ 'getUTCMinutes', 'getUTCMonth', 'getUTCSeconds',
53*1ef15e30SBram Moolenaar					\ 'getYear', 'parse', 'parse',
54*1ef15e30SBram Moolenaar					\ 'setDate', 'setDay', 'setFullYear', 'setHours', 'setMilliseconds',
55*1ef15e30SBram Moolenaar					\ 'setMinutes', 'setMonth', 'setSeconds',
56*1ef15e30SBram Moolenaar					\ 'setUTCDate', 'setUTCDay', 'setUTCFullYear', 'setUTCHours', 'setUTCMilliseconds',
57*1ef15e30SBram Moolenaar					\ 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds', 'setYear', 'setTime',
58*1ef15e30SBram Moolenaar					\ 'toGMTString', 'toLocaleString', 'toLocaleDateString', 'toLocaleTimeString',
59*1ef15e30SBram Moolenaar					\ 'toSource', 'toString', 'toUTCString', 'UTC', 'valueOf', 'watch', 'unwatch']
60*1ef15e30SBram Moolenaar		call map(datemeth, 'v:val."("')
61*1ef15e30SBram Moolenaar		let dates = datemeth
62*1ef15e30SBram Moolenaar
63*1ef15e30SBram Moolenaar		" Function
64*1ef15e30SBram Moolenaar		let funcprop = ['arguments', 'arguments.callee', 'arguments.caller', 'arguments.length',
65*1ef15e30SBram Moolenaar					\ 'arity', 'constructor', 'length', 'prototype']
66*1ef15e30SBram Moolenaar		let funcmeth = ['apply', 'call', 'toSource', 'toString', 'valueOf']
67*1ef15e30SBram Moolenaar		call map(funcmeth, 'v:val."("')
68*1ef15e30SBram Moolenaar		let funcs = funcprop + funcmeth
69*1ef15e30SBram Moolenaar
70*1ef15e30SBram Moolenaar		" Math
71*1ef15e30SBram Moolenaar		let mathprop = ['E', 'LN2', 'LN10', 'LOG2E', 'LOG10E', 'PI', 'SQRT1_2', 'SQRT']
72*1ef15e30SBram Moolenaar		let mathmeth = ['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor',
73*1ef15e30SBram Moolenaar					\ 'log', 'max', 'min', 'pow', 'random', 'round', 'sin', 'sqrt', 'tan',
74*1ef15e30SBram Moolenaar					\ 'watch', 'unwatch']
75*1ef15e30SBram Moolenaar		call map(mathmeth, 'v:val."("')
76*1ef15e30SBram Moolenaar		let maths = mathprop + mathmeth
77*1ef15e30SBram Moolenaar
78*1ef15e30SBram Moolenaar		" Number
79*1ef15e30SBram Moolenaar		let numbprop = ['MAX_VALUE', 'MIN_VALUE', 'NaN', 'NEGATIVE_INFINITY', 'POSITIVE_INFINITY',
80*1ef15e30SBram Moolenaar					\ 'constructor', 'prototype']
81*1ef15e30SBram Moolenaar		let numbmeth = ['toExponential', 'toFixed', 'toPrecision', 'toSource', 'toString', 'valueOf',
82*1ef15e30SBram Moolenaar					\ 'watch', 'unwatch']
83*1ef15e30SBram Moolenaar		call map(numbmeth, 'v:val."("')
84*1ef15e30SBram Moolenaar		let numbs = numbprop + numbmeth
85*1ef15e30SBram Moolenaar
86*1ef15e30SBram Moolenaar		" Object
87*1ef15e30SBram Moolenaar		let objeprop = ['constructor', 'prototype']
88*1ef15e30SBram Moolenaar		let objemeth = ['eval', 'toSource', 'toString', 'unwatch', 'watch', 'valueOf']
89*1ef15e30SBram Moolenaar		call map(objemeth, 'v:val."("')
90*1ef15e30SBram Moolenaar		let objes = objeprop + objemeth
91*1ef15e30SBram Moolenaar
92*1ef15e30SBram Moolenaar		" RegExp
93*1ef15e30SBram Moolenaar		let regeprop = ['constructor', 'global', 'ignoreCase', 'lastIndex', 'multiline', 'source', 'prototype']
94*1ef15e30SBram Moolenaar		let regemeth = ['exec', 'toSource', 'toString', 'test', 'watch', 'unwatch']
95*1ef15e30SBram Moolenaar		call map(regemeth, 'v:val."("')
96*1ef15e30SBram Moolenaar		let reges = regeprop + regemeth
97*1ef15e30SBram Moolenaar
98*1ef15e30SBram Moolenaar		" String
99*1ef15e30SBram Moolenaar		let striprop = ['constructor', 'length', 'prototype']
100*1ef15e30SBram Moolenaar		let strimeth = ['anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'concat',
101*1ef15e30SBram Moolenaar					\ 'fixed', 'fontcolor', 'fontsize', 'fromCharCode', 'indexOf', 'italics',
102*1ef15e30SBram Moolenaar					\ 'lastIndexOf', 'link', 'match', 'replace', 'search', 'slice', 'small',
103*1ef15e30SBram Moolenaar					\ 'split', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLowerCase',
104*1ef15e30SBram Moolenaar					\ 'toSource', 'toString', 'toUpperCase', 'watch', 'unwatch']
105*1ef15e30SBram Moolenaar		call map(strimeth, 'v:val."("')
106*1ef15e30SBram Moolenaar		let stris = striprop + strimeth
107*1ef15e30SBram Moolenaar
108*1ef15e30SBram Moolenaar		" User created properties
109*1ef15e30SBram Moolenaar		if exists("b:jsrange")
110*1ef15e30SBram Moolenaar			let file = getline(b:jsrange[0],b:jsrange[1])
111*1ef15e30SBram Moolenaar			unlet! b:jsrange
112*1ef15e30SBram Moolenaar		else
113*1ef15e30SBram Moolenaar			let file = getline(1, '$')
114*1ef15e30SBram Moolenaar		endif
115*1ef15e30SBram Moolenaar		let user_props1 = filter(copy(file), 'v:val =~ "this\\.\\w"')
116*1ef15e30SBram Moolenaar		let juser_props1 = join(user_props1, ' ')
117*1ef15e30SBram Moolenaar		let user_props1 = split(juser_props1, '\zethis\.')
118*1ef15e30SBram Moolenaar		unlet! juser_props1
119*1ef15e30SBram Moolenaar		call map(user_props1, 'matchstr(v:val, "this\\.\\zs\\w\\+\\ze")')
120*1ef15e30SBram Moolenaar		let user_props2 = filter(copy(file), 'v:val =~ "\\.prototype\\.\\w"')
121*1ef15e30SBram Moolenaar		call map(user_props2, 'matchstr(v:val, "\\.prototype\\.\\zs\\w\\+\\ze")')
122*1ef15e30SBram Moolenaar		let user_props = user_props1 + user_props2
123*1ef15e30SBram Moolenaar
124*1ef15e30SBram Moolenaar		" HTML DOM properties
125*1ef15e30SBram Moolenaar		" Anchors - anchor.
126*1ef15e30SBram Moolenaar		let anchprop = ['accessKey', 'charset', 'coords', 'href', 'hreflang', 'id', 'innerHTML',
127*1ef15e30SBram Moolenaar					\ 'name', 'rel', 'rev', 'shape', 'tabIndex', 'target', 'type', 'onBlur', 'onFocus']
128*1ef15e30SBram Moolenaar		let anchmeth = ['blur', 'focus']
129*1ef15e30SBram Moolenaar		call map(anchmeth, 'v:val."("')
130*1ef15e30SBram Moolenaar		let anths = anchprop + anchmeth
131*1ef15e30SBram Moolenaar		" Area - area.
132*1ef15e30SBram Moolenaar		let areaprop = ['accessKey', 'alt', 'coords', 'hash', 'host', 'hostname', 'href', 'id',
133*1ef15e30SBram Moolenaar					\ 'noHref', 'pathname', 'port', 'protocol', 'search', 'shape', 'tabIndex', 'target']
134*1ef15e30SBram Moolenaar		let areameth = ['onClick', 'onDblClick', 'onMouseOut', 'onMouseOver']
135*1ef15e30SBram Moolenaar		call map(areameth, 'v:val."("')
136*1ef15e30SBram Moolenaar		let areas = areaprop + areameth
137*1ef15e30SBram Moolenaar		" Base - base.
138*1ef15e30SBram Moolenaar		let baseprop = ['href', 'id', 'target']
139*1ef15e30SBram Moolenaar		let bases = baseprop
140*1ef15e30SBram Moolenaar		" Body - body.
141*1ef15e30SBram Moolenaar		let bodyprop = ['aLink', 'background', 'gbColor', 'id', 'link', 'scrollLeft', 'scrollTop',
142*1ef15e30SBram Moolenaar					\ 'text', 'vLink']
143*1ef15e30SBram Moolenaar		let bodys = bodyprop
144*1ef15e30SBram Moolenaar		" Document - document.
145*1ef15e30SBram Moolenaar		let docuprop = ['anchors', 'applets', 'childNodes', 'embeds', 'forms', 'images', 'links', 'stylesheets',
146*1ef15e30SBram Moolenaar					\ 'body', 'cookie', 'documentElement', 'domain', 'lastModified', 'referrer', 'title', 'URL']
147*1ef15e30SBram Moolenaar		let documeth = ['close', 'createAttribute', 'createElement', 'createTextNode', 'focus', 'getElementById',
148*1ef15e30SBram Moolenaar					\ 'getElementsByName', 'getElementsByTagName', 'open', 'write', 'writeln',
149*1ef15e30SBram Moolenaar					\ 'onClick', 'onDblClick', 'onFocus', 'onKeyDown', 'onKeyPress', 'onKeyUp',
150*1ef15e30SBram Moolenaar					\ 'onMouseDown', 'onMouseMove', 'onMouseOut', 'onMouseOver', 'onMouseUp', 'onResize']
151*1ef15e30SBram Moolenaar		call map(documeth, 'v:val."("')
152*1ef15e30SBram Moolenaar		let docus = docuprop + documeth
153*1ef15e30SBram Moolenaar		" Form - form.
154*1ef15e30SBram Moolenaar		let formprop = ['elements', 'acceptCharset', 'action', 'encoding', 'enctype', 'id', 'length',
155*1ef15e30SBram Moolenaar					\ 'method', 'name', 'tabIndex', 'target']
156*1ef15e30SBram Moolenaar		let formmeth = ['reset', 'submit', 'onReset', 'onSubmit']
157*1ef15e30SBram Moolenaar		call map(formmeth, 'v:val."("')
158*1ef15e30SBram Moolenaar		let forms = formprop + formmeth
159*1ef15e30SBram Moolenaar		" Frame - frame.
160*1ef15e30SBram Moolenaar		let framprop = ['contentDocument', 'frameBorder', 'id', 'longDesc', 'marginHeight', 'marginWidth',
161*1ef15e30SBram Moolenaar					\ 'name', 'noResize', 'scrolling', 'src']
162*1ef15e30SBram Moolenaar		let frammeth = ['blur', 'focus']
163*1ef15e30SBram Moolenaar		call map(frammeth, 'v:val."("')
164*1ef15e30SBram Moolenaar		let frams = framprop + frammeth
165*1ef15e30SBram Moolenaar		" Frameset - frameset.
166*1ef15e30SBram Moolenaar		let fsetprop = ['cols', 'id', 'rows']
167*1ef15e30SBram Moolenaar		let fsetmeth = ['blur', 'focus']
168*1ef15e30SBram Moolenaar		call map(fsetmeth, 'v:val."("')
169*1ef15e30SBram Moolenaar		let fsets = fsetprop + fsetmeth
170*1ef15e30SBram Moolenaar		" History - history.
171*1ef15e30SBram Moolenaar		let histprop = ['length']
172*1ef15e30SBram Moolenaar		let histmeth = ['back', 'forward', 'go']
173*1ef15e30SBram Moolenaar		call map(histmeth, 'v:val."("')
174*1ef15e30SBram Moolenaar		let hists = histprop + histmeth
175*1ef15e30SBram Moolenaar		" Iframe - iframe.
176*1ef15e30SBram Moolenaar		let ifraprop = ['align', 'frameBorder', 'height', 'id', 'longDesc', 'marginHeight', 'marginWidth',
177*1ef15e30SBram Moolenaar					\ 'name', 'scrolling', 'src', 'width']
178*1ef15e30SBram Moolenaar		let ifras = ifraprop
179*1ef15e30SBram Moolenaar		" Image - image.
180*1ef15e30SBram Moolenaar		let imagprop = ['align', 'alt', 'border', 'complete', 'height', 'hspace', 'id', 'isMap', 'longDesc',
181*1ef15e30SBram Moolenaar					\ 'lowsrc', 'name', 'src', 'useMap', 'vspace', 'width']
182*1ef15e30SBram Moolenaar		let imagmeth = ['onAbort', 'onError', 'onLoad']
183*1ef15e30SBram Moolenaar		call map(imagmeth, 'v:val."("')
184*1ef15e30SBram Moolenaar		let imags = histprop + imagmeth
185*1ef15e30SBram Moolenaar		" Button - accessible only by other properties
186*1ef15e30SBram Moolenaar		let buttprop = ['accessKey', 'disabled', 'form', 'id', 'name', 'tabIndex', 'type', 'value']
187*1ef15e30SBram Moolenaar		let buttmeth = ['blur', 'click', 'focus', 'onBlur', 'onClick', 'onFocus', 'onMouseDown', 'onMouseUp']
188*1ef15e30SBram Moolenaar		call map(buttmeth, 'v:val."("')
189*1ef15e30SBram Moolenaar		let butts = buttprop + buttmeth
190*1ef15e30SBram Moolenaar		" Checkbox - accessible only by other properties
191*1ef15e30SBram Moolenaar		let checprop = ['accept', 'accessKey', 'align', 'alt', 'checked', 'defaultChecked',
192*1ef15e30SBram Moolenaar					\ 'disabled', 'form', 'id', 'name', 'tabIndex', 'type', 'value']
193*1ef15e30SBram Moolenaar		let checmeth = ['blur', 'click', 'focus', 'onBlur', 'onClick', 'onFocus', 'onMouseDown', 'onMouseUp']
194*1ef15e30SBram Moolenaar		call map(checmeth, 'v:val."("')
195*1ef15e30SBram Moolenaar		let checs = checprop + checmeth
196*1ef15e30SBram Moolenaar		" File upload - accessible only by other properties
197*1ef15e30SBram Moolenaar		let fileprop = ['accept', 'accessKey', 'align', 'alt', 'defaultValue',
198*1ef15e30SBram Moolenaar					\ 'disabled', 'form', 'id', 'name', 'tabIndex', 'type', 'value']
199*1ef15e30SBram Moolenaar		let filemeth = ['blur', 'focus', 'onBlur', 'onClick', 'onFocus', 'onMouseDown', 'onMouseUp']
200*1ef15e30SBram Moolenaar		call map(filemeth, 'v:val."("')
201*1ef15e30SBram Moolenaar		let files = fileprop + filemeth
202*1ef15e30SBram Moolenaar		" Hidden - accessible only by other properties
203*1ef15e30SBram Moolenaar		let hiddprop = ['defaultValue', 'form', 'id', 'name', 'type', 'value']
204*1ef15e30SBram Moolenaar		let hidds = hiddprop
205*1ef15e30SBram Moolenaar		" Password - accessible only by other properties
206*1ef15e30SBram Moolenaar		let passprop = ['accept', 'accessKey', 'defaultValue',
207*1ef15e30SBram Moolenaar					\ 'disabled', 'form', 'id', 'maxLength', 'name', 'readOnly', 'size', 'tabIndex',
208*1ef15e30SBram Moolenaar					\ 'type', 'value']
209*1ef15e30SBram Moolenaar		let passmeth = ['blur', 'click', 'focus', 'select', 'onBlur', 'onFocus', 'onKeyDown',
210*1ef15e30SBram Moolenaar					\ 'onKeyPress', 'onKeyUp']
211*1ef15e30SBram Moolenaar		call map(passmeth, 'v:val."("')
212*1ef15e30SBram Moolenaar		let passs = passprop + passmeth
213*1ef15e30SBram Moolenaar		" Radio - accessible only by other properties
214*1ef15e30SBram Moolenaar		let radiprop = ['accept', 'accessKey', 'align', 'alt', 'checked', 'defaultChecked',
215*1ef15e30SBram Moolenaar					\ 'disabled', 'form', 'id', 'name', 'tabIndex', 'type', 'value']
216*1ef15e30SBram Moolenaar		let radimeth = ['blur', 'click', 'focus', 'select', 'onBlur', 'onFocus']
217*1ef15e30SBram Moolenaar		call map(radimeth, 'v:val."("')
218*1ef15e30SBram Moolenaar		let radis = radiprop + radimeth
219*1ef15e30SBram Moolenaar		" Reset - accessible only by other properties
220*1ef15e30SBram Moolenaar		let reseprop = ['accept', 'accessKey', 'align', 'alt', 'defaultValue',
221*1ef15e30SBram Moolenaar					\ 'disabled', 'form', 'id', 'name', 'size', 'tabIndex', 'type', 'value']
222*1ef15e30SBram Moolenaar		let resemeth = ['blur', 'click', 'focus', 'select', 'onBlur', 'onFocus']
223*1ef15e30SBram Moolenaar		call map(resemeth, 'v:val."("')
224*1ef15e30SBram Moolenaar		let reses = reseprop + resemeth
225*1ef15e30SBram Moolenaar		" Submit - accessible only by other properties
226*1ef15e30SBram Moolenaar		let submprop = ['accept', 'accessKey', 'align', 'alt', 'defaultValue',
227*1ef15e30SBram Moolenaar					\ 'disabled', 'form', 'id', 'name', 'size', 'tabIndex', 'type', 'value']
228*1ef15e30SBram Moolenaar		let submmeth = ['blur', 'click', 'focus', 'select', 'onClick', 'onSelectStart']
229*1ef15e30SBram Moolenaar		call map(submmeth, 'v:val."("')
230*1ef15e30SBram Moolenaar		let subms = submprop + submmeth
231*1ef15e30SBram Moolenaar		" Text - accessible only by other properties
232*1ef15e30SBram Moolenaar		let textprop = ['accept', 'accessKey', 'align', 'alt', 'defaultValue',
233*1ef15e30SBram Moolenaar					\ 'disabled', 'form', 'id', 'maxLength', 'name', 'readOnly',
234*1ef15e30SBram Moolenaar					\ 'size', 'tabIndex', 'type', 'value']
235*1ef15e30SBram Moolenaar		let textmeth = ['blur', 'focus', 'select', 'onBlur', 'onChange', 'onFocus', 'onKeyDown',
236*1ef15e30SBram Moolenaar					\ 'onKeyPress', 'onKeyUp', 'onSelect']
237*1ef15e30SBram Moolenaar		call map(textmeth, 'v:val."("')
238*1ef15e30SBram Moolenaar		let texts = textprop + textmeth
239*1ef15e30SBram Moolenaar		" Link - link.
240*1ef15e30SBram Moolenaar		let linkprop = ['charset', 'disabled', 'href', 'hreflang', 'id', 'media',
241*1ef15e30SBram Moolenaar					\ 'rel', 'rev', 'target', 'type']
242*1ef15e30SBram Moolenaar		let linkmeth = ['onLoad']
243*1ef15e30SBram Moolenaar		call map(linkmeth, 'v:val."("')
244*1ef15e30SBram Moolenaar		let links = linkprop + linkmeth
245*1ef15e30SBram Moolenaar		" Location - location.
246*1ef15e30SBram Moolenaar		let locaprop = ['href', 'hash', 'host', 'hostname', 'pathname', 'port', 'protocol',
247*1ef15e30SBram Moolenaar					\ 'search']
248*1ef15e30SBram Moolenaar		let locameth = ['assign', 'reload', 'replace']
249*1ef15e30SBram Moolenaar		call map(locameth, 'v:val."("')
250*1ef15e30SBram Moolenaar		let locas = locaprop + locameth
251*1ef15e30SBram Moolenaar		" Meta - meta.
252*1ef15e30SBram Moolenaar		let metaprop = ['charset', 'content', 'disabled', 'httpEquiv', 'name', 'scheme']
253*1ef15e30SBram Moolenaar		let metas = metaprop
254*1ef15e30SBram Moolenaar		" Navigator - navigator.
255*1ef15e30SBram Moolenaar		let naviprop = ['plugins', 'appCodeName', 'appName', 'appVersion', 'cookieEnabled',
256*1ef15e30SBram Moolenaar					\ 'platform', 'userAgent']
257*1ef15e30SBram Moolenaar		let navimeth = ['javaEnabled', 'taintEnabled']
258*1ef15e30SBram Moolenaar		call map(navimeth, 'v:val."("')
259*1ef15e30SBram Moolenaar		let navis = naviprop + navimeth
260*1ef15e30SBram Moolenaar		" Object - object.
261*1ef15e30SBram Moolenaar		let objeprop = ['align', 'archive', 'border', 'code', 'codeBase', 'codeType', 'data',
262*1ef15e30SBram Moolenaar					\ 'declare', 'form', 'height', 'hspace', 'id', 'name', 'standby', 'tabIndex',
263*1ef15e30SBram Moolenaar					\ 'type', 'useMap', 'vspace', 'width']
264*1ef15e30SBram Moolenaar		let objes = objeprop
265*1ef15e30SBram Moolenaar		" Option - accessible only by other properties
266*1ef15e30SBram Moolenaar		let optiprop = ['defaultSelected',
267*1ef15e30SBram Moolenaar					\ 'disabled', 'form', 'id', 'index', 'label', 'selected', 'text', 'value']
268*1ef15e30SBram Moolenaar		let optis = optiprop
269*1ef15e30SBram Moolenaar		" Screen - screen.
270*1ef15e30SBram Moolenaar		let screprop = ['availHeight', 'availWidth', 'colorDepth', 'height', 'width']
271*1ef15e30SBram Moolenaar		let scres = screprop
272*1ef15e30SBram Moolenaar		" Select - accessible only by other properties
273*1ef15e30SBram Moolenaar		let seleprop = ['options', 'disabled', 'form', 'id', 'length', 'multiple', 'name',
274*1ef15e30SBram Moolenaar					\ 'selectedIndex', 'size', 'tabIndex', 'type', 'value']
275*1ef15e30SBram Moolenaar		let selemeth = ['blur', 'focus', 'remove', 'onBlur', 'onChange', 'onFocus']
276*1ef15e30SBram Moolenaar		call map(selemeth, 'v:val."("')
277*1ef15e30SBram Moolenaar		let seles = seleprop + selemeth
278*1ef15e30SBram Moolenaar		" Style - style.
279*1ef15e30SBram Moolenaar		let stylprop = ['background', 'backgroundAttachment', 'backgroundColor', 'backgroundImage',
280*1ef15e30SBram Moolenaar					\ 'backgroundPosition', 'backgroundRepeat',
281*1ef15e30SBram Moolenaar					\ 'border', 'borderBottom', 'borderLeft', 'borderRight', 'borderTop',
282*1ef15e30SBram Moolenaar					\ 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor',
283*1ef15e30SBram Moolenaar					\ 'borderBottomStyle', 'borderLeftStyle', 'borderRightStyle', 'borderTopStyle',
284*1ef15e30SBram Moolenaar					\ 'borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth',
285*1ef15e30SBram Moolenaar                    \ 'borderColor', 'borderStyle', 'borderWidth', 'margin', 'marginBottom',
286*1ef15e30SBram Moolenaar                    \ 'marginLeft', 'marginRight', 'marginTop', 'outline', 'outlineStyle', 'outlineWidth',
287*1ef15e30SBram Moolenaar                    \ 'outlineColor', 'outlineStyle', 'outlineWidth', 'padding', 'paddingBottom',
288*1ef15e30SBram Moolenaar                    \ 'paddingLeft', 'paddingRight', 'paddingTop',
289*1ef15e30SBram Moolenaar                    \ 'clear', 'clip', 'clipBottom', 'clipLeft', 'clipRight', 'clipTop', 'content',
290*1ef15e30SBram Moolenaar                    \ 'counterIncrement', 'counterReset', 'cssFloat', 'cursor', 'direction',
291*1ef15e30SBram Moolenaar                    \ 'display', 'markerOffset', 'marks', 'maxHeight', 'maxWidth', 'minHeight',
292*1ef15e30SBram Moolenaar					\ 'minWidth', 'overflow', 'overflowX', 'overflowY', 'verticalAlign', 'visibility',
293*1ef15e30SBram Moolenaar					\ 'width',
294*1ef15e30SBram Moolenaar					\ 'listStyle', 'listStyleImage', 'listStylePosition', 'listStyleType',
295*1ef15e30SBram Moolenaar					\ 'cssText', 'bottom', 'height', 'left', 'position', 'right', 'top', 'width', 'zindex',
296*1ef15e30SBram Moolenaar					\ 'orphans', 'widows', 'page', 'pageBreakAfter', 'pageBreakBefore', 'pageBreakInside',
297*1ef15e30SBram Moolenaar					\ 'borderCollapse', 'borderSpacing', 'captionSide', 'emptyCells', 'tableLayout',
298*1ef15e30SBram Moolenaar					\ 'color', 'font', 'fontFamily', 'fontSize', 'fontSizeAdjust', 'fontStretch',
299*1ef15e30SBram Moolenaar					\ 'fontStyle', 'fontVariant', 'fontWeight', 'letterSpacing', 'lineHeight', 'quotes',
300*1ef15e30SBram Moolenaar					\ 'textAlign', 'textIndent', 'textShadow', 'textTransform', 'textUnderlinePosition',
301*1ef15e30SBram Moolenaar					\ 'unicodeBidi', 'whiteSpace', 'wordSpacing']
302*1ef15e30SBram Moolenaar		let styls = stylprop
303*1ef15e30SBram Moolenaar		" Table - table.
304*1ef15e30SBram Moolenaar		let tablprop = ['rows', 'tBodies', 'align', 'bgColor', 'border', 'caption', 'cellPadding',
305*1ef15e30SBram Moolenaar					\ 'cellSpacing', 'frame', 'height', 'rules', 'summary', 'tFoot', 'tHead', 'width']
306*1ef15e30SBram Moolenaar		let tablmeth = ['createCaption', 'createTFoot', 'createTHead', 'deleteCaption', 'deleteRow',
307*1ef15e30SBram Moolenaar					\ 'deleteTFoot', 'deleteTHead', 'insertRow']
308*1ef15e30SBram Moolenaar		call map(tablmeth, 'v:val."("')
309*1ef15e30SBram Moolenaar		let tabls = tablprop + tablmeth
310*1ef15e30SBram Moolenaar		" Table data - TableData.
311*1ef15e30SBram Moolenaar		let tdatprop = ['abbr', 'align', 'axis', 'bgColor', 'cellIndex', 'ch', 'chOff',
312*1ef15e30SBram Moolenaar					\ 'colSpan', 'headers', 'noWrap', 'rowSpan', 'scope', 'vAlign', 'width']
313*1ef15e30SBram Moolenaar		let tdats = tdatprop
314*1ef15e30SBram Moolenaar		" Table row - TableRow.
315*1ef15e30SBram Moolenaar		let trowprop = ['cells', 'align', 'bgColor', 'ch', 'chOff', 'rowIndex', 'sectionRowIndex',
316*1ef15e30SBram Moolenaar					\ 'vAlign']
317*1ef15e30SBram Moolenaar		let trowmeth = ['deleteCell', 'insertCell']
318*1ef15e30SBram Moolenaar		call map(trowmeth, 'v:val."("')
319*1ef15e30SBram Moolenaar		let trows = trowprop + trowmeth
320*1ef15e30SBram Moolenaar		" Textarea - accessible only by other properties
321*1ef15e30SBram Moolenaar		let tareprop = ['accessKey', 'cols', 'defaultValue',
322*1ef15e30SBram Moolenaar					\ 'disabled', 'form', 'id', 'name', 'readOnly', 'rows',
323*1ef15e30SBram Moolenaar					\ 'tabIndex', 'type', 'value']
324*1ef15e30SBram Moolenaar		let taremeth = ['blur', 'focus', 'select', 'onBlur', 'onChange', 'onFocus']
325*1ef15e30SBram Moolenaar		call map(taremeth, 'v:val."("')
326*1ef15e30SBram Moolenaar		let tares = tareprop + taremeth
327*1ef15e30SBram Moolenaar		" Window - window.
328*1ef15e30SBram Moolenaar		let windprop = ['frames', 'closed', 'defaultStatus', 'length', 'name', 'opener', 'parent',
329*1ef15e30SBram Moolenaar					\ 'self', 'status', 'top']
330*1ef15e30SBram Moolenaar		let windmeth = ['alert', 'blur', 'clearInterval', 'clearTimeout', 'close', 'confirm', 'focus',
331*1ef15e30SBram Moolenaar					\ 'moveBy', 'moveTo', 'open', 'print', 'prompt', 'scrollBy', 'scrollTo', 'setInterval',
332*1ef15e30SBram Moolenaar					\ 'setTimeout']
333*1ef15e30SBram Moolenaar		call map(windmeth, 'v:val."("')
334*1ef15e30SBram Moolenaar		let winds = windprop + windmeth
335*1ef15e30SBram Moolenaar		" XMLHttpRequest - access by new xxx()
336*1ef15e30SBram Moolenaar		let xmlhprop = ['onreadystatechange', 'readyState', 'responseText', 'responseXML',
337*1ef15e30SBram Moolenaar					\ 'status', 'statusText']
338*1ef15e30SBram Moolenaar		let xmlhmeth = ['abort', 'getAllResponseHeaders', 'getResponseHeaders', 'open',
339*1ef15e30SBram Moolenaar					\ 'send', 'setRequestHeader']
340*1ef15e30SBram Moolenaar		call map(xmlhmeth, 'v:val."("')
341*1ef15e30SBram Moolenaar		let xmlhs = xmlhprop + xmlhmeth
342*1ef15e30SBram Moolenaar
343*1ef15e30SBram Moolenaar		let object = matchstr(shortcontext, '\zs\w\+\ze\(\[.\{-}\]\)\?\.$')
344*1ef15e30SBram Moolenaar		let decl_line = search(object.'.\{-}=\s*new\s*', 'bn')
345*1ef15e30SBram Moolenaar		let object_type = matchstr(getline(decl_line), object.'.\{-}=\s*new\s*\zs\w\+\ze')
346*1ef15e30SBram Moolenaar
347*1ef15e30SBram Moolenaar		if object_type == 'Date'
348*1ef15e30SBram Moolenaar			let values = dates
349*1ef15e30SBram Moolenaar		elseif object_type == 'Image'
350*1ef15e30SBram Moolenaar			let values = imags
351*1ef15e30SBram Moolenaar		elseif object_type == 'Array'
352*1ef15e30SBram Moolenaar			let values = arrays
353*1ef15e30SBram Moolenaar		elseif object_type == 'Boolean'
354*1ef15e30SBram Moolenaar			" TODO: a bit more than real boolean
355*1ef15e30SBram Moolenaar			let values = arrays
356*1ef15e30SBram Moolenaar		elseif object_type == 'XMLHttpRequest'
357*1ef15e30SBram Moolenaar			let values = xmlhs
358*1ef15e30SBram Moolenaar		elseif object_type == 'String'
359*1ef15e30SBram Moolenaar			let values = stris
360*1ef15e30SBram Moolenaar		endif
361*1ef15e30SBram Moolenaar
362*1ef15e30SBram Moolenaar		if !exists('values')
363*1ef15e30SBram Moolenaar		" List of properties
364*1ef15e30SBram Moolenaar		if shortcontext =~ 'Math\.$'
365*1ef15e30SBram Moolenaar			let values = maths
366*1ef15e30SBram Moolenaar		elseif shortcontext =~ 'anchor\.$'
367*1ef15e30SBram Moolenaar			let values = anths
368*1ef15e30SBram Moolenaar		elseif shortcontext =~ 'area\.$'
369*1ef15e30SBram Moolenaar			let values = areas
370*1ef15e30SBram Moolenaar		elseif shortcontext =~ 'base\.$'
371*1ef15e30SBram Moolenaar			let values = bases
372*1ef15e30SBram Moolenaar		elseif shortcontext =~ 'body\.$'
373*1ef15e30SBram Moolenaar			let values = bodys
374*1ef15e30SBram Moolenaar		elseif shortcontext =~ 'document\.$'
375*1ef15e30SBram Moolenaar			let values = docus
376*1ef15e30SBram Moolenaar		elseif shortcontext =~ 'form\.$'
377*1ef15e30SBram Moolenaar			let values = forms
378*1ef15e30SBram Moolenaar		elseif shortcontext =~ 'frameset\.$'
379*1ef15e30SBram Moolenaar			let values = fsets
380*1ef15e30SBram Moolenaar		elseif shortcontext =~ 'history\.$'
381*1ef15e30SBram Moolenaar			let values = hists
382*1ef15e30SBram Moolenaar		elseif shortcontext =~ 'iframe\.$'
383*1ef15e30SBram Moolenaar			let values = ifras
384*1ef15e30SBram Moolenaar		elseif shortcontext =~ 'image\.$'
385*1ef15e30SBram Moolenaar			let values = imags
386*1ef15e30SBram Moolenaar		elseif shortcontext =~ 'link\.$'
387*1ef15e30SBram Moolenaar			let values = links
388*1ef15e30SBram Moolenaar		elseif shortcontext =~ 'location\.$'
389*1ef15e30SBram Moolenaar			let values = locas
390*1ef15e30SBram Moolenaar		elseif shortcontext =~ 'meta\.$'
391*1ef15e30SBram Moolenaar			let values = metas
392*1ef15e30SBram Moolenaar		elseif shortcontext =~ 'navigator\.$'
393*1ef15e30SBram Moolenaar			let values = navis
394*1ef15e30SBram Moolenaar		elseif shortcontext =~ 'object\.$'
395*1ef15e30SBram Moolenaar			let values = objes
396*1ef15e30SBram Moolenaar		elseif shortcontext =~ 'screen\.$'
397*1ef15e30SBram Moolenaar			let values = scres
398*1ef15e30SBram Moolenaar		elseif shortcontext =~ 'style\.$'
399*1ef15e30SBram Moolenaar			let values = styls
400*1ef15e30SBram Moolenaar		elseif shortcontext =~ 'table\.$'
401*1ef15e30SBram Moolenaar			let values = tabls
402*1ef15e30SBram Moolenaar		elseif shortcontext =~ 'TableData\.$'
403*1ef15e30SBram Moolenaar			let values = tdats
404*1ef15e30SBram Moolenaar		elseif shortcontext =~ 'TableRow\.$'
405*1ef15e30SBram Moolenaar			let values = trows
406*1ef15e30SBram Moolenaar		elseif shortcontext =~ 'window\.$'
407*1ef15e30SBram Moolenaar			let values = winds
408*1ef15e30SBram Moolenaar		else
409*1ef15e30SBram Moolenaar			let values = user_props + arrays + dates + funcs + maths + numbs + objes + reges + stris
410*1ef15e30SBram Moolenaar			let values += doms + anths + areas + bases + bodys + docus + forms + frams + fsets + hists
411*1ef15e30SBram Moolenaar			let values += ifras + imags + links + locas + metas + navis + objes + scres + styls
412*1ef15e30SBram Moolenaar			let values += tabls + trows + winds
413*1ef15e30SBram Moolenaar		endif
414*1ef15e30SBram Moolenaar		endif
415*1ef15e30SBram Moolenaar
416*1ef15e30SBram Moolenaar		for m in values
417*1ef15e30SBram Moolenaar			if m =~? '^'.a:base
418*1ef15e30SBram Moolenaar				call add(res, m)
419*1ef15e30SBram Moolenaar			elseif m =~? a:base
420*1ef15e30SBram Moolenaar				call add(res2, m)
421*1ef15e30SBram Moolenaar			endif
422*1ef15e30SBram Moolenaar		endfor
423*1ef15e30SBram Moolenaar
424*1ef15e30SBram Moolenaar		unlet! values
425*1ef15e30SBram Moolenaar		return res + res2
426*1ef15e30SBram Moolenaar
427*1ef15e30SBram Moolenaar	endif
428*1ef15e30SBram Moolenaar
429*1ef15e30SBram Moolenaar	if exists("b:jsrange")
430*1ef15e30SBram Moolenaar		let file = getline(b:jsrange[0],b:jsrange[1])
431*1ef15e30SBram Moolenaar		unlet! b:jsrange
432*1ef15e30SBram Moolenaar	else
433*1ef15e30SBram Moolenaar		let file = getline(1, '$')
434*1ef15e30SBram Moolenaar	endif
435*1ef15e30SBram Moolenaar
436*1ef15e30SBram Moolenaar	" Get variables data.
437*1ef15e30SBram Moolenaar	let variables = filter(copy(file), 'v:val =~ "var\\s"')
438*1ef15e30SBram Moolenaar	call map(variables, 'matchstr(v:val, ".\\{-}var\\s\\+\\zs.*\\ze")')
439*1ef15e30SBram Moolenaar	call map(variables, 'substitute(v:val, ";\\|$", ",", "g")')
440*1ef15e30SBram Moolenaar	let vars = []
441*1ef15e30SBram Moolenaar	" This loop is necessary to get variable names from constructs like:
442*1ef15e30SBram Moolenaar	" var var1, var2, var3 = "something";
443*1ef15e30SBram Moolenaar	for i in range(len(variables))
444*1ef15e30SBram Moolenaar		let comma_separated = split(variables[i], ',\s*')
445*1ef15e30SBram Moolenaar		call map(comma_separated, 'matchstr(v:val, "\\w\\+")')
446*1ef15e30SBram Moolenaar		let vars += comma_separated
447*1ef15e30SBram Moolenaar	endfor
448*1ef15e30SBram Moolenaar
449*1ef15e30SBram Moolenaar	let variables = sort(vars)
450*1ef15e30SBram Moolenaar
451*1ef15e30SBram Moolenaar	" Add undeclared variables.
452*1ef15e30SBram Moolenaar	let undeclared_variables = filter(copy(file), 'v:val =~ "^\\s*\\w\\+\\s*="')
453*1ef15e30SBram Moolenaar	call map(undeclared_variables, 'matchstr(v:val, "^\\s*\\zs\\w\\+\\ze")')
454*1ef15e30SBram Moolenaar
455*1ef15e30SBram Moolenaar	let variables += sort(undeclared_variables)
456*1ef15e30SBram Moolenaar
457*1ef15e30SBram Moolenaar	" Get functions
458*1ef15e30SBram Moolenaar	let functions = filter(copy(file), 'v:val =~ "^\\s*function\\s"')
459*1ef15e30SBram Moolenaar	let arguments = copy(functions)
460*1ef15e30SBram Moolenaar	call map(functions, 'matchstr(v:val, "^\\s*function\\s\\+\\zs\\w\\+")')
461*1ef15e30SBram Moolenaar	call map(functions, 'v:val."("')
462*1ef15e30SBram Moolenaar
463*1ef15e30SBram Moolenaar	" Get functions arguments
464*1ef15e30SBram Moolenaar	call map(arguments, 'matchstr(v:val, "function.\\{-}(\\zs.\\{-}\\ze)")')
465*1ef15e30SBram Moolenaar	let jargs = join(arguments, ',')
466*1ef15e30SBram Moolenaar	let jargs = substitute(jargs, '\s', '', 'g')
467*1ef15e30SBram Moolenaar	let arguments = split(jargs, ',')
468*1ef15e30SBram Moolenaar
469*1ef15e30SBram Moolenaar	" Built-in functions
470*1ef15e30SBram Moolenaar	let builtin = []
471*1ef15e30SBram Moolenaar
472*1ef15e30SBram Moolenaar	" Top-level HTML DOM objects
473*1ef15e30SBram Moolenaar	let htmldom = ['document', 'anchor', 'area', 'base', 'body', 'document', 'event', 'form', 'frame', 'frameset', 'history', 'iframe', 'image', 'input', 'link', 'location', 'meta', 'navigator', 'object', 'option', 'screen', 'select', 'table', 'tableData', 'tableHeader', 'tableRow', 'textarea', 'window']
474*1ef15e30SBram Moolenaar	call map(htmldom, 'v:val."."')
475*1ef15e30SBram Moolenaar
476*1ef15e30SBram Moolenaar	" Top-level properties
477*1ef15e30SBram Moolenaar	let properties = ['decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent',
478*1ef15e30SBram Moolenaar				\ 'eval', 'Infinity', 'isFinite', 'isNaN', 'NaN', 'Number', 'parseFloat',
479*1ef15e30SBram Moolenaar				\ 'parseInt', 'String', 'undefined', 'escape', 'unescape']
480*1ef15e30SBram Moolenaar
481*1ef15e30SBram Moolenaar	" Keywords
482*1ef15e30SBram Moolenaar	let keywords = ["Array", "Boolean", "Date", "Function", "Math", "Number", "Object", "RegExp", "String", "XMLHttpRequest", "ActiveXObject", "abstract", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "debugger", "default", "delete", "do", "double ", "else", "enum", "export", "extends", "false", "final", "finally", "float", "for", "function", "goto", "if", "implements", "import", "in ", "instanceof", "int", "interface", "long", "native", "new", "null", "package", "private", "protected", "public", "return", "short", "static", "super ", "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try", "typeof", "var", "void", "volatile", "while", "with"]
483*1ef15e30SBram Moolenaar
484*1ef15e30SBram Moolenaar	let values = variables + functions + htmldom + arguments + builtin + properties + keywords
485*1ef15e30SBram Moolenaar
486*1ef15e30SBram Moolenaar	for m in values
487*1ef15e30SBram Moolenaar		if m =~? '^'.a:base
488*1ef15e30SBram Moolenaar			call add(res, m)
489*1ef15e30SBram Moolenaar		elseif m =~? a:base
490*1ef15e30SBram Moolenaar			call add(res2, m)
491*1ef15e30SBram Moolenaar		endif
492*1ef15e30SBram Moolenaar	endfor
493*1ef15e30SBram Moolenaar
494*1ef15e30SBram Moolenaar	return res + res2
495*1ef15e30SBram Moolenaarendfunction
496