LaravelTest
161 строка · 5.2 Кб
1// CodeMirror, copyright (c) by Marijn Haverbeke and others
2// Distributed under an MIT license: https://codemirror.net/LICENSE
3
4(function(mod) {5if (typeof exports == "object" && typeof module == "object") // CommonJS6mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../ruby/ruby"));7else if (typeof define == "function" && define.amd) // AMD8define(["../../lib/codemirror", "../htmlmixed/htmlmixed", "../ruby/ruby"], mod);9else // Plain browser env10mod(CodeMirror);11})(function(CodeMirror) {12"use strict";13
14// full haml mode. This handled embedded ruby and html fragments too15CodeMirror.defineMode("haml", function(config) {16var htmlMode = CodeMirror.getMode(config, {name: "htmlmixed"});17var rubyMode = CodeMirror.getMode(config, "ruby");18
19function rubyInQuote(endQuote) {20return function(stream, state) {21var ch = stream.peek();22if (ch == endQuote && state.rubyState.tokenize.length == 1) {23// step out of ruby context as it seems to complete processing all the braces24stream.next();25state.tokenize = html;26return "closeAttributeTag";27} else {28return ruby(stream, state);29}30};31}32
33function ruby(stream, state) {34if (stream.match("-#")) {35stream.skipToEnd();36return "comment";37}38return rubyMode.token(stream, state.rubyState);39}40
41function html(stream, state) {42var ch = stream.peek();43
44// handle haml declarations. All declarations that cant be handled here45// will be passed to html mode46if (state.previousToken.style == "comment" ) {47if (state.indented > state.previousToken.indented) {48stream.skipToEnd();49return "commentLine";50}51}52
53if (state.startOfLine) {54if (ch == "!" && stream.match("!!")) {55stream.skipToEnd();56return "tag";57} else if (stream.match(/^%[\w:#\.]+=/)) {58state.tokenize = ruby;59return "hamlTag";60} else if (stream.match(/^%[\w:]+/)) {61return "hamlTag";62} else if (ch == "/" ) {63stream.skipToEnd();64return "comment";65}66}67
68if (state.startOfLine || state.previousToken.style == "hamlTag") {69if ( ch == "#" || ch == ".") {70stream.match(/[\w-#\.]*/);71return "hamlAttribute";72}73}74
75// do not handle --> as valid ruby, make it HTML close comment instead76if (state.startOfLine && !stream.match("-->", false) && (ch == "=" || ch == "-" )) {77state.tokenize = ruby;78return state.tokenize(stream, state);79}80
81if (state.previousToken.style == "hamlTag" ||82state.previousToken.style == "closeAttributeTag" ||83state.previousToken.style == "hamlAttribute") {84if (ch == "(") {85state.tokenize = rubyInQuote(")");86return state.tokenize(stream, state);87} else if (ch == "{") {88if (!stream.match(/^\{%.*/)) {89state.tokenize = rubyInQuote("}");90return state.tokenize(stream, state);91}92}93}94
95return htmlMode.token(stream, state.htmlState);96}97
98return {99// default to html mode100startState: function() {101var htmlState = CodeMirror.startState(htmlMode);102var rubyState = CodeMirror.startState(rubyMode);103return {104htmlState: htmlState,105rubyState: rubyState,106indented: 0,107previousToken: { style: null, indented: 0},108tokenize: html109};110},111
112copyState: function(state) {113return {114htmlState : CodeMirror.copyState(htmlMode, state.htmlState),115rubyState: CodeMirror.copyState(rubyMode, state.rubyState),116indented: state.indented,117previousToken: state.previousToken,118tokenize: state.tokenize119};120},121
122token: function(stream, state) {123if (stream.sol()) {124state.indented = stream.indentation();125state.startOfLine = true;126}127if (stream.eatSpace()) return null;128var style = state.tokenize(stream, state);129state.startOfLine = false;130// dont record comment line as we only want to measure comment line with131// the opening comment block132if (style && style != "commentLine") {133state.previousToken = { style: style, indented: state.indented };134}135// if current state is ruby and the previous token is not `,` reset the136// tokenize to html137if (stream.eol() && state.tokenize == ruby) {138stream.backUp(1);139var ch = stream.peek();140stream.next();141if (ch && ch != ",") {142state.tokenize = html;143}144}145// reprocess some of the specific style tag when finish setting previousToken146if (style == "hamlTag") {147style = "tag";148} else if (style == "commentLine") {149style = "comment";150} else if (style == "hamlAttribute") {151style = "attribute";152} else if (style == "closeAttributeTag") {153style = null;154}155return style;156}157};158}, "htmlmixed", "ruby");159
160CodeMirror.defineMIME("text/x-haml", "haml");161});162