vendor/assets/javascripts/ace/mode-rhtml.js in ace-rails-ap-2.0.1 vs vendor/assets/javascripts/ace/mode-rhtml.js in ace-rails-ap-3.0.0

- old
+ new

@@ -1,219 +1,57 @@ -/* - * rhtml.js - * - * Copyright (C) 2009-11 by RStudio, Inc. - * - * The Initial Developer of the Original Code is - * Ajax.org B.V. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * 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 - */ +define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { +"use strict"; -define('ace/mode/rhtml', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/html', 'ace/tokenizer', 'ace/mode/rhtml_highlight_rules'], function(require, exports, module) { - - var oop = require("../lib/oop"); -var HtmlMode = require("./html").Mode; -var Tokenizer = require("../tokenizer").Tokenizer; +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; -var RHtmlHighlightRules = require("./rhtml_highlight_rules").RHtmlHighlightRules; +var DocCommentHighlightRules = function() { -var Mode = function(doc, session) { - this.$session = session; - this.HighlightRules = RHtmlHighlightRules; + this.$rules = { + "start" : [ { + token : "comment.doc.tag", + regex : "@[\\w\\d_]+" // TODO: fix email addresses + }, { + token : "comment.doc.tag", + regex : "\\bTODO\\b" + }, { + defaultToken : "comment.doc" + }] + }; }; -oop.inherits(Mode, HtmlMode); -(function() { - this.insertChunkInfo = { - value: "<!--begin.rcode\n\nend.rcode-->\n", - position: {row: 0, column: 15} - }; - - this.getLanguageMode = function(position) - { - return this.$session.getState(position.row).match(/^r-/) ? 'R' : 'HTML'; - }; +oop.inherits(DocCommentHighlightRules, TextHighlightRules); - this.$id = "ace/mode/rhtml"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); - -define('ace/mode/html', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text', 'ace/mode/javascript', 'ace/mode/css', 'ace/tokenizer', 'ace/mode/html_highlight_rules', 'ace/mode/behaviour/html', 'ace/mode/folding/html', 'ace/mode/html_completions'], function(require, exports, module) { - - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var JavaScriptMode = require("./javascript").Mode; -var CssMode = require("./css").Mode; -var Tokenizer = require("../tokenizer").Tokenizer; -var HtmlHighlightRules = require("./html_highlight_rules").HtmlHighlightRules; -var HtmlBehaviour = require("./behaviour/html").HtmlBehaviour; -var HtmlFoldMode = require("./folding/html").FoldMode; -var HtmlCompletions = require("./html_completions").HtmlCompletions; - -var Mode = function() { - this.HighlightRules = HtmlHighlightRules; - this.$behaviour = new HtmlBehaviour(); - this.$completer = new HtmlCompletions(); - - this.createModeDelegates({ - "js-": JavaScriptMode, - "css-": CssMode - }); - - this.foldingRules = new HtmlFoldMode(); +DocCommentHighlightRules.getStartRule = function(start) { + return { + token : "comment.doc", // doc comment + regex : "\\/\\*(?=\\*)", + next : start + }; }; -oop.inherits(Mode, TextMode); -(function() { - - this.blockComment = {start: "<!--", end: "-->"}; - - this.getNextLineIndent = function(state, line, tab) { - return this.$getIndent(line); +DocCommentHighlightRules.getEndRule = function (start) { + return { + token : "comment.doc", // closing comment + regex : "\\*\\/", + next : start }; - - this.checkOutdent = function(state, line, input) { - return false; - }; - - this.getCompletions = function(state, session, pos, prefix) { - return this.$completer.getCompletions(state, session, pos, prefix); - }; - - this.$id = "ace/mode/html"; -}).call(Mode.prototype); - -exports.Mode = Mode; -}); - -define('ace/mode/javascript', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text', 'ace/tokenizer', 'ace/mode/javascript_highlight_rules', 'ace/mode/matching_brace_outdent', 'ace/range', 'ace/worker/worker_client', 'ace/mode/behaviour/cstyle', 'ace/mode/folding/cstyle'], function(require, exports, module) { - - -var oop = require("../lib/oop"); -var TextMode = require("./text").Mode; -var Tokenizer = require("../tokenizer").Tokenizer; -var JavaScriptHighlightRules = require("./javascript_highlight_rules").JavaScriptHighlightRules; -var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var Range = require("../range").Range; -var WorkerClient = require("../worker/worker_client").WorkerClient; -var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; -var CStyleFoldMode = require("./folding/cstyle").FoldMode; - -var Mode = function() { - this.HighlightRules = JavaScriptHighlightRules; - - this.$outdent = new MatchingBraceOutdent(); - this.$behaviour = new CstyleBehaviour(); - this.foldingRules = new CStyleFoldMode(); }; -oop.inherits(Mode, TextMode); -(function() { - this.lineCommentStart = "//"; - this.blockComment = {start: "/*", end: "*/"}; +exports.DocCommentHighlightRules = DocCommentHighlightRules; - this.getNextLineIndent = function(state, line, tab) { - var indent = this.$getIndent(line); - - var tokenizedLine = this.getTokenizer().getLineTokens(line, state); - var tokens = tokenizedLine.tokens; - var endState = tokenizedLine.state; - - if (tokens.length && tokens[tokens.length-1].type == "comment") { - return indent; - } - - if (state == "start" || state == "no_regex") { - var match = line.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/); - if (match) { - indent += tab; - } - } else if (state == "doc-start") { - if (endState == "start" || endState == "no_regex") { - return ""; - } - var match = line.match(/^\s*(\/?)\*/); - if (match) { - if (match[1]) { - indent += " "; - } - indent += "* "; - } - } - - return indent; - }; - - this.checkOutdent = function(state, line, input) { - return this.$outdent.checkOutdent(line, input); - }; - - this.autoOutdent = function(state, doc, row) { - this.$outdent.autoOutdent(doc, row); - }; - - this.createWorker = function(session) { - var worker = new WorkerClient(["ace"], "ace/mode/javascript_worker", "JavaScriptWorker"); - worker.attachToDocument(session.getDocument()); - - worker.on("jslint", function(results) { - session.setAnnotations(results.data); - }); - - worker.on("terminate", function() { - session.clearAnnotations(); - }); - - return worker; - }; - - this.$id = "ace/mode/javascript"; -}).call(Mode.prototype); - -exports.Mode = Mode; }); -define('ace/mode/javascript_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/doc_comment_highlight_rules', 'ace/mode/text_highlight_rules'], function(require, exports, module) { +define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"], function(require, exports, module) { +"use strict"; - var oop = require("../lib/oop"); var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules; var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; -var JavaScriptHighlightRules = function() { +var JavaScriptHighlightRules = function(options) { var keywordMapper = this.createKeywordMapper({ "variable.language": "Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|" + // Constructors "Namespace|QName|XML|XMLList|" + // E4X "ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|" + @@ -335,35 +173,34 @@ regex : /(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/ }, { token : ["punctuation.operator", "support.constant"], regex : /(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/ }, { + token : ["support.constant"], + regex : /that\b/ + }, { token : ["storage.type", "punctuation.operator", "support.function.firebug"], - regex : /(console)(\.)(warn|info|log|error|time|timeEnd|assert)\b/ + regex : /(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/ }, { token : keywordMapper, regex : identifierRe }, { token : "keyword.operator", - regex : /--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/, + regex : /--|\+\+|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|[!$%&*+\-~\/^]=?/, next : "start" }, { token : "punctuation.operator", - regex : /\?|\:|\,|\;|\./, + regex : /[?:,;.]/, next : "start" }, { token : "paren.lparen", regex : /[\[({]/, next : "start" }, { token : "paren.rparen", regex : /[\])}]/ }, { - token : "keyword.operator", - regex : /\/=?/, - next : "start" - }, { token: "comment", regex: /^#!.*$/ } ], "start": [ @@ -419,11 +256,11 @@ defaultToken: "string.regexp" } ], "regex_character_class": [ { - token: "regexp.keyword.operator", + token: "regexp.charclass.keyword.operator", regex: "\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)" }, { token: "constant.language.escape", regex: "]", next: "regex" @@ -501,67 +338,63 @@ }, { defaultToken: "string" } ] }; - + + + if (!options || !options.noES6) { + this.$rules.no_regex.unshift({ + regex: "[{}]", onMatch: function(val, state, stack) { + this.next = val == "{" ? this.nextState : ""; + if (val == "{" && stack.length) { + stack.unshift("start", state); + return "paren"; + } + if (val == "}" && stack.length) { + stack.shift(); + this.next = stack.shift(); + if (this.next.indexOf("string") != -1) + return "paren.quasi.end"; + } + return val == "{" ? "paren.lparen" : "paren.rparen"; + }, + nextState: "start" + }, { + token : "string.quasi.start", + regex : /`/, + push : [{ + token : "constant.language.escape", + regex : escapedRe + }, { + token : "paren.quasi.start", + regex : /\${/, + push : "start" + }, { + token : "string.quasi.end", + regex : /`/, + next : "pop" + }, { + defaultToken: "string.quasi" + }] + }); + } + this.embedRules(DocCommentHighlightRules, "doc-", [ DocCommentHighlightRules.getEndRule("no_regex") ]); + + this.normalizeRules(); }; oop.inherits(JavaScriptHighlightRules, TextHighlightRules); exports.JavaScriptHighlightRules = JavaScriptHighlightRules; }); -define('ace/mode/doc_comment_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text_highlight_rules'], function(require, exports, module) { +define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"], function(require, exports, module) { +"use strict"; - -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; - -var DocCommentHighlightRules = function() { - - this.$rules = { - "start" : [ { - token : "comment.doc.tag", - regex : "@[\\w\\d_]+" // TODO: fix email addresses - }, { - token : "comment.doc.tag", - regex : "\\bTODO\\b" - }, { - defaultToken : "comment.doc" - }] - }; -}; - -oop.inherits(DocCommentHighlightRules, TextHighlightRules); - -DocCommentHighlightRules.getStartRule = function(start) { - return { - token : "comment.doc", // doc comment - regex : "\\/\\*(?=\\*)", - next : start - }; -}; - -DocCommentHighlightRules.getEndRule = function (start) { - return { - token : "comment.doc", // closing comment - regex : "\\*\\/", - next : start - }; -}; - - -exports.DocCommentHighlightRules = DocCommentHighlightRules; - -}); - -define('ace/mode/matching_brace_outdent', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) { - - var Range = require("../range").Range; var MatchingBraceOutdent = function() {}; (function() { @@ -595,100 +428,51 @@ }).call(MatchingBraceOutdent.prototype); exports.MatchingBraceOutdent = MatchingBraceOutdent; }); -define('ace/mode/behaviour/cstyle', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/behaviour', 'ace/token_iterator', 'ace/lib/lang'], function(require, exports, module) { +define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"], function(require, exports, module) { +"use strict"; - var oop = require("../../lib/oop"); var Behaviour = require("../behaviour").Behaviour; var TokenIterator = require("../../token_iterator").TokenIterator; var lang = require("../../lib/lang"); var SAFE_INSERT_IN_TOKENS = ["text", "paren.rparen", "punctuation.operator"]; var SAFE_INSERT_BEFORE_TOKENS = ["text", "paren.rparen", "punctuation.operator", "comment"]; - -var autoInsertedBrackets = 0; -var autoInsertedRow = -1; -var autoInsertedLineEnd = ""; -var maybeInsertedBrackets = 0; -var maybeInsertedRow = -1; -var maybeInsertedLineStart = ""; -var maybeInsertedLineEnd = ""; - -var CstyleBehaviour = function () { - - CstyleBehaviour.isSaneInsertion = function(editor, session) { - var cursor = editor.getCursorPosition(); - var iterator = new TokenIterator(session, cursor.row, cursor.column); - if (!this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) { - var iterator2 = new TokenIterator(session, cursor.row, cursor.column + 1); - if (!this.$matchTokenType(iterator2.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) - return false; - } - iterator.stepForward(); - return iterator.getCurrentTokenRow() !== cursor.row || - this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_BEFORE_TOKENS); +var context; +var contextCache = {} +var initContext = function(editor) { + var id = -1; + if (editor.multiSelect) { + id = editor.selection.id; + if (contextCache.rangeCount != editor.multiSelect.rangeCount) + contextCache = {rangeCount: editor.multiSelect.rangeCount}; + } + if (contextCache[id]) + return context = contextCache[id]; + context = contextCache[id] = { + autoInsertedBrackets: 0, + autoInsertedRow: -1, + autoInsertedLineEnd: "", + maybeInsertedBrackets: 0, + maybeInsertedRow: -1, + maybeInsertedLineStart: "", + maybeInsertedLineEnd: "" }; - - CstyleBehaviour.$matchTokenType = function(token, types) { - return types.indexOf(token.type || token) > -1; - }; - - CstyleBehaviour.recordAutoInsert = function(editor, session, bracket) { - var cursor = editor.getCursorPosition(); - var line = session.doc.getLine(cursor.row); - if (!this.isAutoInsertedClosing(cursor, line, autoInsertedLineEnd[0])) - autoInsertedBrackets = 0; - autoInsertedRow = cursor.row; - autoInsertedLineEnd = bracket + line.substr(cursor.column); - autoInsertedBrackets++; - }; - - CstyleBehaviour.recordMaybeInsert = function(editor, session, bracket) { - var cursor = editor.getCursorPosition(); - var line = session.doc.getLine(cursor.row); - if (!this.isMaybeInsertedClosing(cursor, line)) - maybeInsertedBrackets = 0; - maybeInsertedRow = cursor.row; - maybeInsertedLineStart = line.substr(0, cursor.column) + bracket; - maybeInsertedLineEnd = line.substr(cursor.column); - maybeInsertedBrackets++; - }; - - CstyleBehaviour.isAutoInsertedClosing = function(cursor, line, bracket) { - return autoInsertedBrackets > 0 && - cursor.row === autoInsertedRow && - bracket === autoInsertedLineEnd[0] && - line.substr(cursor.column) === autoInsertedLineEnd; - }; - - CstyleBehaviour.isMaybeInsertedClosing = function(cursor, line) { - return maybeInsertedBrackets > 0 && - cursor.row === maybeInsertedRow && - line.substr(cursor.column) === maybeInsertedLineEnd && - line.substr(0, cursor.column) == maybeInsertedLineStart; - }; - - CstyleBehaviour.popAutoInsertedClosing = function() { - autoInsertedLineEnd = autoInsertedLineEnd.substr(1); - autoInsertedBrackets--; - }; - - CstyleBehaviour.clearMaybeInsertedClosing = function() { - maybeInsertedBrackets = 0; - maybeInsertedRow = -1; - }; +}; - this.add("braces", "insertion", function (state, action, editor, session, text) { +var CstyleBehaviour = function() { + this.add("braces", "insertion", function(state, action, editor, session, text) { var cursor = editor.getCursorPosition(); var line = session.doc.getLine(cursor.row); if (text == '{') { + initContext(editor); var selection = editor.getSelectionRange(); var selected = session.doc.getTextRange(selection); if (selected !== "" && selected !== "{" && editor.getWrapBehavioursEnabled()) { return { text: '{' + selected + '}', @@ -708,10 +492,11 @@ selection: [1, 1] }; } } } else if (text == '}') { + initContext(editor); var rightChar = line.substring(cursor.column, cursor.column + 1); if (rightChar == '}') { var matching = session.$findOpeningBracket('}', {column: cursor.column + 1, row: cursor.row}); if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) { CstyleBehaviour.popAutoInsertedClosing(); @@ -720,13 +505,14 @@ selection: [1, 1] }; } } } else if (text == "\n" || text == "\r\n") { + initContext(editor); var closing = ""; if (CstyleBehaviour.isMaybeInsertedClosing(cursor, line)) { - closing = lang.stringRepeat("}", maybeInsertedBrackets); + closing = lang.stringRepeat("}", context.maybeInsertedBrackets); CstyleBehaviour.clearMaybeInsertedClosing(); } var rightChar = line.substring(cursor.column, cursor.column + 1); if (rightChar === '}') { var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column+1}, '}'); @@ -734,10 +520,11 @@ return null; var next_indent = this.$getIndent(session.getLine(openBracePos.row)); } else if (closing) { var next_indent = this.$getIndent(line); } else { + CstyleBehaviour.clearMaybeInsertedClosing(); return; } var indent = next_indent + session.getTabString(); return { @@ -747,26 +534,28 @@ } else { CstyleBehaviour.clearMaybeInsertedClosing(); } }); - this.add("braces", "deletion", function (state, action, editor, session, range) { + this.add("braces", "deletion", function(state, action, editor, session, range) { var selected = session.doc.getTextRange(range); if (!range.isMultiLine() && selected == '{') { + initContext(editor); var line = session.doc.getLine(range.start.row); var rightChar = line.substring(range.end.column, range.end.column + 1); if (rightChar == '}') { range.end.column++; return range; } else { - maybeInsertedBrackets--; + context.maybeInsertedBrackets--; } } }); - this.add("parens", "insertion", function (state, action, editor, session, text) { + this.add("parens", "insertion", function(state, action, editor, session, text) { if (text == '(') { + initContext(editor); var selection = editor.getSelectionRange(); var selected = session.doc.getTextRange(selection); if (selected !== "" && editor.getWrapBehavioursEnabled()) { return { text: '(' + selected + ')', @@ -778,10 +567,11 @@ text: '()', selection: [1, 1] }; } } else if (text == ')') { + initContext(editor); var cursor = editor.getCursorPosition(); var line = session.doc.getLine(cursor.row); var rightChar = line.substring(cursor.column, cursor.column + 1); if (rightChar == ')') { var matching = session.$findOpeningBracket(')', {column: cursor.column + 1, row: cursor.row}); @@ -794,24 +584,26 @@ } } } }); - this.add("parens", "deletion", function (state, action, editor, session, range) { + this.add("parens", "deletion", function(state, action, editor, session, range) { var selected = session.doc.getTextRange(range); if (!range.isMultiLine() && selected == '(') { + initContext(editor); var line = session.doc.getLine(range.start.row); var rightChar = line.substring(range.start.column + 1, range.start.column + 2); if (rightChar == ')') { range.end.column++; return range; } } }); - this.add("brackets", "insertion", function (state, action, editor, session, text) { + this.add("brackets", "insertion", function(state, action, editor, session, text) { if (text == '[') { + initContext(editor); var selection = editor.getSelectionRange(); var selected = session.doc.getTextRange(selection); if (selected !== "" && editor.getWrapBehavioursEnabled()) { return { text: '[' + selected + ']', @@ -823,10 +615,11 @@ text: '[]', selection: [1, 1] }; } } else if (text == ']') { + initContext(editor); var cursor = editor.getCursorPosition(); var line = session.doc.getLine(cursor.row); var rightChar = line.substring(cursor.column, cursor.column + 1); if (rightChar == ']') { var matching = session.$findOpeningBracket(']', {column: cursor.column + 1, row: cursor.row}); @@ -839,24 +632,26 @@ } } } }); - this.add("brackets", "deletion", function (state, action, editor, session, range) { + this.add("brackets", "deletion", function(state, action, editor, session, range) { var selected = session.doc.getTextRange(range); if (!range.isMultiLine() && selected == '[') { + initContext(editor); var line = session.doc.getLine(range.start.row); var rightChar = line.substring(range.start.column + 1, range.start.column + 2); if (rightChar == ']') { range.end.column++; return range; } } }); - this.add("string_dquotes", "insertion", function (state, action, editor, session, text) { + this.add("string_dquotes", "insertion", function(state, action, editor, session, text) { if (text == '"' || text == "'") { + initContext(editor); var quote = text; var selection = editor.getSelectionRange(); var selected = session.doc.getTextRange(selection); if (selected !== "" && selected !== "'" && selected != '"' && editor.getWrapBehavioursEnabled()) { return { @@ -904,13 +699,14 @@ } } } }); - this.add("string_dquotes", "deletion", function (state, action, editor, session, range) { + this.add("string_dquotes", "deletion", function(state, action, editor, session, range) { var selected = session.doc.getTextRange(range); if (!range.isMultiLine() && (selected == '"' || selected == "'")) { + initContext(editor); var line = session.doc.getLine(range.start.row); var rightChar = line.substring(range.start.column + 1, range.start.column + 2); if (rightChar == selected) { range.end.column++; return range; @@ -918,18 +714,85 @@ } }); }; + +CstyleBehaviour.isSaneInsertion = function(editor, session) { + var cursor = editor.getCursorPosition(); + var iterator = new TokenIterator(session, cursor.row, cursor.column); + if (!this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) { + var iterator2 = new TokenIterator(session, cursor.row, cursor.column + 1); + if (!this.$matchTokenType(iterator2.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) + return false; + } + iterator.stepForward(); + return iterator.getCurrentTokenRow() !== cursor.row || + this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_BEFORE_TOKENS); +}; + +CstyleBehaviour.$matchTokenType = function(token, types) { + return types.indexOf(token.type || token) > -1; +}; + +CstyleBehaviour.recordAutoInsert = function(editor, session, bracket) { + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + if (!this.isAutoInsertedClosing(cursor, line, context.autoInsertedLineEnd[0])) + context.autoInsertedBrackets = 0; + context.autoInsertedRow = cursor.row; + context.autoInsertedLineEnd = bracket + line.substr(cursor.column); + context.autoInsertedBrackets++; +}; + +CstyleBehaviour.recordMaybeInsert = function(editor, session, bracket) { + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + if (!this.isMaybeInsertedClosing(cursor, line)) + context.maybeInsertedBrackets = 0; + context.maybeInsertedRow = cursor.row; + context.maybeInsertedLineStart = line.substr(0, cursor.column) + bracket; + context.maybeInsertedLineEnd = line.substr(cursor.column); + context.maybeInsertedBrackets++; +}; + +CstyleBehaviour.isAutoInsertedClosing = function(cursor, line, bracket) { + return context.autoInsertedBrackets > 0 && + cursor.row === context.autoInsertedRow && + bracket === context.autoInsertedLineEnd[0] && + line.substr(cursor.column) === context.autoInsertedLineEnd; +}; + +CstyleBehaviour.isMaybeInsertedClosing = function(cursor, line) { + return context.maybeInsertedBrackets > 0 && + cursor.row === context.maybeInsertedRow && + line.substr(cursor.column) === context.maybeInsertedLineEnd && + line.substr(0, cursor.column) == context.maybeInsertedLineStart; +}; + +CstyleBehaviour.popAutoInsertedClosing = function() { + context.autoInsertedLineEnd = context.autoInsertedLineEnd.substr(1); + context.autoInsertedBrackets--; +}; + +CstyleBehaviour.clearMaybeInsertedClosing = function() { + if (context) { + context.maybeInsertedBrackets = 0; + context.maybeInsertedRow = -1; + } +}; + + + oop.inherits(CstyleBehaviour, Behaviour); exports.CstyleBehaviour = CstyleBehaviour; }); -define('ace/mode/folding/cstyle', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/range', 'ace/mode/folding/fold_mode'], function(require, exports, module) { +define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"], function(require, exports, module) { +"use strict"; - var oop = require("../../lib/oop"); var Range = require("../../range").Range; var BaseFoldMode = require("./fold_mode").FoldMode; var FoldMode = exports.FoldMode = function(commentRegex) { @@ -1018,45 +881,63 @@ }).call(FoldMode.prototype); }); -define('ace/mode/css', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text', 'ace/tokenizer', 'ace/mode/css_highlight_rules', 'ace/mode/matching_brace_outdent', 'ace/worker/worker_client', 'ace/mode/behaviour/css', 'ace/mode/folding/cstyle'], function(require, exports, module) { +define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"], function(require, exports, module) { +"use strict"; - var oop = require("../lib/oop"); var TextMode = require("./text").Mode; -var Tokenizer = require("../tokenizer").Tokenizer; -var CssHighlightRules = require("./css_highlight_rules").CssHighlightRules; +var JavaScriptHighlightRules = require("./javascript_highlight_rules").JavaScriptHighlightRules; var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; +var Range = require("../range").Range; var WorkerClient = require("../worker/worker_client").WorkerClient; -var CssBehaviour = require("./behaviour/css").CssBehaviour; +var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; var CStyleFoldMode = require("./folding/cstyle").FoldMode; var Mode = function() { - this.HighlightRules = CssHighlightRules; + this.HighlightRules = JavaScriptHighlightRules; + this.$outdent = new MatchingBraceOutdent(); - this.$behaviour = new CssBehaviour(); + this.$behaviour = new CstyleBehaviour(); this.foldingRules = new CStyleFoldMode(); }; oop.inherits(Mode, TextMode); (function() { - this.foldingRules = "cStyle"; + this.lineCommentStart = "//"; this.blockComment = {start: "/*", end: "*/"}; this.getNextLineIndent = function(state, line, tab) { var indent = this.$getIndent(line); - var tokens = this.getTokenizer().getLineTokens(line, state).tokens; + + var tokenizedLine = this.getTokenizer().getLineTokens(line, state); + var tokens = tokenizedLine.tokens; + var endState = tokenizedLine.state; + if (tokens.length && tokens[tokens.length-1].type == "comment") { return indent; } - var match = line.match(/^.*\{\s*$/); - if (match) { - indent += tab; + if (state == "start" || state == "no_regex") { + var match = line.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/); + if (match) { + indent += tab; + } + } else if (state == "doc-start") { + if (endState == "start" || endState == "no_regex") { + return ""; + } + var match = line.match(/^\s*(\/?)\*/); + if (match) { + if (match[1]) { + indent += " "; + } + indent += "* "; + } } return indent; }; @@ -1067,34 +948,33 @@ this.autoOutdent = function(state, doc, row) { this.$outdent.autoOutdent(doc, row); }; this.createWorker = function(session) { - var worker = new WorkerClient(["ace"], "ace/mode/css_worker", "Worker"); + var worker = new WorkerClient(["ace"], "ace/mode/javascript_worker", "JavaScriptWorker"); worker.attachToDocument(session.getDocument()); - worker.on("csslint", function(e) { - session.setAnnotations(e.data); + worker.on("jslint", function(results) { + session.setAnnotations(results.data); }); worker.on("terminate", function() { session.clearAnnotations(); }); return worker; }; - this.$id = "ace/mode/css"; + this.$id = "ace/mode/javascript"; }).call(Mode.prototype); exports.Mode = Mode; - }); -define('ace/mode/css_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/lang', 'ace/mode/text_highlight_rules'], function(require, exports, module) { +define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"], function(require, exports, module) { +"use strict"; - var oop = require("../lib/oop"); var lang = require("../lib/lang"); var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; var supportType = exports.supportType = "animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index"; var supportFunction = exports.supportFunction = "rgb|rgba|url|attr|counter|counters"; @@ -1232,13 +1112,13 @@ exports.CssHighlightRules = CssHighlightRules; }); -define('ace/mode/behaviour/css', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/behaviour', 'ace/mode/behaviour/cstyle', 'ace/token_iterator'], function(require, exports, module) { +define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"], function(require, exports, module) { +"use strict"; - var oop = require("../../lib/oop"); var Behaviour = require("../behaviour").Behaviour; var CstyleBehaviour = require("./cstyle").CstyleBehaviour; var TokenIterator = require("../../token_iterator").TokenIterator; @@ -1311,241 +1191,240 @@ oop.inherits(CssBehaviour, CstyleBehaviour); exports.CssBehaviour = CssBehaviour; }); -define('ace/mode/html_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/lang', 'ace/mode/css_highlight_rules', 'ace/mode/javascript_highlight_rules', 'ace/mode/xml_highlight_rules'], function(require, exports, module) { +define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/css","ace/mode/folding/cstyle"], function(require, exports, module) { +"use strict"; - var oop = require("../lib/oop"); -var lang = require("../lib/lang"); +var TextMode = require("./text").Mode; var CssHighlightRules = require("./css_highlight_rules").CssHighlightRules; -var JavaScriptHighlightRules = require("./javascript_highlight_rules").JavaScriptHighlightRules; -var XmlHighlightRules = require("./xml_highlight_rules").XmlHighlightRules; +var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; +var WorkerClient = require("../worker/worker_client").WorkerClient; +var CssBehaviour = require("./behaviour/css").CssBehaviour; +var CStyleFoldMode = require("./folding/cstyle").FoldMode; -var tagMap = lang.createMap({ - a : 'anchor', - button : 'form', - form : 'form', - img : 'image', - input : 'form', - label : 'form', - option : 'form', - script : 'script', - select : 'form', - textarea : 'form', - style : 'style', - table : 'table', - tbody : 'table', - td : 'table', - tfoot : 'table', - th : 'table', - tr : 'table' -}); +var Mode = function() { + this.HighlightRules = CssHighlightRules; + this.$outdent = new MatchingBraceOutdent(); + this.$behaviour = new CssBehaviour(); + this.foldingRules = new CStyleFoldMode(); +}; +oop.inherits(Mode, TextMode); -var HtmlHighlightRules = function() { - XmlHighlightRules.call(this); +(function() { - this.addRules({ - attributes: [{ - include : "space" - }, { - token : "entity.other.attribute-name", - regex : "[-_a-zA-Z0-9:]+" - }, { - token : "keyword.operator.separator", - regex : "=", - push : [{ - include: "space" - }, { - token : "string", - regex : "[^<>='\"`\\s]+", - next : "pop" - }, { - token : "empty", - regex : "", - next : "pop" - }] - }, { - include : "string" - }], - tag: [{ - token : function(start, tag) { - var group = tagMap[tag]; - return ["meta.tag.punctuation.begin", - "meta.tag.name" + (group ? "." + group : "")]; - }, - regex : "(<)([-_a-zA-Z0-9:]+)", - next: "start_tag_stuff" - }, { - token : function(start, tag) { - var group = tagMap[tag]; - return ["meta.tag.punctuation.begin", - "meta.tag.name" + (group ? "." + group : "")]; - }, - regex : "(</)([-_a-zA-Z0-9:]+)", - next: "end_tag_stuff" - }], - start_tag_stuff: [ - {include : "attributes"}, - {token : "meta.tag.punctuation.end", regex : "/?>", next : "start"} - ], - end_tag_stuff: [ - {include : "space"}, - {token : "meta.tag.punctuation.end", regex : ">", next : "start"} - ] - }); + this.foldingRules = "cStyle"; + this.blockComment = {start: "/*", end: "*/"}; - this.embedTagRules(CssHighlightRules, "css-", "style"); - this.embedTagRules(JavaScriptHighlightRules, "js-", "script"); + this.getNextLineIndent = function(state, line, tab) { + var indent = this.$getIndent(line); + var tokens = this.getTokenizer().getLineTokens(line, state).tokens; + if (tokens.length && tokens[tokens.length-1].type == "comment") { + return indent; + } - if (this.constructor === HtmlHighlightRules) - this.normalizeRules(); -}; + var match = line.match(/^.*\{\s*$/); + if (match) { + indent += tab; + } -oop.inherits(HtmlHighlightRules, XmlHighlightRules); + return indent; + }; -exports.HtmlHighlightRules = HtmlHighlightRules; -}); + this.checkOutdent = function(state, line, input) { + return this.$outdent.checkOutdent(line, input); + }; -define('ace/mode/xml_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/xml_util', 'ace/mode/text_highlight_rules'], function(require, exports, module) { + this.autoOutdent = function(state, doc, row) { + this.$outdent.autoOutdent(doc, row); + }; + this.createWorker = function(session) { + var worker = new WorkerClient(["ace"], "ace/mode/css_worker", "Worker"); + worker.attachToDocument(session.getDocument()); + worker.on("csslint", function(e) { + session.setAnnotations(e.data); + }); + + worker.on("terminate", function() { + session.clearAnnotations(); + }); + + return worker; + }; + + this.$id = "ace/mode/css"; +}).call(Mode.prototype); + +exports.Mode = Mode; + +}); + +define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { +"use strict"; + var oop = require("../lib/oop"); -var xmlUtil = require("./xml_util"); var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; var XmlHighlightRules = function(normalize) { this.$rules = { start : [ - {token : "punctuation.string.begin", regex : "<\\!\\[CDATA\\[", next : "cdata"}, + {token : "string.cdata.xml", regex : "<\\!\\[CDATA\\[", next : "cdata"}, { - token : ["punctuation.instruction.begin", "keyword.instruction"], - regex : "(<\\?)(xml)(?=[\\s])", next : "xml_declaration" + token : ["punctuation.xml-decl.xml", "keyword.xml-decl.xml"], + regex : "(<\\?)(xml)(?=[\\s])", next : "xml_decl", caseInsensitive: true }, { - token : ["punctuation.instruction.begin", "keyword.instruction"], - regex : "(<\\?)([-_a-zA-Z0-9]+)", next : "instruction" + token : ["punctuation.instruction.xml", "keyword.instruction.xml"], + regex : "(<\\?)([-_a-zA-Z0-9]+)", next : "processing_instruction", }, - {token : "comment", regex : "<\\!--", next : "comment"}, + {token : "comment.xml", regex : "<\\!--", next : "comment"}, { - token : ["punctuation.doctype.begin", "meta.tag.doctype"], - regex : "(<\\!)(DOCTYPE)(?=[\\s])", next : "doctype" + token : ["xml-pe.doctype.xml", "xml-pe.doctype.xml"], + regex : "(<\\!)(DOCTYPE)(?=[\\s])", next : "doctype", caseInsensitive: true }, {include : "tag"}, - {include : "reference"} + {token : "text.end-tag-open.xml", regex: "</"}, + {token : "text.tag-open.xml", regex: "<"}, + {include : "reference"}, + {defaultToken : "text.xml"} ], - xml_declaration : [ - {include : "attributes"}, - {include : "instruction"} - ], + xml_decl : [{ + token : "entity.other.attribute-name.decl-attribute-name.xml", + regex : "(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+" + }, { + token : "keyword.operator.decl-attribute-equals.xml", + regex : "=" + }, { + include: "whitespace" + }, { + include: "string" + }, { + token : "punctuation.xml-decl.xml", + regex : "\\?>", + next : "start" + }], - instruction : [ - {token : "punctuation.instruction.end", regex : "\\?>", next : "start"} + processing_instruction : [ + {token : "punctuation.instruction.xml", regex : "\\?>", next : "start"}, + {defaultToken : "instruction.xml"} ], doctype : [ - {include : "space"}, + {include : "whitespace"}, {include : "string"}, - {token : "punctuation.doctype.end", regex : ">", next : "start"}, - {token : "xml-pe", regex : "[-_a-zA-Z0-9:]+"}, - {token : "punctuation.begin", regex : "\\[", push : "declarations"} + {token : "xml-pe.doctype.xml", regex : ">", next : "start"}, + {token : "xml-pe.xml", regex : "[-_a-zA-Z0-9:]+"}, + {token : "punctuation.int-subset", regex : "\\[", push : "int_subset"} ], - declarations : [{ - token : "text", + int_subset : [{ + token : "text.xml", regex : "\\s+" }, { - token: "punctuation.end", + token: "punctuation.int-subset.xml", regex: "]", next: "pop" }, { - token : ["punctuation.begin", "keyword"], + token : ["punctuation.markup-decl.xml", "keyword.markup-decl.xml"], regex : "(<\\!)([-_a-zA-Z0-9]+)", push : [{ token : "text", regex : "\\s+" }, { - token : "punctuation.end", + token : "punctuation.markup-decl.xml", regex : ">", next : "pop" }, {include : "string"}] }], cdata : [ - {token : "string.end", regex : "\\]\\]>", next : "start"}, - {token : "text", regex : "\\s+"}, - {token : "text", regex : "(?:[^\\]]|\\](?!\\]>))+"} + {token : "string.cdata.xml", regex : "\\]\\]>", next : "start"}, + {token : "text.xml", regex : "\\s+"}, + {token : "text.xml", regex : "(?:[^\\]]|\\](?!\\]>))+"} ], comment : [ - {token : "comment", regex : "-->", next : "start"}, - {defaultToken : "comment"} + {token : "comment.xml", regex : "-->", next : "start"}, + {defaultToken : "comment.xml"} ], + reference : [{ + token : "constant.language.escape.reference.xml", + regex : "(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)" + }], + + attr_reference : [{ + token : "constant.language.escape.reference.attribute-value.xml", + regex : "(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)" + }], + tag : [{ - token : ["meta.tag.punctuation.begin", "meta.tag.name"], - regex : "(<)((?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+)", + token : ["meta.tag.punctuation.tag-open.xml", "meta.tag.punctuation.end-tag-open.xml", "meta.tag.tag-name.xml"], + regex : "(?:(<)|(</))((?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+)", next: [ {include : "attributes"}, - {token : "meta.tag.punctuation.end", regex : "/?>", next : "start"} + {token : "meta.tag.punctuation.tag-close.xml", regex : "/?>", next : "start"} ] - }, { - token : ["meta.tag.punctuation.begin", "meta.tag.name"], - regex : "(</)((?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+)", - next: [ - {include : "space"}, - {token : "meta.tag.punctuation.end", regex : ">", next : "start"} - ] }], - space : [ - {token : "text", regex : "\\s+"} + tag_whitespace : [ + {token : "text.tag-whitespace.xml", regex : "\\s+"} ], - - reference : [{ - token : "constant.language.escape", - regex : "(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)" - }, { - token : "text", regex : "&" - }], - + whitespace : [ + {token : "text.whitespace.xml", regex : "\\s+"} + ], string: [{ - token : "string", + token : "string.xml", regex : "'", - push : "qstring_inner" + push : [ + {token : "string.xml", regex: "'", next: "pop"}, + {defaultToken : "string.xml"} + ] }, { - token : "string", + token : "string.xml", regex : '"', - push : "qqstring_inner" + push : [ + {token : "string.xml", regex: '"', next: "pop"}, + {defaultToken : "string.xml"} + ] }], - qstring_inner: [ - {token : "string", regex: "'", next: "pop"}, - {include : "reference"}, - {defaultToken : "string"} - ], - - qqstring_inner: [ - {token : "string", regex: '"', next: "pop"}, - {include : "reference"}, - {defaultToken : "string"} - ], - attributes: [{ - token : "entity.other.attribute-name", + token : "entity.other.attribute-name.xml", regex : "(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+" }, { - token : "keyword.operator.separator", + token : "keyword.operator.attribute-equals.xml", regex : "=" }, { - include : "space" + include: "tag_whitespace" }, { - include : "string" + include: "attribute_value" + }], + + attribute_value: [{ + token : "string.attribute-value.xml", + regex : "'", + push : [ + {token : "string.attribute-value.xml", regex: "'", next: "pop"}, + {include : "attr_reference"}, + {defaultToken : "string.attribute-value.xml"} + ] + }, { + token : "string.attribute-value.xml", + regex : '"', + push : [ + {token : "string.attribute-value.xml", regex: '"', next: "pop"}, + {include : "attr_reference"}, + {defaultToken : "string.attribute-value.xml"} + ] }] }; if (this.constructor === XmlHighlightRules) this.normalizeRules(); @@ -1554,37 +1433,36 @@ (function() { this.embedTagRules = function(HighlightRules, prefix, tag){ this.$rules.tag.unshift({ - token : ["meta.tag.punctuation.begin", "meta.tag.name." + tag], - regex : "(<)(" + tag + ")", + token : ["meta.tag.punctuation.tag-open.xml", "meta.tag." + tag + ".tag-name.xml"], + regex : "(<)(" + tag + "(?=\\s|>|$))", next: [ - {include : "space"}, {include : "attributes"}, - {token : "meta.tag.punctuation.end", regex : "/?>", next : prefix + "start"} + {token : "meta.tag.punctuation.tag-close.xml", regex : "/?>", next : prefix + "start"} ] }); this.$rules[tag + "-end"] = [ - {include : "space"}, - {token : "meta.tag.punctuation.end", regex : ">", next: "start", + {include : "attributes"}, + {token : "meta.tag.punctuation.tag-close.xml", regex : "/?>", next: "start", onMatch : function(value, currentState, stack) { stack.splice(0); return this.token; }} ] this.embedRules(HighlightRules, prefix, [{ - token: ["meta.tag.punctuation.begin", "meta.tag.name." + tag], - regex : "(</)(" + tag + ")", + token: ["meta.tag.punctuation.end-tag-open.xml", "meta.tag." + tag + ".tag-name.xml"], + regex : "(</)(" + tag + "(?=\\s|>|$))", next: tag + "-end" }, { - token: "string.begin", + token: "string.cdata.xml", regex : "<\\!\\[CDATA\\[" }, { - token: "string.end", + token: "string.cdata.xml", regex : "\\]\\]>" }]); }; }).call(TextHighlightRules.prototype); @@ -1592,187 +1470,198 @@ oop.inherits(XmlHighlightRules, TextHighlightRules); exports.XmlHighlightRules = XmlHighlightRules; }); -define('ace/mode/xml_util', ['require', 'exports', 'module' ], function(require, exports, module) { +define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"], function(require, exports, module) { +"use strict"; +var oop = require("../lib/oop"); +var lang = require("../lib/lang"); +var CssHighlightRules = require("./css_highlight_rules").CssHighlightRules; +var JavaScriptHighlightRules = require("./javascript_highlight_rules").JavaScriptHighlightRules; +var XmlHighlightRules = require("./xml_highlight_rules").XmlHighlightRules; -function string(state) { - return [{ - token : "string", - regex : '"', - next : state + "_qqstring" - }, { - token : "string", - regex : "'", - next : state + "_qstring" - }]; -} +var tagMap = lang.createMap({ + a : 'anchor', + button : 'form', + form : 'form', + img : 'image', + input : 'form', + label : 'form', + option : 'form', + script : 'script', + select : 'form', + textarea : 'form', + style : 'style', + table : 'table', + tbody : 'table', + td : 'table', + tfoot : 'table', + th : 'table', + tr : 'table' +}); -function multiLineString(quote, state) { - return [ - {token : "string", regex : quote, next : state}, - { - token : "constant.language.escape", - regex : "(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)" - }, - {defaultToken : "string"} - ]; -} +var HtmlHighlightRules = function() { + XmlHighlightRules.call(this); -exports.tag = function(states, name, nextState, tagMap) { - states[name] = [{ - token : "text", - regex : "\\s+" - }, { - - token : !tagMap ? "meta.tag.tag-name" : function(value) { - if (tagMap[value]) - return "meta.tag.tag-name." + tagMap[value]; - else - return "meta.tag.tag-name"; - }, - regex : "[-_a-zA-Z0-9:]+", - next : name + "_embed_attribute_list" - }, { - token: "empty", - regex: "", - next : name + "_embed_attribute_list" - }]; + this.addRules({ + attributes: [{ + include : "tag_whitespace" + }, { + token : "entity.other.attribute-name.xml", + regex : "[-_a-zA-Z0-9:]+" + }, { + token : "keyword.operator.attribute-equals.xml", + regex : "=", + push : [{ + include: "tag_whitespace" + }, { + token : "string.unquoted.attribute-value.html", + regex : "[^<>='\"`\\s]+", + next : "pop" + }, { + token : "empty", + regex : "", + next : "pop" + }] + }, { + include : "attribute_value" + }], + tag: [{ + token : function(start, tag) { + var group = tagMap[tag]; + return ["meta.tag.punctuation." + (start == "<" ? "" : "end-") + "tag-open.xml", + "meta.tag" + (group ? "." + group : "") + ".tag-name.xml"]; + }, + regex : "(</?)([-_a-zA-Z0-9:]+)", + next: "tag_stuff" + }], + tag_stuff: [ + {include : "attributes"}, + {token : "meta.tag.punctuation.tag-close.xml", regex : "/?>", next : "start"} + ], + }); - states[name + "_qstring"] = multiLineString("'", name + "_embed_attribute_list"); - states[name + "_qqstring"] = multiLineString("\"", name + "_embed_attribute_list"); - - states[name + "_embed_attribute_list"] = [{ - token : "meta.tag.r", - regex : "/?>", - next : nextState - }, { - token : "keyword.operator", - regex : "=" - }, { - token : "entity.other.attribute-name", - regex : "[-_a-zA-Z0-9:]+" - }, { - token : "constant.numeric", // float - regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" - }, { - token : "text", - regex : "\\s+" - }].concat(string(name)); + this.embedTagRules(CssHighlightRules, "css-", "style"); + this.embedTagRules(JavaScriptHighlightRules, "js-", "script"); + + if (this.constructor === HtmlHighlightRules) + this.normalizeRules(); }; +oop.inherits(HtmlHighlightRules, XmlHighlightRules); + +exports.HtmlHighlightRules = HtmlHighlightRules; }); -define('ace/mode/behaviour/html', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/behaviour/xml', 'ace/mode/behaviour/cstyle', 'ace/token_iterator'], function(require, exports, module) { +define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"], function(require, exports, module) { +"use strict"; - var oop = require("../../lib/oop"); -var XmlBehaviour = require("../behaviour/xml").XmlBehaviour; -var CstyleBehaviour = require("./cstyle").CstyleBehaviour; +var Behaviour = require("../behaviour").Behaviour; 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 tokenTypes = token.type.split('.'); - return type.split('.').every(function(type){ - return (tokenTypes.indexOf(type) !== -1); - }); - return hasType; +function is(token, type) { + return token.type.lastIndexOf(type + ".xml") > -1; } -var HtmlBehaviour = function () { +var XmlBehaviour = 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); + this.add("string_dquotes", "insertion", function (state, action, editor, session, text) { + if (text == '"' || text == "'") { + var quote = text; + var selected = session.doc.getTextRange(editor.getSelectionRange()); + if (selected !== "" && selected !== "'" && selected != '"' && editor.getWrapBehavioursEnabled()) { + return { + text: quote + selected + quote, + selection: false + }; + } + + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + var rightChar = line.substring(cursor.column, cursor.column + 1); + var iterator = new TokenIterator(session, cursor.row, cursor.column); var token = iterator.getCurrentToken(); - if (token && 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 (rightChar == quote && (is(token, "attribute-value") || is(token, "string"))) { + return { + text: "", + selection: [1, 1] + }; } - if (!token || !hasType(token, 'meta.tag.name') || iterator.stepBackward().value.match('/')) { + + if (!token) + token = iterator.stepBackward(); + + if (!token) return; + + while (is(token, "tag-whitespace") || is(token, "whitespace")) { + token = iterator.stepBackward(); } - var element = token.value; - if (atCursor){ - var element = element.substring(0, position.column - token.start); + var rightSpace = !rightChar || rightChar.match(/\s/); + if (is(token, "attribute-equals") && (rightSpace || rightChar == '>') || (is(token, "decl-attribute-equals") && (rightSpace || rightChar == '?'))) { + return { + text: quote + quote, + selection: [1, 1] + }; } - if (voidElements.indexOf(element) !== -1){ - return; - } - return { - text: '>' + '</' + element + '>', - selection: [1, 1] - } } }); -} -oop.inherits(HtmlBehaviour, XmlBehaviour); -exports.HtmlBehaviour = HtmlBehaviour; -}); - -define('ace/mode/behaviour/xml', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/behaviour', 'ace/mode/behaviour/cstyle', 'ace/token_iterator'], function(require, exports, module) { - - -var oop = require("../../lib/oop"); -var Behaviour = require("../behaviour").Behaviour; -var CstyleBehaviour = require("./cstyle").CstyleBehaviour; -var TokenIterator = require("../../token_iterator").TokenIterator; - -function hasType(token, type) { - var tokenTypes = token.type.split('.'); - return type.split('.').every(function(type){ - return (tokenTypes.indexOf(type) !== -1); + this.add("string_dquotes", "deletion", function(state, action, editor, session, range) { + var selected = session.doc.getTextRange(range); + if (!range.isMultiLine() && (selected == '"' || selected == "'")) { + var line = session.doc.getLine(range.start.row); + var rightChar = line.substring(range.start.column + 1, range.start.column + 2); + if (rightChar == selected) { + range.end.column++; + return range; + } + } }); - return hasType; -} -var XmlBehaviour = function () { - - this.inherit(CstyleBehaviour, ["string_dquotes"]); // Get string 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, 'string') && iterator.getCurrentTokenColumn() + token.value.length > position.column) + var token = iterator.getCurrentToken() || iterator.stepBackward(); + if (!token || !(is(token, "tag-name") || is(token, "tag-whitespace") || is(token, "attribute-name") || is(token, "attribute-equals") || is(token, "attribute-value"))) 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('/')) { + if (is(token, "reference.attribute-value")) return; + if (is(token, "attribute-value")) { + var firstChar = token.value.charAt(0); + if (firstChar == '"' || firstChar == "'") { + var lastChar = token.value.charAt(token.value.length - 1); + var tokenEnd = iterator.getCurrentTokenColumn() + token.value.length; + if (tokenEnd > position.column || tokenEnd == position.column && firstChar != lastChar) + return; + } } - var tag = token.value; - if (atCursor){ - var tag = tag.substring(0, position.column - token.start); + while (!is(token, "tag-name")) { + token = iterator.stepBackward(); } + var tokenRow = iterator.getCurrentTokenRow(); + var tokenColumn = iterator.getCurrentTokenColumn(); + if (is(iterator.stepBackward(), "end-tag-open")) + return; + + var element = token.value; + if (tokenRow == position.row) + element = element.substring(0, position.column - tokenColumn); + + if (this.voidElements.hasOwnProperty(element.toLowerCase())) + return; + return { - text: '>' + '</' + tag + '>', + text: '>' + '</' + element + '>', selection: [1, 1] - } + }; } }); this.add('autoindent', 'insertion', function (state, action, editor, session, text) { if (text == "\n") { @@ -1784,72 +1673,26 @@ var indent = next_indent + session.getTabString(); return { text: '\n' + indent + '\n' + next_indent, selection: [1, indent.length, 1, indent.length] - } + }; } } }); -} +}; + oop.inherits(XmlBehaviour, Behaviour); exports.XmlBehaviour = XmlBehaviour; }); -define('ace/mode/folding/html', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/folding/mixed', 'ace/mode/folding/xml', 'ace/mode/folding/cstyle'], function(require, exports, module) { +define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"], function(require, exports, module) { +"use strict"; - var oop = require("../../lib/oop"); -var MixedFoldMode = require("./mixed").FoldMode; -var XmlFoldMode = require("./xml").FoldMode; -var CStyleFoldMode = require("./cstyle").FoldMode; - -var FoldMode = exports.FoldMode = function() { - MixedFoldMode.call(this, new XmlFoldMode({ - "area": 1, - "base": 1, - "br": 1, - "col": 1, - "command": 1, - "embed": 1, - "hr": 1, - "img": 1, - "input": 1, - "keygen": 1, - "link": 1, - "meta": 1, - "param": 1, - "source": 1, - "track": 1, - "wbr": 1, - "li": 1, - "dt": 1, - "dd": 1, - "p": 1, - "rt": 1, - "rp": 1, - "optgroup": 1, - "option": 1, - "colgroup": 1, - "td": 1, - "th": 1 - }), { - "js-": new CStyleFoldMode(), - "css-": new CStyleFoldMode() - }); -}; - -oop.inherits(FoldMode, MixedFoldMode); - -}); - -define('ace/mode/folding/mixed', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/folding/fold_mode'], function(require, exports, module) { - - -var oop = require("../../lib/oop"); var BaseFoldMode = require("./fold_mode").FoldMode; var FoldMode = exports.FoldMode = function(defaultMode, subModes) { this.defaultMode = defaultMode; this.subModes = subModes; @@ -1896,151 +1739,170 @@ }).call(FoldMode.prototype); }); -define('ace/mode/folding/xml', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/lang', 'ace/range', 'ace/mode/folding/fold_mode', 'ace/token_iterator'], function(require, exports, module) { +define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/range","ace/mode/folding/fold_mode","ace/token_iterator"], function(require, exports, module) { +"use strict"; - var oop = require("../../lib/oop"); var lang = require("../../lib/lang"); var Range = require("../../range").Range; var BaseFoldMode = require("./fold_mode").FoldMode; var TokenIterator = require("../../token_iterator").TokenIterator; -var FoldMode = exports.FoldMode = function(voidElements) { +var FoldMode = exports.FoldMode = function(voidElements, optionalEndTags) { BaseFoldMode.call(this); this.voidElements = voidElements || {}; + this.optionalEndTags = oop.mixin({}, this.voidElements); + if (optionalEndTags) + oop.mixin(this.optionalEndTags, optionalEndTags); + }; oop.inherits(FoldMode, BaseFoldMode); +var Tag = function() { + this.tagName = ""; + this.closing = false; + this.selfClosing = false; + this.start = {row: 0, column: 0}; + this.end = {row: 0, column: 0}; +}; + +function is(token, type) { + return token.type.lastIndexOf(type + ".xml") > -1; +} + (function() { this.getFoldWidget = function(session, foldStyle, row) { var tag = this._getFirstTagInLine(session, row); - if (tag.closing) + if (!tag) + return ""; + + if (tag.closing || (!tag.tagName && tag.selfClosing)) return foldStyle == "markbeginend" ? "end" : ""; - if (!tag.tagName || this.voidElements[tag.tagName.toLowerCase()]) + if (!tag.tagName || tag.selfClosing || this.voidElements.hasOwnProperty(tag.tagName.toLowerCase())) return ""; - if (tag.selfClosing) + if (this._findEndTagInLine(session, row, tag.tagName, tag.end.column)) return ""; - if (tag.value.indexOf("/" + tag.tagName) !== -1) - return ""; - return "start"; }; - this._getFirstTagInLine = function(session, row) { var tokens = session.getTokens(row); - var value = ""; + var tag = new Tag(); + for (var i = 0; i < tokens.length; i++) { var token = tokens[i]; - if (token.type.lastIndexOf("meta.tag", 0) === 0) - value += token.value; - else - value += lang.stringRepeat(" ", token.value.length); + if (is(token, "tag-open")) { + tag.end.column = tag.start.column + token.value.length; + tag.closing = is(token, "end-tag-open"); + token = tokens[++i]; + if (!token) + return null; + tag.tagName = token.value; + tag.end.column += token.value.length; + for (i++; i < tokens.length; i++) { + token = tokens[i]; + tag.end.column += token.value.length; + if (is(token, "tag-close")) { + tag.selfClosing = token.value == '/>'; + break; + } + } + return tag; + } else if (is(token, "tag-close")) { + tag.selfClosing = token.value == '/>'; + return tag; + } + tag.start.column += token.value.length; } - - return this._parseTag(value); + + return null; }; - this.tagRe = /^(\s*)(<?(\/?)([-_a-zA-Z0-9:!]*)\s*(\/?)>?)/; - this._parseTag = function(tag) { - - var match = tag.match(this.tagRe); + this._findEndTagInLine = function(session, row, tagName, startColumn) { + var tokens = session.getTokens(row); var column = 0; - - return { - value: tag, - match: match ? match[2] : "", - closing: match ? !!match[3] : false, - selfClosing: match ? !!match[5] || match[2] == "/>" : false, - tagName: match ? match[4] : "", - column: match[1] ? column + match[1].length : column - }; + for (var i = 0; i < tokens.length; i++) { + var token = tokens[i]; + column += token.value.length; + if (column < startColumn) + continue; + if (is(token, "end-tag-open")) { + token = tokens[i + 1]; + if (token && token.value == tagName) + return true; + } + } + return false; }; this._readTagForward = function(iterator) { var token = iterator.getCurrentToken(); if (!token) return null; - - var value = ""; - var start; - + + var tag = new Tag(); do { - if (token.type.lastIndexOf("meta.tag", 0) === 0) { - if (!start) { - var start = { - row: iterator.getCurrentTokenRow(), - column: iterator.getCurrentTokenColumn() - }; - } - value += token.value; - if (value.indexOf(">") !== -1) { - var tag = this._parseTag(value); - tag.start = start; - tag.end = { - row: iterator.getCurrentTokenRow(), - column: iterator.getCurrentTokenColumn() + token.value.length - }; - iterator.stepForward(); - return tag; - } + if (is(token, "tag-open")) { + tag.closing = is(token, "end-tag-open"); + tag.start.row = iterator.getCurrentTokenRow(); + tag.start.column = iterator.getCurrentTokenColumn(); + } else if (is(token, "tag-name")) { + tag.tagName = token.value; + } else if (is(token, "tag-close")) { + tag.selfClosing = token.value == "/>"; + tag.end.row = iterator.getCurrentTokenRow(); + tag.end.column = iterator.getCurrentTokenColumn() + token.value.length; + iterator.stepForward(); + return tag; } } while(token = iterator.stepForward()); - + return null; }; this._readTagBackward = function(iterator) { var token = iterator.getCurrentToken(); if (!token) return null; - - var value = ""; - var end; + var tag = new Tag(); do { - if (token.type.lastIndexOf("meta.tag", 0) === 0) { - if (!end) { - end = { - row: iterator.getCurrentTokenRow(), - column: iterator.getCurrentTokenColumn() + token.value.length - }; - } - value = token.value + value; - if (value.indexOf("<") !== -1) { - var tag = this._parseTag(value); - tag.end = end; - tag.start = { - row: iterator.getCurrentTokenRow(), - column: iterator.getCurrentTokenColumn() - }; - iterator.stepBackward(); - return tag; - } + if (is(token, "tag-open")) { + tag.closing = is(token, "end-tag-open"); + tag.start.row = iterator.getCurrentTokenRow(); + tag.start.column = iterator.getCurrentTokenColumn(); + iterator.stepBackward(); + return tag; + } else if (is(token, "tag-name")) { + tag.tagName = token.value; + } else if (is(token, "tag-close")) { + tag.selfClosing = token.value == "/>"; + tag.end.row = iterator.getCurrentTokenRow(); + tag.end.column = iterator.getCurrentTokenColumn() + token.value.length; } } while(token = iterator.stepBackward()); - + return null; }; this._pop = function(stack, tag) { while (stack.length) { var top = stack[stack.length-1]; if (!tag || top.tagName == tag.tagName) { return stack.pop(); } - else if (this.voidElements[tag.tagName]) { + else if (this.optionalEndTags.hasOwnProperty(tag.tagName)) { return; } - else if (this.voidElements[top.tagName]) { + else if (this.optionalEndTags.hasOwnProperty(top.tagName)) { stack.pop(); continue; } else { return null; } @@ -2048,22 +1910,22 @@ }; this.getFoldWidgetRange = function(session, foldStyle, row) { var firstTag = this._getFirstTagInLine(session, row); - if (!firstTag.match) + if (!firstTag) return null; var isBackward = firstTag.closing || firstTag.selfClosing; var stack = []; var tag; if (!isBackward) { - var iterator = new TokenIterator(session, row, firstTag.column); + var iterator = new TokenIterator(session, row, firstTag.start.column); var start = { row: row, - column: firstTag.column + firstTag.tagName.length + 2 + column: firstTag.start.column + firstTag.tagName.length + 2 }; while (tag = this._readTagForward(iterator)) { if (tag.selfClosing) { if (!stack.length) { tag.start.column += tag.tagName.length + 2; @@ -2077,19 +1939,19 @@ this._pop(stack, tag); if (stack.length == 0) return Range.fromPoints(start, tag.start); } else { - stack.push(tag) + stack.push(tag); } } } else { - var iterator = new TokenIterator(session, row, firstTag.column + firstTag.match.length); + var iterator = new TokenIterator(session, row, firstTag.end.column); var end = { row: row, - column: firstTag.column + column: firstTag.start.column }; while (tag = this._readTagBackward(iterator)) { if (tag.selfClosing) { if (!stack.length) { @@ -2106,24 +1968,43 @@ tag.start.column += tag.tagName.length + 2; return Range.fromPoints(tag.start, end); } } else { - stack.push(tag) + stack.push(tag); } } } }; }).call(FoldMode.prototype); }); -define('ace/mode/html_completions', ['require', 'exports', 'module' , 'ace/token_iterator'], function(require, exports, module) { +define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"], function(require, exports, module) { +"use strict"; +var oop = require("../../lib/oop"); +var MixedFoldMode = require("./mixed").FoldMode; +var XmlFoldMode = require("./xml").FoldMode; +var CStyleFoldMode = require("./cstyle").FoldMode; +var FoldMode = exports.FoldMode = function(voidElements, optionalTags) { + MixedFoldMode.call(this, new XmlFoldMode(voidElements, optionalTags), { + "js-": new CStyleFoldMode(), + "css-": new CStyleFoldMode() + }); +}; + +oop.inherits(FoldMode, MixedFoldMode); + +}); + +define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"], function(require, exports, module) { +"use strict"; + var TokenIterator = require("../token_iterator").TokenIterator; var commonAttributes = [ "accesskey", "class", @@ -2132,10 +2013,16 @@ "dir", "draggable", "dropzone", "hidden", "id", + "inert", + "itemid", + "itemprop", + "itemref", + "itemscope", + "itemtype", "lang", "spellcheck", "style", "tabindex", "title", @@ -2315,28 +2202,23 @@ "command": ["type", "label", "icon", "disabled", "checked", "radiogroup", "command"], "menu": ["type", "label"], "dialog": ["open"] }; -var allElements = Object.keys(attributeMap); +var elements = Object.keys(attributeMap); -function hasType(token, type) { - var tokenTypes = token.type.split('.'); - return type.split('.').every(function(type){ - return (tokenTypes.indexOf(type) !== -1); - }); +function is(token, type) { + return token.type.lastIndexOf(type + ".xml") > -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'))); + while (token && !is(token, "tag-name")){ + token = iterator.stepBackward(); } - if (token && hasType(token, 'tag-name') && !iterator.stepBackward().value.match('/')) + if (token) return token.value; } var HtmlCompletions = function() { @@ -2347,29 +2229,24 @@ 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"))) + if (is(token, "tag-name") || is(token, "tag-open") || is(token, "end-tag-open")) return this.getTagCompletions(state, session, pos, prefix); - if (hasType(token, 'text') || hasType(token, 'attribute-name')) + if (is(token, "tag-whitespace") || is(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" + meta: "tag", + score: Number.MAX_VALUE }; }); }; this.getAttributeCompetions = function(state, session, pos, prefix) { @@ -2378,59 +2255,182 @@ 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" + meta: "attribute", + score: Number.MAX_VALUE }; }); }; }).call(HtmlCompletions.prototype); exports.HtmlCompletions = HtmlCompletions; }); -define('ace/mode/rhtml_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/r_highlight_rules', 'ace/mode/html_highlight_rules', 'ace/mode/text_highlight_rules'], function(require, exports, module) { +define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"], function(require, exports, module) { +"use strict"; var oop = require("../lib/oop"); -var RHighlightRules = require("./r_highlight_rules").RHighlightRules; +var lang = require("../lib/lang"); +var TextMode = require("./text").Mode; +var JavaScriptMode = require("./javascript").Mode; +var CssMode = require("./css").Mode; var HtmlHighlightRules = require("./html_highlight_rules").HtmlHighlightRules; -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; +var XmlBehaviour = require("./behaviour/xml").XmlBehaviour; +var HtmlFoldMode = require("./folding/html").FoldMode; +var HtmlCompletions = require("./html_completions").HtmlCompletions; +var WorkerClient = require("../worker/worker_client").WorkerClient; +var voidElements = ["area", "base", "br", "col", "embed", "hr", "img", "input", "keygen", "link", "meta", "menuitem", "param", "source", "track", "wbr"]; +var optionalEndTags = ["li", "dt", "dd", "p", "rt", "rp", "optgroup", "option", "colgroup", "td", "th"]; -var RHtmlHighlightRules = function() { - HtmlHighlightRules.call(this); - - this.$rules["start"].unshift({ - token: "support.function.codebegin", - regex: "^<" + "!--\\s*begin.rcode\\s*(?:.*)", - next: "r-start" +var Mode = function(options) { + this.fragmentContext = options && options.fragmentContext; + this.HighlightRules = HtmlHighlightRules; + this.$behaviour = new XmlBehaviour(); + this.$completer = new HtmlCompletions(); + + this.createModeDelegates({ + "js-": JavaScriptMode, + "css-": CssMode }); + + this.foldingRules = new HtmlFoldMode(this.voidElements, lang.arrayToMap(optionalEndTags)); +}; +oop.inherits(Mode, TextMode); - this.embedRules(RHighlightRules, "r-", [{ - token: "support.function.codeend", - regex: "^\\s*end.rcode\\s*-->", - next: "start" - }], ["start"]); +(function() { - this.normalizeRules(); + this.blockComment = {start: "<!--", end: "-->"}; + + this.voidElements = lang.arrayToMap(voidElements); + + this.getNextLineIndent = function(state, line, tab) { + return this.$getIndent(line); + }; + + this.checkOutdent = function(state, line, input) { + return false; + }; + + this.getCompletions = function(state, session, pos, prefix) { + return this.$completer.getCompletions(state, session, pos, prefix); + }; + + this.createWorker = function(session) { + if (this.constructor != Mode) + return; + var worker = new WorkerClient(["ace"], "ace/mode/html_worker", "Worker"); + worker.attachToDocument(session.getDocument()); + + if (this.fragmentContext) + worker.call("setOptions", [{context: this.fragmentContext}]); + + worker.on("error", function(e) { + session.setAnnotations(e.data); + }); + + worker.on("terminate", function() { + session.clearAnnotations(); + }); + + return worker; + }; + + this.$id = "ace/mode/html"; +}).call(Mode.prototype); + +exports.Mode = Mode; +}); + +define("ace/mode/tex_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var lang = require("../lib/lang"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var TexHighlightRules = function(textClass) { + + if (!textClass) + textClass = "text"; + + this.$rules = { + "start" : [ + { + token : "comment", + regex : "%.*$" + }, { + token : textClass, // non-command + regex : "\\\\[$&%#\\{\\}]" + }, { + token : "keyword", // command + regex : "\\\\(?:documentclass|usepackage|newcounter|setcounter|addtocounter|value|arabic|stepcounter|newenvironment|renewenvironment|ref|vref|eqref|pageref|label|cite[a-zA-Z]*|tag|begin|end|bibitem)\\b", + next : "nospell" + }, { + token : "keyword", // command + regex : "\\\\(?:[a-zA-z0-9]+|[^a-zA-z0-9])" + }, { + token : "paren.keyword.operator", + regex : "[[({]" + }, { + token : "paren.keyword.operator", + regex : "[\\])}]" + }, { + token : textClass, + regex : "\\s+" + } + ], + "nospell" : [ + { + token : "comment", + regex : "%.*$", + next : "start" + }, { + token : "nospell." + textClass, // non-command + regex : "\\\\[$&%#\\{\\}]" + }, { + token : "keyword", // command + regex : "\\\\(?:documentclass|usepackage|newcounter|setcounter|addtocounter|value|arabic|stepcounter|newenvironment|renewenvironment|ref|vref|eqref|pageref|label|cite[a-zA-Z]*|tag|begin|end|bibitem)\\b" + }, { + token : "keyword", // command + regex : "\\\\(?:[a-zA-z0-9]+|[^a-zA-z0-9])", + next : "start" + }, { + token : "paren.keyword.operator", + regex : "[[({]" + }, { + token : "paren.keyword.operator", + regex : "[\\])]" + }, { + token : "paren.keyword.operator", + regex : "}", + next : "start" + }, { + token : "nospell." + textClass, + regex : "\\s+" + }, { + token : "nospell." + textClass, + regex : "\\w+" + } + ] + }; }; -oop.inherits(RHtmlHighlightRules, TextHighlightRules); -exports.RHtmlHighlightRules = RHtmlHighlightRules; +oop.inherits(TexHighlightRules, TextHighlightRules); + +exports.TexHighlightRules = TexHighlightRules; }); -define('ace/mode/r_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/lang', 'ace/mode/text_highlight_rules', 'ace/mode/tex_highlight_rules'], function(require, exports, module) { +define("ace/mode/r_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules","ace/mode/tex_highlight_rules"], function(require, exports, module) +{ + var oop = require("../lib/oop"); var lang = require("../lib/lang"); var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; var TexHighlightRules = require("./tex_highlight_rules").TexHighlightRules; @@ -2581,83 +2581,67 @@ oop.inherits(RHighlightRules, TextHighlightRules); exports.RHighlightRules = RHighlightRules; }); -define('ace/mode/tex_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/lang', 'ace/mode/text_highlight_rules'], function(require, exports, module) { +define("ace/mode/rhtml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/r_highlight_rules","ace/mode/html_highlight_rules","ace/mode/text_highlight_rules"], function(require, exports, module) { +"use strict"; var oop = require("../lib/oop"); -var lang = require("../lib/lang"); +var RHighlightRules = require("./r_highlight_rules").RHighlightRules; +var HtmlHighlightRules = require("./html_highlight_rules").HtmlHighlightRules; var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; -var TexHighlightRules = function(textClass) { +var RHtmlHighlightRules = function() { + HtmlHighlightRules.call(this); - if (!textClass) - textClass = "text"; + this.$rules["start"].unshift({ + token: "support.function.codebegin", + regex: "^<" + "!--\\s*begin.rcode\\s*(?:.*)", + next: "r-start" + }); - this.$rules = { - "start" : [ - { - token : "comment", - regex : "%.*$" - }, { - token : textClass, // non-command - regex : "\\\\[$&%#\\{\\}]" - }, { - token : "keyword", // command - regex : "\\\\(?:documentclass|usepackage|newcounter|setcounter|addtocounter|value|arabic|stepcounter|newenvironment|renewenvironment|ref|vref|eqref|pageref|label|cite[a-zA-Z]*|tag|begin|end|bibitem)\\b", - next : "nospell" - }, { - token : "keyword", // command - regex : "\\\\(?:[a-zA-z0-9]+|[^a-zA-z0-9])" - }, { - token : "paren.keyword.operator", - regex : "[[({]" - }, { - token : "paren.keyword.operator", - regex : "[\\])}]" - }, { - token : textClass, - regex : "\\s+" - } - ], - "nospell" : [ - { - token : "comment", - regex : "%.*$", - next : "start" - }, { - token : "nospell." + textClass, // non-command - regex : "\\\\[$&%#\\{\\}]" - }, { - token : "keyword", // command - regex : "\\\\(?:documentclass|usepackage|newcounter|setcounter|addtocounter|value|arabic|stepcounter|newenvironment|renewenvironment|ref|vref|eqref|pageref|label|cite[a-zA-Z]*|tag|begin|end|bibitem)\\b" - }, { - token : "keyword", // command - regex : "\\\\(?:[a-zA-z0-9]+|[^a-zA-z0-9])", - next : "start" - }, { - token : "paren.keyword.operator", - regex : "[[({]" - }, { - token : "paren.keyword.operator", - regex : "[\\])]" - }, { - token : "paren.keyword.operator", - regex : "}", - next : "start" - }, { - token : "nospell." + textClass, - regex : "\\s+" - }, { - token : "nospell." + textClass, - regex : "\\w+" - } - ] - }; + this.embedRules(RHighlightRules, "r-", [{ + token: "support.function.codeend", + regex: "^\\s*end.rcode\\s*-->", + next: "start" + }], ["start"]); + + this.normalizeRules(); }; +oop.inherits(RHtmlHighlightRules, TextHighlightRules); -oop.inherits(TexHighlightRules, TextHighlightRules); +exports.RHtmlHighlightRules = RHtmlHighlightRules; +}); -exports.TexHighlightRules = TexHighlightRules; +define("ace/mode/rhtml",["require","exports","module","ace/lib/oop","ace/mode/html","ace/mode/rhtml_highlight_rules"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var HtmlMode = require("./html").Mode; + +var RHtmlHighlightRules = require("./rhtml_highlight_rules").RHtmlHighlightRules; + +var Mode = function(doc, session) { + HtmlMode.call(this); + this.$session = session; + this.HighlightRules = RHtmlHighlightRules; +}; +oop.inherits(Mode, HtmlMode); + +(function() { + this.insertChunkInfo = { + value: "<!--begin.rcode\n\nend.rcode-->\n", + position: {row: 0, column: 15} + }; + + this.getLanguageMode = function(position) + { + return this.$session.getState(position.row).match(/^r-/) ? 'R' : 'HTML'; + }; + + this.$id = "ace/mode/rhtml"; +}).call(Mode.prototype); + +exports.Mode = Mode; });