v1.0 Release – Fixing the OnScroll Patch to Work with the New Version of hg_templates

In my earlier blog post I outlined my plan to update my OnScroll patch to work with the new version of hg_templates, which was updated recently. Now, it has access to the jquery library, which can be used to do more fun stuff. I was using jquery beforehand too but now I’ve decided to take it a step further and take advantage of jquery even more. I believe by doing this I can significantly reduce the number of lines of code and still retain the same functionality.

The Old Code

For comparisons purposes I’ve posted the old code below:

57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
function loadEntries(iterations) 
{
  for(var t = 0; t < iterations; t++) {
    var loader = document.getElementById("loader");
    var end = start;
    var req = new XMLHttpRequest();
 
    loader.innerHTML = '<img src="{url}static/ajax-loader.gif" align="right" />';
    start = start - 20;
    req.open('GET', '/json-pushes?startID=' + start + '&endID=' + end, true);
    req.onreadystatechange = function() {
      if(req.readyState == 4) {
        if(req.status != 404) {
          var pushData = JSON.parse(req.responseText), counter = 0;
          //var counter = 0;
          for(var i = end; i > start; i--) {
            var row = document.createElement("tr");
            if(counter == 0) {
              row.className = "parity0"; 
              counter = 1;
            } else {
                row.className = "parity1";
                counter = 0;
            }  
            var userCol = document.createElement("td");
            var revCol = createRevTd(pushData[i].individualChangeset);
            var bugLink = createBuglink(pushData[i].desc);
            var authDescCol = document.createElement("td");
 
            userCol.width = "184px";
            userCol.innerHTML += pushData[i].user + '<br />' + pushData[i].formattedDate;
            authDescCol.innerHTML += '<strong>' + pushData[i].author + ' &mdash ' + bugLink + '</strong>';
            row.appendChild(userCol);
            row.appendChild(revCol);
            row.appendChild(authDescCol);
            loader.innerHTML = "";
            document.getElementById("titlePush").appendChild(row);
 
            //Check whether it is a merge changeset or not
            if(pushData[i].MergeData != []) {
              for(var j = 0; j < pushData[i].mergeData.length; j++) {
                if(pushData[i].mergeData[j] != "") {
                  var mergeStr = pushData[i].mergeData[j];
                  for(var k = 0; k < pushData[i].mergeData[j].length; k++) {
                    if(pushData[i].mergeData[j] instanceof Array) {
                      var actualMergeStr = mergeStr[k].split('|-|');
                      var mergeRev = actualMergeStr[0];
                      var mergeUser = actualMergeStr[1];
                      var mergeDesc = actualMergeStr[2];
                    }
                    else {
                      var actualMergeStr = mergeStr.split('|-|');
                      var mergeRev = actualMergeStr[0];
                      var mergeUser = actualMergeStr[1];
                      var mergeDesc = actualMergeStr[2];
                      k = pushData[i].mergeData[j].length;
                    }
                    if(mergeDesc != pushData[i].desc) {
                      var mergeRow = document.createElement("tr");
                      var mergeUserCol = document.createElement("td");
                      var mergeRevCol = createRevTd(mergeRev);
                      var merge_bugLink = createBuglink(mergeDesc);
                      var mergeAuthDescCol = document.createElement("td");
 
                      mergeRow.className = row.className;
                      mergeUserCol.width = "184px";
                      mergeAuthDescCol.innerHTML += '<strong>' + mergeUser + ' &mdash ' + merge_bugLink + '</strong>';
                      mergeRow.appendChild(mergeUserCol);
                      mergeRow.appendChild(mergeRevCol);
                      mergeRow.appendChild(mergeAuthDescCol);
                      document.getElementById("titlePush").appendChild(mergeRow);
                    }
                  }
                }
              }
            }
          }    
        }  
      }
    }
    req.send(null);
  }
}
 
function createRevTd(rev) 
{
  var td = document.createElement("td");
  td.innerHTML +=
    '<a href="/rev/' +
    rev.substring(0, 12) + 
    '">' + 
    rev.substring(0, 12) +
    '</a>'; 
 
  return td;
}

