Консоль для всех браузеров
Это попытка заставить работать синтаксис консоли FireBug'a со всеми браузерами. ИМХО кроссбраузерный дебаг звучит не ок, но это именно он! А все получилось как-то само собой когда я сегодня что-то дебажил на тестовой платформе и для того чтобы тестеры не видели ошибок прикрывал вызовы консоли заглушками.
if(window.console)
console.log("myLog");
В общем это как-то гнило, нашел что по данному поводу пишут разработчики Prototype и jQuery, и даже сами разработчики FireBug'a склоняются к заглушкам
Уж очень мне эти затычки не нравятся. И решил я выяснить что можно с этим сделать. Уточнив с какой версии у браузеров появилась консоль (и текущую версию): IE8b2 (IE7), Opera 9.50 (9.63), Safari 1.3 (3.21), FireFox 2.0.0 (3.0.5), я принялся за работу.
Первое что приходило на ум это что-то вроде
if (!window.console) {
window.console = {};
window.console.log = alert;
}
Но не все так просто, FireBug славится тем что показывает содержимое любого объекта и может делать форматированный вывод. То есть во-первых можно сделать
console.info({a:null});
и увидеть содержимое объекта в закладке DOM, а во-вторых можно сделать форматированный вывод
console.info("string: %d %s %d", 10, "text", 10);
и увидеть строку "string: 10 text 10". В остальных же браузерах можно наблюдать только строку [object Object] и "string: %d %s %d" соответственно, кроме IE8b2, он поддерживает форматный вывод, выпендрился, блин!
Я решил начать с написания форматного вывода, но функция sprintf оказалась настолько громоздкой и избыточной что я решил обойтись небольшим регулярным выражением, для своих нужд, тем более что FireBug тоже не различает %d и %s ;) в отличие от IE8b2 который корректно выводит 0 вместо %d которому соответствует строка. Из этого вывод что достаточно использовать только %s.
Потом я решили что было бы неплохо научиться отображать содержимое объектов и массивов, для этого как нельзя хорошо подходила одна известная функция, написанная очень нелюбимым мной человеком, имя которого можете прочитать в комментарии в коде. Единственные минус этой функции в том что она не может корректно отобразить объекты типа window, на нем она уходит куда-то в глубь рекурсии и безнадежно вешает браузер. Но этот недостаток я постараюсь решить в следующей версии, если такая появиться.
Уже неплохо. Последним штрихом к портрету было прикручивание уровня дебага "log", "debug", "info", "warn", "error". Тут для меня было несколько откровений. Первое это то что массив arguments не такой уже и массив потому что содержит в себе еще и метод callee. Второе - что объект arguments прекрасно превращается в массив с помощью волшебной строки
var args = Array.prototype.slice.call(arguments);
Третье - что этот метод не работает (правильно!) в IE7 и IE8b2, а поэтому не годиться. И наконец четвертое и последние что чертов arguments не возможно обойти циклом через in нужно обязательно это делать через длину
for(var i in arguments) // fail
alert(arguments[i]);
for(var i=0,j=arguments.length;i<j;i++) // ok
alert(arguments[i]);
Но это все не помешало мне дописать сегодня этот скрипт и выложит его на ваше растерзание
myConsole = function(){
var args = (function(a,x){for(var i=0,j=a.length;i<j;i++){x.push(a[i])};return x;})(arguments,[]);
if (args.length>2){
(window.opera?opera.postError:window.alert)(args.shift() +'':\\n''+ args.shift().replace(/(%[ds])/g, function(){
return args.shift();
})
)
}else{
// автор функции dump - Дмитрий Котеров
// http://dklab.ru/chicken/nablas/38.html
(window.opera?opera.postError:window.alert)(args.shift() +'':\\n''+ (function dump(d,l) {
if (l == null) l = 1;
var s = '''';
if (typeof(d) == "object") {
s += typeof(d) + " {\\n"; for (var k in d) {
for (var i=0; i<l; i++){
s += " ";
}
s += k+": " + dump(d[k],l+1);
}
for (var i=0; i<l-1; i++){
s += " ";
}
s += "}\\n"
} else {
s += "" + d + "\\n";
}
return s;
})(args.shift()));
}
}
if (window.loadFirebugConsole) { // since FireBug 1.2
window.loadFirebugConsole();
} else if (!window.console) {
window.console = {};
var names = ["log", "debug", "info", "warn", "error"];
for (var i in names){
window.console[names[i]] = (function(name){return function(){
myConsole.apply(null,(function(a,x){for(var i=0,j=a.length;i<j;i++){x.push(a[i])};return x;})(arguments,[name]))
}})(names[i]);
}
}
Кому пригодиться пишите в каменты...
Свежие комментарии