corrade-nucleus-nucleons – Blame information for rev 20

Subversion Repositories:
Rev:
Rev Author Line No. Line
20 office 1 /*jshint curly:true, eqeqeq:true, laxbreak:true, noempty:false */
2 /*
3  
4 The MIT License (MIT)
5  
6 Copyright (c) 2007-2017 Einar Lielmanis, Liam Newman, and contributors.
7  
8 Permission is hereby granted, free of charge, to any person
9 obtaining a copy of this software and associated documentation files
10 (the "Software"), to deal in the Software without restriction,
11 including without limitation the rights to use, copy, modify, merge,
12 publish, distribute, sublicense, and/or sell copies of the Software,
13 and to permit persons to whom the Software is furnished to do so,
14 subject to the following conditions:
15  
16 The above copyright notice and this permission notice shall be
17 included in all copies or substantial portions of the Software.
18  
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
23 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
24 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 SOFTWARE.
27  
28  
29 CSS Beautifier
30 ---------------
31  
32 Written by Harutyun Amirjanyan, (amirjanyan@gmail.com)
33  
34 Based on code initially developed by: Einar Lielmanis, <einar@jsbeautifier.org>
35 http://jsbeautifier.org/
36  
37 Usage:
38 css_beautify(source_text);
39 css_beautify(source_text, options);
40  
41 The options are (default in brackets):
42 indent_size (4) — indentation size,
43 indent_char (space) — character to indent with,
44 preserve_newlines (default false) - whether existing line breaks should be preserved,
45 selector_separator_newline (true) - separate selectors with newline or
46 not (e.g. "a,\nbr" or "a, br")
47 end_with_newline (false) - end with a newline
48 newline_between_rules (true) - add a new line after every css rule
49 space_around_selector_separator (false) - ensure space around selector separators:
50 '>', '+', '~' (e.g. "a>b" -> "a > b")
51 e.g
52  
53 css_beautify(css_source_text, {
54 'indent_size': 1,
55 'indent_char': '\t',
56 'selector_separator': ' ',
57 'end_with_newline': false,
58 'newline_between_rules': true,
59 'space_around_selector_separator': true
60 });
61 */
62  
63 // http://www.w3.org/TR/CSS21/syndata.html#tokenization
64 // http://www.w3.org/TR/css3-syntax/
65  
66 (function() {
67  
68 function mergeOpts(allOptions, targetType) {
69 var finalOpts = {};
70 var name;
71  
72 for (name in allOptions) {
73 if (name !== targetType) {
74 finalOpts[name] = allOptions[name];
75 }
76 }
77  
78  
79 //merge in the per type settings for the targetType
80 if (targetType in allOptions) {
81 for (name in allOptions[targetType]) {
82 finalOpts[name] = allOptions[targetType][name];
83 }
84 }
85 return finalOpts;
86 }
87  
88 var lineBreak = /\r\n|[\n\r\u2028\u2029]/;
89 var allLineBreaks = new RegExp(lineBreak.source, 'g');
90  
91 function css_beautify(source_text, options) {
92 options = options || {};
93  
94 // Allow the setting of language/file-type specific options
95 // with inheritance of overall settings
96 options = mergeOpts(options, 'css');
97  
98 source_text = source_text || '';
99  
100 var newlinesFromLastWSEat = 0;
101 var indentSize = options.indent_size ? parseInt(options.indent_size, 10) : 4;
102 var indentCharacter = options.indent_char || ' ';
103 var preserve_newlines = (options.preserve_newlines === undefined) ? false : options.preserve_newlines;
104 var selectorSeparatorNewline = (options.selector_separator_newline === undefined) ? true : options.selector_separator_newline;
105 var end_with_newline = (options.end_with_newline === undefined) ? false : options.end_with_newline;
106 var newline_between_rules = (options.newline_between_rules === undefined) ? true : options.newline_between_rules;
107 var space_around_combinator = (options.space_around_combinator === undefined) ? false : options.space_around_combinator;
108 space_around_combinator = space_around_combinator || ((options.space_around_selector_separator === undefined) ? false : options.space_around_selector_separator);
109 var eol = options.eol ? options.eol : 'auto';
110  
111 if (options.indent_with_tabs) {
112 indentCharacter = '\t';
113 indentSize = 1;
114 }
115  
116 if (eol === 'auto') {
117 eol = '\n';
118 if (source_text && lineBreak.test(source_text || '')) {
119 eol = source_text.match(lineBreak)[0];
120 }
121 }
122  
123 eol = eol.replace(/\\r/, '\r').replace(/\\n/, '\n');
124  
125 // HACK: newline parsing inconsistent. This brute force normalizes the input.
126 source_text = source_text.replace(allLineBreaks, '\n');
127  
128 // tokenizer
129 var whiteRe = /^\s+$/;
130  
131 var pos = -1,
132 ch;
133 var parenLevel = 0;
134  
135 function next() {
136 ch = source_text.charAt(++pos);
137 return ch || '';
138 }
139  
140 function peek(skipWhitespace) {
141 var result = '';
142 var prev_pos = pos;
143 if (skipWhitespace) {
144 eatWhitespace();
145 }
146 result = source_text.charAt(pos + 1) || '';
147 pos = prev_pos - 1;
148 next();
149 return result;
150 }
151  
152 function eatString(endChars) {
153 var start = pos;
154 while (next()) {
155 if (ch === "\\") {
156 next();
157 } else if (endChars.indexOf(ch) !== -1) {
158 break;
159 } else if (ch === "\n") {
160 break;
161 }
162 }
163 return source_text.substring(start, pos + 1);
164 }
165  
166 function peekString(endChar) {
167 var prev_pos = pos;
168 var str = eatString(endChar);
169 pos = prev_pos - 1;
170 next();
171 return str;
172 }
173  
174 function eatWhitespace(preserve_newlines_local) {
175 var result = 0;
176 while (whiteRe.test(peek())) {
177 next();
178 if (ch === '\n' && preserve_newlines_local && preserve_newlines) {
179 print.newLine(true);
180 result++;
181 }
182 }
183 newlinesFromLastWSEat = result;
184 return result;
185 }
186  
187 function skipWhitespace() {
188 var result = '';
189 if (ch && whiteRe.test(ch)) {
190 result = ch;
191 }
192 while (whiteRe.test(next())) {
193 result += ch;
194 }
195 return result;
196 }
197  
198 function eatComment(singleLine) {
199 var start = pos;
200 singleLine = peek() === "/";
201 next();
202 while (next()) {
203 if (!singleLine && ch === "*" && peek() === "/") {
204 next();
205 break;
206 } else if (singleLine && ch === "\n") {
207 return source_text.substring(start, pos);
208 }
209 }
210  
211 return source_text.substring(start, pos) + ch;
212 }
213  
214  
215 function lookBack(str) {
216 return source_text.substring(pos - str.length, pos).toLowerCase() ===
217 str;
218 }
219  
220 // Nested pseudo-class if we are insideRule
221 // and the next special character found opens
222 // a new block
223 function foundNestedPseudoClass() {
224 var openParen = 0;
225 for (var i = pos + 1; i < source_text.length; i++) {
226 var ch = source_text.charAt(i);
227 if (ch === "{") {
228 return true;
229 } else if (ch === '(') {
230 // pseudoclasses can contain ()
231 openParen += 1;
232 } else if (ch === ')') {
233 if (openParen === 0) {
234 return false;
235 }
236 openParen -= 1;
237 } else if (ch === ";" || ch === "}") {
238 return false;
239 }
240 }
241 return false;
242 }
243  
244 // printer
245 var basebaseIndentString = source_text.match(/^[\t ]*/)[0];
246 var singleIndent = new Array(indentSize + 1).join(indentCharacter);
247 var indentLevel = 0;
248 var nestedLevel = 0;
249  
250 function indent() {
251 indentLevel++;
252 basebaseIndentString += singleIndent;
253 }
254  
255 function outdent() {
256 indentLevel--;
257 basebaseIndentString = basebaseIndentString.slice(0, -indentSize);
258 }
259  
260 var print = {};
261 print["{"] = function(ch) {
262 print.singleSpace();
263 output.push(ch);
264 if (!eatWhitespace(true)) {
265 print.newLine();
266 }
267 };
268 print["}"] = function(newline) {
269 if (newline) {
270 print.newLine();
271 }
272 output.push('}');
273 if (!eatWhitespace(true)) {
274 print.newLine();
275 }
276 };
277  
278 print._lastCharWhitespace = function() {
279 return whiteRe.test(output[output.length - 1]);
280 };
281  
282 print.newLine = function(keepWhitespace) {
283 if (output.length) {
284 if (!keepWhitespace && output[output.length - 1] !== '\n') {
285 print.trim();
286 } else if (output[output.length - 1] === basebaseIndentString) {
287 output.pop();
288 }
289 output.push('\n');
290  
291 if (basebaseIndentString) {
292 output.push(basebaseIndentString);
293 }
294 }
295 };
296 print.singleSpace = function() {
297 if (output.length && !print._lastCharWhitespace()) {
298 output.push(' ');
299 }
300 };
301  
302 print.preserveSingleSpace = function() {
303 if (isAfterSpace) {
304 print.singleSpace();
305 }
306 };
307  
308 print.trim = function() {
309 while (print._lastCharWhitespace()) {
310 output.pop();
311 }
312 };
313  
314  
315 var output = [];
316 /*_____________________--------------------_____________________*/
317  
318 var insideRule = false;
319 var insidePropertyValue = false;
320 var enteringConditionalGroup = false;
321 var top_ch = '';
322 var last_top_ch = '';
323  
324 while (true) {
325 var whitespace = skipWhitespace();
326 var isAfterSpace = whitespace !== '';
327 var isAfterNewline = whitespace.indexOf('\n') !== -1;
328 last_top_ch = top_ch;
329 top_ch = ch;
330  
331 if (!ch) {
332 break;
333 } else if (ch === '/' && peek() === '*') { /* css comment */
334 var header = indentLevel === 0;
335  
336 if (isAfterNewline || header) {
337 print.newLine();
338 }
339  
340 output.push(eatComment());
341 print.newLine();
342 if (header) {
343 print.newLine(true);
344 }
345 } else if (ch === '/' && peek() === '/') { // single line comment
346 if (!isAfterNewline && last_top_ch !== '{') {
347 print.trim();
348 }
349 print.singleSpace();
350 output.push(eatComment());
351 print.newLine();
352 } else if (ch === '@') {
353 print.preserveSingleSpace();
354  
355 // deal with less propery mixins @{...}
356 if (peek() === '{') {
357 output.push(eatString('}'));
358 } else {
359 output.push(ch);
360  
361 // strip trailing space, if present, for hash property checks
362 var variableOrRule = peekString(": ,;{}()[]/='\"");
363  
364 if (variableOrRule.match(/[ :]$/)) {
365 // we have a variable or pseudo-class, add it and insert one space before continuing
366 next();
367 variableOrRule = eatString(": ").replace(/\s$/, '');
368 output.push(variableOrRule);
369 print.singleSpace();
370 }
371  
372 variableOrRule = variableOrRule.replace(/\s$/, '');
373  
374 // might be a nesting at-rule
375 if (variableOrRule in css_beautify.NESTED_AT_RULE) {
376 nestedLevel += 1;
377 if (variableOrRule in css_beautify.CONDITIONAL_GROUP_RULE) {
378 enteringConditionalGroup = true;
379 }
380 }
381 }
382 } else if (ch === '#' && peek() === '{') {
383 print.preserveSingleSpace();
384 output.push(eatString('}'));
385 } else if (ch === '{') {
386 if (peek(true) === '}') {
387 eatWhitespace();
388 next();
389 print.singleSpace();
390 output.push("{");
391 print['}'](false);
392 if (newlinesFromLastWSEat < 2 && newline_between_rules && indentLevel === 0) {
393 print.newLine(true);
394 }
395 } else {
396 indent();
397 print["{"](ch);
398 // when entering conditional groups, only rulesets are allowed
399 if (enteringConditionalGroup) {
400 enteringConditionalGroup = false;
401 insideRule = (indentLevel > nestedLevel);
402 } else {
403 // otherwise, declarations are also allowed
404 insideRule = (indentLevel >= nestedLevel);
405 }
406 }
407 } else if (ch === '}') {
408 outdent();
409 print["}"](true);
410 insideRule = false;
411 insidePropertyValue = false;
412 if (nestedLevel) {
413 nestedLevel--;
414 }
415 if (newlinesFromLastWSEat < 2 && newline_between_rules && indentLevel === 0) {
416 print.newLine(true);
417 }
418 } else if (ch === ":") {
419 eatWhitespace();
420 if ((insideRule || enteringConditionalGroup) &&
421 !(lookBack("&") || foundNestedPseudoClass()) &&
422 !lookBack("(")) {
423 // 'property: value' delimiter
424 // which could be in a conditional group query
425 output.push(':');
426 if (!insidePropertyValue) {
427 insidePropertyValue = true;
428 print.singleSpace();
429 }
430 } else {
431 // sass/less parent reference don't use a space
432 // sass nested pseudo-class don't use a space
433  
434 // preserve space before pseudoclasses/pseudoelements, as it means "in any child"
435 if (lookBack(" ") && output[output.length - 1] !== " ") {
436 output.push(" ");
437 }
438 if (peek() === ":") {
439 // pseudo-element
440 next();
441 output.push("::");
442 } else {
443 // pseudo-class
444 output.push(':');
445 }
446 }
447 } else if (ch === '"' || ch === '\'') {
448 print.preserveSingleSpace();
449 output.push(eatString(ch));
450 } else if (ch === ';') {
451 insidePropertyValue = false;
452 output.push(ch);
453 if (!eatWhitespace(true)) {
454 print.newLine();
455 }
456 } else if (ch === '(') { // may be a url
457 if (lookBack("url")) {
458 output.push(ch);
459 eatWhitespace();
460 if (next()) {
461 if (ch !== ')' && ch !== '"' && ch !== '\'') {
462 output.push(eatString(')'));
463 } else {
464 pos--;
465 }
466 }
467 } else {
468 parenLevel++;
469 print.preserveSingleSpace();
470 output.push(ch);
471 eatWhitespace();
472 }
473 } else if (ch === ')') {
474 output.push(ch);
475 parenLevel--;
476 } else if (ch === ',') {
477 output.push(ch);
478 if (!eatWhitespace(true) && selectorSeparatorNewline && !insidePropertyValue && parenLevel < 1) {
479 print.newLine();
480 } else {
481 print.singleSpace();
482 }
483 } else if ((ch === '>' || ch === '+' || ch === '~') &&
484 !insidePropertyValue && parenLevel < 1) {
485 //handle combinator spacing
486 if (space_around_combinator) {
487 print.singleSpace();
488 output.push(ch);
489 print.singleSpace();
490 } else {
491 output.push(ch);
492 eatWhitespace();
493 // squash extra whitespace
494 if (ch && whiteRe.test(ch)) {
495 ch = '';
496 }
497 }
498 } else if (ch === ']') {
499 output.push(ch);
500 } else if (ch === '[') {
501 print.preserveSingleSpace();
502 output.push(ch);
503 } else if (ch === '=') { // no whitespace before or after
504 eatWhitespace();
505 output.push('=');
506 if (whiteRe.test(ch)) {
507 ch = '';
508 }
509 } else {
510 print.preserveSingleSpace();
511 output.push(ch);
512 }
513 }
514  
515  
516 var sweetCode = '';
517 if (basebaseIndentString) {
518 sweetCode += basebaseIndentString;
519 }
520  
521 sweetCode += output.join('').replace(/[\r\n\t ]+$/, '');
522  
523 // establish end_with_newline
524 if (end_with_newline) {
525 sweetCode += '\n';
526 }
527  
528 if (eol !== '\n') {
529 sweetCode = sweetCode.replace(/[\n]/g, eol);
530 }
531  
532 return sweetCode;
533 }
534  
535 // https://developer.mozilla.org/en-US/docs/Web/CSS/At-rule
536 css_beautify.NESTED_AT_RULE = {
537 "@page": true,
538 "@font-face": true,
539 "@keyframes": true,
540 // also in CONDITIONAL_GROUP_RULE below
541 "@media": true,
542 "@supports": true,
543 "@document": true
544 };
545 css_beautify.CONDITIONAL_GROUP_RULE = {
546 "@media": true,
547 "@supports": true,
548 "@document": true
549 };
550  
551 /*global define */
552 if (typeof define === "function" && define.amd) {
553 // Add support for AMD ( https://github.com/amdjs/amdjs-api/wiki/AMD#defineamd-property- )
554 define([], function() {
555 return {
556 css_beautify: css_beautify
557 };
558 });
559 } else if (typeof exports !== "undefined") {
560 // Add support for CommonJS. Just put this file somewhere on your require.paths
561 // and you will be able to `var html_beautify = require("beautify").html_beautify`.
562 exports.css_beautify = css_beautify;
563 } else if (typeof window !== "undefined") {
564 // If we're running a web page and don't have either of the above, add our one global
565 window.css_beautify = css_beautify;
566 } else if (typeof global !== "undefined") {
567 // If we don't even have window, try global.
568 global.css_beautify = css_beautify;
569 }
570  
571 }());