提交 e93a0fd8 编写于 作者: A alteredq

Merge remote-tracking branch 'remotes/mrdoob/dev' into dev

......@@ -5,7 +5,7 @@ three.js
The aim of the project is to create a lightweight 3D library with a very low level of complexity — in other words, for dummies. The library provides <canvas>, <svg> and WebGL renderers.
[Examples](http://mrdoob.github.com/three.js/)[Documentation](http://mrdoob.github.com/three.js/docs/latest/)
[Examples](http://mrdoob.github.com/three.js/)[Documentation](http://mrdoob.github.com/three.js/docs/latest/)[Questions](http://stackoverflow.com/questions/tagged/three.js)
### Usage ###
......
......@@ -49,6 +49,7 @@
objectAdded: new SIGNALS.Signal(),
objectSelected: new SIGNALS.Signal(),
objectChanged: new SIGNALS.Signal(),
materialChanged: new SIGNALS.Signal(),
windowResize: new SIGNALS.Signal()
};
......@@ -105,9 +106,7 @@
case 'js':
var loader = new THREE.GeometryLoader();
var geometry = loader.parse( JSON.parse( contents ) );
var geometry = new THREE.GeometryLoader().parse( JSON.parse( contents ) );
var material = new THREE.MeshLambertMaterial( { color: 0xffffff } );
var mesh = new THREE.Mesh( geometry, material );
......@@ -118,9 +117,7 @@
case 'obj':
var loader = new THREE.OBJLoader();
var object = loader.parse( contents );
var object = new THREE.OBJLoader().parse( contents );
signals.objectAdded.dispatch( object );
signals.objectSelected.dispatch( object );
......@@ -135,9 +132,7 @@
case 'vtk':
var loader = new THREE.VTKLoader();
var geometry = loader.parse( contents );
var geometry = new THREE.VTKLoader().parse( contents );
var material = new THREE.MeshLambertMaterial( { color: 0xffffff } );
var mesh = new THREE.Mesh( geometry, material );
......
......@@ -176,8 +176,16 @@ UI.Element.prototype = {
this.setStyle( 'display', arguments );
return this;
},
setOverflow: function () {
this.setStyle( 'overflow', arguments );
return this;
}
}
......
......@@ -5,9 +5,9 @@ var Menubar = function ( signals ) {
var options = new UI.Panel();
options.setMargin( '8px' );
options.add( new UI.Text().setText( 'File' ).setColor( '#666' ).setMarginRight( '10px' ) );
options.add( new UI.Text().setText( 'Edit' ).setColor( '#666' ).setMarginRight( '10px' ) );
options.add( new UI.Text().setText( 'About' ).setColor( '#666' ).setMarginRight( '10px' ) );
options.add( new UI.Text().setText( 'File' ).setColor( '#666' ).setMarginRight( '20px' ) );
options.add( new UI.Text().setText( 'Edit' ).setColor( '#666' ).setMarginRight( '20px' ) );
options.add( new UI.Text().setText( 'About' ).setColor( '#666' ).setMarginRight( '20px' ) );
container.add( options );
return container;
......
......@@ -4,40 +4,27 @@ Sidebar.Properties.Geometry = function ( signals ) {
container.setDisplay( 'none' );
container.add( new UI.Text().setText( 'GEOMETRY' ).setColor( '#666' ) );
var button = new UI.Button( 'absolute' ).setRight( '0px' ).setText( 'Export' ).onClick( exportGeometry );
button.download = 'test.js';
container.add( button );
container.add( new UI.Button( 'absolute' ).setRight( '0px' ).setText( 'Export' ).onClick( exportGeometry ) );
container.add( new UI.Break(), new UI.Break() );
container.add( new UI.Text().setText( 'Name' ).setColor( '#666' ) );
var geometryName = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' ).setFontSize( '12px' );
container.add( geometryName );
container.add( new UI.HorizontalRule() );
container.add( new UI.Text().setText( 'Class' ).setColor( '#666' ) );
var geometryClass = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' ).setFontSize( '12px' );
container.add( geometryClass );
container.add( new UI.HorizontalRule() );
container.add( new UI.Text().setText( 'Vertices' ).setColor( '#666' ) );
var verticesCount = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' ).setFontSize( '12px' );
container.add( verticesCount );
container.add( new UI.HorizontalRule() );
container.add( new UI.Text().setText( 'Faces' ).setColor( '#666' ) );
var facesCount = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' ).setFontSize( '12px' );
container.add( facesCount );
container.add( new UI.Break(), new UI.Break(), new UI.Break() );
//
......@@ -107,6 +94,7 @@ Sidebar.Properties.Geometry = function ( signals ) {
var faces = [];
var uvs = [[]];
var normals = [];
var normalsHash = {};
for ( var i = 0; i < geometry.faces.length; i ++ ) {
......@@ -123,15 +111,14 @@ Sidebar.Properties.Geometry = function ( signals ) {
var faceType = 0
faceType = setBit( faceType, 0, ! isTriangle );
/*
faceType = setBit( faceType, 1, hasMaterial );
faceType = setBit( faceType, 2, hasFaceUv );
faceType = setBit( faceType, 3, hasFaceVertexUv );
// faceType = setBit( faceType, 1, hasMaterial );
// faceType = setBit( faceType, 2, hasFaceUv );
// faceType = setBit( faceType, 3, hasFaceVertexUv );
faceType = setBit( faceType, 4, hasFaceNormal );
faceType = setBit( faceType, 5, hasFaceVertexNormal );
faceType = setBit( faceType, 6, hasFaceColor );
faceType = setBit( faceType, 7, hasFaceVertexColor );
*/
// faceType = setBit( faceType, 6, hasFaceColor );
// faceType = setBit( faceType, 7, hasFaceVertexColor );
faces.push( faceType );
......@@ -189,37 +176,33 @@ Sidebar.Properties.Geometry = function ( signals ) {
if ( hasFaceNormal ) {
/*
var normal = face.normal;
faces.push( normal.x, normal.y, normal.z );
*/
var faceNormal = face.normal;
faces.push( getNormalIndex( faceNormal.x, faceNormal.y, faceNormal.z ) );
}
if ( hasFaceVertexNormal ) {
/*
var normals = face.vertexNormals;
var vertexNormals = face.vertexNormals;
if ( isTriangle ) {
faces.push(
normals[ 0 ].u, normals[ 0 ].y, normals[ 0 ].z,
normals[ 1 ].u, normals[ 1 ].y, normals[ 1 ].z,
normals[ 2 ].u, normals[ 2 ].y, normals[ 2 ].z
getNormalIndex( vertexNormals[ 0 ].x, vertexNormals[ 0 ].y, vertexNormals[ 0 ].z ),
getNormalIndex( vertexNormals[ 1 ].x, vertexNormals[ 1 ].y, vertexNormals[ 1 ].z ),
getNormalIndex( vertexNormals[ 2 ].x, vertexNormals[ 2 ].y, vertexNormals[ 2 ].z )
);
} else {
faces.push(
normals[ 0 ].x, normals[ 0 ].y, normals[ 0 ].z,
normals[ 1 ].x, normals[ 1 ].y, normals[ 1 ].z,
normals[ 2 ].x, normals[ 2 ].y, normals[ 2 ].z,
normals[ 3 ].x, normals[ 3 ].y, normals[ 3 ].z
getNormalIndex( vertexNormals[ 0 ].x, vertexNormals[ 0 ].y, vertexNormals[ 0 ].z ),
getNormalIndex( vertexNormals[ 1 ].x, vertexNormals[ 1 ].y, vertexNormals[ 1 ].z ),
getNormalIndex( vertexNormals[ 2 ].x, vertexNormals[ 2 ].y, vertexNormals[ 2 ].z ),
getNormalIndex( vertexNormals[ 3 ].x, vertexNormals[ 3 ].y, vertexNormals[ 3 ].z )
);
}
*/
}
......@@ -231,6 +214,23 @@ Sidebar.Properties.Geometry = function ( signals ) {
}
function getNormalIndex( x, y, z ) {
var hash = x.toString() + y.toString() + z.toString();
if ( normalsHash[ hash ] !== undefined ) {
return normalsHash[ hash ];
}
normalsHash[ hash ] = normals.length / 3;
normals.push( x, y, z );
return normalsHash[ hash ];
}
//
var output = [
......
......@@ -4,45 +4,72 @@ Sidebar.Properties.Material = function ( signals ) {
container.setDisplay( 'none' );
container.add( new UI.Text().setText( 'MATERIAL' ).setColor( '#666' ) );
container.add( new UI.Break(), new UI.Break() );
container.add( new UI.Text().setText( 'Name' ).setColor( '#666' ) );
var materialName = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' ).setFontSize( '12px' );
container.add( materialName );
container.add( new UI.HorizontalRule() );
container.add( new UI.Text().setText( 'Class' ).setColor( '#666' ) );
var materialClass = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' ).setFontSize( '12px' );
container.add( materialClass );
container.add( new UI.HorizontalRule() );
container.add( new UI.Text().setText( 'Color' ).setColor( '#666' ) );
var materialColor = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' ).setFontSize( '12px' );
container.add( materialColor );
container.add( new UI.HorizontalRule() );
container.add( new UI.Text().setText( 'Map' ).setColor( '#666' ) );
var materialMap = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' ).setFontSize( '12px' );
container.add( materialMap );
container.add( new UI.HorizontalRule() );
container.add( new UI.Text().setText( 'Opacity' ).setColor( '#666' ) );
var materialOpacity = new UI.FloatNumber( 'absolute' ).setLeft( '90px' ).setFontSize( '12px' ).onChange( update );
container.add( materialOpacity );
container.add( new UI.HorizontalRule() );
container.add( new UI.Text().setText( 'Transparent' ).setColor( '#666' ) );
var materialTransparent = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' ).setFontSize( '12px' );
container.add( materialTransparent );
//
var selected = null;
function update() {
if ( selected ) {
selected.opacity = materialOpacity.getValue();
signals.materialChanged.dispatch( selected );
}
}
signals.objectSelected.add( function ( object ) {
if ( object && object.material ) {
selected = object.material;
container.setDisplay( 'block' );
materialName.setText( object.material.name );
materialClass.setText( getMaterialInstanceName( object.material ) );
materialColor.setText( '#' + object.material.color.getHex().toString(16) );
materialMap.setText( object.material.map );
materialOpacity.setValue( object.material.opacity );
materialTransparent.setText( object.material.transparent );
} else {
selected = null;
container.setDisplay( 'none' );
}
......
Sidebar.Properties.Object3D = function ( signals ) {
var selected = null;
var container = new UI.Panel();
container.setDisplay( 'none' );
container.add( new UI.Text().setText( 'OBJECT' ).setColor( '#666' ) );
container.add( new UI.Break(), new UI.Break() );
container.add( new UI.Text().setText( 'Name' ).setColor( '#666' ) );
var objectName = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' ).setFontSize( '12px' );
var objectName = new UI.Text( 'absolute' ).setLeft( '90px' ).setColor( '#444' );
container.add( objectName );
container.add( new UI.HorizontalRule() );
container.add( new UI.Text().setText( 'Position' ).setColor( '#666' ) );
var positionX = new UI.FloatNumber( 'absolute' ).setLeft( '90px' ).onChange( update );
var positionY = new UI.FloatNumber( 'absolute' ).setLeft( '160px' ).onChange( update );
var positionZ = new UI.FloatNumber( 'absolute' ).setLeft( '230px' ).onChange( update );
container.add( positionX, positionY, positionZ );
container.add( new UI.HorizontalRule() );
container.add( new UI.Text().setText( 'Rotation' ).setColor( '#666' ) );
var rotationX = new UI.FloatNumber( 'absolute' ).setLeft( '90px' ).onChange( update );
var rotationY = new UI.FloatNumber( 'absolute' ).setLeft( '160px' ).onChange( update );
var rotationZ = new UI.FloatNumber( 'absolute' ).setLeft( '230px' ).onChange( update );
container.add( rotationX, rotationY, rotationZ );
container.add( new UI.HorizontalRule() );
container.add( new UI.Text().setText( 'Scale' ).setColor( '#666' ) );
var scaleX = new UI.FloatNumber( 'absolute' ).setValue( 1 ).setLeft( '90px' ).onChange( update );
var scaleY = new UI.FloatNumber( 'absolute' ).setValue( 1 ).setLeft( '160px' ).onChange( update );
var scaleZ = new UI.FloatNumber( 'absolute' ).setValue( 1 ).setLeft( '230px' ).onChange( update );
container.add( scaleX, scaleY, scaleZ );
container.add( new UI.Break(), new UI.Break(), new UI.Break() );
//
var selected = null;
function update() {
if ( selected ) {
......
......@@ -3,6 +3,7 @@ var Sidebar = function ( signals ) {
var container = new UI.Panel( 'absolute' );
container.setWidth( '300px' ).setHeight( '100%' );
container.setBackgroundColor( '#eee' );
container.setOverflow( 'auto' );
var outliner = new Sidebar.Outliner( signals );
container.add( outliner );
......
......@@ -46,6 +46,7 @@ var Viewport = function ( signals ) {
camera.lookAt( scene.position );
scene.add( camera );
/*
var controls = new THREE.TrackballControls( camera, container.dom );
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
......@@ -55,6 +56,10 @@ var Viewport = function ( signals ) {
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
controls.addEventListener( 'change', render );
*/
var controls = new THREE.OrbitControls( camera, container.dom );
controls.addEventListener( 'change', render );
var light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 1, 0.5, 0 ).normalize();
......@@ -184,6 +189,12 @@ var Viewport = function ( signals ) {
} );
signals.materialChanged.add( function ( material ) {
render();
} );
signals.windowResize.add( function () {
camera.aspect = container.dom.offsetWidth / container.dom.offsetHeight;
......@@ -215,12 +226,12 @@ var Viewport = function ( signals ) {
function render() {
scene.updateMatrixWorld();
sceneHelpers.updateMatrixWorld();
scene.updateMatrixWorld();
renderer.clear();
renderer.render( scene, camera );
renderer.render( sceneHelpers, camera );
renderer.render( scene, camera );
}
......
var fs = require("fs");
var path = require("path");
var argsparser = require( "argsparser" );
var uglify = require("uglify-js");
function merge(files){
"use strict";
var buffer = [];
for (var i = 0,il = files.length;i<il;i++){
var fileName = path.join("src", files[i]);
buffer.push(fs.readFileSync(fileName,'utf8'));
}
return buffer.join("");
}
function output(text, filename){
"use strict";
var file = path.join('build', filename);
fs.writeFileSync(file,text,'utf8');
}
function compress(text, fname_externs){
/*
externs = ""
if fname_externs:
externs = "--externs %s.js" % fname_externs
in_tuple = tempfile.mkstemp()
with os.fdopen(in_tuple[0], 'w') as handle:
handle.write(text)
out_tuple = tempfile.mkstemp()
os.system("java -jar compiler/compiler.jar --warning_level=VERBOSE --jscomp_off=globalThis --jscomp_off=checkTypes --externs externs_common.js %s --language_in=ECMASCRIPT5_STRICT --js %s --js_output_file %s" % (externs, in_tuple[1], out_tuple[1]))
with os.fdopen(out_tuple[0], 'r') as handle:
compressed = handle.read()
os.unlink(in_tuple[1])
os.unlink(out_tuple[1])
return compressed*/
"use strict";
return uglify(text);
}
function addHeader(text, endFilename){
"use strict";
return "// " + endFilename + " - http://github.com/mrdoob/three.js\n" + text;
}
function makeDebug(text){
"use strict";
var position = 0;
while (true){
position = text.indexOf("/* DEBUG", position);
if (position == -1){
break;
}
text = text.substring(0,position) + text.substring(position+8);
position = text.find("*/", position);
text = text.substring(0,position) + text.substring(position+2);
}
return text;
}
function buildLib(files, debug, minified, filename, fname_externs){
"use strict";
var text = merge(files);
if (debug){
text = makeDebug(text);
filename = filename + 'Debug';
}
var folder;
if (filename == "Three"){
folder = '';
} else {
folder = 'custom/';
}
filename = filename + '.js';
//print("=" * 40)
console.log("========================================");
console.log("Compiling " + filename);
//print("=" * 40)
console.log("========================================");
if (minified){
text = compress(text, fname_externs);
}
output(addHeader(text, filename), folder + filename);
}
function buildIncludes(files, filename){
"use strict";
//var template = "\t\t<script src='../src/%s'></script>";
//var text = "\n".join(template % f for f in files)
var text = [];
for (var i = 0,il = files.length;i<il;i++){
text.push("\t\t<script src='../src/" + files[i] + "'></script>");
}
output(text.join("\n"), filename + '.js');
}
function getFileNames(){
"use strict";
var fileName = "utils/files.json";
var data = JSON.parse(fs.readFileSync(fileName,'utf8'));
return data;
}
function parse_args(){
"use strict";
//parse
var returnValue = argsparser.parse();
/*
# If no arguments have been passed, show the help message and exit
if len(sys.argv) == 1:
parser.print_help()
sys.exit(1)
*/
for (var i in returnValue){
if (i.substring(0,2) == "--"){
returnValue[i.substring(2)] = returnValue[i];
delete returnValue[i];
} else {
delete returnValue[i];
}
}
return returnValue;
}
function main(){
"use strict";
var args = parse_args();
var debug = args.debug;
var minified = args.minified;
var files = getFileNames();
var config = [
['Three', 'includes', '', files["COMMON"].concat(files["EXTRAS"]), args.common],
['ThreeCanvas', 'includes_canvas', '', files["CANVAS"], args.canvas],
['ThreeWebGL', 'includes_webgl', '', files["WEBGL"], args.webgl],
['ThreeExtras', 'includes_extras', 'externs_extras', files["EXTRAS"], args.extras]
];
for (var i = 0,il = config.length;i<il;i++){
var chosenConfig = config[i],
fname_lib = chosenConfig[0],
fname_inc = chosenConfig[1],
fname_externs = chosenConfig[2],
files = chosenConfig[3],
enabled = chosenConfig[4];
if (enabled || args.all){
buildLib(files, debug, minified, fname_lib, fname_externs);
if (args.includes){
buildIncludes(files, fname_inc);
}
}
}
}
main();
.DS_Store
\ No newline at end of file
test:
node test/test.js
.PHONY: test
\ No newline at end of file
module.exports = require('./lib/argsparser');
/**
* Parser arguments array
* @param {Array} args optional arguments arrray.
* @return {Object} opts key value hash.
* @export
*/
exports.parse = function(args) {
// args is optional, default is process.argv
args = args || process.argv;
var opts = {}, curSwitch;
args.forEach(function(arg) {
// its a switch
if (/^(-|--)/.test(arg) || !curSwitch) {
opts[arg] = true;
curSwitch = arg;
// this arg is a data
} else {
if (arg === 'false') {
arg = false;
} else if (arg === 'true') {
arg = true;
} else if (!isNaN(arg)) {
arg = Number(arg);
}
// it was a boolean switch per default,
// now it has got a val
if (typeof opts[curSwitch] === 'boolean') {
opts[curSwitch] = arg;
} else if (Array.isArray(opts[curSwitch])) {
opts[curSwitch].push(arg);
} else {
opts[curSwitch] = [opts[curSwitch], arg];
}
}
});
return opts;
};
{
"name": "argsparser",
"description": "A tiny command line arguments parser",
"version": "0.0.6",
"author": "Oleg Slobodskoi <oleg008@gmail.com>",
"repository": {
"type": "git",
"url": "http://github.com/kof/node-argsparser.git"
},
"keywords": [ "arguments", "options", "command line", "parser" ],
"engines": { "node": ">= 0.2.0" },
"scripts": { "test": "node ./test/test.js" },
"licenses": [
{
"type": "MIT",
"url" : "http://www.opensource.org/licenses/mit-license.php"
}
]
}
## Yet another tiny arguments parser for node
## Features
* extremely tiny
* instead to parse all possible spellings, it uses just some simple rules
## How this parser works
The target is to get a key-value object from an array. A key can be the first element or element prefixed by "-" and "--" (switch).
So the parser loops through the array and looks for keys. After he could detect an a key all next elements will be added as a value of this key until he find another key.
If there is no value, then the key is true (boolean). If there are a lot of values, then the key is an array.
## Examples
node script.js -> {"node": "script.js"}
node script.js -o -> {"node": "script.js", "-o": true}
node script.js -o test -> {"node": "script.js", "-o": "test"}
node script.js -a testa --b testb -> {node: "script.js", "-a": "testa", "--b": "testb"}
node script.js -paths /test.js /test1.js -> {node: "script.js", "-paths": ["/test.js", "/test1.js"]}
## Usage
// per default it parses process.argv
var args = require( "argsparser" ).parse(); // {"node": "/path/to/your/script.js"}
// optional you can pass your own arguments array
var args = require( "argsparser" ).parse(["-a", "test"]); // {"-a": "test"}
## Installation
npm install argsparser
\ No newline at end of file
var a = require('assert'),
util = require('util'),
parse = require('../lib/argsparser').parse;
util.print('Run tests...\n');
a.deepEqual(parse(), {node: __filename}, 'node script.js');
a.deepEqual(parse(['-o']), {'-o': true}, 'node script.js -o');
a.deepEqual(parse(['-o', 'true']), {'-o': true}, 'node script.js -o true');
a.deepEqual(parse(['-o', 'false']), {'-o': false}, 'node script.js -o false');
a.deepEqual(parse(['-o', '123']), {'-o': 123}, 'node script.js -o 123');
a.deepEqual(parse(['--token', 'bla--bla']), {'--token': 'bla--bla'}, 'node script.js --token bla--bla');
a.deepEqual(parse(['-o', '123.456']), {'-o': 123.456}, 'node script.js -o 123.456');
a.deepEqual(parse(['-o', 'test']), {'-o': 'test'}, 'node script.js -o test');
a.deepEqual(parse(['-a', 'testa', '-b', 'testb']), {'-a': 'testa', '-b': 'testb'}, 'node script.js -a testa -b testb');
a.deepEqual(parse(['--a', 'testa', '--b', 'testb']), {'--a': 'testa', '--b': 'testb'}, 'node script.js --a testa --b testb ');
a.deepEqual(parse(['-a', 'testa', '--b', 'testb']), {'-a': 'testa', '--b': 'testb'}, 'node script.js -a testa --b testb');
a.deepEqual(parse(['--a', 'testa', '-b', 'testb']), {'--a': 'testa', '-b': 'testb'}, 'node script.js --a testa -b testb');
a.deepEqual(parse(['-paths', '/test.js', '/test1.js']), {'-paths': ['/test.js', '/test1.js']}, 'node script.js -paths /test.js /test1.js');
a.deepEqual(parse(['--paths', '/test.js', '/test1.js']), {'--paths': ['/test.js', '/test1.js']}, 'node script.js --paths /test.js /test1.js');
a.deepEqual(parse(['--paths', '/test.js', '/test1.js', '-a', 'testa']), {'--paths': ['/test.js', '/test1.js'], '-a': 'testa'}, 'node script.js --paths /test.js /test1.js -a testa');
a.deepEqual(parse(['--port', '80', '8080']), {'--port': [80, 8080]}, 'node server.js --port 80 8080');
util.print('All tests ok\n');
.DS_Store
.tmp*~
*.local.*
.pinf-*
\ No newline at end of file
此差异已折叠。
此差异已折叠。
#!/usr/bin/env node
// -*- js -*-
global.sys = require(/^v0\.[012]/.test(process.version) ? "sys" : "util");
var fs = require("fs");
var uglify = require("uglify-js"), // symlink ~/.node_libraries/uglify-js.js to ../uglify-js.js
consolidator = uglify.consolidator,
jsp = uglify.parser,
pro = uglify.uglify;
var options = {
ast: false,
consolidate: false,
mangle: true,
mangle_toplevel: false,
no_mangle_functions: false,
squeeze: true,
make_seqs: true,
dead_code: true,
verbose: false,
show_copyright: true,
out_same_file: false,
max_line_length: 32 * 1024,
unsafe: false,
reserved_names: null,
defines: { },
lift_vars: false,
codegen_options: {
ascii_only: false,
beautify: false,
indent_level: 4,
indent_start: 0,
quote_keys: false,
space_colon: false,
inline_script: false
},
make: false,
output: true // stdout
};
var args = jsp.slice(process.argv, 2);
var filename;
out: while (args.length > 0) {
var v = args.shift();
switch (v) {
case "-b":
case "--beautify":
options.codegen_options.beautify = true;
break;
case "-c":
case "--consolidate-primitive-values":
options.consolidate = true;
break;
case "-i":
case "--indent":
options.codegen_options.indent_level = args.shift();
break;
case "-q":
case "--quote-keys":
options.codegen_options.quote_keys = true;
break;
case "-mt":
case "--mangle-toplevel":
options.mangle_toplevel = true;
break;
case "-nmf":
case "--no-mangle-functions":
options.no_mangle_functions = true;
break;
case "--no-mangle":
case "-nm":
options.mangle = false;
break;
case "--no-squeeze":
case "-ns":
options.squeeze = false;
break;
case "--no-seqs":
options.make_seqs = false;
break;
case "--no-dead-code":
options.dead_code = false;
break;
case "--no-copyright":
case "-nc":
options.show_copyright = false;
break;
case "-o":
case "--output":
options.output = args.shift();
break;
case "--overwrite":
options.out_same_file = true;
break;
case "-v":
case "--verbose":
options.verbose = true;
break;
case "--ast":
options.ast = true;
break;
case "--unsafe":
options.unsafe = true;
break;
case "--max-line-len":
options.max_line_length = parseInt(args.shift(), 10);
break;
case "--reserved-names":
options.reserved_names = args.shift().split(",");
break;
case "--lift-vars":
options.lift_vars = true;
break;
case "-d":
case "--define":
var defarg = args.shift();
try {
var defsym = function(sym) {
// KEYWORDS_ATOM doesn't include NaN or Infinity - should we check
// for them too ?? We don't check reserved words and the like as the
// define values are only substituted AFTER parsing
if (jsp.KEYWORDS_ATOM.hasOwnProperty(sym)) {
throw "Don't define values for inbuilt constant '"+sym+"'";
}
return sym;
},
defval = function(v) {
if (v.match(/^"(.*)"$/) || v.match(/^'(.*)'$/)) {
return [ "string", RegExp.$1 ];
}
else if (!isNaN(parseFloat(v))) {
return [ "num", parseFloat(v) ];
}
else if (v.match(/^[a-z\$_][a-z\$_0-9]*$/i)) {
return [ "name", v ];
}
else if (!v.match(/"/)) {
return [ "string", v ];
}
else if (!v.match(/'/)) {
return [ "string", v ];
}
throw "Can't understand the specified value: "+v;
};
if (defarg.match(/^([a-z_\$][a-z_\$0-9]*)(=(.*))?$/i)) {
var sym = defsym(RegExp.$1),
val = RegExp.$2 ? defval(RegExp.$2.substr(1)) : [ 'name', 'true' ];
options.defines[sym] = val;
}
else {
throw "The --define option expects SYMBOL[=value]";
}
} catch(ex) {
sys.print("ERROR: In option --define "+defarg+"\n"+ex+"\n");
process.exit(1);
}
break;
case "--define-from-module":
var defmodarg = args.shift(),
defmodule = require(defmodarg),
sym,
val;
for (sym in defmodule) {
if (defmodule.hasOwnProperty(sym)) {
options.defines[sym] = function(val) {
if (typeof val == "string")
return [ "string", val ];
if (typeof val == "number")
return [ "num", val ];
if (val === true)
return [ 'name', 'true' ];
if (val === false)
return [ 'name', 'false' ];
if (val === null)
return [ 'name', 'null' ];
if (val === undefined)
return [ 'name', 'undefined' ];
sys.print("ERROR: In option --define-from-module "+defmodarg+"\n");
sys.print("ERROR: Unknown object type for: "+sym+"="+val+"\n");
process.exit(1);
return null;
}(defmodule[sym]);
}
}
break;
case "--ascii":
options.codegen_options.ascii_only = true;
break;
case "--make":
options.make = true;
break;
case "--inline-script":
options.codegen_options.inline_script = true;
break;
default:
filename = v;
break out;
}
}
if (options.verbose) {
pro.set_logger(function(msg){
sys.debug(msg);
});
}
jsp.set_logger(function(msg){
sys.debug(msg);
});
if (options.make) {
options.out_same_file = false; // doesn't make sense in this case
var makefile = JSON.parse(fs.readFileSync(filename || "Makefile.uglify.js").toString());
output(makefile.files.map(function(file){
var code = fs.readFileSync(file.name);
if (file.module) {
code = "!function(exports, global){global = this;\n" + code + "\n;this." + file.module + " = exports;}({})";
}
else if (file.hide) {
code = "(function(){" + code + "}());";
}
return squeeze_it(code);
}).join("\n"));
}
else if (filename) {
fs.readFile(filename, "utf8", function(err, text){
if (err) throw err;
output(squeeze_it(text));
});
}
else {
var stdin = process.openStdin();
stdin.setEncoding("utf8");
var text = "";
stdin.on("data", function(chunk){
text += chunk;
});
stdin.on("end", function() {
output(squeeze_it(text));
});
}
function output(text) {
var out;
if (options.out_same_file && filename)
options.output = filename;
if (options.output === true) {
out = process.stdout;
} else {
out = fs.createWriteStream(options.output, {
flags: "w",
encoding: "utf8",
mode: 0644
});
}
out.write(text.replace(/;*$/, ";"));
if (options.output !== true) {
out.end();
}
};
// --------- main ends here.
function show_copyright(comments) {
var ret = "";
for (var i = 0; i < comments.length; ++i) {
var c = comments[i];
if (c.type == "comment1") {
ret += "//" + c.value + "\n";
} else {
ret += "/*" + c.value + "*/";
}
}
return ret;
};
function squeeze_it(code) {
var result = "";
if (options.show_copyright) {
var tok = jsp.tokenizer(code), c;
c = tok();
result += show_copyright(c.comments_before);
}
try {
var ast = time_it("parse", function(){ return jsp.parse(code); });
if (options.consolidate) ast = time_it("consolidate", function(){
return consolidator.ast_consolidate(ast);
});
if (options.lift_vars) {
ast = time_it("lift", function(){ return pro.ast_lift_variables(ast); });
}
if (options.mangle) ast = time_it("mangle", function(){
return pro.ast_mangle(ast, {
toplevel : options.mangle_toplevel,
defines : options.defines,
except : options.reserved_names,
no_functions : options.no_mangle_functions
});
});
if (options.squeeze) ast = time_it("squeeze", function(){
ast = pro.ast_squeeze(ast, {
make_seqs : options.make_seqs,
dead_code : options.dead_code,
keep_comps : !options.unsafe
});
if (options.unsafe)
ast = pro.ast_squeeze_more(ast);
return ast;
});
if (options.ast)
return sys.inspect(ast, null, null);
result += time_it("generate", function(){ return pro.gen_code(ast, options.codegen_options) });
if (!options.codegen_options.beautify && options.max_line_length) {
result = time_it("split", function(){ return pro.split_lines(result, options.max_line_length) });
}
return result;
} catch(ex) {
sys.debug(ex.stack);
sys.debug(sys.inspect(ex));
sys.debug(JSON.stringify(ex));
process.exit(1);
}
};
function time_it(name, cont) {
if (!options.verbose)
return cont();
var t1 = new Date().getTime();
try { return cont(); }
finally { sys.debug("// " + name + ": " + ((new Date().getTime() - t1) / 1000).toFixed(3) + " sec."); }
};
html { font-family: "Lucida Grande","Trebuchet MS",sans-serif; font-size: 12pt; }
body { max-width: 60em; }
.title { text-align: center; }
.todo { color: red; }
.done { color: green; }
.tag { background-color:lightblue; font-weight:normal }
.target { }
.timestamp { color: grey }
.timestamp-kwd { color: CadetBlue }
p.verse { margin-left: 3% }
pre {
border: 1pt solid #AEBDCC;
background-color: #F3F5F7;
padding: 5pt;
font-family: monospace;
font-size: 90%;
overflow:auto;
}
pre.src {
background-color: #eee; color: #112; border: 1px solid #000;
}
table { border-collapse: collapse; }
td, th { vertical-align: top; }
dt { font-weight: bold; }
div.figure { padding: 0.5em; }
div.figure p { text-align: center; }
.linenr { font-size:smaller }
.code-highlighted {background-color:#ffff00;}
.org-info-js_info-navigation { border-style:none; }
#org-info-js_console-label { font-size:10px; font-weight:bold;
white-space:nowrap; }
.org-info-js_search-highlight {background-color:#ffff00; color:#000000;
font-weight:bold; }
sup {
vertical-align: baseline;
position: relative;
top: -0.5em;
font-size: 80%;
}
sup a:link, sup a:visited {
text-decoration: none;
color: #c00;
}
sup a:before { content: "["; color: #999; }
sup a:after { content: "]"; color: #999; }
h1.title { border-bottom: 4px solid #000; padding-bottom: 5px; margin-bottom: 2em; }
#postamble {
color: #777;
font-size: 90%;
padding-top: 1em; padding-bottom: 1em; border-top: 1px solid #999;
margin-top: 2em;
padding-left: 2em;
padding-right: 2em;
text-align: right;
}
#postamble p { margin: 0; }
#footnotes { border-top: 1px solid #000; }
h1 { font-size: 200% }
h2 { font-size: 175% }
h3 { font-size: 150% }
h4 { font-size: 125% }
h1, h2, h3, h4 { font-family: "Bookman",Georgia,"Times New Roman",serif; font-weight: normal; }
@media print {
html { font-size: 11pt; }
}
此差异已折叠。
var jsp = require("./parse-js"),
pro = require("./process");
var BY_TYPE = {};
function HOP(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
};
function AST_Node(parent) {
this.parent = parent;
};
AST_Node.prototype.init = function(){};
function DEFINE_NODE_CLASS(type, props, methods) {
var base = methods && methods.BASE || AST_Node;
if (!base) base = AST_Node;
function D(parent, data) {
base.apply(this, arguments);
if (props) props.forEach(function(name, i){
this["_" + name] = data[i];
});
this.init();
};
var P = D.prototype = new AST_Node;
P.node_type = function(){ return type };
if (props) props.forEach(function(name){
var propname = "_" + name;
P["set_" + name] = function(val) {
this[propname] = val;
return this;
};
P["get_" + name] = function() {
return this[propname];
};
});
if (type != null) BY_TYPE[type] = D;
if (methods) for (var i in methods) if (HOP(methods, i)) {
P[i] = methods[i];
}
return D;
};
var AST_String_Node = DEFINE_NODE_CLASS("string", ["value"]);
var AST_Number_Node = DEFINE_NODE_CLASS("num", ["value"]);
var AST_Name_Node = DEFINE_NODE_CLASS("name", ["value"]);
var AST_Statlist_Node = DEFINE_NODE_CLASS(null, ["body"]);
var AST_Root_Node = DEFINE_NODE_CLASS("toplevel", null, { BASE: AST_Statlist_Node });
var AST_Block_Node = DEFINE_NODE_CLASS("block", null, { BASE: AST_Statlist_Node });
var AST_Splice_Node = DEFINE_NODE_CLASS("splice", null, { BASE: AST_Statlist_Node });
var AST_Var_Node = DEFINE_NODE_CLASS("var", ["definitions"]);
var AST_Const_Node = DEFINE_NODE_CLASS("const", ["definitions"]);
var AST_Try_Node = DEFINE_NODE_CLASS("try", ["body", "catch", "finally"]);
var AST_Throw_Node = DEFINE_NODE_CLASS("throw", ["exception"]);
var AST_New_Node = DEFINE_NODE_CLASS("new", ["constructor", "arguments"]);
var AST_Switch_Node = DEFINE_NODE_CLASS("switch", ["expression", "branches"]);
var AST_Switch_Branch_Node = DEFINE_NODE_CLASS(null, ["expression", "body"]);
var AST_Break_Node = DEFINE_NODE_CLASS("break", ["label"]);
var AST_Continue_Node = DEFINE_NODE_CLASS("continue", ["label"]);
var AST_Assign_Node = DEFINE_NODE_CLASS("assign", ["operator", "lvalue", "rvalue"]);
var AST_Dot_Node = DEFINE_NODE_CLASS("dot", ["expression", "name"]);
var AST_Call_Node = DEFINE_NODE_CLASS("call", ["function", "arguments"]);
var AST_Lambda_Node = DEFINE_NODE_CLASS(null, ["name", "arguments", "body"])
var AST_Function_Node = DEFINE_NODE_CLASS("function", null, AST_Lambda_Node);
var AST_Defun_Node = DEFINE_NODE_CLASS("defun", null, AST_Lambda_Node);
var AST_If_Node = DEFINE_NODE_CLASS("if", ["condition", "then", "else"]);
此差异已折叠。
此差异已折叠。
var jsp = require("./parse-js"),
pro = require("./process"),
slice = jsp.slice,
member = jsp.member,
curry = jsp.curry,
MAP = pro.MAP,
PRECEDENCE = jsp.PRECEDENCE,
OPERATORS = jsp.OPERATORS;
function ast_squeeze_more(ast) {
var w = pro.ast_walker(), walk = w.walk, scope;
function with_scope(s, cont) {
var save = scope, ret;
scope = s;
ret = cont();
scope = save;
return ret;
};
function _lambda(name, args, body) {
return [ this[0], name, args, with_scope(body.scope, curry(MAP, body, walk)) ];
};
return w.with_walkers({
"toplevel": function(body) {
return [ this[0], with_scope(this.scope, curry(MAP, body, walk)) ];
},
"function": _lambda,
"defun": _lambda,
"new": function(ctor, args) {
if (ctor[0] == "name") {
if (ctor[1] == "Array" && !scope.has("Array")) {
if (args.length != 1) {
return [ "array", args ];
} else {
return walk([ "call", [ "name", "Array" ], args ]);
}
} else if (ctor[1] == "Object" && !scope.has("Object")) {
if (!args.length) {
return [ "object", [] ];
} else {
return walk([ "call", [ "name", "Object" ], args ]);
}
} else if ((ctor[1] == "RegExp" || ctor[1] == "Function" || ctor[1] == "Error") && !scope.has(ctor[1])) {
return walk([ "call", [ "name", ctor[1] ], args]);
}
}
},
"call": function(expr, args) {
if (expr[0] == "dot" && expr[1][0] == "string" && args.length == 1
&& (args[0][1] > 0 && expr[2] == "substring" || expr[2] == "substr")) {
return [ "call", [ "dot", expr[1], "slice"], args];
}
if (expr[0] == "dot" && expr[2] == "toString" && args.length == 0) {
// foo.toString() ==> foo+""
return [ "binary", "+", expr[1], [ "string", "" ]];
}
if (expr[0] == "name") {
if (expr[1] == "Array" && args.length != 1 && !scope.has("Array")) {
return [ "array", args ];
}
if (expr[1] == "Object" && !args.length && !scope.has("Object")) {
return [ "object", [] ];
}
if (expr[1] == "String" && !scope.has("String")) {
return [ "binary", "+", args[0], [ "string", "" ]];
}
}
}
}, function() {
return walk(pro.ast_add_scope(ast));
});
};
exports.ast_squeeze_more = ast_squeeze_more;
{
"name" : "uglify-js",
"description" : "JavaScript parser and compressor/beautifier toolkit",
"author" : {
"name" : "Mihai Bazon",
"email" : "mihai.bazon@gmail.com",
"url" : "http://mihai.bazon.net/blog"
},
"version" : "1.2.6",
"main" : "./uglify-js.js",
"bin" : {
"uglifyjs" : "./bin/uglifyjs"
},
"repository": {
"type": "git",
"url": "git@github.com:mishoo/UglifyJS.git"
}
}
{
"name" : "uglify-js",
"description" : "JavaScript parser and compressor/beautifier toolkit",
"author" : {
"name" : "Mihai Bazon",
"email" : "mihai.bazon@gmail.com",
"url" : "http://mihai.bazon.net/blog"
},
"version" : "1.2.3",
"main" : "./uglify-js.js",
"bin" : {
"uglifyjs" : "./bin/uglifyjs"
},
"repository": {
"type": "git",
"url": "git@github.com:mishoo/UglifyJS.git"
}
}
#! /usr/bin/env node
global.sys = require("sys");
var fs = require("fs");
var jsp = require("../lib/parse-js");
var pro = require("../lib/process");
var filename = process.argv[2];
fs.readFile(filename, "utf8", function(err, text){
try {
var ast = time_it("parse", function(){ return jsp.parse(text); });
ast = time_it("mangle", function(){ return pro.ast_mangle(ast); });
ast = time_it("squeeze", function(){ return pro.ast_squeeze(ast); });
var gen = time_it("generate", function(){ return pro.gen_code(ast, false); });
sys.puts(gen);
} catch(ex) {
sys.debug(ex.stack);
sys.debug(sys.inspect(ex));
sys.debug(JSON.stringify(ex));
}
});
function time_it(name, cont) {
var t1 = new Date().getTime();
try { return cont(); }
finally { sys.debug("// " + name + ": " + ((new Date().getTime() - t1) / 1000).toFixed(3) + " sec."); }
};
#! /usr/bin/env node
var parseJS = require("../lib/parse-js");
var sys = require("sys");
// write debug in a very straightforward manner
var debug = function(){
sys.log(Array.prototype.slice.call(arguments).join(', '));
};
ParserTestSuite(function(i, input, desc){
try {
parseJS.parse(input);
debug("ok " + i + ": " + desc);
} catch(e){
debug("FAIL " + i + " " + desc + " (" + e + ")");
}
});
function ParserTestSuite(callback){
var inps = [
["var abc;", "Regular variable statement w/o assignment"],
["var abc = 5;", "Regular variable statement with assignment"],
["/* */;", "Multiline comment"],
['/** **/;', 'Double star multiline comment'],
["var f = function(){;};", "Function expression in var assignment"],
['hi; // moo\n;', 'single line comment'],
['var varwithfunction;', 'Dont match keywords as substrings'], // difference between `var withsomevar` and `"str"` (local search and lits)
['a + b;', 'addition'],
["'a';", 'single string literal'],
["'a\\n';", 'single string literal with escaped return'],
['"a";', 'double string literal'],
['"a\\n";', 'double string literal with escaped return'],
['"var";', 'string is a keyword'],
['"variable";', 'string starts with a keyword'],
['"somevariable";', 'string contains a keyword'],
['"somevar";', 'string ends with a keyword'],
['500;', 'int literal'],
['500.;', 'float literal w/o decimals'],
['500.432;', 'float literal with decimals'],
['.432432;', 'float literal w/o int'],
['(a,b,c);', 'parens and comma'],
['[1,2,abc];', 'array literal'],
['var o = {a:1};', 'object literal unquoted key'],
['var o = {"b":2};', 'object literal quoted key'], // opening curly may not be at the start of a statement...
['var o = {c:c};', 'object literal keyname is identifier'],
['var o = {a:1,"b":2,c:c};', 'object literal combinations'],
['var x;\nvar y;', 'two lines'],
['var x;\nfunction n(){; }', 'function def'],
['var x;\nfunction n(abc){; }', 'function def with arg'],
['var x;\nfunction n(abc, def){ ;}', 'function def with args'],
['function n(){ "hello"; }', 'function def with body'],
['/a/;', 'regex literal'],
['/a/b;', 'regex literal with flag'],
['/a/ / /b/;', 'regex div regex'],
['a/b/c;', 'triple division looks like regex'],
['+function(){/regex/;};', 'regex at start of function body'],
// http://code.google.com/p/es-lab/source/browse/trunk/tests/parser/parsertests.js?r=86
// http://code.google.com/p/es-lab/source/browse/trunk/tests/parser/parsertests.js?r=430
// first tests for the lexer, should also parse as program (when you append a semi)
// comments
['//foo!@#^&$1234\nbar;', 'single line comment'],
['/* abcd!@#@$* { } && null*/;', 'single line multi line comment'],
['/*foo\nbar*/;','multi line comment'],
['/*x*x*/;','multi line comment with *'],
['/**/;','empty comment'],
// identifiers
["x;",'1 identifier'],
["_x;",'2 identifier'],
["xyz;",'3 identifier'],
["$x;",'4 identifier'],
["x$;",'5 identifier'],
["_;",'6 identifier'],
["x5;",'7 identifier'],
["x_y;",'8 identifier'],
["x+5;",'9 identifier'],
["xyz123;",'10 identifier'],
["x1y1z1;",'11 identifier'],
["foo\\u00D8bar;",'12 identifier unicode escape'],
//["foo�bar;",'13 identifier unicode embedded (might fail)'],
// numbers
["5;", '1 number'],
["5.5;", '2 number'],
["0;", '3 number'],
["0.0;", '4 number'],
["0.001;", '5 number'],
["1.e2;", '6 number'],
["1.e-2;", '7 number'],
["1.E2;", '8 number'],
["1.E-2;", '9 number'],
[".5;", '10 number'],
[".5e3;", '11 number'],
[".5e-3;", '12 number'],
["0.5e3;", '13 number'],
["55;", '14 number'],
["123;", '15 number'],
["55.55;", '16 number'],
["55.55e10;", '17 number'],
["123.456;", '18 number'],
["1+e;", '20 number'],
["0x01;", '22 number'],
["0XCAFE;", '23 number'],
["0x12345678;", '24 number'],
["0x1234ABCD;", '25 number'],
["0x0001;", '26 number'],
// strings
["\"foo\";", '1 string'],
["\'foo\';", '2 string'],
["\"x\";", '3 string'],
["\'\';", '4 string'],
["\"foo\\tbar\";", '5 string'],
["\"!@#$%^&*()_+{}[]\";", '6 string'],
["\"/*test*/\";", '7 string'],
["\"//test\";", '8 string'],
["\"\\\\\";", '9 string'],
["\"\\u0001\";", '10 string'],
["\"\\uFEFF\";", '11 string'],
["\"\\u10002\";", '12 string'],
["\"\\x55\";", '13 string'],
["\"\\x55a\";", '14 string'],
["\"a\\\\nb\";", '15 string'],
['";"', '16 string: semi in a string'],
['"a\\\nb";', '17 string: line terminator escape'],
// literals
["null;", "null"],
["true;", "true"],
["false;", "false"],
// regex
["/a/;", "1 regex"],
["/abc/;", "2 regex"],
["/abc[a-z]*def/g;", "3 regex"],
["/\\b/;", "4 regex"],
["/[a-zA-Z]/;", "5 regex"],
// program tests (for as far as they havent been covered above)
// regexp
["/foo(.*)/g;", "another regexp"],
// arrays
["[];", "1 array"],
["[ ];", "2 array"],
["[1];", "3 array"],
["[1,2];", "4 array"],
["[1,2,,];", "5 array"],
["[1,2,3];", "6 array"],
["[1,2,3,,,];", "7 array"],
// objects
["{};", "1 object"],
["({x:5});", "2 object"],
["({x:5,y:6});", "3 object"],
["({x:5,});", "4 object"],
["({if:5});", "5 object"],
["({ get x() {42;} });", "6 object"],
["({ set y(a) {1;} });", "7 object"],
// member expression
["o.m;", "1 member expression"],
["o['m'];", "2 member expression"],
["o['n']['m'];", "3 member expression"],
["o.n.m;", "4 member expression"],
["o.if;", "5 member expression"],
// call and invoke expressions
["f();", "1 call/invoke expression"],
["f(x);", "2 call/invoke expression"],
["f(x,y);", "3 call/invoke expression"],
["o.m();", "4 call/invoke expression"],
["o['m'];", "5 call/invoke expression"],
["o.m(x);", "6 call/invoke expression"],
["o['m'](x);", "7 call/invoke expression"],
["o.m(x,y);", "8 call/invoke expression"],
["o['m'](x,y);", "9 call/invoke expression"],
["f(x)(y);", "10 call/invoke expression"],
["f().x;", "11 call/invoke expression"],
// eval
["eval('x');", "1 eval"],
["(eval)('x');", "2 eval"],
["(1,eval)('x');", "3 eval"],
["eval(x,y);", "4 eval"],
// new expression
["new f();", "1 new expression"],
["new o;", "2 new expression"],
["new o.m;", "3 new expression"],
["new o.m(x);", "4 new expression"],
["new o.m(x,y);", "5 new expression"],
// prefix/postfix
["++x;", "1 pre/postfix"],
["x++;", "2 pre/postfix"],
["--x;", "3 pre/postfix"],
["x--;", "4 pre/postfix"],
["x ++;", "5 pre/postfix"],
["x /* comment */ ++;", "6 pre/postfix"],
["++ /* comment */ x;", "7 pre/postfix"],
// unary operators
["delete x;", "1 unary operator"],
["void x;", "2 unary operator"],
["+ x;", "3 unary operator"],
["-x;", "4 unary operator"],
["~x;", "5 unary operator"],
["!x;", "6 unary operator"],
// meh
["new Date++;", "new date ++"],
["+x++;", " + x ++"],
// expression expressions
["1 * 2;", "1 expression expressions"],
["1 / 2;", "2 expression expressions"],
["1 % 2;", "3 expression expressions"],
["1 + 2;", "4 expression expressions"],
["1 - 2;", "5 expression expressions"],
["1 << 2;", "6 expression expressions"],
["1 >>> 2;", "7 expression expressions"],
["1 >> 2;", "8 expression expressions"],
["1 * 2 + 3;", "9 expression expressions"],
["(1+2)*3;", "10 expression expressions"],
["1*(2+3);", "11 expression expressions"],
["x<y;", "12 expression expressions"],
["x>y;", "13 expression expressions"],
["x<=y;", "14 expression expressions"],
["x>=y;", "15 expression expressions"],
["x instanceof y;", "16 expression expressions"],
["x in y;", "17 expression expressions"],
["x&y;", "18 expression expressions"],
["x^y;", "19 expression expressions"],
["x|y;", "20 expression expressions"],
["x+y<z;", "21 expression expressions"],
["x<y+z;", "22 expression expressions"],
["x+y+z;", "23 expression expressions"],
["x+y<z;", "24 expression expressions"],
["x<y+z;", "25 expression expressions"],
["x&y|z;", "26 expression expressions"],
["x&&y;", "27 expression expressions"],
["x||y;", "28 expression expressions"],
["x&&y||z;", "29 expression expressions"],
["x||y&&z;", "30 expression expressions"],
["x<y?z:w;", "31 expression expressions"],
// assignment
["x >>>= y;", "1 assignment"],
["x <<= y;", "2 assignment"],
["x = y;", "3 assignment"],
["x += y;", "4 assignment"],
["x /= y;", "5 assignment"],
// comma
["x, y;", "comma"],
// block
["{};", "1 block"],
["{x;};", "2 block"],
["{x;y;};", "3 block"],
// vars
["var x;", "1 var"],
["var x,y;", "2 var"],
["var x=1,y=2;", "3 var"],
["var x,y=2;", "4 var"],
// empty
[";", "1 empty"],
["\n;", "2 empty"],
// expression statement
["x;", "1 expression statement"],
["5;", "2 expression statement"],
["1+2;", "3 expression statement"],
// if
["if (c) x; else y;", "1 if statement"],
["if (c) x;", "2 if statement"],
["if (c) {} else {};", "3 if statement"],
["if (c1) if (c2) s1; else s2;", "4 if statement"],
// while
["do s; while (e);", "1 while statement"],
["do { s; } while (e);", "2 while statement"],
["while (e) s;", "3 while statement"],
["while (e) { s; };", "4 while statement"],
// for
["for (;;) ;", "1 for statement"],
["for (;c;x++) x;", "2 for statement"],
["for (i;i<len;++i){};", "3 for statement"],
["for (var i=0;i<len;++i) {};", "4 for statement"],
["for (var i=0,j=0;;){};", "5 for statement"],
//["for (x in b; c; u) {};", "6 for statement"],
["for ((x in b); c; u) {};", "7 for statement"],
["for (x in a);", "8 for statement"],
["for (var x in a){};", "9 for statement"],
["for (var x=5 in a) {};", "10 for statement"],
["for (var x = a in b in c) {};", "11 for statement"],
["for (var x=function(){a+b;}; a<b; ++i) some;", "11 for statement, testing for parsingForHeader reset with the function"],
["for (var x=function(){for (x=0; x<15; ++x) alert(foo); }; a<b; ++i) some;", "11 for statement, testing for parsingForHeader reset with the function"],
// flow statements
["while(1){ continue; }", "1 flow statement"],
["label: while(1){ continue label; }", "2 flow statement"],
["while(1){ break; }", "3 flow statement"],
["somewhere: while(1){ break somewhere; }", "4 flow statement"],
["while(1){ continue /* comment */ ; }", "5 flow statement"],
["while(1){ continue \n; }", "6 flow statement"],
["(function(){ return; })()", "7 flow statement"],
["(function(){ return 0; })()", "8 flow statement"],
["(function(){ return 0 + \n 1; })()", "9 flow statement"],
// with
["with (e) s;", "with statement"],
// switch
["switch (e) { case x: s; };", "1 switch statement"],
["switch (e) { case x: s1;s2; default: s3; case y: s4; };", "2 switch statement"],
["switch (e) { default: s1; case x: s2; case y: s3; };", "3 switch statement"],
["switch (e) { default: s; };", "4 switch statement"],
["switch (e) { case x: s1; case y: s2; };", "5 switch statement"],
// labels
["foo : x;", " flow statement"],
// throw
["throw x;", "1 throw statement"],
["throw x\n;", "2 throw statement"],
// try catch finally
["try { s1; } catch (e) { s2; };", "1 trycatchfinally statement"],
["try { s1; } finally { s2; };", "2 trycatchfinally statement"],
["try { s1; } catch (e) { s2; } finally { s3; };", "3 trycatchfinally statement"],
// debugger
["debugger;", "debuger statement"],
// function decl
["function f(x) { e; return x; };", "1 function declaration"],
["function f() { x; y; };", "2 function declaration"],
["function f(x,y) { var z; return x; };", "3 function declaration"],
// function exp
["(function f(x) { return x; });", "1 function expression"],
["(function empty() {;});", "2 function expression"],
["(function empty() {;});", "3 function expression"],
["(function (x) {; });", "4 function expression"],
// program
["var x; function f(){;}; null;", "1 program"],
[";;", "2 program"],
["{ x; y; z; }", "3 program"],
["function f(){ function g(){;}};", "4 program"],
["x;\n/*foo*/\n ;", "5 program"],
// asi
["foo: while(1){ continue \n foo; }", "1 asi"],
["foo: while(1){ break \n foo; }", "2 asi"],
["(function(){ return\nfoo; })()", "3 asi"],
["var x; { 1 \n 2 } 3", "4 asi"],
["ab /* hi */\ncd", "5 asi"],
["ab/*\n*/cd", "6 asi (multi line multilinecomment counts as eol)"],
["foo: while(1){ continue /* wtf \n busta */ foo; }", "7 asi illegal with multi line comment"],
["function f() { s }", "8 asi"],
["function f() { return }", "9 asi"],
// use strict
// XXX: some of these should actually fail?
// no support for "use strict" yet...
['"use strict"; \'bla\'\n; foo;', "1 directive"],
['(function() { "use strict"; \'bla\';\n foo; });', "2 directive"],
['"use\\n strict";', "3 directive"],
['foo; "use strict";', "4 directive"],
// tests from http://es5conform.codeplex.com/
['"use strict"; var o = { eval: 42};', "8.7.2-3-1-s: the use of eval as property name is allowed"],
['({foo:0,foo:1});', 'Duplicate property name allowed in not strict mode'],
['function foo(a,a){}', 'Duplicate parameter name allowed in not strict mode'],
['(function foo(eval){})', 'Eval allowed as parameter name in non strict mode'],
['(function foo(arguments){})', 'Arguments allowed as parameter name in non strict mode'],
// empty programs
['', '1 Empty program'],
['// test', '2 Empty program'],
['//test\n', '3 Empty program'],
['\n// test', '4 Empty program'],
['\n// test\n', '5 Empty program'],
['/* */', '6 Empty program'],
['/*\ns,fd\n*/', '7 Empty program'],
['/*\ns,fd\n*/\n', '8 Empty program'],
[' ', '9 Empty program'],
[' /*\nsmeh*/ \n ', '10 Empty program'],
// trailing whitespace
['a ', '1 Trailing whitespace'],
['a /* something */', '2 Trailing whitespace'],
['a\n // hah', '3 Trailing whitespace'],
['/abc/de//f', '4 Trailing whitespace'],
['/abc/de/*f*/\n ', '5 Trailing whitespace'],
// things the parser tripped over at one point or the other (prevents regression bugs)
['for (x;function(){ a\nb };z) x;', 'for header with function body forcing ASI'],
['c=function(){return;return};', 'resetting noAsi after literal'],
['d\nd()', 'asi exception causing token overflow'],
['for(;;){x=function(){}}', 'function expression in a for header'],
['for(var k;;){}', 'parser failing due to ASI accepting the incorrect "for" rule'],
['({get foo(){ }})', 'getter with empty function body'],
['\nreturnr', 'eol causes return statement to ignore local search requirement'],
[' / /', '1 whitespace before regex causes regex to fail?'],
['/ // / /', '2 whitespace before regex causes regex to fail?'],
['/ / / / /', '3 whitespace before regex causes regex to fail?'],
['\n\t// Used for trimming whitespace\n\ttrimLeft = /^\\s+/;\n\ttrimRight = /\\s+$/;\t\n','turned out this didnt crash (the test below did), but whatever.'],
['/[\\/]/;', 'escaped forward slash inside class group (would choke on fwd slash)'],
['/[/]/;', 'also broke but is valid in es5 (not es3)'],
['({get:5});','get property name thats not a getter'],
['({set:5});','set property name thats not a setter'],
['l !== "px" && (d.style(h, c, (k || 1) + l), j = (k || 1) / f.cur() * j, d.style(h, c, j + l)), i[1] && (k = (i[1] === "-=" ? -1 : 1) * k + j), f.custom(j, k, l)', 'this choked regex/div at some point'],
['(/\'/g, \'\\\\\\\'\') + "\'";', 'the sequence of escaped characters confused the tokenizer'],
['if (true) /=a/.test("a");', 'regexp starting with "=" in not obvious context (not implied by preceding token)']
];
for (var i=0; i<inps.length; ++i) {
callback(i, inps[i][0], inps[i][1]);
};
};
(function(){var a=function(){};return new a(1,2,3,4)})()
(function(){function a(){}return new a(1,2,3,4)})()
(function(){function a(){}(function(){return new a(1,2,3)})()})()
a=1,b=a,c=1,d=b,e=d,longname=2;if(longname+1){x=3;if(x)var z=7}z=1,y=1,x=1,g+=1,h=g,++i,j=i,i++,j=i+17
\ No newline at end of file
var a=a+"a"+"b"+1+c,b=a+"c"+"ds"+123+c,c=a+"c"+123+d+"ds"+c
\ No newline at end of file
function bar(){return--x}function foo(){while(bar());}function mak(){for(;;);}var x=5
a=func(),b=z;for(a++;i<10;i++)alert(i);var z=1;g=2;for(;i<10;i++)alert(i);var a=2;for(var i=1;i<10;i++)alert(i)
\ No newline at end of file
var a=1;a==1?a=2:a=17
\ No newline at end of file
function a(a){return a==1?2:17}
\ No newline at end of file
function x(a){return typeof a=="object"?a:a===42?0:a*2}function y(a){return typeof a=="object"?a:null}
function f(){var a;return(a="a")?a:a}f()
\ No newline at end of file
new(A,B),new(A||B),new(X?A:B)
\ No newline at end of file
var a=/^(?:(\w+):)?(?:\/\/(?:(?:([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#])(?::(\d))?)?(..?$|(?:[^?#\/]\/))([^?#]*)(?:\?([^#]))?(?:#(.))?/
\ No newline at end of file
var a={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"}
var a=function(b){b(),a()}
\ No newline at end of file
var a=0;switch(a){case 0:a++}
\ No newline at end of file
o={".5":.5},o={.5:.5},o={.5:.5}
\ No newline at end of file
result=function(){return 1}()
\ No newline at end of file
var a={};a["this"]=1,a.that=2
\ No newline at end of file
var a=2e3,b=.002,c=2e-5
\ No newline at end of file
function bar(a){try{foo()}catch(b){alert("Exception caught (foo not defined)")}alert(a)}bar(10)
(function(){var a=function b(a,b,c){return b}})()
typeof a=="string",b+""!=c+"",d<e==f<g
\ No newline at end of file
new Array();
new Array(1);
new Array(1, 2, 3);
(function(){
var Array = function(){};
return new Array(1, 2, 3, 4);
})();
(function(){
return new Array(1, 2, 3, 4);
function Array() {};
})();
(function(){
(function(){
return new Array(1, 2, 3);
})();
function Array(){};
})();
a=1;
b=a;
c=1;
d=b;
e=d;
longname=2;
if (longname+1) {
x=3;
if (x) var z = 7;
}
z=1,y=1,x=1
g+=1;
h=g;
++i;
j=i;
i++;
j=i+17;
\ No newline at end of file
var a = a + "a" + "b" + 1 + c;
var b = a + "c" + "ds" + 123 + c;
var c = a + "c" + 123 + d + "ds" + c;
\ No newline at end of file
// test that the calculation is fold to 13
var a = 1 + 2 * 6;
// test that it isn't replaced with 0.3333 because that is more characters
var b = 1/3;
\ No newline at end of file
var x = 5;
function bar() { return --x; }
function foo() { while (bar()); }
function mak() { for(;;); }
a=func();
b=z;
for (a++; i < 10; i++) { alert(i); }
var z=1;
g=2;
for (; i < 10; i++) { alert(i); }
var a = 2;
for (var i = 1; i < 10; i++) { alert(i); }
var a = 1;
if (a == 1) {
a = 2;
} else {
a = 17;
}
function a(b) {
if (b == 1) {
return 2;
} else {
return 17;
}
return 3;
}
\ No newline at end of file
function x(a) {
if (typeof a === 'object')
return a;
if (a === 42)
return 0;
return a * 2;
}
function y(a) {
if (typeof a === 'object')
return a;
return null;
};
function f() { var a; if (a = 'a') { return a; } else { return a; } }; f();
\ No newline at end of file
new (A, B)
new (A || B)
new (X ? A : B)
\ No newline at end of file
var a = /^(?:(\w+):)?(?:\/\/(?:(?:([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#])(?::(\d))?)?(..?$|(?:[^?#\/]\/))([^?#]*)(?:\?([^#]))?(?:#(.))?/;
\ No newline at end of file
var a = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\'};
\ No newline at end of file
var a = 0xC1BDCEEE;
\ No newline at end of file
var a = 0;
switch(a) {
case 0:
a++;
break;
}
\ No newline at end of file
label1 : {
label2 : {
break label2;
console.log(2);
}
console.log(1);
}
\ No newline at end of file
(a ? b : c) ? d : e
\ No newline at end of file
o = {'.5':.5}
o = {'0.5':.5}
o = {0.5:.5}
\ No newline at end of file
result=(function(){ return 1;})()
\ No newline at end of file
var a = 1 << 3;
var b = 8 >> 1;
var c = 8 >>> 1;
\ No newline at end of file
var a = {};
a["this"] = 1;
a["that"] = 2;
\ No newline at end of file
var a = 2e3;
var b = 2e-3;
var c = 2e-5;
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册