From 73fb35e63c9d34e88deeb1df92a9880925559c05 Mon Sep 17 00:00:00 2001 From: Abram Adams Date: Wed, 22 Jan 2014 15:38:52 -0800 Subject: [PATCH] Added cfml behaviour with smart auto closing tags This adds the behaviours for ColdFusion Markup Language (CFML) back in with the addition of exceptions for auto-closing tags. --- lib/ace/mode/behaviour/coldfusion.js | 95 ++++++++++++++++++++++++++++ lib/ace/mode/coldfusion.js | 2 + 2 files changed, 97 insertions(+) create mode 100644 lib/ace/mode/behaviour/coldfusion.js diff --git a/lib/ace/mode/behaviour/coldfusion.js b/lib/ace/mode/behaviour/coldfusion.js new file mode 100644 index 00000000..02ebc270 --- /dev/null +++ b/lib/ace/mode/behaviour/coldfusion.js @@ -0,0 +1,95 @@ +/* ***** 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 ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var XmlBehaviour = require("../behaviour/xml").XmlBehaviour; +var CstyleBehaviour = require("./cstyle").CstyleBehaviour; +var TokenIterator = require("../../token_iterator").TokenIterator; +var voidElements = ['area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr']; + +function hasType(token, type) { + var hasType = true; + var typeList = token.type.split('.'); + var needleList = type.split('.'); + needleList.forEach(function(needle){ + if (typeList.indexOf(needle) == -1) { + hasType = false; + return false; + } + }); + return hasType; +} + +var CfmlBehaviour = function () { + + this.inherit(XmlBehaviour); // Get xml behaviour + + this.add("autoclosing", "insertion", function (state, action, editor, session, text) { + if (text == '>') { + var position = editor.getCursorPosition(); + var iterator = new TokenIterator(session, position.row, position.column); + var token = iterator.getCurrentToken(); + + if (token && hasType(token, 'meta.tag.name') && token.value.match(/cfelse|cfset|cfapplication|cfabort|cfdump|cfargument|cfproperty|cfinvokeargument|cfqueryparam|cfprocparam/gi) !== null) + return; + if (hasType(token, 'string') && iterator.getCurrentTokenColumn() + token.value.length > position.column) + return; + var atCursor = false; + if (!token || !hasType(token, 'meta.tag') && !(hasType(token, 'text') && token.value.match('/'))){ + do { + token = iterator.stepBackward(); + } while (token && (hasType(token, 'string') || hasType(token, 'keyword.operator') || hasType(token, 'entity.attribute-name') || hasType(token, 'text'))); + } else { + atCursor = true; + } + if (!token || !hasType(token, 'meta.tag-name') || iterator.stepBackward().value.match('/')) { + return + } + var element = token.value; + if (atCursor){ + var element = element.substring(0, position.column - token.start); + } + if (voidElements.indexOf(element) !== -1){ + return; + } + return { + text: '>' + '', + selection: [1, 1] + } + } + }); +} +oop.inherits(CfmlBehaviour, XmlBehaviour); + +exports.CfmlBehaviour = CfmlBehaviour; +}); diff --git a/lib/ace/mode/coldfusion.js b/lib/ace/mode/coldfusion.js index b188ae54..16527f26 100644 --- a/lib/ace/mode/coldfusion.js +++ b/lib/ace/mode/coldfusion.js @@ -37,11 +37,13 @@ var JavaScriptMode = require("./javascript").Mode; var CssMode = require("./css").Mode; var Tokenizer = require("../tokenizer").Tokenizer; var ColdfusionHighlightRules = require("./coldfusion_highlight_rules").ColdfusionHighlightRules; +var CfmlBehaviour = require("./behaviour/coldfusion").CfmlBehaviour; var Mode = function() { XmlMode.call(this); this.HighlightRules = ColdfusionHighlightRules; + this.$behaviour = new CfmlBehaviour(); this.createModeDelegates({ "js-": JavaScriptMode,