html-hint.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582
  1. (function () {
  2. function htmlHint(editor, htmlStructure, getToken) {
  3. var cur = editor.getCursor();
  4. var token = getToken(editor, cur);
  5. var keywords = [];
  6. var i = 0;
  7. var j = 0;
  8. var k = 0;
  9. var from = {line: cur.line, ch: cur.ch};
  10. var to = {line: cur.line, ch: cur.ch};
  11. var flagClean = true;
  12. var text = editor.getRange({line: 0, ch: 0}, cur);
  13. var open = text.lastIndexOf('<');
  14. var close = text.lastIndexOf('>');
  15. var tokenString = token.string.replace("<","");
  16. if(open > close) {
  17. var last = editor.getRange({line: cur.line, ch: cur.ch - 1}, cur);
  18. if(last == "<") {
  19. for(i = 0; i < htmlStructure.length; i++) {
  20. keywords.push(htmlStructure[i].tag);
  21. }
  22. from.ch = token.start + 1;
  23. } else {
  24. var counter = 0;
  25. var found = function(token, type, position) {
  26. counter++;
  27. if(counter > 50) return;
  28. if(token.type == type) {
  29. return token;
  30. } else {
  31. position.ch = token.start;
  32. var newToken = editor.getTokenAt(position);
  33. return found(newToken, type, position);
  34. }
  35. };
  36. var nodeToken = found(token, "tag", {line: cur.line, ch: cur.ch});
  37. var node = nodeToken.string.substring(1);
  38. if(token.type === null && token.string.trim() === "") {
  39. for(i = 0; i < htmlStructure.length; i++) {
  40. if(htmlStructure[i].tag == node) {
  41. for(j = 0; j < htmlStructure[i].attr.length; j++) {
  42. keywords.push(htmlStructure[i].attr[j].key + "=\"\" ");
  43. }
  44. for(k = 0; k < globalAttributes.length; k++) {
  45. keywords.push(globalAttributes[k].key + "=\"\" ");
  46. }
  47. }
  48. }
  49. } else if(token.type == "string") {
  50. tokenString = tokenString.substring(1, tokenString.length - 1);
  51. var attributeToken = found(token, "attribute", {line: cur.line, ch: cur.ch});
  52. var attribute = attributeToken.string;
  53. for(i = 0; i < htmlStructure.length; i++) {
  54. if(htmlStructure[i].tag == node) {
  55. for(j = 0; j < htmlStructure[i].attr.length; j++) {
  56. if(htmlStructure[i].attr[j].key == attribute) {
  57. for(k = 0; k < htmlStructure[i].attr[j].values.length; k++) {
  58. keywords.push(htmlStructure[i].attr[j].values[k]);
  59. }
  60. }
  61. }
  62. for(j = 0; j < globalAttributes.length; j++) {
  63. if(globalAttributes[j].key == attribute) {
  64. for(k = 0; k < globalAttributes[j].values.length; k++) {
  65. keywords.push(globalAttributes[j].values[k]);
  66. }
  67. }
  68. }
  69. }
  70. }
  71. from.ch = token.start + 1;
  72. } else if(token.type == "attribute") {
  73. for(i = 0; i < htmlStructure.length; i++) {
  74. if(htmlStructure[i].tag == node) {
  75. for(j = 0; j < htmlStructure[i].attr.length; j++) {
  76. keywords.push(htmlStructure[i].attr[j].key + "=\"\" ");
  77. }
  78. for(k = 0; k < globalAttributes.length; k++) {
  79. keywords.push(globalAttributes[k].key + "=\"\" ");
  80. }
  81. }
  82. }
  83. from.ch = token.start;
  84. } else if(token.type == "tag") {
  85. for(i = 0; i < htmlStructure.length; i++) {
  86. keywords.push(htmlStructure[i].tag);
  87. }
  88. from.ch = token.start + 1;
  89. }
  90. }
  91. } else {
  92. for(i = 0; i < htmlStructure.length; i++) {
  93. keywords.push("<" + htmlStructure[i].tag);
  94. }
  95. tokenString = ("<" + tokenString).trim();
  96. from.ch = token.start;
  97. }
  98. if(flagClean === true && tokenString.trim() === "") {
  99. flagClean = false;
  100. }
  101. if(flagClean) {
  102. keywords = cleanResults(tokenString, keywords);
  103. }
  104. return {list: keywords, from: from, to: to};
  105. }
  106. var cleanResults = function(text, keywords) {
  107. var results = [];
  108. var i = 0;
  109. for(i = 0; i < keywords.length; i++) {
  110. if(keywords[i].substring(0, text.length) == text) {
  111. results.push(keywords[i]);
  112. }
  113. }
  114. return results;
  115. };
  116. var htmlStructure = [
  117. {tag: '!DOCTYPE', attr: []},
  118. {tag: 'a', attr: [
  119. {key: 'href', values: ["#"]},
  120. {key: 'target', values: ["_blank","_self","_top","_parent"]},
  121. {key: 'ping', values: [""]},
  122. {key: 'media', values: ["#"]},
  123. {key: 'hreflang', values: ["en","es"]},
  124. {key: 'type', values: []}
  125. ]},
  126. {tag: 'abbr', attr: []},
  127. {tag: 'acronym', attr: []},
  128. {tag: 'address', attr: []},
  129. {tag: 'applet', attr: []},
  130. {tag: 'area', attr: [
  131. {key: 'alt', values: [""]},
  132. {key: 'coords', values: ["rect: left, top, right, bottom","circle: center-x, center-y, radius","poly: x1, y1, x2, y2, ..."]},
  133. {key: 'shape', values: ["default","rect","circle","poly"]},
  134. {key: 'href', values: ["#"]},
  135. {key: 'target', values: ["#"]},
  136. {key: 'ping', values: []},
  137. {key: 'media', values: []},
  138. {key: 'hreflang', values: []},
  139. {key: 'type', values: []}
  140. ]},
  141. {tag: 'article', attr: []},
  142. {tag: 'aside', attr: []},
  143. {tag: 'audio', attr: [
  144. {key: 'src', values: []},
  145. {key: 'crossorigin', values: ["anonymous","use-credentials"]},
  146. {key: 'preload', values: ["none","metadata","auto"]},
  147. {key: 'autoplay', values: ["","autoplay"]},
  148. {key: 'mediagroup', values: []},
  149. {key: 'loop', values: ["","loop"]},
  150. {key: 'controls', values: ["","controls"]}
  151. ]},
  152. {tag: 'b', attr: []},
  153. {tag: 'base', attr: [
  154. {key: 'href', values: ["#"]},
  155. {key: 'target', values: ["_blank","_self","_top","_parent"]}
  156. ]},
  157. {tag: 'basefont', attr: []},
  158. {tag: 'bdi', attr: []},
  159. {tag: 'bdo', attr: []},
  160. {tag: 'big', attr: []},
  161. {tag: 'blockquote', attr: [
  162. {key: 'cite', values: ["http://"]}
  163. ]},
  164. {tag: 'body', attr: []},
  165. {tag: 'br', attr: []},
  166. {tag: 'button', attr: [
  167. {key: 'autofocus', values: ["","autofocus"]},
  168. {key: 'disabled', values: ["","disabled"]},
  169. {key: 'form', values: []},
  170. {key: 'formaction', values: []},
  171. {key: 'formenctype', values: ["application/x-www-form-urlencoded","multipart/form-data","text/plain"]},
  172. {key: 'formmethod', values: ["get","post","put","delete"]},
  173. {key: 'formnovalidate', values: ["","novalidate"]},
  174. {key: 'formtarget', values: ["_blank","_self","_top","_parent"]},
  175. {key: 'name', values: []},
  176. {key: 'type', values: ["submit","reset","button"]},
  177. {key: 'value', values: []}
  178. ]},
  179. {tag: 'canvas', attr: [
  180. {key: 'width', values: []},
  181. {key: 'height', values: []}
  182. ]},
  183. {tag: 'caption', attr: []},
  184. {tag: 'center', attr: []},
  185. {tag: 'cite', attr: []},
  186. {tag: 'code', attr: []},
  187. {tag: 'col', attr: [
  188. {key: 'span', values: []}
  189. ]},
  190. {tag: 'colgroup', attr: [
  191. {key: 'span', values: []}
  192. ]},
  193. {tag: 'command', attr: [
  194. {key: 'type', values: ["command","checkbox","radio"]},
  195. {key: 'label', values: []},
  196. {key: 'icon', values: []},
  197. {key: 'disabled', values: ["","disabled"]},
  198. {key: 'checked', values: ["","checked"]},
  199. {key: 'radiogroup', values: []},
  200. {key: 'command', values: []},
  201. {key: 'title', values: []}
  202. ]},
  203. {tag: 'data', attr: [
  204. {key: 'value', values: []}
  205. ]},
  206. {tag: 'datagrid', attr: [
  207. {key: 'disabled', values: ["","disabled"]},
  208. {key: 'multiple', values: ["","multiple"]}
  209. ]},
  210. {tag: 'datalist', attr: [
  211. {key: 'data', values: []}
  212. ]},
  213. {tag: 'dd', attr: []},
  214. {tag: 'del', attr: [
  215. {key: 'cite', values: []},
  216. {key: 'datetime', values: []}
  217. ]},
  218. {tag: 'details', attr: [
  219. {key: 'open', values: ["","open"]}
  220. ]},
  221. {tag: 'dfn', attr: []},
  222. {tag: 'dir', attr: []},
  223. {tag: 'div', attr: [
  224. {key: 'id', values: []},
  225. {key: 'class', values: []},
  226. {key: 'style', values: []}
  227. ]},
  228. {tag: 'dl', attr: []},
  229. {tag: 'dt', attr: []},
  230. {tag: 'em', attr: []},
  231. {tag: 'embed', attr: [
  232. {key: 'src', values: []},
  233. {key: 'type', values: []},
  234. {key: 'width', values: []},
  235. {key: 'height', values: []}
  236. ]},
  237. {tag: 'eventsource', attr: [
  238. {key: 'src', values: []}
  239. ]},
  240. {tag: 'fieldset', attr: [
  241. {key: 'disabled', values: ["","disabled"]},
  242. {key: 'form', values: []},
  243. {key: 'name', values: []}
  244. ]},
  245. {tag: 'figcaption', attr: []},
  246. {tag: 'figure', attr: []},
  247. {tag: 'font', attr: []},
  248. {tag: 'footer', attr: []},
  249. {tag: 'form', attr: [
  250. {key: 'accept-charset', values: ["UNKNOWN","utf-8"]},
  251. {key: 'action', values: []},
  252. {key: 'autocomplete', values: ["on","off"]},
  253. {key: 'enctype', values: ["application/x-www-form-urlencoded","multipart/form-data","text/plain"]},
  254. {key: 'method', values: ["get","post","put","delete","dialog"]},
  255. {key: 'name', values: []},
  256. {key: 'novalidate', values: ["","novalidate"]},
  257. {key: 'target', values: ["_blank","_self","_top","_parent"]}
  258. ]},
  259. {tag: 'frame', attr: []},
  260. {tag: 'frameset', attr: []},
  261. {tag: 'h1', attr: []},
  262. {tag: 'h2', attr: []},
  263. {tag: 'h3', attr: []},
  264. {tag: 'h4', attr: []},
  265. {tag: 'h5', attr: []},
  266. {tag: 'h6', attr: []},
  267. {tag: 'head', attr: []},
  268. {tag: 'header', attr: []},
  269. {tag: 'hgroup', attr: []},
  270. {tag: 'hr', attr: []},
  271. {tag: 'html', attr: [
  272. {key: 'manifest', values: []}
  273. ]},
  274. {tag: 'i', attr: []},
  275. {tag: 'iframe', attr: [
  276. {key: 'src', values: []},
  277. {key: 'srcdoc', values: []},
  278. {key: 'name', values: []},
  279. {key: 'sandbox', values: ["allow-top-navigation","allow-same-origin","allow-forms","allow-scripts"]},
  280. {key: 'seamless', values: ["","seamless"]},
  281. {key: 'width', values: []},
  282. {key: 'height', values: []}
  283. ]},
  284. {tag: 'img', attr: [
  285. {key: 'alt', values: []},
  286. {key: 'src', values: []},
  287. {key: 'crossorigin', values: ["anonymous","use-credentials"]},
  288. {key: 'ismap', values: []},
  289. {key: 'usemap', values: []},
  290. {key: 'width', values: []},
  291. {key: 'height', values: []}
  292. ]},
  293. {tag: 'input', attr: [
  294. {key: 'accept', values: ["audio/*","video/*","image/*"]},
  295. {key: 'alt', values: []},
  296. {key: 'autocomplete', values: ["on","off"]},
  297. {key: 'autofocus', values: ["","autofocus"]},
  298. {key: 'checked', values: ["","checked"]},
  299. {key: 'disabled', values: ["","disabled"]},
  300. {key: 'dirname', values: []},
  301. {key: 'form', values: []},
  302. {key: 'formaction', values: []},
  303. {key: 'formenctype', values: ["application/x-www-form-urlencoded","multipart/form-data","text/plain"]},
  304. {key: 'formmethod', values: ["get","post","put","delete"]},
  305. {key: 'formnovalidate', values: ["","novalidate"]},
  306. {key: 'formtarget', values: ["_blank","_self","_top","_parent"]},
  307. {key: 'height', values: []},
  308. {key: 'list', values: []},
  309. {key: 'max', values: []},
  310. {key: 'maxlength', values: []},
  311. {key: 'min', values: []},
  312. {key: 'multiple', values: ["","multiple"]},
  313. {key: 'name', values: []},
  314. {key: 'pattern', values: []},
  315. {key: 'placeholder', values: []},
  316. {key: 'readonly', values: ["","readonly"]},
  317. {key: 'required', values: ["","required"]},
  318. {key: 'size', values: []},
  319. {key: 'src', values: []},
  320. {key: 'step', values: []},
  321. {key: 'type', values: [
  322. "hidden","text","search","tel","url","email","password","datetime","date","month","week","time","datetime-local",
  323. "number","range","color","checkbox","radio","file","submit","image","reset","button"
  324. ]},
  325. {key: 'value', values: []},
  326. {key: 'width', values: []}
  327. ]},
  328. {tag: 'ins', attr: [
  329. {key: 'cite', values: []},
  330. {key: 'datetime', values: []}
  331. ]},
  332. {tag: 'kbd', attr: []},
  333. {tag: 'keygen', attr: [
  334. {key: 'autofocus', values: ["","autofocus"]},
  335. {key: 'challenge', values: []},
  336. {key: 'disabled', values: ["","disabled"]},
  337. {key: 'form', values: []},
  338. {key: 'keytype', values: ["RSA"]},
  339. {key: 'name', values: []}
  340. ]},
  341. {tag: 'label', attr: [
  342. {key: 'for', values: []},
  343. {key: 'form', values: []}
  344. ]},
  345. {tag: 'legend', attr: []},
  346. {tag: 'li', attr: [
  347. {key: 'value', values: []}
  348. ]},
  349. {tag: 'link', attr: [
  350. {key: 'href', values: []},
  351. {key: 'hreflang', values: ["en","es"]},
  352. {key: 'media', values: [
  353. "all","screen","print","embossed","braille","handheld","print","projection","screen","tty","tv","speech","3d-glasses",
  354. "resolution [>][<][=] [X]dpi","resolution [>][<][=] [X]dpcm","device-aspect-ratio: 16/9","device-aspect-ratio: 4/3",
  355. "device-aspect-ratio: 32/18","device-aspect-ratio: 1280/720","device-aspect-ratio: 2560/1440","orientation:portrait",
  356. "orientation:landscape","device-height: [X]px","device-width: [X]px","-webkit-min-device-pixel-ratio: 2"
  357. ]},
  358. {key: 'type', values: []},
  359. {key: 'sizes', values: ["all","16x16","16x16 32x32","16x16 32x32 64x64"]}
  360. ]},
  361. {tag: 'map', attr: [
  362. {key: 'name', values: []}
  363. ]},
  364. {tag: 'mark', attr: []},
  365. {tag: 'menu', attr: [
  366. {key: 'type', values: ["list","context","toolbar"]},
  367. {key: 'label', values: []}
  368. ]},
  369. {tag: 'meta', attr: [
  370. {key: 'charset', attr: ["utf-8"]},
  371. {key: 'name', attr: ["viewport","application-name","author","description","generator","keywords"]},
  372. {key: 'content', attr: ["","width=device-width","initial-scale=1, maximum-scale=1, minimun-scale=1, user-scale=no"]},
  373. {key: 'http-equiv', attr: ["content-language","content-type","default-style","refresh"]}
  374. ]},
  375. {tag: 'meter', attr: [
  376. {key: 'value', values: []},
  377. {key: 'min', values: []},
  378. {key: 'low', values: []},
  379. {key: 'high', values: []},
  380. {key: 'max', values: []},
  381. {key: 'optimum', values: []}
  382. ]},
  383. {tag: 'nav', attr: []},
  384. {tag: 'noframes', attr: []},
  385. {tag: 'noscript', attr: []},
  386. {tag: 'object', attr: [
  387. {key: 'data', values: []},
  388. {key: 'type', values: []},
  389. {key: 'typemustmatch', values: ["","typemustmatch"]},
  390. {key: 'name', values: []},
  391. {key: 'usemap', values: []},
  392. {key: 'form', values: []},
  393. {key: 'width', values: []},
  394. {key: 'height', values: []}
  395. ]},
  396. {tag: 'ol', attr: [
  397. {key: 'reversed', values: ["", "reversed"]},
  398. {key: 'start', values: []},
  399. {key: 'type', values: ["1","a","A","i","I"]}
  400. ]},
  401. {tag: 'optgroup', attr: [
  402. {key: 'disabled', values: ["","disabled"]},
  403. {key: 'label', values: []}
  404. ]},
  405. {tag: 'option', attr: [
  406. {key: 'disabled', values: ["", "disabled"]},
  407. {key: 'label', values: []},
  408. {key: 'selected', values: ["", "selected"]},
  409. {key: 'value', values: []}
  410. ]},
  411. {tag: 'output', attr: [
  412. {key: 'for', values: []},
  413. {key: 'form', values: []},
  414. {key: 'name', values: []}
  415. ]},
  416. {tag: 'p', attr: []},
  417. {tag: 'param', attr: [
  418. {key: 'name', values: []},
  419. {key: 'value', values: []}
  420. ]},
  421. {tag: 'pre', attr: []},
  422. {tag: 'progress', attr: [
  423. {key: 'value', values: []},
  424. {key: 'max', values: []}
  425. ]},
  426. {tag: 'q', attr: [
  427. {key: 'cite', values: []}
  428. ]},
  429. {tag: 'rp', attr: []},
  430. {tag: 'rt', attr: []},
  431. {tag: 'ruby', attr: []},
  432. {tag: 's', attr: []},
  433. {tag: 'samp', attr: []},
  434. {tag: 'script', attr: [
  435. {key: 'type', values: ["text/javascript"]},
  436. {key: 'src', values: []},
  437. {key: 'async', values: ["","async"]},
  438. {key: 'defer', values: ["","defer"]},
  439. {key: 'charset', values: ["utf-8"]}
  440. ]},
  441. {tag: 'section', attr: []},
  442. {tag: 'select', attr: [
  443. {key: 'autofocus', values: ["", "autofocus"]},
  444. {key: 'disabled', values: ["", "disabled"]},
  445. {key: 'form', values: []},
  446. {key: 'multiple', values: ["", "multiple"]},
  447. {key: 'name', values: []},
  448. {key: 'size', values: []}
  449. ]},
  450. {tag: 'small', attr: []},
  451. {tag: 'source', attr: [
  452. {key: 'src', values: []},
  453. {key: 'type', values: []},
  454. {key: 'media', values: []}
  455. ]},
  456. {tag: 'span', attr: []},
  457. {tag: 'strike', attr: []},
  458. {tag: 'strong', attr: []},
  459. {tag: 'style', attr: [
  460. {key: 'type', values: ["text/css"]},
  461. {key: 'media', values: ["all","braille","print","projection","screen","speech"]},
  462. {key: 'scoped', values: []}
  463. ]},
  464. {tag: 'sub', attr: []},
  465. {tag: 'summary', attr: []},
  466. {tag: 'sup', attr: []},
  467. {tag: 'table', attr: [
  468. {key: 'border', values: []}
  469. ]},
  470. {tag: 'tbody', attr: []},
  471. {tag: 'td', attr: [
  472. {key: 'colspan', values: []},
  473. {key: 'rowspan', values: []},
  474. {key: 'headers', values: []}
  475. ]},
  476. {tag: 'textarea', attr: [
  477. {key: 'autofocus', values: ["","autofocus"]},
  478. {key: 'disabled', values: ["","disabled"]},
  479. {key: 'dirname', values: []},
  480. {key: 'form', values: []},
  481. {key: 'maxlength', values: []},
  482. {key: 'name', values: []},
  483. {key: 'placeholder', values: []},
  484. {key: 'readonly', values: ["","readonly"]},
  485. {key: 'required', values: ["","required"]},
  486. {key: 'rows', values: []},
  487. {key: 'cols', values: []},
  488. {key: 'wrap', values: ["soft","hard"]}
  489. ]},
  490. {tag: 'tfoot', attr: []},
  491. {tag: 'th', attr: [
  492. {key: 'colspan', values: []},
  493. {key: 'rowspan', values: []},
  494. {key: 'headers', values: []},
  495. {key: 'scope', values: ["row","col","rowgroup","colgroup"]}
  496. ]},
  497. {tag: 'thead', attr: []},
  498. {tag: 'time', attr: [
  499. {key: 'datetime', values: []}
  500. ]},
  501. {tag: 'title', attr: []},
  502. {tag: 'tr', attr: []},
  503. {tag: 'track', attr: [
  504. {key: 'kind', values: ["subtitles","captions","descriptions","chapters","metadata"]},
  505. {key: 'src', values: []},
  506. {key: 'srclang', values: ["en","es"]},
  507. {key: 'label', values: []},
  508. {key: 'default', values: []}
  509. ]},
  510. {tag: 'tt', attr: []},
  511. {tag: 'u', attr: []},
  512. {tag: 'ul', attr: []},
  513. {tag: 'var', attr: []},
  514. {tag: 'video', attr: [
  515. {key: "src", values: []},
  516. {key: "crossorigin", values: ["anonymous","use-credentials"]},
  517. {key: "poster", values: []},
  518. {key: "preload", values: ["auto","metadata","none"]},
  519. {key: "autoplay", values: ["","autoplay"]},
  520. {key: "mediagroup", values: ["movie"]},
  521. {key: "loop", values: ["","loop"]},
  522. {key: "muted", values: ["","muted"]},
  523. {key: "controls", values: ["","controls"]},
  524. {key: "width", values: []},
  525. {key: "height", values: []}
  526. ]},
  527. {tag: 'wbr', attr: []}
  528. ];
  529. var globalAttributes = [
  530. {key: "accesskey", values: ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9"]},
  531. {key: "class", values: []},
  532. {key: "contenteditable", values: ["true", "false"]},
  533. {key: "contextmenu", values: []},
  534. {key: "dir", values: ["ltr","rtl","auto"]},
  535. {key: "draggable", values: ["true","false","auto"]},
  536. {key: "dropzone", values: ["copy","move","link","string:","file:"]},
  537. {key: "hidden", values: ["hidden"]},
  538. {key: "id", values: []},
  539. {key: "inert", values: ["inert"]},
  540. {key: "itemid", values: []},
  541. {key: "itemprop", values: []},
  542. {key: "itemref", values: []},
  543. {key: "itemscope", values: ["itemscope"]},
  544. {key: "itemtype", values: []},
  545. {key: "lang", values: ["en","es"]},
  546. {key: "spellcheck", values: ["true","false"]},
  547. {key: "style", values: []},
  548. {key: "tabindex", values: ["1","2","3","4","5","6","7","8","9"]},
  549. {key: "title", values: []},
  550. {key: "translate", values: ["yes","no"]},
  551. {key: "onclick", values: []},
  552. {key: 'rel', values: ["stylesheet","alternate","author","bookmark","help","license","next","nofollow","noreferrer","prefetch","prev","search","tag"]}
  553. ];
  554. CodeMirror.htmlHint = function(editor) {
  555. if(String.prototype.trim == undefined) {
  556. String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g, '');};
  557. }
  558. return htmlHint(editor, htmlStructure, function (e, cur) { return e.getTokenAt(cur); });
  559. };
  560. })();