blob: 29b6b16254fa3fbdc94a2b16419ce7d0bee8e621 [file] [log] [blame]
Bram Moolenaar1ef15e32006-02-01 21:56:25 +00001" Vim completion script
2" Language: Java Script
Bram Moolenaare7b1ea02020-08-07 19:54:59 +02003" Maintainer: Jay Sitter (jay@jaysitter.com)
4" URL: https://github.com/jsit/javascriptcomplete.vim/
5" Previous Maintainer: Mikolaj Machowski ( mikmach AT wp DOT pl )
6" Last Change: 2020 Jul 30
Bram Moolenaar1ef15e32006-02-01 21:56:25 +00007
8function! javascriptcomplete#CompleteJS(findstart, base)
9 if a:findstart
Bram Moolenaar8b6144b2006-02-08 09:20:24 +000010 " locate the start of the word
11 let line = getline('.')
12 let start = col('.') - 1
Bram Moolenaar1ef15e32006-02-01 21:56:25 +000013 let curline = line('.')
14 let compl_begin = col('.') - 2
15 " Bit risky but JS is rather limited language and local chars shouldn't
16 " fint way into names
Bram Moolenaar1d2ba7f2006-02-14 22:29:30 +000017 while start >= 0 && line[start - 1] =~ '\k'
Bram Moolenaar1ef15e32006-02-01 21:56:25 +000018 let start -= 1
Bram Moolenaar8b6144b2006-02-08 09:20:24 +000019 endwhile
Bram Moolenaar1ef15e32006-02-01 21:56:25 +000020 let b:compl_context = getline('.')[0:compl_begin]
Bram Moolenaar8b6144b2006-02-08 09:20:24 +000021 return start
Bram Moolenaar1ef15e32006-02-01 21:56:25 +000022 else
23 " Initialize base return lists
Bram Moolenaar8b6144b2006-02-08 09:20:24 +000024 let res = []
25 let res2 = []
Bram Moolenaar1ef15e32006-02-01 21:56:25 +000026 " a:base is very short - we need context
Bram Moolenaar1ef15e32006-02-01 21:56:25 +000027 " Shortcontext is context without a:base, useful for checking if we are
Bram Moolenaar8b6144b2006-02-08 09:20:24 +000028 " looking for objects and for what objects we are looking for
29 let context = b:compl_context
Bram Moolenaar1ef15e32006-02-01 21:56:25 +000030 let shortcontext = substitute(context, a:base.'$', '', '')
31 unlet! b:compl_context
32
Bram Moolenaar8b6144b2006-02-08 09:20:24 +000033 if exists("b:jsrange")
34 let file = getline(b:jsrange[0],b:jsrange[1])
35 unlet! b:jsrange
36
37 if len(b:js_extfiles) > 0
38 let file = b:js_extfiles + file
39 endif
40
41 else
42 let file = getline(1, '$')
43 endif
44
45
46 " Completion of properties, methods, etc. {{{
Bram Moolenaar1ef15e32006-02-01 21:56:25 +000047 if shortcontext =~ '\.$'
48 " Complete methods and properties for objects
49 " DOM separate
50 let doms = ['style.']
51 " Arrays
52 let arrayprop = ['constructor', 'index', 'input', 'length', 'prototype']
Bram Moolenaarc9b4b052006-04-30 18:54:39 +000053 let arraymeth = ['concat', 'join', 'pop', 'push', 'reverse', 'shift',
Bram Moolenaar1ef15e32006-02-01 21:56:25 +000054 \ 'splice', 'sort', 'toSource', 'toString', 'unshift', 'valueOf',
55 \ 'watch', 'unwatch']
56 call map(arraymeth, 'v:val."("')
57 let arrays = arrayprop + arraymeth
58
59 " Boolean - complete subset of array values
60 " properties - constructor, prototype
61 " methods - toSource, toString, valueOf
62
63 " Date
64 " properties - constructor, prototype
65 let datemeth = ['getDate', 'getDay', 'getFullYear', 'getHours', 'getMilliseconds',
66 \ 'getMinutes', 'getMonth', 'getSeconds', 'getTime', 'getTimezoneOffset',
67 \ 'getUTCDate', 'getUTCDay', 'getUTCFullYear', 'getUTCHours', 'getUTCMilliseconds',
68 \ 'getUTCMinutes', 'getUTCMonth', 'getUTCSeconds',
69 \ 'getYear', 'parse', 'parse',
70 \ 'setDate', 'setDay', 'setFullYear', 'setHours', 'setMilliseconds',
71 \ 'setMinutes', 'setMonth', 'setSeconds',
72 \ 'setUTCDate', 'setUTCDay', 'setUTCFullYear', 'setUTCHours', 'setUTCMilliseconds',
73 \ 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds', 'setYear', 'setTime',
74 \ 'toGMTString', 'toLocaleString', 'toLocaleDateString', 'toLocaleTimeString',
75 \ 'toSource', 'toString', 'toUTCString', 'UTC', 'valueOf', 'watch', 'unwatch']
76 call map(datemeth, 'v:val."("')
77 let dates = datemeth
78
79 " Function
80 let funcprop = ['arguments', 'arguments.callee', 'arguments.caller', 'arguments.length',
81 \ 'arity', 'constructor', 'length', 'prototype']
82 let funcmeth = ['apply', 'call', 'toSource', 'toString', 'valueOf']
83 call map(funcmeth, 'v:val."("')
84 let funcs = funcprop + funcmeth
85
86 " Math
87 let mathprop = ['E', 'LN2', 'LN10', 'LOG2E', 'LOG10E', 'PI', 'SQRT1_2', 'SQRT']
88 let mathmeth = ['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor',
89 \ 'log', 'max', 'min', 'pow', 'random', 'round', 'sin', 'sqrt', 'tan',
90 \ 'watch', 'unwatch']
91 call map(mathmeth, 'v:val."("')
92 let maths = mathprop + mathmeth
93
94 " Number
95 let numbprop = ['MAX_VALUE', 'MIN_VALUE', 'NaN', 'NEGATIVE_INFINITY', 'POSITIVE_INFINITY',
96 \ 'constructor', 'prototype']
97 let numbmeth = ['toExponential', 'toFixed', 'toPrecision', 'toSource', 'toString', 'valueOf',
98 \ 'watch', 'unwatch']
99 call map(numbmeth, 'v:val."("')
100 let numbs = numbprop + numbmeth
101
102 " Object
103 let objeprop = ['constructor', 'prototype']
104 let objemeth = ['eval', 'toSource', 'toString', 'unwatch', 'watch', 'valueOf']
105 call map(objemeth, 'v:val."("')
106 let objes = objeprop + objemeth
107
108 " RegExp
109 let regeprop = ['constructor', 'global', 'ignoreCase', 'lastIndex', 'multiline', 'source', 'prototype']
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000110 let regemeth = ['exec', 'test', 'toSource', 'toString', 'watch', 'unwatch']
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000111 call map(regemeth, 'v:val."("')
112 let reges = regeprop + regemeth
113
114 " String
115 let striprop = ['constructor', 'length', 'prototype']
116 let strimeth = ['anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'concat',
117 \ 'fixed', 'fontcolor', 'fontsize', 'fromCharCode', 'indexOf', 'italics',
118 \ 'lastIndexOf', 'link', 'match', 'replace', 'search', 'slice', 'small',
119 \ 'split', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLowerCase',
120 \ 'toSource', 'toString', 'toUpperCase', 'watch', 'unwatch']
121 call map(strimeth, 'v:val."("')
122 let stris = striprop + strimeth
123
124 " User created properties
Bram Moolenaar1d2ba7f2006-02-14 22:29:30 +0000125 let user_props1 = filter(copy(file), 'v:val =~ "this\\.\\k"')
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000126 let juser_props1 = join(user_props1, ' ')
127 let user_props1 = split(juser_props1, '\zethis\.')
128 unlet! juser_props1
Bram Moolenaar1d2ba7f2006-02-14 22:29:30 +0000129 call map(user_props1, 'matchstr(v:val, "this\\.\\zs\\k\\+\\ze")')
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000130
Bram Moolenaar1d2ba7f2006-02-14 22:29:30 +0000131 let user_props2 = filter(copy(file), 'v:val =~ "\\.prototype\\.\\k"')
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000132 let juser_props2 = join(user_props2, ' ')
133 let user_props2 = split(juser_props2, '\zeprototype\.')
134 unlet! juser_props2
Bram Moolenaar1d2ba7f2006-02-14 22:29:30 +0000135 call map(user_props2, 'matchstr(v:val, "prototype\\.\\zs\\k\\+\\ze")')
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000136 let user_props = user_props1 + user_props2
137
138 " HTML DOM properties
139 " Anchors - anchor.
140 let anchprop = ['accessKey', 'charset', 'coords', 'href', 'hreflang', 'id', 'innerHTML',
141 \ 'name', 'rel', 'rev', 'shape', 'tabIndex', 'target', 'type', 'onBlur', 'onFocus']
142 let anchmeth = ['blur', 'focus']
143 call map(anchmeth, 'v:val."("')
144 let anths = anchprop + anchmeth
145 " Area - area.
146 let areaprop = ['accessKey', 'alt', 'coords', 'hash', 'host', 'hostname', 'href', 'id',
147 \ 'noHref', 'pathname', 'port', 'protocol', 'search', 'shape', 'tabIndex', 'target']
148 let areameth = ['onClick', 'onDblClick', 'onMouseOut', 'onMouseOver']
149 call map(areameth, 'v:val."("')
150 let areas = areaprop + areameth
151 " Base - base.
152 let baseprop = ['href', 'id', 'target']
153 let bases = baseprop
154 " Body - body.
155 let bodyprop = ['aLink', 'background', 'gbColor', 'id', 'link', 'scrollLeft', 'scrollTop',
156 \ 'text', 'vLink']
157 let bodys = bodyprop
158 " Document - document.
Bram Moolenaare7b1ea02020-08-07 19:54:59 +0200159 let docuprop = ['anchors', 'body', 'characterSet', 'doctype',
160 \ 'documentElement', 'documentURI', 'embeds', 'fonts', 'forms',
161 \ 'head', 'hidden', 'images', 'implementation', 'lastStyleSheetSet',
162 \ 'links', 'plugins', 'preferredStyleSheetSet', 'scripts',
163 \ 'scrollingElement', 'selectedStyleSheetSet', 'styleSheetSets',
164 \ 'timeline', 'visibilityState', 'cookie', 'defaultView',
165 \ 'designMode', 'dir', 'domain', 'lastModified', 'location',
166 \ 'readyState', 'referrer', 'title', 'URL', 'activeElement',
167 \ 'fullscreenElement', 'styleSheets']
168 let documeth = ['adoptNode', 'close', 'createAttribute',
169 \ 'createAttributeNS', 'createCDATASection', 'createComment',
170 \ 'createDocumentFragment', 'createElement', 'createElementNS',
171 \ 'createEvent', 'createExpression', 'createNSResolver',
172 \ 'createNodeIterator', 'createProcessingInstruction', 'createRange',
173 \ 'createTextNode', 'createTouchList', 'createTreeWalker',
174 \ 'enableStyleSheetsForSet', 'evaluate', 'focus', 'getElementById',
175 \ 'getElementById', 'getElementsByClassName', 'getElementsByName',
176 \ 'getElementsByTagName', 'getElementsByTagNameNS',
177 \ 'hasStorageAccess', 'importNode', 'onClick', 'onDblClick',
178 \ 'onFocus', 'onKeyDown', 'onKeyPress', 'onKeyUp', 'onMouseDown',
179 \ 'onMouseMove', 'onMouseOut', 'onMouseOver', 'onMouseUp',
180 \ 'onResize', 'open', 'querySelector', 'querySelectorAll',
181 \ 'requestStorageAccess', 'write', 'writeln']
182
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000183 call map(documeth, 'v:val."("')
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000184 let docuxprop = ['attributes', 'childNodes', 'doctype', 'documentElement', 'firstChild',
185 \ 'implementation', 'namespaceURI', 'nextSibling', 'nodeName', 'nodeType',
186 \ 'nodeValue', 'ownerDocument', 'parentNode', 'previousSibling']
187 let docuxmeth = ['createAttribute', 'createCDATASection',
188 \ 'createComment', 'createDocument', 'createDocumentFragment',
189 \ 'createElement', 'createEntityReference', 'createProcessingInstruction',
190 \ 'createTextNode']
191 call map(docuxmeth, 'v:val."("')
192 let docus = docuprop + docuxprop + documeth + docuxmeth
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000193 " Form - form.
194 let formprop = ['elements', 'acceptCharset', 'action', 'encoding', 'enctype', 'id', 'length',
195 \ 'method', 'name', 'tabIndex', 'target']
196 let formmeth = ['reset', 'submit', 'onReset', 'onSubmit']
197 call map(formmeth, 'v:val."("')
198 let forms = formprop + formmeth
199 " Frame - frame.
200 let framprop = ['contentDocument', 'frameBorder', 'id', 'longDesc', 'marginHeight', 'marginWidth',
201 \ 'name', 'noResize', 'scrolling', 'src']
202 let frammeth = ['blur', 'focus']
203 call map(frammeth, 'v:val."("')
204 let frams = framprop + frammeth
205 " Frameset - frameset.
206 let fsetprop = ['cols', 'id', 'rows']
207 let fsetmeth = ['blur', 'focus']
208 call map(fsetmeth, 'v:val."("')
209 let fsets = fsetprop + fsetmeth
210 " History - history.
211 let histprop = ['length']
212 let histmeth = ['back', 'forward', 'go']
213 call map(histmeth, 'v:val."("')
214 let hists = histprop + histmeth
215 " Iframe - iframe.
216 let ifraprop = ['align', 'frameBorder', 'height', 'id', 'longDesc', 'marginHeight', 'marginWidth',
217 \ 'name', 'scrolling', 'src', 'width']
218 let ifras = ifraprop
219 " Image - image.
220 let imagprop = ['align', 'alt', 'border', 'complete', 'height', 'hspace', 'id', 'isMap', 'longDesc',
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000221 \ 'lowSrc', 'name', 'src', 'useMap', 'vspace', 'width']
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000222 let imagmeth = ['onAbort', 'onError', 'onLoad']
223 call map(imagmeth, 'v:val."("')
224 let imags = histprop + imagmeth
225 " Button - accessible only by other properties
226 let buttprop = ['accessKey', 'disabled', 'form', 'id', 'name', 'tabIndex', 'type', 'value']
227 let buttmeth = ['blur', 'click', 'focus', 'onBlur', 'onClick', 'onFocus', 'onMouseDown', 'onMouseUp']
228 call map(buttmeth, 'v:val."("')
229 let butts = buttprop + buttmeth
230 " Checkbox - accessible only by other properties
231 let checprop = ['accept', 'accessKey', 'align', 'alt', 'checked', 'defaultChecked',
232 \ 'disabled', 'form', 'id', 'name', 'tabIndex', 'type', 'value']
233 let checmeth = ['blur', 'click', 'focus', 'onBlur', 'onClick', 'onFocus', 'onMouseDown', 'onMouseUp']
234 call map(checmeth, 'v:val."("')
235 let checs = checprop + checmeth
236 " File upload - accessible only by other properties
237 let fileprop = ['accept', 'accessKey', 'align', 'alt', 'defaultValue',
238 \ 'disabled', 'form', 'id', 'name', 'tabIndex', 'type', 'value']
239 let filemeth = ['blur', 'focus', 'onBlur', 'onClick', 'onFocus', 'onMouseDown', 'onMouseUp']
240 call map(filemeth, 'v:val."("')
241 let files = fileprop + filemeth
242 " Hidden - accessible only by other properties
243 let hiddprop = ['defaultValue', 'form', 'id', 'name', 'type', 'value']
244 let hidds = hiddprop
245 " Password - accessible only by other properties
246 let passprop = ['accept', 'accessKey', 'defaultValue',
247 \ 'disabled', 'form', 'id', 'maxLength', 'name', 'readOnly', 'size', 'tabIndex',
248 \ 'type', 'value']
249 let passmeth = ['blur', 'click', 'focus', 'select', 'onBlur', 'onFocus', 'onKeyDown',
250 \ 'onKeyPress', 'onKeyUp']
251 call map(passmeth, 'v:val."("')
252 let passs = passprop + passmeth
253 " Radio - accessible only by other properties
254 let radiprop = ['accept', 'accessKey', 'align', 'alt', 'checked', 'defaultChecked',
255 \ 'disabled', 'form', 'id', 'name', 'tabIndex', 'type', 'value']
256 let radimeth = ['blur', 'click', 'focus', 'select', 'onBlur', 'onFocus']
257 call map(radimeth, 'v:val."("')
258 let radis = radiprop + radimeth
259 " Reset - accessible only by other properties
260 let reseprop = ['accept', 'accessKey', 'align', 'alt', 'defaultValue',
261 \ 'disabled', 'form', 'id', 'name', 'size', 'tabIndex', 'type', 'value']
262 let resemeth = ['blur', 'click', 'focus', 'select', 'onBlur', 'onFocus']
263 call map(resemeth, 'v:val."("')
264 let reses = reseprop + resemeth
265 " Submit - accessible only by other properties
266 let submprop = ['accept', 'accessKey', 'align', 'alt', 'defaultValue',
267 \ 'disabled', 'form', 'id', 'name', 'size', 'tabIndex', 'type', 'value']
268 let submmeth = ['blur', 'click', 'focus', 'select', 'onClick', 'onSelectStart']
269 call map(submmeth, 'v:val."("')
270 let subms = submprop + submmeth
271 " Text - accessible only by other properties
272 let textprop = ['accept', 'accessKey', 'align', 'alt', 'defaultValue',
273 \ 'disabled', 'form', 'id', 'maxLength', 'name', 'readOnly',
274 \ 'size', 'tabIndex', 'type', 'value']
275 let textmeth = ['blur', 'focus', 'select', 'onBlur', 'onChange', 'onFocus', 'onKeyDown',
276 \ 'onKeyPress', 'onKeyUp', 'onSelect']
277 call map(textmeth, 'v:val."("')
278 let texts = textprop + textmeth
279 " Link - link.
280 let linkprop = ['charset', 'disabled', 'href', 'hreflang', 'id', 'media',
281 \ 'rel', 'rev', 'target', 'type']
282 let linkmeth = ['onLoad']
283 call map(linkmeth, 'v:val."("')
284 let links = linkprop + linkmeth
285 " Location - location.
286 let locaprop = ['href', 'hash', 'host', 'hostname', 'pathname', 'port', 'protocol',
287 \ 'search']
288 let locameth = ['assign', 'reload', 'replace']
289 call map(locameth, 'v:val."("')
290 let locas = locaprop + locameth
291 " Meta - meta.
292 let metaprop = ['charset', 'content', 'disabled', 'httpEquiv', 'name', 'scheme']
293 let metas = metaprop
294 " Navigator - navigator.
295 let naviprop = ['plugins', 'appCodeName', 'appName', 'appVersion', 'cookieEnabled',
296 \ 'platform', 'userAgent']
297 let navimeth = ['javaEnabled', 'taintEnabled']
298 call map(navimeth, 'v:val."("')
299 let navis = naviprop + navimeth
300 " Object - object.
301 let objeprop = ['align', 'archive', 'border', 'code', 'codeBase', 'codeType', 'data',
302 \ 'declare', 'form', 'height', 'hspace', 'id', 'name', 'standby', 'tabIndex',
303 \ 'type', 'useMap', 'vspace', 'width']
304 let objes = objeprop
305 " Option - accessible only by other properties
306 let optiprop = ['defaultSelected',
307 \ 'disabled', 'form', 'id', 'index', 'label', 'selected', 'text', 'value']
308 let optis = optiprop
309 " Screen - screen.
310 let screprop = ['availHeight', 'availWidth', 'colorDepth', 'height', 'width']
311 let scres = screprop
312 " Select - accessible only by other properties
313 let seleprop = ['options', 'disabled', 'form', 'id', 'length', 'multiple', 'name',
314 \ 'selectedIndex', 'size', 'tabIndex', 'type', 'value']
315 let selemeth = ['blur', 'focus', 'remove', 'onBlur', 'onChange', 'onFocus']
316 call map(selemeth, 'v:val."("')
317 let seles = seleprop + selemeth
318 " Style - style.
319 let stylprop = ['background', 'backgroundAttachment', 'backgroundColor', 'backgroundImage',
320 \ 'backgroundPosition', 'backgroundRepeat',
321 \ 'border', 'borderBottom', 'borderLeft', 'borderRight', 'borderTop',
322 \ 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor',
323 \ 'borderBottomStyle', 'borderLeftStyle', 'borderRightStyle', 'borderTopStyle',
324 \ 'borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth',
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000325 \ 'borderColor', 'borderStyle', 'borderWidth', 'margin', 'marginBottom',
326 \ 'marginLeft', 'marginRight', 'marginTop', 'outline', 'outlineStyle', 'outlineWidth',
327 \ 'outlineColor', 'outlineStyle', 'outlineWidth', 'padding', 'paddingBottom',
328 \ 'paddingLeft', 'paddingRight', 'paddingTop',
329 \ 'clear', 'clip', 'clipBottom', 'clipLeft', 'clipRight', 'clipTop', 'content',
330 \ 'counterIncrement', 'counterReset', 'cssFloat', 'cursor', 'direction',
331 \ 'display', 'markerOffset', 'marks', 'maxHeight', 'maxWidth', 'minHeight',
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000332 \ 'minWidth', 'overflow', 'overflowX', 'overflowY', 'verticalAlign', 'visibility',
333 \ 'width',
334 \ 'listStyle', 'listStyleImage', 'listStylePosition', 'listStyleType',
335 \ 'cssText', 'bottom', 'height', 'left', 'position', 'right', 'top', 'width', 'zindex',
336 \ 'orphans', 'widows', 'page', 'pageBreakAfter', 'pageBreakBefore', 'pageBreakInside',
337 \ 'borderCollapse', 'borderSpacing', 'captionSide', 'emptyCells', 'tableLayout',
338 \ 'color', 'font', 'fontFamily', 'fontSize', 'fontSizeAdjust', 'fontStretch',
339 \ 'fontStyle', 'fontVariant', 'fontWeight', 'letterSpacing', 'lineHeight', 'quotes',
340 \ 'textAlign', 'textIndent', 'textShadow', 'textTransform', 'textUnderlinePosition',
341 \ 'unicodeBidi', 'whiteSpace', 'wordSpacing']
342 let styls = stylprop
343 " Table - table.
344 let tablprop = ['rows', 'tBodies', 'align', 'bgColor', 'border', 'caption', 'cellPadding',
345 \ 'cellSpacing', 'frame', 'height', 'rules', 'summary', 'tFoot', 'tHead', 'width']
346 let tablmeth = ['createCaption', 'createTFoot', 'createTHead', 'deleteCaption', 'deleteRow',
347 \ 'deleteTFoot', 'deleteTHead', 'insertRow']
348 call map(tablmeth, 'v:val."("')
349 let tabls = tablprop + tablmeth
350 " Table data - TableData.
351 let tdatprop = ['abbr', 'align', 'axis', 'bgColor', 'cellIndex', 'ch', 'chOff',
352 \ 'colSpan', 'headers', 'noWrap', 'rowSpan', 'scope', 'vAlign', 'width']
353 let tdats = tdatprop
354 " Table row - TableRow.
355 let trowprop = ['cells', 'align', 'bgColor', 'ch', 'chOff', 'rowIndex', 'sectionRowIndex',
356 \ 'vAlign']
357 let trowmeth = ['deleteCell', 'insertCell']
358 call map(trowmeth, 'v:val."("')
359 let trows = trowprop + trowmeth
360 " Textarea - accessible only by other properties
361 let tareprop = ['accessKey', 'cols', 'defaultValue',
362 \ 'disabled', 'form', 'id', 'name', 'readOnly', 'rows',
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000363 \ 'tabIndex', 'type', 'value', 'selectionStart', 'selectionEnd']
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000364 let taremeth = ['blur', 'focus', 'select', 'onBlur', 'onChange', 'onFocus']
365 call map(taremeth, 'v:val."("')
366 let tares = tareprop + taremeth
367 " Window - window.
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000368 let windprop = ['frames', 'closed', 'defaultStatus', 'encodeURI', 'event', 'history',
369 \ 'length', 'location', 'name', 'onload', 'opener', 'parent', 'screen', 'self',
370 \ 'status', 'top', 'XMLHttpRequest', 'ActiveXObject']
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000371 let windmeth = ['alert', 'blur', 'clearInterval', 'clearTimeout', 'close', 'confirm', 'focus',
372 \ 'moveBy', 'moveTo', 'open', 'print', 'prompt', 'scrollBy', 'scrollTo', 'setInterval',
373 \ 'setTimeout']
374 call map(windmeth, 'v:val."("')
375 let winds = windprop + windmeth
376 " XMLHttpRequest - access by new xxx()
377 let xmlhprop = ['onreadystatechange', 'readyState', 'responseText', 'responseXML',
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000378 \ 'status', 'statusText', 'parseError']
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000379 let xmlhmeth = ['abort', 'getAllResponseHeaders', 'getResponseHeaders', 'open',
380 \ 'send', 'setRequestHeader']
381 call map(xmlhmeth, 'v:val."("')
382 let xmlhs = xmlhprop + xmlhmeth
383
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000384 " XML DOM
385 " Attributes - element.attributes[x].
386 let xdomattrprop = ['name', 'specified', 'value']
387 " Element - anyelement.
388 let xdomelemprop = ['attributes', 'childNodes', 'firstChild', 'lastChild',
389 \ 'namespaceURI', 'nextSibling', 'nodeName', 'nodeType', 'nodeValue',
390 \ 'ownerDocument', 'parentNode', 'prefix', 'previousSibling', 'tagName']
Bram Moolenaare7b1ea02020-08-07 19:54:59 +0200391 let xdomelemmeth = ['appendChild', 'addEventListener', 'cloneNode',
392 \ 'dispatchEvent', 'getAttribute', 'getAttributeNode',
393 \ 'getElementsByTagName', 'hasChildNodes', 'insertBefore',
394 \ 'normalize', 'removeAttribute', 'removeAttributeNode',
395 \ 'removeChild', 'removeEventListener', 'replaceChild',
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000396 \ 'setAttribute', 'setAttributeNode']
397 call map(xdomelemmeth, 'v:val."("')
398 let xdomelems = xdomelemprop + xdomelemmeth
399 " Node - anynode.
400 let xdomnodeprop = ['attributes', 'childNodes', 'firstChild', 'lastChild',
401 \ 'namespaceURI', 'nextSibling', 'nodeName', 'nodeType', 'nodeValue',
402 \ 'ownerDocument', 'parentNode', 'prefix', 'previousSibling']
403 let xdomnodemeth = ['appendChild', 'cloneNode',
404 \ 'hasChildNodes', 'insertBefore', 'removeChild', 'replaceChild']
405 call map(xdomnodemeth, 'v:val."("')
406 let xdomnodes = xdomnodeprop + xdomnodemeth
407 " NodeList
408 let xdomnliss = ['length', 'item(']
409 " Error - parseError.
410 let xdomerror = ['errorCode', 'reason', 'line', 'linepos', 'srcText', 'url', 'filepos']
411
412 " Find object type declaration to reduce number of suggestions. {{{
413 " 1. Get object name
414 " 2. Find object declaration line
415 " 3. General declaration follows "= new Type" syntax, additional else
416 " for regexp "= /re/"
417 " 4. Make correction for Microsoft.XMLHTTP ActiveXObject
418 " 5. Repeat for external files
Bram Moolenaar1d2ba7f2006-02-14 22:29:30 +0000419 let object = matchstr(shortcontext, '\zs\k\+\ze\(\[.\{-}\]\)\?\.$')
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000420 if len(object) > 0
421 let decl_line = search(object.'.\{-}=\s*new\s*', 'bn')
422 if decl_line > 0
Bram Moolenaar1d2ba7f2006-02-14 22:29:30 +0000423 let object_type = matchstr(getline(decl_line), object.'.\{-}=\s*new\s*\zs\k\+\ze')
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000424 if object_type == 'ActiveXObject' && matchstr(getline(decl_line), object.'.\{-}=\s*new\s*ActiveXObject\s*(.Microsoft\.XMLHTTP.)') != ''
425 let object_type = 'XMLHttpRequest'
426 endif
427 else
428 let decl_line = search('var\s*'.object.'\s*=\s*\/', 'bn')
429 if decl_line > 0
430 let object_type = 'RegExp'
431 endif
432 endif
433 " We didn't find var declaration in current file but we may have
434 " something in external files.
435 if decl_line == 0 && exists("b:js_extfiles")
436 let dext_line = filter(copy(b:js_extfiles), 'v:val =~ "'.object.'.\\{-}=\\s*new\\s*"')
437 if len(dext_line) > 0
Bram Moolenaar1d2ba7f2006-02-14 22:29:30 +0000438 let object_type = matchstr(dext_line[-1], object.'.\{-}=\s*new\s*\zs\k\+\ze')
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000439 if object_type == 'ActiveXObject' && matchstr(dext_line[-1], object.'.\{-}=\s*new\s*ActiveXObject\s*(.Microsoft\.XMLHTTP.)') != ''
440 let object_type = 'XMLHttpRequest'
441 endif
442 else
443 let dext_line = filter(copy(b:js_extfiles), 'v:val =~ "var\s*'.object.'\\s*=\\s*\\/"')
444 if len(dext_line) > 0
445 let object_type = 'RegExp'
446 endif
447 endif
448 endif
449 endif
450 " }}}
451
452 if !exists('object_type')
453 let object_type = ''
454 endif
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000455
456 if object_type == 'Date'
457 let values = dates
458 elseif object_type == 'Image'
459 let values = imags
460 elseif object_type == 'Array'
461 let values = arrays
462 elseif object_type == 'Boolean'
463 " TODO: a bit more than real boolean
464 let values = arrays
465 elseif object_type == 'XMLHttpRequest'
466 let values = xmlhs
467 elseif object_type == 'String'
468 let values = stris
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000469 elseif object_type == 'RegExp'
470 let values = reges
471 elseif object_type == 'Math'
472 let values = maths
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000473 endif
474
475 if !exists('values')
476 " List of properties
477 if shortcontext =~ 'Math\.$'
478 let values = maths
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000479 elseif shortcontext =~ 'anchors\(\[.\{-}\]\)\?\.$'
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000480 let values = anths
481 elseif shortcontext =~ 'area\.$'
482 let values = areas
483 elseif shortcontext =~ 'base\.$'
484 let values = bases
485 elseif shortcontext =~ 'body\.$'
486 let values = bodys
487 elseif shortcontext =~ 'document\.$'
488 let values = docus
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000489 elseif shortcontext =~ 'forms\(\[.\{-}\]\)\?\.$'
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000490 let values = forms
491 elseif shortcontext =~ 'frameset\.$'
492 let values = fsets
493 elseif shortcontext =~ 'history\.$'
494 let values = hists
495 elseif shortcontext =~ 'iframe\.$'
496 let values = ifras
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000497 elseif shortcontext =~ 'images\(\[.\{-}\]\)\?\.$'
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000498 let values = imags
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000499 elseif shortcontext =~ 'links\(\[.\{-}\]\)\?\.$'
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000500 let values = links
501 elseif shortcontext =~ 'location\.$'
502 let values = locas
503 elseif shortcontext =~ 'meta\.$'
504 let values = metas
505 elseif shortcontext =~ 'navigator\.$'
506 let values = navis
507 elseif shortcontext =~ 'object\.$'
508 let values = objes
509 elseif shortcontext =~ 'screen\.$'
510 let values = scres
511 elseif shortcontext =~ 'style\.$'
512 let values = styls
513 elseif shortcontext =~ 'table\.$'
514 let values = tabls
515 elseif shortcontext =~ 'TableData\.$'
516 let values = tdats
517 elseif shortcontext =~ 'TableRow\.$'
518 let values = trows
519 elseif shortcontext =~ 'window\.$'
520 let values = winds
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000521 elseif shortcontext =~ 'parseError\.$'
522 let values = xdomerror
523 elseif shortcontext =~ 'attributes\[\d\+\]\.$'
524 let values = xdomattrprop
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000525 else
526 let values = user_props + arrays + dates + funcs + maths + numbs + objes + reges + stris
527 let values += doms + anths + areas + bases + bodys + docus + forms + frams + fsets + hists
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000528 let values += ifras + imags + links + locas + metas + navis + objes + scres
529 let values += tabls + trows + tares + winds
530 let values += xdomnodes + xdomnliss + xdomelems
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000531 endif
532 endif
533
534 for m in values
535 if m =~? '^'.a:base
536 call add(res, m)
537 elseif m =~? a:base
538 call add(res2, m)
539 endif
540 endfor
541
542 unlet! values
543 return res + res2
544
545 endif
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000546 " }}}
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000547
548 " Get variables data.
549 let variables = filter(copy(file), 'v:val =~ "var\\s"')
550 call map(variables, 'matchstr(v:val, ".\\{-}var\\s\\+\\zs.*\\ze")')
551 call map(variables, 'substitute(v:val, ";\\|$", ",", "g")')
552 let vars = []
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000553 " This loop (and next one) is necessary to get variable names from
554 " constructs like: var var1, var2, var3 = "something";
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000555 for i in range(len(variables))
556 let comma_separated = split(variables[i], ',\s*')
Bram Moolenaar1d2ba7f2006-02-14 22:29:30 +0000557 call map(comma_separated, 'matchstr(v:val, "\\k\\+")')
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000558 let vars += comma_separated
559 endfor
560
561 let variables = sort(vars)
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000562 unlet! vars
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000563
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000564 " Add "no var" variables.
Bram Moolenaar1d2ba7f2006-02-14 22:29:30 +0000565 let undeclared_variables = filter(copy(file), 'v:val =~ "^\\s*\\k\\+\\s*="')
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000566 let u_vars = []
567 for i in range(len(undeclared_variables))
568 let split_equal = split(undeclared_variables[i], '\s*=')
Bram Moolenaar1d2ba7f2006-02-14 22:29:30 +0000569 call map(split_equal, 'matchstr(v:val, "\\k\\+$")')
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000570 let u_vars += split_equal
571 endfor
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000572
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000573 let variables += sort(u_vars)
574 unlet! u_vars
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000575
576 " Get functions
577 let functions = filter(copy(file), 'v:val =~ "^\\s*function\\s"')
578 let arguments = copy(functions)
Bram Moolenaar1d2ba7f2006-02-14 22:29:30 +0000579 call map(functions, 'matchstr(v:val, "^\\s*function\\s\\+\\zs\\k\\+")')
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000580 call map(functions, 'v:val."("')
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000581 let functions = sort(functions)
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000582
Bram Moolenaar1d2ba7f2006-02-14 22:29:30 +0000583 " Create table to keep arguments for additional 'menu' info
584 let b:js_menuinfo = {}
585 for i in arguments
586 let g:ia = i
587 let f_elements = matchlist(i, 'function\s\+\(\k\+\)\s*(\(.\{-}\))')
Bram Moolenaar214641f2017-03-05 17:04:09 +0100588 if len(f_elements) >= 3
Bram Moolenaar1d2ba7f2006-02-14 22:29:30 +0000589 let b:js_menuinfo[f_elements[1].'('] = f_elements[2]
590 endif
591 endfor
592
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000593 " Get functions arguments
594 call map(arguments, 'matchstr(v:val, "function.\\{-}(\\zs.\\{-}\\ze)")')
595 let jargs = join(arguments, ',')
596 let jargs = substitute(jargs, '\s', '', 'g')
597 let arguments = split(jargs, ',')
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000598 let arguments = sort(arguments)
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000599
600 " Built-in functions
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000601 let builtin = ['alert(', 'confirm(']
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000602
603 " Top-level HTML DOM objects
604 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']
605 call map(htmldom, 'v:val."."')
606
607 " Top-level properties
608 let properties = ['decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent',
609 \ 'eval', 'Infinity', 'isFinite', 'isNaN', 'NaN', 'Number', 'parseFloat',
610 \ 'parseInt', 'String', 'undefined', 'escape', 'unescape']
611
612 " Keywords
613 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"]
614
615 let values = variables + functions + htmldom + arguments + builtin + properties + keywords
616
617 for m in values
618 if m =~? '^'.a:base
619 call add(res, m)
620 elseif m =~? a:base
621 call add(res2, m)
622 endif
623 endfor
624
Bram Moolenaar1d2ba7f2006-02-14 22:29:30 +0000625 let menu = res + res2
626 let final_menu = []
627 for i in range(len(menu))
628 let item = menu[i]
629 if item =~ '($'
630 let kind = 'f'
631 if has_key(b:js_menuinfo, item)
632 let m_info = b:js_menuinfo[item]
633 else
634 let m_info = ''
635 endif
636 else
637 let kind = 'v'
638 let m_info = ''
639 endif
640 let final_menu += [{'word':item, 'menu':m_info, 'kind':kind}]
641 endfor
642 let g:fm = final_menu
643 return final_menu
644
Bram Moolenaar1ef15e32006-02-01 21:56:25 +0000645endfunction
Bram Moolenaar8b6144b2006-02-08 09:20:24 +0000646
647" vim:set foldmethod=marker: