1/* ***** BEGIN LICENSE BLOCK ***** 2 * Distributed under the BSD license: 3 * 4 * Copyright (c) 2010, Ajax.org B.V. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are met: 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * * Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * * Neither the name of Ajax.org B.V. nor the 15 * names of its contributors may be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * ***** END LICENSE BLOCK ***** */ 30 31ace.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) { 32 33 34var oop = require("../lib/oop"); 35var TextMode = require("./text").Mode; 36var Tokenizer = require("../tokenizer").Tokenizer; 37var JavaScriptHighlightRules = require("./javascript_highlight_rules").JavaScriptHighlightRules; 38var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; 39var Range = require("../range").Range; 40var WorkerClient = require("../worker/worker_client").WorkerClient; 41var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; 42var CStyleFoldMode = require("./folding/cstyle").FoldMode; 43 44var Mode = function() { 45 this.$tokenizer = new Tokenizer(new JavaScriptHighlightRules().getRules()); 46 this.$outdent = new MatchingBraceOutdent(); 47 this.$behaviour = new CstyleBehaviour(); 48 this.foldingRules = new CStyleFoldMode(); 49}; 50oop.inherits(Mode, TextMode); 51 52(function() { 53 54 55 this.toggleCommentLines = function(state, doc, startRow, endRow) { 56 var outdent = true; 57 var re = /^(\s*)\/\//; 58 59 for (var i=startRow; i<= endRow; i++) { 60 if (!re.test(doc.getLine(i))) { 61 outdent = false; 62 break; 63 } 64 } 65 66 if (outdent) { 67 var deleteRange = new Range(0, 0, 0, 0); 68 for (var i=startRow; i<= endRow; i++) 69 { 70 var line = doc.getLine(i); 71 var m = line.match(re); 72 deleteRange.start.row = i; 73 deleteRange.end.row = i; 74 deleteRange.end.column = m[0].length; 75 doc.replace(deleteRange, m[1]); 76 } 77 } 78 else { 79 doc.indentRows(startRow, endRow, "//"); 80 } 81 }; 82 83 this.getNextLineIndent = function(state, line, tab) { 84 var indent = this.$getIndent(line); 85 86 var tokenizedLine = this.$tokenizer.getLineTokens(line, state); 87 var tokens = tokenizedLine.tokens; 88 var endState = tokenizedLine.state; 89 90 if (tokens.length && tokens[tokens.length-1].type == "comment") { 91 return indent; 92 } 93 94 if (state == "start" || state == "regex_allowed") { 95 var match = line.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/); 96 if (match) { 97 indent += tab; 98 } 99 } else if (state == "doc-start") { 100 if (endState == "start" || state == "regex_allowed") { 101 return ""; 102 } 103 var match = line.match(/^\s*(\/?)\*/); 104 if (match) { 105 if (match[1]) { 106 indent += " "; 107 } 108 indent += "* "; 109 } 110 } 111 112 return indent; 113 }; 114 115 this.checkOutdent = function(state, line, input) { 116 return this.$outdent.checkOutdent(line, input); 117 }; 118 119 this.autoOutdent = function(state, doc, row) { 120 this.$outdent.autoOutdent(doc, row); 121 }; 122 123 this.createWorker = function(session) { 124 var worker = new WorkerClient(["ace"], "ace/mode/javascript_worker", "JavaScriptWorker"); 125 worker.attachToDocument(session.getDocument()); 126 127 worker.on("jslint", function(results) { 128 session.setAnnotations(results.data); 129 }); 130 131 worker.on("terminate", function() { 132 session.clearAnnotations(); 133 }); 134 135 return worker; 136 }; 137 138}).call(Mode.prototype); 139 140exports.Mode = Mode; 141}); 142 143ace.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) { 144 145 146var oop = require("../lib/oop"); 147var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules; 148var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; 149 150var JavaScriptHighlightRules = function() { 151 var keywordMapper = this.createKeywordMapper({ 152 "variable.language": 153 "Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|" + // Constructors 154 "Namespace|QName|XML|XMLList|" + // E4X 155 "ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|" + 156 "Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|" + 157 "Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|" + // Errors 158 "SyntaxError|TypeError|URIError|" + 159 "decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|" + // Non-constructor functions 160 "isNaN|parseFloat|parseInt|" + 161 "JSON|Math|" + // Other 162 "this|arguments|prototype|window|document" , // Pseudo 163 "keyword": 164 "const|yield|import|get|set|" + 165 "break|case|catch|continue|default|delete|do|else|finally|for|function|" + 166 "if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|" + 167 "__parent__|__count__|escape|unescape|with|__proto__|" + 168 "class|enum|extends|super|export|implements|private|public|interface|package|protected|static", 169 "storage.type": 170 "const|let|var|function", 171 "constant.language": 172 "null|Infinity|NaN|undefined", 173 "support.function": 174 "alert", 175 "constant.language.boolean": "true|false" 176 }, "identifier"); 177 var kwBeforeRe = "case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void"; 178 var identifierRe = "[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b"; 179 180 var escapedRe = "\\\\(?:x[0-9a-fA-F]{2}|" + // hex 181 "u[0-9a-fA-F]{4}|" + // unicode 182 "[0-2][0-7]{0,2}|" + // oct 183 "3[0-6][0-7]?|" + // oct 184 "37[0-7]?|" + // oct 185 "[4-7][0-7]?|" + //oct 186 ".)"; 187 188 this.$rules = { 189 "start" : [ 190 { 191 token : "comment", 192 regex : /\/\/.*$/ 193 }, 194 DocCommentHighlightRules.getStartRule("doc-start"), 195 { 196 token : "comment", // multi line comment 197 regex : /\/\*/, 198 next : "comment" 199 }, { 200 token : "string", 201 regex : "'(?=.)", 202 next : "qstring" 203 }, { 204 token : "string", 205 regex : '"(?=.)', 206 next : "qqstring" 207 }, { 208 token : "constant.numeric", // hex 209 regex : /0[xX][0-9a-fA-F]+\b/ 210 }, { 211 token : "constant.numeric", // float 212 regex : /[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/ 213 }, { 214 token : [ 215 "storage.type", "punctuation.operator", "support.function", 216 "punctuation.operator", "entity.name.function", "text","keyword.operator" 217 ], 218 regex : "(" + identifierRe + ")(\\.)(prototype)(\\.)(" + identifierRe +")(\\s*)(=)", 219 next: "function_arguments" 220 }, { 221 token : [ 222 "storage.type", "punctuation.operator", "entity.name.function", "text", 223 "keyword.operator", "text", "storage.type", "text", "paren.lparen" 224 ], 225 regex : "(" + identifierRe + ")(\\.)(" + identifierRe +")(\\s*)(=)(\\s*)(function)(\\s*)(\\()", 226 next: "function_arguments" 227 }, { 228 token : [ 229 "entity.name.function", "text", "keyword.operator", "text", "storage.type", 230 "text", "paren.lparen" 231 ], 232 regex : "(" + identifierRe +")(\\s*)(=)(\\s*)(function)(\\s*)(\\()", 233 next: "function_arguments" 234 }, { 235 token : [ 236 "storage.type", "punctuation.operator", "entity.name.function", "text", 237 "keyword.operator", "text", 238 "storage.type", "text", "entity.name.function", "text", "paren.lparen" 239 ], 240 regex : "(" + identifierRe + ")(\\.)(" + identifierRe +")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()", 241 next: "function_arguments" 242 }, { 243 token : [ 244 "storage.type", "text", "entity.name.function", "text", "paren.lparen" 245 ], 246 regex : "(function)(\\s+)(" + identifierRe + ")(\\s*)(\\()", 247 next: "function_arguments" 248 }, { 249 token : [ 250 "entity.name.function", "text", "punctuation.operator", 251 "text", "storage.type", "text", "paren.lparen" 252 ], 253 regex : "(" + identifierRe + ")(\\s*)(:)(\\s*)(function)(\\s*)(\\()", 254 next: "function_arguments" 255 }, { 256 token : [ 257 "text", "text", "storage.type", "text", "paren.lparen" 258 ], 259 regex : "(:)(\\s*)(function)(\\s*)(\\()", 260 next: "function_arguments" 261 }, { 262 token : "keyword", 263 regex : "(?:" + kwBeforeRe + ")\\b", 264 next : "regex_allowed" 265 }, { 266 token : ["punctuation.operator", "support.function"], 267 regex : /(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:opzzzz|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/ 268 }, { 269 token : ["punctuation.operator", "support.function.dom"], 270 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(?=\()/ 271 }, { 272 token : ["punctuation.operator", "support.constant"], 273 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/ 274 }, { 275 token : ["storage.type", "punctuation.operator", "support.function.firebug"], 276 regex : /(console)(\.)(warn|info|log|error|time|timeEnd|assert)\b/ 277 }, { 278 token : keywordMapper, 279 regex : identifierRe 280 }, { 281 token : "keyword.operator", 282 regex : /--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/, 283 next : "regex_allowed" 284 }, { 285 token : "punctuation.operator", 286 regex : /\?|\:|\,|\;|\./, 287 next : "regex_allowed" 288 }, { 289 token : "paren.lparen", 290 regex : /[\[({]/, 291 next : "regex_allowed" 292 }, { 293 token : "paren.rparen", 294 regex : /[\])}]/ 295 }, { 296 token : "keyword.operator", 297 regex : /\/=?/, 298 next : "regex_allowed" 299 }, { 300 token: "comment", 301 regex: /^#!.*$/ 302 } 303 ], 304 "regex_allowed": [ 305 DocCommentHighlightRules.getStartRule("doc-start"), 306 { 307 token : "comment", // multi line comment 308 regex : "\\/\\*", 309 next : "comment_regex_allowed" 310 }, { 311 token : "comment", 312 regex : "\\/\\/.*$" 313 }, { 314 token: "string.regexp", 315 regex: "\\/", 316 next: "regex", 317 }, { 318 token : "text", 319 regex : "\\s+" 320 }, { 321 token: "empty", 322 regex: "", 323 next: "start" 324 } 325 ], 326 "regex": [ 327 { 328 token: "regexp.keyword.operator", 329 regex: "\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)" 330 }, { 331 token: "string.regexp", 332 regex: "/\\w*", 333 next: "start", 334 }, { 335 token : "invalid", 336 regex: /\{\d+,?(?:\d+)?}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/ 337 }, { 338 token : "constant.language.escape", 339 regex: /\(\?[:=!]|\)|{\d+,?(?:\d+)?}|{,\d+}|[+*]\?|[()$^+*?]/ 340 }, { 341 token : "constant.language.delimiter", 342 regex: /\|/ 343 }, { 344 token: "constant.language.escape", 345 regex: /\[\^?/, 346 next: "regex_character_class", 347 }, { 348 token: "empty", 349 regex: "$", 350 next: "start" 351 }, { 352 defaultToken: "string.regexp" 353 } 354 ], 355 "regex_character_class": [ 356 { 357 token: "regexp.keyword.operator", 358 regex: "\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)" 359 }, { 360 token: "constant.language.escape", 361 regex: "]", 362 next: "regex", 363 }, { 364 token: "constant.language.escape", 365 regex: "-" 366 }, { 367 token: "empty", 368 regex: "$", 369 next: "start" 370 }, { 371 defaultToken: "string.regexp.charachterclass" 372 } 373 ], 374 "function_arguments": [ 375 { 376 token: "variable.parameter", 377 regex: identifierRe 378 }, { 379 token: "punctuation.operator", 380 regex: "[, ]+", 381 }, { 382 token: "punctuation.operator", 383 regex: "$", 384 }, { 385 token: "empty", 386 regex: "", 387 next: "start" 388 } 389 ], 390 "comment_regex_allowed" : [ 391 {token : "comment", regex : "\\*\\/", next : "regex_allowed"}, 392 {defaultToken : "comment"} 393 ], 394 "comment" : [ 395 {token : "comment", regex : "\\*\\/", next : "start"}, 396 {defaultToken : "comment"} 397 ], 398 "qqstring" : [ 399 { 400 token : "constant.language.escape", 401 regex : escapedRe 402 }, { 403 token : "string", 404 regex : "\\\\$", 405 next : "qqstring", 406 }, { 407 token : "string", 408 regex : '"|$', 409 next : "start", 410 }, { 411 defaultToken: "string" 412 } 413 ], 414 "qstring" : [ 415 { 416 token : "constant.language.escape", 417 regex : escapedRe 418 }, { 419 token : "string", 420 regex : "\\\\$", 421 next : "qstring", 422 }, { 423 token : "string", 424 regex : "'|$", 425 next : "start", 426 }, { 427 defaultToken: "string" 428 } 429 ] 430 }; 431 432 this.embedRules(DocCommentHighlightRules, "doc-", 433 [ DocCommentHighlightRules.getEndRule("start") ]); 434}; 435 436oop.inherits(JavaScriptHighlightRules, TextHighlightRules); 437 438exports.JavaScriptHighlightRules = JavaScriptHighlightRules; 439}); 440 441ace.define('ace/mode/doc_comment_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text_highlight_rules'], function(require, exports, module) { 442 443 444var oop = require("../lib/oop"); 445var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; 446 447var DocCommentHighlightRules = function() { 448 449 this.$rules = { 450 "start" : [ { 451 token : "comment.doc.tag", 452 regex : "@[\\w\\d_]+" // TODO: fix email addresses 453 }, { 454 token : "comment.doc.tag", 455 regex : "\\bTODO\\b" 456 }, { 457 defaultToken : "comment.doc" 458 }] 459 }; 460}; 461 462oop.inherits(DocCommentHighlightRules, TextHighlightRules); 463 464DocCommentHighlightRules.getStartRule = function(start) { 465 return { 466 token : "comment.doc", // doc comment 467 regex : "\\/\\*(?=\\*)", 468 next : start 469 }; 470}; 471 472DocCommentHighlightRules.getEndRule = function (start) { 473 return { 474 token : "comment.doc", // closing comment 475 regex : "\\*\\/", 476 next : start 477 }; 478}; 479 480 481exports.DocCommentHighlightRules = DocCommentHighlightRules; 482 483}); 484 485ace.define('ace/mode/matching_brace_outdent', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) { 486 487 488var Range = require("../range").Range; 489 490var MatchingBraceOutdent = function() {}; 491 492(function() { 493 494 this.checkOutdent = function(line, input) { 495 if (! /^\s+$/.test(line)) 496 return false; 497 498 return /^\s*\}/.test(input); 499 }; 500 501 this.autoOutdent = function(doc, row) { 502 var line = doc.getLine(row); 503 var match = line.match(/^(\s*\})/); 504 505 if (!match) return 0; 506 507 var column = match[1].length; 508 var openBracePos = doc.findMatchingBracket({row: row, column: column}); 509 510 if (!openBracePos || openBracePos.row == row) return 0; 511 512 var indent = this.$getIndent(doc.getLine(openBracePos.row)); 513 doc.replace(new Range(row, 0, row, column-1), indent); 514 }; 515 516 this.$getIndent = function(line) { 517 var match = line.match(/^(\s+)/); 518 if (match) { 519 return match[1]; 520 } 521 522 return ""; 523 }; 524 525}).call(MatchingBraceOutdent.prototype); 526 527exports.MatchingBraceOutdent = MatchingBraceOutdent; 528}); 529 530ace.define('ace/mode/behaviour/cstyle', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/behaviour', 'ace/token_iterator', 'ace/lib/lang'], function(require, exports, module) { 531 532 533var oop = require("../../lib/oop"); 534var Behaviour = require("../behaviour").Behaviour; 535var TokenIterator = require("../../token_iterator").TokenIterator; 536var lang = require("../../lib/lang"); 537 538var SAFE_INSERT_IN_TOKENS = 539 ["text", "paren.rparen", "punctuation.operator"]; 540var SAFE_INSERT_BEFORE_TOKENS = 541 ["text", "paren.rparen", "punctuation.operator", "comment"]; 542 543 544var autoInsertedBrackets = 0; 545var autoInsertedRow = -1; 546var autoInsertedLineEnd = ""; 547var maybeInsertedBrackets = 0; 548var maybeInsertedRow = -1; 549var maybeInsertedLineStart = ""; 550var maybeInsertedLineEnd = ""; 551 552var CstyleBehaviour = function () { 553 554 CstyleBehaviour.isSaneInsertion = function(editor, session) { 555 var cursor = editor.getCursorPosition(); 556 var iterator = new TokenIterator(session, cursor.row, cursor.column); 557 if (!this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) { 558 var iterator2 = new TokenIterator(session, cursor.row, cursor.column + 1); 559 if (!this.$matchTokenType(iterator2.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) 560 return false; 561 } 562 iterator.stepForward(); 563 return iterator.getCurrentTokenRow() !== cursor.row || 564 this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_BEFORE_TOKENS); 565 }; 566 567 CstyleBehaviour.$matchTokenType = function(token, types) { 568 return types.indexOf(token.type || token) > -1; 569 }; 570 571 CstyleBehaviour.recordAutoInsert = function(editor, session, bracket) { 572 var cursor = editor.getCursorPosition(); 573 var line = session.doc.getLine(cursor.row); 574 if (!this.isAutoInsertedClosing(cursor, line, autoInsertedLineEnd[0])) 575 autoInsertedBrackets = 0; 576 autoInsertedRow = cursor.row; 577 autoInsertedLineEnd = bracket + line.substr(cursor.column); 578 autoInsertedBrackets++; 579 }; 580 581 CstyleBehaviour.recordMaybeInsert = function(editor, session, bracket) { 582 var cursor = editor.getCursorPosition(); 583 var line = session.doc.getLine(cursor.row); 584 if (!this.isMaybeInsertedClosing(cursor, line)) 585 maybeInsertedBrackets = 0; 586 maybeInsertedRow = cursor.row; 587 maybeInsertedLineStart = line.substr(0, cursor.column) + bracket; 588 maybeInsertedLineEnd = line.substr(cursor.column); 589 maybeInsertedBrackets++; 590 }; 591 592 CstyleBehaviour.isAutoInsertedClosing = function(cursor, line, bracket) { 593 return autoInsertedBrackets > 0 && 594 cursor.row === autoInsertedRow && 595 bracket === autoInsertedLineEnd[0] && 596 line.substr(cursor.column) === autoInsertedLineEnd; 597 }; 598 599 CstyleBehaviour.isMaybeInsertedClosing = function(cursor, line) { 600 return maybeInsertedBrackets > 0 && 601 cursor.row === maybeInsertedRow && 602 line.substr(cursor.column) === maybeInsertedLineEnd && 603 line.substr(0, cursor.column) == maybeInsertedLineStart; 604 }; 605 606 CstyleBehaviour.popAutoInsertedClosing = function() { 607 autoInsertedLineEnd = autoInsertedLineEnd.substr(1); 608 autoInsertedBrackets--; 609 }; 610 611 CstyleBehaviour.clearMaybeInsertedClosing = function() { 612 maybeInsertedBrackets = 0; 613 maybeInsertedRow = -1; 614 }; 615 616 this.add("braces", "insertion", function (state, action, editor, session, text) { 617 var cursor = editor.getCursorPosition(); 618 var line = session.doc.getLine(cursor.row); 619 if (text == '{') { 620 var selection = editor.getSelectionRange(); 621 var selected = session.doc.getTextRange(selection); 622 if (selected !== "" && selected !== "{" && editor.getWrapBehavioursEnabled()) { 623 return { 624 text: '{' + selected + '}', 625 selection: false 626 }; 627 } else if (CstyleBehaviour.isSaneInsertion(editor, session)) { 628 if (/[\]\}\)]/.test(line[cursor.column])) { 629 CstyleBehaviour.recordAutoInsert(editor, session, "}"); 630 return { 631 text: '{}', 632 selection: [1, 1] 633 }; 634 } else { 635 CstyleBehaviour.recordMaybeInsert(editor, session, "{"); 636 return { 637 text: '{', 638 selection: [1, 1] 639 }; 640 } 641 } 642 } else if (text == '}') { 643 var rightChar = line.substring(cursor.column, cursor.column + 1); 644 if (rightChar == '}') { 645 var matching = session.$findOpeningBracket('}', {column: cursor.column + 1, row: cursor.row}); 646 if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) { 647 CstyleBehaviour.popAutoInsertedClosing(); 648 return { 649 text: '', 650 selection: [1, 1] 651 }; 652 } 653 } 654 } else if (text == "\n" || text == "\r\n") { 655 var closing = ""; 656 if (CstyleBehaviour.isMaybeInsertedClosing(cursor, line)) { 657 closing = lang.stringRepeat("}", maybeInsertedBrackets); 658 CstyleBehaviour.clearMaybeInsertedClosing(); 659 } 660 var rightChar = line.substring(cursor.column, cursor.column + 1); 661 if (rightChar == '}' || closing !== "") { 662 var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column}, '}'); 663 if (!openBracePos) 664 return null; 665 666 var indent = this.getNextLineIndent(state, line.substring(0, cursor.column), session.getTabString()); 667 var next_indent = this.$getIndent(line); 668 669 return { 670 text: '\n' + indent + '\n' + next_indent + closing, 671 selection: [1, indent.length, 1, indent.length] 672 }; 673 } 674 } 675 }); 676 677 this.add("braces", "deletion", function (state, action, editor, session, range) { 678 var selected = session.doc.getTextRange(range); 679 if (!range.isMultiLine() && selected == '{') { 680 var line = session.doc.getLine(range.start.row); 681 var rightChar = line.substring(range.end.column, range.end.column + 1); 682 if (rightChar == '}') { 683 range.end.column++; 684 return range; 685 } else { 686 maybeInsertedBrackets--; 687 } 688 } 689 }); 690 691 this.add("parens", "insertion", function (state, action, editor, session, text) { 692 if (text == '(') { 693 var selection = editor.getSelectionRange(); 694 var selected = session.doc.getTextRange(selection); 695 if (selected !== "" && editor.getWrapBehavioursEnabled()) { 696 return { 697 text: '(' + selected + ')', 698 selection: false 699 }; 700 } else if (CstyleBehaviour.isSaneInsertion(editor, session)) { 701 CstyleBehaviour.recordAutoInsert(editor, session, ")"); 702 return { 703 text: '()', 704 selection: [1, 1] 705 }; 706 } 707 } else if (text == ')') { 708 var cursor = editor.getCursorPosition(); 709 var line = session.doc.getLine(cursor.row); 710 var rightChar = line.substring(cursor.column, cursor.column + 1); 711 if (rightChar == ')') { 712 var matching = session.$findOpeningBracket(')', {column: cursor.column + 1, row: cursor.row}); 713 if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) { 714 CstyleBehaviour.popAutoInsertedClosing(); 715 return { 716 text: '', 717 selection: [1, 1] 718 }; 719 } 720 } 721 } 722 }); 723 724 this.add("parens", "deletion", function (state, action, editor, session, range) { 725 var selected = session.doc.getTextRange(range); 726 if (!range.isMultiLine() && selected == '(') { 727 var line = session.doc.getLine(range.start.row); 728 var rightChar = line.substring(range.start.column + 1, range.start.column + 2); 729 if (rightChar == ')') { 730 range.end.column++; 731 return range; 732 } 733 } 734 }); 735 736 this.add("brackets", "insertion", function (state, action, editor, session, text) { 737 if (text == '[') { 738 var selection = editor.getSelectionRange(); 739 var selected = session.doc.getTextRange(selection); 740 if (selected !== "" && editor.getWrapBehavioursEnabled()) { 741 return { 742 text: '[' + selected + ']', 743 selection: false 744 }; 745 } else if (CstyleBehaviour.isSaneInsertion(editor, session)) { 746 CstyleBehaviour.recordAutoInsert(editor, session, "]"); 747 return { 748 text: '[]', 749 selection: [1, 1] 750 }; 751 } 752 } else if (text == ']') { 753 var cursor = editor.getCursorPosition(); 754 var line = session.doc.getLine(cursor.row); 755 var rightChar = line.substring(cursor.column, cursor.column + 1); 756 if (rightChar == ']') { 757 var matching = session.$findOpeningBracket(']', {column: cursor.column + 1, row: cursor.row}); 758 if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) { 759 CstyleBehaviour.popAutoInsertedClosing(); 760 return { 761 text: '', 762 selection: [1, 1] 763 }; 764 } 765 } 766 } 767 }); 768 769 this.add("brackets", "deletion", function (state, action, editor, session, range) { 770 var selected = session.doc.getTextRange(range); 771 if (!range.isMultiLine() && selected == '[') { 772 var line = session.doc.getLine(range.start.row); 773 var rightChar = line.substring(range.start.column + 1, range.start.column + 2); 774 if (rightChar == ']') { 775 range.end.column++; 776 return range; 777 } 778 } 779 }); 780 781 this.add("string_dquotes", "insertion", function (state, action, editor, session, text) { 782 if (text == '"' || text == "'") { 783 var quote = text; 784 var selection = editor.getSelectionRange(); 785 var selected = session.doc.getTextRange(selection); 786 if (selected !== "" && selected !== "'" && selected != '"' && editor.getWrapBehavioursEnabled()) { 787 return { 788 text: quote + selected + quote, 789 selection: false 790 }; 791 } else { 792 var cursor = editor.getCursorPosition(); 793 var line = session.doc.getLine(cursor.row); 794 var leftChar = line.substring(cursor.column-1, cursor.column); 795 if (leftChar == '\\') { 796 return null; 797 } 798 var tokens = session.getTokens(selection.start.row); 799 var col = 0, token; 800 var quotepos = -1; // Track whether we're inside an open quote. 801 802 for (var x = 0; x < tokens.length; x++) { 803 token = tokens[x]; 804 if (token.type == "string") { 805 quotepos = -1; 806 } else if (quotepos < 0) { 807 quotepos = token.value.indexOf(quote); 808 } 809 if ((token.value.length + col) > selection.start.column) { 810 break; 811 } 812 col += tokens[x].value.length; 813 } 814 if (!token || (quotepos < 0 && token.type !== "comment" && (token.type !== "string" || ((selection.start.column !== token.value.length+col-1) && token.value.lastIndexOf(quote) === token.value.length-1)))) { 815 if (!CstyleBehaviour.isSaneInsertion(editor, session)) 816 return; 817 return { 818 text: quote + quote, 819 selection: [1,1] 820 }; 821 } else if (token && token.type === "string") { 822 var rightChar = line.substring(cursor.column, cursor.column + 1); 823 if (rightChar == quote) { 824 return { 825 text: '', 826 selection: [1, 1] 827 }; 828 } 829 } 830 } 831 } 832 }); 833 834 this.add("string_dquotes", "deletion", function (state, action, editor, session, range) { 835 var selected = session.doc.getTextRange(range); 836 if (!range.isMultiLine() && (selected == '"' || selected == "'")) { 837 var line = session.doc.getLine(range.start.row); 838 var rightChar = line.substring(range.start.column + 1, range.start.column + 2); 839 if (rightChar == selected) { 840 range.end.column++; 841 return range; 842 } 843 } 844 }); 845 846}; 847 848oop.inherits(CstyleBehaviour, Behaviour); 849 850exports.CstyleBehaviour = CstyleBehaviour; 851}); 852 853ace.define('ace/mode/folding/cstyle', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/range', 'ace/mode/folding/fold_mode'], function(require, exports, module) { 854 855 856var oop = require("../../lib/oop"); 857var Range = require("../../range").Range; 858var BaseFoldMode = require("./fold_mode").FoldMode; 859 860var FoldMode = exports.FoldMode = function() {}; 861oop.inherits(FoldMode, BaseFoldMode); 862 863(function() { 864 865 this.foldingStartMarker = /(\{|\[)[^\}\]]*$|^\s*(\/\*)/; 866 this.foldingStopMarker = /^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/; 867 868 this.getFoldWidgetRange = function(session, foldStyle, row) { 869 var line = session.getLine(row); 870 var match = line.match(this.foldingStartMarker); 871 if (match) { 872 var i = match.index; 873 874 if (match[1]) 875 return this.openingBracketBlock(session, match[1], row, i); 876 877 return session.getCommentFoldRange(row, i + match[0].length, 1); 878 } 879 880 if (foldStyle !== "markbeginend") 881 return; 882 883 var match = line.match(this.foldingStopMarker); 884 if (match) { 885 var i = match.index + match[0].length; 886 887 if (match[1]) 888 return this.closingBracketBlock(session, match[1], row, i); 889 890 return session.getCommentFoldRange(row, i, -1); 891 } 892 }; 893 894}).call(FoldMode.prototype); 895 896}); 897