LaravelTest

Форк
0
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) {
5
  if (typeof exports == "object" && typeof module == "object") // CommonJS
6
    mod(require("../../lib/codemirror"), require("../javascript/javascript"), require("../css/css"), require("../htmlmixed/htmlmixed"));
7
  else if (typeof define == "function" && define.amd) // AMD
8
    define(["../../lib/codemirror", "../javascript/javascript", "../css/css", "../htmlmixed/htmlmixed"], mod);
9
  else // Plain browser env
10
    mod(CodeMirror);
11
})(function(CodeMirror) {
12
"use strict";
13

14
CodeMirror.defineMode("pug", function (config) {
15
  // token types
16
  var KEYWORD = 'keyword';
17
  var DOCTYPE = 'meta';
18
  var ID = 'builtin';
19
  var CLASS = 'qualifier';
20

21
  var ATTRS_NEST = {
22
    '{': '}',
23
    '(': ')',
24
    '[': ']'
25
  };
26

27
  var jsMode = CodeMirror.getMode(config, 'javascript');
28

29
  function State() {
30
    this.javaScriptLine = false;
31
    this.javaScriptLineExcludesColon = false;
32

33
    this.javaScriptArguments = false;
34
    this.javaScriptArgumentsDepth = 0;
35

36
    this.isInterpolating = false;
37
    this.interpolationNesting = 0;
38

39
    this.jsState = CodeMirror.startState(jsMode);
40

41
    this.restOfLine = '';
42

43
    this.isIncludeFiltered = false;
44
    this.isEach = false;
45

46
    this.lastTag = '';
47
    this.scriptType = '';
48

49
    // Attributes Mode
50
    this.isAttrs = false;
51
    this.attrsNest = [];
52
    this.inAttributeName = true;
53
    this.attributeIsType = false;
54
    this.attrValue = '';
55

56
    // Indented Mode
57
    this.indentOf = Infinity;
58
    this.indentToken = '';
59

60
    this.innerMode = null;
61
    this.innerState = null;
62

63
    this.innerModeForLine = false;
64
  }
65
  /**
66
   * Safely copy a state
67
   *
68
   * @return {State}
69
   */
70
  State.prototype.copy = function () {
71
    var res = new State();
72
    res.javaScriptLine = this.javaScriptLine;
73
    res.javaScriptLineExcludesColon = this.javaScriptLineExcludesColon;
74
    res.javaScriptArguments = this.javaScriptArguments;
75
    res.javaScriptArgumentsDepth = this.javaScriptArgumentsDepth;
76
    res.isInterpolating = this.isInterpolating;
77
    res.interpolationNesting = this.interpolationNesting;
78

79
    res.jsState = CodeMirror.copyState(jsMode, this.jsState);
80

81
    res.innerMode = this.innerMode;
82
    if (this.innerMode && this.innerState) {
83
      res.innerState = CodeMirror.copyState(this.innerMode, this.innerState);
84
    }
85

86
    res.restOfLine = this.restOfLine;
87

88
    res.isIncludeFiltered = this.isIncludeFiltered;
89
    res.isEach = this.isEach;
90
    res.lastTag = this.lastTag;
91
    res.scriptType = this.scriptType;
92
    res.isAttrs = this.isAttrs;
93
    res.attrsNest = this.attrsNest.slice();
94
    res.inAttributeName = this.inAttributeName;
95
    res.attributeIsType = this.attributeIsType;
96
    res.attrValue = this.attrValue;
97
    res.indentOf = this.indentOf;
98
    res.indentToken = this.indentToken;
99

100
    res.innerModeForLine = this.innerModeForLine;
101

102
    return res;
103
  };
104

105
  function javaScript(stream, state) {
106
    if (stream.sol()) {
107
      // if javaScriptLine was set at end of line, ignore it
108
      state.javaScriptLine = false;
109
      state.javaScriptLineExcludesColon = false;
110
    }
111
    if (state.javaScriptLine) {
112
      if (state.javaScriptLineExcludesColon && stream.peek() === ':') {
113
        state.javaScriptLine = false;
114
        state.javaScriptLineExcludesColon = false;
115
        return;
116
      }
117
      var tok = jsMode.token(stream, state.jsState);
118
      if (stream.eol()) state.javaScriptLine = false;
119
      return tok || true;
120
    }
121
  }
122
  function javaScriptArguments(stream, state) {
123
    if (state.javaScriptArguments) {
124
      if (state.javaScriptArgumentsDepth === 0 && stream.peek() !== '(') {
125
        state.javaScriptArguments = false;
126
        return;
127
      }
128
      if (stream.peek() === '(') {
129
        state.javaScriptArgumentsDepth++;
130
      } else if (stream.peek() === ')') {
131
        state.javaScriptArgumentsDepth--;
132
      }
133
      if (state.javaScriptArgumentsDepth === 0) {
134
        state.javaScriptArguments = false;
135
        return;
136
      }
137

138
      var tok = jsMode.token(stream, state.jsState);
139
      return tok || true;
140
    }
141
  }
142

143
  function yieldStatement(stream) {
144
    if (stream.match(/^yield\b/)) {
145
        return 'keyword';
146
    }
147
  }
148

149
  function doctype(stream) {
150
    if (stream.match(/^(?:doctype) *([^\n]+)?/)) {
151
        return DOCTYPE;
152
    }
153
  }
154

155
  function interpolation(stream, state) {
156
    if (stream.match('#{')) {
157
      state.isInterpolating = true;
158
      state.interpolationNesting = 0;
159
      return 'punctuation';
160
    }
161
  }
162

163
  function interpolationContinued(stream, state) {
164
    if (state.isInterpolating) {
165
      if (stream.peek() === '}') {
166
        state.interpolationNesting--;
167
        if (state.interpolationNesting < 0) {
168
          stream.next();
169
          state.isInterpolating = false;
170
          return 'punctuation';
171
        }
172
      } else if (stream.peek() === '{') {
173
        state.interpolationNesting++;
174
      }
175
      return jsMode.token(stream, state.jsState) || true;
176
    }
177
  }
178

179
  function caseStatement(stream, state) {
180
    if (stream.match(/^case\b/)) {
181
      state.javaScriptLine = true;
182
      return KEYWORD;
183
    }
184
  }
185

186
  function when(stream, state) {
187
    if (stream.match(/^when\b/)) {
188
      state.javaScriptLine = true;
189
      state.javaScriptLineExcludesColon = true;
190
      return KEYWORD;
191
    }
192
  }
193

194
  function defaultStatement(stream) {
195
    if (stream.match(/^default\b/)) {
196
      return KEYWORD;
197
    }
198
  }
199

200
  function extendsStatement(stream, state) {
201
    if (stream.match(/^extends?\b/)) {
202
      state.restOfLine = 'string';
203
      return KEYWORD;
204
    }
205
  }
206

207
  function append(stream, state) {
208
    if (stream.match(/^append\b/)) {
209
      state.restOfLine = 'variable';
210
      return KEYWORD;
211
    }
212
  }
213
  function prepend(stream, state) {
214
    if (stream.match(/^prepend\b/)) {
215
      state.restOfLine = 'variable';
216
      return KEYWORD;
217
    }
218
  }
219
  function block(stream, state) {
220
    if (stream.match(/^block\b *(?:(prepend|append)\b)?/)) {
221
      state.restOfLine = 'variable';
222
      return KEYWORD;
223
    }
224
  }
225

226
  function include(stream, state) {
227
    if (stream.match(/^include\b/)) {
228
      state.restOfLine = 'string';
229
      return KEYWORD;
230
    }
231
  }
232

233
  function includeFiltered(stream, state) {
234
    if (stream.match(/^include:([a-zA-Z0-9\-]+)/, false) && stream.match('include')) {
235
      state.isIncludeFiltered = true;
236
      return KEYWORD;
237
    }
238
  }
239

240
  function includeFilteredContinued(stream, state) {
241
    if (state.isIncludeFiltered) {
242
      var tok = filter(stream, state);
243
      state.isIncludeFiltered = false;
244
      state.restOfLine = 'string';
245
      return tok;
246
    }
247
  }
248

249
  function mixin(stream, state) {
250
    if (stream.match(/^mixin\b/)) {
251
      state.javaScriptLine = true;
252
      return KEYWORD;
253
    }
254
  }
255

256
  function call(stream, state) {
257
    if (stream.match(/^\+([-\w]+)/)) {
258
      if (!stream.match(/^\( *[-\w]+ *=/, false)) {
259
        state.javaScriptArguments = true;
260
        state.javaScriptArgumentsDepth = 0;
261
      }
262
      return 'variable';
263
    }
264
    if (stream.match('+#{', false)) {
265
      stream.next();
266
      state.mixinCallAfter = true;
267
      return interpolation(stream, state);
268
    }
269
  }
270
  function callArguments(stream, state) {
271
    if (state.mixinCallAfter) {
272
      state.mixinCallAfter = false;
273
      if (!stream.match(/^\( *[-\w]+ *=/, false)) {
274
        state.javaScriptArguments = true;
275
        state.javaScriptArgumentsDepth = 0;
276
      }
277
      return true;
278
    }
279
  }
280

281
  function conditional(stream, state) {
282
    if (stream.match(/^(if|unless|else if|else)\b/)) {
283
      state.javaScriptLine = true;
284
      return KEYWORD;
285
    }
286
  }
287

288
  function each(stream, state) {
289
    if (stream.match(/^(- *)?(each|for)\b/)) {
290
      state.isEach = true;
291
      return KEYWORD;
292
    }
293
  }
294
  function eachContinued(stream, state) {
295
    if (state.isEach) {
296
      if (stream.match(/^ in\b/)) {
297
        state.javaScriptLine = true;
298
        state.isEach = false;
299
        return KEYWORD;
300
      } else if (stream.sol() || stream.eol()) {
301
        state.isEach = false;
302
      } else if (stream.next()) {
303
        while (!stream.match(/^ in\b/, false) && stream.next());
304
        return 'variable';
305
      }
306
    }
307
  }
308

309
  function whileStatement(stream, state) {
310
    if (stream.match(/^while\b/)) {
311
      state.javaScriptLine = true;
312
      return KEYWORD;
313
    }
314
  }
315

316
  function tag(stream, state) {
317
    var captures;
318
    if (captures = stream.match(/^(\w(?:[-:\w]*\w)?)\/?/)) {
319
      state.lastTag = captures[1].toLowerCase();
320
      if (state.lastTag === 'script') {
321
        state.scriptType = 'application/javascript';
322
      }
323
      return 'tag';
324
    }
325
  }
326

327
  function filter(stream, state) {
328
    if (stream.match(/^:([\w\-]+)/)) {
329
      var innerMode;
330
      if (config && config.innerModes) {
331
        innerMode = config.innerModes(stream.current().substring(1));
332
      }
333
      if (!innerMode) {
334
        innerMode = stream.current().substring(1);
335
      }
336
      if (typeof innerMode === 'string') {
337
        innerMode = CodeMirror.getMode(config, innerMode);
338
      }
339
      setInnerMode(stream, state, innerMode);
340
      return 'atom';
341
    }
342
  }
343

344
  function code(stream, state) {
345
    if (stream.match(/^(!?=|-)/)) {
346
      state.javaScriptLine = true;
347
      return 'punctuation';
348
    }
349
  }
350

351
  function id(stream) {
352
    if (stream.match(/^#([\w-]+)/)) {
353
      return ID;
354
    }
355
  }
356

357
  function className(stream) {
358
    if (stream.match(/^\.([\w-]+)/)) {
359
      return CLASS;
360
    }
361
  }
362

363
  function attrs(stream, state) {
364
    if (stream.peek() == '(') {
365
      stream.next();
366
      state.isAttrs = true;
367
      state.attrsNest = [];
368
      state.inAttributeName = true;
369
      state.attrValue = '';
370
      state.attributeIsType = false;
371
      return 'punctuation';
372
    }
373
  }
374

375
  function attrsContinued(stream, state) {
376
    if (state.isAttrs) {
377
      if (ATTRS_NEST[stream.peek()]) {
378
        state.attrsNest.push(ATTRS_NEST[stream.peek()]);
379
      }
380
      if (state.attrsNest[state.attrsNest.length - 1] === stream.peek()) {
381
        state.attrsNest.pop();
382
      } else  if (stream.eat(')')) {
383
        state.isAttrs = false;
384
        return 'punctuation';
385
      }
386
      if (state.inAttributeName && stream.match(/^[^=,\)!]+/)) {
387
        if (stream.peek() === '=' || stream.peek() === '!') {
388
          state.inAttributeName = false;
389
          state.jsState = CodeMirror.startState(jsMode);
390
          if (state.lastTag === 'script' && stream.current().trim().toLowerCase() === 'type') {
391
            state.attributeIsType = true;
392
          } else {
393
            state.attributeIsType = false;
394
          }
395
        }
396
        return 'attribute';
397
      }
398

399
      var tok = jsMode.token(stream, state.jsState);
400
      if (state.attributeIsType && tok === 'string') {
401
        state.scriptType = stream.current().toString();
402
      }
403
      if (state.attrsNest.length === 0 && (tok === 'string' || tok === 'variable' || tok === 'keyword')) {
404
        try {
405
          Function('', 'var x ' + state.attrValue.replace(/,\s*$/, '').replace(/^!/, ''));
406
          state.inAttributeName = true;
407
          state.attrValue = '';
408
          stream.backUp(stream.current().length);
409
          return attrsContinued(stream, state);
410
        } catch (ex) {
411
          //not the end of an attribute
412
        }
413
      }
414
      state.attrValue += stream.current();
415
      return tok || true;
416
    }
417
  }
418

419
  function attributesBlock(stream, state) {
420
    if (stream.match(/^&attributes\b/)) {
421
      state.javaScriptArguments = true;
422
      state.javaScriptArgumentsDepth = 0;
423
      return 'keyword';
424
    }
425
  }
426

427
  function indent(stream) {
428
    if (stream.sol() && stream.eatSpace()) {
429
      return 'indent';
430
    }
431
  }
432

433
  function comment(stream, state) {
434
    if (stream.match(/^ *\/\/(-)?([^\n]*)/)) {
435
      state.indentOf = stream.indentation();
436
      state.indentToken = 'comment';
437
      return 'comment';
438
    }
439
  }
440

441
  function colon(stream) {
442
    if (stream.match(/^: */)) {
443
      return 'colon';
444
    }
445
  }
446

447
  function text(stream, state) {
448
    if (stream.match(/^(?:\| ?| )([^\n]+)/)) {
449
      return 'string';
450
    }
451
    if (stream.match(/^(<[^\n]*)/, false)) {
452
      // html string
453
      setInnerMode(stream, state, 'htmlmixed');
454
      state.innerModeForLine = true;
455
      return innerMode(stream, state, true);
456
    }
457
  }
458

459
  function dot(stream, state) {
460
    if (stream.eat('.')) {
461
      var innerMode = null;
462
      if (state.lastTag === 'script' && state.scriptType.toLowerCase().indexOf('javascript') != -1) {
463
        innerMode = state.scriptType.toLowerCase().replace(/"|'/g, '');
464
      } else if (state.lastTag === 'style') {
465
        innerMode = 'css';
466
      }
467
      setInnerMode(stream, state, innerMode);
468
      return 'dot';
469
    }
470
  }
471

472
  function fail(stream) {
473
    stream.next();
474
    return null;
475
  }
476

477

478
  function setInnerMode(stream, state, mode) {
479
    mode = CodeMirror.mimeModes[mode] || mode;
480
    mode = config.innerModes ? config.innerModes(mode) || mode : mode;
481
    mode = CodeMirror.mimeModes[mode] || mode;
482
    mode = CodeMirror.getMode(config, mode);
483
    state.indentOf = stream.indentation();
484

485
    if (mode && mode.name !== 'null') {
486
      state.innerMode = mode;
487
    } else {
488
      state.indentToken = 'string';
489
    }
490
  }
491
  function innerMode(stream, state, force) {
492
    if (stream.indentation() > state.indentOf || (state.innerModeForLine && !stream.sol()) || force) {
493
      if (state.innerMode) {
494
        if (!state.innerState) {
495
          state.innerState = state.innerMode.startState ? CodeMirror.startState(state.innerMode, stream.indentation()) : {};
496
        }
497
        return stream.hideFirstChars(state.indentOf + 2, function () {
498
          return state.innerMode.token(stream, state.innerState) || true;
499
        });
500
      } else {
501
        stream.skipToEnd();
502
        return state.indentToken;
503
      }
504
    } else if (stream.sol()) {
505
      state.indentOf = Infinity;
506
      state.indentToken = null;
507
      state.innerMode = null;
508
      state.innerState = null;
509
    }
510
  }
511
  function restOfLine(stream, state) {
512
    if (stream.sol()) {
513
      // if restOfLine was set at end of line, ignore it
514
      state.restOfLine = '';
515
    }
516
    if (state.restOfLine) {
517
      stream.skipToEnd();
518
      var tok = state.restOfLine;
519
      state.restOfLine = '';
520
      return tok;
521
    }
522
  }
523

524

525
  function startState() {
526
    return new State();
527
  }
528
  function copyState(state) {
529
    return state.copy();
530
  }
531
  /**
532
   * Get the next token in the stream
533
   *
534
   * @param {Stream} stream
535
   * @param {State} state
536
   */
537
  function nextToken(stream, state) {
538
    var 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

579
    return tok === true ? null : tok;
580
  }
581
  return {
582
    startState: startState,
583
    copyState: copyState,
584
    token: nextToken
585
  };
586
}, 'javascript', 'css', 'htmlmixed');
587

588
CodeMirror.defineMIME('text/x-pug', 'pug');
589
CodeMirror.defineMIME('text/x-jade', 'pug');
590

591
});
592

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.