123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- /**
- * Copyright 2013-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- */
- /*global exports:true*/
- 'use strict';
- var Syntax = require('esprima-fb').Syntax;
- var utils = require('../src/utils');
- function commaAfterLastParen(value) {
- var state = 'normal';
- var commaPos = 0;
- for (var i = 0; i < value.length; ++i) {
- if (state === 'normal') {
- if (value.substr(i, 2) === '//') {
- state = 'singleline';
- i += 1;
- } else if (value.substr(i, 2) === '/*') {
- state = 'multiline';
- i += 1;
- } else if (value.charAt(i).trim() !== '') {
- commaPos = i + 1;
- }
- } else if (state === 'singleline' && value.charAt(i) === '\n') {
- state = 'normal';
- } else if (state === 'multiline' &&
- value.charAt(i) === '*' &&
- i + 1 < value.length &&
- value.charAt(i + 1) === '/') {
- i += 1;
- state = 'normal';
- }
- }
- return value.substring(0, commaPos) + ', ' + trimLeft(value.substring(commaPos));
- }
- function renderJSXLiteral(object, isLast, state, start, end) {
- var lines = object.value.split(/\r\n|\n|\r/);
- if (start) {
- utils.append(start, state);
- }
- var lastNonEmptyLine = 0;
- lines.forEach(function(line, index) {
- if (line.match(/[^ \t]/)) {
- lastNonEmptyLine = index;
- }
- });
- lines.forEach(function(line, index) {
- var isFirstLine = index === 0;
- var isLastLine = index === lines.length - 1;
- var isLastNonEmptyLine = index === lastNonEmptyLine;
- // replace rendered whitespace tabs with spaces
- var trimmedLine = line.replace(/\t/g, ' ');
- // trim whitespace touching a newline
- if (!isFirstLine) {
- trimmedLine = trimmedLine.replace(/^[ ]+/, '');
- }
- if (!isLastLine) {
- trimmedLine = trimmedLine.replace(/[ ]+$/, '');
- }
- if (!isFirstLine) {
- utils.append(line.match(/^[ \t]*/)[0], state);
- }
- if (trimmedLine || isLastNonEmptyLine) {
- utils.append(
- JSON.stringify(trimmedLine) +
- (!isLastNonEmptyLine ? ' + " " +' : ''),
- state);
- if (isLastNonEmptyLine) {
- if (end) {
- utils.append(end, state);
- }
- if (!isLast) {
- utils.append(', ', state);
- }
- }
- // only restore tail whitespace if line had literals
- if (trimmedLine && !isLastLine) {
- utils.append(line.match(/[ \t]*$/)[0], state);
- }
- }
- if (!isLastLine) {
- utils.append('\n', state);
- }
- });
- utils.move(object.range[1], state);
- }
- function renderJSXExpressionContainer(traverse, object, isLast, path, state) {
- // Plus 1 to skip `{`.
- utils.move(object.range[0] + 1, state);
- utils.catchup(object.expression.range[0], state);
- traverse(object.expression, path, state);
- if (!isLast && object.expression.type !== Syntax.JSXEmptyExpression) {
- // If we need to append a comma, make sure to do so after the expression.
- utils.catchup(object.expression.range[1], state, trimLeft);
- utils.catchup(object.range[1] - 1, state, commaAfterLastParen);
- } else {
- // Minus 1 to skip `}`.
- utils.catchup(object.range[1] - 1, state, trimLeft);
- }
- utils.move(object.range[1], state);
- return false;
- }
- function quoteAttrName(attr) {
- // Quote invalid JS identifiers.
- if (!/^[a-z_$][a-z\d_$]*$/i.test(attr)) {
- return '"' + attr + '"';
- }
- return attr;
- }
- function trimLeft(value) {
- return value.replace(/^[ ]+/, '');
- }
- exports.renderJSXExpressionContainer = renderJSXExpressionContainer;
- exports.renderJSXLiteral = renderJSXLiteral;
- exports.quoteAttrName = quoteAttrName;
- exports.trimLeft = trimLeft;
|