├── HtmlAttributes.json ├── HtmlTags.json ├── LICENSE ├── README.md ├── main.js └── package.json /HtmlAttributes.json: -------------------------------------------------------------------------------- 1 | { 2 | "accesskey": { "attribOption": [], "global": "true" }, 3 | "class": { "attribOption": [], "global": "true", "type": "cssStyle" }, 4 | "contenteditable": { "attribOption": [], "global": "true", "type": "boolean" }, 5 | "contextmenu": { "attribOption": [], "global": "true" }, 6 | "dir": { "attribOption": ["ltr", "rtl"], "global": "true"}, 7 | "draggable": { "attribOption": ["auto", "false", "true"], "global": "true" }, 8 | "dropzone": { "attribOption": ["copy", "move", "link"], "global": "true" }, 9 | "hidden": { "attribOption": ["hidden"], "global": "true" }, 10 | "id": { "attribOption": [], "global": "true", "type": "cssId" }, 11 | "lang": { "attribOption": ["ab", "aa", "af", "sq", "am", "ar", "an", "hy", "as", "ay", "az", "ba", "eu", "bn", "dz", "bh", "bi", "br", 12 | "bg", "my", "be", "km", "ca", "zh", "co", "hr", "cs", "da", "nl", "en", "eo", "et", "fo", "fa", "fi", "fr", 13 | "fy", "gl", "gd", "gv", "ka", "de", "el", "kl", "gn", "gu", "ht", "ha", "he", "hi", "hu", "is", "io", "id", 14 | "ia", "ie", "iu", "ik", "ga", "it", "ja", "jv", "kn", "ks", "kk", "rw", "ky", "rn", "ko", "ku", "lo", "la", 15 | "lv", "li", "ln", "lt", "mk", "mg", "ms", "ml", "mt", "mi", "mr", "mo", "mn", "na", "ne", "no", "oc", "or", 16 | "om", "ps", "pl", "pt", "pa", "qu", "rm", "ro", "ru", "sz", "sm", "sg", "sa", "sr", "sh", "st", "tn", "sn", 17 | "ii", "sd", "si", "ss", "sk", "sl", "so", "es", "su", "sw", "sv", "tl", "tg", "ta", "tt", "te", "th", "bo", 18 | "ti", "to", "ts", "tr", "tk", "tw", "ug", "uk", "ur", "uz", "vi", "vo", "wa", "cy", "wo", "xh", "yi", "yo", 19 | "zu"], 20 | "global": "true" }, 21 | "role": { "attribOption": ["alert", "alertdialog", "article", "application", "banner", "button", "checkbox", "columnheader", "combobox", 22 | "complementary", "contentinfo", "definition", "directory", "dialog", "document", "form", "grid", "gridcell", 23 | "group", "heading", "img", "link", "list", "listbox", "listitem", "log", "main", "marquee", "math", "menu", 24 | "menubar", "menuitem", "menuitemcheckbox", "menuitemradio", "navigation", "note", "option", "presentation", 25 | "progressbar", "radio", "radiogroup", "region", "row", "rowgroup", "rowheader", "scrollbar", "search", 26 | "separator", "slider", "spinbutton", "status", "tab", "tablist", "tabpanel", "textbox", "timer", "toolbar", 27 | "tooltip", "tree", "treegrid", "treeitem"], 28 | "global": "true" }, 29 | "spellcheck": { "attribOption": [], "global": "true", "type": "boolean" }, 30 | "style": { "attribOption": [], "global": "true", "type": "style" }, 31 | "tabindex": { "attribOption": [], "global": "true" }, 32 | "title": { "attribOption": [], "global": "true" }, 33 | 34 | "onabort": { "attribOption": [], "global": "true" }, 35 | "onblur": { "attribOption": [], "global": "true" }, 36 | "oncanplay": { "attribOption": [], "global": "true" }, 37 | "oncanplaythrough": { "attribOption": [], "global": "true" }, 38 | "onchange": { "attribOption": [], "global": "true" }, 39 | "onclick": { "attribOption": [], "global": "true" }, 40 | "oncontextmenu": { "attribOption": [], "global": "true" }, 41 | "oncuechange": { "attribOption": [], "global": "true" }, 42 | "ondblclick": { "attribOption": [], "global": "true" }, 43 | "ondrag": { "attribOption": [], "global": "true" }, 44 | "ondragend": { "attribOption": [], "global": "true" }, 45 | "ondragenter": { "attribOption": [], "global": "true" }, 46 | "ondragleave": { "attribOption": [], "global": "true" }, 47 | "ondragover": { "attribOption": [], "global": "true" }, 48 | "ondragstart": { "attribOption": [], "global": "true" }, 49 | "ondrop": { "attribOption": [], "global": "true" }, 50 | "ondurationchange": { "attribOption": [], "global": "true" }, 51 | "onemptied": { "attribOption": [], "global": "true" }, 52 | "onended": { "attribOption": [], "global": "true" }, 53 | "onerror": { "attribOption": [], "global": "true" }, 54 | "onfocus": { "attribOption": [], "global": "true" }, 55 | "oninput": { "attribOption": [], "global": "true" }, 56 | "oninvalid": { "attribOption": [], "global": "true" }, 57 | "onkeydown": { "attribOption": [], "global": "true" }, 58 | "onkeypress": { "attribOption": [], "global": "true" }, 59 | "onkeyup": { "attribOption": [], "global": "true" }, 60 | "onload": { "attribOption": [], "global": "true" }, 61 | "onloadeddata": { "attribOption": [], "global": "true" }, 62 | "onloadedmetadata": { "attribOption": [], "global": "true" }, 63 | "onloadstart": { "attribOption": [], "global": "true" }, 64 | "onmousedown": { "attribOption": [], "global": "true" }, 65 | "onmousemove": { "attribOption": [], "global": "true" }, 66 | "onmouseout": { "attribOption": [], "global": "true" }, 67 | "onmouseover": { "attribOption": [], "global": "true" }, 68 | "onmouseup": { "attribOption": [], "global": "true" }, 69 | "onmousewheel": { "attribOption": [], "global": "true" }, 70 | "onpause": { "attribOption": [], "global": "true" }, 71 | "onplay": { "attribOption": [], "global": "true" }, 72 | "onplaying": { "attribOption": [], "global": "true" }, 73 | "onprogress": { "attribOption": [], "global": "true" }, 74 | "onratechange": { "attribOption": [], "global": "true" }, 75 | "onreadystatechange": { "attribOption": [], "global": "true" }, 76 | "onreset": { "attribOption": [], "global": "true" }, 77 | "onscroll": { "attribOption": [], "global": "true" }, 78 | "onsearch": { "attribOption": [], "global": "true" }, 79 | "onseeked": { "attribOption": [], "global": "true" }, 80 | "onseeking": { "attribOption": [], "global": "true" }, 81 | "onselect": { "attribOption": [], "global": "true" }, 82 | "onshow": { "attribOption": [], "global": "true" }, 83 | "onstalled": { "attribOption": [], "global": "true" }, 84 | "onsubmit": { "attribOption": [], "global": "true" }, 85 | "onsuspend": { "attribOption": [], "global": "true" }, 86 | "ontimeupdate": { "attribOption": [], "global": "true" }, 87 | "onvolumechange": { "attribOption": [], "global": "true" }, 88 | "onwaiting": { "attribOption": [], "global": "true" }, 89 | 90 | "accept": { "attribOption": ["text/html", "text/plain", "application/msword", "application/msexcel", "application/postscript", 91 | "application/x-zip-compressed", "application/pdf", "application/rtf", "video/x-msvideo", "video/quicktime", 92 | "video/x-mpeg2", "audio/x-pn/realaudio", "audio/x-mpeg", "audio/x-waw", "audio/x-aiff", "audio/basic", 93 | "image/tiff", "image/jpeg", "image/gif", "image/x-png", "image/x-photo-cd", "image/x-MS-bmp", "image/x-rgb", 94 | "image/x-portable-pixmap", "image/x-portable-greymap", "image/x-portablebitmap"] }, 95 | "accept-charset": { "attribOption": [] }, 96 | "action": { "attribOption": [] }, 97 | "align": { "attribOption": [] }, 98 | "alt": { "attribOption": [] }, 99 | "archive": { "attribOption": [] }, 100 | "async": { "attribOption": [], "type": "flag" }, 101 | "autocapitalize": { "attribOption": ["on", "off"] }, 102 | "autocomplete": { "attribOption": ["billing", "cc-name", "cc-number", "cc-css", "cc-exp-month", "cc-exp-year", "cc-type", "country", "email", "name", "off", "on", "postal-code", "region", "shipping", "street-address", "tel", "url"] }, 103 | "autocorrect": { "attribOption": ["on", "off"] }, 104 | "autofocus": { "attribOption": [], "type": "flag" }, 105 | "autoplay": { "attribOption": [], "type": "flag" }, 106 | "behavior": { "attribOption": ["scroll", "slide", "alternate"] }, 107 | "bgcolor": { "attribOption": [], "type": "color" }, 108 | "border": { "attribOption": [] }, 109 | "challenge": { "attribOption": [] }, 110 | "charset": { "attribOption": ["iso-8859-1", "utf-8", "shift_jis", "euc-jp", "big5", "gb2312", "euc-kr", "din_66003-kr", "ns_4551-1-kr", 111 | "sen_850200_b", "csISO2022jp", "hz-gb-2312", "ibm852", "ibm866", "irv", "iso-2022-kr", "iso-8859-2", 112 | "iso-8859-3", "iso-8859-4", "iso-8859-5", "iso-8859-6", "iso-8859-7", "iso-8859-8", "iso-8859-9", "koi8-r", 113 | "ks_c_5601", "windows-1250", "windows-1251", "windows-1252", "windows-1253", "windows-1254", "windows-1255", 114 | "windows-1256", "windows-1257", "windows-1258", "windows-874", "x-euc", "asmo-708", "dos-720", "dos-862", 115 | "dos-874", "cp866", "cp1256"] }, 116 | "checked": { "attribOption": [], "type": "flag" }, 117 | "cite": { "attribOption": [] }, 118 | "codebase": { "attribOption": [] }, 119 | "codetype": { "attribOption": [] }, 120 | "cols": { "attribOption": [] }, 121 | "colspan": { "attribOption": [] }, 122 | "content": { "attribOption": [] }, 123 | "controls": { "attribOption": [], "type": "flag" }, 124 | "coords": { "attribOption": [] }, 125 | "data": { "attribOption": [] }, 126 | "datetime": { "attribOption": [] }, 127 | "declare": { "attribOption": [], "type": "flag" }, 128 | "default": { "attribOption": [], "type": "flag" }, 129 | "defer": { "attribOption": [], "type": "flag" }, 130 | "direction": { "attribOption": ["left", "right", "up", "down"] }, 131 | "dirname": { "attribOption": [] }, 132 | "disabled": { "attribOption": [], "type": "flag" }, 133 | "enctype": { "attribOption": ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"] }, 134 | "for": { "attribOption": [] }, 135 | "form": { "attribOption": [] }, 136 | "formaction": { "attribOption": [] }, 137 | "formenctype": { "attribOption": ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"] }, 138 | "formmethod": { "attribOption": ["get", "post"] }, 139 | "formnovalidate": { "attribOption": [], "type": "flag" }, 140 | "formtarget": { "attribOption": ["_blank", "_parent", "_self", "_top"] }, 141 | "headers": { "attribOption": [] }, 142 | "height": { "attribOption": [] }, 143 | "high": { "attribOption": [] }, 144 | "href": { "attribOption": [] }, 145 | "hreflang": { "attribOption": [] }, 146 | "hspace": { "attribOption": [] }, 147 | "http-equiv": { "attribOption": ["content-language", "content-type", "default-style", "refresh", "X-UA-Compatible"] }, 148 | "icon": { "attribOption": [] }, 149 | "inputmode": { "attribOption": ["email", "numeric", "tel"]}, 150 | "ismap": { "attribOption": [], "type": "flag" }, 151 | "itemprop": { "attribOption": [] }, 152 | "itemscope": { "attribOption": [] }, 153 | "itemtype": { "attribOption": [] }, 154 | "keytype": { "attribOption": ["dsa", "ec", "rsa"] }, 155 | "kind": { "attribOption": ["captions", "chapters", "descriptions", "metadata", "subtitles"] }, 156 | "label": { "attribOption": [] }, 157 | "list": { "attribOption": [] }, 158 | "longdesc": { "attribOption": [] }, 159 | "loop": { "attribOption": [], "type": "flag" }, 160 | "low": { "attribOption": [] }, 161 | "manifest": { "attribOption": [] }, 162 | "max": { "attribOption": [] }, 163 | "maxlength": { "attribOption": [] }, 164 | "media": { "attribOption": ["screen", "tty", "tv", "projection", "handheld", "print", "aural", "braille", "embossed", "speech", "all", "width", 165 | "min-width", "max-width", "height", "min-height", "max-height", "device-width", "min-device-width", "max-device-width", 166 | "device-height", "min-device-height", "max-device-height", "orientation", "aspect-ratio", "min-aspect-ratio", 167 | "max-aspect-ratio", "device-aspect-ratio", "min-device-aspect-ratio", "max-device-aspect-ratio", "color", 168 | "min-color", "max-color", "color-index", "min-color-index", "max-color-index", "monochrome", "min-monochrome", 169 | "max-monochrome", "resolution", "min-resolution", "max-resolution", "scan", "grid"], 170 | "allowMultipleValues": "true" }, 171 | "mediagroup": { "attribOption": [] }, 172 | "method": { "attribOption": ["get", "post"] }, 173 | "min": { "attribOption": [] }, 174 | "multiple": { "attribOption": [], "type": "flag" }, 175 | "muted": { "attribOption": [], "type": "flag" }, 176 | "name": { "attribOption": [] }, 177 | "meta/name": { "attribOption": ["application-name", "author", "description", "format-detection", "generator", "keywords", "publisher", "referrer", "robots", "theme-color", "viewport"] }, 178 | "meta/property": { "attribOption": ["al:ios:url", "al:ios:app_store_id", "al:ios:app_name", "al:android:url", "al:android:app_name", "al:android:package", "al:web:url"] }, 179 | "novalidate": { "attribOption": [], "type": "flag" }, 180 | "open": { "attribOption": [], "type": "flag" }, 181 | "optimum": { "attribOption": [] }, 182 | "pattern": { "attribOption": [] }, 183 | "placeholder": { "attribOption": [] }, 184 | "poster": { "attribOption": [] }, 185 | "preload": { "attribOption": ["auto", "metadata", "none"] }, 186 | "pubdate": { "attribOption": [] }, 187 | "radiogroup": { "attribOption": [] }, 188 | "rel": { "attribOption": ["alternate", "author", "bookmark", "help", "license", "next", "nofollow", "noreferrer", "prefetch", 189 | "prev", "search", "sidebar", "tag", "external"] }, 190 | "link/rel": { "attribOption": ["alternate", "author", "canonical", "dns-prefetch", "help", "icon", "import", "license", "next", "pingback", "prefetch", "prev", "profile", "search", "shortlink", 191 | "sidebar", "stylesheet", "tag"] }, 192 | "readonly": { "attribOption": [], "type": "flag" }, 193 | "required": { "attribOption": [], "type": "flag" }, 194 | "reversed": { "attribOption": [], "type": "flag" }, 195 | "rows": { "attribOption": [] }, 196 | "rowspan": { "attribOption": [] }, 197 | "sandbox": { "attribOption": ["allow-forms", "allow-same-origin", "allow-scripts", "allow-top-navigation"] }, 198 | "seamless": { "attribOption": [], "type": "flag" }, 199 | "selected": { "attribOption": [], "type": "flag" }, 200 | "scope": { "attribOption": ["col", "colgroup", "row", "rowgroup"] }, 201 | "scoped": { "attribOption": [], "type": "boolean" }, 202 | "scrollamount": { "attribOption": [] }, 203 | "scrolldelay": { "attribOption": [] }, 204 | "shape": { "attribOption": ["circle", "default", "poly","rect"] }, 205 | "size": { "attribOption": [] }, 206 | "sizes": { "attribOption": ["any"] }, 207 | "span": { "attribOption": [] }, 208 | "src": { "attribOption": [] }, 209 | "srcdoc": { "attribOption": [] }, 210 | "srcset": { "attribOption": [] }, 211 | "srclang": { "attribOption": [] }, 212 | "standby": { "attribOption": [] }, 213 | "start": { "attribOption": [] }, 214 | "step": { "attribOption": [] }, 215 | "target": { "attribOption": ["_blank", "_parent", "_self", "_top"] }, 216 | "truespeed": { "attribOption": [], "type": "flag" }, 217 | "type": { "attribOption": [] }, 218 | "button/type": { "attribOption": ["button", "reset", "submit"] }, 219 | "command/type": { "attribOption": ["command", "checkbox", "radio"] }, 220 | "link/type": { "attribOption": ["text/css"] }, 221 | "menu/type": { "attribOption": ["context", "list", "toolbar"] }, 222 | "ol/type": { "attribOption": ["1", "a", "A", "i", "I"] }, 223 | "script/type": { "attribOption": ["application/ld+json", "text/javascript", "text/ecmascript", "text/jscript", "text/livescript", "text/tcl", "text/x-javascript", "text/x-ecmascript", 224 | "application/x-javascript", "application/x-ecmascript", "application/javascript", "application/ecmascript"] }, 225 | "style/type": { "attribOption": ["text/css"] }, 226 | "input/type": { "attribOption": ["button", "checkbox", "color", "date", "datetime", "datetime-local", "email", "file", "hidden", "image", "month", 227 | "number", "password", "radio", "range", "reset", "search", "submit", "tel", "text", "time", "url", "week"] }, 228 | "usemap": { "attribOption": [] }, 229 | "value": { "attribOption": [] }, 230 | "vspace": { "attribOption": [] }, 231 | "width": { "attribOption": [] }, 232 | "wrap": { "attribOption": ["hard", "soft"] }, 233 | "xml:lang": { "attribOption": [] }, 234 | "xmlns": { "attribOption": [] }, 235 | "ng-app": { "attribOption": [] }, 236 | "ng-blur": { "attribOption": [] }, 237 | "ng-copy": { "attribOption": [] }, 238 | "ng-cut": { "attribOption": [] }, 239 | "ng-disabled": { "attribOption": [] }, 240 | "ng-list": { "attribOption": [] }, 241 | "ng-model": { "attribOption": [] }, 242 | "ng-open": { "attribOption": [] }, 243 | "ng-href": { "attribOption": [] }, 244 | "ng-controller": { "attribOption": [] , "global": "true" }, 245 | "ng-repeat": { "attribOption": [] , "global": "true" }, 246 | "ng-if": { "attribOption": [] , "global": "true" }, 247 | "ng-bind": { "attribOption": [] , "global": "true" }, 248 | "ng-bind-html": { "attribOption": [] , "global": "true" }, 249 | "ng-bind-template": { "attribOption": [] , "global": "true" }, 250 | "ng-change": { "attribOption": [] , "global": "true" }, 251 | "ng-checked": { "attribOption": [] , "global": "true" }, 252 | "ng-class": { "attribOption": [] , "global": "true" }, 253 | "ng-class-even": { "attribOption": [] , "global": "true" }, 254 | "ng-class-odd": { "attribOption": [] , "global": "true" }, 255 | "ng-click": { "attribOption": [] , "global": "true" }, 256 | "ng-cloak": { "attribOption": [] , "global": "true" , "type": "flag" }, 257 | "ng-dblclick": { "attribOption": [] , "global": "true" }, 258 | "ng-form": { "attribOption": [] , "global": "true" }, 259 | "ng-hide": { "attribOption": [] , "global": "true" }, 260 | "ng-init": { "attribOption": [] , "global": "true" }, 261 | "ng-keydown": { "attribOption": [] , "global": "true" }, 262 | "ng-keypress": { "attribOption": [] , "global": "true" }, 263 | "ng-keyup": { "attribOption": [] , "global": "true" }, 264 | "ng-mousedown": { "attribOption": [] , "global": "true" }, 265 | "ng-mouseenter": { "attribOption": [] , "global": "true" }, 266 | "ng-mouseleave": { "attribOption": [] , "global": "true" }, 267 | "ng-mousemove": { "attribOption": [] , "global": "true" }, 268 | "ng-mouseover": { "attribOption": [] , "global": "true" }, 269 | "ng-mouseup": { "attribOption": [] , "global": "true" }, 270 | "ng-non-bindable": { "attribOption": [] , "global": "true" }, 271 | "ng-repeat": { "attribOption": [] , "global": "true" }, 272 | "ng-show": { "attribOption": [] , "global": "true" }, 273 | "ng-style": { "attribOption": [] , "global": "true" }, 274 | "ng-switch": { "attribOption": [] , "global": "true" }, 275 | "ng-include": { "attribOption": [] , "global": "true" }, 276 | "ng-transclude": { "attribOption": [] , "global": "true" }, 277 | "ng-pluralize": { "attribOption": [] , "global": "true" }, 278 | "ng-view": { "attribOption": [] , "global": "true" }, 279 | "ng-swipe-left": { "attribOption": [] , "global": "true" }, 280 | "ng-swipe-right": { "attribOption": [] , "global": "true" }, 281 | "data-ng-app": { "attribOption": [] }, 282 | "data-ng-blur": { "attribOption": [] }, 283 | "data-ng-copy": { "attribOption": [] }, 284 | "data-ng-cut": { "attribOption": [] }, 285 | "data-ng-disabled": { "attribOption": [] }, 286 | "data-ng-list": { "attribOption": [] }, 287 | "data-ng-model": { "attribOption": [] }, 288 | "data-ng-open": { "attribOption": [] }, 289 | "data-ng-href": { "attribOption": [] }, 290 | "data-ng-controller": { "attribOption": [] , "global": "true" }, 291 | "data-ng-repeat": { "attribOption": [] , "global": "true" }, 292 | "data-ng-if": { "attribOption": [] , "global": "true" }, 293 | "data-ng-bind": { "attribOption": [] , "global": "true" }, 294 | "data-ng-bind-html": { "attribOption": [] , "global": "true" }, 295 | "data-ng-bind-template": { "attribOption": [] , "global": "true" }, 296 | "data-ng-change": { "attribOption": [] , "global": "true" }, 297 | "data-ng-checked": { "attribOption": [] , "global": "true" }, 298 | "data-ng-class": { "attribOption": [] , "global": "true" }, 299 | "data-ng-class-even": { "attribOption": [] , "global": "true" }, 300 | "data-ng-class-odd": { "attribOption": [] , "global": "true" }, 301 | "data-ng-click": { "attribOption": [] , "global": "true" }, 302 | "data-ng-cloak": { "attribOption": [] , "global": "true" , "type": "flag" }, 303 | "data-ng-dblclick": { "attribOption": [] , "global": "true" }, 304 | "data-ng-hide": { "attribOption": [] , "global": "true" }, 305 | "data-ng-init": { "attribOption": [] , "global": "true" }, 306 | "data-ng-keydown": { "attribOption": [] , "global": "true" }, 307 | "data-ng-keypress": { "attribOption": [] , "global": "true" }, 308 | "data-ng-keyup": { "attribOption": [] , "global": "true" }, 309 | "data-ng-mousedown": { "attribOption": [] , "global": "true" }, 310 | "data-ng-mouseenter": { "attribOption": [] , "global": "true" }, 311 | "data-ng-mouseleave": { "attribOption": [] , "global": "true" }, 312 | "data-ng-mousemove": { "attribOption": [] , "global": "true" }, 313 | "data-ng-mouseover": { "attribOption": [] , "global": "true" }, 314 | "data-ng-mouseup": { "attribOption": [] , "global": "true" }, 315 | "data-ng-non-bindable": { "attribOption": [] , "global": "true" }, 316 | "data-ng-repeat": { "attribOption": [] , "global": "true" }, 317 | "data-ng-show": { "attribOption": [] , "global": "true" }, 318 | "data-ng-style": { "attribOption": [] , "global": "true" }, 319 | "data-ng-switch": { "attribOption": [] , "global": "true" }, 320 | "data-ng-include": { "attribOption": [] , "global": "true" }, 321 | "data-ng-transclude": { "attribOption": [] , "global": "true" }, 322 | "data-ng-pluralize": { "attribOption": [] , "global": "true" }, 323 | "data-ng-view": { "attribOption": [] , "global": "true" }, 324 | "data-ng-swipe-left": { "attribOption": [] , "global": "true" }, 325 | "data-ng-swipe-right": { "attribOption": [] , "global": "true" } 326 | } 327 | -------------------------------------------------------------------------------- /HtmlTags.json: -------------------------------------------------------------------------------- 1 | { 2 | "a": { "attributes": ["href", "hreflang", "media", "rel", "target", "type", "ng-blur", "ng-copy", "ng-cut", "data-ng-blur", "data-ng-copy", "data-ng-cut", "ng-href", "data-ng-href"] }, 3 | "abbr": { "attributes": [] }, 4 | "acronym": { "attributes": [] }, 5 | "address": { "attributes": [] }, 6 | "area": { "attributes": ["alt", "coords", "href", "hreflang", "media", "rel", "shape", "target", "type"] }, 7 | "article": { "attributes": [] }, 8 | "aside": { "attributes": [] }, 9 | "audio": { "attributes": ["autoplay", "buffered", "controls", "loop", "mediagroup", "muted", "played", "preload", "src"] }, 10 | "b": { "attributes": [] }, 11 | "base": { "attributes": ["href", "target"] }, 12 | "bdi": { "attributes": [] }, 13 | "bdo": { "attributes": [] }, 14 | "big": { "attributes": [] }, 15 | "blockquote": { "attributes": ["cite"] }, 16 | "body": { "attributes": ["onafterprint", "onbeforeprint", "onbeforeunload", "onhashchange", "onmessage", "onoffline", "ononline", 17 | "onpagehide", "onpageshow", "onpopstate", "onredo", "onresize", "onstorage", "onundo", "onunload", "ng-app", "ng-controller", "ng-csp", "data-ng-app", "data-ng-controller", "data-ng-csp"] }, 18 | "br": { "attributes": [] }, 19 | "button": { "attributes": ["autofocus", "disabled", "form", "formaction", "formenctype", "formmethod", "formnovalidate", "formtarget", 20 | "name", "type", "value"] }, 21 | "canvas": { "attributes": ["height", "width"] }, 22 | "caption": { "attributes": [] }, 23 | "center": { "attributes": [] }, 24 | "cite": { "attributes": [] }, 25 | "code": { "attributes": [] }, 26 | "col": { "attributes": ["span"] }, 27 | "colgroup": { "attributes": ["span"] }, 28 | "command": { "attributes": ["checked", "disabled", "icon", "label", "radiogroup", "type"] }, 29 | "content": { "attributes": [] }, 30 | "datalist": { "attributes": [] }, 31 | "dd": { "attributes": [] }, 32 | "del": { "attributes": ["cite", "datetime"] }, 33 | "details": { "attributes": ["open", "ng-open", "data-ng-open"] }, 34 | "dfn": { "attributes": [] }, 35 | "dialog": { "attributes": ["open", "ng-open", "data-ng-open"] }, 36 | "div": { "attributes": ["ng-app"] }, 37 | "dl": { "attributes": [] }, 38 | "dt": { "attributes": [] }, 39 | "em": { "attributes": [] }, 40 | "embed": { "attributes": ["height", "src", "type", "width"] }, 41 | "fieldset": { "attributes": ["disabled", "form", "name"] }, 42 | "figcaption": { "attributes": [] }, 43 | "figure": { "attributes": [] }, 44 | "footer": { "attributes": [] }, 45 | "form": { "attributes": ["accept-charset", "action", "autocomplete", "enctype", "method", "name", "novalidate", "target", "ng-submit", "data-ng-submit"] }, 46 | "frame": { "attributes": ["frameborder", "name", "scrolling", "src"] }, 47 | "frameset": { "attributes": ["rows"] }, 48 | "h1": { "attributes": [] }, 49 | "h2": { "attributes": [] }, 50 | "h3": { "attributes": [] }, 51 | "h4": { "attributes": [] }, 52 | "h5": { "attributes": [] }, 53 | "h6": { "attributes": [] }, 54 | "head": { "attributes": [] }, 55 | "header": { "attributes": [] }, 56 | "hgroup": { "attributes": [] }, 57 | "hr": { "attributes": [] }, 58 | "html": { "attributes": ["manifest", "xml:lang", "xmlns", "ng-app", "ng-controller", "ng-csp", "data-ng-app", "data-ng-controller", "data-ng-csp"] }, 59 | "i": { "attributes": [] }, 60 | "iframe": { "attributes": ["frameborder", "height", "name", "sandbox", "scrolling", "seamless", "src", "srcdoc", "width"] }, 61 | "ilayer": { "attributes": [] }, 62 | "img": { "attributes": ["alt", "height", "ismap", "longdesc", "src", "srcset", "usemap", "width", "ng-src", "ng-srcset", "data-ng-src", "data-ng-srcset"] }, 63 | "input": { "attributes": ["accept", "alt", "autocomplete", "autocorrect", "autofocus", "checked", "dirname", "disabled", "form", "formaction", "formenctype", "formmethod", 64 | "formnovalidate", "formtarget", "height", "inputmode", "list", "max", "maxlength", "min", "multiple", "name", "pattern", "placeholder", "readonly", 65 | "required", "size", "src", "step", "type", "value", "width", "ng-required", "ng-minlength", "ng-maxlength", "ng-pattern", "ng-change", "ng-trim", "ng-value", "ng-disabled", "ng-blur", "ng-copy", "ng-cut", "ng-model", "ng-list", "ng-readonly", "ng-value", "data-ng-required", "data-ng-minlength", "data-ng-maxlength", "data-ng-pattern", "data-ng-change", "data-ng-trim", "data-ng-value", "data-ng-disabled", "data-ng-blur", "data-ng-copy", "data-ng-cut", "data-ng-model", "data-ng-list", "data-ng-readonly", "data-ng-value"] }, 66 | "ins": { "attributes": ["cite", "datetime"] }, 67 | "kbd": { "attributes": [] }, 68 | "keygen": { "attributes": ["autofocus", "challenge", "disabled", "form", "keytype", "name"] }, 69 | "label": { "attributes": ["for", "form"] }, 70 | "legend": { "attributes": [] }, 71 | "li": { "attributes": ["value"] }, 72 | "link": { "attributes": ["disabled", "href", "hreflang", "media", "rel", "sizes", "type"] }, 73 | "main": { "attributes": [] }, 74 | "map": { "attributes": ["name"] }, 75 | "mark": { "attributes": [] }, 76 | "marquee": { "attributes": ["align", "behavior", "bgcolor", "direction", "height", "hspace", "loop", "scrollamount", "scrolldelay", "truespeed", "vspace", "width"] }, 77 | "menu": { "attributes": ["label", "type"] }, 78 | "meta": { "attributes": ["charset", "content", "http-equiv", "name", "property"] }, 79 | "meter": { "attributes": ["form", "high", "low", "max", "min", "optimum", "value"] }, 80 | "nav": { "attributes": [] }, 81 | "noscript": { "attributes": [] }, 82 | "object": { "attributes": ["archive", "codebase", "codetype", "data", "declare", "form", "height", "name", "standby", "type", "usemap", "width"] }, 83 | "ol": { "attributes": ["reversed", "start", "type"] }, 84 | "optgroup": { "attributes": ["disabled", "label"] }, 85 | "option": { "attributes": ["disabled", "label", "selected", "value", "ng-selected", "data-ng-selected"] }, 86 | "output": { "attributes": ["for", "form", "name"] }, 87 | "p": { "attributes": [] }, 88 | "param": { "attributes": ["name", "value"] }, 89 | "picture": { "attributes": [] }, 90 | "pre": { "attributes": [] }, 91 | "progress": { "attributes": ["form", "max", "value"] }, 92 | "q": { "attributes": ["cite"] }, 93 | "rp": { "attributes": [] }, 94 | "rt": { "attributes": [] }, 95 | "ruby": { "attributes": [] }, 96 | "samp": { "attributes": [] }, 97 | "script": { "attributes": ["async", "charset", "defer", "src", "type"] }, 98 | "section": { "attributes": [] }, 99 | "select": { "attributes": ["autofocus", "disabled", "form", "multiple", "name", "required", "size", "ng-blur", "ng-copy", "ng-cut", "ng-model", "ng-options", "data-ng-blur", "data-ng-copy", "data-ng-cut", "data-ng-model", "data-ng-options"] }, 100 | "small": { "attributes": [] }, 101 | "source": { "attributes": ["media", "sizes", "src", "type", "srcset"] }, 102 | "span": { "attributes": [] }, 103 | "strong": { "attributes": [] }, 104 | "style": { "attributes": ["disabled", "media", "scoped", "type"] }, 105 | "sub": { "attributes": [] }, 106 | "summary": { "attributes": [] }, 107 | "sup": { "attributes": [] }, 108 | "table": { "attributes": ["border", "cellpadding", "cellspacing", "height", "width"] }, 109 | "tbody": { "attributes": [] }, 110 | "td": { "attributes": ["colspan", "headers", "rowspan"] }, 111 | "template": { "attributes": [] }, 112 | "textarea": { "attributes": ["autocomplete", "autofocus", "cols", "dirname", "disabled", "form", "label", "maxlength", "name", "placeholder", "readonly", "required", "rows", "spellcheck", "wrap", "ng-blur", "ng-copy", "ng-cut", "ng-model", "ng-list", "ng-readonly", "ng-value", "data-ng-blur", "data-ng-copy", "data-ng-cut", "data-ng-model", "data-ng-list", "data-ng-readonly", "data-ng-value"] }, 113 | "tfoot": { "attributes": [] }, 114 | "th": { "attributes": ["colspan", "headers", "rowspan", "scope"] }, 115 | "thead": { "attributes": [] }, 116 | "time": { "attributes": ["datetime", "pubdate"] }, 117 | "title": { "attributes": [] }, 118 | "tr": { "attributes": [] }, 119 | "track": { "attributes": ["default", "kind", "label", "src", "srclang"] }, 120 | "tt": { "attributes": [] }, 121 | "ul": { "attributes": [] }, 122 | "var": { "attributes": [] }, 123 | "video": { "attributes": ["autoplay", "buffered", "controls", "crossorigin", "height", "loop", "mediagroup", "muted", "poster", "preload", "src", "width"] }, 124 | "wbr": { "attributes": [] }, 125 | "ng-pluralize": { "attributes": ["count", "when", "offset"] }, 126 | "ng-transclude": { "attributes": [] }, 127 | "ng-include": { "attributes": ["src"] }, 128 | "ng-view": { "attributes": [] } 129 | } 130 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Sirajuddin Choudhary 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | 24 | The MIT License (MIT) 25 | 26 | Copyright (c) 2014 C. Oliff 27 | 28 | Permission is hereby granted, free of charge, to any person obtaining a copy 29 | of this software and associated documentation files (the "Software"), to deal 30 | in the Software without restriction, including without limitation the rights 31 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 32 | copies of the Software, and to permit persons to whom the Software is 33 | furnished to do so, subject to the following conditions: 34 | 35 | The above copyright notice and this permission notice shall be included in all 36 | copies or substantial portions of the Software. 37 | 38 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 39 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 40 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 41 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 42 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 43 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 44 | SOFTWARE. 45 | 46 | 47 | Copyright (c) 2012 Adobe Systems Incorporated. All rights reserved. 48 | 49 | Permission is hereby granted, free of charge, to any person obtaining a 50 | copy of this software and associated documentation files (the "Software"), 51 | to deal in the Software without restriction, including without limitation 52 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 53 | and/or sell copies of the Software, and to permit persons to whom the 54 | Software is furnished to do so, subject to the following conditions: 55 | 56 | The above copyright notice and this permission notice shall be included in 57 | all copies or substantial portions of the Software. 58 | 59 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 60 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 61 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 62 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 63 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 64 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 65 | DEALINGS IN THE SOFTWARE. 66 | 67 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Brackets-AngularJS-CodeHints 2 | ============================ 3 | 4 | Extend Brackets HTML code hints and [coliff](https://github.com/coliff)'s [Brackets-HTML5CodeHints](https://github.com/coliff/Brackets-HTML5CodeHints) with AngularJS elements like ng-include, ng-view and attributes such as ng-class, ng-controller, ng-app. 5 | 6 | ![Angular attributes](https://raw.githubusercontent.com/sirajc/Brackets-AngularJS-CodeHints/gh-pages/BracketsAngularJs1.png) 7 | 8 | ![Angular Elements](https://raw.githubusercontent.com/sirajc/Brackets-AngularJS-CodeHints/gh-pages/BracketsAngularJs2.png) 9 | 10 | Feel free to fork this repo and add more attributes, Create Pull Requests or Issues on this Repo 11 | 12 | Thanks [coliff](https://github.com/coliff) for inspiration 13 | 14 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 C Oliff 3 | */ 4 | 5 | 6 | /*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */ 7 | /*global define, brackets, $ */ 8 | 9 | define(function (require, exports, module) { 10 | "use strict"; 11 | 12 | // Load dependent modules 13 | var AppInit = brackets.getModule("utils/AppInit"), 14 | CodeHintManager = brackets.getModule("editor/CodeHintManager"), 15 | HTMLUtils = brackets.getModule("language/HTMLUtils"), 16 | HTMLTags = require("text!HtmlTags.json"), 17 | HTMLAttributes = require("text!HtmlAttributes.json"), 18 | tags, 19 | attributes; 20 | 21 | /** 22 | * @constructor 23 | */ 24 | function TagHints() { 25 | this.exclusion = null; 26 | } 27 | 28 | /** 29 | * Check whether the exclusion is still the same as text after the cursor. 30 | * If not, reset it to null. 31 | */ 32 | TagHints.prototype.updateExclusion = function () { 33 | var textAfterCursor; 34 | if (this.exclusion && this.tagInfo) { 35 | textAfterCursor = this.tagInfo.tagName.substr(this.tagInfo.position.offset); 36 | if (!CodeHintManager.hasValidExclusion(this.exclusion, textAfterCursor)) { 37 | this.exclusion = null; 38 | } 39 | } 40 | }; 41 | 42 | /** 43 | * Determines whether HTML tag hints are available in the current editor 44 | * context. 45 | * 46 | * @param {Editor} editor 47 | * A non-null editor object for the active window. 48 | * 49 | * @param {string} implicitChar 50 | * Either null, if the hinting request was explicit, or a single character 51 | * that represents the last insertion and that indicates an implicit 52 | * hinting request. 53 | * 54 | * @return {boolean} 55 | * Determines whether the current provider is able to provide hints for 56 | * the given editor context and, in case implicitChar is non- null, 57 | * whether it is appropriate to do so. 58 | */ 59 | TagHints.prototype.hasHints = function (editor, implicitChar) { 60 | var pos = editor.getCursorPos(); 61 | 62 | this.tagInfo = HTMLUtils.getTagInfo(editor, pos); 63 | this.editor = editor; 64 | if (implicitChar === null) { 65 | if (this.tagInfo.position.tokenType === HTMLUtils.TAG_NAME) { 66 | if (this.tagInfo.position.offset >= 0) { 67 | if (this.tagInfo.position.offset === 0) { 68 | this.exclusion = this.tagInfo.tagName; 69 | } else { 70 | this.updateExclusion(); 71 | } 72 | return true; 73 | } 74 | } 75 | return false; 76 | } else { 77 | if (implicitChar === "<") { 78 | this.exclusion = this.tagInfo.tagName; 79 | return true; 80 | } 81 | return false; 82 | } 83 | }; 84 | 85 | /** 86 | * Returns a list of availble HTML tag hints if possible for the current 87 | * editor context. 88 | * 89 | * @return {jQuery.Deferred|{ 90 | * hints: Array., 91 | * match: string, 92 | * selectInitial: boolean, 93 | * handleWideResults: boolean}} 94 | * Null if the provider wishes to end the hinting session. Otherwise, a 95 | * response object that provides: 96 | * 1. a sorted array hints that consists of strings 97 | * 2. a string match that is used by the manager to emphasize matching 98 | * substrings when rendering the hint list 99 | * 3. a boolean that indicates whether the first result, if one exists, 100 | * should be selected by default in the hint list window. 101 | * 4. handleWideResults, a boolean (or undefined) that indicates whether 102 | * to allow result string to stretch width of display. 103 | */ 104 | TagHints.prototype.getHints = function (implicitChar) { 105 | var query, 106 | result; 107 | 108 | this.tagInfo = HTMLUtils.getTagInfo(this.editor, this.editor.getCursorPos()); 109 | if (this.tagInfo.position.tokenType === HTMLUtils.TAG_NAME) { 110 | if (this.tagInfo.position.offset >= 0) { 111 | this.updateExclusion(); 112 | query = this.tagInfo.tagName.slice(0, this.tagInfo.position.offset); 113 | result = $.map(tags, function (value, key) { 114 | if (key.indexOf(query) === 0) { 115 | return key; 116 | } 117 | }).sort(); 118 | 119 | return { 120 | hints: result, 121 | match: query, 122 | selectInitial: true, 123 | handleWideResults: false 124 | }; 125 | } 126 | } 127 | 128 | return null; 129 | }; 130 | 131 | /** 132 | * Inserts a given HTML tag hint into the current editor context. 133 | * 134 | * @param {string} hint 135 | * The hint to be inserted into the editor context. 136 | * 137 | * @return {boolean} 138 | * Indicates whether the manager should follow hint insertion with an 139 | * additional explicit hint request. 140 | */ 141 | TagHints.prototype.insertHint = function (completion) { 142 | var start = {line: -1, ch: -1}, 143 | end = {line: -1, ch: -1}, 144 | cursor = this.editor.getCursorPos(), 145 | charCount = 0; 146 | 147 | if (this.tagInfo.position.tokenType === HTMLUtils.TAG_NAME) { 148 | var textAfterCursor = this.tagInfo.tagName.substr(this.tagInfo.position.offset); 149 | if (CodeHintManager.hasValidExclusion(this.exclusion, textAfterCursor)) { 150 | charCount = this.tagInfo.position.offset; 151 | } else { 152 | charCount = this.tagInfo.tagName.length; 153 | } 154 | } 155 | 156 | end.line = start.line = cursor.line; 157 | start.ch = cursor.ch - this.tagInfo.position.offset; 158 | end.ch = start.ch + charCount; 159 | 160 | if (this.exclusion || completion !== this.tagInfo.tagName) { 161 | if (start.ch !== end.ch) { 162 | this.editor.document.replaceRange(completion, start, end); 163 | } else { 164 | this.editor.document.replaceRange(completion, start); 165 | } 166 | this.exclusion = null; 167 | } 168 | 169 | return false; 170 | }; 171 | 172 | /** 173 | * @constructor 174 | */ 175 | function AttrHints() { 176 | this.globalAttributes = this.readGlobalAttrHints(); 177 | this.cachedHints = null; 178 | this.exclusion = ""; 179 | } 180 | 181 | /** 182 | * @private 183 | * Parse the code hints from JSON data and extract all hints from property names. 184 | * @return {!Array.} An array of code hints read from the JSON data source. 185 | */ 186 | AttrHints.prototype.readGlobalAttrHints = function () { 187 | return $.map(attributes, function (value, key) { 188 | if (value.global === "true") { 189 | return key; 190 | } 191 | }); 192 | }; 193 | 194 | /** 195 | * Helper function that determines the possible value hints for a given html tag/attribute name pair 196 | * 197 | * @param {{queryStr: string}} query 198 | * The current query 199 | * 200 | * @param {string} tagName 201 | * HTML tag name 202 | * 203 | * @param {string} attrName 204 | * HTML attribute name 205 | * 206 | * @return {{hints: Array.|$.Deferred, sortFunc: ?Function}} 207 | * The (possibly deferred) hints and the sort function to use on thise hints. 208 | */ 209 | AttrHints.prototype._getValueHintsForAttr = function (query, tagName, attrName) { 210 | // We look up attribute values with tagName plus a slash and attrName first. 211 | // If the lookup fails, then we fall back to look up with attrName only. Most 212 | // of the attributes in JSON are using attribute name only as their properties, 213 | // but in some cases like "type" attribute, we have different properties like 214 | // "script/type", "link/type" and "button/type". 215 | var hints = [], 216 | sortFunc = null; 217 | 218 | var tagPlusAttr = tagName + "/" + attrName, 219 | attrInfo = attributes[tagPlusAttr] || attributes[attrName]; 220 | 221 | if (attrInfo) { 222 | if (attrInfo.type === "boolean") { 223 | hints = ["false", "true"]; 224 | } else if (attrInfo.attribOption) { 225 | hints = attrInfo.attribOption; 226 | } 227 | } 228 | 229 | return { hints: hints, sortFunc: sortFunc }; 230 | }; 231 | 232 | /** 233 | * Check whether the exclusion is still the same as text after the cursor. 234 | * If not, reset it to null. 235 | * 236 | * @param {boolean} attrNameOnly 237 | * true to indicate that we update the exclusion only if the cursor is inside an attribute name context. 238 | * Otherwise, we also update exclusion for attribute value context. 239 | */ 240 | AttrHints.prototype.updateExclusion = function (attrNameOnly) { 241 | if (this.exclusion && this.tagInfo) { 242 | var tokenType = this.tagInfo.position.tokenType, 243 | offset = this.tagInfo.position.offset, 244 | textAfterCursor; 245 | 246 | if (tokenType === HTMLUtils.ATTR_NAME) { 247 | textAfterCursor = this.tagInfo.attr.name.substr(offset); 248 | } else if (!attrNameOnly && tokenType === HTMLUtils.ATTR_VALUE) { 249 | textAfterCursor = this.tagInfo.attr.value.substr(offset); 250 | } 251 | if (!CodeHintManager.hasValidExclusion(this.exclusion, textAfterCursor)) { 252 | this.exclusion = null; 253 | } 254 | } 255 | }; 256 | 257 | /** 258 | * Determines whether HTML attribute hints are available in the current 259 | * editor context. 260 | * 261 | * @param {Editor} editor 262 | * A non-null editor object for the active window. 263 | * 264 | * @param {string} implicitChar 265 | * Either null, if the hinting request was explicit, or a single character 266 | * that represents the last insertion and that indicates an implicit 267 | * hinting request. 268 | * 269 | * @return {boolean} 270 | * Determines whether the current provider is able to provide hints for 271 | * the given editor context and, in case implicitChar is non-null, 272 | * whether it is appropriate to do so. 273 | */ 274 | AttrHints.prototype.hasHints = function (editor, implicitChar) { 275 | var pos = editor.getCursorPos(), 276 | tokenType, 277 | offset, 278 | query; 279 | 280 | this.editor = editor; 281 | this.tagInfo = HTMLUtils.getTagInfo(editor, pos); 282 | tokenType = this.tagInfo.position.tokenType; 283 | offset = this.tagInfo.position.offset; 284 | if (implicitChar === null) { 285 | query = null; 286 | 287 | if (tokenType === HTMLUtils.ATTR_NAME) { 288 | if (offset >= 0) { 289 | query = this.tagInfo.attr.name.slice(0, offset); 290 | } 291 | } else if (tokenType === HTMLUtils.ATTR_VALUE) { 292 | if (this.tagInfo.position.offset >= 0) { 293 | query = this.tagInfo.attr.value.slice(0, offset); 294 | } else { 295 | // We get negative offset for a quoted attribute value with some leading whitespaces 296 | // as in = 0) { 324 | if (tokenType === HTMLUtils.ATTR_NAME && offset === 0) { 325 | this.exclusion = this.tagInfo.attr.name; 326 | } else { 327 | this.updateExclusion(false); 328 | } 329 | } 330 | 331 | return query !== null; 332 | } else { 333 | if (implicitChar === " " || implicitChar === "'" || 334 | implicitChar === "\"" || implicitChar === "=") { 335 | if (tokenType === HTMLUtils.ATTR_NAME) { 336 | this.exclusion = this.tagInfo.attr.name; 337 | } 338 | return true; 339 | } 340 | return false; 341 | } 342 | }; 343 | 344 | /** 345 | * Returns a list of availble HTML attribute hints if possible for the 346 | * current editor context. 347 | * 348 | * @return {jQuery.Deferred|{ 349 | * hints: Array., 350 | * match: string, 351 | * selectInitial: boolean, 352 | * handleWideResults: boolean}} 353 | * Null if the provider wishes to end the hinting session. Otherwise, a 354 | * response object that provides: 355 | * 1. a sorted array hints that consists of strings 356 | * 2. a string match that is used by the manager to emphasize matching 357 | * substrings when rendering the hint list 358 | * 3. a boolean that indicates whether the first result, if one exists, 359 | * should be selected by default in the hint list window. 360 | * 4. handleWideResults, a boolean (or undefined) that indicates whether 361 | * to allow result string to stretch width of display. 362 | */ 363 | AttrHints.prototype.getHints = function (implicitChar) { 364 | var cursor = this.editor.getCursorPos(), 365 | query = {queryStr: null}, 366 | tokenType, 367 | offset, 368 | result = []; 369 | 370 | this.tagInfo = HTMLUtils.getTagInfo(this.editor, cursor); 371 | tokenType = this.tagInfo.position.tokenType; 372 | offset = this.tagInfo.position.offset; 373 | if (tokenType === HTMLUtils.ATTR_NAME || tokenType === HTMLUtils.ATTR_VALUE) { 374 | query.tag = this.tagInfo.tagName; 375 | 376 | if (offset >= 0) { 377 | if (tokenType === HTMLUtils.ATTR_NAME) { 378 | query.queryStr = this.tagInfo.attr.name.slice(0, offset); 379 | } else { 380 | query.queryStr = this.tagInfo.attr.value.slice(0, offset); 381 | query.attrName = this.tagInfo.attr.name; 382 | } 383 | this.updateExclusion(false); 384 | } else if (tokenType === HTMLUtils.ATTR_VALUE) { 385 | // We get negative offset for a quoted attribute value with some leading whitespaces 386 | // as in =1.1" 15 | } 16 | } 17 | --------------------------------------------------------------------------------