kayahr / console-shim

Browser console compatibility shim for legacy JavaScript engines
MIT License
86 stars 16 forks source link

IE memory Leak #6

Open jbadeau opened 11 years ago

jbadeau commented 11 years ago

The line with:

var console = (/* @type {Object} / global.console); results in memory leak in IE9-

dmp42 commented 11 years ago

It's called only once. Do you mean it's leaking across page reloads? Also, what tool did you use to detect the leak?

jbadeau commented 11 years ago

Hi, Sorry for the short explanation, I accidentally pressed comment. This issues happens after a page refresh. I noticed it by using the good old windows process viewer. Seems the console var cannot be dereferenced. I have fixed the issue and will make a pull request.

beatgammit commented 11 years ago

@jbadeau - Any progress on this?

jbadeau commented 11 years ago

I am not allowed to do a pullrequest but I can post the changes:

/**

(function(){ "use strict";

/**

// Create console if not present if (!window["console"]) window.console = /* @type {Console} / ({}); var console = (/* @type {Object} / window.console);

// Implement console log if needed if (!console["log"]) { // Use log4javascript if present if (window["log4javascript"]) { var log = log4javascript.getDefaultLogger(); console.log = bind(log.info, log); console.debug = bind(log.debug, log); console.info = bind(log.info, log); console.warn = bind(log.warn, log); console.error = bind(log.error, log); }

// Use empty dummy implementation to ignore logging
else
{
    console.log = (/** @param {...*} args */ function(args) {});
}

}

// Implement other log levels to console.log if missing if (!console["debug"]) console.debug = console.log; if (!console["info"]) console.info = console.log; if (!console["warn"]) console.warn = console.log; if (!console["error"]) console.error = console.log;

// Wrap the log methods in IE (<=9) because their argument handling is wrong // This wrapping is also done if the consoleShimTest symbol is set. This // is needed for unit testing. if (window["consoleShimTest"] != null || eval("/_@cc_on @_jscriptversion <= 9@/")) { /* * Wraps the call to a real IE logging method. Modifies the arguments so * parameters which are not represented by a placeholder are properly * printed with a space character as separator. * @param {...} args * The function arguments. First argument is the log function * to call, the other arguments are the log arguments. / var wrap = function(args) { var i, max, match, log;

    // Convert argument list to real array
    args = Array.prototype.slice.call(arguments, 0);

    // First argument is the log method to call
    log = args.shift();

    max = args.length;
    if (max > 1 && window["__consoleShimTest__"] !== false)
    {
        // When first parameter is not a string then add a format string to
        // the argument list so we are able to modify it in the next stop
        if (typeof(args[0]) != "string")
        {
            args.unshift("%o");
            max += 1;
        }

        // For each additional parameter which has no placeholder in the
        // format string we add another placeholder separated with a
        // space character.
        match = args[0].match(/%[a-z]/g);
        for (i = match ? match.length + 1 : 1; i < max; i += 1)
        {
            args[0] += " %o";
        }
    }
    Function.apply.call(log, console, args);
};

// Wrap the native log methods of IE to fix argument output problems
console.log = bind(wrap, window, console.log);
console.debug = bind(wrap, window, console.debug);
console.info = bind(wrap, window, console.info);
console.warn = bind(wrap, window, console.warn);
console.error = bind(wrap, window, console.error);

}

// Implement console.assert if missing if (!console["assert"]) { console["assert"] = function() { var args = Array.prototype.slice.call(arguments, 0); var expr = args.shift(); if (!expr) { args[0] = "Assertion failed: " + args[0]; console.error.apply(console, args); } }; }

// Linking console.dir and console.dirxml to the console.log method if // missing. Hopefully the browser already logs objects and DOM nodes as a // tree. if (!console["dir"]) console["dir"] = console.log; if (!console["dirxml"]) console["dirxml"] = console.log;

// Linking console.exception to console.error. This is not the same but // at least some error message is displayed. if (!console["exception"]) console["exception"] = console.error;

// Implement console.time and console.timeEnd if one of them is missing if (!console["time"] || !console["timeEnd"]) { var timers = {}; console["time"] = function(id) { timers[id] = new Date().getTime(); }; console["timeEnd"] = function(id) { var start = timers[id]; if (start) { console.log(id + ": " + (new Date().getTime() - start) + "ms"); delete timers[id]; } }; }

// Implement console.table if missing if (!console["table"]) { console["table"] = function(data, columns) { var i, iMax, row, j, jMax, k;

    // Do nothing if data has wrong type or no data was specified
    if (!data || !(data instanceof Array) || !data.length) return;

    // Auto-calculate columns array if not set
    if (!columns || !(columns instanceof Array))
    {
        columns = [];
        for (k in data[0])
        {
            if (!data[0].hasOwnProperty(k)) continue;
            columns.push(k);
        }
    }

    for (i = 0, iMax = data.length; i < iMax; i += 1)
    {
        row = [];
        for (j = 0, jMax = columns.length; j < jMax; j += 1)
        {
            row.push(data[i][columns[j]]);
        }

        Function.apply.call(console.log, console, row);
    }
};

}

// Dummy implementations of other console features to prevent error messages // in browsers not supporting it. if (!console["clear"]) console["clear"] = function() {}; if (!console["trace"]) console["trace"] = function() {}; if (!console["group"]) console["group"] = function() {}; if (!console["groupCollapsed"]) console["groupCollapsed"] = function() {}; if (!console["groupEnd"]) console["groupEnd"] = function() {}; if (!console["timeStamp"]) console["timeStamp"] = function() {}; if (!console["profile"]) console["profile"] = function() {}; if (!console["profileEnd"]) console["profileEnd"] = function() {}; if (!console["count"]) console["count"] = function() {};

})();

kayahr commented 11 years ago

What do you mean with "I am not allowed to do a pullrequest"? I don't know of any pull request restrictions. Anyone can fork the repo and create pull requests. Unfortunately in the current form it is hard to see what exactly you have changed to fix this memory leak. If you really can't create a pull request then can you please post the changes in diff format?

sigod commented 9 years ago

Hm. Only difference I can find is this: var console = (/** @type {Object} */ window.console); => var console = (/* @type {Object} */ window.console);

sigod commented 9 years ago

Nah, never mind. #8