Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ECMAScript comment to JSMin.cs/NextCharExcludingComments() #177

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 88 additions & 66 deletions ClientDependency.Core/CompositeFiles/JSMin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,51 +43,51 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*/

namespace ClientDependency.Core.CompositeFiles
{
public class JSMin
{
private const int Eof = -1;
private TextReader _sr;
private TextWriter _sw;
private int _theA;
private int _theB;
private int _theLookahead = Eof;
private int _theX = Eof;
private int _theY = Eof;
private int _retStatement = -1;
private bool _start = false;
[Obsolete("Use the overloads specifying a Stream instead")]
public static string CompressJS(string body)
{
return new JSMin().Minify(body);
}
public static string CompressJS(Stream stream)
{
var jsMin = new JSMin();
if (!stream.CanRead) throw new InvalidOperationException("Cannot read input stream");
if (stream.CanSeek)
{
stream.Position = 0;
}
return jsMin.Minify(new StreamReader(stream));
}
[Obsolete("Use the overloads specifying a TextReader instead")]
public string Minify(string src)
{
StringBuilder sb = new StringBuilder();
using (_sr = new StringReader(src))
{
using (_sw = new StringWriter(sb))
{
ExecuteJsMin();
}
}
return sb.ToString();
}
{
public class JSMin
{
private const int Eof = -1;
private TextReader _sr;
private TextWriter _sw;
private int _theA;
private int _theB;
private int _theLookahead = Eof;
private int _theX = Eof;
private int _theY = Eof;
private int _retStatement = -1;
private bool _start = false;

[Obsolete("Use the overloads specifying a Stream instead")]
public static string CompressJS(string body)
{
return new JSMin().Minify(body);
}

public static string CompressJS(Stream stream)
{
var jsMin = new JSMin();
if (!stream.CanRead) throw new InvalidOperationException("Cannot read input stream");
if (stream.CanSeek)
{
stream.Position = 0;
}
return jsMin.Minify(new StreamReader(stream));
}

[Obsolete("Use the overloads specifying a TextReader instead")]
public string Minify(string src)
{
StringBuilder sb = new StringBuilder();
using (_sr = new StringReader(src))
{
using (_sw = new StringWriter(sb))
{
ExecuteJsMin();
}
}
return sb.ToString();
}

public string Minify(TextReader reader)
{
_sr = reader;
Expand Down Expand Up @@ -126,7 +126,7 @@ private void ExecuteJsMin()
break;
case '\n':
case '\u2028':
case '\u2029':
case '\u2029':
switch (_theB)
{
case '{':
Expand All @@ -146,9 +146,9 @@ private void ExecuteJsMin()
//Maintain the line break
Action(1);
break;
case ' ':
case ' ':
Action(3);
break;
break;
default:
if (!_start)
{
Expand All @@ -164,7 +164,7 @@ private void ExecuteJsMin()
default:
switch (_theB)
{

case ' ':
Action(IsAlphanum(_theA) ? 1 : 3);
break;
Expand Down Expand Up @@ -221,8 +221,8 @@ void Action(int d)

//process string literals or end of statement and track return statement
if (!HandleStringLiteral())
HandleEndOfStatement();
HandleEndOfStatement();

goto case 3;
case 3:
_theB = NextCharExcludingComments();
Expand Down Expand Up @@ -260,8 +260,8 @@ private bool TrackReturnStatement()
{
_retStatement = 0;
return true;
}
}

if (_retStatement >= (r.Length - 1))
{
//reset when there is a return statement and the next char is not whitespace
Expand All @@ -287,8 +287,8 @@ private bool TrackReturnStatement()
/// </summary>
private bool HandleEndOfStatement()
{
if (_theA != '}') return false;
if (_theA != '}') return false;

var peek = Peek();
//NOTE: We don't skip over a new line, this is becase in some cases
// library managers don't put a semicolon after a } when they have defined a variable as a method,
Expand All @@ -308,15 +308,15 @@ private bool HandleEndOfStatement()
private bool HandleStringLiteral()
{
if (_theA != '\'' && _theA != '"' && _theA != '`')
return false;
//only allowed with template strings
var allowLineFeed = _theA == '`';
//write the start quote
return false;

//only allowed with template strings
var allowLineFeed = _theA == '`';

//write the start quote
Put(_theA);
_theA = Get(replaceCr: !allowLineFeed); //don't replace CR here, if we need to deal with that

for (;;)
{
//If the A matches B it means the string literal is done
Expand All @@ -327,14 +327,14 @@ private bool HandleStringLiteral()
Put(_theA);

//reset, this essentially resets the process
_theA = ' ';
_theA = ' ';
break;
}

var skipRead = false;

switch (_theA)
{
{
case '\r':
case '\n':
if (!allowLineFeed)
Expand All @@ -359,7 +359,7 @@ private bool HandleStringLiteral()
Put(_theA); //write the backslash
_theA = Get(); //get the escaped char
if (_theA == Eof)
throw new Exception($"Error: JSMIN unterminated string literal: {_theA}\n");
throw new Exception($"Error: JSMIN unterminated string literal: {_theA}\n");
Put(_theA); //write the escaped char
_theA = Get();
skipRead = true; //go to beginning of loop
Expand Down Expand Up @@ -590,6 +590,26 @@ private int NextCharExcludingComments()
}
}

//ECMA javascript standard comment format <!--singleLinecommentChars-->
else if (c=='<')
{
if (Peek()=='!')
{
for(;;)
{
c = Get();
if(c=='-'){
if(Peek()=='>')
{
Get();
break;
}
}
}
c = Get();
}
}

_theY = _theX;
_theX = c;
return c;
Expand All @@ -615,6 +635,8 @@ private int Get(bool replaceCr = true)
{
int c = _theLookahead;
_theLookahead = Eof;
//c==Eof means Get() without Peek()
//if c!=Eof means the next char already in Peek(), no need to read again
if (c == Eof)
{
c = _sr.Read();
Expand Down Expand Up @@ -662,4 +684,4 @@ private bool IsLineSeparator(int c)
}

}
}
}