LaravelTest
591 строка · 15.6 Кб
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("../javascript/javascript"), require("../css/css"), require("../htmlmixed/htmlmixed"));7else if (typeof define == "function" && define.amd) // AMD8define(["../../lib/codemirror", "../javascript/javascript", "../css/css", "../htmlmixed/htmlmixed"], mod);9else // Plain browser env10mod(CodeMirror);11})(function(CodeMirror) {12"use strict";13
14CodeMirror.defineMode("pug", function (config) {15// token types16var KEYWORD = 'keyword';17var DOCTYPE = 'meta';18var ID = 'builtin';19var CLASS = 'qualifier';20
21var ATTRS_NEST = {22'{': '}',23'(': ')',24'[': ']'25};26
27var jsMode = CodeMirror.getMode(config, 'javascript');28
29function State() {30this.javaScriptLine = false;31this.javaScriptLineExcludesColon = false;32
33this.javaScriptArguments = false;34this.javaScriptArgumentsDepth = 0;35
36this.isInterpolating = false;37this.interpolationNesting = 0;38
39this.jsState = CodeMirror.startState(jsMode);40
41this.restOfLine = '';42
43this.isIncludeFiltered = false;44this.isEach = false;45
46this.lastTag = '';47this.scriptType = '';48
49// Attributes Mode50this.isAttrs = false;51this.attrsNest = [];52this.inAttributeName = true;53this.attributeIsType = false;54this.attrValue = '';55
56// Indented Mode57this.indentOf = Infinity;58this.indentToken = '';59
60this.innerMode = null;61this.innerState = null;62
63this.innerModeForLine = false;64}65/**66* Safely copy a state
67*
68* @return {State}
69*/
70State.prototype.copy = function () {71var res = new State();72res.javaScriptLine = this.javaScriptLine;73res.javaScriptLineExcludesColon = this.javaScriptLineExcludesColon;74res.javaScriptArguments = this.javaScriptArguments;75res.javaScriptArgumentsDepth = this.javaScriptArgumentsDepth;76res.isInterpolating = this.isInterpolating;77res.interpolationNesting = this.interpolationNesting;78
79res.jsState = CodeMirror.copyState(jsMode, this.jsState);80
81res.innerMode = this.innerMode;82if (this.innerMode && this.innerState) {83res.innerState = CodeMirror.copyState(this.innerMode, this.innerState);84}85
86res.restOfLine = this.restOfLine;87
88res.isIncludeFiltered = this.isIncludeFiltered;89res.isEach = this.isEach;90res.lastTag = this.lastTag;91res.scriptType = this.scriptType;92res.isAttrs = this.isAttrs;93res.attrsNest = this.attrsNest.slice();94res.inAttributeName = this.inAttributeName;95res.attributeIsType = this.attributeIsType;96res.attrValue = this.attrValue;97res.indentOf = this.indentOf;98res.indentToken = this.indentToken;99
100res.innerModeForLine = this.innerModeForLine;101
102return res;103};104
105function javaScript(stream, state) {106if (stream.sol()) {107// if javaScriptLine was set at end of line, ignore it108state.javaScriptLine = false;109state.javaScriptLineExcludesColon = false;110}111if (state.javaScriptLine) {112if (state.javaScriptLineExcludesColon && stream.peek() === ':') {113state.javaScriptLine = false;114state.javaScriptLineExcludesColon = false;115return;116}117var tok = jsMode.token(stream, state.jsState);118if (stream.eol()) state.javaScriptLine = false;119return tok || true;120}121}122function javaScriptArguments(stream, state) {123if (state.javaScriptArguments) {124if (state.javaScriptArgumentsDepth === 0 && stream.peek() !== '(') {125state.javaScriptArguments = false;126return;127}128if (stream.peek() === '(') {129state.javaScriptArgumentsDepth++;130} else if (stream.peek() === ')') {131state.javaScriptArgumentsDepth--;132}133if (state.javaScriptArgumentsDepth === 0) {134state.javaScriptArguments = false;135return;136}137
138var tok = jsMode.token(stream, state.jsState);139return tok || true;140}141}142
143function yieldStatement(stream) {144if (stream.match(/^yield\b/)) {145return 'keyword';146}147}148
149function doctype(stream) {150if (stream.match(/^(?:doctype) *([^\n]+)?/)) {151return DOCTYPE;152}153}154
155function interpolation(stream, state) {156if (stream.match('#{')) {157state.isInterpolating = true;158state.interpolationNesting = 0;159return 'punctuation';160}161}162
163function interpolationContinued(stream, state) {164if (state.isInterpolating) {165if (stream.peek() === '}') {166state.interpolationNesting--;167if (state.interpolationNesting < 0) {168stream.next();169state.isInterpolating = false;170return 'punctuation';171}172} else if (stream.peek() === '{') {173state.interpolationNesting++;174}175return jsMode.token(stream, state.jsState) || true;176}177}178
179function caseStatement(stream, state) {180if (stream.match(/^case\b/)) {181state.javaScriptLine = true;182return KEYWORD;183}184}185
186function when(stream, state) {187if (stream.match(/^when\b/)) {188state.javaScriptLine = true;189state.javaScriptLineExcludesColon = true;190return KEYWORD;191}192}193
194function defaultStatement(stream) {195if (stream.match(/^default\b/)) {196return KEYWORD;197}198}199
200function extendsStatement(stream, state) {201if (stream.match(/^extends?\b/)) {202state.restOfLine = 'string';203return KEYWORD;204}205}206
207function append(stream, state) {208if (stream.match(/^append\b/)) {209state.restOfLine = 'variable';210return KEYWORD;211}212}213function prepend(stream, state) {214if (stream.match(/^prepend\b/)) {215state.restOfLine = 'variable';216return KEYWORD;217}218}219function block(stream, state) {220if (stream.match(/^block\b *(?:(prepend|append)\b)?/)) {221state.restOfLine = 'variable';222return KEYWORD;223}224}225
226function include(stream, state) {227if (stream.match(/^include\b/)) {228state.restOfLine = 'string';229return KEYWORD;230}231}232
233function includeFiltered(stream, state) {234if (stream.match(/^include:([a-zA-Z0-9\-]+)/, false) && stream.match('include')) {235state.isIncludeFiltered = true;236return KEYWORD;237}238}239
240function includeFilteredContinued(stream, state) {241if (state.isIncludeFiltered) {242var tok = filter(stream, state);243state.isIncludeFiltered = false;244state.restOfLine = 'string';245return tok;246}247}248
249function mixin(stream, state) {250if (stream.match(/^mixin\b/)) {251state.javaScriptLine = true;252return KEYWORD;253}254}255
256function call(stream, state) {257if (stream.match(/^\+([-\w]+)/)) {258if (!stream.match(/^\( *[-\w]+ *=/, false)) {259state.javaScriptArguments = true;260state.javaScriptArgumentsDepth = 0;261}262return 'variable';263}264if (stream.match('+#{', false)) {265stream.next();266state.mixinCallAfter = true;267return interpolation(stream, state);268}269}270function callArguments(stream, state) {271if (state.mixinCallAfter) {272state.mixinCallAfter = false;273if (!stream.match(/^\( *[-\w]+ *=/, false)) {274state.javaScriptArguments = true;275state.javaScriptArgumentsDepth = 0;276}277return true;278}279}280
281function conditional(stream, state) {282if (stream.match(/^(if|unless|else if|else)\b/)) {283state.javaScriptLine = true;284return KEYWORD;285}286}287
288function each(stream, state) {289if (stream.match(/^(- *)?(each|for)\b/)) {290state.isEach = true;291return KEYWORD;292}293}294function eachContinued(stream, state) {295if (state.isEach) {296if (stream.match(/^ in\b/)) {297state.javaScriptLine = true;298state.isEach = false;299return KEYWORD;300} else if (stream.sol() || stream.eol()) {301state.isEach = false;302} else if (stream.next()) {303while (!stream.match(/^ in\b/, false) && stream.next());304return 'variable';305}306}307}308
309function whileStatement(stream, state) {310if (stream.match(/^while\b/)) {311state.javaScriptLine = true;312return KEYWORD;313}314}315
316function tag(stream, state) {317var captures;318if (captures = stream.match(/^(\w(?:[-:\w]*\w)?)\/?/)) {319state.lastTag = captures[1].toLowerCase();320if (state.lastTag === 'script') {321state.scriptType = 'application/javascript';322}323return 'tag';324}325}326
327function filter(stream, state) {328if (stream.match(/^:([\w\-]+)/)) {329var innerMode;330if (config && config.innerModes) {331innerMode = config.innerModes(stream.current().substring(1));332}333if (!innerMode) {334innerMode = stream.current().substring(1);335}336if (typeof innerMode === 'string') {337innerMode = CodeMirror.getMode(config, innerMode);338}339setInnerMode(stream, state, innerMode);340return 'atom';341}342}343
344function code(stream, state) {345if (stream.match(/^(!?=|-)/)) {346state.javaScriptLine = true;347return 'punctuation';348}349}350
351function id(stream) {352if (stream.match(/^#([\w-]+)/)) {353return ID;354}355}356
357function className(stream) {358if (stream.match(/^\.([\w-]+)/)) {359return CLASS;360}361}362
363function attrs(stream, state) {364if (stream.peek() == '(') {365stream.next();366state.isAttrs = true;367state.attrsNest = [];368state.inAttributeName = true;369state.attrValue = '';370state.attributeIsType = false;371return 'punctuation';372}373}374
375function attrsContinued(stream, state) {376if (state.isAttrs) {377if (ATTRS_NEST[stream.peek()]) {378state.attrsNest.push(ATTRS_NEST[stream.peek()]);379}380if (state.attrsNest[state.attrsNest.length - 1] === stream.peek()) {381state.attrsNest.pop();382} else if (stream.eat(')')) {383state.isAttrs = false;384return 'punctuation';385}386if (state.inAttributeName && stream.match(/^[^=,\)!]+/)) {387if (stream.peek() === '=' || stream.peek() === '!') {388state.inAttributeName = false;389state.jsState = CodeMirror.startState(jsMode);390if (state.lastTag === 'script' && stream.current().trim().toLowerCase() === 'type') {391state.attributeIsType = true;392} else {393state.attributeIsType = false;394}395}396return 'attribute';397}398
399var tok = jsMode.token(stream, state.jsState);400if (state.attributeIsType && tok === 'string') {401state.scriptType = stream.current().toString();402}403if (state.attrsNest.length === 0 && (tok === 'string' || tok === 'variable' || tok === 'keyword')) {404try {405Function('', 'var x ' + state.attrValue.replace(/,\s*$/, '').replace(/^!/, ''));406state.inAttributeName = true;407state.attrValue = '';408stream.backUp(stream.current().length);409return attrsContinued(stream, state);410} catch (ex) {411//not the end of an attribute412}413}414state.attrValue += stream.current();415return tok || true;416}417}418
419function attributesBlock(stream, state) {420if (stream.match(/^&attributes\b/)) {421state.javaScriptArguments = true;422state.javaScriptArgumentsDepth = 0;423return 'keyword';424}425}426
427function indent(stream) {428if (stream.sol() && stream.eatSpace()) {429return 'indent';430}431}432
433function comment(stream, state) {434if (stream.match(/^ *\/\/(-)?([^\n]*)/)) {435state.indentOf = stream.indentation();436state.indentToken = 'comment';437return 'comment';438}439}440
441function colon(stream) {442if (stream.match(/^: */)) {443return 'colon';444}445}446
447function text(stream, state) {448if (stream.match(/^(?:\| ?| )([^\n]+)/)) {449return 'string';450}451if (stream.match(/^(<[^\n]*)/, false)) {452// html string453setInnerMode(stream, state, 'htmlmixed');454state.innerModeForLine = true;455return innerMode(stream, state, true);456}457}458
459function dot(stream, state) {460if (stream.eat('.')) {461var innerMode = null;462if (state.lastTag === 'script' && state.scriptType.toLowerCase().indexOf('javascript') != -1) {463innerMode = state.scriptType.toLowerCase().replace(/"|'/g, '');464} else if (state.lastTag === 'style') {465innerMode = 'css';466}467setInnerMode(stream, state, innerMode);468return 'dot';469}470}471
472function fail(stream) {473stream.next();474return null;475}476
477
478function setInnerMode(stream, state, mode) {479mode = CodeMirror.mimeModes[mode] || mode;480mode = config.innerModes ? config.innerModes(mode) || mode : mode;481mode = CodeMirror.mimeModes[mode] || mode;482mode = CodeMirror.getMode(config, mode);483state.indentOf = stream.indentation();484
485if (mode && mode.name !== 'null') {486state.innerMode = mode;487} else {488state.indentToken = 'string';489}490}491function innerMode(stream, state, force) {492if (stream.indentation() > state.indentOf || (state.innerModeForLine && !stream.sol()) || force) {493if (state.innerMode) {494if (!state.innerState) {495state.innerState = state.innerMode.startState ? CodeMirror.startState(state.innerMode, stream.indentation()) : {};496}497return stream.hideFirstChars(state.indentOf + 2, function () {498return state.innerMode.token(stream, state.innerState) || true;499});500} else {501stream.skipToEnd();502return state.indentToken;503}504} else if (stream.sol()) {505state.indentOf = Infinity;506state.indentToken = null;507state.innerMode = null;508state.innerState = null;509}510}511function restOfLine(stream, state) {512if (stream.sol()) {513// if restOfLine was set at end of line, ignore it514state.restOfLine = '';515}516if (state.restOfLine) {517stream.skipToEnd();518var tok = state.restOfLine;519state.restOfLine = '';520return tok;521}522}523
524
525function startState() {526return new State();527}528function copyState(state) {529return state.copy();530}531/**532* Get the next token in the stream
533*
534* @param {Stream} stream
535* @param {State} state
536*/
537function nextToken(stream, state) {538var tok = innerMode(stream, state)539|| restOfLine(stream, state)540|| interpolationContinued(stream, state)541|| includeFilteredContinued(stream, state)542|| eachContinued(stream, state)543|| attrsContinued(stream, state)544|| javaScript(stream, state)545|| javaScriptArguments(stream, state)546|| callArguments(stream, state)547
548|| yieldStatement(stream)549|| doctype(stream)550|| interpolation(stream, state)551|| caseStatement(stream, state)552|| when(stream, state)553|| defaultStatement(stream)554|| extendsStatement(stream, state)555|| append(stream, state)556|| prepend(stream, state)557|| block(stream, state)558|| include(stream, state)559|| includeFiltered(stream, state)560|| mixin(stream, state)561|| call(stream, state)562|| conditional(stream, state)563|| each(stream, state)564|| whileStatement(stream, state)565|| tag(stream, state)566|| filter(stream, state)567|| code(stream, state)568|| id(stream)569|| className(stream)570|| attrs(stream, state)571|| attributesBlock(stream, state)572|| indent(stream)573|| text(stream, state)574|| comment(stream, state)575|| colon(stream)576|| dot(stream, state)577|| fail(stream);578
579return tok === true ? null : tok;580}581return {582startState: startState,583copyState: copyState,584token: nextToken585};586}, 'javascript', 'css', 'htmlmixed');587
588CodeMirror.defineMIME('text/x-pug', 'pug');589CodeMirror.defineMIME('text/x-jade', 'pug');590
591});592