/*
,---------------------------------------------------------.
/ )
/ Hohoooo, hahaha... Pwet pwet! /
/ /
( Ioan Sameli, 04.2007 /
`--\ /--------------------------------------------------´
| /
\|
`
(")-''-(").___,.~-´'^`-._
\O_ O ) `-. ( ).`-.__.´)
(_Y_.)/ ._ ) `._ `. `´-..-´
_,.`--´_,.-_/ /~-`_.´ ,´
(il).-'´ (li).´ ((!.-´
TODO
----
* Remove the term "Key" and replace by "ID"
*/
var server_url = "http://www4.tsr.ch/vote/";
var json_url = server_url + 'vote.php';
// Default account id, but should be specified in the page from where the script is included
var idAccount = 1;
// The default template to display the comments
// (can be overriden in the page that calls this script)
if (typeof commentTemplate != 'string') commentTemplate = '
$author_name'
+ ', le $date à $time$text
';
var commentTemplateEF07 = '
$author_name / $date_time
$text
';
var latestCommentTemplateEF07 = '$text';
var err_notext = 'Veuillez remplir le formulaire avant de l\'envoyer';
// Define how many requests will be bundled together
// For example, on a page with 100 requests, bundle them by pack of 10 requests to avoid having one huge or 100 small requests
var requestBundleCount = 8;
var tsrvoteTags = {};
var tsrvoteTitles = {};
// Object containing
// class: The classes of the elements that will contain the data loaded from server
// idPrefix: The prefix of the name of the elements, remove it and you'll get the ID
// HTML exemple according to these settings:
// There are X votes
var elementsKeys = {
// Get the tags
'tags':{
'elClass':'tsrvote-tags',
'idPrefix':'tsrvote-tags-',
'dataType':'vote',
'functionInitElement':function(node, id) {
tsrvoteTags[id] = node.innerHTML;
// node.innerHTML = '';
}
},
// Get the titles
'title':{
'elClass':'tsrvote-title',
'idPrefix':'tsrvote-title-',
'dataType':'vote',
'functionInitElement':function(node, id) {
tsrvoteTitles[id] = node.innerHTML;
// node.innerHTML = '';
}
},
// Display a simple text counter
'count':{
'elClass':'tsrvote-count',
'idPrefix':'tsrvote-count-',
'dataType':'vote',
'functionDisplayResult':function(node, r) {
node.innerHTML = r.vote_count;
}
},
// Display a simple text counter
'countTxt':{
'elClass':'tsrvote-count',
'idPrefix':'tsrvote-countTxt-',
'dataType':'vote',
'functionDisplayResult':function(node, r) {
node.innerHTML = r.vote_count+" votes";
}
},
// Display a simple text average
'average':{
'elClass':'tsrvote-average',
'idPrefix':'tsrvote-average-',
'dataType':'vote',
'functionDisplayResult':function(node, r) {
node.innerHTML = r.vote_average;
}/*,
'functionInitElement':function(n) {n.innerHTML = '';}*/
},
// Display a simple text average
'poll':{
'elClass':'tsrvote-poll',
'idPrefix':'tsrvote-poll-',
'dataType':'vote',
'functionDisplayResult':function(node, r) {
// node.innerHTML = r.vote_average;
},
'functionInitElement':function(n) {
var a = n.id.replace(this.idPrefix, '').split('-');
for (var i in a) {
polls[a[i]] = a;
}
}
},
// Display a simple text average
'pollitem':{
'elClass':'tsrvote-pollitem',
'idPrefix':'tsrvote-pollitem-',
'dataType':'vote',
'functionDisplayResult':function(n, r) {
polls.render(n.id.replace(this.idPrefix, ''), r);
},
'functionInitElement':function(n) {
n.innerHTML = n.id + '';
}
},
// Comments ?
'comments':{
'elClass':'tsrvote-comments',
'idPrefix':'tsrvote-comments-',
'dataType':'comment',
'functionDisplayResult':function(node, r) {
if (!r.comments) return;
var allComments = '';
for (var c in r.comments) {
r.comments[c] = parseWebcams(r.comments[c]);
var t = commentTemplate;
// Replace all the properties in the template
for (var prop in r.comments[c]) {t = t.replace('$' + prop, r.comments[c][prop]);}
allComments += t;
}
node.innerHTML = allComments;
},
'functionInitElement':function(node, id) {node.innerHTML = '(Aucun commentaire)'}
},
// Latest Comments EF07-jourJ
'ef07latestcomments':{
'elClass':'ef07-latest-comments',
'idPrefix':'ef07-latest-comments-',
'dataType':'comment',
'functionDisplayResult':function(node, r) {
if (!r.comments) return;
var allComments = '';
for (var c in r.comments) {
var t = latestCommentTemplateEF07;
// Replace all the properties in the template
for (var prop in r.comments[c]) {
t = t.replace('$' + prop, r.comments[c][prop]);
}
//allComments += t;
allComments = t;
}
allComments = allComments.replace('ê','e');
allComments = allComments.replace('é','e');
allComments = allComments.replace('è','e');
allComments = allComments.replace('à','a');
allComments = allComments.replace('â','a');
allComments = allComments.replace(' ',' ');
allComments = allComments.replace('\\n',' ');
allComments = allComments.replace(' ',' ');
allComments = allComments.replace('\\r',' ');
node.innerHTML = allComments.substring(0,60)+' [...]';
},
'functionInitElement':function(node, id) {node.innerHTML = 'Aucun commentaire pour le moment'}
},
// Comments EF07-jourJ
'ef07comments':{
'elClass':'ef07-comments',
'idPrefix':'ef07-comments-',
'dataType':'comment',
'functionDisplayResult':function(node, r) {
if (!r.comments) return;
var allComments = '';
for (var c in r.comments) {
var t = commentTemplateEF07;
// Replace all the properties in the template
for (var prop in r.comments[c]) {
t = t.replace('$' + prop, r.comments[c][prop]);
}
allComments += t;
//allComments = t;
}
node.innerHTML = allComments;
},
'functionInitElement':function(node, id) {node.innerHTML = '(no comments yet)'}
},
// Comment form EF 07 Jour J
'ef07commentform':{
'elClass':'ef07-commentform',
'idPrefix':'ef07-commentform-',
'dataType':'comment',
// 'functionDisplayResult':function(node, r) {},
'functionInitElement':function(node, id) {
var lUrl = server_url + 'comment_form.php?account=' + tsrvote.idAccount + '&id=' + id;
// Load the comment form from the server
getURLContent(lUrl, function(t) {
// Under MSIE, if the iframe is created with dom, the form won't submit in it.
// So it has to be created using innerHTML
var codeIframe = '';
node.innerHTML = t + codeIframe;
// Function called when the form is submitted
var fPost = function() {
var elText = document.getElementById('comment_text-' + id);
// If there's a text entered (prevent empty comments)
if (elText.value) {
var elForm = document.getElementById('form-comment-' + id);
elForm.action = server_url + 'save-comment.php';
elForm.target = 'comment_saver_'+id;
elForm.submit();
elText.value = '';
// Reload the comments with a delay (to make sure that the server had time to record it)
window.setTimeout(function() {tsrvote.request(id, null, 'comment');}, 250);
document.getElementById('ef07-commentform-'+ id).style.display = 'none';
document.getElementById('ef07-comments-'+ id).style.display = 'block';
} else alert(err_notext);
}
var elSubmit = document.getElementById('submit-comment-' + id);
elSubmit.onclick = fPost;
});
}
},
// Comment form
'commentform':{
'elClass':'tsrvote-commentform',
'idPrefix':'tsrvote-commentform-',
'dataType':'comment',
// 'functionDisplayResult':function(node, r) {},
'functionInitElement':function(node, id) {
var lUrl = server_url + 'comment_form.php' +
'?account=' + tsrvote.idAccount +
'&id=' + id +
'&tags=' + encodeURI(tsrvoteTags[id]) +
'&title=' + encodeURI(tsrvoteTitles[id]);
// prompt('asdf',lUrl);
// Load the comment form from the server
getURLContent(lUrl, function(t) {
// Under MSIE, if the iframe is created with dom, the form won't submit in it.
// So it has to be created using innerHTML
var codeIframe = '';
node.innerHTML = t + codeIframe;
// Function called when the form is submitted
var fPost = function() {
var elText = document.getElementById('comment_text-' + id);
// If there's a text entered (prevent empty comments)
if (elText.value) {
var elForm = document.getElementById('form-comment-' + id);
elForm.action = server_url + 'save-comment.php';
elForm.target = 'comment_saver_'+id;
elForm.submit();
elText.value = '';
// Reload the comments with a delay (to make sure that the server had time to record it)
window.setTimeout(function() {tsrvote.request(id, null, 'comment');}, 250);
document.getElementById('comment-comfirm-' + id).style.display = 'block';
elForm.style.display='none';
} else alert(err_notext);
}
var elSubmit = document.getElementById('submit-comment-' + id);
elSubmit.onclick = fPost;
});
}
},
// A "digg style" button to vote on items
'digger':{
'elClass':'tsrvote-digger',
'idPrefix':'tsrvote-digger-',
'dataType':'vote',
'functionDisplayResult':function(node, r) {
// Display a "dugg" or "diggable" state according to the answer from server
node.className = this.elClass + ' ' + (r.vote_delay ? 'state-dugg' : 'state-digg');
},
'functionInitElement':function(node, id) {
// Add all the HTML elements needed using DOM
var score = node.innerHTML || ' ';
node.innerHTML = '';
node.className += ' state-digg';
var elCounter = document.createElement('span');
elCounter.className = 'tsrvote-count';
elCounter.id = 'tsrvote-count-'+id;
elCounter.innerHTML = score;
node.appendChild(elCounter);
var elDugg = document.createElement('span');
elDugg.className = 'dugg';
elDugg.appendChild(document.createTextNode('dugg'));
node.appendChild(elDugg);
var elDigger = document.createElement('a');
elDigger.href = '#';
elDigger.className = 'digg';
elDigger.onclick = function() {
tsrvote.request(id, 1);
return false;
};
elDigger.appendChild(document.createTextNode('digg it'));
node.appendChild(elDigger);
}
},
// A "digg style" button to vote on items
'tsrelectionbtn':{
'elClass':'blockVoteBtnVoter',
'idPrefix':'blockVoteBtnVoter-',
'dataType':'vote',
'functionDisplayResult':function(node, r) {
if (r.vote_delay) {
node.innerHTML = '';
var elImg = document.createElement('img');
elImg.src = '/images/dossier_module/btn_merci.gif';
elImg.alt = 'Merci';
node.appendChild(elImg);
}
},
'functionInitElement':function(node, id) {
// Add all the HTML elements needed using DOM
node.innerHTML = '';
var elDigger = document.createElement('a');
elDigger.href = '#';
elDigger.className = 'digg';
elDigger.onclick = function() {
tsrvote.request(id, 1);
return false;
};
var elImg = document.createElement('img');
elImg.src = '/images/dossier_module/btn_voter.gif';
elImg.alt = 'Voter';
elDigger.appendChild(elImg);
node.appendChild(elDigger);
}
},
// Create a simple list of links from 0 to 10 to vote.
'textvoter':{
'elClass':'tsrvote-textvoter',
'idPrefix':'tsrvote-textvoter-',
'dataType':'vote',
'functionInitElement':function(node, id) {
var h = '';
for (var i = 0; i < 11; i++)
h += '' + i + '\n';
node.innerHTML = h;
}
},
// A "digg style" button to vote on items
'tsrVoteBtn':{
'elClass':'tsrVoteBtn',
'idPrefix':'tsrVoteBtn-',
'dataType':'vote',
'functionDisplayResult':function(node, r) {
if (r.vote_delay) {
//node.innerHTML = 'Merci d\'avoir voté';
node.innerHTML = r.vote_count+' votes';
//var elImg = document.createElement('img');
//elImg.src = '/images/dossier_module/btn_merci.gif';
//elImg.alt = 'Merci';
//node.appendChild(elImg);
}
},
'functionInitElement':function(node, id) {
// Add all the HTML elements needed using DOM
node.innerHTML = '';
var elDigger = document.createElement('a');
elDigger.href = '#';
elDigger.className = 'digg';
elDigger.onclick = function() {
tsrvote.request(id, 1);
return false;
};
var elImg = document.createElement('img');
texte = 'Voter';
elDigger.innerHTML = texte;
node.appendChild(elDigger);
}
},
// Create a simple list of links from 0 to 10 to vote.
'textvoter':{
'elClass':'tsrvote-textvoter',
'idPrefix':'tsrvote-textvoter-',
'dataType':'vote',
'functionInitElement':function(node, id) {
var h = '';
for (var i = 0; i < 11; i++)
h += '' + i + '\n';
node.innerHTML = h;
}
},
// A pretty graphic star-based voter.
'stars':{
'elClass':'tsrvote-stars',
'idPrefix':'tsrvote-stars-',
'dataType':'vote',
'functionDisplayResult':function(node, r) {
if (r.vote_delay) {
node.firstChild.className = 'voted value-'+Math.round(r.vote_average/2);
} else {
node.firstChild.className = 'votable value-'+Math.round(r.vote_average/2);
node.firstChild.title = 'Moyenne: ' + r.vote_average + ' / 10';
}
},
'functionInitElement':function(node, id) {
var elList = document.createElement('ul');
for (var i = 1; i < 6; i++) {
var elLink = document.createElement('a');
elLink.href = '#'+i*2;
elLink.name = 'value-' + i;
elLink.className = 'star-' + i;
elLink.onclick = function() {
tsrvote.request(id, this.name.substr(6) * 2);
return false;
};
elLink.appendChild(document.createTextNode('vote ' + i));
var elElm = document.createElement('li');
elElm.appendChild(elLink);
elList.appendChild(elElm);
}
elList.className = 'votable';
node.appendChild(elList);
}
},
// A pretty graphic star-based voter. (note sur 6)
'stars6':{
'elClass':'tsrvote-stars6',
'idPrefix':'tsrvote-stars6-',
'dataType':'vote',
'functionDisplayResult':function(node, r) {
if (r.vote_delay) {
node.innerHTML = '';
var elImg = document.createElement('img');
//elImg.src = server_url + 'graphics/star_rating_ok_6.png';
elImg.src = server_url + 'graphics/star-rating-all-6.gif';
elImg.style.backgroundPosition = '-' + Math.round(((6 - r.vote_average)/6 * 120)) + 'px';
//node.removeChild()
elImg.title = 'Note: ' + r.vote_average + ' / 6';
node.appendChild(elImg);
}
},
'functionInitElement':function(node, id) {
var elList = document.createElement('ul');
for (var i = 1; i < 7; i++) {
var elLink = document.createElement('a');
elLink.href = '#'+i;
elLink.name = 'value-' + i;
elLink.className = 'star-' + i;
elLink.onclick = function() {
tsrvote.request(id, this.name.substr(6));
return false;
};
elLink.appendChild(document.createTextNode('vote ' + i));
var elElm = document.createElement('li');
elElm.appendChild(elLink);
elList.appendChild(elElm);
}
elList.className = 'votable';
node.appendChild(elList);
}
},
// A graphic bar displaying the result
'bar':{
'elClass':'tsrvote-bar',
'idPrefix':'tsrvote-bar-',
'dataType':'vote',
'functionDisplayResult':function(node, r) {
var elImg = node.firstChild;
elImg.style.backgroundPosition = '-' + Math.round(((1-(r.vote_average / 10)) * 150)) + 'px';
elImg.title = elImg.alt = Math.round((r.vote_average / 10) * 100) + '%';
},
'functionInitElement':function(node, id) {
var elImg = document.createElement('img');
elImg.src = server_url + 'graphics/percent_bar_container.png';
elImg.title = elImg.alt = '0%';
node.innerHTML = '';
node.appendChild(elImg);
}
},
// Simply a test, will display some asdf stuff
'asdf':{
'elClass':'tsrvote-asdf',
'idPrefix':'tsrvote-asdf-',
'dataType':'vote',
'functionInitElement':function(node) {
node.innerHTML = 'sdofihsdopf hspdfuhgp isdfhgos aehrgkshd flsgherp';
}
}
}
// Root object of TSRVote
var tsrvote = {
// Launch a request to the TSRVote server
// used both to load results or to register a vote
// Arguments:
// vote_id (required): one or several IDs, separated by comma
// voted_value (optional): give this parameter to vote on the given ID
// vote_callback (optional): a function to execute once the server answered.
'request':function(vote_id, voted_value, data_type, vote_callback) {
// Function that handles the results of the JSON, and modify the page according to the new data.
var handleVote = function(r) {
// If there is a list of all the objects to update in the page (this.elementsToUpdate), only update these
// Otherwise, update all the possibilities, with a list from elementsKeys.
// for (var j in ((this.elementsToUpdate||0)[r.vote_results[i].id] || elementsKeys)) {
for (var i in r.items) {
for (var j in elementsKeys) {
if (elementsKeys[j].functionDisplayResult) {
if (node = document.getElementById(elementsKeys[j].idPrefix + r.items[i].id)) {
elementsKeys[j].functionDisplayResult(node, r.items[i]);
}
}
}
}
};
var f = vote_callback ? function(r) {handleVote(r); vote_callback(r)} : handleVote;
// Create JSON request using tsrkit
var newRequest = new wonderJSON({
rSource: json_url,
rSourceArguments: {
'data': data_type,
'account': tsrvote.idAccount,
'id': vote_id,
'value': voted_value,
'tags': tsrvoteTags[vote_id] || '',
'title': tsrvoteTitles[vote_id] || ''
},
addCallbackArgument: '&jsonp=',
onAnswer: f
}).launch();
},
'setTag':function(id,tags) {
tsrvoteTags[id] = tags;
},
'initPage':function() {
tsrvote.idAccount = idAccount;
// Will contain a list of all the keys to load the vote from
var allIdsToLoad = {};
// For each type of elements supported, check if there are some in the page
for (var i in elementsKeys) {
var keys = elementsKeys[i], nodes = getClassVote(keys.elClass);
// Walk trough all the elements found for this type
for (var j = nodes.length - 1; j >= 0; --j) {
var node = nodes[j];
// Get the key of the ressource to get the score from, that is contained in the id attribute of the tag
var id = encodeURIComponent(node.id.replace(keys.idPrefix, ''));
if (!id) continue;
var dt = keys.dataType;
if (!allIdsToLoad[dt]) allIdsToLoad[dt] = {};
// If there's a function to display results for this type of object,
// add the id to the list of ids to load.
if (keys.functionDisplayResult) {
(allIdsToLoad[dt][id] || (allIdsToLoad[dt][id] = {}))[i] = 1;
}
// If there's a function to init the element (that doesn't need data from the DB)
if (keys.functionInitElement) keys.functionInitElement(node, id);
}
}
// Bundle the ids together in comma-separated strings.
// To avoid making many single little requests, and not one huge request too.
for (var dataType in allIdsToLoad) {
var dataIds = allIdsToLoad[dataType];
var strIds = {}, i = 0, j = 0;
for (var cid in dataIds) {
if (i++ % requestBundleCount == 0) strIds[++j] = '';
strIds[j] += (strIds[j] ? ',' : '') + cid;
}
for (var i in strIds) tsrvote.request(strIds[i], null, dataType);
// for (var i in strIds) alert(strIds[i]);
}
}
}
function parseWebcams(c) {
if (c['author_name'] == 'nouvoscope') {
var flash_webcam_server = 'http://fms.nouvo.ch/fms/infrarouge/streams/';
var webcam_player_path = 'http://www.tsr.ch/flash/flv-player.swf';
var webcam_player_path = 'http://www.tsr.ch/flash/flvplayer_presse-webcam.swf';
flvPath = c['author_website'].replace('nouvoscope://', flash_webcam_server );
c['text'] = ''
+''
+''+c['text'];
c['author_website'] = '';
c['author_name'] = 'webcam';
}
return c;
}
/***************************************/
/***** RANDOM USEFUL FUNCTIONS *****/
/***************************************/
startList = [];
// Add a function that will be executed at page loading
// f: the function to be executed on page load
function addToStart(f) {startList.push(f);}
// To execute several functions on page load
window.onload = function() {while (startList.length) startList.shift()();}
// classic getElementsByClassName function
// with non standard name to avoid collision with other scripts
// Ioan Sameli, 04/2007
function getClassVote(cName, tags, node) {
var a = [], re = new RegExp('\\b' + cName + '\\b');
//var els = (node || document).getElementsByTagName(tags || "*");
if (!node) node = document;
var els = (node).getElementsByTagName(tags || "*");
for (var i=0, j=els.length; i