| 1 | var Marker = require('./marker');
|
|---|
| 2 | var Token = require('./token');
|
|---|
| 3 |
|
|---|
| 4 | var formatPosition = require('../utils/format-position');
|
|---|
| 5 |
|
|---|
| 6 | var Level = {
|
|---|
| 7 | BLOCK: 'block',
|
|---|
| 8 | COMMENT: 'comment',
|
|---|
| 9 | DOUBLE_QUOTE: 'double-quote',
|
|---|
| 10 | RULE: 'rule',
|
|---|
| 11 | SINGLE_QUOTE: 'single-quote'
|
|---|
| 12 | };
|
|---|
| 13 |
|
|---|
| 14 | var AT_RULES = [
|
|---|
| 15 | '@charset',
|
|---|
| 16 | '@import'
|
|---|
| 17 | ];
|
|---|
| 18 |
|
|---|
| 19 | var BLOCK_RULES = [
|
|---|
| 20 | '@-moz-document',
|
|---|
| 21 | '@document',
|
|---|
| 22 | '@-moz-keyframes',
|
|---|
| 23 | '@-ms-keyframes',
|
|---|
| 24 | '@-o-keyframes',
|
|---|
| 25 | '@-webkit-keyframes',
|
|---|
| 26 | '@keyframes',
|
|---|
| 27 | '@media',
|
|---|
| 28 | '@supports',
|
|---|
| 29 | '@container',
|
|---|
| 30 | '@layer'
|
|---|
| 31 | ];
|
|---|
| 32 |
|
|---|
| 33 | var IGNORE_END_COMMENT_PATTERN = /\/\* clean-css ignore:end \*\/$/;
|
|---|
| 34 | var IGNORE_START_COMMENT_PATTERN = /^\/\* clean-css ignore:start \*\//;
|
|---|
| 35 |
|
|---|
| 36 | var PAGE_MARGIN_BOXES = [
|
|---|
| 37 | '@bottom-center',
|
|---|
| 38 | '@bottom-left',
|
|---|
| 39 | '@bottom-left-corner',
|
|---|
| 40 | '@bottom-right',
|
|---|
| 41 | '@bottom-right-corner',
|
|---|
| 42 | '@left-bottom',
|
|---|
| 43 | '@left-middle',
|
|---|
| 44 | '@left-top',
|
|---|
| 45 | '@right-bottom',
|
|---|
| 46 | '@right-middle',
|
|---|
| 47 | '@right-top',
|
|---|
| 48 | '@top-center',
|
|---|
| 49 | '@top-left',
|
|---|
| 50 | '@top-left-corner',
|
|---|
| 51 | '@top-right',
|
|---|
| 52 | '@top-right-corner'
|
|---|
| 53 | ];
|
|---|
| 54 |
|
|---|
| 55 | var EXTRA_PAGE_BOXES = [
|
|---|
| 56 | '@footnote',
|
|---|
| 57 | '@footnotes',
|
|---|
| 58 | '@left',
|
|---|
| 59 | '@page-float-bottom',
|
|---|
| 60 | '@page-float-top',
|
|---|
| 61 | '@right'
|
|---|
| 62 | ];
|
|---|
| 63 |
|
|---|
| 64 | var REPEAT_PATTERN = /^\[\s{0,31}\d+\s{0,31}\]$/;
|
|---|
| 65 | var TAIL_BROKEN_VALUE_PATTERN = /([^}])\}*$/;
|
|---|
| 66 | var RULE_WORD_SEPARATOR_PATTERN = /[\s(]/;
|
|---|
| 67 |
|
|---|
| 68 | function tokenize(source, externalContext) {
|
|---|
| 69 | var internalContext = {
|
|---|
| 70 | level: Level.BLOCK,
|
|---|
| 71 | position: {
|
|---|
| 72 | source: externalContext.source || undefined,
|
|---|
| 73 | line: 1,
|
|---|
| 74 | column: 0,
|
|---|
| 75 | index: 0
|
|---|
| 76 | }
|
|---|
| 77 | };
|
|---|
| 78 |
|
|---|
| 79 | return intoTokens(source, externalContext, internalContext, false);
|
|---|
| 80 | }
|
|---|
| 81 |
|
|---|
| 82 | function intoTokens(source, externalContext, internalContext, isNested) {
|
|---|
| 83 | var allTokens = [];
|
|---|
| 84 | var newTokens = allTokens;
|
|---|
| 85 | var lastToken;
|
|---|
| 86 | var ruleToken;
|
|---|
| 87 | var ruleTokens = [];
|
|---|
| 88 | var propertyToken;
|
|---|
| 89 | var metadata;
|
|---|
| 90 | var metadatas = [];
|
|---|
| 91 | var level = internalContext.level;
|
|---|
| 92 | var levels = [];
|
|---|
| 93 | var buffer = [];
|
|---|
| 94 | var buffers = [];
|
|---|
| 95 | var isBufferEmpty = true;
|
|---|
| 96 | var serializedBuffer;
|
|---|
| 97 | var serializedBufferPart;
|
|---|
| 98 | var roundBracketLevel = 0;
|
|---|
| 99 | var isQuoted;
|
|---|
| 100 | var isSpace;
|
|---|
| 101 | var isNewLineNix;
|
|---|
| 102 | var isNewLineWin;
|
|---|
| 103 | var isCarriageReturn;
|
|---|
| 104 | var isCommentStart;
|
|---|
| 105 | var wasCommentStart = false;
|
|---|
| 106 | var isCommentEnd;
|
|---|
| 107 | var wasCommentEnd = false;
|
|---|
| 108 | var isCommentEndMarker;
|
|---|
| 109 | var isEscaped;
|
|---|
| 110 | var wasEscaped = false;
|
|---|
| 111 | var characterWithNoSpecialMeaning;
|
|---|
| 112 | var isPreviousDash = false;
|
|---|
| 113 | var isVariable = false;
|
|---|
| 114 | var isRaw = false;
|
|---|
| 115 | var seekingValue = false;
|
|---|
| 116 | var seekingPropertyBlockClosing = false;
|
|---|
| 117 | var position = internalContext.position;
|
|---|
| 118 | var lastCommentStartAt;
|
|---|
| 119 |
|
|---|
| 120 | for (; position.index < source.length; position.index++) {
|
|---|
| 121 | var character = source[position.index];
|
|---|
| 122 |
|
|---|
| 123 | isQuoted = level == Level.SINGLE_QUOTE || level == Level.DOUBLE_QUOTE;
|
|---|
| 124 | isSpace = character == Marker.SPACE || character == Marker.TAB;
|
|---|
| 125 | isNewLineNix = character == Marker.NEW_LINE_NIX;
|
|---|
| 126 | isNewLineWin = character == Marker.NEW_LINE_NIX
|
|---|
| 127 | && source[position.index - 1] == Marker.CARRIAGE_RETURN;
|
|---|
| 128 | isCarriageReturn = character == Marker.CARRIAGE_RETURN
|
|---|
| 129 | && source[position.index + 1] && source[position.index + 1] != Marker.NEW_LINE_NIX;
|
|---|
| 130 | isCommentStart = !wasCommentEnd
|
|---|
| 131 | && level != Level.COMMENT && !isQuoted
|
|---|
| 132 | && character == Marker.ASTERISK && source[position.index - 1] == Marker.FORWARD_SLASH;
|
|---|
| 133 | isCommentEndMarker = !wasCommentStart
|
|---|
| 134 | && !isQuoted && character == Marker.FORWARD_SLASH
|
|---|
| 135 | && source[position.index - 1] == Marker.ASTERISK;
|
|---|
| 136 | isCommentEnd = level == Level.COMMENT && isCommentEndMarker;
|
|---|
| 137 | characterWithNoSpecialMeaning = !isSpace && !isCarriageReturn && (character >= 'A' && character <= 'Z' || character >= 'a' && character <= 'z' || character >= '0' && character <= '9' || character == '-');
|
|---|
| 138 | isVariable = isVariable || (level != Level.COMMENT && !seekingValue && isPreviousDash && character === '-' && buffer.length === 1);
|
|---|
| 139 | isPreviousDash = character === '-';
|
|---|
| 140 | roundBracketLevel = Math.max(roundBracketLevel, 0);
|
|---|
| 141 |
|
|---|
| 142 | metadata = isBufferEmpty
|
|---|
| 143 | ? [position.line, position.column, position.source]
|
|---|
| 144 | : metadata;
|
|---|
| 145 |
|
|---|
| 146 | if (isEscaped) {
|
|---|
| 147 | // previous character was a backslash
|
|---|
| 148 | buffer.push(character);
|
|---|
| 149 | isBufferEmpty = false;
|
|---|
| 150 | } else if (characterWithNoSpecialMeaning) {
|
|---|
| 151 | // it's just an alphanumeric character or a hyphen (part of any rule or property name) so let's end it quickly
|
|---|
| 152 | buffer.push(character);
|
|---|
| 153 | isBufferEmpty = false;
|
|---|
| 154 | } else if ((isSpace || isNewLineNix && !isNewLineWin) && (isQuoted || level == Level.COMMENT)) {
|
|---|
| 155 | buffer.push(character);
|
|---|
| 156 | isBufferEmpty = false;
|
|---|
| 157 | } else if ((isSpace || isNewLineNix && !isNewLineWin) && isBufferEmpty) {
|
|---|
| 158 | // noop
|
|---|
| 159 | } else if (!isCommentEnd && level == Level.COMMENT) {
|
|---|
| 160 | buffer.push(character);
|
|---|
| 161 | isBufferEmpty = false;
|
|---|
| 162 | } else if (!isCommentStart && !isCommentEnd && isRaw) {
|
|---|
| 163 | buffer.push(character);
|
|---|
| 164 | isBufferEmpty = false;
|
|---|
| 165 | } else if (isCommentStart
|
|---|
| 166 | && isVariable
|
|---|
| 167 | && (level == Level.BLOCK || level == Level.RULE) && buffer.length > 1) {
|
|---|
| 168 | // comment start within a variable, e.g. var(/*<--
|
|---|
| 169 | buffer.push(character);
|
|---|
| 170 | isBufferEmpty = false;
|
|---|
| 171 |
|
|---|
| 172 | levels.push(level);
|
|---|
| 173 | level = Level.COMMENT;
|
|---|
| 174 | } else if (isCommentStart && (level == Level.BLOCK || level == Level.RULE) && buffer.length > 1) {
|
|---|
| 175 | // comment start within block preceded by some content, e.g. div/*<--
|
|---|
| 176 | metadatas.push(metadata);
|
|---|
| 177 | buffer.push(character);
|
|---|
| 178 | buffers.push(buffer.slice(0, -2));
|
|---|
| 179 | isBufferEmpty = false;
|
|---|
| 180 |
|
|---|
| 181 | buffer = buffer.slice(-2);
|
|---|
| 182 | metadata = [position.line, position.column - 1, position.source];
|
|---|
| 183 |
|
|---|
| 184 | levels.push(level);
|
|---|
| 185 | level = Level.COMMENT;
|
|---|
| 186 | } else if (isCommentStart) {
|
|---|
| 187 | // comment start, e.g. /*<--
|
|---|
| 188 | levels.push(level);
|
|---|
| 189 | level = Level.COMMENT;
|
|---|
| 190 | buffer.push(character);
|
|---|
| 191 | isBufferEmpty = false;
|
|---|
| 192 | } else if (isCommentEnd && isVariable) {
|
|---|
| 193 | // comment end within a variable, e.g. var(/*!*/<--
|
|---|
| 194 | buffer.push(character);
|
|---|
| 195 | level = levels.pop();
|
|---|
| 196 | } else if (isCommentEnd && isIgnoreStartComment(buffer)) {
|
|---|
| 197 | // ignore:start comment end, e.g. /* clean-css ignore:start */<--
|
|---|
| 198 | serializedBuffer = buffer.join('').trim() + character;
|
|---|
| 199 | lastToken = [
|
|---|
| 200 | Token.COMMENT,
|
|---|
| 201 | serializedBuffer,
|
|---|
| 202 | [originalMetadata(metadata, serializedBuffer, externalContext)]
|
|---|
| 203 | ];
|
|---|
| 204 | newTokens.push(lastToken);
|
|---|
| 205 |
|
|---|
| 206 | isRaw = true;
|
|---|
| 207 | metadata = metadatas.pop() || null;
|
|---|
| 208 | buffer = buffers.pop() || [];
|
|---|
| 209 | isBufferEmpty = buffer.length === 0;
|
|---|
| 210 | } else if (isCommentEnd && isIgnoreEndComment(buffer)) {
|
|---|
| 211 | // ignore:start comment end, e.g. /* clean-css ignore:end */<--
|
|---|
| 212 | serializedBuffer = buffer.join('') + character;
|
|---|
| 213 | lastCommentStartAt = serializedBuffer.lastIndexOf(Marker.FORWARD_SLASH + Marker.ASTERISK);
|
|---|
| 214 |
|
|---|
| 215 | serializedBufferPart = serializedBuffer.substring(0, lastCommentStartAt);
|
|---|
| 216 | lastToken = [
|
|---|
| 217 | Token.RAW,
|
|---|
| 218 | serializedBufferPart,
|
|---|
| 219 | [originalMetadata(metadata, serializedBufferPart, externalContext)]
|
|---|
| 220 | ];
|
|---|
| 221 | newTokens.push(lastToken);
|
|---|
| 222 |
|
|---|
| 223 | serializedBufferPart = serializedBuffer.substring(lastCommentStartAt);
|
|---|
| 224 | metadata = [position.line, position.column - serializedBufferPart.length + 1, position.source];
|
|---|
| 225 | lastToken = [
|
|---|
| 226 | Token.COMMENT,
|
|---|
| 227 | serializedBufferPart,
|
|---|
| 228 | [originalMetadata(metadata, serializedBufferPart, externalContext)]
|
|---|
| 229 | ];
|
|---|
| 230 | newTokens.push(lastToken);
|
|---|
| 231 |
|
|---|
| 232 | isRaw = false;
|
|---|
| 233 | level = levels.pop();
|
|---|
| 234 | metadata = metadatas.pop() || null;
|
|---|
| 235 | buffer = buffers.pop() || [];
|
|---|
| 236 | isBufferEmpty = buffer.length === 0;
|
|---|
| 237 | } else if (isCommentEnd) {
|
|---|
| 238 | // comment end, e.g. /* comment */<--
|
|---|
| 239 | serializedBuffer = buffer.join('').trim() + character;
|
|---|
| 240 | lastToken = [
|
|---|
| 241 | Token.COMMENT,
|
|---|
| 242 | serializedBuffer,
|
|---|
| 243 | [originalMetadata(metadata, serializedBuffer, externalContext)]
|
|---|
| 244 | ];
|
|---|
| 245 | newTokens.push(lastToken);
|
|---|
| 246 |
|
|---|
| 247 | level = levels.pop();
|
|---|
| 248 | metadata = metadatas.pop() || null;
|
|---|
| 249 | buffer = buffers.pop() || [];
|
|---|
| 250 | isBufferEmpty = buffer.length === 0;
|
|---|
| 251 | } else if (isCommentEndMarker && source[position.index + 1] != Marker.ASTERISK) {
|
|---|
| 252 | externalContext.warnings.push('Unexpected \'*/\' at ' + formatPosition([position.line, position.column, position.source]) + '.');
|
|---|
| 253 | buffer = [];
|
|---|
| 254 | isBufferEmpty = true;
|
|---|
| 255 | } else if (character == Marker.SINGLE_QUOTE && !isQuoted) {
|
|---|
| 256 | // single quotation start, e.g. a[href^='https<--
|
|---|
| 257 | levels.push(level);
|
|---|
| 258 | level = Level.SINGLE_QUOTE;
|
|---|
| 259 | buffer.push(character);
|
|---|
| 260 | isBufferEmpty = false;
|
|---|
| 261 | } else if (character == Marker.SINGLE_QUOTE && level == Level.SINGLE_QUOTE) {
|
|---|
| 262 | // single quotation end, e.g. a[href^='https'<--
|
|---|
| 263 | level = levels.pop();
|
|---|
| 264 | buffer.push(character);
|
|---|
| 265 | isBufferEmpty = false;
|
|---|
| 266 | } else if (character == Marker.DOUBLE_QUOTE && !isQuoted) {
|
|---|
| 267 | // double quotation start, e.g. a[href^="<--
|
|---|
| 268 | levels.push(level);
|
|---|
| 269 | level = Level.DOUBLE_QUOTE;
|
|---|
| 270 | buffer.push(character);
|
|---|
| 271 | isBufferEmpty = false;
|
|---|
| 272 | } else if (character == Marker.DOUBLE_QUOTE && level == Level.DOUBLE_QUOTE) {
|
|---|
| 273 | // double quotation end, e.g. a[href^="https"<--
|
|---|
| 274 | level = levels.pop();
|
|---|
| 275 | buffer.push(character);
|
|---|
| 276 | isBufferEmpty = false;
|
|---|
| 277 | } else if (character != Marker.CLOSE_ROUND_BRACKET
|
|---|
| 278 | && character != Marker.OPEN_ROUND_BRACKET
|
|---|
| 279 | && level != Level.COMMENT && !isQuoted && roundBracketLevel > 0) {
|
|---|
| 280 | // character inside any function, e.g. hsla(.<--
|
|---|
| 281 | buffer.push(character);
|
|---|
| 282 | isBufferEmpty = false;
|
|---|
| 283 | } else if (character == Marker.OPEN_ROUND_BRACKET
|
|---|
| 284 | && !isQuoted && level != Level.COMMENT
|
|---|
| 285 | && !seekingValue) {
|
|---|
| 286 | // round open bracket, e.g. @import url(<--
|
|---|
| 287 | buffer.push(character);
|
|---|
| 288 | isBufferEmpty = false;
|
|---|
| 289 |
|
|---|
| 290 | roundBracketLevel++;
|
|---|
| 291 | } else if (character == Marker.CLOSE_ROUND_BRACKET
|
|---|
| 292 | && !isQuoted
|
|---|
| 293 | && level != Level.COMMENT
|
|---|
| 294 | && !seekingValue) {
|
|---|
| 295 | // round open bracket, e.g. @import url(test.css)<--
|
|---|
| 296 | buffer.push(character);
|
|---|
| 297 | isBufferEmpty = false;
|
|---|
| 298 |
|
|---|
| 299 | roundBracketLevel--;
|
|---|
| 300 | } else if (character == Marker.SEMICOLON && level == Level.BLOCK && buffer[0] == Marker.AT) {
|
|---|
| 301 | // semicolon ending rule at block level, e.g. @import '...';<--
|
|---|
| 302 | serializedBuffer = buffer.join('').trim();
|
|---|
| 303 | allTokens.push([
|
|---|
| 304 | Token.AT_RULE,
|
|---|
| 305 | serializedBuffer,
|
|---|
| 306 | [originalMetadata(metadata, serializedBuffer, externalContext)]
|
|---|
| 307 | ]);
|
|---|
| 308 |
|
|---|
| 309 | buffer = [];
|
|---|
| 310 | isBufferEmpty = true;
|
|---|
| 311 | } else if (character == Marker.COMMA && level == Level.BLOCK && ruleToken) {
|
|---|
| 312 | // comma separator at block level, e.g. a,div,<--
|
|---|
| 313 | serializedBuffer = buffer.join('').trim();
|
|---|
| 314 | ruleToken[1].push([
|
|---|
| 315 | tokenScopeFrom(ruleToken[0]),
|
|---|
| 316 | serializedBuffer,
|
|---|
| 317 | [originalMetadata(metadata, serializedBuffer, externalContext, ruleToken[1].length)]
|
|---|
| 318 | ]);
|
|---|
| 319 |
|
|---|
| 320 | buffer = [];
|
|---|
| 321 | isBufferEmpty = true;
|
|---|
| 322 | } else if (character == Marker.COMMA && level == Level.BLOCK && tokenTypeFrom(buffer) == Token.AT_RULE) {
|
|---|
| 323 | // comma separator at block level, e.g. @import url(...) screen,<--
|
|---|
| 324 | // keep iterating as end semicolon will create the token
|
|---|
| 325 | buffer.push(character);
|
|---|
| 326 | isBufferEmpty = false;
|
|---|
| 327 | } else if (character == Marker.COMMA && level == Level.BLOCK) {
|
|---|
| 328 | // comma separator at block level, e.g. a,<--
|
|---|
| 329 | ruleToken = [tokenTypeFrom(buffer), [], []];
|
|---|
| 330 | serializedBuffer = buffer.join('').trim();
|
|---|
| 331 | ruleToken[1].push([
|
|---|
| 332 | tokenScopeFrom(ruleToken[0]),
|
|---|
| 333 | serializedBuffer,
|
|---|
| 334 | [originalMetadata(metadata, serializedBuffer, externalContext, 0)]
|
|---|
| 335 | ]);
|
|---|
| 336 |
|
|---|
| 337 | buffer = [];
|
|---|
| 338 | isBufferEmpty = true;
|
|---|
| 339 | } else if (character == Marker.OPEN_CURLY_BRACKET
|
|---|
| 340 | && level == Level.BLOCK
|
|---|
| 341 | && ruleToken
|
|---|
| 342 | && ruleToken[0] == Token.NESTED_BLOCK) {
|
|---|
| 343 | // open brace opening at-rule at block level, e.g. @media{<--
|
|---|
| 344 | serializedBuffer = buffer.join('').trim();
|
|---|
| 345 | ruleToken[1].push([
|
|---|
| 346 | Token.NESTED_BLOCK_SCOPE,
|
|---|
| 347 | serializedBuffer,
|
|---|
| 348 | [originalMetadata(metadata, serializedBuffer, externalContext)]
|
|---|
| 349 | ]);
|
|---|
| 350 | allTokens.push(ruleToken);
|
|---|
| 351 |
|
|---|
| 352 | levels.push(level);
|
|---|
| 353 | position.column++;
|
|---|
| 354 | position.index++;
|
|---|
| 355 | buffer = [];
|
|---|
| 356 | isBufferEmpty = true;
|
|---|
| 357 |
|
|---|
| 358 | ruleToken[2] = intoTokens(source, externalContext, internalContext, true);
|
|---|
| 359 | ruleToken = null;
|
|---|
| 360 | } else if (character == Marker.OPEN_CURLY_BRACKET
|
|---|
| 361 | && level == Level.BLOCK
|
|---|
| 362 | && tokenTypeFrom(buffer) == Token.NESTED_BLOCK) {
|
|---|
| 363 | // open brace opening at-rule at block level, e.g. @media{<--
|
|---|
| 364 | serializedBuffer = buffer.join('').trim();
|
|---|
| 365 | ruleToken = ruleToken || [Token.NESTED_BLOCK, [], []];
|
|---|
| 366 | ruleToken[1].push([
|
|---|
| 367 | Token.NESTED_BLOCK_SCOPE,
|
|---|
| 368 | serializedBuffer,
|
|---|
| 369 | [originalMetadata(metadata, serializedBuffer, externalContext)]
|
|---|
| 370 | ]);
|
|---|
| 371 | allTokens.push(ruleToken);
|
|---|
| 372 |
|
|---|
| 373 | levels.push(level);
|
|---|
| 374 | position.column++;
|
|---|
| 375 | position.index++;
|
|---|
| 376 | buffer = [];
|
|---|
| 377 | isBufferEmpty = true;
|
|---|
| 378 | isVariable = false;
|
|---|
| 379 |
|
|---|
| 380 | ruleToken[2] = intoTokens(source, externalContext, internalContext, true);
|
|---|
| 381 | ruleToken = null;
|
|---|
| 382 | } else if (character == Marker.OPEN_CURLY_BRACKET && level == Level.BLOCK) {
|
|---|
| 383 | // open brace opening rule at block level, e.g. div{<--
|
|---|
| 384 | serializedBuffer = buffer.join('').trim();
|
|---|
| 385 | ruleToken = ruleToken || [tokenTypeFrom(buffer), [], []];
|
|---|
| 386 | ruleToken[1].push([
|
|---|
| 387 | tokenScopeFrom(ruleToken[0]),
|
|---|
| 388 | serializedBuffer,
|
|---|
| 389 | [originalMetadata(metadata, serializedBuffer, externalContext, ruleToken[1].length)]
|
|---|
| 390 | ]);
|
|---|
| 391 | newTokens = ruleToken[2];
|
|---|
| 392 | allTokens.push(ruleToken);
|
|---|
| 393 |
|
|---|
| 394 | levels.push(level);
|
|---|
| 395 | level = Level.RULE;
|
|---|
| 396 | buffer = [];
|
|---|
| 397 | isBufferEmpty = true;
|
|---|
| 398 | } else if (character == Marker.OPEN_CURLY_BRACKET && level == Level.RULE && seekingValue) {
|
|---|
| 399 | // open brace opening rule at rule level, e.g. div{--variable:{<--
|
|---|
| 400 | ruleTokens.push(ruleToken);
|
|---|
| 401 | ruleToken = [Token.PROPERTY_BLOCK, []];
|
|---|
| 402 | propertyToken.push(ruleToken);
|
|---|
| 403 | newTokens = ruleToken[1];
|
|---|
| 404 |
|
|---|
| 405 | levels.push(level);
|
|---|
| 406 | level = Level.RULE;
|
|---|
| 407 | seekingValue = false;
|
|---|
| 408 | } else if (character == Marker.OPEN_CURLY_BRACKET && level == Level.RULE && isPageMarginBox(buffer)) {
|
|---|
| 409 | // open brace opening page-margin box at rule level, e.g. @page{@top-center{<--
|
|---|
| 410 | serializedBuffer = buffer.join('').trim();
|
|---|
| 411 | ruleTokens.push(ruleToken);
|
|---|
| 412 | ruleToken = [Token.AT_RULE_BLOCK, [], []];
|
|---|
| 413 | ruleToken[1].push([
|
|---|
| 414 | Token.AT_RULE_BLOCK_SCOPE,
|
|---|
| 415 | serializedBuffer,
|
|---|
| 416 | [originalMetadata(metadata, serializedBuffer, externalContext)]
|
|---|
| 417 | ]);
|
|---|
| 418 | newTokens.push(ruleToken);
|
|---|
| 419 | newTokens = ruleToken[2];
|
|---|
| 420 |
|
|---|
| 421 | levels.push(level);
|
|---|
| 422 | level = Level.RULE;
|
|---|
| 423 | buffer = [];
|
|---|
| 424 | isBufferEmpty = true;
|
|---|
| 425 | } else if (character == Marker.COLON && level == Level.RULE && !seekingValue) {
|
|---|
| 426 | // colon at rule level, e.g. a{color:<--
|
|---|
| 427 | serializedBuffer = buffer.join('').trim();
|
|---|
| 428 | propertyToken = [
|
|---|
| 429 | Token.PROPERTY,
|
|---|
| 430 | [
|
|---|
| 431 | Token.PROPERTY_NAME,
|
|---|
| 432 | serializedBuffer,
|
|---|
| 433 | [originalMetadata(metadata, serializedBuffer, externalContext)]
|
|---|
| 434 | ]
|
|---|
| 435 | ];
|
|---|
| 436 | newTokens.push(propertyToken);
|
|---|
| 437 |
|
|---|
| 438 | seekingValue = true;
|
|---|
| 439 | buffer = [];
|
|---|
| 440 | isBufferEmpty = true;
|
|---|
| 441 | } else if (character == Marker.SEMICOLON
|
|---|
| 442 | && level == Level.RULE
|
|---|
| 443 | && propertyToken
|
|---|
| 444 | && ruleTokens.length > 0
|
|---|
| 445 | && !isBufferEmpty
|
|---|
| 446 | && buffer[0] == Marker.AT) {
|
|---|
| 447 | // semicolon at rule level for at-rule, e.g. a{--color:{@apply(--other-color);<--
|
|---|
| 448 | serializedBuffer = buffer.join('').trim();
|
|---|
| 449 | ruleToken[1].push([
|
|---|
| 450 | Token.AT_RULE,
|
|---|
| 451 | serializedBuffer,
|
|---|
| 452 | [originalMetadata(metadata, serializedBuffer, externalContext)]
|
|---|
| 453 | ]);
|
|---|
| 454 |
|
|---|
| 455 | buffer = [];
|
|---|
| 456 | isBufferEmpty = true;
|
|---|
| 457 | } else if (character == Marker.SEMICOLON && level == Level.RULE && propertyToken && !isBufferEmpty) {
|
|---|
| 458 | // semicolon at rule level, e.g. a{color:red;<--
|
|---|
| 459 | serializedBuffer = buffer.join('').trim();
|
|---|
| 460 | propertyToken.push([
|
|---|
| 461 | Token.PROPERTY_VALUE,
|
|---|
| 462 | serializedBuffer,
|
|---|
| 463 | [originalMetadata(metadata, serializedBuffer, externalContext)]
|
|---|
| 464 | ]);
|
|---|
| 465 |
|
|---|
| 466 | propertyToken = null;
|
|---|
| 467 | seekingValue = false;
|
|---|
| 468 | buffer = [];
|
|---|
| 469 | isBufferEmpty = true;
|
|---|
| 470 | isVariable = false;
|
|---|
| 471 | } else if (character == Marker.SEMICOLON
|
|---|
| 472 | && level == Level.RULE
|
|---|
| 473 | && propertyToken
|
|---|
| 474 | && isBufferEmpty
|
|---|
| 475 | && isVariable
|
|---|
| 476 | && !propertyToken[2]) {
|
|---|
| 477 | // semicolon after empty variable value at rule level, e.g. a{--color: ;<--
|
|---|
| 478 | propertyToken.push([Token.PROPERTY_VALUE, ' ', [originalMetadata(metadata, ' ', externalContext)]]);
|
|---|
| 479 | isVariable = false;
|
|---|
| 480 | propertyToken = null;
|
|---|
| 481 | seekingValue = false;
|
|---|
| 482 | } else if (character == Marker.SEMICOLON && level == Level.RULE && propertyToken && isBufferEmpty) {
|
|---|
| 483 | // semicolon after bracketed value at rule level, e.g. a{color:rgb(...);<--
|
|---|
| 484 | propertyToken = null;
|
|---|
| 485 | seekingValue = false;
|
|---|
| 486 | } else if (character == Marker.SEMICOLON
|
|---|
| 487 | && level == Level.RULE
|
|---|
| 488 | && !isBufferEmpty
|
|---|
| 489 | && buffer[0] == Marker.AT) {
|
|---|
| 490 | // semicolon for at-rule at rule level, e.g. a{@apply(--variable);<--
|
|---|
| 491 | serializedBuffer = buffer.join('');
|
|---|
| 492 | newTokens.push([
|
|---|
| 493 | Token.AT_RULE,
|
|---|
| 494 | serializedBuffer,
|
|---|
| 495 | [originalMetadata(metadata, serializedBuffer, externalContext)]
|
|---|
| 496 | ]);
|
|---|
| 497 |
|
|---|
| 498 | seekingValue = false;
|
|---|
| 499 | buffer = [];
|
|---|
| 500 | isBufferEmpty = true;
|
|---|
| 501 | } else if (character == Marker.SEMICOLON && level == Level.RULE && seekingPropertyBlockClosing) {
|
|---|
| 502 | // close brace after a property block at rule level, e.g. a{--custom:{color:red;};<--
|
|---|
| 503 | seekingPropertyBlockClosing = false;
|
|---|
| 504 | buffer = [];
|
|---|
| 505 | isBufferEmpty = true;
|
|---|
| 506 | } else if (character == Marker.SEMICOLON && level == Level.RULE && isBufferEmpty) {
|
|---|
| 507 | // stray semicolon at rule level, e.g. a{;<--
|
|---|
| 508 | // noop
|
|---|
| 509 | } else if (character == Marker.CLOSE_CURLY_BRACKET
|
|---|
| 510 | && level == Level.RULE
|
|---|
| 511 | && propertyToken
|
|---|
| 512 | && seekingValue
|
|---|
| 513 | && !isBufferEmpty && ruleTokens.length > 0) {
|
|---|
| 514 | // close brace at rule level, e.g. a{--color:{color:red}<--
|
|---|
| 515 | serializedBuffer = buffer.join('');
|
|---|
| 516 | propertyToken.push([
|
|---|
| 517 | Token.PROPERTY_VALUE,
|
|---|
| 518 | serializedBuffer,
|
|---|
| 519 | [originalMetadata(metadata, serializedBuffer, externalContext)]
|
|---|
| 520 | ]);
|
|---|
| 521 | propertyToken = null;
|
|---|
| 522 | ruleToken = ruleTokens.pop();
|
|---|
| 523 | newTokens = ruleToken[2];
|
|---|
| 524 |
|
|---|
| 525 | level = levels.pop();
|
|---|
| 526 | seekingValue = false;
|
|---|
| 527 | buffer = [];
|
|---|
| 528 | isBufferEmpty = true;
|
|---|
| 529 | } else if (character == Marker.CLOSE_CURLY_BRACKET
|
|---|
| 530 | && level == Level.RULE
|
|---|
| 531 | && propertyToken
|
|---|
| 532 | && !isBufferEmpty
|
|---|
| 533 | && buffer[0] == Marker.AT
|
|---|
| 534 | && ruleTokens.length > 0) {
|
|---|
| 535 | // close brace at rule level for at-rule, e.g. a{--color:{@apply(--other-color)}<--
|
|---|
| 536 | serializedBuffer = buffer.join('');
|
|---|
| 537 | ruleToken[1].push([
|
|---|
| 538 | Token.AT_RULE,
|
|---|
| 539 | serializedBuffer,
|
|---|
| 540 | [originalMetadata(metadata, serializedBuffer, externalContext)]
|
|---|
| 541 | ]);
|
|---|
| 542 | propertyToken = null;
|
|---|
| 543 | ruleToken = ruleTokens.pop();
|
|---|
| 544 | newTokens = ruleToken[2];
|
|---|
| 545 |
|
|---|
| 546 | level = levels.pop();
|
|---|
| 547 | seekingValue = false;
|
|---|
| 548 | buffer = [];
|
|---|
| 549 | isBufferEmpty = true;
|
|---|
| 550 | } else if (character == Marker.CLOSE_CURLY_BRACKET
|
|---|
| 551 | && level == Level.RULE
|
|---|
| 552 | && propertyToken
|
|---|
| 553 | && ruleTokens.length > 0) {
|
|---|
| 554 | // close brace at rule level after space, e.g. a{--color:{color:red }<--
|
|---|
| 555 | propertyToken = null;
|
|---|
| 556 | ruleToken = ruleTokens.pop();
|
|---|
| 557 | newTokens = ruleToken[2];
|
|---|
| 558 |
|
|---|
| 559 | level = levels.pop();
|
|---|
| 560 | seekingValue = false;
|
|---|
| 561 | } else if (character == Marker.CLOSE_CURLY_BRACKET
|
|---|
| 562 | && level == Level.RULE
|
|---|
| 563 | && propertyToken
|
|---|
| 564 | && !isBufferEmpty) {
|
|---|
| 565 | // close brace at rule level, e.g. a{color:red}<--
|
|---|
| 566 | serializedBuffer = buffer.join('');
|
|---|
| 567 | propertyToken.push([
|
|---|
| 568 | Token.PROPERTY_VALUE,
|
|---|
| 569 | serializedBuffer,
|
|---|
| 570 | [originalMetadata(metadata, serializedBuffer, externalContext)]
|
|---|
| 571 | ]);
|
|---|
| 572 | propertyToken = null;
|
|---|
| 573 | ruleToken = ruleTokens.pop();
|
|---|
| 574 | newTokens = allTokens;
|
|---|
| 575 |
|
|---|
| 576 | level = levels.pop();
|
|---|
| 577 | seekingValue = false;
|
|---|
| 578 | buffer = [];
|
|---|
| 579 | isBufferEmpty = true;
|
|---|
| 580 | } else if (character == Marker.CLOSE_CURLY_BRACKET
|
|---|
| 581 | && level == Level.RULE
|
|---|
| 582 | && !isBufferEmpty
|
|---|
| 583 | && buffer[0] == Marker.AT) {
|
|---|
| 584 | // close brace after at-rule at rule level, e.g. a{@apply(--variable)}<--
|
|---|
| 585 | propertyToken = null;
|
|---|
| 586 | ruleToken = null;
|
|---|
| 587 | serializedBuffer = buffer.join('').trim();
|
|---|
| 588 | newTokens.push([
|
|---|
| 589 | Token.AT_RULE,
|
|---|
| 590 | serializedBuffer,
|
|---|
| 591 | [originalMetadata(metadata, serializedBuffer, externalContext)]
|
|---|
| 592 | ]);
|
|---|
| 593 | newTokens = allTokens;
|
|---|
| 594 |
|
|---|
| 595 | level = levels.pop();
|
|---|
| 596 | seekingValue = false;
|
|---|
| 597 | buffer = [];
|
|---|
| 598 | isBufferEmpty = true;
|
|---|
| 599 | } else if (character == Marker.CLOSE_CURLY_BRACKET
|
|---|
| 600 | && level == Level.RULE
|
|---|
| 601 | && levels[levels.length - 1] == Level.RULE) {
|
|---|
| 602 | // close brace after a property block at rule level, e.g. a{--custom:{color:red;}<--
|
|---|
| 603 | propertyToken = null;
|
|---|
| 604 | ruleToken = ruleTokens.pop();
|
|---|
| 605 | newTokens = ruleToken[2];
|
|---|
| 606 |
|
|---|
| 607 | level = levels.pop();
|
|---|
| 608 | seekingValue = false;
|
|---|
| 609 | seekingPropertyBlockClosing = true;
|
|---|
| 610 | buffer = [];
|
|---|
| 611 | isBufferEmpty = true;
|
|---|
| 612 | } else if (character == Marker.CLOSE_CURLY_BRACKET
|
|---|
| 613 | && level == Level.RULE
|
|---|
| 614 | && isVariable
|
|---|
| 615 | && propertyToken
|
|---|
| 616 | && !propertyToken[2]) {
|
|---|
| 617 | // close brace after an empty variable declaration inside a rule, e.g. a{--color: }<--
|
|---|
| 618 | propertyToken.push([Token.PROPERTY_VALUE, ' ', [originalMetadata(metadata, ' ', externalContext)]]);
|
|---|
| 619 | isVariable = false;
|
|---|
| 620 | propertyToken = null;
|
|---|
| 621 | ruleToken = null;
|
|---|
| 622 | newTokens = allTokens;
|
|---|
| 623 |
|
|---|
| 624 | level = levels.pop();
|
|---|
| 625 | seekingValue = false;
|
|---|
| 626 | isVariable = false;
|
|---|
| 627 | } else if (character == Marker.CLOSE_CURLY_BRACKET && level == Level.RULE) {
|
|---|
| 628 | // close brace after a rule, e.g. a{color:red;}<--
|
|---|
| 629 | propertyToken = null;
|
|---|
| 630 | ruleToken = null;
|
|---|
| 631 | newTokens = allTokens;
|
|---|
| 632 |
|
|---|
| 633 | level = levels.pop();
|
|---|
| 634 | seekingValue = false;
|
|---|
| 635 | isVariable = false;
|
|---|
| 636 | } else if (character == Marker.CLOSE_CURLY_BRACKET
|
|---|
| 637 | && level == Level.BLOCK
|
|---|
| 638 | && !isNested
|
|---|
| 639 | && position.index <= source.length - 1) {
|
|---|
| 640 | // stray close brace at block level, e.g. a{color:red}color:blue}<--
|
|---|
| 641 | externalContext.warnings.push('Unexpected \'}\' at ' + formatPosition([position.line, position.column, position.source]) + '.');
|
|---|
| 642 | buffer.push(character);
|
|---|
| 643 | isBufferEmpty = false;
|
|---|
| 644 | } else if (character == Marker.CLOSE_CURLY_BRACKET && level == Level.BLOCK) {
|
|---|
| 645 | // close brace at block level, e.g. @media screen {...}<--
|
|---|
| 646 | break;
|
|---|
| 647 | } else if (character == Marker.OPEN_ROUND_BRACKET && level == Level.RULE && seekingValue) {
|
|---|
| 648 | // round open bracket, e.g. a{color:hsla(<--
|
|---|
| 649 | buffer.push(character);
|
|---|
| 650 | isBufferEmpty = false;
|
|---|
| 651 | roundBracketLevel++;
|
|---|
| 652 | } else if (character == Marker.CLOSE_ROUND_BRACKET
|
|---|
| 653 | && level == Level.RULE
|
|---|
| 654 | && seekingValue
|
|---|
| 655 | && roundBracketLevel == 1) {
|
|---|
| 656 | // round close bracket, e.g. a{color:hsla(0,0%,0%)<--
|
|---|
| 657 | buffer.push(character);
|
|---|
| 658 | isBufferEmpty = false;
|
|---|
| 659 | serializedBuffer = buffer.join('').trim();
|
|---|
| 660 | propertyToken.push([
|
|---|
| 661 | Token.PROPERTY_VALUE,
|
|---|
| 662 | serializedBuffer,
|
|---|
| 663 | [originalMetadata(metadata, serializedBuffer, externalContext)]
|
|---|
| 664 | ]);
|
|---|
| 665 |
|
|---|
| 666 | roundBracketLevel--;
|
|---|
| 667 | buffer = [];
|
|---|
| 668 | isBufferEmpty = true;
|
|---|
| 669 | isVariable = false;
|
|---|
| 670 | } else if (character == Marker.CLOSE_ROUND_BRACKET && level == Level.RULE && seekingValue) {
|
|---|
| 671 | // round close bracket within other brackets, e.g. a{width:calc((10rem / 2)<--
|
|---|
| 672 | buffer.push(character);
|
|---|
| 673 | isBufferEmpty = false;
|
|---|
| 674 | isVariable = false;
|
|---|
| 675 | roundBracketLevel--;
|
|---|
| 676 | } else if (character == Marker.FORWARD_SLASH
|
|---|
| 677 | && source[position.index + 1] != Marker.ASTERISK
|
|---|
| 678 | && level == Level.RULE
|
|---|
| 679 | && seekingValue
|
|---|
| 680 | && !isBufferEmpty) {
|
|---|
| 681 | // forward slash within a property, e.g. a{background:url(image.png) 0 0/<--
|
|---|
| 682 | serializedBuffer = buffer.join('').trim();
|
|---|
| 683 | propertyToken.push([
|
|---|
| 684 | Token.PROPERTY_VALUE,
|
|---|
| 685 | serializedBuffer,
|
|---|
| 686 | [originalMetadata(metadata, serializedBuffer, externalContext)]
|
|---|
| 687 | ]);
|
|---|
| 688 | propertyToken.push([
|
|---|
| 689 | Token.PROPERTY_VALUE,
|
|---|
| 690 | character,
|
|---|
| 691 | [[position.line, position.column, position.source]]
|
|---|
| 692 | ]);
|
|---|
| 693 |
|
|---|
| 694 | buffer = [];
|
|---|
| 695 | isBufferEmpty = true;
|
|---|
| 696 | } else if (character == Marker.FORWARD_SLASH
|
|---|
| 697 | && source[position.index + 1] != Marker.ASTERISK
|
|---|
| 698 | && level == Level.RULE
|
|---|
| 699 | && seekingValue) {
|
|---|
| 700 | // forward slash within a property after space, e.g. a{background:url(image.png) 0 0 /<--
|
|---|
| 701 | propertyToken.push([
|
|---|
| 702 | Token.PROPERTY_VALUE,
|
|---|
| 703 | character,
|
|---|
| 704 | [[position.line, position.column, position.source]]
|
|---|
| 705 | ]);
|
|---|
| 706 |
|
|---|
| 707 | buffer = [];
|
|---|
| 708 | isBufferEmpty = true;
|
|---|
| 709 | } else if (character == Marker.COMMA && level == Level.RULE && seekingValue && !isBufferEmpty) {
|
|---|
| 710 | // comma within a property, e.g. a{background:url(image.png),<--
|
|---|
| 711 | serializedBuffer = buffer.join('').trim();
|
|---|
| 712 | propertyToken.push([
|
|---|
| 713 | Token.PROPERTY_VALUE,
|
|---|
| 714 | serializedBuffer,
|
|---|
| 715 | [originalMetadata(metadata, serializedBuffer, externalContext)]
|
|---|
| 716 | ]);
|
|---|
| 717 | propertyToken.push([
|
|---|
| 718 | Token.PROPERTY_VALUE,
|
|---|
| 719 | character,
|
|---|
| 720 | [[position.line, position.column, position.source]]
|
|---|
| 721 | ]);
|
|---|
| 722 |
|
|---|
| 723 | buffer = [];
|
|---|
| 724 | isBufferEmpty = true;
|
|---|
| 725 | } else if (character == Marker.COMMA && level == Level.RULE && seekingValue) {
|
|---|
| 726 | // comma within a property after space, e.g. a{background:url(image.png) ,<--
|
|---|
| 727 | propertyToken.push([
|
|---|
| 728 | Token.PROPERTY_VALUE,
|
|---|
| 729 | character,
|
|---|
| 730 | [[position.line, position.column, position.source]]
|
|---|
| 731 | ]);
|
|---|
| 732 |
|
|---|
| 733 | buffer = [];
|
|---|
| 734 | isBufferEmpty = true;
|
|---|
| 735 | } else if (character == Marker.CLOSE_SQUARE_BRACKET
|
|---|
| 736 | && propertyToken
|
|---|
| 737 | && propertyToken.length > 1
|
|---|
| 738 | && !isBufferEmpty
|
|---|
| 739 | && isRepeatToken(buffer)) {
|
|---|
| 740 | buffer.push(character);
|
|---|
| 741 | serializedBuffer = buffer.join('').trim();
|
|---|
| 742 | propertyToken[propertyToken.length - 1][1] += serializedBuffer;
|
|---|
| 743 |
|
|---|
| 744 | buffer = [];
|
|---|
| 745 | isBufferEmpty = true;
|
|---|
| 746 | } else if ((isSpace || (isNewLineNix && !isNewLineWin))
|
|---|
| 747 | && level == Level.RULE
|
|---|
| 748 | && seekingValue
|
|---|
| 749 | && propertyToken
|
|---|
| 750 | && !isBufferEmpty) {
|
|---|
| 751 | // space or *nix newline within property, e.g. a{margin:0 <--
|
|---|
| 752 | serializedBuffer = buffer.join('').trim();
|
|---|
| 753 | propertyToken.push([
|
|---|
| 754 | Token.PROPERTY_VALUE,
|
|---|
| 755 | serializedBuffer,
|
|---|
| 756 | [originalMetadata(metadata, serializedBuffer, externalContext)]
|
|---|
| 757 | ]);
|
|---|
| 758 |
|
|---|
| 759 | buffer = [];
|
|---|
| 760 | isBufferEmpty = true;
|
|---|
| 761 | } else if (isNewLineWin && level == Level.RULE && seekingValue && propertyToken && buffer.length > 1) {
|
|---|
| 762 | // win newline within property, e.g. a{margin:0\r\n<--
|
|---|
| 763 | serializedBuffer = buffer.join('').trim();
|
|---|
| 764 | propertyToken.push([
|
|---|
| 765 | Token.PROPERTY_VALUE,
|
|---|
| 766 | serializedBuffer,
|
|---|
| 767 | [originalMetadata(metadata, serializedBuffer, externalContext)]
|
|---|
| 768 | ]);
|
|---|
| 769 |
|
|---|
| 770 | buffer = [];
|
|---|
| 771 | isBufferEmpty = true;
|
|---|
| 772 | } else if (isNewLineWin && level == Level.RULE && seekingValue) {
|
|---|
| 773 | // win newline
|
|---|
| 774 | buffer = [];
|
|---|
| 775 | isBufferEmpty = true;
|
|---|
| 776 | } else if (isNewLineWin && buffer.length == 1) {
|
|---|
| 777 | // ignore windows newline which is composed of two characters
|
|---|
| 778 | buffer.pop();
|
|---|
| 779 | isBufferEmpty = buffer.length === 0;
|
|---|
| 780 | } else if (!isBufferEmpty || !isSpace && !isNewLineNix && !isNewLineWin && !isCarriageReturn) {
|
|---|
| 781 | // any character
|
|---|
| 782 | buffer.push(character);
|
|---|
| 783 | isBufferEmpty = false;
|
|---|
| 784 | }
|
|---|
| 785 |
|
|---|
| 786 | wasEscaped = isEscaped;
|
|---|
| 787 | isEscaped = !wasEscaped && character == Marker.BACK_SLASH;
|
|---|
| 788 | wasCommentStart = isCommentStart;
|
|---|
| 789 | wasCommentEnd = isCommentEnd;
|
|---|
| 790 |
|
|---|
| 791 | position.line = (isNewLineWin || isNewLineNix || isCarriageReturn) ? position.line + 1 : position.line;
|
|---|
| 792 | position.column = (isNewLineWin || isNewLineNix || isCarriageReturn) ? 0 : position.column + 1;
|
|---|
| 793 | }
|
|---|
| 794 |
|
|---|
| 795 | if (seekingValue) {
|
|---|
| 796 | externalContext.warnings.push('Missing \'}\' at ' + formatPosition([position.line, position.column, position.source]) + '.');
|
|---|
| 797 | }
|
|---|
| 798 |
|
|---|
| 799 | if (seekingValue && buffer.length > 0) {
|
|---|
| 800 | serializedBuffer = buffer.join('').trimRight().replace(TAIL_BROKEN_VALUE_PATTERN, '$1').trimRight();
|
|---|
| 801 | propertyToken.push([
|
|---|
| 802 | Token.PROPERTY_VALUE,
|
|---|
| 803 | serializedBuffer,
|
|---|
| 804 | [originalMetadata(metadata, serializedBuffer, externalContext)]
|
|---|
| 805 | ]);
|
|---|
| 806 |
|
|---|
| 807 | buffer = [];
|
|---|
| 808 | }
|
|---|
| 809 |
|
|---|
| 810 | if (buffer.length > 0) {
|
|---|
| 811 | externalContext.warnings.push('Invalid character(s) \'' + buffer.join('') + '\' at ' + formatPosition(metadata) + '. Ignoring.');
|
|---|
| 812 | }
|
|---|
| 813 |
|
|---|
| 814 | return allTokens;
|
|---|
| 815 | }
|
|---|
| 816 |
|
|---|
| 817 | function isIgnoreStartComment(buffer) {
|
|---|
| 818 | return IGNORE_START_COMMENT_PATTERN.test(buffer.join('') + Marker.FORWARD_SLASH);
|
|---|
| 819 | }
|
|---|
| 820 |
|
|---|
| 821 | function isIgnoreEndComment(buffer) {
|
|---|
| 822 | return IGNORE_END_COMMENT_PATTERN.test(buffer.join('') + Marker.FORWARD_SLASH);
|
|---|
| 823 | }
|
|---|
| 824 |
|
|---|
| 825 | function originalMetadata(metadata, value, externalContext, selectorFallbacks) {
|
|---|
| 826 | var source = metadata[2];
|
|---|
| 827 |
|
|---|
| 828 | return externalContext.inputSourceMapTracker.isTracking(source)
|
|---|
| 829 | ? externalContext.inputSourceMapTracker.originalPositionFor(metadata, value.length, selectorFallbacks)
|
|---|
| 830 | : metadata;
|
|---|
| 831 | }
|
|---|
| 832 |
|
|---|
| 833 | function tokenTypeFrom(buffer) {
|
|---|
| 834 | var isAtRule = buffer[0] == Marker.AT || buffer[0] == Marker.UNDERSCORE;
|
|---|
| 835 | var ruleWord = buffer.join('').split(RULE_WORD_SEPARATOR_PATTERN)[0];
|
|---|
| 836 |
|
|---|
| 837 | if (isAtRule && BLOCK_RULES.indexOf(ruleWord) > -1) {
|
|---|
| 838 | return Token.NESTED_BLOCK;
|
|---|
| 839 | } if (isAtRule && AT_RULES.indexOf(ruleWord) > -1) {
|
|---|
| 840 | return Token.AT_RULE;
|
|---|
| 841 | } if (isAtRule) {
|
|---|
| 842 | return Token.AT_RULE_BLOCK;
|
|---|
| 843 | }
|
|---|
| 844 | return Token.RULE;
|
|---|
| 845 | }
|
|---|
| 846 |
|
|---|
| 847 | function tokenScopeFrom(tokenType) {
|
|---|
| 848 | if (tokenType == Token.RULE) {
|
|---|
| 849 | return Token.RULE_SCOPE;
|
|---|
| 850 | } if (tokenType == Token.NESTED_BLOCK) {
|
|---|
| 851 | return Token.NESTED_BLOCK_SCOPE;
|
|---|
| 852 | } if (tokenType == Token.AT_RULE_BLOCK) {
|
|---|
| 853 | return Token.AT_RULE_BLOCK_SCOPE;
|
|---|
| 854 | }
|
|---|
| 855 | }
|
|---|
| 856 |
|
|---|
| 857 | function isPageMarginBox(buffer) {
|
|---|
| 858 | var serializedBuffer = buffer.join('').trim();
|
|---|
| 859 |
|
|---|
| 860 | return PAGE_MARGIN_BOXES.indexOf(serializedBuffer) > -1 || EXTRA_PAGE_BOXES.indexOf(serializedBuffer) > -1;
|
|---|
| 861 | }
|
|---|
| 862 |
|
|---|
| 863 | function isRepeatToken(buffer) {
|
|---|
| 864 | return REPEAT_PATTERN.test(buffer.join('') + Marker.CLOSE_SQUARE_BRACKET);
|
|---|
| 865 | }
|
|---|
| 866 |
|
|---|
| 867 | module.exports = tokenize;
|
|---|