In the past, when I used JSMin, I would open the execution page from /jsmin/, then paste my own code, and then copy the weight-loss code back to the text editing tool and save it.
Over time, I found that this was really troublesome! Since we are programmers, why not make things easier by ourselves?
So I started to "friendly" JSMin.
In the process of "friendly" work, I encountered some unexpected problems "unexpectedly". I immediately talked about what problems I encountered and how to solve them in the end.
However, since I remembered to write the article after all the problems were solved, I am sorry, this time it was "no picture and no truth".
Before starting the explanation, I will explain some of the technical knowledge involved in this question - if you have the programming experience of Windows script hosting, then you can skip this part; if you have the experience of ASP, then there may be some content in this part you already know.
Windows Script Host (WSH), which is a Windows script host, is manifested as some executable files (and), whose function is to execute task files written in JScript or VBScript without being restricted by Internet security policies, thereby performing some system management work. It is worth noting that by default, files with the .js extension in Windows are considered WSH files. If you try to double-click a .js file, you may find some error prompts, or be intercepted by antivirus software.
HTML Application is abbreviated as HTA, as the name suggests, is a "HTML application" - it executes scripts under quite loose security conditions like Windows script hosts. The difference between it and Windows script hosts is that HTML applications often have a better graphical interface. Essentially, an HTA file is actually an HTML file with a special extension. If you don't want to spend too much effort on the production interface and have both HTML and WSH experience, then using HTML Application to solve the problem is a pretty good choice. It should be noted that HTML Application is also often considered the predecessor of WPF technology. If your target usage environment has WPF support (i.e. .NET Framework 3.0+), then using WPF may be more suitable. HTA files were once used in * downloaders because they were easy to create. To this day, some antivirus software may still roughly judge HTA files as * downloaders. Just like a binary executable file like .exe, whether an HTA file is harmful is determined by its own design, not by the file type innately.
FileSystemObject, referred to as FSO, is a component object provided in Windows scripting technology to facilitate scripts to operate file system. It is also very common in ASP programming.
WshShell is a component object provided by the WSH running environment to facilitate script operation of Shell-related objects. Many WSH programs use this object.
, sometimes called "ADO Stream", is a component object provided in ADO to facilitate operation of binary data streams, but is often used outside the database, such as file operations.
Functional features such as "just click the mouse on the file icon" are called "shell association" and so on. Many times, people's understanding of shell association is "associated to mouse double-click" or something. But those who are a little careful will find that in the shortcut menu popped up with the right mouse button, in addition to the default commands, there are some other commands such as "edit" and "print".
What we have to do this time is to add a "Minimize" instruction to the .js file. When we click this instruction, we will start JSMin's ECMAScript code to lose weight.
It's here that I ran into the first problem:
I wrote a .js file (actually a WSH task file) and used it to "automated" "install" it.
To add file associations to .js files in Windows, you need to add a child to the Shell item under the "JSFile" corresponding to the "default" value of the HKCR\.js registry key, and a child named Command, as well as a subsidiary.
After adding the Minimize item under HKCR\JSFile\Shell and setting the "My hta file path "%1"" value for the Command subkey, I found that using this Minimize directive will produce an error like "not a legal executable file". If the start directive is added before, the "Open With" dialog box appears...
It seems that it is not possible to take such a shortcut under the shell item, so I had to read the file type setting of htafile first, and then set it to the newly added Minimize directive. The .js file is written like this:
view sourceprint?1 var asocCommand = ("HKEY_CLASSES_ROOT\\htafile\\Shell\\Open\\Command\\").replace("%1", instPath + "\\" + appExec).replace("%*", '"%1"');
The problem of shell association has just been solved, followed by the analysis of command line parameters:
Initially I planned to use the WSH task file as the carrier of this gadget, but immediately I found that by default WSH files lack UI support - InputBox in VBScript and propt in HTML do not exist in WSH task files written in JScript. If you insist on using WSH, you can only get user input through the Windows console. If you obtain user input through the console, the standard usage process of this tool becomes "Mouse clicks on the file icon - shortcut menu - Minimize - enters a character on the keyboard". After a series of mouse operations (of course, it is also possible to use the keyboard), it seems that something is wrong to use the keyboard to suddenly switch to the keyboard.
Therefore, I chose to use HTA, a file type that can provide rich interfaces, as a way to implement this tool.
Selecting HTA means that some features of WSH "no outgoing transmission" are also lost, such as the lack of "Arguments" object for parsing command line parameters.
In my concept, it should be possible to specify the JSMin code reduction level through the -level parameter and close the prompt information through the -silent parameter. If these parameters cannot be interpreted from the command line, these functions cannot be implemented.
So I wrote two functions:
//========//========
// parse command-line info
// Decipher the actual path and additional parameters of the executed HTA from the command line in the HTA environment
// This part of the code is original by NanaLich and you can use it directly under any circumstances without written permission. You should not claim that you or your agency has created these codes without authorization, nor should you release modified versions without authorization in the name of NanaLich.
//========//========
function namedOrNot(args) {
var named = {}, not = [], c;
for(var i = 0; i < ; i++) {
c = args[i];
switch((0)) {
case "-":
case "/":
c = (1);
if(("=") > 0) {
c = ("=");
named[()] = ("=");
} else if((":") > 0) {
c = (":");
named[()] = (":");
} else {
// It is not possible to determine whether a named parameter also accepts additional parameters. This is an unsolved problem
//i++;
named[c] = args[i + 1];
}
break;
default:
(c);
break;
}
}
= named;
= not;
}
function parseArgs(str) {
var a = [], q = false, c = "", $ = "";
function mit() {
if(c)
(c);
}
for(var i = 0; i < ; i++) {
$ = (i);
if($ == '"') {
q = !q;
} else {
if($ == " " && !q) {
mit();
c = "";
} else {
c += $;
}
}
}
mit();
namedOrNot(a);
return a;
}
//========//========
In this way, just pass the commandLine attribute of the HTA:Application object into this function, and you can get the parsed named and unnamed parameters.
After solving the problem of command line parameters, the next step is the file encoding problem.
In our actual web development process, we may use other encoding formats other than "non-Unicode area encoding" and "Unicode (UTF-16) encoding" for various reasons, such as "Unicode (UTF-16) Big Endian" and "UTF-8" encoding methods.
If we copy and paste the code through the existing text editing tool, we just need to select the encoding type when saving the file; but now we are designing a tool that eliminates the cumbersome operation steps such as "Open-copy-paste-copy-paste-save", and we need to design a function that automatically adapts to the encoding type in this tool.
Unfortunately, in my tests, FSO and none of them have the ability to automatically recognize text encoding, so we must think of other methods - fortunately, VBScript is also supported by default in HTA. Although VBScript does not have the function of directly operating byte groups, operating byte groups as strings in VBScript can still meet our requirements to a certain extent.
So, I wrote the following function:
Function vbDetectFileEncoding(fn)
Dim Stream, B3
Set Stream = CreateObject("")
= 1
Call ()
Call (fn)
B3 = CStr((3))
Call ()
Set Stream = Nothing
Dim L1
L1 = Left(B3, 1)
If (L1 = ChrW(&hFEFF)) Then
vbDetectFileEncoding = "unicode"
Exit Function
Elseif (L1 = ChrW(&hFFFE)) Then
vbDetectFileEncoding = "unicodeFEFF"
Exit Function
Elseif B3 = (ChrB(&hEF) & ChrB(&hBB) & ChrB(&hBF)) Then
vbDetectFileEncoding = "utf-8"
Exit Function
End If
vbDetectFileEncoding = defEncoding
End Function
This function infers the encoding method used by the file based on the possible BOM in a text file.
One thing to note here is:
Allowed values are typical strings passed over the interface as Internet character set names (for example, "iso-8859-1", "Windows-1252", and so on). For a list of the character set names that are known by a system, see the subkeys of HKEY_CLASSES_ROOT\MIME\Database\Charset in the Windows Registry., while "Unicode Big Endian" (Encoding 1201) The corresponding item is "unicodeFFFE". From this information, it is inferred that when using "Unicode Big Endian" encoding in ADO Stream, the Charset attribute should be specified as "unicodeFFFE";
There is an easy-to-confused implementation here: the Unicode number of the BOM character is U+FEFF, and the "general" and "Unicode encoding" are actually "Unicode Little Endian" - the BOM character will be written as "FF FE" and will be written as "FE FF" in "Unicode Big Endian".
So here, the problem arises - if the opposite of "unicodeFFFE" is "unicodeFEFF", we can understand that "FEFF" here is the Unicode number of the BOM character; but at the same time, what does "FFFE" in "unicodeFFFE" representing "Unicode Big Endian" have the meaning? Obviously this cannot mean "a character with Unicode numbered U+FFFE".
In practice, I found that whether you set "unicode" or "unicodeFFFE" for the Charset attribute, the output files are encoded in "Unicode (Little Endian)", which is obviously inconsistent with the meaning expressed in the document.
When I tried further, I found that if I wanted to output a "Unicode Big Endian" encoded file, the Charset property should be set to "unicodeFEFF" - we can easily find that "FEFF" just conforms to the byte order of BOM characters in the file; we can also find that when setting "unicodeFXFX" for the Charset property, it is actually equivalent to "encoded with byte order like FXFX", which is to enjoy special treatment and does not fully conform to what is written in the registry.
Until now, the gadget can read and write encoding files such as "Unicode", "Unicode Big Endian", "UTF-8" and "non-Unicode area encoding", but I still haven't figured out why the documents and registry contain incorrect or completely useless information...
After the above problems were solved one by one, there seemed to be no more questions worth studying.
However, in the process of using JSMin, another problem was discovered:
Some people (for example, I) work mainly on Windows, and the default line separator for text files in Windows is a CR LF pair.
JSMin will replace all CRs with LF, so that the CR LF pair will become the "LF LF" of two LFs.
According to JSMin's original design, the control character LF usually needs to be reduced, so two consecutive LFs are not a problem; but there is a new function to retain "important comments" with certain characteristics (/*! ... */), and if there is a CR LF pair in this "important comment", it will eventually become two LF control characters that cannot be removed, which is not good.
To solve this problem, I made some modifications... However, because JSMin is a bit beyond my understanding, I can only turn CR into spaces. Fortunately, this also has some benefits in Windows (in most Windows versions, separate LF control characters are almost impossible to observe in the "Notepad" program, and the two lines of text separated by it look like they are glued together). Just use it just to make do with it... I won't list this part of the modifications separately.
All the code mentioned in this article can be found in this compressed package.
The compressed package contains three files: the "install" script associated with the registration file, the "application" that actually runs when using the "Minimize" instruction, and I modified it.
After unzipping the three files to the same folder, double-click to install the tool. If you reinstall the operating system, you may find that the tool is still left in your personal folder; as long as you double-click on the one left in your personal folder, you can use this tool again.
Note: Since Windows XP, newer versions of Windows will set a flag for files downloaded from the network. This flag may prevent the HTA file from executing normally. If you encounter such a problem when using it, please click the "Unlock" button in the File Properties dialog box to remove this flag.
Updated: Modified. Now it can also be installed correctly on 64-bit Windows 7; you don’t have to manually “unlock” after installation.
The secret is here:
var appsPath = ((regUSF + "Personal")) + "\\Scriptlet";
try{
(instPath + "\\" + appExec + ":", 1).Close();
(instPath + "\\" + appExec + ":", 2).Close();
}catch(ex){ }
File packaging and downloadThe file is accompanied by a renamed jse. It is convenient for friends who often develop js to avoid confusion.
Because many friends use win2003 to develop, the .js file is opened using normal text. It is impossible to use js to run it in the future. You can just change it to run it, haha.
Thanks to the author for posting such a good thing. The author's blog address
/NanaLich
Over time, I found that this was really troublesome! Since we are programmers, why not make things easier by ourselves?
So I started to "friendly" JSMin.
In the process of "friendly" work, I encountered some unexpected problems "unexpectedly". I immediately talked about what problems I encountered and how to solve them in the end.
However, since I remembered to write the article after all the problems were solved, I am sorry, this time it was "no picture and no truth".
Before starting the explanation, I will explain some of the technical knowledge involved in this question - if you have the programming experience of Windows script hosting, then you can skip this part; if you have the experience of ASP, then there may be some content in this part you already know.
Windows Script Host (WSH), which is a Windows script host, is manifested as some executable files (and), whose function is to execute task files written in JScript or VBScript without being restricted by Internet security policies, thereby performing some system management work. It is worth noting that by default, files with the .js extension in Windows are considered WSH files. If you try to double-click a .js file, you may find some error prompts, or be intercepted by antivirus software.
HTML Application is abbreviated as HTA, as the name suggests, is a "HTML application" - it executes scripts under quite loose security conditions like Windows script hosts. The difference between it and Windows script hosts is that HTML applications often have a better graphical interface. Essentially, an HTA file is actually an HTML file with a special extension. If you don't want to spend too much effort on the production interface and have both HTML and WSH experience, then using HTML Application to solve the problem is a pretty good choice. It should be noted that HTML Application is also often considered the predecessor of WPF technology. If your target usage environment has WPF support (i.e. .NET Framework 3.0+), then using WPF may be more suitable. HTA files were once used in * downloaders because they were easy to create. To this day, some antivirus software may still roughly judge HTA files as * downloaders. Just like a binary executable file like .exe, whether an HTA file is harmful is determined by its own design, not by the file type innately.
FileSystemObject, referred to as FSO, is a component object provided in Windows scripting technology to facilitate scripts to operate file system. It is also very common in ASP programming.
WshShell is a component object provided by the WSH running environment to facilitate script operation of Shell-related objects. Many WSH programs use this object.
, sometimes called "ADO Stream", is a component object provided in ADO to facilitate operation of binary data streams, but is often used outside the database, such as file operations.
Functional features such as "just click the mouse on the file icon" are called "shell association" and so on. Many times, people's understanding of shell association is "associated to mouse double-click" or something. But those who are a little careful will find that in the shortcut menu popped up with the right mouse button, in addition to the default commands, there are some other commands such as "edit" and "print".
What we have to do this time is to add a "Minimize" instruction to the .js file. When we click this instruction, we will start JSMin's ECMAScript code to lose weight.
It's here that I ran into the first problem:
I wrote a .js file (actually a WSH task file) and used it to "automated" "install" it.
To add file associations to .js files in Windows, you need to add a child to the Shell item under the "JSFile" corresponding to the "default" value of the HKCR\.js registry key, and a child named Command, as well as a subsidiary.
After adding the Minimize item under HKCR\JSFile\Shell and setting the "My hta file path "%1"" value for the Command subkey, I found that using this Minimize directive will produce an error like "not a legal executable file". If the start directive is added before, the "Open With" dialog box appears...
It seems that it is not possible to take such a shortcut under the shell item, so I had to read the file type setting of htafile first, and then set it to the newly added Minimize directive. The .js file is written like this:
Copy the codeThe code is as follows:
view sourceprint?1 var asocCommand = ("HKEY_CLASSES_ROOT\\htafile\\Shell\\Open\\Command\\").replace("%1", instPath + "\\" + appExec).replace("%*", '"%1"');
The problem of shell association has just been solved, followed by the analysis of command line parameters:
Initially I planned to use the WSH task file as the carrier of this gadget, but immediately I found that by default WSH files lack UI support - InputBox in VBScript and propt in HTML do not exist in WSH task files written in JScript. If you insist on using WSH, you can only get user input through the Windows console. If you obtain user input through the console, the standard usage process of this tool becomes "Mouse clicks on the file icon - shortcut menu - Minimize - enters a character on the keyboard". After a series of mouse operations (of course, it is also possible to use the keyboard), it seems that something is wrong to use the keyboard to suddenly switch to the keyboard.
Therefore, I chose to use HTA, a file type that can provide rich interfaces, as a way to implement this tool.
Selecting HTA means that some features of WSH "no outgoing transmission" are also lost, such as the lack of "Arguments" object for parsing command line parameters.
In my concept, it should be possible to specify the JSMin code reduction level through the -level parameter and close the prompt information through the -silent parameter. If these parameters cannot be interpreted from the command line, these functions cannot be implemented.
So I wrote two functions:
Copy the codeThe code is as follows:
//========//========
// parse command-line info
// Decipher the actual path and additional parameters of the executed HTA from the command line in the HTA environment
// This part of the code is original by NanaLich and you can use it directly under any circumstances without written permission. You should not claim that you or your agency has created these codes without authorization, nor should you release modified versions without authorization in the name of NanaLich.
//========//========
function namedOrNot(args) {
var named = {}, not = [], c;
for(var i = 0; i < ; i++) {
c = args[i];
switch((0)) {
case "-":
case "/":
c = (1);
if(("=") > 0) {
c = ("=");
named[()] = ("=");
} else if((":") > 0) {
c = (":");
named[()] = (":");
} else {
// It is not possible to determine whether a named parameter also accepts additional parameters. This is an unsolved problem
//i++;
named[c] = args[i + 1];
}
break;
default:
(c);
break;
}
}
= named;
= not;
}
function parseArgs(str) {
var a = [], q = false, c = "", $ = "";
function mit() {
if(c)
(c);
}
for(var i = 0; i < ; i++) {
$ = (i);
if($ == '"') {
q = !q;
} else {
if($ == " " && !q) {
mit();
c = "";
} else {
c += $;
}
}
}
mit();
namedOrNot(a);
return a;
}
//========//========
In this way, just pass the commandLine attribute of the HTA:Application object into this function, and you can get the parsed named and unnamed parameters.
After solving the problem of command line parameters, the next step is the file encoding problem.
In our actual web development process, we may use other encoding formats other than "non-Unicode area encoding" and "Unicode (UTF-16) encoding" for various reasons, such as "Unicode (UTF-16) Big Endian" and "UTF-8" encoding methods.
If we copy and paste the code through the existing text editing tool, we just need to select the encoding type when saving the file; but now we are designing a tool that eliminates the cumbersome operation steps such as "Open-copy-paste-copy-paste-save", and we need to design a function that automatically adapts to the encoding type in this tool.
Unfortunately, in my tests, FSO and none of them have the ability to automatically recognize text encoding, so we must think of other methods - fortunately, VBScript is also supported by default in HTA. Although VBScript does not have the function of directly operating byte groups, operating byte groups as strings in VBScript can still meet our requirements to a certain extent.
So, I wrote the following function:
Copy the codeThe code is as follows:
Function vbDetectFileEncoding(fn)
Dim Stream, B3
Set Stream = CreateObject("")
= 1
Call ()
Call (fn)
B3 = CStr((3))
Call ()
Set Stream = Nothing
Dim L1
L1 = Left(B3, 1)
If (L1 = ChrW(&hFEFF)) Then
vbDetectFileEncoding = "unicode"
Exit Function
Elseif (L1 = ChrW(&hFFFE)) Then
vbDetectFileEncoding = "unicodeFEFF"
Exit Function
Elseif B3 = (ChrB(&hEF) & ChrB(&hBB) & ChrB(&hBF)) Then
vbDetectFileEncoding = "utf-8"
Exit Function
End If
vbDetectFileEncoding = defEncoding
End Function
This function infers the encoding method used by the file based on the possible BOM in a text file.
One thing to note here is:
Allowed values are typical strings passed over the interface as Internet character set names (for example, "iso-8859-1", "Windows-1252", and so on). For a list of the character set names that are known by a system, see the subkeys of HKEY_CLASSES_ROOT\MIME\Database\Charset in the Windows Registry., while "Unicode Big Endian" (Encoding 1201) The corresponding item is "unicodeFFFE". From this information, it is inferred that when using "Unicode Big Endian" encoding in ADO Stream, the Charset attribute should be specified as "unicodeFFFE";
There is an easy-to-confused implementation here: the Unicode number of the BOM character is U+FEFF, and the "general" and "Unicode encoding" are actually "Unicode Little Endian" - the BOM character will be written as "FF FE" and will be written as "FE FF" in "Unicode Big Endian".
So here, the problem arises - if the opposite of "unicodeFFFE" is "unicodeFEFF", we can understand that "FEFF" here is the Unicode number of the BOM character; but at the same time, what does "FFFE" in "unicodeFFFE" representing "Unicode Big Endian" have the meaning? Obviously this cannot mean "a character with Unicode numbered U+FFFE".
In practice, I found that whether you set "unicode" or "unicodeFFFE" for the Charset attribute, the output files are encoded in "Unicode (Little Endian)", which is obviously inconsistent with the meaning expressed in the document.
When I tried further, I found that if I wanted to output a "Unicode Big Endian" encoded file, the Charset property should be set to "unicodeFEFF" - we can easily find that "FEFF" just conforms to the byte order of BOM characters in the file; we can also find that when setting "unicodeFXFX" for the Charset property, it is actually equivalent to "encoded with byte order like FXFX", which is to enjoy special treatment and does not fully conform to what is written in the registry.
Until now, the gadget can read and write encoding files such as "Unicode", "Unicode Big Endian", "UTF-8" and "non-Unicode area encoding", but I still haven't figured out why the documents and registry contain incorrect or completely useless information...
After the above problems were solved one by one, there seemed to be no more questions worth studying.
However, in the process of using JSMin, another problem was discovered:
Some people (for example, I) work mainly on Windows, and the default line separator for text files in Windows is a CR LF pair.
JSMin will replace all CRs with LF, so that the CR LF pair will become the "LF LF" of two LFs.
According to JSMin's original design, the control character LF usually needs to be reduced, so two consecutive LFs are not a problem; but there is a new function to retain "important comments" with certain characteristics (/*! ... */), and if there is a CR LF pair in this "important comment", it will eventually become two LF control characters that cannot be removed, which is not good.
To solve this problem, I made some modifications... However, because JSMin is a bit beyond my understanding, I can only turn CR into spaces. Fortunately, this also has some benefits in Windows (in most Windows versions, separate LF control characters are almost impossible to observe in the "Notepad" program, and the two lines of text separated by it look like they are glued together). Just use it just to make do with it... I won't list this part of the modifications separately.
All the code mentioned in this article can be found in this compressed package.
The compressed package contains three files: the "install" script associated with the registration file, the "application" that actually runs when using the "Minimize" instruction, and I modified it.
After unzipping the three files to the same folder, double-click to install the tool. If you reinstall the operating system, you may find that the tool is still left in your personal folder; as long as you double-click on the one left in your personal folder, you can use this tool again.
Note: Since Windows XP, newer versions of Windows will set a flag for files downloaded from the network. This flag may prevent the HTA file from executing normally. If you encounter such a problem when using it, please click the "Unlock" button in the File Properties dialog box to remove this flag.
Updated: Modified. Now it can also be installed correctly on 64-bit Windows 7; you don’t have to manually “unlock” after installation.
The secret is here:
Copy the codeThe code is as follows:
var appsPath = ((regUSF + "Personal")) + "\\Scriptlet";
try{
(instPath + "\\" + appExec + ":", 1).Close();
(instPath + "\\" + appExec + ":", 2).Close();
}catch(ex){ }
File packaging and downloadThe file is accompanied by a renamed jse. It is convenient for friends who often develop js to avoid confusion.
Because many friends use win2003 to develop, the .js file is opened using normal text. It is impossible to use js to run it in the future. You can just change it to run it, haha.
Thanks to the author for posting such a good thing. The author's blog address
/NanaLich