pidgin/pidgin

69b44723d52c
facebook: Make $.hugePictureUrl.uri optional

Facebook seems to randomly send null in this field sometimes. It's not
very important so it can be made optional.

This includes moving the checksum code (which was previously duplicated)
to a separate function so that there's a single null check.
<!DOCTYPE html>
<html>
<head>
<style>
body{white-space:pre-wrap;}
div.l0{color:#000000;} /* All debug levels. */
div.l1{color:#666666;} /* Misc. */
div.l2{color:#000000;} /* Information. */
div.l3{color:#660000;} /* Warnings. */
div.l4{color:#FF0000;} /* Errors. */
div.l5{color:#FF0000;font-weight:bold;} /* Fatal errors. */
/* Filter levels */
div#pause~div{display:none;}
body.l1 div.l0{display:none;}
body.l2 div.l0,body.l2 div.l1{display:none;}
body.l3 div.l0,body.l3 div.l1,body.l3 div.l2{display:none;}
body.l4 div.l0,body.l4 div.l1,body.l4 div.l2,body.l4 div.l3{display:none;}
body.l5 div.l0,body.l5 div.l1,body.l5 div.l2,body.l5 div.l3,body.l5 div.l4{display:none;}
/* Regex */
div.hide{display:none;}
span.regex{background-color:#ffafaf;font-weight:bold;}
</style>
<script>
function nearBottom() {
return ( document.body.scrollTop >= ( document.body.offsetHeight - ( window.innerHeight * 1.5 ) ) );
}
function scrollToBottom() {
document.body.scrollTop = document.body.offsetHeight;
}
regex = {
clear: function () {
var list, i;
var scroll = nearBottom();
/* Remove highlighting SPANs */
list = document.getElementsByClassName('regex');
i = list.length;
while (i--) {
var span = list[i];
var parent = span.parentNode;
var content = span.textContent;
var text = document.createTextNode(content);
parent.replaceChild(text, span);
}
/* Remove hidden DIVs */
list = document.getElementsByClassName('hide');
i = list.length;
while (i--) {
list[i].classList.remove('hide');
}
if (scroll)
scrollToBottom();
this.enabled = false;
},
highlightTextNodes: function (div, start_pos, end_pos) {
var data = [], node, range, span, contents;
var ind, end_ind
var this_start, this_end;
ind = 0;
div.normalize();
node = div;
/* First, find the container nodes and offsets to apply highlighting. */
do {
if (node.nodeType === Node.TEXT_NODE) {
end_ind = ind + node.length;
if (start_pos <= ind)
this_start = 0;
else if (start_pos < end_ind)
this_start = start_pos - ind;
else
this_start = -1;
if (end_pos < end_ind)
this_end = end_pos - ind;
else
this_end = end_ind - ind;
if (this_start != -1 && this_start < this_end) {
data.push(this_end, this_start, node);
}
ind = end_ind;
}
if (node.hasChildNodes()) {
node = node.firstChild;
} else {
while (node != div) {
var next = node.nextSibling;
if (next) {
node = next;
break;
} else {
node = node.parentNode;
}
}
}
} while (node != div);
/* Second, apply highlighting to saved sections. Changing the DOM is
automatically reflected in all WebKit API, so we have to do this after
finding the offsets, or things could get complicated. */
while (data.length) {
node = data.pop();
this_start = data.pop();
this_end = data.pop();
range = document.createRange();
range.setStart(node, this_start);
range.setEnd(node, this_end);
span = document.createElement('span');
span.className = 'regex';
contents = range.extractContents();
range.insertNode(span);
span.appendChild(contents);
}
},
match: function (div) {
var text, match_info;
var m, count, start_pos, end_pos;
text = div.textContent;
if (!text)
return;
/* We do a first pass to see if it matches at all. If it does we work out
* the offsets to highlight.
*/
this.regex.lastIndex = 0;
var match_info = this.regex.exec(text);
if ((match_info != null) != this.invert) {
/* If we're not highlighting or the expression is inverted, we're
* done and move on.
*/
if (!this.highlight || this.invert)
return;
do {
if (match_info === null)
break;
count = match_info.length;
if (count === 1)
m = 0;
else
m = 1;
/* We do this because JS doesn't provide a sufficient means to
determine the indices of matched groups. So we're just going
to highlight the entire match instead. */
m = 0; count = 1;
for (; m < count; m++) {
start_pos = match_info.index;
end_pos = this.regex.lastIndex;
if (end_pos == -1)
break;
this.highlightTextNodes(div, start_pos, end_pos);
}
/* Workaround broken API for empty matches */
if (match_info.index == this.regex.lastIndex)
this.regex.lastIndex++;
} while (match_info = this.regex.exec(text));
} else {
div.classList.add('hide');
}
},
filterAll: function (str, inv, high) {
this.regex = new RegExp(str, 'gi');
this.invert = inv;
this.highlight = high;
this.enabled = true;
var list = document.getElementsByTagName('div');
for (var i = 0; i < list.length; i++)
this.match(list[i]);
},
highlight: false,
invert: false,
enabled: false,
regex: undefined
}
function append(level, time, cat, msg) {
var div = document.createElement('div');
div.className = 'l' + level;
div.appendChild(document.createTextNode('(' + time + ') '));
if (cat) {
var cat_n = document.createElement('b');
cat_n.appendChild(document.createTextNode(cat + ':'));
div.appendChild(cat_n);
div.appendChild(document.createTextNode(' '));
}
div.appendChild(document.createTextNode(msg));
if (regex.enabled)
regex.match(div);
var scroll = nearBottom();
document.body.appendChild(div);
if (scroll)
scrollToBottom();
}
function clear() {
document.body.innerHTML = '';
}
function pauseOutput() {
document.body.insertAdjacentHTML('beforeEnd', '<div id=pause></div>');
}
function resumeOutput() {
var pause = document.getElementById('pause');
if (pause) {
var parent = pause.parentNode;
parent.removeChild(pause);
scrollToBottom();
}
}
function setFilterLevel(l) {
var scroll = nearBottom();
document.body.className = 'l'+l;
if (scroll)
scrollToBottom();
}
</script>
</head>
<body class=l0></body>
</html>