/** * Copyright 2013-2014, 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('jstransform').Syntax; var utils = require('jstransform/src/utils'); var knownTags = { a: true, abbr: true, address: true, applet: true, area: true, article: true, aside: true, audio: true, b: true, base: true, bdi: true, bdo: true, big: true, blockquote: true, body: true, br: true, button: true, canvas: true, caption: true, circle: true, cite: true, code: true, col: true, colgroup: true, command: true, data: true, datalist: true, dd: true, defs: true, del: true, details: true, dfn: true, dialog: true, div: true, dl: true, dt: true, ellipse: true, em: true, embed: true, fieldset: true, figcaption: true, figure: true, footer: true, form: true, g: true, h1: true, h2: true, h3: true, h4: true, h5: true, h6: true, head: true, header: true, hgroup: true, hr: true, html: true, i: true, iframe: true, img: true, input: true, ins: true, kbd: true, keygen: true, label: true, legend: true, li: true, line: true, linearGradient: true, link: true, main: true, map: true, mark: true, marquee: true, mask: false, menu: true, menuitem: true, meta: true, meter: true, nav: true, noscript: true, object: true, ol: true, optgroup: true, option: true, output: true, p: true, param: true, path: true, pattern: false, picture: true, polygon: true, polyline: true, pre: true, progress: true, q: true, radialGradient: true, rect: true, rp: true, rt: true, ruby: true, s: true, samp: true, script: true, section: true, select: true, small: true, source: true, span: true, stop: true, strong: true, style: true, sub: true, summary: true, sup: true, svg: true, table: true, tbody: true, td: true, text: true, textarea: true, tfoot: true, th: true, thead: true, time: true, title: true, tr: true, track: true, tspan: true, u: true, ul: true, 'var': true, video: true, wbr: true }; function renderXJSLiteral(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 renderXJSExpressionContainer(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.XJSEmptyExpression) { // If we need to append a comma, make sure to do so after the expression. utils.catchup(object.expression.range[1], state, trimLeft); utils.append(', ', state); } // 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.knownTags = knownTags; exports.renderXJSExpressionContainer = renderXJSExpressionContainer; exports.renderXJSLiteral = renderXJSLiteral; exports.quoteAttrName = quoteAttrName; exports.trimLeft = trimLeft;