"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "includes/libs/JavaScriptMinifier.php" between
mediawiki-1.31.1.tar.gz and mediawiki-1.32.0.tar.gz

About: MediaWiki is a wiki engine (the collaborative editing software that runs for e.g. Wikipedia, the free encyclopedia).

JavaScriptMinifier.php  (mediawiki-1.31.1):JavaScriptMinifier.php  (mediawiki-1.32.0)
<?php <?php
/** /**
* JavaScript Minifier * JavaScript Minifier
* *
* @file * @file
* @author Paul Copperman <paul.copperman@gmail.com> * @author Paul Copperman <paul.copperman@gmail.com>
* @license Choose any of Apache, MIT, GPL, LGPL * @license Apache-2.0
* @license MIT
* @license GPL-2.0-or-later
* @license LGPL-2.1-or-later
*/ */
/** /**
* This class is meant to safely minify javascript code, while leaving syntactic ally correct * This class is meant to safely minify javascript code, while leaving syntactic ally correct
* programs intact. Other libraries, such as JSMin require a certain coding styl e to work * programs intact. Other libraries, such as JSMin require a certain coding styl e to work
* correctly. OTOH, libraries like jsminplus, that do parse the code correctly a re rather * correctly. OTOH, libraries like jsminplus, that do parse the code correctly a re rather
* slow, because they construct a complete parse tree before outputting the code minified. * slow, because they construct a complete parse tree before outputting the code minified.
* So this class is meant to allow arbitrary (but syntactically correct) input, while being * So this class is meant to allow arbitrary (but syntactically correct) input, while being
* fast enough to be used for on-the-fly minifying. * fast enough to be used for on-the-fly minifying.
*
* This class was written with ECMA-262 Edition 3 in mind ("ECMAScript 3"). Pars
ing features
* new to ECMAScript 5 or later might not be supported. However, Edition 5.1 bet
ter reflects
* how actual JS engines worked and work and is simpler and more readable prose.
As such,
* the below code will refer to sections of the 5.1 specification.
*
* See <https://www.ecma-international.org/ecma-262/5.1/>.
*/ */
class JavaScriptMinifier { class JavaScriptMinifier {
/* Parsing states. /* Parsing states.
* The state machine is only necessary to decide whether to parse a slash as division * The state machine is only necessary to decide whether to parse a slash as division
* operator or as regexp literal. * operator or as regexp literal.
* States are named after the next expected item. We only distinguish sta tes when the * States are named after the next expected item. We only distinguish sta tes when the
* distinction is relevant for our purpose. * distinction is relevant for our purpose.
*/ */
const STATEMENT = 0; const STATEMENT = 0;
skipping to change at line 44 skipping to change at line 54
const EXPRESSION_TERNARY_OP = 8; const EXPRESSION_TERNARY_OP = 8;
const EXPRESSION_TERNARY_FUNC = 9; const EXPRESSION_TERNARY_FUNC = 9;
const PAREN_EXPRESSION = 10; // expression which is not on the to p level const PAREN_EXPRESSION = 10; // expression which is not on the to p level
const PAREN_EXPRESSION_OP = 11; const PAREN_EXPRESSION_OP = 11;
const PAREN_EXPRESSION_FUNC = 12; const PAREN_EXPRESSION_FUNC = 12;
const PROPERTY_EXPRESSION = 13; // expression which is within an obj ect literal const PROPERTY_EXPRESSION = 13; // expression which is within an obj ect literal
const PROPERTY_EXPRESSION_OP = 14; const PROPERTY_EXPRESSION_OP = 14;
const PROPERTY_EXPRESSION_FUNC = 15; const PROPERTY_EXPRESSION_FUNC = 15;
/* Token types */ /* Token types */
const TYPE_UN_OP = 1; // unary operators const TYPE_UN_OP = 101; // unary operators
const TYPE_INCR_OP = 2; // ++ and -- const TYPE_INCR_OP = 102; // ++ and --
const TYPE_BIN_OP = 3; // binary operators const TYPE_BIN_OP = 103; // binary operators
const TYPE_ADD_OP = 4; // + and - which can be either unary or binar const TYPE_ADD_OP = 104; // + and - which can be either unary or bin
y ops ary ops
const TYPE_HOOK = 5; // ? const TYPE_HOOK = 105; // ?
const TYPE_COLON = 6; // : const TYPE_COLON = 106; // :
const TYPE_COMMA = 7; // , const TYPE_COMMA = 107; // ,
const TYPE_SEMICOLON = 8; // ; const TYPE_SEMICOLON = 108; // ;
const TYPE_BRACE_OPEN = 9; // { const TYPE_BRACE_OPEN = 109; // {
const TYPE_BRACE_CLOSE = 10; // } const TYPE_BRACE_CLOSE = 110; // }
const TYPE_PAREN_OPEN = 11; // ( and [ const TYPE_PAREN_OPEN = 111; // ( and [
const TYPE_PAREN_CLOSE = 12; // ) and ] const TYPE_PAREN_CLOSE = 112; // ) and ]
const TYPE_RETURN = 13; // keywords: break, continue, return, throw const TYPE_RETURN = 113; // keywords: break, continue, return, throw
const TYPE_IF = 14; // keywords: catch, for, with, switch, while const TYPE_IF = 114; // keywords: catch, for, with, switch, whil
, if e, if
const TYPE_DO = 15; // keywords: case, var, finally, else, do, t const TYPE_DO = 115; // keywords: case, var, finally, else, do,
ry try
const TYPE_FUNC = 16; // keywords: function const TYPE_FUNC = 116; // keywords: function
const TYPE_LITERAL = 17; // all literals, identifiers and unrecognise const TYPE_LITERAL = 117; // all literals, identifiers and unrecognis
d tokens ed tokens
const ACTION_GOTO = 201;
const ACTION_PUSH = 202;
const ACTION_POP = 203;
// Sanity limit to avoid excessive memory usage // Sanity limit to avoid excessive memory usage
const STACK_LIMIT = 1000; const STACK_LIMIT = 1000;
/** /**
* NOTE: This isn't a strict maximum. Longer lines will be produced when * Maximum line length
* literals (e.g. quoted strings) longer than this are encountered *
* or when required to guard against semicolon insertion. * This is not a strict maximum, but a guideline. Longer lines will be
* produced when literals (e.g. quoted strings) longer than this are
* encountered, or when required to guard against semicolon insertion.
*
* This is a private member (instead of constant) to allow tests to
* set it to 1, to verify ASI and line-breaking behaviour.
*/ */
const MAX_LINE_LENGTH = 1000; private static $maxLineLength = 1000;
/** /**
* Returns minified JavaScript code. * Returns minified JavaScript code.
* *
* @param string $s JavaScript code to minify * @param string $s JavaScript code to minify
* @return String Minified code * @return String Minified code
*/ */
public static function minify( $s ) { public static function minify( $s ) {
// First we declare a few tables that contain our parsing rules // First we declare a few tables that contain our parsing rules
// $opChars : characters, which can be combined without whitespac e in between them // $opChars : Characters which can be combined without whitespace between them.
$opChars = [ $opChars = [
'!' => true, // ECMAScript 5.1 § 7.7 Punctuators
'"' => true, // Unlike the spec, these are individual symbols, not seq
'%' => true, uences.
'&' => true, '{' => true,
"'" => true, '}' => true,
'(' => true, '(' => true,
')' => true, ')' => true,
'*' => true, '[' => true,
'+' => true, ']' => true,
',' => true,
'-' => true,
'.' => true, '.' => true,
'/' => true,
':' => true,
';' => true, ';' => true,
',' => true,
'<' => true, '<' => true,
'=' => true,
'>' => true, '>' => true,
'?' => true, '=' => true,
'[' => true, '!' => true,
']' => true, '+' => true,
'^' => true, '-' => true,
'{' => true, '*' => true,
'%' => true,
'&' => true,
'|' => true, '|' => true,
'}' => true, '^' => true,
'~' => true '~' => true,
'?' => true,
':' => true,
'/' => true,
// ECMAScript 5.1 § 7.8.4 String Literals
'"' => true,
"'" => true,
]; ];
// $tokenTypes : maps keywords and operators to their correspondi ng token type // $tokenTypes : Map keywords and operators to their correspondin g token type
$tokenTypes = [ $tokenTypes = [
'!' => self::TYPE_UN_OP, // ECMAScript 5.1 § 11.4 Unary Operators
'~' => self::TYPE_UN_OP, // ECMAScript 5.1 § 11.6 Additive Operators
'delete' => self::TYPE_UN_OP, // UnaryExpression includes PostfixExpression, which incl
udes 'new'.
'new' => self::TYPE_UN_OP, 'new' => self::TYPE_UN_OP,
'typeof' => self::TYPE_UN_OP, 'delete' => self::TYPE_UN_OP,
'void' => self::TYPE_UN_OP, 'void' => self::TYPE_UN_OP,
'typeof' => self::TYPE_UN_OP,
'++' => self::TYPE_INCR_OP, '++' => self::TYPE_INCR_OP,
'--' => self::TYPE_INCR_OP, '--' => self::TYPE_INCR_OP,
'+' => self::TYPE_ADD_OP,
'-' => self::TYPE_ADD_OP,
'~' => self::TYPE_UN_OP,
'!' => self::TYPE_UN_OP,
// ECMAScript 5.1 § 11.5 Multiplicative Operators
'*' => self::TYPE_BIN_OP,
'/' => self::TYPE_BIN_OP,
'%' => self::TYPE_BIN_OP,
// ECMAScript 5.1 § 11.7 Bitwise Shift Operators
'<<' => self::TYPE_BIN_OP,
'>>' => self::TYPE_BIN_OP,
'>>>' => self::TYPE_BIN_OP,
// ECMAScript 5.1 § 11.8 Relational Operators
'<' => self::TYPE_BIN_OP,
'>' => self::TYPE_BIN_OP,
'<=' => self::TYPE_BIN_OP,
'>=' => self::TYPE_BIN_OP,
// ECMAScript 5.1 § 11.9 Equality Operators
'==' => self::TYPE_BIN_OP,
'!=' => self::TYPE_BIN_OP, '!=' => self::TYPE_BIN_OP,
'===' => self::TYPE_BIN_OP,
'!==' => self::TYPE_BIN_OP, '!==' => self::TYPE_BIN_OP,
'%' => self::TYPE_BIN_OP, 'instanceof' => self::TYPE_BIN_OP,
'%=' => self::TYPE_BIN_OP, 'in' => self::TYPE_BIN_OP,
// ECMAScript 5.1 § 11.10 Binary Bitwise Operators
'&' => self::TYPE_BIN_OP, '&' => self::TYPE_BIN_OP,
'^' => self::TYPE_BIN_OP,
'|' => self::TYPE_BIN_OP,
// ECMAScript 5.1 § 11.11 Binary Logical Operators
'&&' => self::TYPE_BIN_OP, '&&' => self::TYPE_BIN_OP,
'&=' => self::TYPE_BIN_OP, '||' => self::TYPE_BIN_OP,
'*' => self::TYPE_BIN_OP, // ECMAScript 5.1 § 11.12 Conditional Operator
// Also known as ternary.
'?' => self::TYPE_HOOK,
':' => self::TYPE_COLON,
// ECMAScript 5.1 § 11.13 Assignment Operators
'=' => self::TYPE_BIN_OP,
'*=' => self::TYPE_BIN_OP, '*=' => self::TYPE_BIN_OP,
'/=' => self::TYPE_BIN_OP,
'%=' => self::TYPE_BIN_OP,
'+=' => self::TYPE_BIN_OP, '+=' => self::TYPE_BIN_OP,
'-=' => self::TYPE_BIN_OP, '-=' => self::TYPE_BIN_OP,
'.' => self::TYPE_BIN_OP,
'/' => self::TYPE_BIN_OP,
'/=' => self::TYPE_BIN_OP,
'<' => self::TYPE_BIN_OP,
'<<' => self::TYPE_BIN_OP,
'<<=' => self::TYPE_BIN_OP, '<<=' => self::TYPE_BIN_OP,
'<=' => self::TYPE_BIN_OP,
'=' => self::TYPE_BIN_OP,
'==' => self::TYPE_BIN_OP,
'===' => self::TYPE_BIN_OP,
'>' => self::TYPE_BIN_OP,
'>=' => self::TYPE_BIN_OP,
'>>' => self::TYPE_BIN_OP,
'>>=' => self::TYPE_BIN_OP, '>>=' => self::TYPE_BIN_OP,
'>>>' => self::TYPE_BIN_OP,
'>>>=' => self::TYPE_BIN_OP, '>>>=' => self::TYPE_BIN_OP,
'^' => self::TYPE_BIN_OP, '&=' => self::TYPE_BIN_OP,
'^=' => self::TYPE_BIN_OP, '^=' => self::TYPE_BIN_OP,
'|' => self::TYPE_BIN_OP,
'|=' => self::TYPE_BIN_OP, '|=' => self::TYPE_BIN_OP,
'||' => self::TYPE_BIN_OP, // ECMAScript 5.1 § 11.14 Comma Operator
'in' => self::TYPE_BIN_OP,
'instanceof' => self::TYPE_BIN_OP,
'+' => self::TYPE_ADD_OP,
'-' => self::TYPE_ADD_OP,
'?' => self::TYPE_HOOK,
':' => self::TYPE_COLON,
',' => self::TYPE_COMMA, ',' => self::TYPE_COMMA,
';' => self::TYPE_SEMICOLON,
'{' => self::TYPE_BRACE_OPEN, // The keywords that disallow LineTerminator before their
'}' => self::TYPE_BRACE_CLOSE, // (sometimes optional) Expression or Identifier.
'(' => self::TYPE_PAREN_OPEN, //
'[' => self::TYPE_PAREN_OPEN, // keyword ;
')' => self::TYPE_PAREN_CLOSE, // keyword [no LineTerminator here] Identifier ;
']' => self::TYPE_PAREN_CLOSE, // keyword [no LineTerminator here] Expression ;
'break' => self::TYPE_RETURN, //
// See also ECMAScript 5.1:
// - § 12.7 The continue Statement
// - $ 12.8 The break Statement
// - § 12.9 The return Statement
// - § 12.13 The throw Statement
'continue' => self::TYPE_RETURN, 'continue' => self::TYPE_RETURN,
'break' => self::TYPE_RETURN,
'return' => self::TYPE_RETURN, 'return' => self::TYPE_RETURN,
'throw' => self::TYPE_RETURN, 'throw' => self::TYPE_RETURN,
// The keywords require a parenthesised Expression or Ide
ntifier
// before the next Statement.
//
// keyword ( Expression ) Statement
// keyword ( Identifier ) Statement
//
// See also ECMAScript 5.1:
// - § 12.5 The if Statement
// - § 12.6 Iteration Statements (do, while, for)
// - § 12.10 The with Statement
// - § 12.11 The switch Statement
// - § 12.13 The throw Statement
'if' => self::TYPE_IF,
'catch' => self::TYPE_IF, 'catch' => self::TYPE_IF,
'while' => self::TYPE_IF,
'for' => self::TYPE_IF, 'for' => self::TYPE_IF,
'if' => self::TYPE_IF,
'switch' => self::TYPE_IF, 'switch' => self::TYPE_IF,
'while' => self::TYPE_IF,
'with' => self::TYPE_IF, 'with' => self::TYPE_IF,
'case' => self::TYPE_DO,
'do' => self::TYPE_DO, // The keywords followed by an Identifier, Statement,
// Expression, or Block.
//
// var Identifier
// else Statement
// do Statement
// case Expression
// try Block
// finally Block
//
// See also ECMAScript 5.1:
// - § 12.2 Variable Statement
// - § 12.5 The if Statement (else)
// - § 12.6 Iteration Statements (do, while, for)
// - § 12.11 The switch Statement (case)
// - § 12.14 The try Statement
'var' => self::TYPE_DO,
'else' => self::TYPE_DO, 'else' => self::TYPE_DO,
'finally' => self::TYPE_DO, 'do' => self::TYPE_DO,
'case' => self::TYPE_DO,
'try' => self::TYPE_DO, 'try' => self::TYPE_DO,
'var' => self::TYPE_DO, 'finally' => self::TYPE_DO,
'function' => self::TYPE_FUNC
];
// $goto : This is the main table for our state machine. For ever // ECMAScript 5.1 § 13 Function Definition
y state/token pair 'function' => self::TYPE_FUNC,
// the following state is defined. When no rule exists fo
r a given pair, // Can be one of:
// the state is left unchanged. // - DecimalLiteral (ECMAScript 5.1 § 7.8.3 Numeric Liter
$goto = [ als)
self::STATEMENT => [ // - MemberExpression (ECMAScript 5.1 § 11.2 Left-Hand-Si
self::TYPE_UN_OP => self::EXPRESSION, de Expressions)
self::TYPE_INCR_OP => self::EXPRESSION, '.' => self::TYPE_BIN_OP,
self::TYPE_ADD_OP => self::EXPRESSION,
self::TYPE_PAREN_OPEN => self::PAREN_EXPRESSION, // Can be one of:
self::TYPE_RETURN => self::EXPRESSION_NO_NL, // - Block (ECMAScript 5.1 § 12.1 Block)
self::TYPE_IF => self::CONDITION, // - ObjectLiteral (ECMAScript 5.1 § 11.1 Primary Express
self::TYPE_FUNC => self::CONDITION, ions)
self::TYPE_LITERAL => self::EXPRESSION_OP '{' => self::TYPE_BRACE_OPEN,
], '}' => self::TYPE_BRACE_CLOSE,
self::CONDITION => [
self::TYPE_PAREN_OPEN => self::PAREN_EXPRESSION // Can be one of:
], // - Parenthesised Identifier or Expression after a
self::PROPERTY_ASSIGNMENT => [ // TYPE_IF or TYPE_FUNC keyword.
self::TYPE_COLON => self::PROPERTY_EXPRESSIO // - PrimaryExpression (ECMAScript 5.1 § 11.1 Primary Exp
N, ressions)
self::TYPE_BRACE_OPEN => self::STATEMENT // - CallExpression (ECMAScript 5.1 § 11.2 Left-Hand-Side
], Expressions)
self::EXPRESSION => [ '(' => self::TYPE_PAREN_OPEN,
self::TYPE_SEMICOLON => self::STATEMENT, ')' => self::TYPE_PAREN_CLOSE,
self::TYPE_BRACE_OPEN => self::PROPERTY_ASSIGNMEN
T, // Can be one of:
self::TYPE_PAREN_OPEN => self::PAREN_EXPRESSION, // - ArrayLiteral (ECMAScript 5.1 § 11.1 Primary Expressi
self::TYPE_FUNC => self::EXPRESSION_FUNC, ons)
self::TYPE_LITERAL => self::EXPRESSION_OP '[' => self::TYPE_PAREN_OPEN,
], ']' => self::TYPE_PAREN_CLOSE,
self::EXPRESSION_NO_NL => [
self::TYPE_SEMICOLON => self::STATEMENT, // Can be one of:
self::TYPE_BRACE_OPEN => self::PROPERTY_ASSIGNMEN // - End of any statement
T, // - EmptyStatement (ECMAScript 5.1 § 12.3 Empty Statemen
self::TYPE_PAREN_OPEN => self::PAREN_EXPRESSION, t)
self::TYPE_FUNC => self::EXPRESSION_FUNC, ';' => self::TYPE_SEMICOLON,
self::TYPE_LITERAL => self::EXPRESSION_OP
],
self::EXPRESSION_OP => [
self::TYPE_BIN_OP => self::EXPRESSION,
self::TYPE_ADD_OP => self::EXPRESSION,
self::TYPE_HOOK => self::EXPRESSION_TERNARY
,
self::TYPE_COLON => self::STATEMENT,
self::TYPE_COMMA => self::EXPRESSION,
self::TYPE_SEMICOLON => self::STATEMENT,
self::TYPE_PAREN_OPEN => self::PAREN_EXPRESSION
],
self::EXPRESSION_FUNC => [
self::TYPE_BRACE_OPEN => self::STATEMENT
],
self::EXPRESSION_TERNARY => [
self::TYPE_BRACE_OPEN => self::PROPERTY_ASSIGNMEN
T,
self::TYPE_PAREN_OPEN => self::PAREN_EXPRESSION,
self::TYPE_FUNC => self::EXPRESSION_TERNARY
_FUNC,
self::TYPE_LITERAL => self::EXPRESSION_TERNARY
_OP
],
self::EXPRESSION_TERNARY_OP => [
self::TYPE_BIN_OP => self::EXPRESSION_TERNARY
,
self::TYPE_ADD_OP => self::EXPRESSION_TERNARY
,
self::TYPE_HOOK => self::EXPRESSION_TERNARY
,
self::TYPE_COMMA => self::EXPRESSION_TERNARY
,
self::TYPE_PAREN_OPEN => self::PAREN_EXPRESSION
],
self::EXPRESSION_TERNARY_FUNC => [
self::TYPE_BRACE_OPEN => self::STATEMENT
],
self::PAREN_EXPRESSION => [
self::TYPE_BRACE_OPEN => self::PROPERTY_ASSIGNMEN
T,
self::TYPE_PAREN_OPEN => self::PAREN_EXPRESSION,
self::TYPE_FUNC => self::PAREN_EXPRESSION_F
UNC,
self::TYPE_LITERAL => self::PAREN_EXPRESSION_O
P
],
self::PAREN_EXPRESSION_OP => [
self::TYPE_BIN_OP => self::PAREN_EXPRESSION,
self::TYPE_ADD_OP => self::PAREN_EXPRESSION,
self::TYPE_HOOK => self::PAREN_EXPRESSION,
self::TYPE_COLON => self::PAREN_EXPRESSION,
self::TYPE_COMMA => self::PAREN_EXPRESSION,
self::TYPE_SEMICOLON => self::PAREN_EXPRESSION,
self::TYPE_PAREN_OPEN => self::PAREN_EXPRESSION
],
self::PAREN_EXPRESSION_FUNC => [
self::TYPE_BRACE_OPEN => self::STATEMENT
],
self::PROPERTY_EXPRESSION => [
self::TYPE_BRACE_OPEN => self::PROPERTY_ASSIGNMEN
T,
self::TYPE_PAREN_OPEN => self::PAREN_EXPRESSION,
self::TYPE_FUNC => self::PROPERTY_EXPRESSIO
N_FUNC,
self::TYPE_LITERAL => self::PROPERTY_EXPRESSIO
N_OP
],
self::PROPERTY_EXPRESSION_OP => [
self::TYPE_BIN_OP => self::PROPERTY_EXPRESSIO
N,
self::TYPE_ADD_OP => self::PROPERTY_EXPRESSIO
N,
self::TYPE_HOOK => self::PROPERTY_EXPRESSIO
N,
self::TYPE_COMMA => self::PROPERTY_ASSIGNMEN
T,
self::TYPE_PAREN_OPEN => self::PAREN_EXPRESSION
],
self::PROPERTY_EXPRESSION_FUNC => [
self::TYPE_BRACE_OPEN => self::STATEMENT
]
]; ];
// $push : This table contains the rules for when to push a state // $model : This is the main table for our state machine. For eve
onto the stack. ry state/token pair
// The pushed state is the state to return to when the co // the desired action is defined.
rresponding //
// closing token is found // The state pushed onto the stack by ACTION_PUSH will be returne
$push = [ d to by ACTION_POP.
//
// A given state/token pair MAY NOT specify both ACTION_POP and A
CTION_GOTO.
// In the event of such mistake, ACTION_POP is used instead of AC
TION_GOTO.
$model = [
// Statement - This is the initial state.
self::STATEMENT => [ self::STATEMENT => [
self::TYPE_BRACE_OPEN => self::STATEMENT, self::TYPE_UN_OP => [
self::TYPE_PAREN_OPEN => self::EXPRESSION_OP self::ACTION_GOTO => self::EXPRESSION,
],
self::TYPE_INCR_OP => [
self::ACTION_GOTO => self::EXPRESSION,
],
self::TYPE_ADD_OP => [
self::ACTION_GOTO => self::EXPRESSION,
],
self::TYPE_BRACE_OPEN => [
// Use of '{' in statement context, creat
es a Block.
self::ACTION_PUSH => self::STATEMENT,
],
self::TYPE_BRACE_CLOSE => [
// Ends a Block
self::ACTION_POP => true,
],
self::TYPE_PAREN_OPEN => [
self::ACTION_PUSH => self::EXPRESSION_OP,
self::ACTION_GOTO => self::PAREN_EXPRESSI
ON,
],
self::TYPE_RETURN => [
self::ACTION_GOTO => self::EXPRESSION_NO_
NL,
],
self::TYPE_IF => [
self::ACTION_GOTO => self::CONDITION,
],
self::TYPE_FUNC => [
self::ACTION_GOTO => self::CONDITION,
],
self::TYPE_LITERAL => [
self::ACTION_GOTO => self::EXPRESSION_OP,
],
], ],
self::CONDITION => [ self::CONDITION => [
self::TYPE_PAREN_OPEN => self::STATEMENT self::TYPE_PAREN_OPEN => [
self::ACTION_PUSH => self::STATEMENT,
self::ACTION_GOTO => self::PAREN_EXPRESSI
ON,
],
], ],
// Property assignment - This is an object literal declar
ation.
// For example: `{ key: value }`
self::PROPERTY_ASSIGNMENT => [ self::PROPERTY_ASSIGNMENT => [
self::TYPE_BRACE_OPEN => self::PROPERTY_ASSIGNMEN self::TYPE_COLON => [
T self::ACTION_GOTO => self::PROPERTY_EXPRE
SSION,
],
self::TYPE_BRACE_OPEN => [
self::ACTION_PUSH => self::PROPERTY_ASSIG
NMENT,
self::ACTION_GOTO => self::STATEMENT,
],
self::TYPE_BRACE_CLOSE => [
self::ACTION_POP => true,
],
], ],
self::EXPRESSION => [ self::EXPRESSION => [
self::TYPE_BRACE_OPEN => self::EXPRESSION_OP, self::TYPE_SEMICOLON => [
self::TYPE_PAREN_OPEN => self::EXPRESSION_OP self::ACTION_GOTO => self::STATEMENT,
],
self::TYPE_BRACE_OPEN => [
self::ACTION_PUSH => self::EXPRESSION_OP,
self::ACTION_GOTO => self::PROPERTY_ASSIG
NMENT,
],
self::TYPE_BRACE_CLOSE => [
self::ACTION_POP => true,
],
self::TYPE_PAREN_OPEN => [
self::ACTION_PUSH => self::EXPRESSION_OP,
self::ACTION_GOTO => self::PAREN_EXPRESSI
ON,
],
self::TYPE_FUNC => [
self::ACTION_GOTO => self::EXPRESSION_FUN
C,
],
self::TYPE_LITERAL => [
self::ACTION_GOTO => self::EXPRESSION_OP,
],
], ],
self::EXPRESSION_NO_NL => [ self::EXPRESSION_NO_NL => [
self::TYPE_BRACE_OPEN => self::EXPRESSION_OP, self::TYPE_SEMICOLON => [
self::TYPE_PAREN_OPEN => self::EXPRESSION_OP self::ACTION_GOTO => self::STATEMENT,
],
self::TYPE_BRACE_OPEN => [
self::ACTION_PUSH => self::EXPRESSION_OP,
self::ACTION_GOTO => self::PROPERTY_ASSIG
NMENT,
],
self::TYPE_BRACE_CLOSE => [
self::ACTION_POP => true,
],
self::TYPE_PAREN_OPEN => [
self::ACTION_PUSH => self::EXPRESSION_OP,
self::ACTION_GOTO => self::PAREN_EXPRESSI
ON,
],
self::TYPE_FUNC => [
self::ACTION_GOTO => self::EXPRESSION_FUN
C,
],
self::TYPE_LITERAL => [
self::ACTION_GOTO => self::EXPRESSION_OP,
],
], ],
self::EXPRESSION_OP => [ self::EXPRESSION_OP => [
self::TYPE_HOOK => self::EXPRESSION, self::TYPE_BIN_OP => [
self::TYPE_PAREN_OPEN => self::EXPRESSION_OP self::ACTION_GOTO => self::EXPRESSION,
],
self::TYPE_ADD_OP => [
self::ACTION_GOTO => self::EXPRESSION,
],
self::TYPE_HOOK => [
self::ACTION_PUSH => self::EXPRESSION,
self::ACTION_GOTO => self::EXPRESSION_TER
NARY,
],
self::TYPE_COLON => [
self::ACTION_GOTO => self::STATEMENT,
],
self::TYPE_COMMA => [
self::ACTION_GOTO => self::EXPRESSION,
],
self::TYPE_SEMICOLON => [
self::ACTION_GOTO => self::STATEMENT,
],
self::TYPE_PAREN_OPEN => [
self::ACTION_PUSH => self::EXPRESSION_OP,
self::ACTION_GOTO => self::PAREN_EXPRESSI
ON,
],
self::TYPE_BRACE_CLOSE => [
self::ACTION_POP => true,
],
], ],
self::EXPRESSION_FUNC => [ self::EXPRESSION_FUNC => [
self::TYPE_BRACE_OPEN => self::EXPRESSION_OP self::TYPE_BRACE_OPEN => [
self::ACTION_PUSH => self::EXPRESSION_OP,
self::ACTION_GOTO => self::STATEMENT,
],
], ],
self::EXPRESSION_TERNARY => [ self::EXPRESSION_TERNARY => [
self::TYPE_BRACE_OPEN => self::EXPRESSION_TERNARY self::TYPE_BRACE_OPEN => [
_OP, self::ACTION_PUSH => self::EXPRESSION_TER
self::TYPE_PAREN_OPEN => self::EXPRESSION_TERNARY NARY_OP,
_OP self::ACTION_GOTO => self::PROPERTY_ASSIG
NMENT,
],
self::TYPE_PAREN_OPEN => [
self::ACTION_PUSH => self::EXPRESSION_TER
NARY_OP,
self::ACTION_GOTO => self::PAREN_EXPRESSI
ON,
],
self::TYPE_FUNC => [
self::ACTION_GOTO => self::EXPRESSION_TER
NARY_FUNC,
],
self::TYPE_LITERAL => [
self::ACTION_GOTO => self::EXPRESSION_TER
NARY_OP,
],
], ],
self::EXPRESSION_TERNARY_OP => [ self::EXPRESSION_TERNARY_OP => [
self::TYPE_HOOK => self::EXPRESSION_TERNARY self::TYPE_BIN_OP => [
, self::ACTION_GOTO => self::EXPRESSION_TER
self::TYPE_PAREN_OPEN => self::EXPRESSION_TERNARY NARY,
_OP ],
self::TYPE_ADD_OP => [
self::ACTION_GOTO => self::EXPRESSION_TER
NARY,
],
self::TYPE_HOOK => [
self::ACTION_PUSH => self::EXPRESSION_TER
NARY,
self::ACTION_GOTO => self::EXPRESSION_TER
NARY,
],
self::TYPE_COMMA => [
self::ACTION_GOTO => self::EXPRESSION_TER
NARY,
],
self::TYPE_PAREN_OPEN => [
self::ACTION_PUSH => self::EXPRESSION_TER
NARY_OP,
self::ACTION_GOTO => self::PAREN_EXPRESSI
ON,
],
self::TYPE_COLON => [
self::ACTION_POP => true,
],
], ],
self::EXPRESSION_TERNARY_FUNC => [ self::EXPRESSION_TERNARY_FUNC => [
self::TYPE_BRACE_OPEN => self::EXPRESSION_TERNARY self::TYPE_BRACE_OPEN => [
_OP self::ACTION_PUSH => self::EXPRESSION_TER
NARY_OP,
self::ACTION_GOTO => self::STATEMENT,
],
], ],
self::PAREN_EXPRESSION => [ self::PAREN_EXPRESSION => [
self::TYPE_BRACE_OPEN => self::PAREN_EXPRESSION_O self::TYPE_BRACE_OPEN => [
P, self::ACTION_PUSH => self::PAREN_EXPRESSI
self::TYPE_PAREN_OPEN => self::PAREN_EXPRESSION_O ON_OP,
P self::ACTION_GOTO => self::PROPERTY_ASSIG
NMENT,
],
self::TYPE_PAREN_OPEN => [
self::ACTION_PUSH => self::PAREN_EXPRESSI
ON_OP,
self::ACTION_GOTO => self::PAREN_EXPRESSI
ON,
],
self::TYPE_PAREN_CLOSE => [
self::ACTION_POP => true,
],
self::TYPE_FUNC => [
self::ACTION_GOTO => self::PAREN_EXPRESSI
ON_FUNC,
],
self::TYPE_LITERAL => [
self::ACTION_GOTO => self::PAREN_EXPRESSI
ON_OP,
],
], ],
self::PAREN_EXPRESSION_OP => [ self::PAREN_EXPRESSION_OP => [
self::TYPE_PAREN_OPEN => self::PAREN_EXPRESSION_O self::TYPE_BIN_OP => [
P self::ACTION_GOTO => self::PAREN_EXPRESSI
ON,
],
self::TYPE_ADD_OP => [
self::ACTION_GOTO => self::PAREN_EXPRESSI
ON,
],
self::TYPE_HOOK => [
self::ACTION_GOTO => self::PAREN_EXPRESSI
ON,
],
self::TYPE_COLON => [
self::ACTION_GOTO => self::PAREN_EXPRESSI
ON,
],
self::TYPE_COMMA => [
self::ACTION_GOTO => self::PAREN_EXPRESSI
ON,
],
self::TYPE_SEMICOLON => [
self::ACTION_GOTO => self::PAREN_EXPRESSI
ON,
],
self::TYPE_PAREN_OPEN => [
self::ACTION_PUSH => self::PAREN_EXPRESSI
ON_OP,
self::ACTION_GOTO => self::PAREN_EXPRESSI
ON,
],
self::TYPE_PAREN_CLOSE => [
self::ACTION_POP => true,
],
], ],
self::PAREN_EXPRESSION_FUNC => [ self::PAREN_EXPRESSION_FUNC => [
self::TYPE_BRACE_OPEN => self::PAREN_EXPRESSION_O self::TYPE_BRACE_OPEN => [
P self::ACTION_PUSH => self::PAREN_EXPRESSI
ON_OP,
self::ACTION_GOTO => self::STATEMENT,
],
], ],
// Property expression - The value of a key in an object literal.
self::PROPERTY_EXPRESSION => [ self::PROPERTY_EXPRESSION => [
self::TYPE_BRACE_OPEN => self::PROPERTY_EXPRESSIO self::TYPE_BRACE_OPEN => [
N_OP, self::ACTION_PUSH => self::PROPERTY_EXPRE
self::TYPE_PAREN_OPEN => self::PROPERTY_EXPRESSIO SSION_OP,
N_OP self::ACTION_GOTO => self::PROPERTY_ASSIG
NMENT,
],
self::TYPE_BRACE_CLOSE => [
self::ACTION_POP => true,
],
self::TYPE_PAREN_OPEN => [
self::ACTION_PUSH => self::PROPERTY_EXPRE
SSION_OP,
self::ACTION_GOTO => self::PAREN_EXPRESSI
ON,
],
self::TYPE_FUNC => [
self::ACTION_GOTO => self::PROPERTY_EXPRE
SSION_FUNC,
],
self::TYPE_LITERAL => [
self::ACTION_GOTO => self::PROPERTY_EXPRE
SSION_OP,
],
], ],
self::PROPERTY_EXPRESSION_OP => [ self::PROPERTY_EXPRESSION_OP => [
self::TYPE_PAREN_OPEN => self::PROPERTY_EXPRESSIO self::TYPE_BIN_OP => [
N_OP self::ACTION_GOTO => self::PROPERTY_EXPRE
SSION,
],
self::TYPE_ADD_OP => [
self::ACTION_GOTO => self::PROPERTY_EXPRE
SSION,
],
self::TYPE_HOOK => [
self::ACTION_PUSH => self::PROPERTY_EXPRE
SSION,
self::ACTION_GOTO => self::EXPRESSION_TER
NARY,
],
self::TYPE_COMMA => [
self::ACTION_GOTO => self::PROPERTY_ASSIG
NMENT,
],
self::TYPE_BRACE_OPEN => [
self::ACTION_PUSH => self::PROPERTY_EXPRE
SSION_OP,
],
self::TYPE_BRACE_CLOSE => [
self::ACTION_POP => true,
],
self::TYPE_PAREN_OPEN => [
self::ACTION_PUSH => self::PROPERTY_EXPRE
SSION_OP,
self::ACTION_GOTO => self::PAREN_EXPRESSI
ON,
],
], ],
self::PROPERTY_EXPRESSION_FUNC => [ self::PROPERTY_EXPRESSION_FUNC => [
self::TYPE_BRACE_OPEN => self::PROPERTY_EXPRESSIO self::TYPE_BRACE_OPEN => [
N_OP self::ACTION_PUSH => self::PROPERTY_EXPRE
] SSION_OP,
]; self::ACTION_GOTO => self::STATEMENT,
],
// $pop : Rules for when to pop a state from the stack ],
$pop = [
self::STATEMENT => [ self::TYPE_BRACE_CLOSE
=> true ],
self::PROPERTY_ASSIGNMENT => [ self::TYPE_BRACE_CLOSE
=> true ],
self::EXPRESSION => [ self::TYPE_BRACE_CLOSE
=> true ],
self::EXPRESSION_NO_NL => [ self::TYPE_BRACE_CLOSE
=> true ],
self::EXPRESSION_OP => [ self::TYPE_BRACE_CLOSE
=> true ],
self::EXPRESSION_TERNARY_OP => [ self::TYPE_COLON
=> true ],
self::PAREN_EXPRESSION => [ self::TYPE_PAREN_CLOSE
=> true ],
self::PAREN_EXPRESSION_OP => [ self::TYPE_PAREN_CLOSE
=> true ],
self::PROPERTY_EXPRESSION => [ self::TYPE_BRACE_CLOSE
=> true ],
self::PROPERTY_EXPRESSION_OP => [ self::TYPE_BRACE_CLOSE
=> true ]
]; ];
// $semicolon : Rules for when a semicolon insertion is appropria te // $semicolon : Rules for when a semicolon insertion is appropria te
$semicolon = [ $semicolon = [
self::EXPRESSION_NO_NL => [ self::EXPRESSION_NO_NL => [
self::TYPE_UN_OP => true, self::TYPE_UN_OP => true,
self::TYPE_INCR_OP => true, self::TYPE_INCR_OP => true,
self::TYPE_ADD_OP => true, self::TYPE_ADD_OP => true,
self::TYPE_BRACE_OPEN => true, self::TYPE_BRACE_OPEN => true,
self::TYPE_PAREN_OPEN => true, self::TYPE_PAREN_OPEN => true,
self::TYPE_RETURN => true, self::TYPE_RETURN => true,
self::TYPE_IF => true, self::TYPE_IF => true,
self::TYPE_DO => true, self::TYPE_DO => true,
self::TYPE_FUNC => true, self::TYPE_FUNC => true,
self::TYPE_LITERAL => true self::TYPE_LITERAL => true
], ],
self::EXPRESSION_OP => [ self::EXPRESSION_OP => [
self::TYPE_UN_OP => true, self::TYPE_UN_OP => true,
self::TYPE_INCR_OP => true, self::TYPE_INCR_OP => true,
self::TYPE_BRACE_OPEN => true, self::TYPE_BRACE_OPEN => true,
self::TYPE_RETURN => true, self::TYPE_RETURN => true,
self::TYPE_IF => true, self::TYPE_IF => true,
self::TYPE_DO => true, self::TYPE_DO => true,
self::TYPE_FUNC => true, self::TYPE_FUNC => true,
self::TYPE_LITERAL => true self::TYPE_LITERAL => true
] ]
]; ];
// $divStates : Contains all states that can be followed by a div ision operator // $divStates : Contains all states that can be followed by a div ision operator
$divStates = [ $divStates = [
self::EXPRESSION_OP => true, self::EXPRESSION_OP => true,
self::EXPRESSION_TERNARY_OP => true, self::EXPRESSION_TERNARY_OP => true,
self::PAREN_EXPRESSION_OP => true, self::PAREN_EXPRESSION_OP => true,
self::PROPERTY_EXPRESSION_OP => true self::PROPERTY_EXPRESSION_OP => true
]; ];
skipping to change at line 575 skipping to change at line 792
$end++; $end++;
} }
} else { } else {
// Identifier or reserved word. Search for the en d by excluding whitespace and // Identifier or reserved word. Search for the en d by excluding whitespace and
// punctuation. // punctuation.
$end += strcspn( $s, " \t\n.;,=<>+-{}()[]?:*/%'\" !&|^~\xb\xc\r", $end ); $end += strcspn( $s, " \t\n.;,=<>+-{}()[]?:*/%'\" !&|^~\xb\xc\r", $end );
} }
// Now get the token type from our type array // Now get the token type from our type array
$token = substr( $s, $pos, $end - $pos ); // so $end - $p os == strlen( $token ) $token = substr( $s, $pos, $end - $pos ); // so $end - $p os == strlen( $token )
$type = isset( $tokenTypes[$token] ) ? $tokenTypes[$token ] : self::TYPE_LITERAL; $type = $tokenTypes[$token] ?? self::TYPE_LITERAL;
if ( $newlineFound && isset( $semicolon[$state][$type] ) ) { if ( $newlineFound && isset( $semicolon[$state][$type] ) ) {
// This token triggers the semicolon insertion me chanism of javascript. While we // This token triggers the semicolon insertion me chanism of javascript. While we
// could add the ; token here ourselves, keeping the newline has a few advantages. // could add the ; token here ourselves, keeping the newline has a few advantages.
$out .= "\n"; $out .= "\n";
$state = self::STATEMENT; $state = self::STATEMENT;
$lineLength = 0; $lineLength = 0;
} elseif ( $lineLength + $end - $pos > self::MAX_LINE_LEN GTH && } elseif ( $lineLength + $end - $pos > self::$maxLineLeng th &&
!isset( $semicolon[$state][$type] ) && $t ype !== self::TYPE_INCR_OP ) { !isset( $semicolon[$state][$type] ) && $t ype !== self::TYPE_INCR_OP ) {
// This line would get too long if we added $toke n, so add a newline first. // This line would get too long if we added $toke n, so add a newline first.
// Only do this if it won't trigger semicolon ins ertion and if it won't // Only do this if it won't trigger semicolon ins ertion and if it won't
// put a postfix increment operator on its own li ne, which is illegal in js. // put a postfix increment operator on its own li ne, which is illegal in js.
$out .= "\n"; $out .= "\n";
$lineLength = 0; $lineLength = 0;
// Check, whether we have to separate the token from the last one with whitespace // Check, whether we have to separate the token from the last one with whitespace
} elseif ( !isset( $opChars[$last] ) && !isset( $opChars[ $ch] ) ) { } elseif ( !isset( $opChars[$last] ) && !isset( $opChars[ $ch] ) ) {
$out .= ' '; $out .= ' ';
$lineLength++; $lineLength++;
skipping to change at line 615 skipping to change at line 832
$token = ( $token === 'true' ) ? '!0' : '!1'; $token = ( $token === 'true' ) ? '!0' : '!1';
} }
$out .= $token; $out .= $token;
$lineLength += $end - $pos; // += strlen( $token ) $lineLength += $end - $pos; // += strlen( $token )
$last = $s[$end - 1]; $last = $s[$end - 1];
$pos = $end; $pos = $end;
$newlineFound = false; $newlineFound = false;
// Now that we have output our token, transition into the new state. // Now that we have output our token, transition into the new state.
if ( isset( $push[$state][$type] ) && count( $stack ) < s if ( isset( $model[$state][$type][self::ACTION_PUSH] ) &&
elf::STACK_LIMIT ) { count( $stack ) < self::STACK_LIMIT
$stack[] = $push[$state][$type]; ) {
$stack[] = $model[$state][$type][self::ACTION_PUS
H];
} }
if ( $stack && isset( $pop[$state][$type] ) ) { if ( $stack && isset( $model[$state][$type][self::ACTION_ POP] ) ) {
$state = array_pop( $stack ); $state = array_pop( $stack );
} elseif ( isset( $goto[$state][$type] ) ) { } elseif ( isset( $model[$state][$type][self::ACTION_GOTO
$state = $goto[$state][$type]; ] ) ) {
$state = $model[$state][$type][self::ACTION_GOTO]
;
} }
} }
return $out; return $out;
} }
static function parseError( $fullJavascript, $position, $errorMsg ) { static function parseError( $fullJavascript, $position, $errorMsg ) {
// TODO: Handle the error: trigger_error, throw exception, return false... // TODO: Handle the error: trigger_error, throw exception, return false...
return false; return false;
} }
} }
 End of changes. 67 change blocks. 
305 lines changed or deleted 553 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)