Archiwum dla September, 2010

Ostatnio miałem nieprzyjemność integrowania płatnego komponentu ExtJs. Chodzi  konkretnie o komponent kalendarza, który wyglądem oraz funkcjonalnością naśladował Google Calendar. Niestety kod był napisany fatalnie, powiązania pomiędzy poszczególnymi elementami kalendarza były bardzo zawiłe co strasznie utrudniało integracje z istniejącym systemem.  Śledzenie wywołań poszczególnych metod i ich parametrów przysparzało sporo problemów. Dodatkowo dodawanie linijki console.log(arguments) wewnątrz cudzych funkcji nie jest eleganckie (choć i tak często to robię…)

Chcąc ułatwić swoją pracę i jednocześnie rezygnując z niepotrzebnego ingerowania w obcy kod stworzyłem bardzo prostą w działaniu funkcję do monitorowania wywołań metod wskazanych klass i obiektów (W przypadku biblioteki ExtJs sprawuje się ona znakomicie).

/**
 * Klasa monitoruje wywołania metod klas i obiektów
 *
 * @author Hubert Marzec
 * @param {Object} source - klasa/obiekt
 * @param {string} className - nazwa klasy
 * @param {array} methodList - wyszczególniona lista metod
 */
function classLogger(source, className, methodsList){
  if (source &&
    (typeof source == "object" || typeof source == "function")) {
    source = source.prototype || source;
    className = className || '';
    methodsList = methodsList || [];

    var name, method;
    var vLog = (typeof(console) !== 'undefined'
      && console != null) ? console.log : function(){};

    for (name in source){
     method = source[name];
     if (typeof method == "function" && (methodsList.length ?
       (inArray(methodsList, name)): true )){

       source[name] = function(name, method){
       return function(){
         var vResult = method.apply(this, arguments);
         vResult = vResult || '';
         vLog(className + '->' + name,
           arguments, ' = ',
           vResult
         );
         return vResult;
       };

      }(name, method);
     }
    }
  }

  function inArray(pArray, value) {
   pArray = pArray || [];
   for(var i=0, all=pArray.length; i < all; i++) {
     if (pArray[i] == value) {
       return true;
     }
   }
   return false
  }
}

Działanie jest dość proste: wybrane lub wszystkie (gdy nie wyszczególniono konkretnych) metody danego obiektu/klasy zostają opakowane przez dodatkową funkcje, która jest odpowiedzialna za wyświetlanie nazwy, parametrów wejściowych oraz wyniku funkcji oryginalnej.

firebug.jpg

Całość jest wyświetlana przy pomocy konsoli przeglądarki. W przypadku gdy konsola nie jest zaimplementowana, logi nie są wyświetlane. Przykładowe sposoby użycia classLoggera:

var mainWindow = new Ext.Window({
  title: 'okno'
});
classLogger(Ext.Panel, 'Ext.Panel');
classLogger(mainWindow, 'mainWindow');

Będzie mi bardzo miło, jeżeli ten fragment kodu się komuś przyda. Jednocześnie jestem otwarty na uwagi i waszą opinię.

category ExtJs, javascript, programowanie Komentarze (2)