The New Code

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
function loadEntries(iterations) {
  for(var t = 0; t < iterations; t++) {
    var end = start;
 
    $('.loader').html('<img src="{url}static/ajax-loader.gif" align="right" />');
    start -= 20;
    $.get('/json-pushes?startID=' + start + '&endID=' + end, function(responseText) {
      var pushData = JSON.parse(responseText), counter = 0;
      for(var i = end; i > start; i--) {
        var row = $(document.createElement('tr'));
        if(counter == 0) {
          row.addClass('parity0');
          counter = 1;
        } 
        else {
          row.addClass('parity1');
          counter = 0;
        }
        // user column
        $('<td>' + pushData[i].user + '<br /><span class="date">' + pushData[i].formattedDate + '</span></td>')
          .appendTo(row)
          .width(184);  
        // rev column
        $('<td>' + createRevTd(pushData[i].individualChangeset) + '</td>').appendTo(row);
        // author and description column
        $('<td>' + '<strong>' + pushData[i].author + ' &mdash ' + createBuglink(pushData[i].desc) + '</strong>' + '</td>').appendTo(row);
        $('.loader').html("");
        $('.titlePush').append(row);
 
        //Check whether it is a merge changeset or not
        if(pushData[i].MergeData != []) {
          for(var j = 0; j < pushData[i].mergeData.length; j++) {
            if(pushData[i].mergeData[j] != "") {
              var mergeStr = pushData[i].mergeData[j];
              for(var k = 0; k < pushData[i].mergeData[j].length; k++) {
                if(pushData[i].mergeData[j] instanceof Array) {
                  var actualMergeStr = mergeStr[k].split('|-|');
                  var mergeRev = actualMergeStr[0];
                  var mergeUser = actualMergeStr[1];
                  var mergeDesc = actualMergeStr[2];
                }
                else {
                  var actualMergeStr = mergeStr.split('|-|');
                  var mergeRev = actualMergeStr[0];
                  var mergeUser = actualMergeStr[1];
                  var mergeDesc = actualMergeStr[2];
                  k = pushData[i].mergeData[j].length;
                }
                if(mergeDesc != pushData[i].desc) {
                  var mergeRow = $(document.createElement('tr')).addClass(row.attr('class'));
                  $(document.createElement('td')).appendTo(mergeRow).width(184);
                  $('<td>' + createRevTd(mergeRev) + '</td>').appendTo(mergeRow);
                  $('<td>' + '<strong>' + mergeUser + ' &mdash ' + createBuglink(mergeDesc) + '</strong>' + '</td>').appendTo(mergeRow);
                  $('.titlePush').append(mergeRow);
                }
              }
            }
          }
        }
      }    
    });
  }
}
 
function createRevTd(rev) {
  return '<a href="/rev/' +
    rev.substring(0, 12) + 
    '">' + 
    rev.substring(0, 12) +
    '</a>';
}

As you can see above is the new code. Lots of changes to look at it. First of all the JavaScript code has been shifted within $document.ready(). The major changes have occurred in loadEntries(). The jquery library makes it extremely simple to retrieve an object by its class or id name. Instead of having to use document.getElementbyId() I can use $(‘<class_name>’). I’ve used this way extensively throughout my new implementation. Furthermore, I don’t need to use document.createElement() anymore either. I can just use the  $(‘<html>’) syntax to create an element (e.g. line 84). Another great little change is how jquery creates an xmlHttpRequest(). The syntax is so much simpler. Only a simple $.get(url, function(responseText) {} ) is needed (line 65). Another little quirk that makes jquery awesome can be seen on lines 78-80. I can create the new element, append it to another element and change its attributes all in one go.

One important thing to note, however, is that some things didn’t change much at all. Such as the string manipulation functionality found at lines 88-107. All in all the end result of all these changes is that I have manged to reduce the total number of lines by 19. On top of that I have also added 2 extra pieces of functionality (I’ll be discussing them in future posts) without having to add any additional lines of code. A very good result, in my opinion.

This entry was posted in DPS911, Mercurial Project, Open Source and tagged , , . Bookmark the permalink.

6 Responses to v1.0 Release – Fixing the OnScroll Patch to Work with the New Version of hg_templates

  1. Excellent post thanks!

    Sent from my iPhone 4G

  2. Z1 guy says:

    Amazing post thank you!

  3. toyota camry says:

    My friend and I were arguing about this! Now I know that I was right. lol! Thanks for making me sure!

  4. tommy says:

    @toyota camry you and your friend were arguing about a new patch? wow that’s an arguement that’ll probably never happen again!

  5. Joe Francis says:

    Any code re-editing that reduces the number of lines of code can only be a good thing for everyone – programmers and non-programmers alike. Thanks for doing this project.

  6. Daniel Falk says:

    Noticed that this was posted a while ago – is the patch still necessary? By the way, would be great if you could highlight the differences!

Leave a Reply to toyota camry Cancel reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>