build/JSXTransformer.js in react-source-0.3.3 vs build/JSXTransformer.js in react-source-0.4.0
- old
+ new
@@ -1,721 +1,270 @@
/**
- * JSXTransformer v0.3.3
+ * JSXTransformer v0.4.0
*/
(function(e){if("function"==typeof bootstrap)bootstrap("jsxtransformer",e);else if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else if("undefined"!=typeof ses){if(!ses.ok())return;ses.makeJSXTransformer=e}else"undefined"!=typeof window?window.JSXTransformer=e():global.JSXTransformer=e()})(function(){var define,ses,bootstrap,module,exports;
return (function(e,t,n){function i(n,s){if(!t[n]){if(!e[n]){var o=typeof require=="function"&&require;if(!s&&o)return o(n,!0);if(r)return r(n,!0);throw new Error("Cannot find module '"+n+"'")}var u=t[n]={exports:{}};e[n][0].call(u.exports,function(t){var r=e[n][1][t];return i(r?r:t)},u,u.exports)}return t[n].exports}var r=typeof require=="function"&&require;for(var s=0;s<n.length;s++)i(n[s]);return i})({1:[function(require,module,exports){
-/**
- * Copyright 2013 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/* jshint browser: true */
-/* jslint evil: true */
+var Base62 = (function (my) {
+ my.chars = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
-'use strict';
-var runScripts;
-
-var transform = require('./fbtransform/lib/transform').transform;
-var visitors = require('./fbtransform/visitors').transformVisitors;
-var transform = transform.bind(null, visitors.react);
-var docblock = require('./fbtransform/lib/docblock');
-
-var headEl = document.getElementsByTagName('head')[0];
-
-exports.transform = transform;
-
-exports.exec = function(code) {
- return eval(transform(code));
-};
-
-var run = exports.run = function(code) {
- var jsx = docblock.parseAsObject(docblock.extract(code)).jsx;
-
- var functionBody = jsx ? transform(code).code : code;
- var scriptEl = document.createElement('script');
-
- scriptEl.innerHTML = functionBody;
- headEl.appendChild(scriptEl);
-};
-
-if (typeof window === "undefined" || window === null) {
- return;
-}
-
-var load = exports.load = function(url, callback) {
- var xhr;
- xhr = window.ActiveXObject ? new window.ActiveXObject('Microsoft.XMLHTTP')
- : new XMLHttpRequest();
- // Disable async since we need to execute scripts in the order they are in the
- // DOM to mirror normal script loading.
- xhr.open('GET', url, false);
- if ('overrideMimeType' in xhr) {
- xhr.overrideMimeType('text/plain');
- }
- xhr.onreadystatechange = function() {
- if (xhr.readyState === 4) {
- if (xhr.status === 0 || xhr.status === 200) {
- run(xhr.responseText);
- } else {
- throw new Error("Could not load " + url);
- }
- if (callback) {
- return callback();
- }
+ my.encode = function(i){
+ if (i === 0) {return '0'}
+ var s = ''
+ while (i > 0) {
+ s = this.chars[i % 62] + s
+ i = Math.floor(i/62)
}
+ return s
};
- return xhr.send(null);
-};
+ my.decode = function(a,b,c,d){
+ for (
+ b = c = (
+ a === (/\W|_|^$/.test(a += "") || a)
+ ) - 1;
+ d = a.charCodeAt(c++);
+ )
+ b = b * 62 + d - [, 48, 29, 87][d >> 5];
+ return b
+ };
-runScripts = function() {
- var scripts = document.getElementsByTagName('script');
- scripts = Array.prototype.slice.call(scripts);
- var jsxScripts = scripts.filter(function(script) {
- return script.type === 'text/jsx';
- });
+ return my;
+}({}));
- jsxScripts.forEach(function(script) {
- if (script.src) {
- load(script.src);
- } else {
- run(script.innerHTML);
+module.exports = Base62
+},{}],2:[function(require,module,exports){
+(function(process){function filter (xs, fn) {
+ var res = [];
+ for (var i = 0; i < xs.length; i++) {
+ if (fn(xs[i], i, xs)) res.push(xs[i]);
}
- });
-};
-
-if (window.addEventListener) {
- window.addEventListener('DOMContentLoaded', runScripts, false);
-} else {
- window.attachEvent('onload', runScripts);
+ return res;
}
-},{"./fbtransform/lib/transform":2,"./fbtransform/visitors":3,"./fbtransform/lib/docblock":4}],4:[function(require,module,exports){
-/**
- * Copyright 2013 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+// resolves . and .. elements in a path array with directory names there
+// must be no slashes, empty elements, or device names (c:\) in the array
+// (so also no leading and trailing slashes - it does not distinguish
+// relative and absolute paths)
+function normalizeArray(parts, allowAboveRoot) {
+ // if the path tries to go above the root, `up` ends up > 0
+ var up = 0;
+ for (var i = parts.length; i >= 0; i--) {
+ var last = parts[i];
+ if (last == '.') {
+ parts.splice(i, 1);
+ } else if (last === '..') {
+ parts.splice(i, 1);
+ up++;
+ } else if (up) {
+ parts.splice(i, 1);
+ up--;
+ }
+ }
-var docblockRe = /^\s*(\/\*\*(.|\n)*?\*\/)/;
-var ltrimRe = /^\s*/;
-/**
- * @param {String} contents
- * @return {String}
- */
-function extract(contents) {
- var match = contents.match(docblockRe);
- if (match) {
- return match[0].replace(ltrimRe, '') || '';
+ // if the path is allowed to go above the root, restore leading ..s
+ if (allowAboveRoot) {
+ for (; up--; up) {
+ parts.unshift('..');
+ }
}
- return '';
+
+ return parts;
}
+// Regex to split a filename into [*, dir, basename, ext]
+// posix version
+var splitPathRe = /^(.+\/(?!$)|\/)?((?:.+?)?(\.[^.]*)?)$/;
-var commentStartRe = /^\/\*\*?/;
-var commentEndRe = /\*\/$/;
-var wsRe = /[\t ]+/g;
-var stringStartRe = /(\n|^) *\*/g;
-var multilineRe = /(?:^|\n) *(@[^\n]*?) *\n *([^@\n\s][^@\n]+?) *\n/g;
-var propertyRe = /(?:^|\n) *@(\S+) *([^\n]*)/g;
+// path.resolve([from ...], to)
+// posix version
+exports.resolve = function() {
+var resolvedPath = '',
+ resolvedAbsolute = false;
-/**
- * @param {String} contents
- * @return {Array}
- */
-function parse(docblock) {
- docblock = docblock
- .replace(commentStartRe, '')
- .replace(commentEndRe, '')
- .replace(wsRe, ' ')
- .replace(stringStartRe, '$1');
+for (var i = arguments.length; i >= -1 && !resolvedAbsolute; i--) {
+ var path = (i >= 0)
+ ? arguments[i]
+ : process.cwd();
- // Normalize multi-line directives
- var prev = '';
- while (prev != docblock) {
- prev = docblock;
- docblock = docblock.replace(multilineRe, "\n$1 $2\n");
+ // Skip empty and invalid entries
+ if (typeof path !== 'string' || !path) {
+ continue;
}
- docblock = docblock.trim();
- var result = [];
- var match;
- while (match = propertyRe.exec(docblock)) {
- result.push([match[1], match[2]]);
- }
-
- return result;
+ resolvedPath = path + '/' + resolvedPath;
+ resolvedAbsolute = path.charAt(0) === '/';
}
-/**
- * Same as parse but returns an object of prop: value instead of array of paris
- * If a property appers more than once the last one will be returned
- *
- * @param {String} contents
- * @return {Object}
- */
-function parseAsObject(docblock) {
- var pairs = parse(docblock);
- var result = {};
- for (var i = 0; i < pairs.length; i++) {
- result[pairs[i][0]] = pairs[i][1];
- }
- return result;
-}
+// At this point the path should be resolved to a full absolute path, but
+// handle relative paths to be safe (might happen when process.cwd() fails)
+// Normalize the path
+resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
+ return !!p;
+ }), !resolvedAbsolute).join('/');
-exports.extract = extract;
-exports.parse = parse;
-exports.parseAsObject = parseAsObject;
-
-},{}],3:[function(require,module,exports){
-(function(){/*global exports:true*/
-var classes = require('./transforms/classes');
-var react = require('./transforms/react');
-var reactDisplayName = require('./transforms/reactDisplayName');
-
-/**
- * Map from transformName => orderedListOfVisitors.
- */
-var transformVisitors = {
- 'es6-classes': [
- classes.visitClassExpression,
- classes.visitClassDeclaration,
- classes.visitSuperCall,
- classes.visitPrivateProperty
- ]
+ return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
};
-transformVisitors.react = transformVisitors[
- "es6-classes"
-].concat([
- react.visitReactTag,
- reactDisplayName.visitReactDisplayName
-]);
+// path.normalize(path)
+// posix version
+exports.normalize = function(path) {
+var isAbsolute = path.charAt(0) === '/',
+ trailingSlash = path.slice(-1) === '/';
-/**
- * Specifies the order in which each transform should run.
- */
-var transformRunOrder = [
- 'es6-classes',
- 'react'
-];
+// Normalize the path
+path = normalizeArray(filter(path.split('/'), function(p) {
+ return !!p;
+ }), !isAbsolute).join('/');
-/**
- * Given a list of transform names, return the ordered list of visitors to be
- * passed to the transform() function.
- *
- * @param {array?} excludes
- * @return {array}
- */
-function getVisitorsList(excludes) {
- var ret = [];
- for (var i = 0, il = transformRunOrder.length; i < il; i++) {
- if (!excludes || excludes.indexOf(transformRunOrder[i]) === -1) {
- ret = ret.concat(transformVisitors[transformRunOrder[i]]);
- }
+ if (!path && !isAbsolute) {
+ path = '.';
}
- return ret;
-}
+ if (path && trailingSlash) {
+ path += '/';
+ }
+
+ return (isAbsolute ? '/' : '') + path;
+};
-exports.getVisitorsList = getVisitorsList;
-exports.transformVisitors = transformVisitors;
-})()
-},{"./transforms/classes":5,"./transforms/react":6,"./transforms/reactDisplayName":7}],8:[function(require,module,exports){
-(function(){/**
- * Copyright 2013 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*global exports:true*/
+// posix version
+exports.join = function() {
+ var paths = Array.prototype.slice.call(arguments, 0);
+ return exports.normalize(filter(paths, function(p, index) {
+ return p && typeof p === 'string';
+ }).join('/'));
+};
-/**
- * State represents the given parser state. It has a local and global parts.
- * Global contains parser position, source, etc. Local contains scope based
- * properties, like current class name. State should contain all the info
- * required for transformation. It's the only mandatory object that is being
- * passed to every function in transform chain.
- *
- * @param {String} source
- * @param {Object} transformOptions
- * @return {Object}
- */
-function createState(source, transformOptions) {
- return {
- /**
- * Name of the super class variable
- * @type {String}
- */
- superVar: '',
- /**
- * Name of the enclosing class scope
- * @type {String}
- */
- scopeName: '',
- /**
- * Global state (not affected by updateState)
- * @type {Object}
- */
- g: {
- /**
- * A set of general options that transformations can consider while doing
- * a transformation:
- *
- * - minify
- * Specifies that transformation steps should do their best to minify
- * the output source when possible. This is useful for places where
- * minification optimizations are possible with higher-level context
- * info than what jsxmin can provide.
- *
- * For example, the ES6 class transform will minify munged private
- * variables if this flag is set.
- */
- opts: transformOptions,
- /**
- * Current position in the source code
- * @type {Number}
- */
- position: 0,
- /**
- * Buffer containing the result
- * @type {String}
- */
- buffer: '',
- /**
- * Indentation offset (only negative offset is supported now)
- * @type {Number}
- */
- indentBy: 0,
- /**
- * Source that is being transformed
- * @type {String}
- */
- source: source,
- /**
- * Cached parsed docblock (see getDocblock)
- * @type {object}
- */
- docblock: null,
+exports.dirname = function(path) {
+ var dir = splitPathRe.exec(path)[1] || '';
+ var isWindows = false;
+ if (!dir) {
+ // No dirname
+ return '.';
+ } else if (dir.length === 1 ||
+ (isWindows && dir.length <= 3 && dir.charAt(1) === ':')) {
+ // It is just a slash or a drive letter with a slash
+ return dir;
+ } else {
+ // It is a full dirname, strip trailing slash
+ return dir.substring(0, dir.length - 1);
+ }
+};
- /**
- * Whether the thing was used
- * @type {Boolean}
- */
- tagNamespaceUsed: false,
- /**
- * If using bolt xjs transformation
- * @type {Boolean}
- */
- isBolt: undefined,
-
- /**
- * Whether to record source map (expensive) or not
- * @type {SourceMapGenerator|null}
- */
- sourceMap: null,
-
- /**
- * Filename of the file being processed. Will be returned as a source
- * attribute in the source map
- */
- sourceMapFilename: 'source.js',
-
- /**
- * Only when source map is used: last line in the source for which
- * source map was generated
- * @type {Number}
- */
- sourceLine: 1,
-
- /**
- * Only when source map is used: last line in the buffer for which
- * source map was generated
- * @type {Number}
- */
- bufferLine: 1,
-
- /**
- * The top-level Program AST for the original file.
- */
- originalProgramAST: null,
-
- sourceColumn: 0,
- bufferColumn: 0
- }
- };
-}
-
-/**
- * Updates a copy of a given state with "update" and returns an updated state.
- *
- * @param {Object} state
- * @param {Object} update
- * @return {Object}
- */
-function updateState(state, update) {
- return {
- g: state.g,
- superVar: update.superVar || state.superVar,
- scopeName: update.scopeName || state.scopeName
- };
-}
-
-/**
- * Given a state fill the resulting buffer from the original source up to
- * the end
- * @param {Number} end
- * @param {Object} state
- * @param {Function?} contentTransformer Optional callback to transform newly
- * added content.
- */
-function catchup(end, state, contentTransformer) {
- if (end < state.g.position) {
- // cannot move backwards
- return;
+exports.basename = function(path, ext) {
+ var f = splitPathRe.exec(path)[2] || '';
+ // TODO: make this comparison case-insensitive on windows?
+ if (ext && f.substr(-1 * ext.length) === ext) {
+ f = f.substr(0, f.length - ext.length);
}
- var source = state.g.source.substring(state.g.position, end);
- var transformed = updateIndent(source, state);
- if (state.g.sourceMap && transformed) {
- // record where we are
- state.g.sourceMap.addMapping({
- generated: { line: state.g.bufferLine, column: state.g.bufferColumn },
- original: { line: state.g.sourceLine, column: state.g.sourceColumn },
- source: state.g.sourceMapFilename
- });
+ return f;
+};
- // record line breaks in transformed source
- var sourceLines = source.split('\n');
- var transformedLines = transformed.split('\n');
- // Add line break mappings between last known mapping and the end of the
- // added piece. So for the code piece
- // (foo, bar);
- // > var x = 2;
- // > var b = 3;
- // var c =
- // only add lines marked with ">": 2, 3.
- for (var i = 1; i < sourceLines.length - 1; i++) {
- state.g.sourceMap.addMapping({
- generated: { line: state.g.bufferLine, column: 0 },
- original: { line: state.g.sourceLine, column: 0 },
- source: state.g.sourceMapFilename
- });
- state.g.sourceLine++;
- state.g.bufferLine++;
- }
- // offset for the last piece
- if (sourceLines.length > 1) {
- state.g.sourceLine++;
- state.g.bufferLine++;
- state.g.sourceColumn = 0;
- state.g.bufferColumn = 0;
- }
- state.g.sourceColumn += sourceLines[sourceLines.length - 1].length;
- state.g.bufferColumn +=
- transformedLines[transformedLines.length - 1].length;
- }
- state.g.buffer +=
- contentTransformer ? contentTransformer(transformed) : transformed;
- state.g.position = end;
-}
-/**
- * Applies `catchup` but passing in a function that removes any non-whitespace
- * characters.
- */
-var re = /(\S)/g;
-function stripNonWhite(value) {
- return value.replace(re, function() {
- return '';
- });
-}
-/**
- * Catches up as `catchup` but turns each non-white character into a space.
- */
-function catchupWhiteSpace(end, state) {
- catchup(end, state, stripNonWhite);
-}
+exports.extname = function(path) {
+ return splitPathRe.exec(path)[3] || '';
+};
-/**
- * Same as catchup but does not touch the buffer
- * @param {Number} end
- * @param {Object} state
- */
-function move(end, state) {
- // move the internal cursors
- if (state.g.sourceMap) {
- if (end < state.g.position) {
- state.g.position = 0;
- state.g.sourceLine = 1;
- state.g.sourceColumn = 0;
- }
+exports.relative = function(from, to) {
+ from = exports.resolve(from).substr(1);
+ to = exports.resolve(to).substr(1);
- var source = state.g.source.substring(state.g.position, end);
- var sourceLines = source.split('\n');
- if (sourceLines.length > 1) {
- state.g.sourceLine += sourceLines.length - 1;
- state.g.sourceColumn = 0;
+ function trim(arr) {
+ var start = 0;
+ for (; start < arr.length; start++) {
+ if (arr[start] !== '') break;
}
- state.g.sourceColumn += sourceLines[sourceLines.length - 1].length;
- }
- state.g.position = end;
-}
-/**
- * Appends a string of text to the buffer
- * @param {String} string
- * @param {Object} state
- */
-function append(string, state) {
- if (state.g.sourceMap && string) {
- state.g.sourceMap.addMapping({
- generated: { line: state.g.bufferLine, column: state.g.bufferColumn },
- original: { line: state.g.sourceLine, column: state.g.sourceColumn },
- source: state.g.sourceMapFilename
- });
- var transformedLines = string.split('\n');
- if (transformedLines.length > 1) {
- state.g.bufferLine += transformedLines.length - 1;
- state.g.bufferColumn = 0;
+ var end = arr.length - 1;
+ for (; end >= 0; end--) {
+ if (arr[end] !== '') break;
}
- state.g.bufferColumn +=
- transformedLines[transformedLines.length - 1].length;
- }
- state.g.buffer += string;
-}
-/**
- * Update indent using state.indentBy property. Indent is measured in
- * double spaces. Updates a single line only.
- *
- * @param {String} str
- * @param {Object} state
- * @return {String}
- */
-function updateIndent(str, state) {
- for (var i = 0; i < -state.g.indentBy; i++) {
- str = str.replace(/(^|\n)( {2}|\t)/g, '$1');
+ if (start > end) return [];
+ return arr.slice(start, end - start + 1);
}
- return str;
-}
-/**
- * Calculates indent from the beginning of the line until "start" or the first
- * character before start.
- * @example
- * " foo.bar()"
- * ^
- * start
- * indent will be 2
- *
- * @param {Number} start
- * @param {Object} state
- * @return {Number}
- */
-function indentBefore(start, state) {
- var end = start;
- start = start - 1;
+ var fromParts = trim(from.split('/'));
+ var toParts = trim(to.split('/'));
- while (start > 0 && state.g.source[start] != '\n') {
- if (!state.g.source[start].match(/[ \t]/)) {
- end = start;
+ var length = Math.min(fromParts.length, toParts.length);
+ var samePartsLength = length;
+ for (var i = 0; i < length; i++) {
+ if (fromParts[i] !== toParts[i]) {
+ samePartsLength = i;
+ break;
}
- start--;
}
- return state.g.source.substring(start + 1, end);
-}
-function getDocblock(state) {
- if (!state.g.docblock) {
- var docblock = require('./docblock');
- state.g.docblock =
- docblock.parseAsObject(docblock.extract(state.g.source));
+ var outputParts = [];
+ for (var i = samePartsLength; i < fromParts.length; i++) {
+ outputParts.push('..');
}
- return state.g.docblock;
-}
-exports.catchup = catchup;
-exports.catchupWhiteSpace = catchupWhiteSpace;
-exports.append = append;
-exports.move = move;
-exports.updateIndent = updateIndent;
-exports.indentBefore = indentBefore;
-exports.updateState = updateState;
-exports.createState = createState;
-exports.getDocblock = getDocblock;
+ outputParts = outputParts.concat(toParts.slice(samePartsLength));
-})()
-},{"./docblock":4}],2:[function(require,module,exports){
-(function(){/**
- * Copyright 2013 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*global exports:true*/
-/*jslint node: true*/
-"use strict";
+ return outputParts.join('/');
+};
-/**
- * Syntax transfomer for javascript. Takes the source in, spits the source
- * out. Tries to maintain readability and preserve whitespace and line numbers
- * where posssible.
- *
- * Support
- * - ES6 class transformation + private property munging, see ./classes.js
- * - React XHP style syntax transformations, see ./react.js
- * - Bolt XHP style syntax transformations, see ./bolt.js
- *
- * The general flow is the following:
- * - Parse the source with our customized esprima-parser
- * https://github.com/voloko/esprima. We have to customize the parser to
- * support non-standard XHP-style syntax. We parse the source range: true
- * option that forces esprima to return positions in the source within
- * resulting parse tree.
- *
- * - Traverse resulting syntax tree, trying to apply a set of visitors to each
- * node. Each visitor should provide a .test() function that tests if the
- * visitor can process a given node.
- *
- * - Visitor is responsible for code generation for a given syntax node.
- * Generated code is stored in state.g.buffer that is passed to every
- * visitor. It's up to the visitor to process the code the way it sees fit.
- * All of the current visitors however use both the node and the original
- * source to generate transformed code. They use nodes to generate new
- * code and they copy the original source, preserving whitespace and comments,
- * for the parts they don't care about.
- */
-var esprima = require('esprima');
+})(require("__browserify_process"))
+},{"__browserify_process":3}],3:[function(require,module,exports){
+// shim for using process in browser
-var createState = require('./utils').createState;
-var catchup = require('./utils').catchup;
+var process = module.exports = {};
-/**
- * @param {object} object
- * @param {function} visitor
- * @param {array} path
- * @param {object} state
- */
-function traverse(object, path, state) {
- var key, child;
+process.nextTick = (function () {
+ var canSetImmediate = typeof window !== 'undefined'
+ && window.setImmediate;
+ var canPost = typeof window !== 'undefined'
+ && window.postMessage && window.addEventListener
+ ;
- if (walker(traverse, object, path, state) === false) {
- return;
- }
- path.unshift(object);
- for (key in object) {
- // skip obviously wrong attributes
- if (key === 'range' || key === 'loc') {
- continue;
+ if (canSetImmediate) {
+ return function (f) { return window.setImmediate(f) };
}
- if (object.hasOwnProperty(key)) {
- child = object[key];
- if (typeof child === 'object' && child !== null) {
- child.range && catchup(child.range[0], state);
- traverse(child, path, state);
- child.range && catchup(child.range[1], state);
- }
- }
- }
- path.shift();
-}
-function walker(traverse, object, path, state) {
- var visitors = state.g.visitors;
- for (var i = 0; i < visitors.length; i++) {
- if (visitors[i].test(object, path, state)) {
- return visitors[i](traverse, object, path, state);
+ if (canPost) {
+ var queue = [];
+ window.addEventListener('message', function (ev) {
+ if (ev.source === window && ev.data === 'process-tick') {
+ ev.stopPropagation();
+ if (queue.length > 0) {
+ var fn = queue.shift();
+ fn();
+ }
+ }
+ }, true);
+
+ return function nextTick(fn) {
+ queue.push(fn);
+ window.postMessage('process-tick', '*');
+ };
}
- }
-}
-function runPass(source, visitors, options) {
- var ast = esprima.parse(source, { comment: true, loc: true, range: true });
- var state = createState(source, options);
- state.g.originalProgramAST = ast;
- state.g.visitors = visitors;
+ return function nextTick(fn) {
+ setTimeout(fn, 0);
+ };
+})();
- if (options.sourceMap) {
- var SourceMapGenerator = require('source-map').SourceMapGenerator;
- state.g.sourceMap = new SourceMapGenerator({ file: 'transformed.js' });
- }
- traverse(ast, [], state);
- catchup(source.length, state);
- return state;
-}
+process.title = 'browser';
+process.browser = true;
+process.env = {};
+process.argv = [];
-/**
- * Applies all available transformations to the source
- * @param {array} visitors
- * @param {string} source
- * @param {?object} options
- * @return {object}
- */
-function transform(visitors, source, options) {
- options = options || {};
-
- var state = runPass(source, visitors, options);
- var sourceMap = state.g.sourceMap;
-
- if (sourceMap) {
- return {
- sourceMap: sourceMap,
- sourceMapFilename: options.filename || 'source.js',
- code: state.g.buffer
- };
- } else {
- return {
- code: state.g.buffer
- };
- }
+process.binding = function (name) {
+ throw new Error('process.binding is not supported');
}
+// TODO(shtylman)
+process.cwd = function () { return '/' };
+process.chdir = function (dir) {
+ throw new Error('process.chdir is not supported');
+};
-exports.transform = transform;
-
-})()
-},{"./utils":8,"esprima":9,"source-map":10}],9:[function(require,module,exports){
+},{}],4:[function(require,module,exports){
(function(){/*
Copyright (C) 2013 Thaddee Tyl <thaddee.tyl@gmail.com>
Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
Copyright (C) 2012 Mathias Bynens <mathias@qiwi.be>
Copyright (C) 2012 Joost-Wim Boekesteijn <joost-wim@boekesteijn.nl>
@@ -757,11 +306,11 @@
parseLeftHandSideExpression: true, parseParams: true, validateParam: true,
parseSpreadOrAssignmentExpression: true,
parseStatement: true, parseSourceElement: true, parseModuleBlock: true, parseConciseBody: true,
advanceXJSChild: true, isXJSIdentifierStart: true, isXJSIdentifierPart: true,
scanXJSStringLiteral: true, scanXJSIdentifier: true,
-parseXJSAttributeValue: true, parseXJSChild: true, parseXJSElement: true, parseXJSExpression: true,
+parseXJSAttributeValue: true, parseXJSChild: true, parseXJSElement: true, parseXJSExpressionContainer: true, parseXJSEmptyExpression: true,
parseYieldExpression: true
*/
(function (root, factory) {
'use strict';
@@ -901,11 +450,12 @@
VariableDeclaration: 'VariableDeclaration',
VariableDeclarator: 'VariableDeclarator',
WhileStatement: 'WhileStatement',
WithStatement: 'WithStatement',
XJSIdentifier: 'XJSIdentifier',
- XJSExpression: 'XJSExpression',
+ XJSEmptyExpression: 'XJSEmptyExpression',
+ XJSExpressionContainer: 'XJSExpressionContainer',
XJSElement: 'XJSElement',
XJSClosingElement: 'XJSClosingElement',
XJSOpeningElement: 'XJSOpeningElement',
XJSAttribute: 'XJSAttribute',
XJSText: 'XJSText',
@@ -2454,17 +2004,23 @@
attributes: openingElement.attributes,
children: children
};
},
- createXJSExpression: function (expression) {
+ createXJSEmptyExpression: function () {
return {
- type: Syntax.XJSExpression,
- value: expression
+ type: Syntax.XJSEmptyExpression
};
},
+ createXJSExpressionContainer: function (expression) {
+ return {
+ type: Syntax.XJSExpressionContainer,
+ expression: expression
+ };
+ },
+
createXJSOpeningElement: function (name, attributes, selfClosing) {
return {
type: Syntax.XJSOpeningElement,
name: name,
selfClosing: selfClosing,
@@ -5958,38 +5514,56 @@
return delegate.createXJSIdentifier(token.value, token.namespace);
}
function parseXJSAttributeValue() {
var value;
- if (lookahead.value === '{') {
- value = parseXJSExpression();
+ if (match('{')) {
+ value = parseXJSExpressionContainer();
+ if (value.expression.type === Syntax.XJSEmptyExpression) {
+ throwError(
+ value,
+ 'XJS attributes must only be assigned a non-empty ' +
+ 'expression'
+ );
+ }
} else if (lookahead.type === Token.XJSText) {
value = delegate.createLiteral(lex());
} else {
throwError({}, Messages.InvalidXJSAttributeValue);
}
return value;
}
- function parseXJSExpression() {
- var value, origInXJSChild, origInXJSTag;
+ function parseXJSEmptyExpression() {
+ while (source.charAt(index) !== '}') {
+ index++;
+ }
+ return delegate.createXJSEmptyExpression();
+ }
+ function parseXJSExpressionContainer() {
+ var expression, origInXJSChild, origInXJSTag;
+
origInXJSChild = state.inXJSChild;
origInXJSTag = state.inXJSTag;
state.inXJSChild = false;
state.inXJSTag = false;
expect('{');
- value = parseExpression();
+ if (match('}')) {
+ expression = parseXJSEmptyExpression();
+ } else {
+ expression = parseExpression();
+ }
state.inXJSChild = origInXJSChild;
state.inXJSTag = origInXJSTag;
expect('}');
- return delegate.createXJSExpression(value);
+ return delegate.createXJSExpressionContainer(expression);
}
function parseXJSAttribute() {
var token, name, value;
@@ -6004,12 +5578,12 @@
return delegate.createXJSAttribute(name);
}
function parseXJSChild() {
var token;
- if (lookahead.value === '{') {
- token = parseXJSExpression();
+ if (match('{')) {
+ token = parseXJSExpressionContainer();
} else if (lookahead.type === Token.XJSText) {
token = delegate.createLiteral(lex());
} else {
state.inXJSChild = false;
token = parseXJSElement();
@@ -6491,11 +6065,12 @@
extra.parseClassBody = parseClassBody;
extra.parseXJSIdentifier = parseXJSIdentifier;
extra.parseXJSChild = parseXJSChild;
extra.parseXJSAttribute = parseXJSAttribute;
extra.parseXJSAttributeValue = parseXJSAttributeValue;
- extra.parseXJSExpression = parseXJSExpression;
+ extra.parseXJSExpressionContainer = parseXJSExpressionContainer;
+ extra.parseXJSEmptyExpression = parseXJSEmptyExpression;
extra.parseXJSElement = parseXJSElement;
extra.parseXJSClosingElement = parseXJSClosingElement;
extra.parseXJSOpeningElement = parseXJSOpeningElement;
parseAssignmentExpression = wrapTracking(extra.parseAssignmentExpression);
@@ -6543,11 +6118,12 @@
parseClassBody = wrapTracking(extra.parseClassBody);
parseXJSIdentifier = wrapTracking(extra.parseXJSIdentifier);
parseXJSChild = wrapTrackingPreserveWhitespace(extra.parseXJSChild);
parseXJSAttribute = wrapTracking(extra.parseXJSAttribute);
parseXJSAttributeValue = wrapTracking(extra.parseXJSAttributeValue);
- parseXJSExpression = wrapTracking(extra.parseXJSExpression);
+ parseXJSExpressionContainer = wrapTracking(extra.parseXJSExpressionContainer);
+ parseXJSEmptyExpression = wrapTrackingPreserveWhitespace(extra.parseXJSEmptyExpression);
parseXJSElement = wrapTracking(extra.parseXJSElement);
parseXJSClosingElement = wrapTracking(extra.parseXJSClosingElement);
parseXJSOpeningElement = wrapTracking(extra.parseXJSOpeningElement);
}
@@ -6612,11 +6188,12 @@
parseClassBody = extra.parseClassBody;
parseXJSIdentifier = extra.parseXJSIdentifier;
parseXJSChild = extra.parseXJSChild;
parseXJSAttribute = extra.parseXJSAttribute;
parseXJSAttributeValue = extra.parseXJSAttributeValue;
- parseXJSExpression = extra.parseXJSExpression;
+ parseXJSExpressionContainer = extra.parseXJSExpressionContainer;
+ parseXJSEmptyExpression = extra.parseXJSEmptyExpression;
parseXJSElement = extra.parseXJSElement;
parseXJSClosingElement = extra.parseXJSClosingElement;
parseXJSOpeningElement = extra.parseXJSOpeningElement;
}
@@ -6867,1489 +6444,400 @@
}));
/* vim: set sw=4 ts=4 et tw=80 : */
})()
-},{}],11:[function(require,module,exports){
-(function(){/**
- * Copyright 2013 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*global exports:true*/
-"use strict";
-var catchup = require('../lib/utils').catchup;
-var append = require('../lib/utils').append;
-var move = require('../lib/utils').move;
-
-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,
- blockquote: true,
- body: true,
- br: true,
- button: true,
- canvas: true,
- circle: true,
- ellipse: true,
- caption: true,
- cite: true,
- code: true,
- col: true,
- colgroup: true,
- command: true,
- data: true,
- datalist: true,
- dd: true,
- del: true,
- details: true,
- dfn: true,
- dialog: true,
- div: true,
- dl: true,
- dt: 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,
- link: true,
- map: true,
- mark: true,
- marquee: true,
- menu: true,
- meta: true,
- meter: true,
- nav: true,
- noscript: true,
- object: true,
- ol: true,
- optgroup: true,
- option: true,
- output: true,
- p: true,
- path: true,
- param: true,
- pre: true,
- progress: true,
- q: 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,
- 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,
- u: true,
- ul: true,
- 'var': true,
- video: true,
- wbr: true
-};
-
-function safeTrim(string) {
- return string.replace(/^[ \t]+/, '').replace(/[ \t]+$/, '');
-}
-
-// Replace all trailing whitespace characters with a single space character
-function trimWithSingleSpace(string) {
- return string.replace(/^[ \t\xA0]{2,}/, ' ').
- replace(/[ \t\xA0]{2,}$/, ' ').replace(/^\s+$/, '');
-}
-
-/**
- * Special handling for multiline string literals
- * print lines:
- *
- * line
- * line
- *
- * as:
- *
- * "line "+
- * "line"
- */
-function renderXJSLiteral(object, isLast, state, start, end) {
- /** Added blank check filtering and triming*/
- var trimmedChildValue = safeTrim(object.value);
-
- if (trimmedChildValue) {
- // head whitespace
- append(object.value.match(/^[\t ]*/)[0], state);
- if (start) {
- append(start, state);
- }
-
- var trimmedChildValueWithSpace = trimWithSingleSpace(object.value);
-
- /**
- */
- var initialLines = trimmedChildValue.split(/\r\n|\n|\r/);
-
- var lines = initialLines.filter(function(line) {
- return safeTrim(line).length > 0;
- });
-
- var hasInitialNewLine = initialLines[0] !== lines[0];
- var hasFinalNewLine =
- initialLines[initialLines.length - 1] !== lines[lines.length - 1];
-
- var numLines = lines.length;
- lines.forEach(function (line, ii) {
- var lastLine = ii === numLines - 1;
- var trimmedLine = safeTrim(line);
- if (trimmedLine === '' && !lastLine) {
- append(line, state);
- } else {
- var preString = '';
- var postString = '';
- var leading = '';
-
- if (ii === 0) {
- if (hasInitialNewLine) {
- preString = ' ';
- leading = '\n';
- }
- if (trimmedChildValueWithSpace.substring(0, 1) === ' ') {
- // If this is the first line, and the original content starts with
- // whitespace, place a single space at the beginning.
- preString = ' ';
- }
- } else {
- leading = line.match(/^[ \t]*/)[0];
- }
- if (!lastLine || trimmedChildValueWithSpace.substr(
- trimmedChildValueWithSpace.length - 1, 1) === ' ' ||
- hasFinalNewLine
- ) {
- // If either not on the last line, or the original content ends with
- // whitespace, place a single character at the end.
- postString = ' ';
- }
-
- append(
- leading +
- JSON.stringify(
- preString + trimmedLine + postString
- ) +
- (lastLine ? '' : '+') +
- line.match(/[ \t]*$/)[0],
- state);
- }
- if (!lastLine) {
- append('\n', state);
- }
- });
- } else {
- if (start) {
- append(start, state);
- }
- append('""', state);
- }
- if (end) {
- append(end, state);
- }
-
- // add comma before trailing whitespace
- if (!isLast) {
- append(',', state);
- }
-
- // tail whitespace
- append(object.value.match(/[ \t]*$/)[0], state);
- move(object.range[1], state);
-}
-
-function renderXJSExpression(traverse, object, isLast, path, state) {
- // Plus 1 to skip `{`.
- move(object.range[0] + 1, state);
- traverse(object.value, path, state);
- if (!isLast) {
- // If we need to append a comma, make sure to do so after the expression.
- catchup(object.value.range[1], state);
- append(',', state);
- }
- // Minus 1 to skip `}`.
- catchup(object.range[1] - 1, state);
- 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;
-}
-
-exports.knownTags = knownTags;
-exports.renderXJSExpression = renderXJSExpression;
-exports.renderXJSLiteral = renderXJSLiteral;
-exports.quoteAttrName = quoteAttrName;
-
-})()
-},{"../lib/utils":8}],10:[function(require,module,exports){
+},{}],5:[function(require,module,exports){
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
exports.SourceMapGenerator = require('./source-map/source-map-generator').SourceMapGenerator;
exports.SourceMapConsumer = require('./source-map/source-map-consumer').SourceMapConsumer;
exports.SourceNode = require('./source-map/source-node').SourceNode;
-},{"./source-map/source-map-generator":12,"./source-map/source-map-consumer":13,"./source-map/source-node":14}],5:[function(require,module,exports){
-(function(){/**
- * Copyright 2013 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+},{"./source-map/source-map-consumer":10,"./source-map/source-map-generator":11,"./source-map/source-node":12}],6:[function(require,module,exports){
+/* -*- Mode: js; js-indent-level: 2; -*- */
+/*
+ * Copyright 2011 Mozilla Foundation and contributors
+ * Licensed under the New BSD license. See LICENSE or:
+ * http://opensource.org/licenses/BSD-3-Clause
*/
-/*global exports:true*/
-"use strict";
+if (typeof define !== 'function') {
+ var define = require('amdefine')(module, require);
+}
+define(function (require, exports, module) {
-/**
- * Desugarizer for ES6 minimal class proposal. See
- * http://wiki.ecmascript.org/doku.php?id=harmony:proposals
- *
- * Does not require any runtime. Preserves whitespace and comments.
- * Supports a class declaration with methods, super calls and inheritance.
- * Currently does not support for getters and setters, since there's a very
- * low probability we're going to use them anytime soon.
- *
- * Additional features:
- * - Any member with private name (the name with prefix _, such _name) inside
- * the class's scope will be munged. This would will to eliminate the case
- * of sub-class accidentally overriding the super-class's provate properties
- * also discouage people from accessing private members that they should not
- * access. However, quoted property names don't get munged.
- *
- * class SkinnedMesh extends require('THREE').Mesh {
- *
- * update(camera) {
- * camera.code = 'iphone'
- * super.update(camera);
- * }
- *
- * /
- * * @constructor
- * /
- * constructor(geometry, materials) {
- * super(geometry, materials);
- *
- * super.update(1);
- *
- * this.identityMatrix = new THREE.Matrix4();
- * this.bones = [];
- * this.boneMatrices = [];
- * this._name = 'foo';
- * }
- *
- * /
- * * some other code
- * /
- * readMore() {
- *
- * }
- *
- * _doSomething() {
- *
- * }
- * }
- *
- * should be converted to
- *
- * var SkinnedMesh = (function() {
- * var __super = require('parent').Mesh;
- *
- * /
- * * @constructor
- * /
- * function SkinnedMesh(geometry, materials) {
- * __super.call(this, geometry, materials);
- *
- * __super.prototype.update.call(this, 1);
- *
- * this.identityMatrix = new THREE.Matrix4();
- * this.bones = [];
- * this.boneMatrices = [];
- * this.$SkinnedMesh_name = 'foo';
- * }
- * SkinnedMesh.prototype = Object.create(__super.prototype);
- * SkinnedMesh.prototype.constructor = SkinnedMesh;
- *
- * /
- * * @param camera
- * /
- * SkinnedMesh.prototype.update = function(camera) {
- * camera.code = 'iphone'
- * __super.prototype.update.call(this, camera);
- * };
- *
- * SkinnedMesh.prototype.readMore = function() {
- *
- * };
- *
- * SkinnedMesh.prototype.$SkinnedMesh_doSomething = function() {
- *
- * };
- *
- * return SkinnedMesh;
- * })();
- *
- */
-var Syntax = require('esprima').Syntax;
-var base62 = require('base62');
+ var util = require('./util');
-var catchup = require('../lib/utils').catchup;
-var append = require('../lib/utils').append;
-var move = require('../lib/utils').move;
-var indentBefore = require('../lib/utils').indentBefore;
-var updateIndent = require('../lib/utils').updateIndent;
-var updateState = require('../lib/utils').updateState;
-
-function findConstructorIndex(object) {
- var classElements = object.body && object.body.body || [];
- for (var i = 0; i < classElements.length; i++) {
- if (classElements[i].type === Syntax.MethodDefinition &&
- classElements[i].key.name === 'constructor') {
- return i;
- }
+ /**
+ * A data structure which is a combination of an array and a set. Adding a new
+ * member is O(1), testing for membership is O(1), and finding the index of an
+ * element is O(1). Removing elements from the set is not supported. Only
+ * strings are supported for membership.
+ */
+ function ArraySet() {
+ this._array = [];
+ this._set = {};
}
- return -1;
-}
-var _mungedSymbolMaps = {};
-function getMungedName(scopeName, name, minify) {
- if (minify) {
- if (!_mungedSymbolMaps[scopeName]) {
- _mungedSymbolMaps[scopeName] = {
- symbolMap: {},
- identifierUUIDCounter: 0
- };
+ /**
+ * Static method for creating ArraySet instances from an existing array.
+ */
+ ArraySet.fromArray = function ArraySet_fromArray(aArray) {
+ var set = new ArraySet();
+ for (var i = 0, len = aArray.length; i < len; i++) {
+ set.add(aArray[i]);
}
+ return set;
+ };
- var symbolMap = _mungedSymbolMaps[scopeName].symbolMap;
- if (!symbolMap[name]) {
- symbolMap[name] =
- base62.encode(_mungedSymbolMaps[scopeName].identifierUUIDCounter);
- _mungedSymbolMaps[scopeName].identifierUUIDCounter++;
+ /**
+ * Add the given string to this set.
+ *
+ * @param String aStr
+ */
+ ArraySet.prototype.add = function ArraySet_add(aStr) {
+ if (this.has(aStr)) {
+ // Already a member; nothing to do.
+ return;
}
- name = symbolMap[name];
- }
- return '$' + scopeName + name;
-}
+ var idx = this._array.length;
+ this._array.push(aStr);
+ this._set[util.toSetString(aStr)] = idx;
+ };
-function shouldMungeName(scopeName, name, state) {
- // only run when @preventMunge is not present in the docblock
- if (state.g.preventMunge === undefined) {
- var docblock = require('../lib/docblock');
- state.g.preventMunge = docblock.parseAsObject(
- docblock.extract(state.g.source)).preventMunge !== undefined;
- }
- // Starts with only a single underscore (i.e. don't count double-underscores)
- return !state.g.preventMunge && scopeName ? /^_(?!_)/.test(name) : false;
-}
+ /**
+ * Is the given string a member of this set?
+ *
+ * @param String aStr
+ */
+ ArraySet.prototype.has = function ArraySet_has(aStr) {
+ return Object.prototype.hasOwnProperty.call(this._set,
+ util.toSetString(aStr));
+ };
-
-function getProtoOfPrototypeVariableName(superVar) {
- return superVar + 'ProtoOfPrototype';
-}
-
-function getSuperKeyName(superVar) {
- return superVar + 'Key';
-}
-
-function getSuperProtoOfPrototypeVariable(superVariableName, indent) {
- var string = (indent +
- 'var $proto = $superName && $superName.prototype ? ' +
- '$superName.prototype : $superName;\n'
- ).replace(/\$proto/g, getProtoOfPrototypeVariableName(superVariableName))
- .replace(/\$superName/g, superVariableName);
- return string;
-}
-
-
-function getInheritanceSetup(superClassToken, className, indent, superName) {
- var string = '';
- if (superClassToken) {
- string += getStaticMethodsOnConstructorSetup(className, indent, superName);
- string += getPrototypeOnConstructorSetup(className, indent, superName);
- string += getConstructorPropertySetup(className, indent);
- }
- return string;
-}
-
-function getStaticMethodsOnConstructorSetup(className, indent, superName) {
- var string = ( indent +
- 'for (var $keyName in $superName) {\n' + indent +
- ' if ($superName.hasOwnProperty($keyName)) {\n' + indent +
- ' $className[$keyName] = $superName[$keyName];\n' + indent +
- ' }\n' + indent +
- '}\n')
- .replace(/\$className/g, className)
- .replace(/\$keyName/g, getSuperKeyName(superName))
- .replace(/\$superName/g, superName);
- return string;
-}
-
-function getPrototypeOnConstructorSetup(className, indent, superName) {
- var string = ( indent +
- '$className.prototype = Object.create($protoPrototype);\n')
- .replace(/\$protoPrototype/g, getProtoOfPrototypeVariableName(superName))
- .replace(/\$className/g, className);
- return string;
-}
-
-function getConstructorPropertySetup(className, indent) {
- var string = ( indent +
- '$className.prototype.constructor = $className;\n')
- .replace(/\$className/g, className);
-
- return string;
-}
-
-function getSuperConstructorSetup(superClassToken, indent, superName) {
- if (!superClassToken) return '';
- var string = ( '\n' + indent +
- ' if ($superName && $superName.prototype) {\n' + indent +
- ' $superName.apply(this, arguments);\n' + indent +
- ' }\n' + indent)
- .replace(/\$superName/g, superName);
- return string;
-}
-
-function getMemberFunctionCall(superVar, propertyName, superArgs) {
- var string = (
- '$superPrototype.$propertyName.call($superArguments)')
- .replace(/\$superPrototype/g, getProtoOfPrototypeVariableName(superVar))
- .replace(/\$propertyName/g, propertyName)
- .replace(/\$superArguments/g, superArgs);
- return string;
-}
-
-function getCallParams(classElement, state) {
- var params = classElement.value.params;
- if (!params.length) {
- return '';
- }
- return state.g.source.substring(
- params[0].range[0],
- params[params.length - 1].range[1]);
-}
-
-function getSuperArguments(callExpression, state) {
- var args = callExpression.arguments;
- if (!args.length) {
- return 'this';
- }
- return 'this, ' + state.g.source.substring(
- args[0].range[0],
- args[args.length - 1].range[1]);
-}
-
-// The seed is used to generate the name for an anonymous class,
-// and this seed should be unique per browser's session.
-// The value of the seed looks like this: 1229588505.2969012.
-var classIDSeed = Date.now() % (60 * 60 * 1000) + Math.random();
-
-/**
- * Generates a name for an anonymous class. The generated value looks like
- * this: "Classkc6pcn_mniza1yvi"
- * @param {String} scopeName
- * @return {string} the scope name for Anonymous Class
- */
-function generateAnonymousClassName(scopeName) {
- classIDSeed++;
- return 'Class' +
- (classIDSeed).toString(36).replace('.', '_') +
- (scopeName || '');
-}
-
-function renderMethods(traverse, object, name, path, state) {
- var classElements = object.body && object.body.body || [];
-
- move(object.body.range[0] + 1, state);
- for (var i = 0; i < classElements.length; i++) {
- if (classElements[i].key.name !== 'constructor') {
- catchup(classElements[i].range[0], state);
-
- var memberName = classElements[i].key.name;
- if (shouldMungeName(state.scopeName, memberName, state)) {
- memberName = getMungedName(
- state.scopeName,
- memberName,
- state.g.opts.minify
- );
- }
-
- var prototypeOrStatic;
- if (classElements[i]['static']) {
- prototypeOrStatic = '';
- } else {
- prototypeOrStatic = 'prototype.';
- }
-
- append(name + '.' + prototypeOrStatic + memberName + ' = ', state);
- renderMethod(traverse, classElements[i], null, path, state);
- append(';', state);
+ /**
+ * What is the index of the given string in the array?
+ *
+ * @param String aStr
+ */
+ ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
+ if (this.has(aStr)) {
+ return this._set[util.toSetString(aStr)];
}
- move(classElements[i].range[1], state);
- }
- if (classElements.length) {
- append('\n', state);
- }
- move(object.range[1], state);
-}
+ throw new Error('"' + aStr + '" is not in the set.');
+ };
-function renderMethod(traverse, method, name, path, state) {
- append(name ? 'function ' + name + '(' : 'function(', state);
- append(getCallParams(method, state) + ') {', state);
- move(method.value.body.range[0] + 1, state);
- traverse(method.value.body, path, state);
- catchup(method.value.body.range[1] - 1, state);
- append('}', state);
-}
-
-function renderSuperClass(traverse, superClass, path, state) {
- append('var ' + state.superVar + ' = ', state);
- move(superClass.range[0], state);
- traverse(superClass, path, state);
- catchup(superClass.range[1], state);
- append(';\n', state);
-}
-
-function renderConstructor(traverse, object, name, indent, path, state) {
- var classElements = object.body && object.body.body || [];
- var constructorIndex = findConstructorIndex(object);
- var constructor = constructorIndex === -1 ?
- null :
- classElements[constructorIndex];
- if (constructor) {
- move(constructorIndex === 0 ?
- object.body.range[0] + 1 :
- classElements[constructorIndex - 1].range[1], state);
- catchup(constructor.range[0], state);
- renderMethod(traverse, constructor, name, path, state);
- append('\n', state);
- } else {
- if (object.superClass) {
- append('\n' + indent, state);
+ /**
+ * What is the element at the given index?
+ *
+ * @param Number aIdx
+ */
+ ArraySet.prototype.at = function ArraySet_at(aIdx) {
+ if (aIdx >= 0 && aIdx < this._array.length) {
+ return this._array[aIdx];
}
- append('function ', state);
- if (object.id) {
- move(object.id.range[0], state);
- }
- append(name, state);
- if (object.id) {
- move(object.id.range[1], state);
- }
- append('(){ ', state);
- if (object.body) {
- move(object.body.range[0], state);
- }
- append(getSuperConstructorSetup(
- object.superClass,
- indent,
- state.superVar), state);
- append('}\n', state);
- }
-}
+ throw new Error('No element indexed by ' + aIdx);
+ };
-var superId = 0;
-function renderClassBody(traverse, object, path, state) {
- var name = object.id ? object.id.name : 'constructor';
- var superClass = object.superClass;
- var indent = updateIndent(
- indentBefore(object.range[0], state) + ' ',
- state);
+ /**
+ * Returns the array representation of this set (which has the proper indices
+ * indicated by indexOf). Note that this is a copy of the internal array used
+ * for storing the members so that no one can mess with internal state.
+ */
+ ArraySet.prototype.toArray = function ArraySet_toArray() {
+ return this._array.slice();
+ };
- state = updateState(
- state,
- {
- scopeName: object.id ? object.id.name :
- generateAnonymousClassName(state.scopeName),
- superVar: superClass ? '__super' + superId++ : ''
- });
+ exports.ArraySet = ArraySet;
- // super class
- if (superClass) {
- append(indent, state);
- renderSuperClass(traverse, superClass, path, state);
- append(getSuperProtoOfPrototypeVariable(state.superVar, indent), state);
- }
+});
- renderConstructor(traverse, object, name, indent, path, state);
- append(getInheritanceSetup(superClass, name, indent, state.superVar), state);
- renderMethods(traverse, object, name, path, state);
-}
-
-
-/**
- * @public
- */
-function visitClassExpression(traverse, object, path, state) {
- var indent = updateIndent(
- indentBefore(object.range[0], state) + ' ',
- state);
- var name = object.id ? object.id.name : 'constructor';
-
- append('(function() {\n', state);
- renderClassBody(traverse, object, path, state);
- append(indent + 'return ' + name + ';\n', state);
- append(indent.substring(0, indent.length - 2) + '})()', state);
- return false
-}
-
-visitClassExpression.test = function(object, path, state) {
- return object.type === Syntax.ClassExpression;
-};
-
-/**
- * @public
- */
-function visitClassDeclaration(traverse, object, path, state) {
- state.g.indentBy--;
- renderClassBody(traverse, object, path, state);
- state.g.indentBy++;
- return false;
-}
-
-visitClassDeclaration.test = function(object, path, state) {
- return object.type === Syntax.ClassDeclaration;
-};
-
-
-/**
- * @public
- */
-function visitSuperCall(traverse, object, path, state) {
- if (path[0].type === Syntax.CallExpression) {
- append(state.superVar +
- '.call(' + getSuperArguments(path[0], state) + ')', state);
- move(path[0].range[1], state);
- } else if (path[0].type === Syntax.MemberExpression) {
- append(getMemberFunctionCall(
- state.superVar,
- path[0].property.name,
- getSuperArguments(path[1], state)), state);
- move(path[1].range[1], state);
- }
- return false;
-}
-
-visitSuperCall.test = function(object, path, state) {
- return state.superVar && object.type === Syntax.Identifier &&
- object.name === 'super';
-};
-
-/**
- * @public
- */
-function visitPrivateProperty(traverse, object, path, state) {
- var type = path[0] ? path[0].type : null;
- if (type !== Syntax.Property) {
- if (type === Syntax.MemberExpression) {
- type = path[0].object ? path[0].object.type : null;
- if (type === Syntax.Identifier &&
- path[0].object.range[0] === object.range[0]) {
- // Identifier is a variable that appears "private".
- return;
- }
- } else {
- // Other syntax that are neither Property nor MemberExpression.
- return;
- }
- }
-
- var oldName = object.name;
- var newName = getMungedName(
- state.scopeName,
- oldName,
- state.g.opts.minify
- );
- append(newName, state);
- move(object.range[1], state);
-}
-
-visitPrivateProperty.test = function(object, path, state) {
- return object.type === Syntax.Identifier &&
- shouldMungeName(state.scopeName, object.name, state);
-};
-
-
-exports.visitClassDeclaration = visitClassDeclaration;
-exports.visitClassExpression = visitClassExpression;
-exports.visitSuperCall = visitSuperCall;
-exports.visitPrivateProperty = visitPrivateProperty;
-
-})()
-},{"../lib/utils":8,"../lib/docblock":4,"esprima":9,"base62":15}],6:[function(require,module,exports){
-(function(){/**
- * Copyright 2013 Facebook, Inc.
+},{"./util":13,"amdefine":14}],7:[function(require,module,exports){
+/* -*- Mode: js; js-indent-level: 2; -*- */
+/*
+ * Copyright 2011 Mozilla Foundation and contributors
+ * Licensed under the New BSD license. See LICENSE or:
+ * http://opensource.org/licenses/BSD-3-Clause
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Based on the Base 64 VLQ implementation in Closure Compiler:
+ * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * Copyright 2011 The Closure Compiler Authors. All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*global exports:true*/
-"use strict";
+if (typeof define !== 'function') {
+ var define = require('amdefine')(module, require);
+}
+define(function (require, exports, module) {
-var Syntax = require('esprima').Syntax;
+ var base64 = require('./base64');
-var catchup = require('../lib/utils').catchup;
-var append = require('../lib/utils').append;
-var move = require('../lib/utils').move;
-var getDocblock = require('../lib/utils').getDocblock;
+ // A single base 64 digit can contain 6 bits of data. For the base 64 variable
+ // length quantities we use in the source map spec, the first bit is the sign,
+ // the next four bits are the actual value, and the 6th bit is the
+ // continuation bit. The continuation bit tells us whether there are more
+ // digits in this value following this digit.
+ //
+ // Continuation
+ // | Sign
+ // | |
+ // V V
+ // 101011
-var FALLBACK_TAGS = require('./xjs').knownTags;
-var renderXJSExpression = require('./xjs').renderXJSExpression;
-var renderXJSLiteral = require('./xjs').renderXJSLiteral;
-var quoteAttrName = require('./xjs').quoteAttrName;
+ var VLQ_BASE_SHIFT = 5;
-/**
- * Customized desugar processor.
- *
- * Currently: (Somewhat tailored to React)
- * <X> </X> => X(null, null)
- * <X prop="1" /> => X({prop: '1'}, null)
- * <X prop="2"><Y /></X> => X({prop:'2'}, Y(null, null))
- * <X prop="2"><Y /><Z /></X> => X({prop:'2'}, [Y(null, null), Z(null, null)])
- *
- * Exceptions to the simple rules above:
- * if a property is named "class" it will be changed to "className" in the
- * javascript since "class" is not a valid object key in javascript.
- */
+ // binary: 100000
+ var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
-var JSX_ATTRIBUTE_RENAMES = {
- 'class': 'className',
- cxName: 'className'
-};
+ // binary: 011111
+ var VLQ_BASE_MASK = VLQ_BASE - 1;
-var JSX_ATTRIBUTE_TRANSFORMS = {
- cxName: function(attr) {
- if (attr.value.type !== Syntax.Literal) {
- throw new Error("cx only accepts a string literal");
- } else {
- var classNames = attr.value.value.split(/\s+/g);
- return 'cx(' + classNames.map(JSON.stringify).join(',') + ')';
- }
- }
-};
+ // binary: 100000
+ var VLQ_CONTINUATION_BIT = VLQ_BASE;
-function visitReactTag(traverse, object, path, state) {
- var jsxObjIdent = getDocblock(state).jsx;
-
- catchup(object.openingElement.range[0], state);
-
- if (object.name.namespace) {
- throw new Error(
- 'Namespace tags are not supported. ReactJSX is not XML.');
+ /**
+ * Converts from a two-complement value to a value where the sign bit is
+ * is placed in the least significant bit. For example, as decimals:
+ * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
+ * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
+ */
+ function toVLQSigned(aValue) {
+ return aValue < 0
+ ? ((-aValue) << 1) + 1
+ : (aValue << 1) + 0;
}
- var isFallbackTag = FALLBACK_TAGS[object.name.name];
- append(
- (isFallbackTag ? jsxObjIdent + '.' : '') + (object.name.name) + '(',
- state
- );
-
- move(object.name.range[1], state);
-
- var childrenToRender = object.children.filter(function(child) {
- return !(child.type === Syntax.Literal && !child.value.match(/\S/));
- });
-
- // if we don't have any attributes, pass in null
- if (object.attributes.length === 0) {
- append('null', state);
+ /**
+ * Converts to a two-complement value from a value where the sign bit is
+ * is placed in the least significant bit. For example, as decimals:
+ * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1
+ * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2
+ */
+ function fromVLQSigned(aValue) {
+ var isNegative = (aValue & 1) === 1;
+ var shifted = aValue >> 1;
+ return isNegative
+ ? -shifted
+ : shifted;
}
- // write attributes
- object.attributes.forEach(function(attr, index) {
- catchup(attr.range[0], state);
- if (attr.name.namespace) {
- throw new Error(
- 'Namespace attributes are not supported. ReactJSX is not XML.');
- }
- var name = JSX_ATTRIBUTE_RENAMES[attr.name.name] || attr.name.name;
- var isFirst = index === 0;
- var isLast = index === object.attributes.length - 1;
+ /**
+ * Returns the base 64 VLQ encoded value.
+ */
+ exports.encode = function base64VLQ_encode(aValue) {
+ var encoded = "";
+ var digit;
- if (isFirst) {
- append('{', state);
- }
+ var vlq = toVLQSigned(aValue);
- append(quoteAttrName(name), state);
- append(':', state);
-
- if (!attr.value) {
- state.g.buffer += 'true';
- state.g.position = attr.name.range[1];
- if (!isLast) {
- append(',', state);
+ do {
+ digit = vlq & VLQ_BASE_MASK;
+ vlq >>>= VLQ_BASE_SHIFT;
+ if (vlq > 0) {
+ // There are still more digits in this value, so we must make sure the
+ // continuation bit is marked.
+ digit |= VLQ_CONTINUATION_BIT;
}
- } else if (JSX_ATTRIBUTE_TRANSFORMS[attr.name.name]) {
- move(attr.value.range[0], state);
- append(JSX_ATTRIBUTE_TRANSFORMS[attr.name.name](attr), state);
- move(attr.value.range[1], state);
- if (!isLast) {
- append(',', state);
- }
- } else if (attr.value.type === Syntax.Literal) {
- move(attr.value.range[0], state);
- renderXJSLiteral(attr.value, isLast, state);
- } else {
- move(attr.value.range[0], state);
- renderXJSExpression(traverse, attr.value, isLast, path, state);
- }
+ encoded += base64.encode(digit);
+ } while (vlq > 0);
- if (isLast) {
- append('}', state);
- }
+ return encoded;
+ };
- catchup(attr.range[1], state);
- });
+ /**
+ * Decodes the next base 64 VLQ value from the given string and returns the
+ * value and the rest of the string.
+ */
+ exports.decode = function base64VLQ_decode(aStr) {
+ var i = 0;
+ var strLen = aStr.length;
+ var result = 0;
+ var shift = 0;
+ var continuation, digit;
- if (!object.selfClosing) {
- catchup(object.openingElement.range[1] - 1, state);
- move(object.openingElement.range[1], state);
- }
-
- // separate props and children arguments
- append(', ', state);
-
- // filter out whitespace
- if (childrenToRender.length > 0) {
- if (childrenToRender.length > 1) {
- append('[', state);
- }
- object.children.forEach(function(child) {
- if (child.type === Syntax.Literal && !child.value.match(/\S/)) {
- return;
+ do {
+ if (i >= strLen) {
+ throw new Error("Expected more digits in base 64 VLQ value.");
}
- catchup(child.range[0], state);
+ digit = base64.decode(aStr.charAt(i++));
+ continuation = !!(digit & VLQ_CONTINUATION_BIT);
+ digit &= VLQ_BASE_MASK;
+ result = result + (digit << shift);
+ shift += VLQ_BASE_SHIFT;
+ } while (continuation);
- var isLast = child === childrenToRender[childrenToRender.length - 1];
-
- if (child.type === Syntax.Literal) {
- renderXJSLiteral(child, isLast, state);
- } else if (child.type === Syntax.XJSExpression) {
- renderXJSExpression(traverse, child, isLast, path, state);
- } else {
- traverse(child, path, state);
- if (!isLast) {
- append(',', state);
- state.g.buffer = state.g.buffer.replace(/(\s*),$/, ',$1');
- }
- }
-
- catchup(child.range[1], state);
- });
- } else {
- append('null', state);
- }
-
- if (object.selfClosing) {
- // everything up to />
- catchup(object.openingElement.range[1] - 2, state);
- move(object.openingElement.range[1], state);
- } else {
- // everything up to </ sdflksjfd>
- catchup(object.closingElement.range[0], state);
- move(object.closingElement.range[1], state);
- }
-
- if (childrenToRender.length > 0) {
- if (childrenToRender.length > 1) {
- append(']', state);
- }
- }
- append(')', state);
- return false;
-}
-
-visitReactTag.test = function(object, path, state) {
- // only run react when react @jsx namespace is specified in docblock
- var jsx = getDocblock(state).jsx;
- return object.type === Syntax.XJSElement && jsx && jsx.length;
-};
-
-exports.visitReactTag = visitReactTag;
-
-})()
-},{"../lib/utils":8,"./xjs":11,"esprima":9}],7:[function(require,module,exports){
-(function(){/**
- * Copyright 2013 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*global exports:true*/
-"use strict";
-
-var Syntax = require('esprima').Syntax;
-var catchup = require('../lib/utils').catchup;
-var append = require('../lib/utils').append;
-var getDocblock = require('../lib/utils').getDocblock;
-
-/**
- * Transforms the following:
- *
- * var MyComponent = React.createClass({
- * render: ...
- * });
- *
- * into:
- *
- * var MyComponent = React.createClass({
- * displayName: 'MyComponent',
- * render: ...
- * });
- */
-function visitReactDisplayName(traverse, object, path, state) {
- if (object.id.type === Syntax.Identifier &&
- object.init &&
- object.init.type === Syntax.CallExpression &&
- object.init.callee.type === Syntax.MemberExpression &&
- object.init.callee.object.type === Syntax.Identifier &&
- object.init.callee.object.name === 'React' &&
- object.init.callee.property.type === Syntax.Identifier &&
- object.init.callee.property.name === 'createClass' &&
- object.init['arguments'].length === 1 &&
- object.init['arguments'][0].type === Syntax.ObjectExpression) {
-
- var displayName = object.id.name;
- catchup(object.init['arguments'][0].range[0] + 1, state);
- append("displayName: '" + displayName + "',", state);
- }
-}
-
-/**
- * Will only run on @jsx files for now.
- */
-visitReactDisplayName.test = function(object, path, state) {
- return object.type === Syntax.VariableDeclarator && !!getDocblock(state).jsx;
-};
-
-exports.visitReactDisplayName = visitReactDisplayName;
-
-})()
-},{"../lib/utils":8,"esprima":9}],15:[function(require,module,exports){
-var Base62 = (function (my) {
- my.chars = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
-
- my.encode = function(i){
- if (i === 0) {return '0'}
- var s = ''
- while (i > 0) {
- s = this.chars[i % 62] + s
- i = Math.floor(i/62)
- }
- return s
+ return {
+ value: fromVLQSigned(result),
+ rest: aStr.slice(i)
+ };
};
- my.decode = function(a,b,c,d){
- for (
- b = c = (
- a === (/\W|_|^$/.test(a += "") || a)
- ) - 1;
- d = a.charCodeAt(c++);
- )
- b = b * 62 + d - [, 48, 29, 87][d >> 5];
- return b
- };
- return my;
-}({}));
+});
-module.exports = Base62
-},{}],12:[function(require,module,exports){
+},{"./base64":8,"amdefine":14}],8:[function(require,module,exports){
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
if (typeof define !== 'function') {
- var define = require('amdefine')(module);
+ var define = require('amdefine')(module, require);
}
define(function (require, exports, module) {
- var base64VLQ = require('./base64-vlq');
- var util = require('./util');
- var ArraySet = require('./array-set').ArraySet;
+ var charToIntMap = {};
+ var intToCharMap = {};
- /**
- * An instance of the SourceMapGenerator represents a source map which is
- * being built incrementally. To create a new one, you must pass an object
- * with the following properties:
- *
- * - file: The filename of the generated source.
- * - sourceRoot: An optional root for all URLs in this source map.
- */
- function SourceMapGenerator(aArgs) {
- this._file = util.getArg(aArgs, 'file');
- this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);
- this._sources = new ArraySet();
- this._names = new ArraySet();
- this._mappings = [];
- this._sourcesContents = null;
- }
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
+ .split('')
+ .forEach(function (ch, index) {
+ charToIntMap[ch] = index;
+ intToCharMap[index] = ch;
+ });
- SourceMapGenerator.prototype._version = 3;
-
/**
- * Creates a new SourceMapGenerator based on a SourceMapConsumer
- *
- * @param aSourceMapConsumer The SourceMap.
+ * Encode an integer in the range of 0 to 63 to a single base 64 digit.
*/
- SourceMapGenerator.fromSourceMap =
- function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
- var sourceRoot = aSourceMapConsumer.sourceRoot;
- var generator = new SourceMapGenerator({
- file: aSourceMapConsumer.file,
- sourceRoot: sourceRoot
- });
- aSourceMapConsumer.eachMapping(function (mapping) {
- var newMapping = {
- generated: {
- line: mapping.generatedLine,
- column: mapping.generatedColumn
- }
- };
+ exports.encode = function base64_encode(aNumber) {
+ if (aNumber in intToCharMap) {
+ return intToCharMap[aNumber];
+ }
+ throw new TypeError("Must be between 0 and 63: " + aNumber);
+ };
- if (mapping.source) {
- newMapping.source = mapping.source;
- if (sourceRoot) {
- newMapping.source = util.relative(sourceRoot, newMapping.source);
- }
-
- newMapping.original = {
- line: mapping.originalLine,
- column: mapping.originalColumn
- };
-
- if (mapping.name) {
- newMapping.name = mapping.name;
- }
- }
-
- generator.addMapping(newMapping);
- });
- aSourceMapConsumer.sources.forEach(function (sourceFile) {
- var content = aSourceMapConsumer.sourceContentFor(sourceFile);
- if (content) {
- generator.setSourceContent(sourceFile, content);
- }
- });
- return generator;
- };
-
/**
- * Add a single mapping from original source line and column to the generated
- * source's line and column for this source map being created. The mapping
- * object should have the following properties:
- *
- * - generated: An object with the generated line and column positions.
- * - original: An object with the original line and column positions.
- * - source: The original source file (relative to the sourceRoot).
- * - name: An optional original token name for this mapping.
+ * Decode a single base 64 digit to an integer.
*/
- SourceMapGenerator.prototype.addMapping =
- function SourceMapGenerator_addMapping(aArgs) {
- var generated = util.getArg(aArgs, 'generated');
- var original = util.getArg(aArgs, 'original', null);
- var source = util.getArg(aArgs, 'source', null);
- var name = util.getArg(aArgs, 'name', null);
+ exports.decode = function base64_decode(aChar) {
+ if (aChar in charToIntMap) {
+ return charToIntMap[aChar];
+ }
+ throw new TypeError("Not a valid base 64 digit: " + aChar);
+ };
- this._validateMapping(generated, original, source, name);
+});
- if (source && !this._sources.has(source)) {
- this._sources.add(source);
- }
+},{"amdefine":14}],9:[function(require,module,exports){
+/* -*- Mode: js; js-indent-level: 2; -*- */
+/*
+ * Copyright 2011 Mozilla Foundation and contributors
+ * Licensed under the New BSD license. See LICENSE or:
+ * http://opensource.org/licenses/BSD-3-Clause
+ */
+if (typeof define !== 'function') {
+ var define = require('amdefine')(module, require);
+}
+define(function (require, exports, module) {
- if (name && !this._names.has(name)) {
- this._names.add(name);
- }
-
- this._mappings.push({
- generated: generated,
- original: original,
- source: source,
- name: name
- });
- };
-
/**
- * Set the source content for a source file.
- */
- SourceMapGenerator.prototype.setSourceContent =
- function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
- var source = aSourceFile;
- if (this._sourceRoot) {
- source = util.relative(this._sourceRoot, source);
- }
-
- if (aSourceContent !== null) {
- // Add the source content to the _sourcesContents map.
- // Create a new _sourcesContents map if the property is null.
- if (!this._sourcesContents) {
- this._sourcesContents = {};
- }
- this._sourcesContents[util.toSetString(source)] = aSourceContent;
- } else {
- // Remove the source file from the _sourcesContents map.
- // If the _sourcesContents map is empty, set the property to null.
- delete this._sourcesContents[util.toSetString(source)];
- if (Object.keys(this._sourcesContents).length === 0) {
- this._sourcesContents = null;
- }
- }
- };
-
- /**
- * Applies the mappings of a sub-source-map for a specific source file to the
- * source map being generated. Each mapping to the supplied source file is
- * rewritten using the supplied source map. Note: The resolution for the
- * resulting mappings is the minimium of this map and the supplied map.
+ * Recursive implementation of binary search.
*
- * @param aSourceMapConsumer The source map to be applied.
- * @param aSourceFile Optional. The filename of the source file.
- * If omitted, SourceMapConsumer's file property will be used.
+ * @param aLow Indices here and lower do not contain the needle.
+ * @param aHigh Indices here and higher do not contain the needle.
+ * @param aNeedle The element being searched for.
+ * @param aHaystack The non-empty array being searched.
+ * @param aCompare Function which takes two elements and returns -1, 0, or 1.
*/
- SourceMapGenerator.prototype.applySourceMap =
- function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile) {
- // If aSourceFile is omitted, we will use the file property of the SourceMap
- if (!aSourceFile) {
- aSourceFile = aSourceMapConsumer.file;
+ function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare) {
+ // This function terminates when one of the following is true:
+ //
+ // 1. We find the exact element we are looking for.
+ //
+ // 2. We did not find the exact element, but we can return the next
+ // closest element that is less than that element.
+ //
+ // 3. We did not find the exact element, and there is no next-closest
+ // element which is less than the one we are searching for, so we
+ // return null.
+ var mid = Math.floor((aHigh - aLow) / 2) + aLow;
+ var cmp = aCompare(aNeedle, aHaystack[mid]);
+ if (cmp === 0) {
+ // Found the element we are looking for.
+ return aHaystack[mid];
+ }
+ else if (cmp > 0) {
+ // aHaystack[mid] is greater than our needle.
+ if (aHigh - mid > 1) {
+ // The element is in the upper half.
+ return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare);
}
- var sourceRoot = this._sourceRoot;
- // Make "aSourceFile" relative if an absolute Url is passed.
- if (sourceRoot) {
- aSourceFile = util.relative(sourceRoot, aSourceFile);
+ // We did not find an exact match, return the next closest one
+ // (termination case 2).
+ return aHaystack[mid];
+ }
+ else {
+ // aHaystack[mid] is less than our needle.
+ if (mid - aLow > 1) {
+ // The element is in the lower half.
+ return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare);
}
- // Applying the SourceMap can add and remove items from the sources and
- // the names array.
- var newSources = new ArraySet();
- var newNames = new ArraySet();
+ // The exact needle element was not found in this haystack. Determine if
+ // we are in termination case (2) or (3) and return the appropriate thing.
+ return aLow < 0
+ ? null
+ : aHaystack[aLow];
+ }
+ }
- // Find mappings for the "aSourceFile"
- this._mappings.forEach(function (mapping) {
- if (mapping.source === aSourceFile && mapping.original) {
- // Check if it can be mapped by the source map, then update the mapping.
- var original = aSourceMapConsumer.originalPositionFor({
- line: mapping.original.line,
- column: mapping.original.column
- });
- if (original.source !== null) {
- // Copy mapping
- if (sourceRoot) {
- mapping.source = util.relative(sourceRoot, original.source);
- } else {
- mapping.source = original.source;
- }
- mapping.original.line = original.line;
- mapping.original.column = original.column;
- if (original.name !== null && mapping.name !== null) {
- // Only use the identifier name if it's an identifier
- // in both SourceMaps
- mapping.name = original.name;
- }
- }
- }
-
- var source = mapping.source;
- if (source && !newSources.has(source)) {
- newSources.add(source);
- }
-
- var name = mapping.name;
- if (name && !newNames.has(name)) {
- newNames.add(name);
- }
-
- }, this);
- this._sources = newSources;
- this._names = newNames;
-
- // Copy sourcesContents of applied map.
- aSourceMapConsumer.sources.forEach(function (sourceFile) {
- var content = aSourceMapConsumer.sourceContentFor(sourceFile);
- if (content) {
- if (sourceRoot) {
- sourceFile = util.relative(sourceRoot, sourceFile);
- }
- this.setSourceContent(sourceFile, content);
- }
- }, this);
- };
-
/**
- * A mapping can have one of the three levels of data:
+ * This is an implementation of binary search which will always try and return
+ * the next lowest value checked if there is no exact hit. This is because
+ * mappings between original and generated line/col pairs are single points,
+ * and there is an implicit region between each of them, so a miss just means
+ * that you aren't on the very start of a region.
*
- * 1. Just the generated position.
- * 2. The Generated position, original position, and original source.
- * 3. Generated and original position, original source, as well as a name
- * token.
- *
- * To maintain consistency, we validate that any new mapping being added falls
- * in to one of these categories.
+ * @param aNeedle The element you are looking for.
+ * @param aHaystack The array that is being searched.
+ * @param aCompare A function which takes the needle and an element in the
+ * array and returns -1, 0, or 1 depending on whether the needle is less
+ * than, equal to, or greater than the element, respectively.
*/
- SourceMapGenerator.prototype._validateMapping =
- function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
- aName) {
- if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
- && aGenerated.line > 0 && aGenerated.column >= 0
- && !aOriginal && !aSource && !aName) {
- // Case 1.
- return;
- }
- else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
- && aOriginal && 'line' in aOriginal && 'column' in aOriginal
- && aGenerated.line > 0 && aGenerated.column >= 0
- && aOriginal.line > 0 && aOriginal.column >= 0
- && aSource) {
- // Cases 2 and 3.
- return;
- }
- else {
- throw new Error('Invalid mapping.');
- }
- };
+ exports.search = function search(aNeedle, aHaystack, aCompare) {
+ return aHaystack.length > 0
+ ? recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, aCompare)
+ : null;
+ };
- function cmpLocation(loc1, loc2) {
- var cmp = (loc1 && loc1.line) - (loc2 && loc2.line);
- return cmp ? cmp : (loc1 && loc1.column) - (loc2 && loc2.column);
- }
-
- function strcmp(str1, str2) {
- str1 = str1 || '';
- str2 = str2 || '';
- return (str1 > str2) - (str1 < str2);
- }
-
- function cmpMapping(mappingA, mappingB) {
- return cmpLocation(mappingA.generated, mappingB.generated) ||
- cmpLocation(mappingA.original, mappingB.original) ||
- strcmp(mappingA.source, mappingB.source) ||
- strcmp(mappingA.name, mappingB.name);
- }
-
- /**
- * Serialize the accumulated mappings in to the stream of base 64 VLQs
- * specified by the source map format.
- */
- SourceMapGenerator.prototype._serializeMappings =
- function SourceMapGenerator_serializeMappings() {
- var previousGeneratedColumn = 0;
- var previousGeneratedLine = 1;
- var previousOriginalColumn = 0;
- var previousOriginalLine = 0;
- var previousName = 0;
- var previousSource = 0;
- var result = '';
- var mapping;
-
- // The mappings must be guarenteed to be in sorted order before we start
- // serializing them or else the generated line numbers (which are defined
- // via the ';' separators) will be all messed up. Note: it might be more
- // performant to maintain the sorting as we insert them, rather than as we
- // serialize them, but the big O is the same either way.
- this._mappings.sort(cmpMapping);
-
- for (var i = 0, len = this._mappings.length; i < len; i++) {
- mapping = this._mappings[i];
-
- if (mapping.generated.line !== previousGeneratedLine) {
- previousGeneratedColumn = 0;
- while (mapping.generated.line !== previousGeneratedLine) {
- result += ';';
- previousGeneratedLine++;
- }
- }
- else {
- if (i > 0) {
- if (!cmpMapping(mapping, this._mappings[i - 1])) {
- continue;
- }
- result += ',';
- }
- }
-
- result += base64VLQ.encode(mapping.generated.column
- - previousGeneratedColumn);
- previousGeneratedColumn = mapping.generated.column;
-
- if (mapping.source && mapping.original) {
- result += base64VLQ.encode(this._sources.indexOf(mapping.source)
- - previousSource);
- previousSource = this._sources.indexOf(mapping.source);
-
- // lines are stored 0-based in SourceMap spec version 3
- result += base64VLQ.encode(mapping.original.line - 1
- - previousOriginalLine);
- previousOriginalLine = mapping.original.line - 1;
-
- result += base64VLQ.encode(mapping.original.column
- - previousOriginalColumn);
- previousOriginalColumn = mapping.original.column;
-
- if (mapping.name) {
- result += base64VLQ.encode(this._names.indexOf(mapping.name)
- - previousName);
- previousName = this._names.indexOf(mapping.name);
- }
- }
- }
-
- return result;
- };
-
- /**
- * Externalize the source map.
- */
- SourceMapGenerator.prototype.toJSON =
- function SourceMapGenerator_toJSON() {
- var map = {
- version: this._version,
- file: this._file,
- sources: this._sources.toArray(),
- names: this._names.toArray(),
- mappings: this._serializeMappings()
- };
- if (this._sourceRoot) {
- map.sourceRoot = this._sourceRoot;
- }
- if (this._sourcesContents) {
- map.sourcesContent = map.sources.map(function (source) {
- if (map.sourceRoot) {
- source = util.relative(map.sourceRoot, source);
- }
- return Object.prototype.hasOwnProperty.call(
- this._sourcesContents, util.toSetString(source))
- ? this._sourcesContents[util.toSetString(source)]
- : null;
- }, this);
- }
- return map;
- };
-
- /**
- * Render the source map being generated to a string.
- */
- SourceMapGenerator.prototype.toString =
- function SourceMapGenerator_toString() {
- return JSON.stringify(this);
- };
-
- exports.SourceMapGenerator = SourceMapGenerator;
-
});
-},{"./base64-vlq":16,"./util":17,"./array-set":18,"amdefine":19}],13:[function(require,module,exports){
+},{"amdefine":14}],10:[function(require,module,exports){
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
if (typeof define !== 'function') {
- var define = require('amdefine')(module);
+ var define = require('amdefine')(module, require);
}
define(function (require, exports, module) {
var util = require('./util');
var binarySearch = require('./binary-search');
@@ -8638,13 +7126,13 @@
name: null
};
};
/**
- * Returns the original source content. The only argument is
- * the url of the original source file. Returns null if no
- * original source content is availible.
+ * Returns the original source content. The only argument is the url of the
+ * original source file. Returns null if no original source content is
+ * availible.
*/
SourceMapConsumer.prototype.sourceContentFor =
function SourceMapConsumer_sourceContentFor(aSource) {
if (!this.sourcesContent) {
return null;
@@ -8658,14 +7146,25 @@
return this.sourcesContent[this._sources.indexOf(aSource)];
}
var url;
if (this.sourceRoot
- && (url = util.urlParse(this.sourceRoot))
- && (!url.path || url.path == "/")
- && this._sources.has("/" + aSource)) {
- return this.sourcesContent[this._sources.indexOf("/" + aSource)];
+ && (url = util.urlParse(this.sourceRoot))) {
+ // XXX: file:// URIs and absolute paths lead to unexpected behavior for
+ // many users. We can help them out when they expect file:// URIs to
+ // behave like it would if they were running a local HTTP server. See
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=885597.
+ var fileUriAbsPath = aSource.replace(/^file:\/\//, "");
+ if (url.scheme == "file"
+ && this._sources.has(fileUriAbsPath)) {
+ return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]
+ }
+
+ if ((!url.path || url.path == "/")
+ && this._sources.has("/" + aSource)) {
+ return this.sourcesContent[this._sources.indexOf("/" + aSource)];
+ }
}
throw new Error('"' + aSource + '" is not in the SourceMap.');
};
@@ -8769,22 +7268,405 @@
exports.SourceMapConsumer = SourceMapConsumer;
});
-},{"./util":17,"./binary-search":20,"./array-set":18,"./base64-vlq":16,"amdefine":19}],14:[function(require,module,exports){
+},{"./array-set":6,"./base64-vlq":7,"./binary-search":9,"./util":13,"amdefine":14}],11:[function(require,module,exports){
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
if (typeof define !== 'function') {
- var define = require('amdefine')(module);
+ var define = require('amdefine')(module, require);
}
define(function (require, exports, module) {
+ var base64VLQ = require('./base64-vlq');
+ var util = require('./util');
+ var ArraySet = require('./array-set').ArraySet;
+
+ /**
+ * An instance of the SourceMapGenerator represents a source map which is
+ * being built incrementally. To create a new one, you must pass an object
+ * with the following properties:
+ *
+ * - file: The filename of the generated source.
+ * - sourceRoot: An optional root for all URLs in this source map.
+ */
+ function SourceMapGenerator(aArgs) {
+ this._file = util.getArg(aArgs, 'file');
+ this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);
+ this._sources = new ArraySet();
+ this._names = new ArraySet();
+ this._mappings = [];
+ this._sourcesContents = null;
+ }
+
+ SourceMapGenerator.prototype._version = 3;
+
+ /**
+ * Creates a new SourceMapGenerator based on a SourceMapConsumer
+ *
+ * @param aSourceMapConsumer The SourceMap.
+ */
+ SourceMapGenerator.fromSourceMap =
+ function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
+ var sourceRoot = aSourceMapConsumer.sourceRoot;
+ var generator = new SourceMapGenerator({
+ file: aSourceMapConsumer.file,
+ sourceRoot: sourceRoot
+ });
+ aSourceMapConsumer.eachMapping(function (mapping) {
+ var newMapping = {
+ generated: {
+ line: mapping.generatedLine,
+ column: mapping.generatedColumn
+ }
+ };
+
+ if (mapping.source) {
+ newMapping.source = mapping.source;
+ if (sourceRoot) {
+ newMapping.source = util.relative(sourceRoot, newMapping.source);
+ }
+
+ newMapping.original = {
+ line: mapping.originalLine,
+ column: mapping.originalColumn
+ };
+
+ if (mapping.name) {
+ newMapping.name = mapping.name;
+ }
+ }
+
+ generator.addMapping(newMapping);
+ });
+ aSourceMapConsumer.sources.forEach(function (sourceFile) {
+ var content = aSourceMapConsumer.sourceContentFor(sourceFile);
+ if (content) {
+ generator.setSourceContent(sourceFile, content);
+ }
+ });
+ return generator;
+ };
+
+ /**
+ * Add a single mapping from original source line and column to the generated
+ * source's line and column for this source map being created. The mapping
+ * object should have the following properties:
+ *
+ * - generated: An object with the generated line and column positions.
+ * - original: An object with the original line and column positions.
+ * - source: The original source file (relative to the sourceRoot).
+ * - name: An optional original token name for this mapping.
+ */
+ SourceMapGenerator.prototype.addMapping =
+ function SourceMapGenerator_addMapping(aArgs) {
+ var generated = util.getArg(aArgs, 'generated');
+ var original = util.getArg(aArgs, 'original', null);
+ var source = util.getArg(aArgs, 'source', null);
+ var name = util.getArg(aArgs, 'name', null);
+
+ this._validateMapping(generated, original, source, name);
+
+ if (source && !this._sources.has(source)) {
+ this._sources.add(source);
+ }
+
+ if (name && !this._names.has(name)) {
+ this._names.add(name);
+ }
+
+ this._mappings.push({
+ generated: generated,
+ original: original,
+ source: source,
+ name: name
+ });
+ };
+
+ /**
+ * Set the source content for a source file.
+ */
+ SourceMapGenerator.prototype.setSourceContent =
+ function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
+ var source = aSourceFile;
+ if (this._sourceRoot) {
+ source = util.relative(this._sourceRoot, source);
+ }
+
+ if (aSourceContent !== null) {
+ // Add the source content to the _sourcesContents map.
+ // Create a new _sourcesContents map if the property is null.
+ if (!this._sourcesContents) {
+ this._sourcesContents = {};
+ }
+ this._sourcesContents[util.toSetString(source)] = aSourceContent;
+ } else {
+ // Remove the source file from the _sourcesContents map.
+ // If the _sourcesContents map is empty, set the property to null.
+ delete this._sourcesContents[util.toSetString(source)];
+ if (Object.keys(this._sourcesContents).length === 0) {
+ this._sourcesContents = null;
+ }
+ }
+ };
+
+ /**
+ * Applies the mappings of a sub-source-map for a specific source file to the
+ * source map being generated. Each mapping to the supplied source file is
+ * rewritten using the supplied source map. Note: The resolution for the
+ * resulting mappings is the minimium of this map and the supplied map.
+ *
+ * @param aSourceMapConsumer The source map to be applied.
+ * @param aSourceFile Optional. The filename of the source file.
+ * If omitted, SourceMapConsumer's file property will be used.
+ */
+ SourceMapGenerator.prototype.applySourceMap =
+ function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile) {
+ // If aSourceFile is omitted, we will use the file property of the SourceMap
+ if (!aSourceFile) {
+ aSourceFile = aSourceMapConsumer.file;
+ }
+ var sourceRoot = this._sourceRoot;
+ // Make "aSourceFile" relative if an absolute Url is passed.
+ if (sourceRoot) {
+ aSourceFile = util.relative(sourceRoot, aSourceFile);
+ }
+ // Applying the SourceMap can add and remove items from the sources and
+ // the names array.
+ var newSources = new ArraySet();
+ var newNames = new ArraySet();
+
+ // Find mappings for the "aSourceFile"
+ this._mappings.forEach(function (mapping) {
+ if (mapping.source === aSourceFile && mapping.original) {
+ // Check if it can be mapped by the source map, then update the mapping.
+ var original = aSourceMapConsumer.originalPositionFor({
+ line: mapping.original.line,
+ column: mapping.original.column
+ });
+ if (original.source !== null) {
+ // Copy mapping
+ if (sourceRoot) {
+ mapping.source = util.relative(sourceRoot, original.source);
+ } else {
+ mapping.source = original.source;
+ }
+ mapping.original.line = original.line;
+ mapping.original.column = original.column;
+ if (original.name !== null && mapping.name !== null) {
+ // Only use the identifier name if it's an identifier
+ // in both SourceMaps
+ mapping.name = original.name;
+ }
+ }
+ }
+
+ var source = mapping.source;
+ if (source && !newSources.has(source)) {
+ newSources.add(source);
+ }
+
+ var name = mapping.name;
+ if (name && !newNames.has(name)) {
+ newNames.add(name);
+ }
+
+ }, this);
+ this._sources = newSources;
+ this._names = newNames;
+
+ // Copy sourcesContents of applied map.
+ aSourceMapConsumer.sources.forEach(function (sourceFile) {
+ var content = aSourceMapConsumer.sourceContentFor(sourceFile);
+ if (content) {
+ if (sourceRoot) {
+ sourceFile = util.relative(sourceRoot, sourceFile);
+ }
+ this.setSourceContent(sourceFile, content);
+ }
+ }, this);
+ };
+
+ /**
+ * A mapping can have one of the three levels of data:
+ *
+ * 1. Just the generated position.
+ * 2. The Generated position, original position, and original source.
+ * 3. Generated and original position, original source, as well as a name
+ * token.
+ *
+ * To maintain consistency, we validate that any new mapping being added falls
+ * in to one of these categories.
+ */
+ SourceMapGenerator.prototype._validateMapping =
+ function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
+ aName) {
+ if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
+ && aGenerated.line > 0 && aGenerated.column >= 0
+ && !aOriginal && !aSource && !aName) {
+ // Case 1.
+ return;
+ }
+ else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
+ && aOriginal && 'line' in aOriginal && 'column' in aOriginal
+ && aGenerated.line > 0 && aGenerated.column >= 0
+ && aOriginal.line > 0 && aOriginal.column >= 0
+ && aSource) {
+ // Cases 2 and 3.
+ return;
+ }
+ else {
+ throw new Error('Invalid mapping.');
+ }
+ };
+
+ function cmpLocation(loc1, loc2) {
+ var cmp = (loc1 && loc1.line) - (loc2 && loc2.line);
+ return cmp ? cmp : (loc1 && loc1.column) - (loc2 && loc2.column);
+ }
+
+ function strcmp(str1, str2) {
+ str1 = str1 || '';
+ str2 = str2 || '';
+ return (str1 > str2) - (str1 < str2);
+ }
+
+ function cmpMapping(mappingA, mappingB) {
+ return cmpLocation(mappingA.generated, mappingB.generated) ||
+ cmpLocation(mappingA.original, mappingB.original) ||
+ strcmp(mappingA.source, mappingB.source) ||
+ strcmp(mappingA.name, mappingB.name);
+ }
+
+ /**
+ * Serialize the accumulated mappings in to the stream of base 64 VLQs
+ * specified by the source map format.
+ */
+ SourceMapGenerator.prototype._serializeMappings =
+ function SourceMapGenerator_serializeMappings() {
+ var previousGeneratedColumn = 0;
+ var previousGeneratedLine = 1;
+ var previousOriginalColumn = 0;
+ var previousOriginalLine = 0;
+ var previousName = 0;
+ var previousSource = 0;
+ var result = '';
+ var mapping;
+
+ // The mappings must be guaranteed to be in sorted order before we start
+ // serializing them or else the generated line numbers (which are defined
+ // via the ';' separators) will be all messed up. Note: it might be more
+ // performant to maintain the sorting as we insert them, rather than as we
+ // serialize them, but the big O is the same either way.
+ this._mappings.sort(cmpMapping);
+
+ for (var i = 0, len = this._mappings.length; i < len; i++) {
+ mapping = this._mappings[i];
+
+ if (mapping.generated.line !== previousGeneratedLine) {
+ previousGeneratedColumn = 0;
+ while (mapping.generated.line !== previousGeneratedLine) {
+ result += ';';
+ previousGeneratedLine++;
+ }
+ }
+ else {
+ if (i > 0) {
+ if (!cmpMapping(mapping, this._mappings[i - 1])) {
+ continue;
+ }
+ result += ',';
+ }
+ }
+
+ result += base64VLQ.encode(mapping.generated.column
+ - previousGeneratedColumn);
+ previousGeneratedColumn = mapping.generated.column;
+
+ if (mapping.source && mapping.original) {
+ result += base64VLQ.encode(this._sources.indexOf(mapping.source)
+ - previousSource);
+ previousSource = this._sources.indexOf(mapping.source);
+
+ // lines are stored 0-based in SourceMap spec version 3
+ result += base64VLQ.encode(mapping.original.line - 1
+ - previousOriginalLine);
+ previousOriginalLine = mapping.original.line - 1;
+
+ result += base64VLQ.encode(mapping.original.column
+ - previousOriginalColumn);
+ previousOriginalColumn = mapping.original.column;
+
+ if (mapping.name) {
+ result += base64VLQ.encode(this._names.indexOf(mapping.name)
+ - previousName);
+ previousName = this._names.indexOf(mapping.name);
+ }
+ }
+ }
+
+ return result;
+ };
+
+ /**
+ * Externalize the source map.
+ */
+ SourceMapGenerator.prototype.toJSON =
+ function SourceMapGenerator_toJSON() {
+ var map = {
+ version: this._version,
+ file: this._file,
+ sources: this._sources.toArray(),
+ names: this._names.toArray(),
+ mappings: this._serializeMappings()
+ };
+ if (this._sourceRoot) {
+ map.sourceRoot = this._sourceRoot;
+ }
+ if (this._sourcesContents) {
+ map.sourcesContent = map.sources.map(function (source) {
+ if (map.sourceRoot) {
+ source = util.relative(map.sourceRoot, source);
+ }
+ return Object.prototype.hasOwnProperty.call(
+ this._sourcesContents, util.toSetString(source))
+ ? this._sourcesContents[util.toSetString(source)]
+ : null;
+ }, this);
+ }
+ return map;
+ };
+
+ /**
+ * Render the source map being generated to a string.
+ */
+ SourceMapGenerator.prototype.toString =
+ function SourceMapGenerator_toString() {
+ return JSON.stringify(this);
+ };
+
+ exports.SourceMapGenerator = SourceMapGenerator;
+
+});
+
+},{"./array-set":6,"./base64-vlq":7,"./util":13,"amdefine":14}],12:[function(require,module,exports){
+/* -*- Mode: js; js-indent-level: 2; -*- */
+/*
+ * Copyright 2011 Mozilla Foundation and contributors
+ * Licensed under the New BSD license. See LICENSE or:
+ * http://opensource.org/licenses/BSD-3-Clause
+ */
+if (typeof define !== 'function') {
+ var define = require('amdefine')(module, require);
+}
+define(function (require, exports, module) {
+
var SourceMapGenerator = require('./source-map-generator').SourceMapGenerator;
var util = require('./util');
/**
* SourceNodes provide a way to abstract over interpolating/concatenating
@@ -8897,11 +7779,11 @@
});
return node;
function addMappingWithCode(mapping, code) {
- if (mapping.source === undefined) {
+ if (mapping === null || mapping.source === undefined) {
node.add(code);
} else {
node.add(new SourceNode(mapping.originalLine,
mapping.originalColumn,
mapping.source,
@@ -9124,65 +8006,130 @@
exports.SourceNode = SourceNode;
});
-},{"./source-map-generator":12,"./util":17,"amdefine":19}],21:[function(require,module,exports){
-// shim for using process in browser
+},{"./source-map-generator":11,"./util":13,"amdefine":14}],13:[function(require,module,exports){
+/* -*- Mode: js; js-indent-level: 2; -*- */
+/*
+ * Copyright 2011 Mozilla Foundation and contributors
+ * Licensed under the New BSD license. See LICENSE or:
+ * http://opensource.org/licenses/BSD-3-Clause
+ */
+if (typeof define !== 'function') {
+ var define = require('amdefine')(module, require);
+}
+define(function (require, exports, module) {
-var process = module.exports = {};
+ /**
+ * This is a helper function for getting values from parameter/options
+ * objects.
+ *
+ * @param args The object we are extracting values from
+ * @param name The name of the property we are getting.
+ * @param defaultValue An optional value to return if the property is missing
+ * from the object. If this is not specified and the property is missing, an
+ * error will be thrown.
+ */
+ function getArg(aArgs, aName, aDefaultValue) {
+ if (aName in aArgs) {
+ return aArgs[aName];
+ } else if (arguments.length === 3) {
+ return aDefaultValue;
+ } else {
+ throw new Error('"' + aName + '" is a required argument.');
+ }
+ }
+ exports.getArg = getArg;
-process.nextTick = (function () {
- var canSetImmediate = typeof window !== 'undefined'
- && window.setImmediate;
- var canPost = typeof window !== 'undefined'
- && window.postMessage && window.addEventListener
- ;
+ var urlRegexp = /([\w+\-.]+):\/\/((\w+:\w+)@)?([\w.]+)?(:(\d+))?(\S+)?/;
- if (canSetImmediate) {
- return function (f) { return window.setImmediate(f) };
+ function urlParse(aUrl) {
+ var match = aUrl.match(urlRegexp);
+ if (!match) {
+ return null;
}
+ return {
+ scheme: match[1],
+ auth: match[3],
+ host: match[4],
+ port: match[6],
+ path: match[7]
+ };
+ }
+ exports.urlParse = urlParse;
- if (canPost) {
- var queue = [];
- window.addEventListener('message', function (ev) {
- if (ev.source === window && ev.data === 'process-tick') {
- ev.stopPropagation();
- if (queue.length > 0) {
- var fn = queue.shift();
- fn();
- }
- }
- }, true);
+ function urlGenerate(aParsedUrl) {
+ var url = aParsedUrl.scheme + "://";
+ if (aParsedUrl.auth) {
+ url += aParsedUrl.auth + "@"
+ }
+ if (aParsedUrl.host) {
+ url += aParsedUrl.host;
+ }
+ if (aParsedUrl.port) {
+ url += ":" + aParsedUrl.port
+ }
+ if (aParsedUrl.path) {
+ url += aParsedUrl.path;
+ }
+ return url;
+ }
+ exports.urlGenerate = urlGenerate;
- return function nextTick(fn) {
- queue.push(fn);
- window.postMessage('process-tick', '*');
- };
+ function join(aRoot, aPath) {
+ var url;
+
+ if (aPath.match(urlRegexp)) {
+ return aPath;
}
- return function nextTick(fn) {
- setTimeout(fn, 0);
- };
-})();
+ if (aPath.charAt(0) === '/' && (url = urlParse(aRoot))) {
+ url.path = aPath;
+ return urlGenerate(url);
+ }
-process.title = 'browser';
-process.browser = true;
-process.env = {};
-process.argv = [];
+ return aRoot.replace(/\/$/, '') + '/' + aPath;
+ }
+ exports.join = join;
-process.binding = function (name) {
- throw new Error('process.binding is not supported');
-}
+ /**
+ * Because behavior goes wacky when you set `__proto__` on objects, we
+ * have to prefix all the strings in our set with an arbitrary character.
+ *
+ * See https://github.com/mozilla/source-map/pull/31 and
+ * https://github.com/mozilla/source-map/issues/30
+ *
+ * @param String aStr
+ */
+ function toSetString(aStr) {
+ return '$' + aStr;
+ }
+ exports.toSetString = toSetString;
-// TODO(shtylman)
-process.cwd = function () { return '/' };
-process.chdir = function (dir) {
- throw new Error('process.chdir is not supported');
-};
+ function fromSetString(aStr) {
+ return aStr.substr(1);
+ }
+ exports.fromSetString = fromSetString;
-},{}],19:[function(require,module,exports){
+ function relative(aRoot, aPath) {
+ aRoot = aRoot.replace(/\/$/, '');
+
+ var url = urlParse(aRoot);
+ if (aPath.charAt(0) == "/" && url && url.path == "/") {
+ return aPath.slice(1);
+ }
+
+ return aPath.indexOf(aRoot + '/') === 0
+ ? aPath.substr(aRoot.length + 1)
+ : aPath;
+ }
+ exports.relative = relative;
+
+});
+
+},{"amdefine":14}],14:[function(require,module,exports){
(function(process,__filename){/** vim: et:ts=4:sw=4:sts=4
* @license amdefine 0.0.5 Copyright (c) 2011, The Dojo Foundation All Rights Reserved.
* Available via the MIT or new BSD license.
* see: http://github.com/jrburke/amdefine for details
*/
@@ -9480,676 +8427,1770 @@
}
module.exports = amdefine;
})(require("__browserify_process"),"/../node_modules/source-map/node_modules/amdefine/amdefine.js")
-},{"path":22,"__browserify_process":21}],16:[function(require,module,exports){
-/* -*- Mode: js; js-indent-level: 2; -*- */
-/*
- * Copyright 2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE or:
- * http://opensource.org/licenses/BSD-3-Clause
+},{"__browserify_process":3,"path":2}],15:[function(require,module,exports){
+/**
+ * Copyright 2013 Facebook, Inc.
*
- * Based on the Base 64 VLQ implementation in Closure Compiler:
- * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Copyright 2011 The Closure Compiler Authors. All rights reserved.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
-if (typeof define !== 'function') {
- var define = require('amdefine')(module);
+/* jshint browser: true */
+/* jslint evil: true */
+
+'use strict';
+var runScripts;
+
+var transform = require('./fbtransform/lib/transform').transform;
+var visitors = require('./fbtransform/visitors').transformVisitors;
+var transform = transform.bind(null, visitors.react);
+var docblock = require('./fbtransform/lib/docblock');
+
+var headEl = document.getElementsByTagName('head')[0];
+
+exports.transform = transform;
+
+exports.exec = function(code) {
+ return eval(transform(code));
+};
+
+var run = exports.run = function(code) {
+ var jsx = docblock.parseAsObject(docblock.extract(code)).jsx;
+
+ var functionBody = jsx ? transform(code).code : code;
+ var scriptEl = document.createElement('script');
+
+ scriptEl.innerHTML = functionBody;
+ headEl.appendChild(scriptEl);
+};
+
+if (typeof window === "undefined" || window === null) {
+ return;
}
-define(function (require, exports, module) {
- var base64 = require('./base64');
+var load = exports.load = function(url, callback) {
+ var xhr;
+ xhr = window.ActiveXObject ? new window.ActiveXObject('Microsoft.XMLHTTP')
+ : new XMLHttpRequest();
+ // Disable async since we need to execute scripts in the order they are in the
+ // DOM to mirror normal script loading.
+ xhr.open('GET', url, false);
+ if ('overrideMimeType' in xhr) {
+ xhr.overrideMimeType('text/plain');
+ }
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState === 4) {
+ if (xhr.status === 0 || xhr.status === 200) {
+ run(xhr.responseText);
+ } else {
+ throw new Error("Could not load " + url);
+ }
+ if (callback) {
+ return callback();
+ }
+ }
+ };
+ return xhr.send(null);
+};
- // A single base 64 digit can contain 6 bits of data. For the base 64 variable
- // length quantities we use in the source map spec, the first bit is the sign,
- // the next four bits are the actual value, and the 6th bit is the
- // continuation bit. The continuation bit tells us whether there are more
- // digits in this value following this digit.
- //
- // Continuation
- // | Sign
- // | |
- // V V
- // 101011
+runScripts = function() {
+ var scripts = document.getElementsByTagName('script');
+ scripts = Array.prototype.slice.call(scripts);
+ var jsxScripts = scripts.filter(function(script) {
+ return script.type === 'text/jsx';
+ });
- var VLQ_BASE_SHIFT = 5;
+ jsxScripts.forEach(function(script) {
+ if (script.src) {
+ load(script.src);
+ } else {
+ run(script.innerHTML);
+ }
+ });
+};
- // binary: 100000
- var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
+if (window.addEventListener) {
+ window.addEventListener('DOMContentLoaded', runScripts, false);
+} else {
+ window.attachEvent('onload', runScripts);
+}
- // binary: 011111
- var VLQ_BASE_MASK = VLQ_BASE - 1;
+},{"./fbtransform/lib/docblock":16,"./fbtransform/lib/transform":17,"./fbtransform/visitors":23}],16:[function(require,module,exports){
+/**
+ * Copyright 2013 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
- // binary: 100000
- var VLQ_CONTINUATION_BIT = VLQ_BASE;
+var docblockRe = /^\s*(\/\*\*(.|\n)*?\*\/)/;
+var ltrimRe = /^\s*/;
+/**
+ * @param {String} contents
+ * @return {String}
+ */
+function extract(contents) {
+ var match = contents.match(docblockRe);
+ if (match) {
+ return match[0].replace(ltrimRe, '') || '';
+ }
+ return '';
+}
- /**
- * Converts from a two-complement value to a value where the sign bit is
- * is placed in the least significant bit. For example, as decimals:
- * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
- * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
- */
- function toVLQSigned(aValue) {
- return aValue < 0
- ? ((-aValue) << 1) + 1
- : (aValue << 1) + 0;
+
+var commentStartRe = /^\/\*\*?/;
+var commentEndRe = /\*\/$/;
+var wsRe = /[\t ]+/g;
+var stringStartRe = /(\n|^) *\*/g;
+var multilineRe = /(?:^|\n) *(@[^\n]*?) *\n *([^@\n\s][^@\n]+?) *\n/g;
+var propertyRe = /(?:^|\n) *@(\S+) *([^\n]*)/g;
+
+/**
+ * @param {String} contents
+ * @return {Array}
+ */
+function parse(docblock) {
+ docblock = docblock
+ .replace(commentStartRe, '')
+ .replace(commentEndRe, '')
+ .replace(wsRe, ' ')
+ .replace(stringStartRe, '$1');
+
+ // Normalize multi-line directives
+ var prev = '';
+ while (prev != docblock) {
+ prev = docblock;
+ docblock = docblock.replace(multilineRe, "\n$1 $2\n");
}
+ docblock = docblock.trim();
- /**
- * Converts to a two-complement value from a value where the sign bit is
- * is placed in the least significant bit. For example, as decimals:
- * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1
- * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2
- */
- function fromVLQSigned(aValue) {
- var isNegative = (aValue & 1) === 1;
- var shifted = aValue >> 1;
- return isNegative
- ? -shifted
- : shifted;
+ var result = [];
+ var match;
+ while (match = propertyRe.exec(docblock)) {
+ result.push([match[1], match[2]]);
}
- /**
- * Returns the base 64 VLQ encoded value.
- */
- exports.encode = function base64VLQ_encode(aValue) {
- var encoded = "";
- var digit;
+ return result;
+}
- var vlq = toVLQSigned(aValue);
+/**
+ * Same as parse but returns an object of prop: value instead of array of paris
+ * If a property appers more than once the last one will be returned
+ *
+ * @param {String} contents
+ * @return {Object}
+ */
+function parseAsObject(docblock) {
+ var pairs = parse(docblock);
+ var result = {};
+ for (var i = 0; i < pairs.length; i++) {
+ result[pairs[i][0]] = pairs[i][1];
+ }
+ return result;
+}
- do {
- digit = vlq & VLQ_BASE_MASK;
- vlq >>>= VLQ_BASE_SHIFT;
- if (vlq > 0) {
- // There are still more digits in this value, so we must make sure the
- // continuation bit is marked.
- digit |= VLQ_CONTINUATION_BIT;
- }
- encoded += base64.encode(digit);
- } while (vlq > 0);
- return encoded;
- };
+exports.extract = extract;
+exports.parse = parse;
+exports.parseAsObject = parseAsObject;
- /**
- * Decodes the next base 64 VLQ value from the given string and returns the
- * value and the rest of the string.
- */
- exports.decode = function base64VLQ_decode(aStr) {
- var i = 0;
- var strLen = aStr.length;
- var result = 0;
- var shift = 0;
- var continuation, digit;
+},{}],17:[function(require,module,exports){
+(function(){/**
+ * Copyright 2013 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*global exports:true*/
+/*jslint node: true*/
+"use strict";
- do {
- if (i >= strLen) {
- throw new Error("Expected more digits in base 64 VLQ value.");
+/**
+ * Syntax transfomer for javascript. Takes the source in, spits the source
+ * out. Tries to maintain readability and preserve whitespace and line numbers
+ * where posssible.
+ *
+ * Support
+ * - ES6 class transformation + private property munging, see ./classes.js
+ * - React XHP style syntax transformations, see ./react.js
+ * - Bolt XHP style syntax transformations, see ./bolt.js
+ *
+ * The general flow is the following:
+ * - Parse the source with our customized esprima-parser
+ * https://github.com/voloko/esprima. We have to customize the parser to
+ * support non-standard XHP-style syntax. We parse the source range: true
+ * option that forces esprima to return positions in the source within
+ * resulting parse tree.
+ *
+ * - Traverse resulting syntax tree, trying to apply a set of visitors to each
+ * node. Each visitor should provide a .test() function that tests if the
+ * visitor can process a given node.
+ *
+ * - Visitor is responsible for code generation for a given syntax node.
+ * Generated code is stored in state.g.buffer that is passed to every
+ * visitor. It's up to the visitor to process the code the way it sees fit.
+ * All of the current visitors however use both the node and the original
+ * source to generate transformed code. They use nodes to generate new
+ * code and they copy the original source, preserving whitespace and comments,
+ * for the parts they don't care about.
+ */
+var esprima = require('esprima');
+
+var createState = require('./utils').createState;
+var catchup = require('./utils').catchup;
+
+/**
+ * @param {object} object
+ * @param {function} visitor
+ * @param {array} path
+ * @param {object} state
+ */
+function traverse(object, path, state) {
+ var key, child;
+
+ if (walker(traverse, object, path, state) === false) {
+ return;
+ }
+ path.unshift(object);
+ for (key in object) {
+ // skip obviously wrong attributes
+ if (key === 'range' || key === 'loc') {
+ continue;
+ }
+ if (object.hasOwnProperty(key)) {
+ child = object[key];
+ if (typeof child === 'object' && child !== null) {
+ child.range && catchup(child.range[0], state);
+ traverse(child, path, state);
+ child.range && catchup(child.range[1], state);
}
- digit = base64.decode(aStr.charAt(i++));
- continuation = !!(digit & VLQ_CONTINUATION_BIT);
- digit &= VLQ_BASE_MASK;
- result = result + (digit << shift);
- shift += VLQ_BASE_SHIFT;
- } while (continuation);
+ }
+ }
+ path.shift();
+}
+function walker(traverse, object, path, state) {
+ var visitors = state.g.visitors;
+ for (var i = 0; i < visitors.length; i++) {
+ if (visitors[i].test(object, path, state)) {
+ return visitors[i](traverse, object, path, state);
+ }
+ }
+}
+
+function runPass(source, visitors, options) {
+ var ast;
+ try {
+ ast = esprima.parse(source, { comment: true, loc: true, range: true });
+ } catch (e) {
+ e.message = 'Parse Error: ' + e.message;
+ throw e;
+ }
+ var state = createState(source, options);
+ state.g.originalProgramAST = ast;
+ state.g.visitors = visitors;
+
+ if (options.sourceMap) {
+ var SourceMapGenerator = require('source-map').SourceMapGenerator;
+ state.g.sourceMap = new SourceMapGenerator({ file: 'transformed.js' });
+ }
+ traverse(ast, [], state);
+ catchup(source.length, state);
+ return state;
+}
+
+/**
+ * Applies all available transformations to the source
+ * @param {array} visitors
+ * @param {string} source
+ * @param {?object} options
+ * @return {object}
+ */
+function transform(visitors, source, options) {
+ options = options || {};
+
+ var state = runPass(source, visitors, options);
+ var sourceMap = state.g.sourceMap;
+
+ if (sourceMap) {
return {
- value: fromVLQSigned(result),
- rest: aStr.slice(i)
+ sourceMap: sourceMap,
+ sourceMapFilename: options.filename || 'source.js',
+ code: state.g.buffer
};
- };
+ } else {
+ return {
+ code: state.g.buffer
+ };
+ }
+}
-});
-},{"./base64":23,"amdefine":19}],22:[function(require,module,exports){
-(function(process){function filter (xs, fn) {
- var res = [];
- for (var i = 0; i < xs.length; i++) {
- if (fn(xs[i], i, xs)) res.push(xs[i]);
+exports.transform = transform;
+
+})()
+},{"./utils":18,"esprima":4,"source-map":5}],18:[function(require,module,exports){
+(function(){/**
+ * Copyright 2013 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*global exports:true*/
+
+/**
+ * State represents the given parser state. It has a local and global parts.
+ * Global contains parser position, source, etc. Local contains scope based
+ * properties, like current class name. State should contain all the info
+ * required for transformation. It's the only mandatory object that is being
+ * passed to every function in transform chain.
+ *
+ * @param {String} source
+ * @param {Object} transformOptions
+ * @return {Object}
+ */
+function createState(source, transformOptions) {
+ return {
+ /**
+ * Name of the super class variable
+ * @type {String}
+ */
+ superVar: '',
+ /**
+ * Name of the enclosing class scope
+ * @type {String}
+ */
+ scopeName: '',
+ /**
+ * Global state (not affected by updateState)
+ * @type {Object}
+ */
+ g: {
+ /**
+ * A set of general options that transformations can consider while doing
+ * a transformation:
+ *
+ * - minify
+ * Specifies that transformation steps should do their best to minify
+ * the output source when possible. This is useful for places where
+ * minification optimizations are possible with higher-level context
+ * info than what jsxmin can provide.
+ *
+ * For example, the ES6 class transform will minify munged private
+ * variables if this flag is set.
+ */
+ opts: transformOptions,
+ /**
+ * Current position in the source code
+ * @type {Number}
+ */
+ position: 0,
+ /**
+ * Buffer containing the result
+ * @type {String}
+ */
+ buffer: '',
+ /**
+ * Indentation offset (only negative offset is supported now)
+ * @type {Number}
+ */
+ indentBy: 0,
+ /**
+ * Source that is being transformed
+ * @type {String}
+ */
+ source: source,
+
+ /**
+ * Cached parsed docblock (see getDocblock)
+ * @type {object}
+ */
+ docblock: null,
+
+ /**
+ * Whether the thing was used
+ * @type {Boolean}
+ */
+ tagNamespaceUsed: false,
+
+ /**
+ * If using bolt xjs transformation
+ * @type {Boolean}
+ */
+ isBolt: undefined,
+
+ /**
+ * Whether to record source map (expensive) or not
+ * @type {SourceMapGenerator|null}
+ */
+ sourceMap: null,
+
+ /**
+ * Filename of the file being processed. Will be returned as a source
+ * attribute in the source map
+ */
+ sourceMapFilename: 'source.js',
+
+ /**
+ * Only when source map is used: last line in the source for which
+ * source map was generated
+ * @type {Number}
+ */
+ sourceLine: 1,
+
+ /**
+ * Only when source map is used: last line in the buffer for which
+ * source map was generated
+ * @type {Number}
+ */
+ bufferLine: 1,
+
+ /**
+ * The top-level Program AST for the original file.
+ */
+ originalProgramAST: null,
+
+ sourceColumn: 0,
+ bufferColumn: 0
}
- return res;
+ };
}
-// resolves . and .. elements in a path array with directory names there
-// must be no slashes, empty elements, or device names (c:\) in the array
-// (so also no leading and trailing slashes - it does not distinguish
-// relative and absolute paths)
-function normalizeArray(parts, allowAboveRoot) {
- // if the path tries to go above the root, `up` ends up > 0
- var up = 0;
- for (var i = parts.length; i >= 0; i--) {
- var last = parts[i];
- if (last == '.') {
- parts.splice(i, 1);
- } else if (last === '..') {
- parts.splice(i, 1);
- up++;
- } else if (up) {
- parts.splice(i, 1);
- up--;
- }
+/**
+ * Updates a copy of a given state with "update" and returns an updated state.
+ *
+ * @param {Object} state
+ * @param {Object} update
+ * @return {Object}
+ */
+function updateState(state, update) {
+ return {
+ g: state.g,
+ superVar: update.superVar || state.superVar,
+ scopeName: update.scopeName || state.scopeName
+ };
+}
+
+/**
+ * Given a state fill the resulting buffer from the original source up to
+ * the end
+ * @param {Number} end
+ * @param {Object} state
+ * @param {Function?} contentTransformer Optional callback to transform newly
+ * added content.
+ */
+function catchup(end, state, contentTransformer) {
+ if (end < state.g.position) {
+ // cannot move backwards
+ return;
}
+ var source = state.g.source.substring(state.g.position, end);
+ var transformed = updateIndent(source, state);
+ if (state.g.sourceMap && transformed) {
+ // record where we are
+ state.g.sourceMap.addMapping({
+ generated: { line: state.g.bufferLine, column: state.g.bufferColumn },
+ original: { line: state.g.sourceLine, column: state.g.sourceColumn },
+ source: state.g.sourceMapFilename
+ });
- // if the path is allowed to go above the root, restore leading ..s
- if (allowAboveRoot) {
- for (; up--; up) {
- parts.unshift('..');
+ // record line breaks in transformed source
+ var sourceLines = source.split('\n');
+ var transformedLines = transformed.split('\n');
+ // Add line break mappings between last known mapping and the end of the
+ // added piece. So for the code piece
+ // (foo, bar);
+ // > var x = 2;
+ // > var b = 3;
+ // var c =
+ // only add lines marked with ">": 2, 3.
+ for (var i = 1; i < sourceLines.length - 1; i++) {
+ state.g.sourceMap.addMapping({
+ generated: { line: state.g.bufferLine, column: 0 },
+ original: { line: state.g.sourceLine, column: 0 },
+ source: state.g.sourceMapFilename
+ });
+ state.g.sourceLine++;
+ state.g.bufferLine++;
}
+ // offset for the last piece
+ if (sourceLines.length > 1) {
+ state.g.sourceLine++;
+ state.g.bufferLine++;
+ state.g.sourceColumn = 0;
+ state.g.bufferColumn = 0;
+ }
+ state.g.sourceColumn += sourceLines[sourceLines.length - 1].length;
+ state.g.bufferColumn +=
+ transformedLines[transformedLines.length - 1].length;
}
+ state.g.buffer +=
+ contentTransformer ? contentTransformer(transformed) : transformed;
+ state.g.position = end;
+}
- return parts;
+/**
+ * Applies `catchup` but passing in a function that removes any non-whitespace
+ * characters.
+ */
+var re = /(\S)/g;
+function stripNonWhite(value) {
+ return value.replace(re, function() {
+ return '';
+ });
}
+/**
+ * Catches up as `catchup` but turns each non-white character into a space.
+ */
+function catchupWhiteSpace(end, state) {
+ catchup(end, state, stripNonWhite);
+}
-// Regex to split a filename into [*, dir, basename, ext]
-// posix version
-var splitPathRe = /^(.+\/(?!$)|\/)?((?:.+?)?(\.[^.]*)?)$/;
+/**
+ * Same as catchup but does not touch the buffer
+ * @param {Number} end
+ * @param {Object} state
+ */
+function move(end, state) {
+ // move the internal cursors
+ if (state.g.sourceMap) {
+ if (end < state.g.position) {
+ state.g.position = 0;
+ state.g.sourceLine = 1;
+ state.g.sourceColumn = 0;
+ }
-// path.resolve([from ...], to)
-// posix version
-exports.resolve = function() {
-var resolvedPath = '',
- resolvedAbsolute = false;
+ var source = state.g.source.substring(state.g.position, end);
+ var sourceLines = source.split('\n');
+ if (sourceLines.length > 1) {
+ state.g.sourceLine += sourceLines.length - 1;
+ state.g.sourceColumn = 0;
+ }
+ state.g.sourceColumn += sourceLines[sourceLines.length - 1].length;
+ }
+ state.g.position = end;
+}
-for (var i = arguments.length; i >= -1 && !resolvedAbsolute; i--) {
- var path = (i >= 0)
- ? arguments[i]
- : process.cwd();
+/**
+ * Appends a string of text to the buffer
+ * @param {String} string
+ * @param {Object} state
+ */
+function append(string, state) {
+ if (state.g.sourceMap && string) {
+ state.g.sourceMap.addMapping({
+ generated: { line: state.g.bufferLine, column: state.g.bufferColumn },
+ original: { line: state.g.sourceLine, column: state.g.sourceColumn },
+ source: state.g.sourceMapFilename
+ });
+ var transformedLines = string.split('\n');
+ if (transformedLines.length > 1) {
+ state.g.bufferLine += transformedLines.length - 1;
+ state.g.bufferColumn = 0;
+ }
+ state.g.bufferColumn +=
+ transformedLines[transformedLines.length - 1].length;
+ }
+ state.g.buffer += string;
+}
- // Skip empty and invalid entries
- if (typeof path !== 'string' || !path) {
- continue;
+/**
+ * Update indent using state.indentBy property. Indent is measured in
+ * double spaces. Updates a single line only.
+ *
+ * @param {String} str
+ * @param {Object} state
+ * @return {String}
+ */
+function updateIndent(str, state) {
+ for (var i = 0; i < -state.g.indentBy; i++) {
+ str = str.replace(/(^|\n)( {2}|\t)/g, '$1');
}
+ return str;
+}
- resolvedPath = path + '/' + resolvedPath;
- resolvedAbsolute = path.charAt(0) === '/';
+/**
+ * Calculates indent from the beginning of the line until "start" or the first
+ * character before start.
+ * @example
+ * " foo.bar()"
+ * ^
+ * start
+ * indent will be 2
+ *
+ * @param {Number} start
+ * @param {Object} state
+ * @return {Number}
+ */
+function indentBefore(start, state) {
+ var end = start;
+ start = start - 1;
+
+ while (start > 0 && state.g.source[start] != '\n') {
+ if (!state.g.source[start].match(/[ \t]/)) {
+ end = start;
+ }
+ start--;
+ }
+ return state.g.source.substring(start + 1, end);
}
-// At this point the path should be resolved to a full absolute path, but
-// handle relative paths to be safe (might happen when process.cwd() fails)
+function getDocblock(state) {
+ if (!state.g.docblock) {
+ var docblock = require('./docblock');
+ state.g.docblock =
+ docblock.parseAsObject(docblock.extract(state.g.source));
+ }
+ return state.g.docblock;
+}
-// Normalize the path
-resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
- return !!p;
- }), !resolvedAbsolute).join('/');
+exports.catchup = catchup;
+exports.catchupWhiteSpace = catchupWhiteSpace;
+exports.append = append;
+exports.move = move;
+exports.updateIndent = updateIndent;
+exports.indentBefore = indentBefore;
+exports.updateState = updateState;
+exports.createState = createState;
+exports.getDocblock = getDocblock;
- return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
-};
+})()
+},{"./docblock":16}],19:[function(require,module,exports){
+(function(){/**
+ * Copyright 2013 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*global exports:true*/
+"use strict";
-// path.normalize(path)
-// posix version
-exports.normalize = function(path) {
-var isAbsolute = path.charAt(0) === '/',
- trailingSlash = path.slice(-1) === '/';
+/**
+ * Desugarizer for ES6 minimal class proposal. See
+ * http://wiki.ecmascript.org/doku.php?id=harmony:proposals
+ *
+ * Does not require any runtime. Preserves whitespace and comments.
+ * Supports a class declaration with methods, super calls and inheritance.
+ * Currently does not support for getters and setters, since there's a very
+ * low probability we're going to use them anytime soon.
+ *
+ * Additional features:
+ * - Any member with private name (the name with prefix _, such _name) inside
+ * the class's scope will be munged. This would will to eliminate the case
+ * of sub-class accidentally overriding the super-class's provate properties
+ * also discouage people from accessing private members that they should not
+ * access. However, quoted property names don't get munged.
+ *
+ * class SkinnedMesh extends require('THREE').Mesh {
+ *
+ * update(camera) {
+ * camera.code = 'iphone'
+ * super.update(camera);
+ * }
+ *
+ * /
+ * * @constructor
+ * /
+ * constructor(geometry, materials) {
+ * super(geometry, materials);
+ *
+ * super.update(1);
+ *
+ * this.identityMatrix = new THREE.Matrix4();
+ * this.bones = [];
+ * this.boneMatrices = [];
+ * this._name = 'foo';
+ * }
+ *
+ * /
+ * * some other code
+ * /
+ * readMore() {
+ *
+ * }
+ *
+ * _doSomething() {
+ *
+ * }
+ * }
+ *
+ * should be converted to
+ *
+ * var SkinnedMesh = (function() {
+ * var __super = require('parent').Mesh;
+ *
+ * /
+ * * @constructor
+ * /
+ * function SkinnedMesh(geometry, materials) {
+ * __super.call(this, geometry, materials);
+ *
+ * __super.prototype.update.call(this, 1);
+ *
+ * this.identityMatrix = new THREE.Matrix4();
+ * this.bones = [];
+ * this.boneMatrices = [];
+ * this.$SkinnedMesh_name = 'foo';
+ * }
+ * SkinnedMesh.prototype = Object.create(__super.prototype);
+ * SkinnedMesh.prototype.constructor = SkinnedMesh;
+ *
+ * /
+ * * @param camera
+ * /
+ * SkinnedMesh.prototype.update = function(camera) {
+ * camera.code = 'iphone'
+ * __super.prototype.update.call(this, camera);
+ * };
+ *
+ * SkinnedMesh.prototype.readMore = function() {
+ *
+ * };
+ *
+ * SkinnedMesh.prototype.$SkinnedMesh_doSomething = function() {
+ *
+ * };
+ *
+ * return SkinnedMesh;
+ * })();
+ *
+ */
+var Syntax = require('esprima').Syntax;
+var base62 = require('base62');
-// Normalize the path
-path = normalizeArray(filter(path.split('/'), function(p) {
- return !!p;
- }), !isAbsolute).join('/');
+var catchup = require('../lib/utils').catchup;
+var append = require('../lib/utils').append;
+var move = require('../lib/utils').move;
+var indentBefore = require('../lib/utils').indentBefore;
+var updateIndent = require('../lib/utils').updateIndent;
+var updateState = require('../lib/utils').updateState;
- if (!path && !isAbsolute) {
- path = '.';
+function findConstructorIndex(object) {
+ var classElements = object.body && object.body.body || [];
+ for (var i = 0; i < classElements.length; i++) {
+ if (classElements[i].type === Syntax.MethodDefinition &&
+ classElements[i].key.name === 'constructor') {
+ return i;
+ }
}
- if (path && trailingSlash) {
- path += '/';
+ return -1;
+}
+
+var _mungedSymbolMaps = {};
+function getMungedName(scopeName, name, minify) {
+ if (minify) {
+ if (!_mungedSymbolMaps[scopeName]) {
+ _mungedSymbolMaps[scopeName] = {
+ symbolMap: {},
+ identifierUUIDCounter: 0
+ };
+ }
+
+ var symbolMap = _mungedSymbolMaps[scopeName].symbolMap;
+ if (!symbolMap[name]) {
+ symbolMap[name] =
+ base62.encode(_mungedSymbolMaps[scopeName].identifierUUIDCounter);
+ _mungedSymbolMaps[scopeName].identifierUUIDCounter++;
+ }
+ name = symbolMap[name];
}
-
- return (isAbsolute ? '/' : '') + path;
-};
+ return '$' + scopeName + name;
+}
+function shouldMungeName(scopeName, name, state) {
+ // only run when @preventMunge is not present in the docblock
+ if (state.g.preventMunge === undefined) {
+ var docblock = require('../lib/docblock');
+ state.g.preventMunge = docblock.parseAsObject(
+ docblock.extract(state.g.source)).preventMunge !== undefined;
+ }
+ // Starts with only a single underscore (i.e. don't count double-underscores)
+ return !state.g.preventMunge && scopeName ? /^_(?!_)/.test(name) : false;
+}
-// posix version
-exports.join = function() {
- var paths = Array.prototype.slice.call(arguments, 0);
- return exports.normalize(filter(paths, function(p, index) {
- return p && typeof p === 'string';
- }).join('/'));
-};
+function getProtoOfPrototypeVariableName(superVar) {
+ return superVar + 'ProtoOfPrototype';
+}
-exports.dirname = function(path) {
- var dir = splitPathRe.exec(path)[1] || '';
- var isWindows = false;
- if (!dir) {
- // No dirname
- return '.';
- } else if (dir.length === 1 ||
- (isWindows && dir.length <= 3 && dir.charAt(1) === ':')) {
- // It is just a slash or a drive letter with a slash
- return dir;
- } else {
- // It is a full dirname, strip trailing slash
- return dir.substring(0, dir.length - 1);
+function getSuperKeyName(superVar) {
+ return superVar + 'Key';
+}
+
+function getSuperProtoOfPrototypeVariable(superVariableName, indent) {
+ var string = (indent +
+ 'var $proto = $superName && $superName.prototype ? ' +
+ '$superName.prototype : $superName;\n'
+ ).replace(/\$proto/g, getProtoOfPrototypeVariableName(superVariableName))
+ .replace(/\$superName/g, superVariableName);
+ return string;
+}
+
+
+function getInheritanceSetup(superClassToken, className, indent, superName) {
+ var string = '';
+ if (superClassToken) {
+ string += getStaticMethodsOnConstructorSetup(className, indent, superName);
+ string += getPrototypeOnConstructorSetup(className, indent, superName);
+ string += getConstructorPropertySetup(className, indent);
}
-};
+ return string;
+}
+function getStaticMethodsOnConstructorSetup(className, indent, superName) {
+ var string = ( indent +
+ 'for (var $keyName in $superName) {\n' + indent +
+ ' if ($superName.hasOwnProperty($keyName)) {\n' + indent +
+ ' $className[$keyName] = $superName[$keyName];\n' + indent +
+ ' }\n' + indent +
+ '}\n')
+ .replace(/\$className/g, className)
+ .replace(/\$keyName/g, getSuperKeyName(superName))
+ .replace(/\$superName/g, superName);
+ return string;
+}
-exports.basename = function(path, ext) {
- var f = splitPathRe.exec(path)[2] || '';
- // TODO: make this comparison case-insensitive on windows?
- if (ext && f.substr(-1 * ext.length) === ext) {
- f = f.substr(0, f.length - ext.length);
+function getPrototypeOnConstructorSetup(className, indent, superName) {
+ var string = ( indent +
+ '$className.prototype = Object.create($protoPrototype);\n')
+ .replace(/\$protoPrototype/g, getProtoOfPrototypeVariableName(superName))
+ .replace(/\$className/g, className);
+ return string;
+}
+
+function getConstructorPropertySetup(className, indent) {
+ var string = ( indent +
+ '$className.prototype.constructor = $className;\n')
+ .replace(/\$className/g, className);
+
+ return string;
+}
+
+function getSuperConstructorSetup(superClassToken, indent, superName) {
+ if (!superClassToken) return '';
+ var string = ( '\n' + indent +
+ ' if ($superName && $superName.prototype) {\n' + indent +
+ ' $superName.apply(this, arguments);\n' + indent +
+ ' }\n' + indent)
+ .replace(/\$superName/g, superName);
+ return string;
+}
+
+function getMemberFunctionCall(superVar, propertyName, superArgs) {
+ var string = (
+ '$superPrototype.$propertyName.call($superArguments)')
+ .replace(/\$superPrototype/g, getProtoOfPrototypeVariableName(superVar))
+ .replace(/\$propertyName/g, propertyName)
+ .replace(/\$superArguments/g, superArgs);
+ return string;
+}
+
+function getCallParams(classElement, state) {
+ var params = classElement.value.params;
+ if (!params.length) {
+ return '';
}
- return f;
-};
+ return state.g.source.substring(
+ params[0].range[0],
+ params[params.length - 1].range[1]);
+}
+function getSuperArguments(callExpression, state) {
+ var args = callExpression.arguments;
+ if (!args.length) {
+ return 'this';
+ }
+ return 'this, ' + state.g.source.substring(
+ args[0].range[0],
+ args[args.length - 1].range[1]);
+}
-exports.extname = function(path) {
- return splitPathRe.exec(path)[3] || '';
-};
+// The seed is used to generate the name for an anonymous class,
+// and this seed should be unique per browser's session.
+// The value of the seed looks like this: 1229588505.2969012.
+var classIDSeed = Date.now() % (60 * 60 * 1000) + Math.random();
-exports.relative = function(from, to) {
- from = exports.resolve(from).substr(1);
- to = exports.resolve(to).substr(1);
+/**
+ * Generates a name for an anonymous class. The generated value looks like
+ * this: "Classkc6pcn_mniza1yvi"
+ * @param {String} scopeName
+ * @return {string} the scope name for Anonymous Class
+ */
+function generateAnonymousClassName(scopeName) {
+ classIDSeed++;
+ return 'Class' +
+ (classIDSeed).toString(36).replace('.', '_') +
+ (scopeName || '');
+}
- function trim(arr) {
- var start = 0;
- for (; start < arr.length; start++) {
- if (arr[start] !== '') break;
- }
+function renderMethods(traverse, object, name, path, state) {
+ var classElements = object.body && object.body.body || [];
- var end = arr.length - 1;
- for (; end >= 0; end--) {
- if (arr[end] !== '') break;
- }
+ move(object.body.range[0] + 1, state);
+ for (var i = 0; i < classElements.length; i++) {
+ if (classElements[i].key.name !== 'constructor') {
+ catchup(classElements[i].range[0], state);
- if (start > end) return [];
- return arr.slice(start, end - start + 1);
+ var memberName = classElements[i].key.name;
+ if (shouldMungeName(state.scopeName, memberName, state)) {
+ memberName = getMungedName(
+ state.scopeName,
+ memberName,
+ state.g.opts.minify
+ );
+ }
+
+ var prototypeOrStatic;
+ if (classElements[i]['static']) {
+ prototypeOrStatic = '';
+ } else {
+ prototypeOrStatic = 'prototype.';
+ }
+
+ append(name + '.' + prototypeOrStatic + memberName + ' = ', state);
+ renderMethod(traverse, classElements[i], null, path, state);
+ append(';', state);
+ }
+ move(classElements[i].range[1], state);
}
+ if (classElements.length) {
+ append('\n', state);
+ }
+ move(object.range[1], state);
+}
- var fromParts = trim(from.split('/'));
- var toParts = trim(to.split('/'));
+function renderMethod(traverse, method, name, path, state) {
+ append(name ? 'function ' + name + '(' : 'function(', state);
+ append(getCallParams(method, state) + ') {', state);
+ move(method.value.body.range[0] + 1, state);
+ traverse(method.value.body, path, state);
+ catchup(method.value.body.range[1] - 1, state);
+ append('}', state);
+}
- var length = Math.min(fromParts.length, toParts.length);
- var samePartsLength = length;
- for (var i = 0; i < length; i++) {
- if (fromParts[i] !== toParts[i]) {
- samePartsLength = i;
- break;
+function renderSuperClass(traverse, superClass, path, state) {
+ append('var ' + state.superVar + ' = ', state);
+ move(superClass.range[0], state);
+ traverse(superClass, path, state);
+ catchup(superClass.range[1], state);
+ append(';\n', state);
+}
+
+function renderConstructor(traverse, object, name, indent, path, state) {
+ var classElements = object.body && object.body.body || [];
+ var constructorIndex = findConstructorIndex(object);
+ var constructor = constructorIndex === -1 ?
+ null :
+ classElements[constructorIndex];
+ if (constructor) {
+ move(constructorIndex === 0 ?
+ object.body.range[0] + 1 :
+ classElements[constructorIndex - 1].range[1], state);
+ catchup(constructor.range[0], state);
+ renderMethod(traverse, constructor, name, path, state);
+ append('\n', state);
+ } else {
+ if (object.superClass) {
+ append('\n' + indent, state);
}
+ append('function ', state);
+ if (object.id) {
+ move(object.id.range[0], state);
+ }
+ append(name, state);
+ if (object.id) {
+ move(object.id.range[1], state);
+ }
+ append('(){ ', state);
+ if (object.body) {
+ move(object.body.range[0], state);
+ }
+ append(getSuperConstructorSetup(
+ object.superClass,
+ indent,
+ state.superVar), state);
+ append('}\n', state);
}
+}
- var outputParts = [];
- for (var i = samePartsLength; i < fromParts.length; i++) {
- outputParts.push('..');
+var superId = 0;
+function renderClassBody(traverse, object, path, state) {
+ var name = object.id ? object.id.name : 'constructor';
+ var superClass = object.superClass;
+ var indent = updateIndent(
+ indentBefore(object.range[0], state) + ' ',
+ state);
+
+ state = updateState(
+ state,
+ {
+ scopeName: object.id ? object.id.name :
+ generateAnonymousClassName(state.scopeName),
+ superVar: superClass ? '__super' + superId++ : ''
+ });
+
+ // super class
+ if (superClass) {
+ append(indent, state);
+ renderSuperClass(traverse, superClass, path, state);
+ append(getSuperProtoOfPrototypeVariable(state.superVar, indent), state);
}
- outputParts = outputParts.concat(toParts.slice(samePartsLength));
+ renderConstructor(traverse, object, name, indent, path, state);
+ append(getInheritanceSetup(superClass, name, indent, state.superVar), state);
+ renderMethods(traverse, object, name, path, state);
+}
- return outputParts.join('/');
+
+/**
+ * @public
+ */
+function visitClassExpression(traverse, object, path, state) {
+ var indent = updateIndent(
+ indentBefore(object.range[0], state) + ' ',
+ state);
+ var name = object.id ? object.id.name : 'constructor';
+
+ append('(function() {\n', state);
+ renderClassBody(traverse, object, path, state);
+ append(indent + 'return ' + name + ';\n', state);
+ append(indent.substring(0, indent.length - 2) + '})()', state);
+ return false
+}
+
+visitClassExpression.test = function(object, path, state) {
+ return object.type === Syntax.ClassExpression;
};
-})(require("__browserify_process"))
-},{"__browserify_process":21}],17:[function(require,module,exports){
-/* -*- Mode: js; js-indent-level: 2; -*- */
-/*
- * Copyright 2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE or:
- * http://opensource.org/licenses/BSD-3-Clause
+/**
+ * @public
*/
-if (typeof define !== 'function') {
- var define = require('amdefine')(module);
+function visitClassDeclaration(traverse, object, path, state) {
+ state.g.indentBy--;
+ renderClassBody(traverse, object, path, state);
+ state.g.indentBy++;
+ return false;
}
-define(function (require, exports, module) {
- /**
- * This is a helper function for getting values from parameter/options
- * objects.
- *
- * @param args The object we are extracting values from
- * @param name The name of the property we are getting.
- * @param defaultValue An optional value to return if the property is missing
- * from the object. If this is not specified and the property is missing, an
- * error will be thrown.
- */
- function getArg(aArgs, aName, aDefaultValue) {
- if (aName in aArgs) {
- return aArgs[aName];
- } else if (arguments.length === 3) {
- return aDefaultValue;
+visitClassDeclaration.test = function(object, path, state) {
+ return object.type === Syntax.ClassDeclaration;
+};
+
+
+/**
+ * @public
+ */
+function visitSuperCall(traverse, object, path, state) {
+ if (path[0].type === Syntax.CallExpression) {
+ append(state.superVar +
+ '.call(' + getSuperArguments(path[0], state) + ')', state);
+ move(path[0].range[1], state);
+ } else if (path[0].type === Syntax.MemberExpression) {
+ append(getMemberFunctionCall(
+ state.superVar,
+ path[0].property.name,
+ getSuperArguments(path[1], state)), state);
+ move(path[1].range[1], state);
+ }
+ return false;
+}
+
+visitSuperCall.test = function(object, path, state) {
+ return state.superVar && object.type === Syntax.Identifier &&
+ object.name === 'super';
+};
+
+/**
+ * @public
+ */
+function visitPrivateProperty(traverse, object, path, state) {
+ var type = path[0] ? path[0].type : null;
+ if (type !== Syntax.Property) {
+ if (type === Syntax.MemberExpression) {
+ type = path[0].object ? path[0].object.type : null;
+ if (type === Syntax.Identifier &&
+ path[0].object.range[0] === object.range[0]) {
+ // Identifier is a variable that appears "private".
+ return;
+ }
} else {
- throw new Error('"' + aName + '" is a required argument.');
+ // Other syntax that are neither Property nor MemberExpression.
+ return;
}
}
- exports.getArg = getArg;
- var urlRegexp = /([\w+\-.]+):\/\/((\w+:\w+)@)?([\w.]+)?(:(\d+))?(\S+)?/;
+ var oldName = object.name;
+ var newName = getMungedName(
+ state.scopeName,
+ oldName,
+ state.g.opts.minify
+ );
+ append(newName, state);
+ move(object.range[1], state);
+}
- function urlParse(aUrl) {
- var match = aUrl.match(urlRegexp);
- if (!match) {
- return null;
+visitPrivateProperty.test = function(object, path, state) {
+ return object.type === Syntax.Identifier &&
+ shouldMungeName(state.scopeName, object.name, state);
+};
+
+
+exports.visitClassDeclaration = visitClassDeclaration;
+exports.visitClassExpression = visitClassExpression;
+exports.visitSuperCall = visitSuperCall;
+exports.visitPrivateProperty = visitPrivateProperty;
+
+})()
+},{"../lib/docblock":16,"../lib/utils":18,"base62":1,"esprima":4}],20:[function(require,module,exports){
+(function(){/**
+ * Copyright 2013 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*global exports:true*/
+"use strict";
+
+var Syntax = require('esprima').Syntax;
+
+var catchup = require('../lib/utils').catchup;
+var append = require('../lib/utils').append;
+var move = require('../lib/utils').move;
+var getDocblock = require('../lib/utils').getDocblock;
+
+var FALLBACK_TAGS = require('./xjs').knownTags;
+var renderXJSExpressionContainer =
+ require('./xjs').renderXJSExpressionContainer;
+var renderXJSLiteral = require('./xjs').renderXJSLiteral;
+var quoteAttrName = require('./xjs').quoteAttrName;
+
+/**
+ * Customized desugar processor.
+ *
+ * Currently: (Somewhat tailored to React)
+ * <X> </X> => X(null, null)
+ * <X prop="1" /> => X({prop: '1'}, null)
+ * <X prop="2"><Y /></X> => X({prop:'2'}, Y(null, null))
+ * <X prop="2"><Y /><Z /></X> => X({prop:'2'}, [Y(null, null), Z(null, null)])
+ *
+ * Exceptions to the simple rules above:
+ * if a property is named "class" it will be changed to "className" in the
+ * javascript since "class" is not a valid object key in javascript.
+ */
+
+var JSX_ATTRIBUTE_RENAMES = {
+ 'class': 'className',
+ cxName: 'className'
+};
+
+var JSX_ATTRIBUTE_TRANSFORMS = {
+ cxName: function(attr) {
+ if (attr.value.type !== Syntax.Literal) {
+ throw new Error("cx only accepts a string literal");
+ } else {
+ var classNames = attr.value.value.split(/\s+/g);
+ return 'cx(' + classNames.map(JSON.stringify).join(',') + ')';
}
- return {
- scheme: match[1],
- auth: match[3],
- host: match[4],
- port: match[6],
- path: match[7]
- };
}
- exports.urlParse = urlParse;
+};
- function urlGenerate(aParsedUrl) {
- var url = aParsedUrl.scheme + "://";
- if (aParsedUrl.auth) {
- url += aParsedUrl.auth + "@"
+function visitReactTag(traverse, object, path, state) {
+ var jsxObjIdent = getDocblock(state).jsx;
+
+ catchup(object.openingElement.range[0], state);
+
+ if (object.name.namespace) {
+ throw new Error(
+ 'Namespace tags are not supported. ReactJSX is not XML.');
+ }
+
+ var isFallbackTag = FALLBACK_TAGS[object.name.name];
+ append(
+ (isFallbackTag ? jsxObjIdent + '.' : '') + (object.name.name) + '(',
+ state
+ );
+
+ move(object.name.range[1], state);
+
+ var childrenToRender = object.children.filter(function(child) {
+ return !(child.type === Syntax.Literal && !child.value.match(/\S/));
+ });
+
+ // if we don't have any attributes, pass in null
+ if (object.attributes.length === 0) {
+ append('null', state);
+ }
+
+ // write attributes
+ object.attributes.forEach(function(attr, index) {
+ catchup(attr.range[0], state);
+ if (attr.name.namespace) {
+ throw new Error(
+ 'Namespace attributes are not supported. ReactJSX is not XML.');
}
- if (aParsedUrl.host) {
- url += aParsedUrl.host;
+ var name = JSX_ATTRIBUTE_RENAMES[attr.name.name] || attr.name.name;
+ var isFirst = index === 0;
+ var isLast = index === object.attributes.length - 1;
+
+ if (isFirst) {
+ append('{', state);
}
- if (aParsedUrl.port) {
- url += ":" + aParsedUrl.port
- }
- if (aParsedUrl.path) {
- url += aParsedUrl.path;
- }
- return url;
- }
- exports.urlGenerate = urlGenerate;
- function join(aRoot, aPath) {
- var url;
+ append(quoteAttrName(name), state);
+ append(':', state);
- if (aPath.match(urlRegexp)) {
- return aPath;
+ if (!attr.value) {
+ state.g.buffer += 'true';
+ state.g.position = attr.name.range[1];
+ if (!isLast) {
+ append(',', state);
+ }
+ } else if (JSX_ATTRIBUTE_TRANSFORMS[attr.name.name]) {
+ move(attr.value.range[0], state);
+ append(JSX_ATTRIBUTE_TRANSFORMS[attr.name.name](attr), state);
+ move(attr.value.range[1], state);
+ if (!isLast) {
+ append(',', state);
+ }
+ } else if (attr.value.type === Syntax.Literal) {
+ move(attr.value.range[0], state);
+ renderXJSLiteral(attr.value, isLast, state);
+ } else {
+ move(attr.value.range[0], state);
+ renderXJSExpressionContainer(traverse, attr.value, isLast, path, state);
}
- if (aPath.charAt(0) === '/' && (url = urlParse(aRoot))) {
- url.path = aPath;
- return urlGenerate(url);
+ if (isLast) {
+ append('}', state);
}
- return aRoot.replace(/\/$/, '') + '/' + aPath;
+ catchup(attr.range[1], state);
+ });
+
+ if (!object.selfClosing) {
+ catchup(object.openingElement.range[1] - 1, state);
+ move(object.openingElement.range[1], state);
}
- exports.join = join;
- /**
- * Because behavior goes wacky when you set `__proto__` on objects, we
- * have to prefix all the strings in our set with an arbitrary character.
- *
- * See https://github.com/mozilla/source-map/pull/31 and
- * https://github.com/mozilla/source-map/issues/30
- *
- * @param String aStr
- */
- function toSetString(aStr) {
- return '$' + aStr;
+ // filter out whitespace
+ if (childrenToRender.length > 0) {
+ append(', ', state);
+
+ object.children.forEach(function(child) {
+ if (child.type === Syntax.Literal && !child.value.match(/\S/)) {
+ return;
+ }
+ catchup(child.range[0], state);
+
+ var isLast = child === childrenToRender[childrenToRender.length - 1];
+
+ if (child.type === Syntax.Literal) {
+ renderXJSLiteral(child, isLast, state);
+ } else if (child.type === Syntax.XJSExpressionContainer) {
+ renderXJSExpressionContainer(traverse, child, isLast, path, state);
+ } else {
+ traverse(child, path, state);
+ if (!isLast) {
+ append(',', state);
+ state.g.buffer = state.g.buffer.replace(/(\s*),$/, ',$1');
+ }
+ }
+
+ catchup(child.range[1], state);
+ });
}
- exports.toSetString = toSetString;
- function fromSetString(aStr) {
- return aStr.substr(1);
+ if (object.selfClosing) {
+ // everything up to />
+ catchup(object.openingElement.range[1] - 2, state);
+ move(object.openingElement.range[1], state);
+ } else {
+ // everything up to </ sdflksjfd>
+ catchup(object.closingElement.range[0], state);
+ move(object.closingElement.range[1], state);
}
- exports.fromSetString = fromSetString;
- function relative(aRoot, aPath) {
- aRoot = aRoot.replace(/\/$/, '');
+ append(')', state);
+ return false;
+}
- var url = urlParse(aRoot);
- if (aPath.charAt(0) == "/" && url && url.path == "/") {
- return aPath.slice(1);
- }
+visitReactTag.test = function(object, path, state) {
+ // only run react when react @jsx namespace is specified in docblock
+ var jsx = getDocblock(state).jsx;
+ return object.type === Syntax.XJSElement && jsx && jsx.length;
+};
- return aPath.indexOf(aRoot + '/') === 0
- ? aPath.substr(aRoot.length + 1)
- : aPath;
- }
- exports.relative = relative;
+exports.visitReactTag = visitReactTag;
-});
+})()
+},{"../lib/utils":18,"./xjs":22,"esprima":4}],21:[function(require,module,exports){
+(function(){/**
+ * Copyright 2013 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*global exports:true*/
+"use strict";
-},{"amdefine":19}],18:[function(require,module,exports){
-/* -*- Mode: js; js-indent-level: 2; -*- */
-/*
- * Copyright 2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE or:
- * http://opensource.org/licenses/BSD-3-Clause
+var Syntax = require('esprima').Syntax;
+var catchup = require('../lib/utils').catchup;
+var append = require('../lib/utils').append;
+var getDocblock = require('../lib/utils').getDocblock;
+
+/**
+ * Transforms the following:
+ *
+ * var MyComponent = React.createClass({
+ * render: ...
+ * });
+ *
+ * into:
+ *
+ * var MyComponent = React.createClass({
+ * displayName: 'MyComponent',
+ * render: ...
+ * });
*/
-if (typeof define !== 'function') {
- var define = require('amdefine')(module);
+function visitReactDisplayName(traverse, object, path, state) {
+ if (object.id.type === Syntax.Identifier &&
+ object.init &&
+ object.init.type === Syntax.CallExpression &&
+ object.init.callee.type === Syntax.MemberExpression &&
+ object.init.callee.object.type === Syntax.Identifier &&
+ object.init.callee.object.name === 'React' &&
+ object.init.callee.property.type === Syntax.Identifier &&
+ object.init.callee.property.name === 'createClass' &&
+ object.init['arguments'].length === 1 &&
+ object.init['arguments'][0].type === Syntax.ObjectExpression) {
+
+ var displayName = object.id.name;
+ catchup(object.init['arguments'][0].range[0] + 1, state);
+ append("displayName: '" + displayName + "',", state);
+ }
}
-define(function (require, exports, module) {
- var util = require('./util');
+/**
+ * Will only run on @jsx files for now.
+ */
+visitReactDisplayName.test = function(object, path, state) {
+ return object.type === Syntax.VariableDeclarator && !!getDocblock(state).jsx;
+};
- /**
- * A data structure which is a combination of an array and a set. Adding a new
- * member is O(1), testing for membership is O(1), and finding the index of an
- * element is O(1). Removing elements from the set is not supported. Only
- * strings are supported for membership.
- */
- function ArraySet() {
- this._array = [];
- this._set = {};
- }
+exports.visitReactDisplayName = visitReactDisplayName;
- /**
- * Static method for creating ArraySet instances from an existing array.
- */
- ArraySet.fromArray = function ArraySet_fromArray(aArray) {
- var set = new ArraySet();
- for (var i = 0, len = aArray.length; i < len; i++) {
- set.add(aArray[i]);
- }
- return set;
- };
+})()
+},{"../lib/utils":18,"esprima":4}],22:[function(require,module,exports){
+(function(){/**
+ * Copyright 2013 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*global exports:true*/
+"use strict";
+var append = require('../lib/utils').append;
+var catchup = require('../lib/utils').catchup;
+var move = require('../lib/utils').move;
+var Syntax = require('esprima').Syntax;
- /**
- * Add the given string to this set.
- *
- * @param String aStr
- */
- ArraySet.prototype.add = function ArraySet_add(aStr) {
- if (this.has(aStr)) {
- // Already a member; nothing to do.
- return;
- }
- var idx = this._array.length;
- this._array.push(aStr);
- this._set[util.toSetString(aStr)] = idx;
- };
+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,
+ 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,
+ link: true,
+ main: true,
+ map: true,
+ mark: true,
+ marquee: true,
+ 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,
+ polyline: true,
+ pre: true,
+ progress: true,
+ q: 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,
+ 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,
+ u: true,
+ ul: true,
+ 'var': true,
+ video: true,
+ wbr: true
+};
- /**
- * Is the given string a member of this set?
- *
- * @param String aStr
- */
- ArraySet.prototype.has = function ArraySet_has(aStr) {
- return Object.prototype.hasOwnProperty.call(this._set,
- util.toSetString(aStr));
- };
+function safeTrim(string) {
+ return string.replace(/^[ \t]+/, '').replace(/[ \t]+$/, '');
+}
- /**
- * What is the index of the given string in the array?
- *
- * @param String aStr
- */
- ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
- if (this.has(aStr)) {
- return this._set[util.toSetString(aStr)];
- }
- throw new Error('"' + aStr + '" is not in the set.');
- };
+// Replace all trailing whitespace characters with a single space character
+function trimWithSingleSpace(string) {
+ return string.replace(/^[ \t\xA0]{2,}/, ' ').
+ replace(/[ \t\xA0]{2,}$/, ' ').replace(/^\s+$/, '');
+}
- /**
- * What is the element at the given index?
- *
- * @param Number aIdx
- */
- ArraySet.prototype.at = function ArraySet_at(aIdx) {
- if (aIdx >= 0 && aIdx < this._array.length) {
- return this._array[aIdx];
+/**
+ * Special handling for multiline string literals
+ * print lines:
+ *
+ * line
+ * line
+ *
+ * as:
+ *
+ * "line "+
+ * "line"
+ */
+function renderXJSLiteral(object, isLast, state, start, end) {
+ /** Added blank check filtering and triming*/
+ var trimmedChildValue = safeTrim(object.value);
+
+ if (trimmedChildValue) {
+ // head whitespace
+ append(object.value.match(/^[\t ]*/)[0], state);
+ if (start) {
+ append(start, state);
}
- throw new Error('No element indexed by ' + aIdx);
- };
- /**
- * Returns the array representation of this set (which has the proper indices
- * indicated by indexOf). Note that this is a copy of the internal array used
- * for storing the members so that no one can mess with internal state.
- */
- ArraySet.prototype.toArray = function ArraySet_toArray() {
- return this._array.slice();
- };
+ var trimmedChildValueWithSpace = trimWithSingleSpace(object.value);
- exports.ArraySet = ArraySet;
+ /**
+ */
+ var initialLines = trimmedChildValue.split(/\r\n|\n|\r/);
-});
+ var lines = initialLines.filter(function(line) {
+ return safeTrim(line).length > 0;
+ });
-},{"./util":17,"amdefine":19}],20:[function(require,module,exports){
-/* -*- Mode: js; js-indent-level: 2; -*- */
-/*
- * Copyright 2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE or:
- * http://opensource.org/licenses/BSD-3-Clause
- */
-if (typeof define !== 'function') {
- var define = require('amdefine')(module);
-}
-define(function (require, exports, module) {
+ var hasInitialNewLine = initialLines[0] !== lines[0];
+ var hasFinalNewLine =
+ initialLines[initialLines.length - 1] !== lines[lines.length - 1];
- /**
- * Recursive implementation of binary search.
- *
- * @param aLow Indices here and lower do not contain the needle.
- * @param aHigh Indices here and higher do not contain the needle.
- * @param aNeedle The element being searched for.
- * @param aHaystack The non-empty array being searched.
- * @param aCompare Function which takes two elements and returns -1, 0, or 1.
- */
- function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare) {
- // This function terminates when one of the following is true:
- //
- // 1. We find the exact element we are looking for.
- //
- // 2. We did not find the exact element, but we can return the next
- // closest element that is less than that element.
- //
- // 3. We did not find the exact element, and there is no next-closest
- // element which is less than the one we are searching for, so we
- // return null.
- var mid = Math.floor((aHigh - aLow) / 2) + aLow;
- var cmp = aCompare(aNeedle, aHaystack[mid]);
- if (cmp === 0) {
- // Found the element we are looking for.
- return aHaystack[mid];
- }
- else if (cmp > 0) {
- // aHaystack[mid] is greater than our needle.
- if (aHigh - mid > 1) {
- // The element is in the upper half.
- return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare);
+ var numLines = lines.length;
+ lines.forEach(function (line, ii) {
+ var lastLine = ii === numLines - 1;
+ var trimmedLine = safeTrim(line);
+ if (trimmedLine === '' && !lastLine) {
+ append(line, state);
+ } else {
+ var preString = '';
+ var postString = '';
+ var leading = '';
+
+ if (ii === 0) {
+ if (hasInitialNewLine) {
+ preString = ' ';
+ leading = '\n';
+ }
+ if (trimmedChildValueWithSpace.substring(0, 1) === ' ') {
+ // If this is the first line, and the original content starts with
+ // whitespace, place a single space at the beginning.
+ preString = ' ';
+ }
+ } else {
+ leading = line.match(/^[ \t]*/)[0];
+ }
+ if (!lastLine || trimmedChildValueWithSpace.substr(
+ trimmedChildValueWithSpace.length - 1, 1) === ' ' ||
+ hasFinalNewLine
+ ) {
+ // If either not on the last line, or the original content ends with
+ // whitespace, place a single character at the end.
+ postString = ' ';
+ }
+
+ append(
+ leading +
+ JSON.stringify(
+ preString + trimmedLine + postString
+ ) +
+ (lastLine ? '' : '+') +
+ line.match(/[ \t]*$/)[0],
+ state);
}
- // We did not find an exact match, return the next closest one
- // (termination case 2).
- return aHaystack[mid];
- }
- else {
- // aHaystack[mid] is less than our needle.
- if (mid - aLow > 1) {
- // The element is in the lower half.
- return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare);
+ if (!lastLine) {
+ append('\n', state);
}
- // The exact needle element was not found in this haystack. Determine if
- // we are in termination case (2) or (3) and return the appropriate thing.
- return aLow < 0
- ? null
- : aHaystack[aLow];
+ });
+ } else {
+ if (start) {
+ append(start, state);
}
+ append('""', state);
}
+ if (end) {
+ append(end, state);
+ }
- /**
- * This is an implementation of binary search which will always try and return
- * the next lowest value checked if there is no exact hit. This is because
- * mappings between original and generated line/col pairs are single points,
- * and there is an implicit region between each of them, so a miss just means
- * that you aren't on the very start of a region.
- *
- * @param aNeedle The element you are looking for.
- * @param aHaystack The array that is being searched.
- * @param aCompare A function which takes the needle and an element in the
- * array and returns -1, 0, or 1 depending on whether the needle is less
- * than, equal to, or greater than the element, respectively.
- */
- exports.search = function search(aNeedle, aHaystack, aCompare) {
- return aHaystack.length > 0
- ? recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, aCompare)
- : null;
- };
+ // add comma before trailing whitespace
+ if (!isLast) {
+ append(',', state);
+ }
-});
+ // tail whitespace
+ append(object.value.match(/[ \t]*$/)[0], state);
+ move(object.range[1], state);
+}
-},{"amdefine":19}],23:[function(require,module,exports){
-/* -*- Mode: js; js-indent-level: 2; -*- */
-/*
- * Copyright 2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE or:
- * http://opensource.org/licenses/BSD-3-Clause
- */
-if (typeof define !== 'function') {
- var define = require('amdefine')(module);
+function renderXJSExpressionContainer(traverse, object, isLast, path, state) {
+ // Plus 1 to skip `{`.
+ move(object.range[0] + 1, 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.
+ catchup(object.expression.range[1], state);
+ append(',', state);
+ }
+
+ // Minus 1 to skip `}`.
+ catchup(object.range[1] - 1, state);
+ move(object.range[1], state);
+ return false;
}
-define(function (require, exports, module) {
- var charToIntMap = {};
- var intToCharMap = {};
+function quoteAttrName(attr) {
+ // Quote invalid JS identifiers.
+ if (!/^[a-z_$][a-z\d_$]*$/i.test(attr)) {
+ return "'" + attr + "'";
+ }
+ return attr;
+}
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
- .split('')
- .forEach(function (ch, index) {
- charToIntMap[ch] = index;
- intToCharMap[index] = ch;
- });
+exports.knownTags = knownTags;
+exports.renderXJSExpressionContainer = renderXJSExpressionContainer;
+exports.renderXJSLiteral = renderXJSLiteral;
+exports.quoteAttrName = quoteAttrName;
- /**
- * Encode an integer in the range of 0 to 63 to a single base 64 digit.
- */
- exports.encode = function base64_encode(aNumber) {
- if (aNumber in intToCharMap) {
- return intToCharMap[aNumber];
- }
- throw new TypeError("Must be between 0 and 63: " + aNumber);
- };
+})()
+},{"../lib/utils":18,"esprima":4}],23:[function(require,module,exports){
+(function(){/*global exports:true*/
+var classes = require('./transforms/classes');
+var react = require('./transforms/react');
+var reactDisplayName = require('./transforms/reactDisplayName');
- /**
- * Decode a single base 64 digit to an integer.
- */
- exports.decode = function base64_decode(aChar) {
- if (aChar in charToIntMap) {
- return charToIntMap[aChar];
+/**
+ * Map from transformName => orderedListOfVisitors.
+ */
+var transformVisitors = {
+ 'es6-classes': [
+ classes.visitClassExpression,
+ classes.visitClassDeclaration,
+ classes.visitSuperCall,
+ classes.visitPrivateProperty
+ ]
+};
+
+transformVisitors.react = transformVisitors[
+ "es6-classes"
+].concat([
+ react.visitReactTag,
+ reactDisplayName.visitReactDisplayName
+]);
+
+/**
+ * Specifies the order in which each transform should run.
+ */
+var transformRunOrder = [
+ 'es6-classes',
+ 'react'
+];
+
+/**
+ * Given a list of transform names, return the ordered list of visitors to be
+ * passed to the transform() function.
+ *
+ * @param {array?} excludes
+ * @return {array}
+ */
+function getVisitorsList(excludes) {
+ var ret = [];
+ for (var i = 0, il = transformRunOrder.length; i < il; i++) {
+ if (!excludes || excludes.indexOf(transformRunOrder[i]) === -1) {
+ ret = ret.concat(transformVisitors[transformRunOrder[i]]);
}
- throw new TypeError("Not a valid base 64 digit: " + aChar);
- };
+ }
+ return ret;
+}
-});
+exports.getVisitorsList = getVisitorsList;
+exports.transformVisitors = transformVisitors;
-},{"amdefine":19}]},{},[1])(1)
+})()
+},{"./transforms/classes":19,"./transforms/react":20,"./transforms/reactDisplayName":21}]},{},[15])(15)
});
;
\ No newline at end of file