html_completions.js 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. /* ***** BEGIN LICENSE BLOCK *****
  2. * Distributed under the BSD license:
  3. *
  4. * Copyright (c) 2010, Ajax.org B.V.
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are met:
  9. * * Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * * Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * * Neither the name of Ajax.org B.V. nor the
  15. * names of its contributors may be used to endorse or promote products
  16. * derived from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  19. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21. * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
  22. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  24. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  25. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  27. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. *
  29. * ***** END LICENSE BLOCK ***** */
  30. define(function(require, exports, module) {
  31. "use strict";
  32. var TokenIterator = require("../token_iterator").TokenIterator;
  33. var commonAttributes = [
  34. "accesskey",
  35. "class",
  36. "contenteditable",
  37. "contextmenu",
  38. "dir",
  39. "draggable",
  40. "dropzone",
  41. "hidden",
  42. "id",
  43. "inert",
  44. "itemid",
  45. "itemprop",
  46. "itemref",
  47. "itemscope",
  48. "itemtype",
  49. "lang",
  50. "spellcheck",
  51. "style",
  52. "tabindex",
  53. "title",
  54. "translate"
  55. ];
  56. var eventAttributes = [
  57. "onabort",
  58. "onblur",
  59. "oncancel",
  60. "oncanplay",
  61. "oncanplaythrough",
  62. "onchange",
  63. "onclick",
  64. "onclose",
  65. "oncontextmenu",
  66. "oncuechange",
  67. "ondblclick",
  68. "ondrag",
  69. "ondragend",
  70. "ondragenter",
  71. "ondragleave",
  72. "ondragover",
  73. "ondragstart",
  74. "ondrop",
  75. "ondurationchange",
  76. "onemptied",
  77. "onended",
  78. "onerror",
  79. "onfocus",
  80. "oninput",
  81. "oninvalid",
  82. "onkeydown",
  83. "onkeypress",
  84. "onkeyup",
  85. "onload",
  86. "onloadeddata",
  87. "onloadedmetadata",
  88. "onloadstart",
  89. "onmousedown",
  90. "onmousemove",
  91. "onmouseout",
  92. "onmouseover",
  93. "onmouseup",
  94. "onmousewheel",
  95. "onpause",
  96. "onplay",
  97. "onplaying",
  98. "onprogress",
  99. "onratechange",
  100. "onreset",
  101. "onscroll",
  102. "onseeked",
  103. "onseeking",
  104. "onselect",
  105. "onshow",
  106. "onstalled",
  107. "onsubmit",
  108. "onsuspend",
  109. "ontimeupdate",
  110. "onvolumechange",
  111. "onwaiting"
  112. ];
  113. var globalAttributes = commonAttributes.concat(eventAttributes);
  114. var attributeMap = {
  115. "html": ["manifest"],
  116. "head": [],
  117. "title": [],
  118. "base": ["href", "target"],
  119. "link": ["href", "hreflang", "rel", "media", "type", "sizes"],
  120. "meta": ["http-equiv", "name", "content", "charset"],
  121. "style": ["type", "media", "scoped"],
  122. "script": ["charset", "type", "src", "defer", "async"],
  123. "noscript": ["href"],
  124. "body": ["onafterprint", "onbeforeprint", "onbeforeunload", "onhashchange", "onmessage", "onoffline", "onpopstate", "onredo", "onresize", "onstorage", "onundo", "onunload"],
  125. "section": [],
  126. "nav": [],
  127. "article": ["pubdate"],
  128. "aside": [],
  129. "h1": [],
  130. "h2": [],
  131. "h3": [],
  132. "h4": [],
  133. "h5": [],
  134. "h6": [],
  135. "header": [],
  136. "footer": [],
  137. "address": [],
  138. "main": [],
  139. "p": [],
  140. "hr": [],
  141. "pre": [],
  142. "blockquote": ["cite"],
  143. "ol": ["start", "reversed"],
  144. "ul": [],
  145. "li": ["value"],
  146. "dl": [],
  147. "dt": [],
  148. "dd": [],
  149. "figure": [],
  150. "figcaption": [],
  151. "div": [],
  152. "a": ["href", "target", "ping", "rel", "media", "hreflang", "type"],
  153. "em": [],
  154. "strong": [],
  155. "small": [],
  156. "s": [],
  157. "cite": [],
  158. "q": ["cite"],
  159. "dfn": [],
  160. "abbr": [],
  161. "data": [],
  162. "time": ["datetime"],
  163. "code": [],
  164. "var": [],
  165. "samp": [],
  166. "kbd": [],
  167. "sub": [],
  168. "sup": [],
  169. "i": [],
  170. "b": [],
  171. "u": [],
  172. "mark": [],
  173. "ruby": [],
  174. "rt": [],
  175. "rp": [],
  176. "bdi": [],
  177. "bdo": [],
  178. "span": [],
  179. "br": [],
  180. "wbr": [],
  181. "ins": ["cite", "datetime"],
  182. "del": ["cite", "datetime"],
  183. "img": ["alt", "src", "height", "width", "usemap", "ismap"],
  184. "iframe": ["name", "src", "height", "width", "sandbox", "seamless"],
  185. "embed": ["src", "height", "width", "type"],
  186. "object": ["param", "data", "type", "height" , "width", "usemap", "name", "form", "classid"],
  187. "param": ["name", "value"],
  188. "video": ["src", "autobuffer", "autoplay", "loop", "controls", "width", "height", "poster"],
  189. "audio": ["src", "autobuffer", "autoplay", "loop", "controls"],
  190. "source": ["src", "type", "media"],
  191. "track": ["kind", "src", "srclang", "label", "default"],
  192. "canvas": ["width", "height"],
  193. "map": ["name"],
  194. "area": ["shape", "coords", "href", "hreflang", "alt", "target", "media", "rel", "ping", "type"],
  195. "svg": [],
  196. "math": [],
  197. "table": ["summary"],
  198. "caption": [],
  199. "colgroup": ["span"],
  200. "col": ["span"],
  201. "tbody": [],
  202. "thead": [],
  203. "tfoot": [],
  204. "tr": [],
  205. "td": ["headers", "rowspan", "colspan"],
  206. "th": ["headers", "rowspan", "colspan", "scope"],
  207. "form": ["accept-charset", "action", "autocomplete", "enctype", "method", "name", "novalidate", "target"],
  208. "fieldset": ["disabled", "form", "name"],
  209. "legend": [],
  210. "label": ["form", "for"],
  211. "input": ["type", "accept", "alt", "autocomplete", "checked", "disabled", "form", "formaction", "formenctype", "formmethod", "formnovalidate", "formtarget", "height", "list", "max", "maxlength", "min", "multiple", "pattern", "placeholder", "readonly", "required", "size", "src", "step", "width", "files", "value"],
  212. "button": ["autofocus", "disabled", "form", "formaction", "formenctype", "formmethod", "formnovalidate", "formtarget", "name", "value", "type"],
  213. "select": ["autofocus", "disabled", "form", "multiple", "name", "size"],
  214. "datalist": [],
  215. "optgroup": ["disabled", "label"],
  216. "option": ["disabled", "selected", "label", "value"],
  217. "textarea": ["autofocus", "disabled", "form", "maxlength", "name", "placeholder", "readonly", "required", "rows", "cols", "wrap"],
  218. "keygen": ["autofocus", "challenge", "disabled", "form", "keytype", "name"],
  219. "output": ["for", "form", "name"],
  220. "progress": ["value", "max"],
  221. "meter": ["value", "min", "max", "low", "high", "optimum"],
  222. "details": ["open"],
  223. "summary": [],
  224. "command": ["type", "label", "icon", "disabled", "checked", "radiogroup", "command"],
  225. "menu": ["type", "label"],
  226. "dialog": ["open"]
  227. };
  228. var elements = Object.keys(attributeMap);
  229. function is(token, type) {
  230. return token.type.lastIndexOf(type + ".xml") > -1;
  231. }
  232. function findTagName(session, pos) {
  233. var iterator = new TokenIterator(session, pos.row, pos.column);
  234. var token = iterator.getCurrentToken();
  235. while (token && !is(token, "tag-name")){
  236. token = iterator.stepBackward();
  237. }
  238. if (token)
  239. return token.value;
  240. }
  241. var HtmlCompletions = function() {
  242. };
  243. (function() {
  244. this.getCompletions = function(state, session, pos, prefix) {
  245. var token = session.getTokenAt(pos.row, pos.column);
  246. if (!token)
  247. return [];
  248. // tag name
  249. if (is(token, "tag-name") || is(token, "tag-open") || is(token, "end-tag-open"))
  250. return this.getTagCompletions(state, session, pos, prefix);
  251. // tag attribute
  252. if (is(token, "tag-whitespace") || is(token, "attribute-name"))
  253. return this.getAttributeCompetions(state, session, pos, prefix);
  254. return [];
  255. };
  256. this.getTagCompletions = function(state, session, pos, prefix) {
  257. return elements.map(function(element){
  258. return {
  259. value: element,
  260. meta: "tag",
  261. score: Number.MAX_VALUE
  262. };
  263. });
  264. };
  265. this.getAttributeCompetions = function(state, session, pos, prefix) {
  266. var tagName = findTagName(session, pos);
  267. if (!tagName)
  268. return [];
  269. var attributes = globalAttributes;
  270. if (tagName in attributeMap) {
  271. attributes = attributes.concat(attributeMap[tagName]);
  272. }
  273. return attributes.map(function(attribute){
  274. return {
  275. caption: attribute,
  276. snippet: attribute + '="$0"',
  277. meta: "attribute",
  278. score: Number.MAX_VALUE
  279. };
  280. });
  281. };
  282. }).call(HtmlCompletions.prototype);
  283. exports.HtmlCompletions = HtmlCompletions;
  284. });