Skip to main content
Code Review

Return to Revisions

4 of 6
added 364 characters in body; edited title

What are practical issues using this code with common JavaScript libraries?

I'm not a JavaScript programmer. I have next to no idea about "what's out there" of libraries and so on. Therefore it's not unlikely that the referred to Windows HTML Application (HTA) code here, which is a mix of HTML5, CSS3 and JScript 5.6, may be incompatible with such libraries, common naming conventions, whatever, and I would like to rectify the issues that the more JavaScript-experienced reader can spot.

Compatibility is important because this is intended as a host environment for simple JavaScript scripts, which may likely use common libraries etc.

This code consists of a number of logical modules encapsulated in a single .HTA file by design*.

Therefore, even though it's only about half-finished it's too large to present inline here, I think, at about 750 lines. And since I have no idea what the issues could be, I'm reluctant to pare it down to what I think can be relevant. I think would be bound to err there.

Code at http://pastebin.com/FW88DLS1.


As per request in comments I tried to post the full code inline here, but there was a limitation of 30.000 characters, while the code is some 36.000 characters.

Here's the CSS part (first part of the code):

<html>
 <!-- Windows HTA application "Text Stream Host". Copyright (©) 2014 Alf P. Steinbach -->
 <head id="head-element">
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
 <meta http-equiv="MSThemeCompatible" content="yes">
 <title id="title-element"></title>
 
 <style>
 * { font: 10pt 'MS Shell Dlg 2'; }
 code { font: 10pt 'Courier new'; }
 body {
 padding: 0; margin: 0; overflow: hidden;
 background-color: #F0F0F0;
 }
 #text-stream-display p { margin: 0; padding: 0; color: #000080; }
 #control-area {
 padding-top: 0; padding-left: 0; padding-right: 0.5em; padding-bottom: 0;
 overflow: none;
 margin: 0;
 position: absolute;
 left: 0; top: 0;
 /*background-color: #FF0000;*/
 width: 30em; height: 2em; left: -14em; top: +14em;
 transform: rotate(-90deg);
 }
 #info-area {
 background-color: white;
 overflow: none;
 position: absolute;
 left: 2.5em; top: 0; right: 0; bottom: 0px;
 }
 
 #commandline-display {
 color: gray;
 overflow: auto;
 white-space: nowrap;
 padding: 0.5em;
 border-bottom: 1px solid gray;
 margin-bottom: 0.5em;
 position: absolute; left: 0; top: 0; right: 0;
 height: 7em;
 }
 .command-line { background-color: #F0FFF0; }
 #text-stream-display {
 overflow: auto;
 white-space: nowrap;
 padding: 0.5em;
 position: absolute;
 left: 0; top: 0px; right: 0; bottom: 0px;
 }
 .checkbox-div {
 border: 1px black solid;
 border-radius: 5px;
 padding-bottom: 0.2em; margin-bottom: 0.1em;
 padding-right: 0.5em;
 display: inline-block;
 cursor: pointer;
 }
 .checkbox-div:hover {
 background: #D0E0FF;
 }
 </style>

