зеркало из https://github.com/mozilla/popcorn-js.git
Merge commit 'scott/lint' into 0.1
Conflicts: index.html
This commit is contained in:
Коммит
49d9f643aa
|
@ -0,0 +1,55 @@
|
|||
# Make sure $JSSHELL points to your js shell binary in .profile or .bashrc
|
||||
TOOLSDIR=./tools
|
||||
|
||||
all: release
|
||||
|
||||
create-release: clean
|
||||
mkdir ./release
|
||||
|
||||
# Version number used in naming release files.
|
||||
VERSION ?= $(error Specify a version for your release (e.g., VERSION=0.5))
|
||||
|
||||
release: release-files zipped
|
||||
|
||||
release-files: popcorn yui release-docs
|
||||
|
||||
zipped: release-files
|
||||
gzip -c ./release/popcorn-${VERSION}.min.js > ./release/popcorn-${VERSION}.min.js.gz
|
||||
find ./release -print | zip -j ./release/popcorn.js-${VERSION}.zip -@
|
||||
|
||||
release-docs: create-release
|
||||
cp AUTHORS ./release
|
||||
cat README | sed -e 's/@VERSION@/${VERSION}/' > ./release/README
|
||||
cp LICENSE ./release
|
||||
cp CHANGELOG ./release
|
||||
|
||||
pretty: create-release
|
||||
${TOOLSDIR}/jsbeautify.py ${JSSHELL} popcorn.js > ./release/popcorn-${VERSION}.js.tmp
|
||||
# check for any parsing errors in pretty version of popcorn.js
|
||||
${JSSHELL} -f ${TOOLSDIR}/fake-dom.js -f ./release/popcorn-${VERSION}.js.tmp
|
||||
cat ./release/popcorn-${VERSION}.js.tmp | sed -e 's/@VERSION@/${VERSION}/' > ./release/popcorn-${VERSION}.js
|
||||
rm -f ./release/popcorn-${VERSION}.js.tmp
|
||||
|
||||
popcorn: create-release
|
||||
cp popcorn.js ./release/popcorn-${VERSION}.js.tmp
|
||||
# check for any parsing errors in popcorn.js
|
||||
${JSSHELL} -f ${TOOLSDIR}/fake-dom.js -f ./release/popcorn-${VERSION}.js.tmp
|
||||
cat ./release/popcorn-${VERSION}.js.tmp | sed -e 's/@VERSION@/${VERSION}/' > ./release/popcorn-${VERSION}.js
|
||||
rm -f ./release/popcorn-${VERSION}.js.tmp
|
||||
|
||||
yui: create-release
|
||||
# java -jar ${TOOLSDIR}/yui/yuicompressor-2.4.2.jar --nomunge popcorn.js -o ./release/popcorn-${VERSION}.min.js
|
||||
java -jar ${TOOLSDIR}/yui/yuicompressor-2.4.2.jar popcorn.js -o ./release/popcorn-${VERSION}.min.js
|
||||
# check for any parsing errors in compiled version of popcorn.js
|
||||
${JSSHELL} -f ${TOOLSDIR}/fake-dom.js -f ./release/popcorn-${VERSION}.min.js
|
||||
|
||||
check: check-lint
|
||||
|
||||
check-lint:
|
||||
${TOOLSDIR}/jslint.py ${JSSHELL} popcorn.js
|
||||
|
||||
# Most targets use commands that need a js shell path specified
|
||||
JSSHELL ?= $(error Specify a valid path to a js shell binary in ~/.profile: export JSSHELL=C:\path\js.exe or /path/js)
|
||||
|
||||
clean:
|
||||
rm -fr ./release
|
70
popcorn.js
70
popcorn.js
|
@ -1,3 +1,5 @@
|
|||
/*global google: false */ // This global comment is read by jslint
|
||||
|
||||
(function() {
|
||||
|
||||
// The video manager manages a single video element, and all it's commands.
|
||||
|
@ -17,24 +19,28 @@
|
|||
// Update is called on the video every time it's time changes.
|
||||
VideoManager.update = function(vid, manager) {
|
||||
var t = vid.currentTime;
|
||||
// Loops through all commands in the manager, preloading data, and calling in() or out().
|
||||
// Loops through all commands in the manager, preloading data, and calling onIn() or onOut().
|
||||
var commandObject = {};
|
||||
for (var i in manager.commandObjects) {
|
||||
commandObject = manager.commandObjects[i];
|
||||
if (commandObject.running && (commandObject.params.in > t || commandObject.params.out < t)) {
|
||||
commandObject.running = false;
|
||||
commandObject.out();
|
||||
if (manager.commandObjects.hasOwnProperty(i)) {
|
||||
commandObject = manager.commandObjects[i];
|
||||
if (commandObject.running && (commandObject.params["in"] > t || commandObject.params["out"] < t)) {
|
||||
commandObject.running = false;
|
||||
commandObject.onOut();
|
||||
}
|
||||
}
|
||||
}
|
||||
for (var i in manager.commandObjects) {
|
||||
commandObject = manager.commandObjects[i];
|
||||
if (!commandObject.loaded && (commandObject.params.in-5) < t && commandObject.params.out > t) {
|
||||
commandObject.loaded = true;
|
||||
commandObject.preload();
|
||||
}
|
||||
if (!commandObject.running && commandObject.params.in < t && commandObject.params.out > t) {
|
||||
commandObject.running = true;
|
||||
commandObject.in();
|
||||
for (var j in manager.commandObjects) {
|
||||
if (manager.commandObjects.hasOwnProperty(j)) {
|
||||
commandObject = manager.commandObjects[j];
|
||||
if (!commandObject.loaded && (commandObject.params["in"] - 5) < t && commandObject.params["out"] > t) {
|
||||
commandObject.loaded = true;
|
||||
commandObject.preload();
|
||||
}
|
||||
if (!commandObject.running && commandObject.params["in"] < t && commandObject.params["out"] > t) {
|
||||
commandObject.running = true;
|
||||
commandObject.onIn();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -80,8 +86,8 @@
|
|||
this.text = text;
|
||||
this.running = false;
|
||||
this.loaded = false;
|
||||
this.in = function() {};
|
||||
this.out = function() {};
|
||||
this.onIn = function() {};
|
||||
this.onOut = function() {};
|
||||
this.preload = function() {};
|
||||
this.id = name + VideoCommand.count++;
|
||||
for (var i = 0, pl = params.length; i < pl; i++) {
|
||||
|
@ -98,24 +104,24 @@
|
|||
};
|
||||
VideoCommand.count = 0;
|
||||
|
||||
// Child commands. Uses in() and out() to do time based operations
|
||||
// Child commands. Uses onIn() and onOut() to do time based operations
|
||||
var SubtitleCommand = function(name, params, text) {
|
||||
VideoCommand.call(this, name, params, text);
|
||||
this.in = function() {
|
||||
this.onIn = function() {
|
||||
document.getElementById("sub").innerHTML = this.text;
|
||||
};
|
||||
this.out = function() {
|
||||
this.onOut = function() {
|
||||
document.getElementById("sub").innerHTML = "";
|
||||
};
|
||||
};
|
||||
|
||||
var TagCommand = function(name, params, text) {
|
||||
VideoCommand.call(this, name, params, text);
|
||||
this.in = function() {
|
||||
this.onIn = function() {
|
||||
TagCommand.people.contains[this.text] = this.text;
|
||||
document.getElementById("inthisvideo").innerHTML = TagCommand.people.toString();
|
||||
};
|
||||
this.out = function() {
|
||||
this.onOut = function() {
|
||||
delete TagCommand.people.contains[this.text];
|
||||
document.getElementById("inthisvideo").innerHTML = TagCommand.people.toString();
|
||||
};
|
||||
|
@ -125,7 +131,9 @@
|
|||
toString: function() {
|
||||
var r = [];
|
||||
for (var i in this.contains) {
|
||||
r.push(" " + this.contains[i]);
|
||||
if (this.contains.hasOwnProperty(i)) {
|
||||
r.push(" " + this.contains[i]);
|
||||
}
|
||||
}
|
||||
return r.toString();
|
||||
}
|
||||
|
@ -133,21 +141,21 @@
|
|||
|
||||
var MapCommand = function(name, params, text) {
|
||||
VideoCommand.call(this, name, params, text);
|
||||
this.params.zoom = parseInt(this.params.zoom);
|
||||
this.params.zoom = parseInt(this.params.zoom, 10);
|
||||
// load the map
|
||||
// http://code.google.com/apis/maps/documentation/javascript/reference.html#MapOptions <-- Map API
|
||||
this.location = new google.maps.LatLng(this.params.lat, this.params.long);
|
||||
if (!MapCommand.map) {
|
||||
MapCommand.map = new google.maps.Map(document.getElementById(this.params.target), {mapTypeId: google.maps.MapTypeId.HYBRID});
|
||||
MapCommand.map.setCenter(new google.maps.LatLng(0, 0))
|
||||
MapCommand.map.setCenter(new google.maps.LatLng(0, 0));
|
||||
MapCommand.map.setZoom(0);
|
||||
}
|
||||
this.in = function() {
|
||||
this.onIn = function() {
|
||||
MapCommand.map.setCenter(this.location);
|
||||
MapCommand.map.setZoom(this.params.zoom);
|
||||
};
|
||||
this.out = function() {
|
||||
MapCommand.map.setCenter(new google.maps.LatLng(0, 0))
|
||||
this.onOut = function() {
|
||||
MapCommand.map.setCenter(new google.maps.LatLng(0, 0));
|
||||
MapCommand.map.setZoom(0);
|
||||
};
|
||||
};
|
||||
|
@ -186,7 +194,9 @@
|
|||
videoManager.addCommand(commands[node.nodeName].create(node.nodeName, allAttributes, node.textContent));
|
||||
} else {
|
||||
for (var i = 0; i < childNodes.length; i++) {
|
||||
childNodes[i].nodeType === 1 && parseNode(childNodes[i], allAttributes);
|
||||
if (childNodes[i].nodeType === 1) {
|
||||
parseNode(childNodes[i], allAttributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -194,7 +204,9 @@
|
|||
for (var j = 0, dl = xmlDoc.length; j < dl; j++) {
|
||||
var x = xmlDoc[j].documentElement.childNodes;
|
||||
for (var i = 0, xl = x.length; i < xl; i++) {
|
||||
x[i].nodeType === 1 && parseNode(x[i], []);
|
||||
if (x[i].nodeType === 1) {
|
||||
parseNode(x[i], []);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
// Swap escaped bits in code. See jsshellhelper.py for creation of __escaped_string
|
||||
function __unescape_string() {
|
||||
return __escaped_string.replace(/@DQUOTE@/g, '"').
|
||||
replace(/@SQUOTE@/g, "'").
|
||||
replace(/@NEWLINE@/g, '\n').
|
||||
replace(/@BACKSLASH@/g, '\\');
|
||||
}
|
|
@ -0,0 +1,974 @@
|
|||
/*jslint onevar: false, plusplus: false */
|
||||
/*
|
||||
|
||||
JS Beautifier
|
||||
---------------
|
||||
|
||||
|
||||
Written by Einar Lielmanis, <einars@gmail.com>
|
||||
http://jsbeautifier.org/
|
||||
|
||||
Originally converted to javascript by Vital, <vital76@gmail.com>
|
||||
|
||||
You are free to use this in any way you want, in case you find this useful or working for you.
|
||||
|
||||
Usage:
|
||||
js_beautify(js_source_text);
|
||||
js_beautify(js_source_text, options);
|
||||
|
||||
The options are:
|
||||
indent_size (default 4) — indentation size,
|
||||
indent_char (default space) — character to indent with,
|
||||
preserve_newlines (default true) — whether existing line breaks should be preserved,
|
||||
indent_level (default 0) — initial indentation level, you probably won't need this ever,
|
||||
|
||||
space_after_anon_function (default false) — if true, then space is added between "function ()"
|
||||
(jslint is happy about this); if false, then the common "function()" output is used.
|
||||
|
||||
e.g
|
||||
|
||||
js_beautify(js_source_text, {indent_size: 1, indent_char: '\t'});
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
function js_beautify(js_source_text, options) {
|
||||
|
||||
var input, output, token_text, last_type, last_text, last_last_text, last_word, flags, flag_store, indent_string;
|
||||
var whitespace, wordchar, punct, parser_pos, line_starters, digits;
|
||||
var prefix, token_type, do_block_just_closed;
|
||||
var indent_level, wanted_newline, just_added_newline, n_newlines;
|
||||
|
||||
|
||||
options = options || {};
|
||||
var opt_indent_size = options.indent_size || 4;
|
||||
var opt_indent_char = options.indent_char || ' ';
|
||||
var opt_preserve_newlines = typeof options.preserve_newlines === 'undefined' ? true : options.preserve_newlines;
|
||||
var opt_indent_level = options.indent_level || 0; // starting indentation
|
||||
var opt_space_after_anon_function = options.space_after_anon_function === 'undefined' ? false : options.space_after_anon_function;
|
||||
var opt_keep_array_indentation = typeof options.keep_array_indentation === 'undefined' ? true : options.keep_array_indentation;
|
||||
|
||||
just_added_newline = false;
|
||||
|
||||
|
||||
function trim_output() {
|
||||
while (output.length && (output[output.length - 1] === ' ' || output[output.length - 1] === indent_string)) {
|
||||
output.pop();
|
||||
}
|
||||
}
|
||||
|
||||
function print_newline(ignore_repeated) {
|
||||
|
||||
if (opt_keep_array_indentation && is_array(flags.mode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ignore_repeated = typeof ignore_repeated === 'undefined' ? true : ignore_repeated;
|
||||
|
||||
flags.if_line = false;
|
||||
trim_output();
|
||||
|
||||
if (!output.length) {
|
||||
return; // no newline on start of file
|
||||
}
|
||||
|
||||
if (output[output.length - 1] !== "\n" || !ignore_repeated) {
|
||||
just_added_newline = true;
|
||||
output.push("\n");
|
||||
}
|
||||
for (var i = 0; i < indent_level; i += 1) {
|
||||
output.push(indent_string);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function print_single_space() {
|
||||
var last_output = ' ';
|
||||
if (output.length) {
|
||||
last_output = output[output.length - 1];
|
||||
}
|
||||
if (last_output !== ' ' && last_output !== '\n' && last_output !== indent_string) { // prevent occassional duplicate space
|
||||
output.push(' ');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function print_token() {
|
||||
just_added_newline = false;
|
||||
output.push(token_text);
|
||||
}
|
||||
|
||||
function indent() {
|
||||
indent_level += 1;
|
||||
}
|
||||
|
||||
|
||||
function unindent() {
|
||||
if (indent_level) {
|
||||
indent_level -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function remove_indent() {
|
||||
if (output.length && output[output.length - 1] === indent_string) {
|
||||
output.pop();
|
||||
}
|
||||
}
|
||||
|
||||
function print_javadoc_comment() {
|
||||
var lines = token_text.split('\n');
|
||||
output.push(lines[0]);
|
||||
for (var i = 1; i < lines.length; i++) {
|
||||
print_newline();
|
||||
output.push(' ');
|
||||
output.push(lines[i].replace(/^\s+/, ''));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function set_mode(mode) {
|
||||
if (flags) {
|
||||
flag_store.push(flags);
|
||||
}
|
||||
flags = {
|
||||
mode: mode,
|
||||
var_line: false,
|
||||
var_line_tainted: false,
|
||||
if_line: false,
|
||||
in_case: false,
|
||||
indentation_baseline: -1
|
||||
};
|
||||
}
|
||||
|
||||
function is_expression(mode) {
|
||||
return mode === '[EXPRESSION]' || mode === '[INDENTED-EXPRESSION]' || mode === '(EXPRESSION)';
|
||||
}
|
||||
|
||||
function is_array(mode) {
|
||||
return mode === '[EXPRESSION]' || mode === '[INDENTED-EXPRESSION]';
|
||||
}
|
||||
|
||||
function restore_mode() {
|
||||
do_block_just_closed = flags.mode === 'DO_BLOCK';
|
||||
if (flag_store.length > 0) {
|
||||
flags = flag_store.pop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function in_array(what, arr) {
|
||||
for (var i = 0; i < arr.length; i += 1) {
|
||||
if (arr[i] === what) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Walk backwards from the colon to find a '?' (colon is part of a ternary op)
|
||||
// or a '{' (colon is part of a class literal). Along the way, keep track of
|
||||
// the blocks and expressions we pass so we only trigger on those chars in our
|
||||
// own level, and keep track of the colons so we only trigger on the matching '?'.
|
||||
|
||||
|
||||
function is_ternary_op() {
|
||||
var level = 0,
|
||||
colon_count = 0;
|
||||
for (var i = output.length - 1; i >= 0; i--) {
|
||||
switch (output[i]) {
|
||||
case ':':
|
||||
if (level === 0) {
|
||||
colon_count++;
|
||||
}
|
||||
break;
|
||||
case '?':
|
||||
if (level === 0) {
|
||||
if (colon_count === 0) {
|
||||
return true;
|
||||
} else {
|
||||
colon_count--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '{':
|
||||
if (level === 0) {
|
||||
return false;
|
||||
}
|
||||
level--;
|
||||
break;
|
||||
case '(':
|
||||
case '[':
|
||||
level--;
|
||||
break;
|
||||
case ')':
|
||||
case ']':
|
||||
case '}':
|
||||
level++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function get_next_token() {
|
||||
n_newlines = 0;
|
||||
|
||||
if (parser_pos >= input.length) {
|
||||
return ['', 'TK_EOF'];
|
||||
}
|
||||
|
||||
var c = input.charAt(parser_pos);
|
||||
parser_pos += 1;
|
||||
|
||||
|
||||
var keep_whitespace = opt_keep_array_indentation && is_array(flags.mode);
|
||||
wanted_newline = false;
|
||||
|
||||
if (keep_whitespace) {
|
||||
|
||||
//
|
||||
// slight mess to allow nice preservation of array indentation and reindent that correctly
|
||||
// first time when we get to the arrays:
|
||||
// var a = [
|
||||
// ....'something'
|
||||
// we make note of whitespace_count = 4 into flags.indentation_baseline
|
||||
// so we know that 4 whitespaces in original source match indent_level of reindented source
|
||||
//
|
||||
// and afterwards, when we get to
|
||||
// 'something,
|
||||
// .......'something else'
|
||||
// we know that this should be indented to indent_level + (7 - indentation_baseline) spaces
|
||||
//
|
||||
var whitespace_count = 0;
|
||||
|
||||
while (in_array(c, whitespace)) {
|
||||
|
||||
if (c === "\n") {
|
||||
trim_output();
|
||||
output.push("\n");
|
||||
just_added_newline = true;
|
||||
whitespace_count = 0;
|
||||
} else {
|
||||
if (c === '\t') {
|
||||
whitespace_count += 4;
|
||||
} else {
|
||||
whitespace_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (parser_pos >= input.length) {
|
||||
return ['', 'TK_EOF'];
|
||||
}
|
||||
|
||||
c = input.charAt(parser_pos);
|
||||
parser_pos += 1;
|
||||
|
||||
}
|
||||
if (flags.indentation_baseline === -1) {
|
||||
flags.indentation_baseline = whitespace_count;
|
||||
}
|
||||
|
||||
if (just_added_newline) {
|
||||
for (var i = 0; i < indent_level + 1; i += 1) {
|
||||
output.push(indent_string);
|
||||
}
|
||||
if (flags.indentation_baseline !== -1) {
|
||||
for (var i = 0; i < whitespace_count - flags.indentation_baseline; i++) {
|
||||
output.push(' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
while (in_array(c, whitespace)) {
|
||||
|
||||
if (c === "\n") {
|
||||
n_newlines += 1;
|
||||
}
|
||||
|
||||
|
||||
if (parser_pos >= input.length) {
|
||||
return ['', 'TK_EOF'];
|
||||
}
|
||||
|
||||
c = input.charAt(parser_pos);
|
||||
parser_pos += 1;
|
||||
|
||||
}
|
||||
|
||||
if (opt_preserve_newlines) {
|
||||
if (n_newlines > 1) {
|
||||
for (var i = 0; i < n_newlines; i += 1) {
|
||||
print_newline(i === 0);
|
||||
just_added_newline = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
wanted_newline = n_newlines > 0;
|
||||
}
|
||||
|
||||
|
||||
if (in_array(c, wordchar)) {
|
||||
if (parser_pos < input.length) {
|
||||
while (in_array(input.charAt(parser_pos), wordchar)) {
|
||||
c += input.charAt(parser_pos);
|
||||
parser_pos += 1;
|
||||
if (parser_pos === input.length) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// small and surprisingly unugly hack for 1E-10 representation
|
||||
if (parser_pos !== input.length && c.match(/^[0-9]+[Ee]$/) && (input.charAt(parser_pos) === '-' || input.charAt(parser_pos) === '+')) {
|
||||
|
||||
var sign = input.charAt(parser_pos);
|
||||
parser_pos += 1;
|
||||
|
||||
var t = get_next_token(parser_pos);
|
||||
c += sign + t[0];
|
||||
return [c, 'TK_WORD'];
|
||||
}
|
||||
|
||||
if (c === 'in') { // hack for 'in' operator
|
||||
return [c, 'TK_OPERATOR'];
|
||||
}
|
||||
if (wanted_newline && last_type !== 'TK_OPERATOR' && !flags.if_line && (opt_preserve_newlines || last_text !== 'var')) {
|
||||
print_newline();
|
||||
}
|
||||
return [c, 'TK_WORD'];
|
||||
}
|
||||
|
||||
if (c === '(' || c === '[') {
|
||||
return [c, 'TK_START_EXPR'];
|
||||
}
|
||||
|
||||
if (c === ')' || c === ']') {
|
||||
return [c, 'TK_END_EXPR'];
|
||||
}
|
||||
|
||||
if (c === '{') {
|
||||
return [c, 'TK_START_BLOCK'];
|
||||
}
|
||||
|
||||
if (c === '}') {
|
||||
return [c, 'TK_END_BLOCK'];
|
||||
}
|
||||
|
||||
if (c === ';') {
|
||||
return [c, 'TK_SEMICOLON'];
|
||||
}
|
||||
|
||||
if (c === '/') {
|
||||
var comment = '';
|
||||
// peek for comment /* ... */
|
||||
if (input.charAt(parser_pos) === '*') {
|
||||
parser_pos += 1;
|
||||
if (parser_pos < input.length) {
|
||||
while (! (input.charAt(parser_pos) === '*' && input.charAt(parser_pos + 1) && input.charAt(parser_pos + 1) === '/') && parser_pos < input.length) {
|
||||
comment += input.charAt(parser_pos);
|
||||
parser_pos += 1;
|
||||
if (parser_pos >= input.length) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
parser_pos += 2;
|
||||
return ['/*' + comment + '*/', 'TK_BLOCK_COMMENT'];
|
||||
}
|
||||
// peek for comment // ...
|
||||
if (input.charAt(parser_pos) === '/') {
|
||||
comment = c;
|
||||
while (input.charAt(parser_pos) !== "\x0d" && input.charAt(parser_pos) !== "\x0a") {
|
||||
comment += input.charAt(parser_pos);
|
||||
parser_pos += 1;
|
||||
if (parser_pos >= input.length) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
parser_pos += 1;
|
||||
if (wanted_newline) {
|
||||
print_newline();
|
||||
}
|
||||
return [comment, 'TK_COMMENT'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (c === "'" || // string
|
||||
c === '"' || // string
|
||||
(c === '/' && ((last_type === 'TK_WORD' && in_array(last_text, ['return', 'do'])) || (last_type === 'TK_START_EXPR' || last_type === 'TK_START_BLOCK' || last_type === 'TK_END_BLOCK' || last_type === 'TK_OPERATOR' || last_type === 'TK_EOF' || last_type === 'TK_SEMICOLON')))) { // regexp
|
||||
var sep = c;
|
||||
var esc = false;
|
||||
var resulting_string = c;
|
||||
|
||||
if (parser_pos < input.length) {
|
||||
if (sep === '/') {
|
||||
//
|
||||
// handle regexp separately...
|
||||
//
|
||||
var in_char_class = false;
|
||||
while (esc || in_char_class || input.charAt(parser_pos) !== sep) {
|
||||
resulting_string += input.charAt(parser_pos);
|
||||
if (!esc) {
|
||||
esc = input.charAt(parser_pos) === '\\';
|
||||
if (input.charAt(parser_pos) === '[') {
|
||||
in_char_class = true;
|
||||
} else if (input.charAt(parser_pos) === ']') {
|
||||
in_char_class = false;
|
||||
}
|
||||
} else {
|
||||
esc = false;
|
||||
}
|
||||
parser_pos += 1;
|
||||
if (parser_pos >= input.length) {
|
||||
// incomplete string/rexp when end-of-file reached.
|
||||
// bail out with what had been received so far.
|
||||
return [resulting_string, 'TK_STRING'];
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
//
|
||||
// and handle string also separately
|
||||
//
|
||||
while (esc || input.charAt(parser_pos) !== sep) {
|
||||
resulting_string += input.charAt(parser_pos);
|
||||
if (!esc) {
|
||||
esc = input.charAt(parser_pos) === '\\';
|
||||
} else {
|
||||
esc = false;
|
||||
}
|
||||
parser_pos += 1;
|
||||
if (parser_pos >= input.length) {
|
||||
// incomplete string/rexp when end-of-file reached.
|
||||
// bail out with what had been received so far.
|
||||
return [resulting_string, 'TK_STRING'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
parser_pos += 1;
|
||||
|
||||
resulting_string += sep;
|
||||
|
||||
if (sep === '/') {
|
||||
// regexps may have modifiers /regexp/MOD , so fetch those, too
|
||||
while (parser_pos < input.length && in_array(input.charAt(parser_pos), wordchar)) {
|
||||
resulting_string += input.charAt(parser_pos);
|
||||
parser_pos += 1;
|
||||
}
|
||||
}
|
||||
return [resulting_string, 'TK_STRING'];
|
||||
}
|
||||
|
||||
if (c === '#') {
|
||||
// Spidermonkey-specific sharp variables for circular references
|
||||
// https://developer.mozilla.org/En/Sharp_variables_in_JavaScript
|
||||
// http://mxr.mozilla.org/mozilla-central/source/js/src/jsscan.cpp around line 1935
|
||||
var sharp = '#';
|
||||
if (parser_pos < input.length && in_array(input.charAt(parser_pos), digits)) {
|
||||
do {
|
||||
c = input.charAt(parser_pos);
|
||||
sharp += c;
|
||||
parser_pos += 1;
|
||||
} while (parser_pos < input.length && c !== '#' && c !== '=');
|
||||
if (c === '#') {
|
||||
return [sharp, 'TK_WORD'];
|
||||
} else {
|
||||
return [sharp, 'TK_OPERATOR'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (c === '<' && input.substring(parser_pos - 1, parser_pos + 3) === '<!--') {
|
||||
parser_pos += 3;
|
||||
return ['<!--', 'TK_COMMENT'];
|
||||
}
|
||||
|
||||
if (c === '-' && input.substring(parser_pos - 1, parser_pos + 2) === '-->') {
|
||||
parser_pos += 2;
|
||||
if (wanted_newline) {
|
||||
print_newline();
|
||||
}
|
||||
return ['-->', 'TK_COMMENT'];
|
||||
}
|
||||
|
||||
if (in_array(c, punct)) {
|
||||
while (parser_pos < input.length && in_array(c + input.charAt(parser_pos), punct)) {
|
||||
c += input.charAt(parser_pos);
|
||||
parser_pos += 1;
|
||||
if (parser_pos >= input.length) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return [c, 'TK_OPERATOR'];
|
||||
}
|
||||
|
||||
return [c, 'TK_UNKNOWN'];
|
||||
}
|
||||
|
||||
//----------------------------------
|
||||
indent_string = '';
|
||||
while (opt_indent_size > 0) {
|
||||
indent_string += opt_indent_char;
|
||||
opt_indent_size -= 1;
|
||||
}
|
||||
|
||||
indent_level = opt_indent_level;
|
||||
|
||||
input = js_source_text;
|
||||
|
||||
last_word = ''; // last 'TK_WORD' passed
|
||||
last_type = 'TK_START_EXPR'; // last token type
|
||||
last_text = ''; // last token text
|
||||
last_last_text = ''; // pre-last token text
|
||||
output = [];
|
||||
|
||||
do_block_just_closed = false;
|
||||
|
||||
whitespace = "\n\r\t ".split('');
|
||||
wordchar = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$'.split('');
|
||||
digits = '0123456789'.split('');
|
||||
|
||||
// <!-- is a special case (ok, it's a minor hack actually)
|
||||
punct = '+ - * / % & ++ -- = += -= *= /= %= == === != !== > < >= <= >> << >>> >>>= >>= <<= && &= | || ! !! , : ? ^ ^= |= ::'.split(' ');
|
||||
|
||||
// words which should always start on new line.
|
||||
line_starters = 'continue,try,throw,return,var,if,switch,case,default,for,while,break,function'.split(',');
|
||||
|
||||
// states showing if we are currently in expression (i.e. "if" case) - 'EXPRESSION', or in usual block (like, procedure), 'BLOCK'.
|
||||
// some formatting depends on that.
|
||||
flag_store = [];
|
||||
set_mode('BLOCK');
|
||||
|
||||
parser_pos = 0;
|
||||
while (true) {
|
||||
var t = get_next_token(parser_pos);
|
||||
token_text = t[0];
|
||||
token_type = t[1];
|
||||
if (token_type === 'TK_EOF') {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (token_type) {
|
||||
|
||||
case 'TK_START_EXPR':
|
||||
|
||||
if (token_text === '[') {
|
||||
|
||||
if (last_type === 'TK_WORD' || last_text === ')') {
|
||||
// this is array index specifier, break immediately
|
||||
// a[x], fn()[x]
|
||||
if (last_word === 'return' || last_word === 'throw') {
|
||||
print_single_space();
|
||||
}
|
||||
set_mode('(EXPRESSION)');
|
||||
print_token();
|
||||
break;
|
||||
}
|
||||
|
||||
if (flags.mode === '[EXPRESSION]' || flags.mode === '[INDENTED-EXPRESSION]') {
|
||||
if (last_last_text === ']' && last_text === ',') {
|
||||
// ], [ goes to new line
|
||||
if (flags.mode === '[EXPRESSION]') {
|
||||
if (!opt_keep_array_indentation) {
|
||||
indent();
|
||||
}
|
||||
flags.mode = '[INDENTED-EXPRESSION]';
|
||||
}
|
||||
if (!opt_keep_array_indentation) {
|
||||
print_newline();
|
||||
}
|
||||
set_mode('[EXPRESSION]');
|
||||
} else if (last_text === '[') {
|
||||
if (flags.mode === '[EXPRESSION]') {
|
||||
if (!opt_keep_array_indentation) {
|
||||
indent();
|
||||
}
|
||||
flags.mode = '[INDENTED-EXPRESSION]';
|
||||
}
|
||||
if (!opt_keep_array_indentation) {
|
||||
print_newline();
|
||||
}
|
||||
set_mode('[EXPRESSION]');
|
||||
} else {
|
||||
set_mode('[EXPRESSION]');
|
||||
}
|
||||
} else {
|
||||
set_mode('[EXPRESSION]');
|
||||
}
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
set_mode('(EXPRESSION)');
|
||||
}
|
||||
|
||||
if (last_text === ';' || last_type === 'TK_START_BLOCK') {
|
||||
print_newline();
|
||||
} else if (last_type === 'TK_END_EXPR' || last_type === 'TK_START_EXPR' || last_type === 'TK_END_BLOCK') {
|
||||
// do nothing on (( and )( and ][ and ]( ..
|
||||
} else if (last_type !== 'TK_WORD' && last_type !== 'TK_OPERATOR') {
|
||||
print_single_space();
|
||||
} else if (last_word === 'function') {
|
||||
// function() vs function ()
|
||||
if (opt_space_after_anon_function) {
|
||||
print_single_space();
|
||||
}
|
||||
} else if (in_array(last_word, line_starters)) {
|
||||
print_single_space();
|
||||
}
|
||||
print_token();
|
||||
|
||||
break;
|
||||
|
||||
case 'TK_END_EXPR':
|
||||
if (token_text === ']') {
|
||||
if (flags.mode === '[INDENTED-EXPRESSION]') {
|
||||
unindent();
|
||||
if (last_text === ']') {
|
||||
print_newline();
|
||||
}
|
||||
}
|
||||
}
|
||||
restore_mode();
|
||||
print_token();
|
||||
break;
|
||||
|
||||
case 'TK_START_BLOCK':
|
||||
|
||||
if (last_word === 'do') {
|
||||
set_mode('DO_BLOCK');
|
||||
} else {
|
||||
set_mode('BLOCK');
|
||||
}
|
||||
if (last_type !== 'TK_OPERATOR' && last_type !== 'TK_START_EXPR') {
|
||||
if (last_type === 'TK_START_BLOCK') {
|
||||
print_newline();
|
||||
} else {
|
||||
print_single_space();
|
||||
}
|
||||
}
|
||||
print_token();
|
||||
indent();
|
||||
break;
|
||||
|
||||
case 'TK_END_BLOCK':
|
||||
if (last_type === 'TK_START_BLOCK') {
|
||||
// nothing
|
||||
if (just_added_newline) {
|
||||
remove_indent();
|
||||
// {
|
||||
//
|
||||
// }
|
||||
} else {
|
||||
// {}
|
||||
trim_output();
|
||||
}
|
||||
unindent();
|
||||
} else {
|
||||
unindent();
|
||||
print_newline();
|
||||
}
|
||||
print_token();
|
||||
restore_mode();
|
||||
break;
|
||||
|
||||
case 'TK_WORD':
|
||||
|
||||
// no, it's not you. even I have problems understanding how this works
|
||||
// and what does what.
|
||||
if (do_block_just_closed) {
|
||||
// do {} ## while ()
|
||||
print_single_space();
|
||||
print_token();
|
||||
print_single_space();
|
||||
do_block_just_closed = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (token_text === 'function') {
|
||||
if ((just_added_newline || last_text == ';') && last_text !== '{') {
|
||||
// make sure there is a nice clean space of at least one blank line
|
||||
// before a new function definition
|
||||
n_newlines = just_added_newline ? n_newlines : 0;
|
||||
|
||||
for (var i = 0; i < 2 - n_newlines; i++) {
|
||||
print_newline(false);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (token_text === 'case' || token_text === 'default') {
|
||||
if (last_text === ':') {
|
||||
// switch cases following one another
|
||||
remove_indent();
|
||||
} else {
|
||||
// case statement starts in the same line where switch
|
||||
unindent();
|
||||
print_newline();
|
||||
indent();
|
||||
}
|
||||
print_token();
|
||||
flags.in_case = true;
|
||||
break;
|
||||
}
|
||||
|
||||
prefix = 'NONE';
|
||||
|
||||
if (last_type === 'TK_END_BLOCK') {
|
||||
if (!in_array(token_text.toLowerCase(), ['else', 'catch', 'finally'])) {
|
||||
prefix = 'NEWLINE';
|
||||
} else {
|
||||
prefix = 'SPACE';
|
||||
print_single_space();
|
||||
}
|
||||
} else if (last_type === 'TK_SEMICOLON' && (flags.mode === 'BLOCK' || flags.mode === 'DO_BLOCK')) {
|
||||
prefix = 'NEWLINE';
|
||||
} else if (last_type === 'TK_SEMICOLON' && is_expression(flags.mode)) {
|
||||
prefix = 'SPACE';
|
||||
} else if (last_type === 'TK_STRING') {
|
||||
prefix = 'NEWLINE';
|
||||
} else if (last_type === 'TK_WORD') {
|
||||
prefix = 'SPACE';
|
||||
} else if (last_type === 'TK_START_BLOCK') {
|
||||
prefix = 'NEWLINE';
|
||||
} else if (last_type === 'TK_END_EXPR') {
|
||||
print_single_space();
|
||||
prefix = 'NEWLINE';
|
||||
}
|
||||
|
||||
if (last_type !== 'TK_END_BLOCK' && in_array(token_text.toLowerCase(), ['else', 'catch', 'finally'])) {
|
||||
print_newline();
|
||||
} else if (in_array(token_text, line_starters) || prefix === 'NEWLINE') {
|
||||
if (last_text === 'else') {
|
||||
// no need to force newline on else break
|
||||
print_single_space();
|
||||
} else if ((last_type === 'TK_START_EXPR' || last_text === '=' || last_text === ',') && token_text === 'function') {
|
||||
// no need to force newline on 'function': (function
|
||||
// DONOTHING
|
||||
} else if (last_text === 'return' || last_text === 'throw') {
|
||||
// no newline between 'return nnn'
|
||||
print_single_space();
|
||||
} else if (last_type !== 'TK_END_EXPR') {
|
||||
if ((last_type !== 'TK_START_EXPR' || token_text !== 'var') && last_text !== ':') {
|
||||
// no need to force newline on 'var': for (var x = 0...)
|
||||
if (token_text === 'if' && last_word === 'else' && last_text !== '{') {
|
||||
// no newline for } else if {
|
||||
print_single_space();
|
||||
} else {
|
||||
print_newline();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (in_array(token_text, line_starters) && last_text !== ')') {
|
||||
print_newline();
|
||||
}
|
||||
}
|
||||
} else if (prefix === 'SPACE') {
|
||||
print_single_space();
|
||||
}
|
||||
print_token();
|
||||
last_word = token_text;
|
||||
|
||||
if (token_text === 'var') {
|
||||
flags.var_line = true;
|
||||
flags.var_line_tainted = false;
|
||||
}
|
||||
|
||||
if (token_text === 'if' || token_text === 'else') {
|
||||
flags.if_line = true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'TK_SEMICOLON':
|
||||
|
||||
print_token();
|
||||
flags.var_line = false;
|
||||
break;
|
||||
|
||||
case 'TK_STRING':
|
||||
|
||||
if (last_type === 'TK_START_BLOCK' || last_type === 'TK_END_BLOCK' || last_type === 'TK_SEMICOLON') {
|
||||
print_newline();
|
||||
} else if (last_type === 'TK_WORD') {
|
||||
print_single_space();
|
||||
}
|
||||
print_token();
|
||||
break;
|
||||
|
||||
case 'TK_OPERATOR':
|
||||
|
||||
var start_delim = true;
|
||||
var end_delim = true;
|
||||
if (flags.var_line && token_text === ',' && (is_expression(flags.mode))) {
|
||||
// do not break on comma, for(var a = 1, b = 2)
|
||||
flags.var_line_tainted = false;
|
||||
}
|
||||
|
||||
if (flags.var_line) {
|
||||
if (token_text === ',') {
|
||||
if (flags.var_line_tainted) {
|
||||
print_token();
|
||||
print_newline();
|
||||
output.push(indent_string);
|
||||
flags.var_line_tainted = false;
|
||||
break;
|
||||
} else {
|
||||
flags.var_line_tainted = false;
|
||||
}
|
||||
} else {
|
||||
flags.var_line_tainted = true;
|
||||
if (token_text === ':') {
|
||||
flags.var_line = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (last_text === 'return' || last_text === 'throw') {
|
||||
// "return" had a special handling in TK_WORD. Now we need to return the favor
|
||||
print_single_space();
|
||||
print_token();
|
||||
break;
|
||||
}
|
||||
|
||||
if (token_text === ':' && flags.in_case) {
|
||||
print_token(); // colon really asks for separate treatment
|
||||
print_newline();
|
||||
flags.in_case = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (token_text === '::') {
|
||||
// no spaces around exotic namespacing syntax operator
|
||||
print_token();
|
||||
break;
|
||||
}
|
||||
|
||||
if (token_text === ',') {
|
||||
if (flags.var_line) {
|
||||
if (flags.var_line_tainted) {
|
||||
print_token();
|
||||
print_newline();
|
||||
flags.var_line_tainted = false;
|
||||
} else {
|
||||
print_token();
|
||||
print_single_space();
|
||||
}
|
||||
} else if (last_type === 'TK_END_BLOCK') {
|
||||
print_token();
|
||||
print_newline();
|
||||
} else {
|
||||
if (flags.mode === 'BLOCK') {
|
||||
print_token();
|
||||
print_newline();
|
||||
} else {
|
||||
// EXPR or DO_BLOCK
|
||||
print_token();
|
||||
print_single_space();
|
||||
}
|
||||
}
|
||||
break;
|
||||
} else if (token_text === '--' || token_text === '++') { // unary operators special case
|
||||
if (last_text === ';') {
|
||||
if (flags.mode === 'BLOCK') {
|
||||
// { foo; --i }
|
||||
print_newline();
|
||||
start_delim = true;
|
||||
end_delim = false;
|
||||
} else {
|
||||
// space for (;; ++i)
|
||||
start_delim = true;
|
||||
end_delim = false;
|
||||
}
|
||||
} else {
|
||||
if (last_text === '{') {
|
||||
// {--i
|
||||
print_newline();
|
||||
}
|
||||
start_delim = false;
|
||||
end_delim = false;
|
||||
}
|
||||
} else if ((token_text === '!' || token_text === '+' || token_text === '-') && (last_text === 'return' || last_text === 'case')) {
|
||||
start_delim = true;
|
||||
end_delim = false;
|
||||
} else if ((token_text === '!' || token_text === '+' || token_text === '-') && last_type === 'TK_START_EXPR') {
|
||||
// special case handling: if (!a)
|
||||
start_delim = false;
|
||||
end_delim = false;
|
||||
} else if (last_type === 'TK_OPERATOR') {
|
||||
start_delim = false;
|
||||
end_delim = false;
|
||||
} else if (last_type === 'TK_END_EXPR') {
|
||||
start_delim = true;
|
||||
end_delim = true;
|
||||
} else if (token_text === '.') {
|
||||
// decimal digits or object.property
|
||||
start_delim = false;
|
||||
end_delim = false;
|
||||
|
||||
} else if (token_text === ':') {
|
||||
if (is_ternary_op()) {
|
||||
start_delim = true;
|
||||
} else {
|
||||
start_delim = false;
|
||||
}
|
||||
}
|
||||
if (start_delim) {
|
||||
print_single_space();
|
||||
}
|
||||
|
||||
print_token();
|
||||
|
||||
if (end_delim) {
|
||||
print_single_space();
|
||||
}
|
||||
break;
|
||||
|
||||
case 'TK_BLOCK_COMMENT':
|
||||
|
||||
print_newline();
|
||||
if (token_text.substring(0, 3) == '/**') {
|
||||
print_javadoc_comment();
|
||||
} else {
|
||||
print_token();
|
||||
}
|
||||
print_newline();
|
||||
break;
|
||||
|
||||
case 'TK_COMMENT':
|
||||
|
||||
// print_newline();
|
||||
if (wanted_newline) {
|
||||
print_newline();
|
||||
} else {
|
||||
print_single_space();
|
||||
}
|
||||
print_token();
|
||||
print_newline();
|
||||
break;
|
||||
|
||||
case 'TK_UNKNOWN':
|
||||
print_token();
|
||||
break;
|
||||
}
|
||||
|
||||
last_last_text = last_text;
|
||||
last_type = token_type;
|
||||
last_text = token_text;
|
||||
}
|
||||
|
||||
return output.join('').replace(/\n+$/, '');
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/env python
|
||||
import sys, os, os.path, signal
|
||||
import jsshellhelper
|
||||
from optparse import OptionParser
|
||||
from subprocess import Popen, PIPE, STDOUT
|
||||
|
||||
# Uses jsshell https://developer.mozilla.org/en/Introduction_to_the_JavaScript_shell
|
||||
|
||||
class Beautifier(object):
|
||||
toolsdir = os.path.dirname(os.path.abspath(__file__))
|
||||
def run(self, jsshell, filename):
|
||||
tmpFile = jsshellhelper.createEscapedFile(filename)
|
||||
|
||||
cmd = [jsshell,
|
||||
'-f', os.path.join(self.toolsdir, 'jsbeautify.js'),
|
||||
'-f', os.path.join(self.toolsdir, 'cleaner.js'),
|
||||
'-f', tmpFile,
|
||||
'-e', "var input = __unescape_string(); print(js_beautify(input, {indent_size: 2}));"]
|
||||
|
||||
proc = Popen(cmd, stdout=PIPE, stderr=PIPE)
|
||||
stdout, stderr = proc.communicate()
|
||||
|
||||
if stdout:
|
||||
print stdout
|
||||
else:
|
||||
print stderr
|
||||
|
||||
jsshellhelper.cleanUp(tmpFile)
|
||||
|
||||
def main():
|
||||
parser = OptionParser()
|
||||
options, args = parser.parse_args()
|
||||
|
||||
if len(args) < 2:
|
||||
print >>sys.stderr, """Usage: %s <path to jsshell> <js file>""" % sys.argv[0]
|
||||
sys.exit(1)
|
||||
|
||||
beautifier = Beautifier()
|
||||
beautifier.run(args[0], args[1])
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,44 @@
|
|||
#!/usr/bin/env python
|
||||
import sys, os, os.path, signal
|
||||
import jsshellhelper
|
||||
from optparse import OptionParser
|
||||
from subprocess import Popen, PIPE, STDOUT
|
||||
|
||||
# Uses jsshell https://developer.mozilla.org/en/Introduction_to_the_JavaScript_shell
|
||||
|
||||
class Linter(object):
|
||||
toolsdir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
def run(self, jsshell, filename):
|
||||
tmpFile = jsshellhelper.createEscapedFile(filename)
|
||||
|
||||
cmd = [jsshell,
|
||||
'-f', os.path.join(self.toolsdir, 'cleaner.js'),
|
||||
'-f', tmpFile,
|
||||
'-e', 'var input = __unescape_string();\n',
|
||||
'-f', os.path.join(self.toolsdir, 'jslint-cmdline.js')]
|
||||
|
||||
proc = Popen(cmd)
|
||||
stdout, stderr = proc.communicate()
|
||||
|
||||
if stdout:
|
||||
print stdout
|
||||
else:
|
||||
print stderr
|
||||
|
||||
jsshellhelper.cleanUp(tmpFile)
|
||||
|
||||
|
||||
def main():
|
||||
parser = OptionParser()
|
||||
options, args = parser.parse_args()
|
||||
|
||||
if len(args) < 2:
|
||||
print >>sys.stderr, """Usage: %s <path to jsshell> <js file>""" % sys.argv[0]
|
||||
sys.exit(1)
|
||||
|
||||
linter = Linter()
|
||||
linter.run(args[0], args[1])
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -0,0 +1,28 @@
|
|||
#!/usr/bin/env python
|
||||
import os, os.path
|
||||
import tempfile
|
||||
|
||||
# Uses jsshell https://developer.mozilla.org/en/Introduction_to_the_JavaScript_shell
|
||||
|
||||
def createEscapedFile(filename):
|
||||
""" Stringifies a file (.js, .pde) and sticks it tmp file as an escaped js string with variable __escaped_string """
|
||||
filepath = os.path.abspath(filename)
|
||||
es = 'var __escaped_string ="'
|
||||
f = open(filepath, "r");
|
||||
for line in f:
|
||||
es += line.rstrip('\r\n').replace('"', '@DQUOTE@').replace("'", '@SQUOTE@').replace("\\", "@BACKSLASH@") + "@NEWLINE@"
|
||||
f.close()
|
||||
es += '";\n'
|
||||
|
||||
# write the escaped string out to a tmp file, return the filename
|
||||
tmp = tempfile.mkstemp()
|
||||
os.close(tmp[0])
|
||||
|
||||
t = open(tmp[1], 'w')
|
||||
t.write(es)
|
||||
t.close()
|
||||
|
||||
return tmp[1]
|
||||
|
||||
def cleanUp(filepath):
|
||||
os.remove(filepath)
|
Двоичный файл не отображается.
|
@ -0,0 +1,140 @@
|
|||
==============================================================================
|
||||
YUI Compressor
|
||||
==============================================================================
|
||||
|
||||
NAME
|
||||
|
||||
YUI Compressor - The Yahoo! JavaScript and CSS Compressor
|
||||
|
||||
SYNOPSIS
|
||||
|
||||
Usage: java -jar yuicompressor-x.y.z.jar [options] [input file]
|
||||
|
||||
Global Options
|
||||
-h, --help Displays this information
|
||||
--type <js|css> Specifies the type of the input file
|
||||
--charset <charset> Read the input file using <charset>
|
||||
--line-break <column> Insert a line break after the specified column number
|
||||
-v, --verbose Display informational messages and warnings
|
||||
-o <file> Place the output into <file>. Defaults to stdout.
|
||||
|
||||
JavaScript Options
|
||||
--nomunge Minify only, do not obfuscate
|
||||
--preserve-semi Preserve all semicolons
|
||||
--disable-optimizations Disable all micro optimizations
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
The YUI Compressor is a JavaScript compressor which, in addition to removing
|
||||
comments and white-spaces, obfuscates local variables using the smallest
|
||||
possible variable name. This obfuscation is safe, even when using constructs
|
||||
such as 'eval' or 'with' (although the compression is not optimal is those
|
||||
cases) Compared to jsmin, the average savings is around 20%.
|
||||
|
||||
The YUI Compressor is also able to safely compress CSS files. The decision
|
||||
on which compressor is being used is made on the file extension (js or css)
|
||||
|
||||
GLOBAL OPTIONS
|
||||
|
||||
-h, --help
|
||||
Prints help on how to use the YUI Compressor
|
||||
|
||||
--line-break
|
||||
Some source control tools don't like files containing lines longer than,
|
||||
say 8000 characters. The linebreak option is used in that case to split
|
||||
long lines after a specific column. It can also be used to make the code
|
||||
more readable, easier to debug (especially with the MS Script Debugger)
|
||||
Specify 0 to get a line break after each semi-colon in JavaScript, and
|
||||
after each rule in CSS.
|
||||
|
||||
--type js|css
|
||||
The type of compressor (JavaScript or CSS) is chosen based on the
|
||||
extension of the input file name (.js or .css) This option is required
|
||||
if no input file has been specified. Otherwise, this option is only
|
||||
required if the input file extension is neither 'js' nor 'css'.
|
||||
|
||||
--charset character-set
|
||||
If a supported character set is specified, the YUI Compressor will use it
|
||||
to read the input file. Otherwise, it will assume that the platform's
|
||||
default character set is being used. The output file is encoded using
|
||||
the same character set.
|
||||
|
||||
-o outfile
|
||||
Place output in file outfile. If not specified, the YUI Compressor will
|
||||
default to the standard output, which you can redirect to a file.
|
||||
|
||||
-v, --verbose
|
||||
Display informational messages and warnings.
|
||||
|
||||
JAVASCRIPT ONLY OPTIONS
|
||||
|
||||
--nomunge
|
||||
Minify only. Do not obfuscate local symbols.
|
||||
|
||||
--preserve-semi
|
||||
Preserve unnecessary semicolons (such as right before a '}') This option
|
||||
is useful when compressed code has to be run through JSLint (which is the
|
||||
case of YUI for example)
|
||||
|
||||
--disable-optimizations
|
||||
Disable all the built-in micro optimizations.
|
||||
|
||||
NOTES
|
||||
|
||||
+ If no input file is specified, it defaults to stdin.
|
||||
|
||||
+ The YUI Compressor requires Java version >= 1.4.
|
||||
|
||||
+ It is possible to prevent a local variable, nested function or function
|
||||
argument from being obfuscated by using "hints". A hint is a string that
|
||||
is located at the very beginning of a function body like so:
|
||||
|
||||
function fn (arg1, arg2, arg3) {
|
||||
"arg2:nomunge, localVar:nomunge, nestedFn:nomunge";
|
||||
|
||||
...
|
||||
var localVar;
|
||||
...
|
||||
|
||||
function nestedFn () {
|
||||
....
|
||||
}
|
||||
|
||||
...
|
||||
}
|
||||
|
||||
The hint itself disappears from the compressed file.
|
||||
|
||||
+ C-style comments starting with /*! are preserved. This is useful with
|
||||
comments containing copyright/license information. For example:
|
||||
|
||||
/*!
|
||||
* TERMS OF USE - EASING EQUATIONS
|
||||
* Open source under the BSD License.
|
||||
* Copyright 2001 Robert Penner All rights reserved.
|
||||
*/
|
||||
|
||||
becomes:
|
||||
|
||||
/*
|
||||
* TERMS OF USE - EASING EQUATIONS
|
||||
* Open source under the BSD License.
|
||||
* Copyright 2001 Robert Penner All rights reserved.
|
||||
*/
|
||||
|
||||
AUTHOR
|
||||
|
||||
The YUI Compressor was written and is maintained by:
|
||||
Julien Lecomte <jlecomte@yahoo-inc.com>
|
||||
The CSS portion is a port of Isaac Schlueter's cssmin utility.
|
||||
|
||||
COPYRIGHT
|
||||
|
||||
Copyright (c) 2007-2009, Yahoo! Inc. All rights reserved.
|
||||
|
||||
LICENSE
|
||||
|
||||
All code specific to YUI Compressor is issued under a BSD license.
|
||||
YUI Compressor extends and implements code from Mozilla's Rhino project.
|
||||
Rhino is issued under the Mozilla Public License (MPL), and MPL applies
|
||||
to the Rhino source and binaries that are distributed with YUI Compressor.
|
Двоичный файл не отображается.
Загрузка…
Ссылка в новой задаче