OLD | NEW |
(Empty) | |
| 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others |
| 2 // Distributed under an MIT license: http://codemirror.net/LICENSE |
| 3 |
| 4 // Stylus mode created by Dmitry Kiselyov http://git.io/AaRB |
| 5 |
| 6 (function(mod) { |
| 7 if (typeof exports == "object" && typeof module == "object") // CommonJS |
| 8 mod(require("../../lib/codemirror")); |
| 9 else if (typeof define == "function" && define.amd) // AMD |
| 10 define(["../../lib/codemirror"], mod); |
| 11 else // Plain browser env |
| 12 mod(CodeMirror); |
| 13 })(function(CodeMirror) { |
| 14 "use strict"; |
| 15 |
| 16 CodeMirror.defineMode("stylus", function(config) { |
| 17 var indentUnit = config.indentUnit, |
| 18 tagKeywords = keySet(tagKeywords_), |
| 19 tagVariablesRegexp = /^(a|b|i|s|col|em)$/i, |
| 20 propertyKeywords = keySet(propertyKeywords_), |
| 21 nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_), |
| 22 valueKeywords = keySet(valueKeywords_), |
| 23 colorKeywords = keySet(colorKeywords_), |
| 24 documentTypes = keySet(documentTypes_), |
| 25 documentTypesRegexp = wordRegexp(documentTypes_), |
| 26 mediaFeatures = keySet(mediaFeatures_), |
| 27 mediaTypes = keySet(mediaTypes_), |
| 28 fontProperties = keySet(fontProperties_), |
| 29 operatorsRegexp = /^\s*([.]{2,3}|&&|\|\||\*\*|[?!=:]?=|[-+*\/%<>]=?|\?:|
\~)/, |
| 30 wordOperatorKeywordsRegexp = wordRegexp(wordOperatorKeywords_), |
| 31 blockKeywords = keySet(blockKeywords_), |
| 32 vendorPrefixesRegexp = new RegExp(/^\-(moz|ms|o|webkit)-/i), |
| 33 commonAtoms = keySet(commonAtoms_), |
| 34 firstWordMatch = "", |
| 35 states = {}, |
| 36 ch, |
| 37 style, |
| 38 type, |
| 39 override; |
| 40 |
| 41 /** |
| 42 * Tokenizers |
| 43 */ |
| 44 function tokenBase(stream, state) { |
| 45 firstWordMatch = stream.string.match(/(^[\w-]+\s*=\s*$)|(^\s*[\w-]+\s*=\s*
[\w-])|(^\s*(\.|#|@|\$|\&|\[|\d|\+|::?|\{|\>|~|\/)?\s*[\w-]*([a-z0-9-]|\*|\/\*)(
\(|,)?)/); |
| 46 state.context.line.firstWord = firstWordMatch ? firstWordMatch[0].replace(
/^\s*/, "") : ""; |
| 47 state.context.line.indent = stream.indentation(); |
| 48 ch = stream.peek(); |
| 49 |
| 50 // Line comment |
| 51 if (stream.match("//")) { |
| 52 stream.skipToEnd(); |
| 53 return ["comment", "comment"]; |
| 54 } |
| 55 // Block comment |
| 56 if (stream.match("/*")) { |
| 57 state.tokenize = tokenCComment; |
| 58 return tokenCComment(stream, state); |
| 59 } |
| 60 // String |
| 61 if (ch == "\"" || ch == "'") { |
| 62 stream.next(); |
| 63 state.tokenize = tokenString(ch); |
| 64 return state.tokenize(stream, state); |
| 65 } |
| 66 // Def |
| 67 if (ch == "@") { |
| 68 stream.next(); |
| 69 stream.eatWhile(/[\w\\-]/); |
| 70 return ["def", stream.current()]; |
| 71 } |
| 72 // ID selector or Hex color |
| 73 if (ch == "#") { |
| 74 stream.next(); |
| 75 // Hex color |
| 76 if (stream.match(/^[0-9a-f]{6}|[0-9a-f]{3}/i)) { |
| 77 return ["atom", "atom"]; |
| 78 } |
| 79 // ID selector |
| 80 if (stream.match(/^[a-z][\w-]*/i)) { |
| 81 return ["builtin", "hash"]; |
| 82 } |
| 83 } |
| 84 // Vendor prefixes |
| 85 if (stream.match(vendorPrefixesRegexp)) { |
| 86 return ["meta", "vendor-prefixes"]; |
| 87 } |
| 88 // Numbers |
| 89 if (stream.match(/^-?[0-9]?\.?[0-9]/)) { |
| 90 stream.eatWhile(/[a-z%]/i); |
| 91 return ["number", "unit"]; |
| 92 } |
| 93 // !important|optional |
| 94 if (ch == "!") { |
| 95 stream.next(); |
| 96 return [stream.match(/^(important|optional)/i) ? "keyword": "operator",
"important"]; |
| 97 } |
| 98 // Class |
| 99 if (ch == "." && stream.match(/^\.[a-z][\w-]*/i)) { |
| 100 return ["qualifier", "qualifier"]; |
| 101 } |
| 102 // url url-prefix domain regexp |
| 103 if (stream.match(documentTypesRegexp)) { |
| 104 if (stream.peek() == "(") state.tokenize = tokenParenthesized; |
| 105 return ["property", "word"]; |
| 106 } |
| 107 // Mixins / Functions |
| 108 if (stream.match(/^[a-z][\w-]*\(/i)) { |
| 109 stream.backUp(1); |
| 110 return ["keyword", "mixin"]; |
| 111 } |
| 112 // Block mixins |
| 113 if (stream.match(/^(\+|-)[a-z][\w-]*\(/i)) { |
| 114 stream.backUp(1); |
| 115 return ["keyword", "block-mixin"]; |
| 116 } |
| 117 // Parent Reference BEM naming |
| 118 if (stream.string.match(/^\s*&/) && stream.match(/^[-_]+[a-z][\w-]*/)) { |
| 119 return ["qualifier", "qualifier"]; |
| 120 } |
| 121 // / Root Reference & Parent Reference |
| 122 if (stream.match(/^(\/|&)(-|_|:|\.|#|[a-z])/)) { |
| 123 stream.backUp(1); |
| 124 return ["variable-3", "reference"]; |
| 125 } |
| 126 if (stream.match(/^&{1}\s*$/)) { |
| 127 return ["variable-3", "reference"]; |
| 128 } |
| 129 // Word operator |
| 130 if (stream.match(wordOperatorKeywordsRegexp)) { |
| 131 return ["operator", "operator"]; |
| 132 } |
| 133 // Word |
| 134 if (stream.match(/^\$?[-_]*[a-z0-9]+[\w-]*/i)) { |
| 135 // Variable |
| 136 if (stream.match(/^(\.|\[)[\w-\'\"\]]+/i, false)) { |
| 137 if (!wordIsTag(stream.current())) { |
| 138 stream.match(/\./); |
| 139 return ["variable-2", "variable-name"]; |
| 140 } |
| 141 } |
| 142 return ["variable-2", "word"]; |
| 143 } |
| 144 // Operators |
| 145 if (stream.match(operatorsRegexp)) { |
| 146 return ["operator", stream.current()]; |
| 147 } |
| 148 // Delimiters |
| 149 if (/[:;,{}\[\]\(\)]/.test(ch)) { |
| 150 stream.next(); |
| 151 return [null, ch]; |
| 152 } |
| 153 // Non-detected items |
| 154 stream.next(); |
| 155 return [null, null]; |
| 156 } |
| 157 |
| 158 /** |
| 159 * Token comment |
| 160 */ |
| 161 function tokenCComment(stream, state) { |
| 162 var maybeEnd = false, ch; |
| 163 while ((ch = stream.next()) != null) { |
| 164 if (maybeEnd && ch == "/") { |
| 165 state.tokenize = null; |
| 166 break; |
| 167 } |
| 168 maybeEnd = (ch == "*"); |
| 169 } |
| 170 return ["comment", "comment"]; |
| 171 } |
| 172 |
| 173 /** |
| 174 * Token string |
| 175 */ |
| 176 function tokenString(quote) { |
| 177 return function(stream, state) { |
| 178 var escaped = false, ch; |
| 179 while ((ch = stream.next()) != null) { |
| 180 if (ch == quote && !escaped) { |
| 181 if (quote == ")") stream.backUp(1); |
| 182 break; |
| 183 } |
| 184 escaped = !escaped && ch == "\\"; |
| 185 } |
| 186 if (ch == quote || !escaped && quote != ")") state.tokenize = null; |
| 187 return ["string", "string"]; |
| 188 }; |
| 189 } |
| 190 |
| 191 /** |
| 192 * Token parenthesized |
| 193 */ |
| 194 function tokenParenthesized(stream, state) { |
| 195 stream.next(); // Must be "(" |
| 196 if (!stream.match(/\s*[\"\')]/, false)) |
| 197 state.tokenize = tokenString(")"); |
| 198 else |
| 199 state.tokenize = null; |
| 200 return [null, "("]; |
| 201 } |
| 202 |
| 203 /** |
| 204 * Context management |
| 205 */ |
| 206 function Context(type, indent, prev, line) { |
| 207 this.type = type; |
| 208 this.indent = indent; |
| 209 this.prev = prev; |
| 210 this.line = line || {firstWord: "", indent: 0}; |
| 211 } |
| 212 |
| 213 function pushContext(state, stream, type, indent) { |
| 214 indent = indent >= 0 ? indent : indentUnit; |
| 215 state.context = new Context(type, stream.indentation() + indent, state.con
text); |
| 216 return type; |
| 217 } |
| 218 |
| 219 function popContext(state, currentIndent) { |
| 220 var contextIndent = state.context.indent - indentUnit; |
| 221 currentIndent = currentIndent || false; |
| 222 state.context = state.context.prev; |
| 223 if (currentIndent) state.context.indent = contextIndent; |
| 224 return state.context.type; |
| 225 } |
| 226 |
| 227 function pass(type, stream, state) { |
| 228 return states[state.context.type](type, stream, state); |
| 229 } |
| 230 |
| 231 function popAndPass(type, stream, state, n) { |
| 232 for (var i = n || 1; i > 0; i--) |
| 233 state.context = state.context.prev; |
| 234 return pass(type, stream, state); |
| 235 } |
| 236 |
| 237 |
| 238 /** |
| 239 * Parser |
| 240 */ |
| 241 function wordIsTag(word) { |
| 242 return word.toLowerCase() in tagKeywords; |
| 243 } |
| 244 |
| 245 function wordIsProperty(word) { |
| 246 word = word.toLowerCase(); |
| 247 return word in propertyKeywords || word in fontProperties; |
| 248 } |
| 249 |
| 250 function wordIsBlock(word) { |
| 251 return word.toLowerCase() in blockKeywords; |
| 252 } |
| 253 |
| 254 function wordIsVendorPrefix(word) { |
| 255 return word.toLowerCase().match(vendorPrefixesRegexp); |
| 256 } |
| 257 |
| 258 function wordAsValue(word) { |
| 259 var wordLC = word.toLowerCase(); |
| 260 var override = "variable-2"; |
| 261 if (wordIsTag(word)) override = "tag"; |
| 262 else if (wordIsBlock(word)) override = "block-keyword"; |
| 263 else if (wordIsProperty(word)) override = "property"; |
| 264 else if (wordLC in valueKeywords || wordLC in commonAtoms) override = "ato
m"; |
| 265 else if (wordLC == "return" || wordLC in colorKeywords) override = "keywor
d"; |
| 266 |
| 267 // Font family |
| 268 else if (word.match(/^[A-Z]/)) override = "string"; |
| 269 return override; |
| 270 } |
| 271 |
| 272 function typeIsBlock(type, stream) { |
| 273 return ((endOfLine(stream) && (type == "{" || type == "]" || type == "hash
" || type == "qualifier")) || type == "block-mixin"); |
| 274 } |
| 275 |
| 276 function typeIsInterpolation(type, stream) { |
| 277 return type == "{" && stream.match(/^\s*\$?[\w-]+/i, false); |
| 278 } |
| 279 |
| 280 function typeIsPseudo(type, stream) { |
| 281 return type == ":" && stream.match(/^[a-z-]+/, false); |
| 282 } |
| 283 |
| 284 function startOfLine(stream) { |
| 285 return stream.sol() || stream.string.match(new RegExp("^\\s*" + escapeRegE
xp(stream.current()))); |
| 286 } |
| 287 |
| 288 function endOfLine(stream) { |
| 289 return stream.eol() || stream.match(/^\s*$/, false); |
| 290 } |
| 291 |
| 292 function firstWordOfLine(line) { |
| 293 var re = /^\s*[-_]*[a-z0-9]+[\w-]*/i; |
| 294 var result = typeof line == "string" ? line.match(re) : line.string.match(
re); |
| 295 return result ? result[0].replace(/^\s*/, "") : ""; |
| 296 } |
| 297 |
| 298 |
| 299 /** |
| 300 * Block |
| 301 */ |
| 302 states.block = function(type, stream, state) { |
| 303 if ((type == "comment" && startOfLine(stream)) || |
| 304 (type == "," && endOfLine(stream)) || |
| 305 type == "mixin") { |
| 306 return pushContext(state, stream, "block", 0); |
| 307 } |
| 308 if (typeIsInterpolation(type, stream)) { |
| 309 return pushContext(state, stream, "interpolation"); |
| 310 } |
| 311 if (endOfLine(stream) && type == "]") { |
| 312 if (!/^\s*(\.|#|:|\[|\*|&)/.test(stream.string) && !wordIsTag(firstWordO
fLine(stream))) { |
| 313 return pushContext(state, stream, "block", 0); |
| 314 } |
| 315 } |
| 316 if (typeIsBlock(type, stream, state)) { |
| 317 return pushContext(state, stream, "block"); |
| 318 } |
| 319 if (type == "}" && endOfLine(stream)) { |
| 320 return pushContext(state, stream, "block", 0); |
| 321 } |
| 322 if (type == "variable-name") { |
| 323 if (stream.string.match(/^\s?\$[\w-\.\[\]\'\"]+$/) || wordIsBlock(firstW
ordOfLine(stream))) { |
| 324 return pushContext(state, stream, "variableName"); |
| 325 } |
| 326 else { |
| 327 return pushContext(state, stream, "variableName", 0); |
| 328 } |
| 329 } |
| 330 if (type == "=") { |
| 331 if (!endOfLine(stream) && !wordIsBlock(firstWordOfLine(stream))) { |
| 332 return pushContext(state, stream, "block", 0); |
| 333 } |
| 334 return pushContext(state, stream, "block"); |
| 335 } |
| 336 if (type == "*") { |
| 337 if (endOfLine(stream) || stream.match(/\s*(,|\.|#|\[|:|{)/,false)) { |
| 338 override = "tag"; |
| 339 return pushContext(state, stream, "block"); |
| 340 } |
| 341 } |
| 342 if (typeIsPseudo(type, stream)) { |
| 343 return pushContext(state, stream, "pseudo"); |
| 344 } |
| 345 if (/@(font-face|media|supports|(-moz-)?document)/.test(type)) { |
| 346 return pushContext(state, stream, endOfLine(stream) ? "block" : "atBlock
"); |
| 347 } |
| 348 if (/@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) { |
| 349 return pushContext(state, stream, "keyframes"); |
| 350 } |
| 351 if (/@extends?/.test(type)) { |
| 352 return pushContext(state, stream, "extend", 0); |
| 353 } |
| 354 if (type && type.charAt(0) == "@") { |
| 355 |
| 356 // Property Lookup |
| 357 if (stream.indentation() > 0 && wordIsProperty(stream.current().slice(1)
)) { |
| 358 override = "variable-2"; |
| 359 return "block"; |
| 360 } |
| 361 if (/(@import|@require|@charset)/.test(type)) { |
| 362 return pushContext(state, stream, "block", 0); |
| 363 } |
| 364 return pushContext(state, stream, "block"); |
| 365 } |
| 366 if (type == "reference" && endOfLine(stream)) { |
| 367 return pushContext(state, stream, "block"); |
| 368 } |
| 369 if (type == "(") { |
| 370 return pushContext(state, stream, "parens"); |
| 371 } |
| 372 |
| 373 if (type == "vendor-prefixes") { |
| 374 return pushContext(state, stream, "vendorPrefixes"); |
| 375 } |
| 376 if (type == "word") { |
| 377 var word = stream.current(); |
| 378 override = wordAsValue(word); |
| 379 |
| 380 if (override == "property") { |
| 381 if (startOfLine(stream)) { |
| 382 return pushContext(state, stream, "block", 0); |
| 383 } else { |
| 384 override = "atom"; |
| 385 return "block"; |
| 386 } |
| 387 } |
| 388 |
| 389 if (override == "tag") { |
| 390 |
| 391 // tag is a css value |
| 392 if (/embed|menu|pre|progress|sub|table/.test(word)) { |
| 393 if (wordIsProperty(firstWordOfLine(stream))) { |
| 394 override = "atom"; |
| 395 return "block"; |
| 396 } |
| 397 } |
| 398 |
| 399 // tag is an attribute |
| 400 if (stream.string.match(new RegExp("\\[\\s*" + word + "|" + word +"\\s
*\\]"))) { |
| 401 override = "atom"; |
| 402 return "block"; |
| 403 } |
| 404 |
| 405 // tag is a variable |
| 406 if (tagVariablesRegexp.test(word)) { |
| 407 if ((startOfLine(stream) && stream.string.match(/=/)) || |
| 408 (!startOfLine(stream) && |
| 409 !stream.string.match(/^(\s*\.|#|\&|\[|\/|>|\*)/) && |
| 410 !wordIsTag(firstWordOfLine(stream)))) { |
| 411 override = "variable-2"; |
| 412 if (wordIsBlock(firstWordOfLine(stream))) return "block"; |
| 413 return pushContext(state, stream, "block", 0); |
| 414 } |
| 415 } |
| 416 |
| 417 if (endOfLine(stream)) return pushContext(state, stream, "block"); |
| 418 } |
| 419 if (override == "block-keyword") { |
| 420 override = "keyword"; |
| 421 |
| 422 // Postfix conditionals |
| 423 if (stream.current(/(if|unless)/) && !startOfLine(stream)) { |
| 424 return "block"; |
| 425 } |
| 426 return pushContext(state, stream, "block"); |
| 427 } |
| 428 if (word == "return") return pushContext(state, stream, "block", 0); |
| 429 |
| 430 // Placeholder selector |
| 431 if (override == "variable-2" && stream.string.match(/^\s?\$[\w-\.\[\]\'\
"]+$/)) { |
| 432 return pushContext(state, stream, "block"); |
| 433 } |
| 434 } |
| 435 return state.context.type; |
| 436 }; |
| 437 |
| 438 |
| 439 /** |
| 440 * Parens |
| 441 */ |
| 442 states.parens = function(type, stream, state) { |
| 443 if (type == "(") return pushContext(state, stream, "parens"); |
| 444 if (type == ")") { |
| 445 if (state.context.prev.type == "parens") { |
| 446 return popContext(state); |
| 447 } |
| 448 if ((stream.string.match(/^[a-z][\w-]*\(/i) && endOfLine(stream)) || |
| 449 wordIsBlock(firstWordOfLine(stream)) || |
| 450 /(\.|#|:|\[|\*|&|>|~|\+|\/)/.test(firstWordOfLine(stream)) || |
| 451 (!stream.string.match(/^-?[a-z][\w-\.\[\]\'\"]*\s*=/) && |
| 452 wordIsTag(firstWordOfLine(stream)))) { |
| 453 return pushContext(state, stream, "block"); |
| 454 } |
| 455 if (stream.string.match(/^[\$-]?[a-z][\w-\.\[\]\'\"]*\s*=/) || |
| 456 stream.string.match(/^\s*(\(|\)|[0-9])/) || |
| 457 stream.string.match(/^\s+[a-z][\w-]*\(/i) || |
| 458 stream.string.match(/^\s+[\$-]?[a-z]/i)) { |
| 459 return pushContext(state, stream, "block", 0); |
| 460 } |
| 461 if (endOfLine(stream)) return pushContext(state, stream, "block"); |
| 462 else return pushContext(state, stream, "block", 0); |
| 463 } |
| 464 if (type && type.charAt(0) == "@" && wordIsProperty(stream.current().slice
(1))) { |
| 465 override = "variable-2"; |
| 466 } |
| 467 if (type == "word") { |
| 468 var word = stream.current(); |
| 469 override = wordAsValue(word); |
| 470 if (override == "tag" && tagVariablesRegexp.test(word)) { |
| 471 override = "variable-2"; |
| 472 } |
| 473 if (override == "property" || word == "to") override = "atom"; |
| 474 } |
| 475 if (type == "variable-name") { |
| 476 return pushContext(state, stream, "variableName"); |
| 477 } |
| 478 if (typeIsPseudo(type, stream)) { |
| 479 return pushContext(state, stream, "pseudo"); |
| 480 } |
| 481 return state.context.type; |
| 482 }; |
| 483 |
| 484 |
| 485 /** |
| 486 * Vendor prefixes |
| 487 */ |
| 488 states.vendorPrefixes = function(type, stream, state) { |
| 489 if (type == "word") { |
| 490 override = "property"; |
| 491 return pushContext(state, stream, "block", 0); |
| 492 } |
| 493 return popContext(state); |
| 494 }; |
| 495 |
| 496 |
| 497 /** |
| 498 * Pseudo |
| 499 */ |
| 500 states.pseudo = function(type, stream, state) { |
| 501 if (!wordIsProperty(firstWordOfLine(stream.string))) { |
| 502 stream.match(/^[a-z-]+/); |
| 503 override = "variable-3"; |
| 504 if (endOfLine(stream)) return pushContext(state, stream, "block"); |
| 505 return popContext(state); |
| 506 } |
| 507 return popAndPass(type, stream, state); |
| 508 }; |
| 509 |
| 510 |
| 511 /** |
| 512 * atBlock |
| 513 */ |
| 514 states.atBlock = function(type, stream, state) { |
| 515 if (type == "(") return pushContext(state, stream, "atBlock_parens"); |
| 516 if (typeIsBlock(type, stream, state)) { |
| 517 return pushContext(state, stream, "block"); |
| 518 } |
| 519 if (typeIsInterpolation(type, stream)) { |
| 520 return pushContext(state, stream, "interpolation"); |
| 521 } |
| 522 if (type == "word") { |
| 523 var word = stream.current().toLowerCase(); |
| 524 if (/^(only|not|and|or)$/.test(word)) |
| 525 override = "keyword"; |
| 526 else if (documentTypes.hasOwnProperty(word)) |
| 527 override = "tag"; |
| 528 else if (mediaTypes.hasOwnProperty(word)) |
| 529 override = "attribute"; |
| 530 else if (mediaFeatures.hasOwnProperty(word)) |
| 531 override = "property"; |
| 532 else if (nonStandardPropertyKeywords.hasOwnProperty(word)) |
| 533 override = "string-2"; |
| 534 else override = wordAsValue(stream.current()); |
| 535 if (override == "tag" && endOfLine(stream)) { |
| 536 return pushContext(state, stream, "block"); |
| 537 } |
| 538 } |
| 539 if (type == "operator" && /^(not|and|or)$/.test(stream.current())) { |
| 540 override = "keyword"; |
| 541 } |
| 542 return state.context.type; |
| 543 }; |
| 544 |
| 545 states.atBlock_parens = function(type, stream, state) { |
| 546 if (type == "{" || type == "}") return state.context.type; |
| 547 if (type == ")") { |
| 548 if (endOfLine(stream)) return pushContext(state, stream, "block"); |
| 549 else return pushContext(state, stream, "atBlock"); |
| 550 } |
| 551 if (type == "word") { |
| 552 var word = stream.current().toLowerCase(); |
| 553 override = wordAsValue(word); |
| 554 if (/^(max|min)/.test(word)) override = "property"; |
| 555 if (override == "tag") { |
| 556 tagVariablesRegexp.test(word) ? override = "variable-2" : override = "
atom"; |
| 557 } |
| 558 return state.context.type; |
| 559 } |
| 560 return states.atBlock(type, stream, state); |
| 561 }; |
| 562 |
| 563 |
| 564 /** |
| 565 * Keyframes |
| 566 */ |
| 567 states.keyframes = function(type, stream, state) { |
| 568 if (stream.indentation() == "0" && ((type == "}" && startOfLine(stream)) |
| type == "]" || type == "hash" |
| 569 || type == "qualifier" || wordIsTag(st
ream.current()))) { |
| 570 return popAndPass(type, stream, state); |
| 571 } |
| 572 if (type == "{") return pushContext(state, stream, "keyframes"); |
| 573 if (type == "}") { |
| 574 if (startOfLine(stream)) return popContext(state, true); |
| 575 else return pushContext(state, stream, "keyframes"); |
| 576 } |
| 577 if (type == "unit" && /^[0-9]+\%$/.test(stream.current())) { |
| 578 return pushContext(state, stream, "keyframes"); |
| 579 } |
| 580 if (type == "word") { |
| 581 override = wordAsValue(stream.current()); |
| 582 if (override == "block-keyword") { |
| 583 override = "keyword"; |
| 584 return pushContext(state, stream, "keyframes"); |
| 585 } |
| 586 } |
| 587 if (/@(font-face|media|supports|(-moz-)?document)/.test(type)) { |
| 588 return pushContext(state, stream, endOfLine(stream) ? "block" : "atBlock
"); |
| 589 } |
| 590 if (type == "mixin") { |
| 591 return pushContext(state, stream, "block", 0); |
| 592 } |
| 593 return state.context.type; |
| 594 }; |
| 595 |
| 596 |
| 597 /** |
| 598 * Interpolation |
| 599 */ |
| 600 states.interpolation = function(type, stream, state) { |
| 601 if (type == "{") popContext(state) && pushContext(state, stream, "block"); |
| 602 if (type == "}") { |
| 603 if (stream.string.match(/^\s*(\.|#|:|\[|\*|&|>|~|\+|\/)/i) || |
| 604 (stream.string.match(/^\s*[a-z]/i) && wordIsTag(firstWordOfLine(stre
am)))) { |
| 605 return pushContext(state, stream, "block"); |
| 606 } |
| 607 if (!stream.string.match(/^(\{|\s*\&)/) || |
| 608 stream.match(/\s*[\w-]/,false)) { |
| 609 return pushContext(state, stream, "block", 0); |
| 610 } |
| 611 return pushContext(state, stream, "block"); |
| 612 } |
| 613 if (type == "variable-name") { |
| 614 return pushContext(state, stream, "variableName", 0); |
| 615 } |
| 616 if (type == "word") { |
| 617 override = wordAsValue(stream.current()); |
| 618 if (override == "tag") override = "atom"; |
| 619 } |
| 620 return state.context.type; |
| 621 }; |
| 622 |
| 623 |
| 624 /** |
| 625 * Extend/s |
| 626 */ |
| 627 states.extend = function(type, stream, state) { |
| 628 if (type == "[" || type == "=") return "extend"; |
| 629 if (type == "]") return popContext(state); |
| 630 if (type == "word") { |
| 631 override = wordAsValue(stream.current()); |
| 632 return "extend"; |
| 633 } |
| 634 return popContext(state); |
| 635 }; |
| 636 |
| 637 |
| 638 /** |
| 639 * Variable name |
| 640 */ |
| 641 states.variableName = function(type, stream, state) { |
| 642 if (type == "string" || type == "[" || type == "]" || stream.current().mat
ch(/^(\.|\$)/)) { |
| 643 if (stream.current().match(/^\.[\w-]+/i)) override = "variable-2"; |
| 644 return "variableName"; |
| 645 } |
| 646 return popAndPass(type, stream, state); |
| 647 }; |
| 648 |
| 649 |
| 650 return { |
| 651 startState: function(base) { |
| 652 return { |
| 653 tokenize: null, |
| 654 state: "block", |
| 655 context: new Context("block", base || 0, null) |
| 656 }; |
| 657 }, |
| 658 token: function(stream, state) { |
| 659 if (!state.tokenize && stream.eatSpace()) return null; |
| 660 style = (state.tokenize || tokenBase)(stream, state); |
| 661 if (style && typeof style == "object") { |
| 662 type = style[1]; |
| 663 style = style[0]; |
| 664 } |
| 665 override = style; |
| 666 state.state = states[state.state](type, stream, state); |
| 667 return override; |
| 668 }, |
| 669 indent: function(state, textAfter, line) { |
| 670 |
| 671 var cx = state.context, |
| 672 ch = textAfter && textAfter.charAt(0), |
| 673 indent = cx.indent, |
| 674 lineFirstWord = firstWordOfLine(textAfter), |
| 675 lineIndent = line.length - line.replace(/^\s*/, "").length, |
| 676 prevLineFirstWord = state.context.prev ? state.context.prev.line.fir
stWord : "", |
| 677 prevLineIndent = state.context.prev ? state.context.prev.line.indent
: lineIndent; |
| 678 |
| 679 if (cx.prev && |
| 680 (ch == "}" && (cx.type == "block" || cx.type == "atBlock" || cx.type
== "keyframes") || |
| 681 ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") |
| |
| 682 ch == "{" && (cx.type == "at"))) { |
| 683 indent = cx.indent - indentUnit; |
| 684 cx = cx.prev; |
| 685 } else if (!(/(\})/.test(ch))) { |
| 686 if (/@|\$|\d/.test(ch) || |
| 687 /^\{/.test(textAfter) || |
| 688 /^\s*\/(\/|\*)/.test(textAfter) || |
| 689 /^\s*\/\*/.test(prevLineFirstWord) || |
| 690 /^\s*[\w-\.\[\]\'\"]+\s*(\?|:|\+)?=/i.test(textAfter) || |
| 691 /^(\+|-)?[a-z][\w-]*\(/i.test(textAfter) || |
| 692 /^return/.test(textAfter) || |
| 693 wordIsBlock(lineFirstWord)) { |
| 694 indent = lineIndent; |
| 695 } else if (/(\.|#|:|\[|\*|&|>|~|\+|\/)/.test(ch) || wordIsTag(lineFirs
tWord)) { |
| 696 if (/\,\s*$/.test(prevLineFirstWord)) { |
| 697 indent = prevLineIndent; |
| 698 } else if (/^\s+/.test(line) && (/(\.|#|:|\[|\*|&|>|~|\+|\/)/.test(p
revLineFirstWord) || wordIsTag(prevLineFirstWord))) { |
| 699 indent = lineIndent <= prevLineIndent ? prevLineIndent : prevLineI
ndent + indentUnit; |
| 700 } else { |
| 701 indent = lineIndent; |
| 702 } |
| 703 } else if (!/,\s*$/.test(line) && (wordIsVendorPrefix(lineFirstWord) |
| wordIsProperty(lineFirstWord))) { |
| 704 if (wordIsBlock(prevLineFirstWord)) { |
| 705 indent = lineIndent <= prevLineIndent ? prevLineIndent : prevLineI
ndent + indentUnit; |
| 706 } else if (/^\{/.test(prevLineFirstWord)) { |
| 707 indent = lineIndent <= prevLineIndent ? lineIndent : prevLineInden
t + indentUnit; |
| 708 } else if (wordIsVendorPrefix(prevLineFirstWord) || wordIsProperty(p
revLineFirstWord)) { |
| 709 indent = lineIndent >= prevLineIndent ? prevLineIndent : lineInden
t; |
| 710 } else if (/^(\.|#|:|\[|\*|&|@|\+|\-|>|~|\/)/.test(prevLineFirstWord
) || |
| 711 /=\s*$/.test(prevLineFirstWord) || |
| 712 wordIsTag(prevLineFirstWord) || |
| 713 /^\$[\w-\.\[\]\'\"]/.test(prevLineFirstWord)) { |
| 714 indent = prevLineIndent + indentUnit; |
| 715 } else { |
| 716 indent = lineIndent; |
| 717 } |
| 718 } |
| 719 } |
| 720 return indent; |
| 721 }, |
| 722 electricChars: "}", |
| 723 lineComment: "//", |
| 724 fold: "indent" |
| 725 }; |
| 726 }); |
| 727 |
| 728 // developer.mozilla.org/en-US/docs/Web/HTML/Element |
| 729 var tagKeywords_ = ["a","abbr","address","area","article","aside","audio", "b"
, "base","bdi", "bdo","bgsound","blockquote","body","br","button","canvas","capt
ion","cite", "code","col","colgroup","data","datalist","dd","del","details","dfn
","div", "dl","dt","em","embed","fieldset","figcaption","figure","footer","form"
,"h1", "h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe
", "img","input","ins","kbd","keygen","label","legend","li","link","main","map",
"mark","marquee","menu","menuitem","meta","meter","nav","nobr","noframes", "nos
cript","object","ol","optgroup","option","output","p","param","pre", "progress",
"q","rp","rt","ruby","s","samp","script","section","select", "small","source","s
pan","strong","style","sub","summary","sup","table","tbody","td","textarea","tfo
ot","th","thead","time","tr","track", "u","ul","var","video"]; |
| 730 |
| 731 // github.com/codemirror/CodeMirror/blob/master/mode/css/css.js |
| 732 var documentTypes_ = ["domain", "regexp", "url", "url-prefix"]; |
| 733 var mediaTypes_ = ["all","aural","braille","handheld","print","projection","sc
reen","tty","tv","embossed"]; |
| 734 var mediaFeatures_ = ["width","min-width","max-width","height","min-height","m
ax-height","device-width","min-device-width","max-device-width","device-height",
"min-device-height","max-device-height","aspect-ratio","min-aspect-ratio","max-a
spect-ratio","device-aspect-ratio","min-device-aspect-ratio","max-device-aspect-
ratio","color","min-color","max-color","color-index","min-color-index","max-colo
r-index","monochrome","min-monochrome","max-monochrome","resolution","min-resolu
tion","max-resolution","scan","grid"]; |
| 735 var propertyKeywords_ = ["align-content","align-items","align-self","alignment
-adjust","alignment-baseline","anchor-point","animation","animation-delay","anim
ation-direction","animation-duration","animation-fill-mode","animation-iteration
-count","animation-name","animation-play-state","animation-timing-function","app
earance","azimuth","backface-visibility","background","background-attachment","b
ackground-clip","background-color","background-image","background-origin","backg
round-position","background-repeat","background-size","baseline-shift","binding"
,"bleed","bookmark-label","bookmark-level","bookmark-state","bookmark-target","b
order","border-bottom","border-bottom-color","border-bottom-left-radius","border
-bottom-right-radius","border-bottom-style","border-bottom-width","border-collap
se","border-color","border-image","border-image-outset","border-image-repeat","b
order-image-slice","border-image-source","border-image-width","border-left","bor
der-left-color","border-left-style","border-left-width","border-radius","border-
right","border-right-color","border-right-style","border-right-width","border-sp
acing","border-style","border-top","border-top-color","border-top-left-radius","
border-top-right-radius","border-top-style","border-top-width","border-width","b
ottom","box-decoration-break","box-shadow","box-sizing","break-after","break-bef
ore","break-inside","caption-side","clear","clip","color","color-profile","colum
n-count","column-fill","column-gap","column-rule","column-rule-color","column-ru
le-style","column-rule-width","column-span","column-width","columns","content","
counter-increment","counter-reset","crop","cue","cue-after","cue-before","cursor
","direction","display","dominant-baseline","drop-initial-after-adjust","drop-in
itial-after-align","drop-initial-before-adjust","drop-initial-before-align","dro
p-initial-size","drop-initial-value","elevation","empty-cells","fit","fit-positi
on","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","
flex-wrap","float","float-offset","flow-from","flow-into","font","font-feature-s
ettings","font-family","font-kerning","font-language-override","font-size","font
-size-adjust","font-stretch","font-style","font-synthesis","font-variant","font-
variant-alternates","font-variant-caps","font-variant-east-asian","font-variant-
ligatures","font-variant-numeric","font-variant-position","font-weight","grid","
grid-area","grid-auto-columns","grid-auto-flow","grid-auto-position","grid-auto-
rows","grid-column","grid-column-end","grid-column-start","grid-row","grid-row-e
nd","grid-row-start","grid-template","grid-template-areas","grid-template-column
s","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-o
rientation","image-rendering","image-resolution","inline-box-align","justify-con
tent","left","letter-spacing","line-break","line-height","line-stacking","line-s
tacking-ruby","line-stacking-shift","line-stacking-strategy","list-style","list-
style-image","list-style-position","list-style-type","margin","margin-bottom","m
argin-left","margin-right","margin-top","marker-offset","marks","marquee-directi
on","marquee-loop","marquee-play-count","marquee-speed","marquee-style","max-hei
ght","max-width","min-height","min-width","move-to","nav-down","nav-index","nav-
left","nav-right","nav-up","object-fit","object-position","opacity","order","orp
hans","outline","outline-color","outline-offset","outline-style","outline-width"
,"overflow","overflow-style","overflow-wrap","overflow-x","overflow-y","padding"
,"padding-bottom","padding-left","padding-right","padding-top","page","page-brea
k-after","page-break-before","page-break-inside","page-policy","pause","pause-af
ter","pause-before","perspective","perspective-origin","pitch","pitch-range","pl
ay-during","position","presentation-level","punctuation-trim","quotes","region-b
reak-after","region-break-before","region-break-inside","region-fragment","rende
ring-intent","resize","rest","rest-after","rest-before","richness","right","rota
tion","rotation-point","ruby-align","ruby-overhang","ruby-position","ruby-span",
"shape-image-threshold","shape-inside","shape-margin","shape-outside","size","sp
eak","speak-as","speak-header","speak-numeral","speak-punctuation","speech-rate"
,"stress","string-set","tab-size","table-layout","target","target-name","target-
new","target-position","text-align","text-align-last","text-decoration","text-de
coration-color","text-decoration-line","text-decoration-skip","text-decoration-s
tyle","text-emphasis","text-emphasis-color","text-emphasis-position","text-empha
sis-style","text-height","text-indent","text-justify","text-outline","text-overf
low","text-shadow","text-size-adjust","text-space-collapse","text-transform","te
xt-underline-position","text-wrap","top","transform","transform-origin","transfo
rm-style","transition","transition-delay","transition-duration","transition-prop
erty","transition-timing-function","unicode-bidi","vertical-align","visibility",
"voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voi
ce-rate","voice-stress","voice-volume","volume","white-space","widows","width","
word-break","word-spacing","word-wrap","z-index","clip-path","clip-rule","mask",
"enable-background","filter","flood-color","flood-opacity","lighting-color","sto
p-color","stop-opacity","pointer-events","color-interpolation","color-interpolat
ion-filters","color-rendering","fill","fill-opacity","fill-rule","image-renderin
g","marker","marker-end","marker-mid","marker-start","shape-rendering","stroke",
"stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","strok
e-miterlimit","stroke-opacity","stroke-width","text-rendering","baseline-shift",
"dominant-baseline","glyph-orientation-horizontal","glyph-orientation-vertical",
"text-anchor","writing-mode","font-smoothing","osx-font-smoothing"]; |
| 736 var nonStandardPropertyKeywords_ = ["scrollbar-arrow-color","scrollbar-base-co
lor","scrollbar-dark-shadow-color","scrollbar-face-color","scrollbar-highlight-c
olor","scrollbar-shadow-color","scrollbar-3d-light-color","scrollbar-track-color
","shape-inside","searchfield-cancel-button","searchfield-decoration","searchfie
ld-results-button","searchfield-results-decoration","zoom"]; |
| 737 var fontProperties_ = ["font-family","src","unicode-range","font-variant","fon
t-feature-settings","font-stretch","font-weight","font-style"]; |
| 738 var colorKeywords_ = ["aliceblue","antiquewhite","aqua","aquamarine","azure","
beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood"
,"cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crims
on","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkkha
ki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalm
on","darkseagreen","darkslateblue","darkslategray","darkturquoise","darkviolet",
"deeppink","deepskyblue","dimgray","dodgerblue","firebrick","floralwhite","fores
tgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","gre
en","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lav
ender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","ligh
tcyan","lightgoldenrodyellow","lightgray","lightgreen","lightpink","lightsalmon"
,"lightseagreen","lightskyblue","lightslategray","lightsteelblue","lightyellow",
"lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","m
ediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgree
n","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","m
occasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered"
,"orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhi
p","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red",
"rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell
","sienna","silver","skyblue","slateblue","slategray","snow","springgreen","stee
lblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whi
tesmoke","yellow","yellowgreen"]; |
| 739 var valueKeywords_ = ["above","absolute","activeborder","additive","activecapt
ion","afar","after-white-space","ahead","alias","all","all-scroll","alphabetic",
"alternate","always","amharic","amharic-abegede","antialiased","appworkspace","a
rabic-indic","armenian","asterisks","attr","auto","avoid","avoid-column","avoid-
page","avoid-region","background","backwards","baseline","below","bidi-override"
,"binary","bengali","blink","block","block-axis","bold","bolder","border","borde
r-box","both","bottom","break","break-all","break-word","bullets","button","butt
on-bevel","buttonface","buttonhighlight","buttonshadow","buttontext","calc","cam
bodian","capitalize","caps-lock-indicator","caption","captiontext","caret","cell
","center","checkbox","circle","cjk-decimal","cjk-earthly-branch","cjk-heavenly-
stem","cjk-ideographic","clear","clip","close-quote","col-resize","collapse","co
lumn","compact","condensed","contain","content","content-box","context-menu","co
ntinuous","copy","counter","counters","cover","crop","cross","crosshair","curren
tcolor","cursive","cyclic","dashed","decimal","decimal-leading-zero","default","
default-button","destination-atop","destination-in","destination-out","destinati
on-over","devanagari","disc","discard","disclosure-closed","disclosure-open","do
cument","dot-dash","dot-dot-dash","dotted","double","down","e-resize","ease","ea
se-in","ease-in-out","ease-out","element","ellipse","ellipsis","embed","end","et
hiopic","ethiopic-abegede","ethiopic-abegede-am-et","ethiopic-abegede-gez","ethi
opic-abegede-ti-er","ethiopic-abegede-ti-et","ethiopic-halehame-aa-er","ethiopic
-halehame-aa-et","ethiopic-halehame-am-et","ethiopic-halehame-gez","ethiopic-hal
ehame-om-et","ethiopic-halehame-sid-et","ethiopic-halehame-so-et","ethiopic-hale
hame-ti-er","ethiopic-halehame-ti-et","ethiopic-halehame-tig","ethiopic-numeric"
,"ew-resize","expanded","extends","extra-condensed","extra-expanded","fantasy","
fast","fill","fixed","flat","flex","footnotes","forwards","from","geometricPreci
sion","georgian","graytext","groove","gujarati","gurmukhi","hand","hangul","hang
ul-consonant","hebrew","help","hidden","hide","higher","highlight","highlighttex
t","hiragana","hiragana-iroha","horizontal","hsl","hsla","icon","ignore","inacti
veborder","inactivecaption","inactivecaptiontext","infinite","infobackground","i
nfotext","inherit","initial","inline","inline-axis","inline-block","inline-flex"
,"inline-table","inset","inside","intrinsic","invert","italic","japanese-formal"
,"japanese-informal","justify","kannada","katakana","katakana-iroha","keep-all",
"khmer","korean-hangul-formal","korean-hanja-formal","korean-hanja-informal","la
ndscape","lao","large","larger","left","level","lighter","line-through","linear"
,"linear-gradient","lines","list-item","listbox","listitem","local","logical","l
oud","lower","lower-alpha","lower-armenian","lower-greek","lower-hexadecimal","l
ower-latin","lower-norwegian","lower-roman","lowercase","ltr","malayalam","match
","matrix","matrix3d","media-controls-background","media-current-time-display","
media-fullscreen-button","media-mute-button","media-play-button","media-return-t
o-realtime-button","media-rewind-button","media-seek-back-button","media-seek-fo
rward-button","media-slider","media-sliderthumb","media-time-remaining-display",
"media-volume-slider","media-volume-slider-container","media-volume-sliderthumb"
,"medium","menu","menulist","menulist-button","menulist-text","menulist-textfiel
d","menutext","message-box","middle","min-intrinsic","mix","mongolian","monospac
e","move","multiple","myanmar","n-resize","narrower","ne-resize","nesw-resize","
no-close-quote","no-drop","no-open-quote","no-repeat","none","normal","not-allow
ed","nowrap","ns-resize","numbers","numeric","nw-resize","nwse-resize","oblique"
,"octal","open-quote","optimizeLegibility","optimizeSpeed","oriya","oromo","outs
et","outside","outside-shape","overlay","overline","padding","padding-box","pain
ted","page","paused","persian","perspective","plus-darker","plus-lighter","point
er","polygon","portrait","pre","pre-line","pre-wrap","preserve-3d","progress","p
ush-button","radial-gradient","radio","read-only","read-write","read-write-plain
text-only","rectangle","region","relative","repeat","repeating-linear-gradient",
"repeating-radial-gradient","repeat-x","repeat-y","reset","reverse","rgb","rgba"
,"ridge","right","rotate","rotate3d","rotateX","rotateY","rotateZ","round","row-
resize","rtl","run-in","running","s-resize","sans-serif","scale","scale3d","scal
eX","scaleY","scaleZ","scroll","scrollbar","se-resize","searchfield","searchfiel
d-cancel-button","searchfield-decoration","searchfield-results-button","searchfi
eld-results-decoration","semi-condensed","semi-expanded","separate","serif","sho
w","sidama","simp-chinese-formal","simp-chinese-informal","single","skew","skewX
","skewY","skip-white-space","slide","slider-horizontal","slider-vertical","slid
erthumb-horizontal","sliderthumb-vertical","slow","small","small-caps","small-ca
ption","smaller","solid","somali","source-atop","source-in","source-out","source
-over","space","spell-out","square","square-button","start","static","status-bar
","stretch","stroke","sub","subpixel-antialiased","super","sw-resize","symbolic"
,"symbols","table","table-caption","table-cell","table-column","table-column-gro
up","table-footer-group","table-header-group","table-row","table-row-group","tam
il","telugu","text","text-bottom","text-top","textarea","textfield","thai","thic
k","thin","threeddarkshadow","threedface","threedhighlight","threedlightshadow",
"threedshadow","tibetan","tigre","tigrinya-er","tigrinya-er-abegede","tigrinya-e
t","tigrinya-et-abegede","to","top","trad-chinese-formal","trad-chinese-informal
","translate","translate3d","translateX","translateY","translateZ","transparent"
,"ultra-condensed","ultra-expanded","underline","up","upper-alpha","upper-armeni
an","upper-greek","upper-hexadecimal","upper-latin","upper-norwegian","upper-rom
an","uppercase","urdu","url","var","vertical","vertical-text","visible","visible
Fill","visiblePainted","visibleStroke","visual","w-resize","wait","wave","wider"
,"window","windowframe","windowtext","words","x-large","x-small","xor","xx-large
","xx-small","bicubic","optimizespeed","grayscale","row","row-reverse","wrap","w
rap-reverse","column-reverse","flex-start","flex-end","space-between","space-aro
und"]; |
| 740 |
| 741 var wordOperatorKeywords_ = ["in","and","or","not","is not","is a","is","isnt"
,"defined","if unless"], |
| 742 blockKeywords_ = ["for","if","else","unless", "from", "to"], |
| 743 commonAtoms_ = ["null","true","false","href","title","type","not-allowed",
"readonly","disabled"], |
| 744 commonDef_ = ["@font-face", "@keyframes", "@media", "@viewport", "@page",
"@host", "@supports", "@block", "@css"]; |
| 745 |
| 746 var hintWords = tagKeywords_.concat(documentTypes_,mediaTypes_,mediaFeatures_, |
| 747 propertyKeywords_,nonStandardPropertyKeywo
rds_, |
| 748 colorKeywords_,valueKeywords_,fontProperti
es_, |
| 749 wordOperatorKeywords_,blockKeywords_, |
| 750 commonAtoms_,commonDef_); |
| 751 |
| 752 function wordRegexp(words) { |
| 753 words = words.sort(function(a,b){return b > a;}); |
| 754 return new RegExp("^((" + words.join(")|(") + "))\\b"); |
| 755 } |
| 756 |
| 757 function keySet(array) { |
| 758 var keys = {}; |
| 759 for (var i = 0; i < array.length; ++i) keys[array[i]] = true; |
| 760 return keys; |
| 761 } |
| 762 |
| 763 function escapeRegExp(text) { |
| 764 return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); |
| 765 } |
| 766 |
| 767 CodeMirror.registerHelper("hintWords", "stylus", hintWords); |
| 768 CodeMirror.defineMIME("text/x-styl", "stylus"); |
| 769 }); |
OLD | NEW |