Support Windows Script Host CLI #198

Closed
DinoChiesa opened this Issue Oct 20, 2011 · 4 comments

2 participants

@DinoChiesa

Support a WSH CLI. It's very similar to the Rhino CLI. I had to add array prototype methods for indexOf, forEach and filter. Here's the code I used:

var wshapi = (function(){
    var fso = new ActiveXObject("Scripting.FileSystemObject");
    var shell = WScript.CreateObject("WScript.Shell");
    var arguments = [], i, args = WScript.Arguments;

    if (typeof Array.prototype.forEach !== "function") {
        Array.prototype.forEach = function(f,m) {
            for (var i=0, L=this.length; i<L; ++i) {
                f(this[i], i, m);
            }
        };
    }

    if (typeof Array.prototype.filter !== "function") {
        Array.prototype.filter = function(fn /*, thisp*/) {
            if (typeof fn != "function")
                throw "not a function";
            var res = [], val, thisp = arguments[1];
            for (var i = 0, L = this.length; i < L; i++) {
                if (i in this) {
                    val = this[i]; // in case fun mutates this
                    if (fn.call(thisp, val, i, this))
                        res.push(val);
                }
            }

            return res;
        };
    }

    if (!Array.prototype.indexOf) {
        Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
            "use strict";
            if (this === void 0 || this === null) {
                throw "unknown instance";
            }
            var t = Object(this);
            var len = t.length >>> 0;
            if (len === 0) {
                return -1;
            }
            var n = 0;
            if (arguments.length > 0) {
                n = Number(arguments[1]);
                if (n !== n) { // shortcut for verifying if it's NaN
                    n = 0;
                } else if (n !== 0 && n !== Infinity && n !== -Infinity) {
                    n = (n > 0 || -1) * Math.floor(Math.abs(n));
                }
            }
            if (n >= len) {
                return -1;
            }
            var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
            for (; k < len; k++) {
                if (k in t && t[k] === searchElement) {
                    return k;
                }
            }
            return -1;
        }
    }

    function traverseDir(files, path) {
        var filename, folder = fso.GetFolder(path),
            subFlds, fc = new Enumerator(folder.files);

        for (; !fc.atEnd(); fc.moveNext()) {
            filename = fc.item()
            if (/\.css$/.test(filename)) {
                files.push(filename);
            }
        }

        subFlds = new Enumerator(folder.SubFolders);
        for (; !subFlds.atEnd(); subFlds.moveNext()) {
            traverseDir(files, subFlds.item());
        }
    }

    // turn the WScript.Arguments thing into a regular array
    if (args.Length > 0) {
        for (i = 0; i < args.Length; i++) {
            arguments.push(args(i))
        }
    }

    return {
        args: arguments,
        print: function(s) { WScript.Echo(s);},
        quit: function (v) { WScript.Quit(v);},

        isDirectory: function(name){
            return fso.FolderExists(name);
        },

        getFiles: function(dir){
            var files = [];
            traverseDir(files, dir);
            return files;
        },

        fixFilenames: function(files){
            return files;
        },

        getWorkingDirectory: function() {
            return shell.CurrentDirectory;
        },

        getFullPath: function(filename){
            return fso.GetAbsolutePathName(filename);
        },

        readFile: function(path){
            var forReading = 1;
            var tf = fso.OpenTextFile(path, forReading);
            var allText = tf.ReadAll();
            tf.Close();
            return allText;
        }
    };

}());

cli(wshapi);

Also, I needed to change the fire function to use typeof and not just a negation:

    fire: function(event){
        if (typeof event == "string"){
            event = { type: event };
        }
        if (typeof event.target == "undefined"){ // compat with wsh
            event.target = this;
        }

        if (typeof event.type == "undefined"){ // for wsh
            throw new Error("Event object missing 'type' property.");
        }

        if (this._listeners[event.type]){

            //create a copy of the array and use that so listeners can't chane
            var listeners = this._listeners[event.type].concat();
            for (var i=0, len=listeners.length; i < len; i++){
                listeners[i].call(this, event);
            }
        }
    },
@nzakas

Okay, the fire function is part of the parser library, which is a separate project. I can make that fix. Can you create a pull request for the rest?

@DinoChiesa
@nzakas

Hi Dino, if you're unfamiliar with GitHub and how pull requests work, then I'd suggest reading through some of the help documentation.

Forking a repo: http://help.github.com/fork-a-repo/

Pull Requests: http://help.github.com/send-pull-requests/

@nzakas

Okay, I'll manually merge it in this time. In the future, please read up on submitting a pull request, which makes it much easier for us to accept your contributions. Thanks.

@nzakas nzakas pushed a commit that closed this issue Nov 17, 2011
Nicholas C. Zakas Added Windows Script Host CLI (fixes #198) 334d0ef
@nzakas nzakas closed this in 334d0ef Nov 17, 2011
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment