Merge pull request #5987 from WoltLab/acp-dahsboard-box-hight
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / js / 3rdParty / codemirror / mode / smarty / smarty.js
CommitLineData
44f4c339 1// CodeMirror, copyright (c) by Marijn Haverbeke and others
373d1232 2// Distributed under an MIT license: https://codemirror.net/LICENSE
44f4c339 3
837afb80
TD
4/**
5 * Smarty 2 and 3 mode.
6 */
7
8(function(mod) {
9 if (typeof exports == "object" && typeof module == "object") // CommonJS
10 mod(require("../../lib/codemirror"));
11 else if (typeof define == "function" && define.amd) // AMD
12 define(["../../lib/codemirror"], mod);
13 else // Plain browser env
14 mod(CodeMirror);
15})(function(CodeMirror) {
837afb80
TD
16 "use strict";
17
44f4c339
AE
18 CodeMirror.defineMode("smarty", function(config, parserConf) {
19 var rightDelimiter = parserConf.rightDelimiter || "}";
20 var leftDelimiter = parserConf.leftDelimiter || "{";
21 var version = parserConf.version || 2;
22 var baseMode = CodeMirror.getMode(config, parserConf.baseMode || "null");
23
24 var keyFunctions = ["debug", "extends", "function", "include", "literal"];
25 var regs = {
26 operatorChars: /[+\-*&%=<>!?]/,
27 validIdentifier: /[a-zA-Z0-9_]/,
28 stringChar: /['"]/
29 };
30
31 var last;
32 function cont(style, lastType) {
837afb80
TD
33 last = lastType;
34 return style;
44f4c339
AE
35 }
36
37 function chain(stream, state, parser) {
77b7b761
TD
38 state.tokenize = parser;
39 return parser(stream, state);
40 }
77b7b761 41
44f4c339
AE
42 // Smarty 3 allows { and } surrounded by whitespace to NOT slip into Smarty mode
43 function doesNotCount(stream, pos) {
44 if (pos == null) pos = stream.pos;
45 return version === 3 && leftDelimiter == "{" &&
46 (pos == stream.string.length || /\s/.test(stream.string.charAt(pos)));
47 }
77b7b761 48
44f4c339
AE
49 function tokenTop(stream, state) {
50 var string = stream.string;
51 for (var scan = stream.pos;;) {
52 var nextMatch = string.indexOf(leftDelimiter, scan);
53 scan = nextMatch + leftDelimiter.length;
54 if (nextMatch == -1 || !doesNotCount(stream, nextMatch + leftDelimiter.length)) break;
55 }
56 if (nextMatch == stream.pos) {
57 stream.match(leftDelimiter);
837afb80 58 if (stream.eat("*")) {
44f4c339 59 return chain(stream, state, tokenBlock("comment", "*" + rightDelimiter));
837afb80 60 } else {
837afb80 61 state.depth++;
44f4c339
AE
62 state.tokenize = tokenSmarty;
63 last = "startTag";
64 return "tag";
77b7b761 65 }
77b7b761 66 }
44f4c339
AE
67
68 if (nextMatch > -1) stream.string = string.slice(0, nextMatch);
69 var token = baseMode.token(stream, state.base);
70 if (nextMatch > -1) stream.string = string;
71 return token;
72 }
77b7b761 73
837afb80 74 // parsing Smarty content
44f4c339
AE
75 function tokenSmarty(stream, state) {
76 if (stream.match(rightDelimiter, true)) {
77 if (version === 3) {
837afb80
TD
78 state.depth--;
79 if (state.depth <= 0) {
44f4c339 80 state.tokenize = tokenTop;
837afb80
TD
81 }
82 } else {
44f4c339 83 state.tokenize = tokenTop;
77b7b761 84 }
44f4c339 85 return cont("tag", null);
77b7b761 86 }
837afb80 87
44f4c339 88 if (stream.match(leftDelimiter, true)) {
837afb80 89 state.depth++;
44f4c339 90 return cont("tag", "startTag");
77b7b761 91 }
77b7b761 92
837afb80
TD
93 var ch = stream.next();
94 if (ch == "$") {
95 stream.eatWhile(regs.validIdentifier);
44f4c339 96 return cont("variable-2", "variable");
837afb80 97 } else if (ch == "|") {
44f4c339 98 return cont("operator", "pipe");
837afb80 99 } else if (ch == ".") {
44f4c339 100 return cont("operator", "property");
837afb80 101 } else if (regs.stringChar.test(ch)) {
44f4c339
AE
102 state.tokenize = tokenAttribute(ch);
103 return cont("string", "string");
837afb80
TD
104 } else if (regs.operatorChars.test(ch)) {
105 stream.eatWhile(regs.operatorChars);
44f4c339 106 return cont("operator", "operator");
837afb80 107 } else if (ch == "[" || ch == "]") {
44f4c339 108 return cont("bracket", "bracket");
837afb80 109 } else if (ch == "(" || ch == ")") {
44f4c339 110 return cont("bracket", "operator");
837afb80
TD
111 } else if (/\d/.test(ch)) {
112 stream.eatWhile(/\d/);
44f4c339 113 return cont("number", "number");
837afb80
TD
114 } else {
115
116 if (state.last == "variable") {
117 if (ch == "@") {
118 stream.eatWhile(regs.validIdentifier);
44f4c339 119 return cont("property", "property");
837afb80
TD
120 } else if (ch == "|") {
121 stream.eatWhile(regs.validIdentifier);
44f4c339 122 return cont("qualifier", "modifier");
837afb80
TD
123 }
124 } else if (state.last == "pipe") {
125 stream.eatWhile(regs.validIdentifier);
44f4c339 126 return cont("qualifier", "modifier");
837afb80
TD
127 } else if (state.last == "whitespace") {
128 stream.eatWhile(regs.validIdentifier);
44f4c339 129 return cont("attribute", "modifier");
837afb80
TD
130 } if (state.last == "property") {
131 stream.eatWhile(regs.validIdentifier);
44f4c339 132 return cont("property", null);
837afb80
TD
133 } else if (/\s/.test(ch)) {
134 last = "whitespace";
135 return null;
77b7b761 136 }
77b7b761 137
837afb80
TD
138 var str = "";
139 if (ch != "/") {
140 str += ch;
77b7b761 141 }
837afb80
TD
142 var c = null;
143 while (c = stream.eat(regs.validIdentifier)) {
144 str += c;
145 }
146 for (var i=0, j=keyFunctions.length; i<j; i++) {
147 if (keyFunctions[i] == str) {
44f4c339 148 return cont("keyword", "keyword");
837afb80
TD
149 }
150 }
151 if (/\s/.test(ch)) {
152 return null;
153 }
44f4c339 154 return cont("tag", "tag");
77b7b761 155 }
44f4c339 156 }
837afb80 157
44f4c339 158 function tokenAttribute(quote) {
837afb80
TD
159 return function(stream, state) {
160 var prevChar = null;
161 var currChar = null;
162 while (!stream.eol()) {
163 currChar = stream.peek();
164 if (stream.next() == quote && prevChar !== '\\') {
44f4c339 165 state.tokenize = tokenSmarty;
837afb80
TD
166 break;
167 }
168 prevChar = currChar;
169 }
170 return "string";
171 };
44f4c339 172 }
837afb80 173
44f4c339 174 function tokenBlock(style, terminator) {
837afb80
TD
175 return function(stream, state) {
176 while (!stream.eol()) {
177 if (stream.match(terminator)) {
44f4c339 178 state.tokenize = tokenTop;
837afb80
TD
179 break;
180 }
181 stream.next();
182 }
183 return style;
184 };
185 }
837afb80 186
44f4c339
AE
187 return {
188 startState: function() {
189 return {
190 base: CodeMirror.startState(baseMode),
191 tokenize: tokenTop,
192 last: null,
193 depth: 0
194 };
195 },
196 copyState: function(state) {
197 return {
198 base: CodeMirror.copyState(baseMode, state.base),
199 tokenize: state.tokenize,
200 last: state.last,
201 depth: state.depth
202 };
203 },
204 innerMode: function(state) {
205 if (state.tokenize == tokenTop)
206 return {mode: baseMode, state: state.base};
207 },
208 token: function(stream, state) {
209 var style = state.tokenize(stream, state);
210 state.last = last;
211 return style;
212 },
373d1232 213 indent: function(state, text, line) {
44f4c339 214 if (state.tokenize == tokenTop && baseMode.indent)
373d1232 215 return baseMode.indent(state.base, text, line);
44f4c339
AE
216 else
217 return CodeMirror.Pass;
218 },
219 blockCommentStart: leftDelimiter + "*",
220 blockCommentEnd: "*" + rightDelimiter
221 };
222 });
223
224 CodeMirror.defineMIME("text/x-smarty", "smarty");
837afb80 225});