When I used JSMin in the past, I would open the execution page from http://fmarcia.info/jsmin/, then paste my own code there, and then copy the weighted 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 simpler by ourselves?
So I started the work of "friendly" JSMin.
In the process of "friendly" work, "unsurprisingly" we encountered some unexpected problems. I will talk about what problems we encountered and how to solve them in the end.
But because I only thought of writing an article after all the problems were solved, I’m sorry, this time it’s “no pictures and no truth”.
Before I start to explain, let me explain some of the technical knowledge involved in this question - if you have programming experience with Windows Script Host, you can skip this part. Yes; if you have experience with ASP, there may be some content in this section that you already know.
Windows Script Host (WSH) is a Windows script host, which appears as some executable files (wscript.exe and cscript.exe). Their function is to execute JScript without being restricted by Internet security policies. Or task files written in VBScript to perform some system management work. It is worth noting that by default, files with a .js extension in Windows are considered WSH files. If you try to double-click a .js file, you may find some error messages or be intercepted by anti-virus software.
HTML Application is abbreviated as HTA. As the name suggests, it is an "HTML application" - it executes scripts under fairly loose security conditions like the Windows Script Host. The difference from the Windows Script Host is that HTML applications tend to have better graphical interface. Essentially, an HTA file is actually an HTM file with a special extension. If you don't want to spend too much energy on making the interface, and you happen to have experience in both HTML and WSH, then using HTML Application to solve the problem is a quite Not a bad choice. It should be noted that HTML Application is often considered the predecessor of WPF technology. If your target environment has WPF support (ie. .NET Framework 3.0), then using WPF may be more suitable. HTA files were once used as Trojan downloaders because they were easy to create. To this day, some anti-virus software may still roughly judge HTA files as Trojan downloaders. Just like binary executable files such as .exe, whether an HTA file is harmful is determined by its own design, not by the file type.
FileSystemObject, referred to as FSO, is a component object provided in Windows scripting technology to facilitate scripts to perform file system operations. It is also very common in ASP programming.
WshShell is a component object provided by the WSH running environment to facilitate scripts to operate Shell-related objects. Many WSH programs use this object.
ADODB.Stream, sometimes also called "ADO Stream", is a component object provided in ADO to facilitate the operation of binary data streams, but it is also often used in places other than databases, such as file operations.
Functional features such as "just click the mouse on the file icon" are called "shell association" and the like. Many times, people's understanding of shell association is "associated with the mouse." Double click" or something. But anyone who pays a little more attention will find that in the shortcut menu that pops up by clicking the right button of the mouse, in addition to the default commands, there are 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, JSMin will be started to reduce weight for our ECMAScript code.
It was here that I encountered my first problem:
I wrote a .js file (actually a WSH task file) and used it to "automate" Install".
To add a file association to a .js file in Windows, you need to add a subkey to the Shell key under the "JSFile" - HKCRJSFile key corresponding to the "default" value of the HKCR.js registry key. and a dependent subkey named Command.
After adding the Minimize item under HKCRJSFileShell and setting the "My hta file path "%1"" value for the Command subkey, I found that using this Minimize command will generate an "Not a legal executable File" error, and if the start command is added in front, the "Open with" dialog box appears...
It seems that it is not possible to be so opportunistic under the Shell item, so I had to read it first htafile file type setting, and then set it to the newly added Minimize instruction. The .js file is written like this:
view sourceprint?1 var asocCommand = wshShell.RegRead("HKEY_CLASSES_ROOT\htafile\Shell\Open\Command\").replace("%1" , instPath "\" appExec).replace("%*", '"%1"');
The shell-related problem has just been solved, and then there is the problem of command line parameter parsing:
Initially I planned to use the WSH task file as the carrier of this gadget, but I soon found that the WSH file was lacking by default. UI support - InputBox in VBScript and prompt in HTML do not exist in WSH task files written in JScript. If you insist on using WSH, you can only obtain user input through the Windows console. And if user input is obtained through the console, the standard usage process of this tool becomes "click the file icon with the mouse - shortcut menu - Minimize - enter a character with the keyboard", in a series of mouse operations (of course, use Keyboard operation is also possible) and then suddenly switching to the keyboard, it doesn't seem right.
Therefore, I chose to use HTA, a file type that can provide a rich interface, as a way to implement this tool.
Choosing HTA means that you will also lose some of the "no external transmission" features of WSH, such as the lack of the "Arguments" object used to parse command line parameters.
In my idea, it should be possible to specify the code reduction level of JSMin through the -level parameter and turn off the prompt information through the -silent parameter. If these parameters cannot be interpreted from the command line, these functions will not be implemented.
So I wrote two functions:
//========//========
// parse command-line info
// Interpret from the command line in the HTA environment The actual path of the executed HTA and additional parameters
// This part of the code was originally created by NanaLich and you can use it directly without written permission under any circumstances. You should not claim that you or your institution created the code without authorization, nor should you publish modified versions in the name of NanaLich without authorization.
//========//========
function namedOrNot(args) {
var named = {}, not = [], c;
for(var i = 0; i < args.length; i ) {
c = args[i];
switch(c.charAt(0)) {
case "-":
case "/":
c = c.substring(1);
if(c.indexOf("=") > 0) {
c = c.split("=") ;
named[c.shift()] = c.join("=");
} else if(c.indexOf(":") > 0) {
c = c.split (":");
named[c.shift()] = c.join(":");
} 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:
not.push(c);
break;
}
}
args.named = named;
args.unnamed = not;
}
function parseArgs(str) {
var a = [], q = false, c = "", $ = "";
function mit() {
if(c)
a.push(c);
}
for (var i = 0; i < str.length; i ) {
$ = str.charAt(i);
if($ == '"') {
q = !q;
} else {
if($ == " " && !q) {
mit();
c = "";
} else {
c = $;
}
}
}
mit();
namedOrNot(a);
return a;
}
//========// ========
In this way, as long as the commandLine attribute of the HTA:Application object is passed into this function, the named and unnamed parameters after parsing can be obtained.
After solving the problem of command line parameters, the next step is the encoding of the file.
In our actual Web development process, we may use other encoding formats other than "non-Unicode regional 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 code through existing text editing tools, we only need to select the encoding type when saving the file; but now we are designing a method that eliminates the need to "open-copy- -Paste-Copy-Paste-Save" is a tool with such tedious operation steps. We need to design a function in this tool that automatically adapts to the encoding type.
Unfortunately, in my test, neither FSO nor ADODB.Stream has the ability to automatically identify text encoding. I have to find other methods - fortunately, VBScript is also supported by default in HTA, although VBScript is not The function of directly operating on byte groups, but operating on 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("ADODB.Stream")
Stream.Type = 1
Call Stream.Open()
Call Stream.LoadFromFile(fn)
B3 = CStr(Stream.Read(3))
Call Stream.Close()
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 used in a text file based on the BOM that may exist in the file.
One thing to note here is:
The relevant documentation for ADODB.Stream writes that 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_ROOTMIMEDatabaseCharset in the Windows Registry., and "Unicode Big Endian "(Encoding 1201) The corresponding item is "unicodeFFFE". From this information, it can be inferred that when using "Unicode Big Endian" encoding in ADO Stream, the Charset attribute should be specified as "unicodeFFFE";
Here is an easy The implementation of confusion is: the Unicode number of the BOM character is U FEFF, and the "general" "Unicode encoding" is actually "Unicode Little Endian" - the BOM character will be written as "FF FE" with two bytes, and in " Unicode Big Endian" will be written as "FE FF".
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 the "FFFE" in "unicodeFFFE" that stands for "Unicode Big Endian" mean? Obviously this cannot mean "a character with Unicode number U FFFE".
In practice, I found that no matter whether "unicode" or "unicodeFFFE" is set for the Charset attribute, the output files are encoded in "Unicode (Little Endian)", which is obviously what the document means. Doesn’t match.
When I tried further, I found that if I want to output a "Unicode Big Endian" encoded file, the Charset property should be set to "unicodeFEFF" - we can easily find that "FEFF" exactly matches the BOM The byte order of characters in the file; we can also find that setting "unicodeFXFX" for the Charset attribute is actually equivalent to "encoding with byte order such as FXFX", which enjoys special treatment and is not completely consistent. as written in the registry.
Up to now, the gadget can read and write files in "Unicode", "Unicode Big Endian", "UTF-8" and "Non-Unicode regional encoding", but I still haven't thought about it. Understand why documents and registration forms contain incorrect or completely useless information...
After the above problems are solved one by one, it seems that there are no more problems worth studying. .
But in the process of using JSMin, I discovered another problem:
Some people (such as me) mainly work on Windows. The default line delimiter for text files in Windows is CR. LF Right.
JSMin will replace all CR with LF, so the CR LF pair becomes a "LF LF" pair of two LFs.
According to the original design of JSMin, the control character LF is usually reduced, so two consecutive LFs are not a problem; but jsmin.js has a new feature that retains certain characteristics (/*! ... */), and if there is a CR LF pair in such an "important comment", it will eventually become two LF control characters that cannot be removed, which is not good.
In order to solve this problem, I made some modifications to jsmin.js... But because JSMin is a bit beyond my understanding, I can only change CR into spaces, but fortunately, this can be done on Windows There are some benefits (in most versions of Windows, the LF control character alone is almost unobservable in the Notepad program, and the two lines of text separated by it look like they are stuck together), that's it Just use it... I won't list these modifications separately.
All the codes mentioned in this article can be found in this compressed package.
The compressed package contains three files: install.js is the "installation" script associated with the registration file, jsmin.hta is the "application" actually run when using the "Minimize" command, and jsmin.js is I modify the later jsmin.js.
After extracting the three files to the same folder, double-click install.js to install this tool. If you have reinstalled the operating system, you may find that the tool is still left in your personal folder; as long as you double-click the install.js left in the personal folder, you can use the tool again.
Note: Starting from Windows XP, newer versions of Windows will set a flag for files downloaded from the Internet. This flag may prevent the HTA file from executing normally. If you encounter If you encounter such a problem, please click the "Unlock" button in the file properties dialog box to remove this flag.
Update: Modified install.js. Now it can be installed correctly on 64-bit Windows 7; there is no need to manually "unlock" it after installation.
The secret is here:
var appsPath = wshShell.ExpandEnvironmentStrings(wshShell.RegRead(regUSF "Personal")) "\Scriptlet";
try{
fso.OpenTextFile(instPath "\" appExec ": Zone.Identifier", 1).Close();
fso.OpenTextFile(instPath "\" appExec ":Zone.Identifier", 2).Close();
}catch(ex){ }
File package download The file is attached with a renamed jse. It is convenient for friends who often develop js to avoid confusion.
Because many of my friends use win2003 for development, the .js file is opened with ordinary text. It is impossible to run it with js in the future. Just change it to install.jse and it will run. Haha.
Thanks to the author for publishing such good stuff. The author's blog address
http://www.cnblogs.com/NanaLich