Caret/js/ace/mode-html_completions.js

310 lines
9.6 KiB
JavaScript
Raw Normal View History

/* ***** BEGIN LICENSE BLOCK *****
* Distributed under the BSD license:
*
* Copyright (c) 2010, Ajax.org B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Ajax.org B.V. nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ***** END LICENSE BLOCK ***** */
ace.define('ace/mode/html_completions', ['require', 'exports', 'module' , 'ace/token_iterator'], function(require, exports, module) {
var TokenIterator = require("../token_iterator").TokenIterator;
var commonAttributes = [
"accesskey",
"class",
"contenteditable",
"contextmenu",
"dir",
"draggable",
"dropzone",
"hidden",
"id",
"lang",
"spellcheck",
"style",
"tabindex",
"title",
"translate"
];
var eventAttributes = [
"onabort",
"onblur",
"oncancel",
"oncanplay",
"oncanplaythrough",
"onchange",
"onclick",
"onclose",
"oncontextmenu",
"oncuechange",
"ondblclick",
"ondrag",
"ondragend",
"ondragenter",
"ondragleave",
"ondragover",
"ondragstart",
"ondrop",
"ondurationchange",
"onemptied",
"onended",
"onerror",
"onfocus",
"oninput",
"oninvalid",
"onkeydown",
"onkeypress",
"onkeyup",
"onload",
"onloadeddata",
"onloadedmetadata",
"onloadstart",
"onmousedown",
"onmousemove",
"onmouseout",
"onmouseover",
"onmouseup",
"onmousewheel",
"onpause",
"onplay",
"onplaying",
"onprogress",
"onratechange",
"onreset",
"onscroll",
"onseeked",
"onseeking",
"onselect",
"onshow",
"onstalled",
"onsubmit",
"onsuspend",
"ontimeupdate",
"onvolumechange",
"onwaiting"
];
var globalAttributes = commonAttributes.concat(eventAttributes);
var attributeMap = {
"html": ["manifest"],
"head": [],
"title": [],
"base": ["href", "target"],
"link": ["href", "hreflang", "rel", "media", "type", "sizes"],
"meta": ["http-equiv", "name", "content", "charset"],
"style": ["type", "media", "scoped"],
"script": ["charset", "type", "src", "defer", "async"],
"noscript": ["href"],
"body": ["onafterprint", "onbeforeprint", "onbeforeunload", "onhashchange", "onmessage", "onoffline", "onpopstate", "onredo", "onresize", "onstorage", "onundo", "onunload"],
"section": [],
"nav": [],
"article": ["pubdate"],
"aside": [],
"h1": [],
"h2": [],
"h3": [],
"h4": [],
"h5": [],
"h6": [],
"header": [],
"footer": [],
"address": [],
"main": [],
"p": [],
"hr": [],
"pre": [],
"blockquote": ["cite"],
"ol": ["start", "reversed"],
"ul": [],
"li": ["value"],
"dl": [],
"dt": [],
"dd": [],
"figure": [],
"figcaption": [],
"div": [],
"a": ["href", "target", "ping", "rel", "media", "hreflang", "type"],
"em": [],
"strong": [],
"small": [],
"s": [],
"cite": [],
"q": ["cite"],
"dfn": [],
"abbr": [],
"data": [],
"time": ["datetime"],
"code": [],
"var": [],
"samp": [],
"kbd": [],
"sub": [],
"sup": [],
"i": [],
"b": [],
"u": [],
"mark": [],
"ruby": [],
"rt": [],
"rp": [],
"bdi": [],
"bdo": [],
"span": [],
"br": [],
"wbr": [],
"ins": ["cite", "datetime"],
"del": ["cite", "datetime"],
"img": ["alt", "src", "height", "width", "usemap", "ismap"],
"iframe": ["name", "src", "height", "width", "sandbox", "seamless"],
"embed": ["src", "height", "width", "type"],
"object": ["param", "data", "type", "height" , "width", "usemap", "name", "form", "classid"],
"param": ["name", "value"],
"video": ["src", "autobuffer", "autoplay", "loop", "controls", "width", "height", "poster"],
"audio": ["src", "autobuffer", "autoplay", "loop", "controls"],
"source": ["src", "type", "media"],
"track": ["kind", "src", "srclang", "label", "default"],
"canvas": ["width", "height"],
"map": ["name"],
"area": ["shape", "coords", "href", "hreflang", "alt", "target", "media", "rel", "ping", "type"],
"svg": [],
"math": [],
"table": ["summary"],
"caption": [],
"colgroup": ["span"],
"col": ["span"],
"tbody": [],
"thead": [],
"tfoot": [],
"tr": [],
"td": ["headers", "rowspan", "colspan"],
"th": ["headers", "rowspan", "colspan", "scope"],
"form": ["accept-charset", "action", "autocomplete", "enctype", "method", "name", "novalidate", "target"],
"fieldset": ["disabled", "form", "name"],
"legend": [],
"label": ["form", "for"],
"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"],
"button": ["autofocus", "disabled", "form", "formaction", "formenctype", "formmethod", "formnovalidate", "formtarget", "name", "value", "type"],
"select": ["autofocus", "disabled", "form", "multiple", "name", "size"],
"datalist": [],
"optgroup": ["disabled", "label"],
"option": ["disabled", "selected", "label", "value"],
"textarea": ["autofocus", "disabled", "form", "maxlength", "name", "placeholder", "readonly", "required", "rows", "cols", "wrap"],
"keygen": ["autofocus", "challenge", "disabled", "form", "keytype", "name"],
"output": ["for", "form", "name"],
"progress": ["value", "max"],
"meter": ["value", "min", "max", "low", "high", "optimum"],
"details": ["open"],
"summary": [],
"command": ["type", "label", "icon", "disabled", "checked", "radiogroup", "command"],
"menu": ["type", "label"],
"dialog": ["open"]
};
var allElements = Object.keys(attributeMap);
function hasType(token, type) {
var tokenTypes = token.type.split('.');
return type.split('.').every(function(type){
return (tokenTypes.indexOf(type) !== -1);
});
}
function findTagName(session, pos) {
var iterator = new TokenIterator(session, pos.row, pos.column);
var token = iterator.getCurrentToken();
if (!token || !hasType(token, 'tag') && !(hasType(token, 'text') && token.value.match('/'))){
do {
token = iterator.stepBackward();
} while (token && (hasType(token, 'string') || hasType(token, 'operator') || hasType(token, 'attribute-name') || hasType(token, 'text')));
}
if (token && hasType(token, 'tag-name') && !iterator.stepBackward().value.match('/'))
return token.value;
}
var HtmlCompletions = function() {
};
(function() {
this.getCompletions = function(state, session, pos, prefix) {
var token = session.getTokenAt(pos.row, pos.column);
if (!token)
return [];
if (hasType(token, "tag-name") || (token.value == '<' && hasType(token, "text")))
return this.getTagCompletions(state, session, pos, prefix);
if (hasType(token, 'text') || hasType(token, 'attribute-name'))
return this.getAttributeCompetions(state, session, pos, prefix);
return [];
};
this.getTagCompletions = function(state, session, pos, prefix) {
var elements = allElements;
if (prefix) {
elements = elements.filter(function(element){
return element.indexOf(prefix) === 0;
});
}
return elements.map(function(element){
return {
value: element,
meta: "tag"
};
});
};
this.getAttributeCompetions = function(state, session, pos, prefix) {
var tagName = findTagName(session, pos);
if (!tagName)
return [];
var attributes = globalAttributes;
if (tagName in attributeMap) {
attributes = attributes.concat(attributeMap[tagName]);
}
if (prefix) {
attributes = attributes.filter(function(attribute){
return attribute.indexOf(prefix) === 0;
});
}
return attributes.map(function(attribute){
return {
caption: attribute,
snippet: attribute + '="$0"',
meta: "attribute"
};
});
};
}).call(HtmlCompletions.prototype);
exports.HtmlCompletions = HtmlCompletions;
});