JSMin是一个很好的JS压缩工具,只是使用时比较不方便,于是,我给它加了个GUI,增加了多线程支持,这样,可以尽量提高JSMin的操作性。
//核心代码
void JSMinDialog::DoOK(const wxString& srcPath,const wxString& destPath)
{
if(srcPath == destPath)
{
wxLog::OnLog(wxLOG_Error,wxT("源文件目录下输出目录不能是同一个"),time(NULL));
return;
}
wxDir srcDir(srcPath);
wxDir destDir(destPath);
wxArrayString fiels;
size_t srcs = srcDir.GetAllFiles(srcPath, &fiels, wxT("*.js"));
wxString srcFileName;
wxString destFileName;
wxString destFilePath;
for(int i=0; i<fiels.Count(); ++i)
{
srcFileName = fiels.Item(i);
destFileName = srcFileName;
destFilePath = ::wxPathOnly(destFileName);
destFilePath.Replace(srcPath,destPath);
if(!::wxDirExists(destFilePath))
{
if(!::wxMkdir(destFilePath))
{
continue;
}
}
destFileName.Replace(srcPath,destPath);
CJSMin* js = new CJSMin(srcFileName,destFileName,wxT(""));
CJSMinThread* pThread = new CJSMinThread(js);
if(pThread->Create() != wxTHREAD_NO_ERROR)
{
delete js;
wxLog::OnLog(wxLOG_Error,wxT("生成") + destFileName + wxT("错误"),wxDateTime::GetTimeNow());
}
else
{
wxLog::OnLog(wxLOG_Message,wxT("处理")+srcFileName+wxT(" > ") + destFileName,wxDateTime::GetTimeNow());
pThread->Run();
}
}
}
#ifndef WXJSMIN_H_INCLUDED
#define WXJSMIN_H_INCLUDED
#include <wx/file.h>
#define INLINE inline
class CJSMin
{
private:
static const int eof = EOF;
private:
wxFile inf;
wxFile outf;
int theA;
int theB;
int theLookahead;
private:
INLINE void action(int d);
INLINE int isAlphanum(int c);
INLINE int get();
INLINE int next();
INLINE int peek();
public:
INLINE void jsmin();
public:
CJSMin(wxString src,wxString dest,wxString copyRiht):inf(src),outf(dest,wxFile::write),theLookahead(EOF){}
virtual ~CJSMin();
};
INLINE int CJSMin::isAlphanum(int c)
{
return ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
(c >= 'A' && c <= 'Z') || c == '_' || c == '$' || c == '\\' ||
c > 126);
}
/* get -- return the next character from stdin. Watch out for lookahead. If
the character is a control character, translate it to a space or
linefeed.
*/
INLINE int CJSMin::get()
{
int c = theLookahead;
theLookahead = eof;
if (c == eof) {
char t = 0;
//c = getc(stdin);
if(!inf.Eof())
{
inf.Read(&t,1);
c = t;
}
else
{
c = eof;
}
}
if (c >= ' ' || c == '\n' || c == eof) {
return c;
}
if (c == '\r') {
return '\n';
}
return ' ';
}
/* peek -- get the next character without getting it.
*/
INLINE int CJSMin::peek()
{
theLookahead = get();
return theLookahead;
}
/* next -- get the next character, excluding comments. peek() is used to see
if a '/' is followed by a '/' or '*'.
*/
INLINE int CJSMin::next()
{
int c = get();
if (c == '/') {
switch (peek()) {
case '/':
for (;;) {
c = get();
if (c <= '\n') {
return c;
}
}
case '*':
get();
for (;;) {
switch (get()) {
case '*':
if (peek() == '/') {
get();
return ' ';
}
break;
case eof:
fprintf(stderr, "Error: JSMIN Unterminated comment.\n");
exit(1);
}
}
default:
return c;
}
}
return c;
}
/* action -- do something! What you do is determined by the argument:
1 Output A. Copy B to A. Get the next B.
2 Copy B to A. Get the next B. (Delete A).
3 Get the next B. (Delete B).
action treats a string as a single character. Wow!
action recognizes a regular expression if it is preceded by ( or , or =.
*/
责任编辑:小草