Here's the first logical JavaScript module (following right after the above in the full code):

 <!-- Namespace js_util
 JavaScript utilities -->
 <script type="text/javascript">
 js_util = new function()
 {
 this.is_whitespace_character = function( ch )
 {
 return (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t');
 };
 this.is_whitespace = function( s )
 {
 with( this )
 {
 var n = s.length;
 for( var i = 0; i < n; ++i )
 {
 if( !is_whitespace_character( s.substr( i, 1 ) ) )
 {
 return false;
 }
 }
 }
 return true;
 };
 this.hex_digits = '0123456789ABCDEF';
 this.hex_from_int = function( number, n_digits )
 {
 if( n_digits == undefined ) { n_digits = 8; }
 var digits = new Array();
 for( var i = 1; i <= n_digits; ++i )
 {
 digits.push( number & 0xF );
 number >>>= 4;
 }
 var result = '';
 for( var i = n_digits - 1; i >= 0; --i )
 {
 result += this.hex_digits.substr( digits[i], 1 );
 }
 return result;
 }
 this.add_class = function( html_elem, classname )
 {
 var classname_set = html_elem.classList;
 if( !classname_set.contains( classname ) )
 {
 classname_set.toggle( classname );
 return true;
 }
 return false;
 }
 
 this.unquoted = function( s )
 {
 var quote = '"';
 var n = s.length;
 if( n <= 1 )
 {
 return s;
 }
 if( s.substr( 0, 1 ) == quote && s.substr( n - 1, 1 ) == quote )
 {
 return s.substring( 1, n - 1 );
 }
 return s;
 }
 this.local_file_url = function( filespec )
 {
 with( this )
 {
 var url = 'file:///' + unquoted( filespec ).replace( /\\/g, '/' );
 return url;
 }
 }
 };
 </script>

Here's the second JavaScript module:

 <!-- Namespace windows.wsh
 Windows Script Host (shell functionality only). -->
 <script type="text/javascript">
 var windows = windows || {};
 windows.wsh = new function()
 {
 this.shell = new ActiveXObject( 'WScript.Shell' );
 this.sleep = function( millisecs )
 {
 with( this )
 {
 var nowindow = 0;
 var wait = true;
 shell.Run( 'ping 1.1.1.1 -n 1 -w ' + millisecs, nowindow, wait );
 }
 };
 
 this.is_running = function( wsh_execution )
 {
 return (wsh_execution.Status == 0);
 };
 
 this.run_hidden = function( command )
 {
 var hidden_window = 0;
 var wait_for_completion = true;
 with( this )
 {
 return shell.Run( command, hidden_window, wait_for_completion );
 }
 }
 };
 </script>

Here's the third JavaScript module:

 <!-- Namespace windows.fs
 File System Object (part of Window's script support). -->
 <script type="text/javascript">
 var windows = windows || {};
 windows.fs = new function()
 {
 this.fso = new ActiveXObject( "Scripting.FileSystemObject" );
 
 this.tempfolder = this.fso.GetSpecialFolder( 2 );
 this.tempfolder_path = this.tempfolder.Path;
 this.open_for_reading = function( textfile_spec )
 {
 var for_reading = 1;
 var do_not_create = false;
 var ascii_encoding = 0;
 var utf16_encoding = -1;
 var default_encoding = -2;
 with( this )
 {
 return fso.OpenTextFile(
 textfile_spec,
 for_reading, do_not_create, default_encoding
 );
 }
 }
 this.joined_paths = function( folder_path, filename )
 {
 with( this ) return fso.BuildPath( folder_path, filename );
 }
 this.temp_filename = function()
 {
 with( this ) return fso.GetTempName();
 }
 
 this.temp_filepath = function()
 {
 with( this ) return joined_paths( tempfolder_path, temp_filename() );
 }
 
 this.quoted = function( path )
 {
 var quote = '"';
 var is_quoted = (path.length > 0 && path.substr( 0, 1 ) == quote);
 return (is_quoted? path : quote + path + quote);
 }
 };
 </script>

Here's the fourth JavaScript module:

 <!-- Namespace windows.process_info
 Windows process information. -->
 <script type="text/javascript">
 var windows = windows || {};
 windows.process_info = new function()
 {
 var pg = {}; // "private globals" namespace, to make that explicit.
 pg.Record = function()
 {
 this._add_item = function( spec )
 {
 i_delimiter = spec.indexOf( '=' );
 if( i_delimiter != -1 )
 {
 var property_name = spec.substring( 0, i_delimiter );
 var value = spec.substr( i_delimiter + 1 );
 this[property_name] = value;
 }
 }
 };
 this.new_records = function()
 {
 var filepath = windows.fs.temp_filepath();
 var exitcode = windows.wsh.run_hidden(
 'cmd /c wmic process list full >' + windows.fs.quoted( filepath )
 );
 if( exitcode != 0 )
 {
 return null; // TODO: exception
 }
 var records = new Array();
 var current_record = null;
 var f = windows.fs.open_for_reading( filepath );
 while( !f.AtEndOfStream )
 {
 var line = f.ReadLine();
 var i_end = line.length - 1;
 while( i_end >= 0 && line.substr( i_end, 1 ) < ' ' )
 {
 --i_end;
 }
 if( 0 <= i_end && i_end < line.length - 1 )
 {
 line = line.substr( 0, i_end + 1 );
 }
 if( js_util.is_whitespace( line ) )
 {
 if( current_record != null )
 {
 records.push( current_record );
 current_record = null;
 }
 }
 else // line.length > 0
 {
 if( current_record == null )
 {
 current_record = new pg.Record();
 }
 current_record._add_item( line );
 }
 }
 
 // Complete a possible last record.
 if( current_record != null )
 {
 records.push( current_record );
 }
 
 f.Close();
 windows.fs.fso.DeleteFile( filepath );
 return records;
 };
 };
 </script>

When I try to post the fifth and main JavaScript module, I get an error about exceeding the max length. So that module plus the main HTML body is missing here. Consult the PasteBin posting for a complete version that can be tried out – which I believe is a practical necessity for gaining a good understanding of code.


*Single file: the idea is to provide a simple text only i/o host environment for learning programming, where one simply drags the javascript source onto the HTA file. And for beginners I think it's decidedly an advantage to have the host environment as a single file, with no special installation issues etc.
default

AltStyle によって変換されたページ (->オリジナル) /