SURPRISE! Preliminary PostgreSQL support added. The required schema file is not present in this commit and will be included at a later date. No installer support is implemented. Also in this commit: several fixes including <!-- SYSMSG ... --> was broken in template compiler; set fixed width on included images to prevent the thumbnail box from getting huge; added a much more friendly interface to AJAX responses that are invalid JSON
+ − // Comments
+ −
+ − var comment_template = false;
+ − var comment_render_track = 0;
+ −
+ − function ajaxComments(parms)
+ − {
+ − setAjaxLoading();
+ − var pid = strToPageID(title);
+ − if(!parms)
+ − {
+ − var parms = {
+ − 'mode' : 'fetch'
+ − };
+ − }
+ − parms.page_id = pid[0];
+ − parms.namespace = pid[1];
+ − if(comment_template)
+ − parms.have_template = true;
+ − parms = ajaxEscape(toJSONString(parms));
+ − ajaxPost(stdAjaxPrefix+'&_mode=comments', 'data=' + parms, function() {
+ − if(ajax.readyState == 4) {
+ − unsetAjaxLoading();
+ − selectButtonMajor('discussion');
+ − unselectAllButtonsMinor();
+ − // IE compatibility - doing ajax.responseText.substr() doesn't work
+ − var rsptxt = ajax.responseText + '';
+ − if ( rsptxt.substr(0, 1) != '{' )
+ − {
+ − document.getElementById('ajaxEditContainer').innerHTML = '<p>Comment system Javascript runtime: invalid JSON response from server, response text:</p><pre>' + ajax.responseText + '</pre>';
+ − return false;
+ − }
+ − var response = parseJSON(ajax.responseText);
+ − switch(response.mode)
+ − {
+ − case 'fetch':
+ − document.getElementById('ajaxEditContainer').innerHTML = '<div class="wait-box">Rendering '+response.count_total+' comments...</div>';
+ − if(response.template)
+ − comment_template = response.template;
+ − setAjaxLoading();
+ − renderComments(response);
+ − unsetAjaxLoading();
+ − break;
+ − case 'redraw':
+ − redrawComment(response);
+ − break;
+ − case 'annihilate':
+ − annihiliateComment(response.id);
+ − break;
+ − case 'materialize':
+ − alert('Your comment has been posted. If it does not appear right away, it is probably awaiting approval.');
+ − hideCommentForm();
+ − materializeComment(response);
+ − break;
+ − case 'error':
+ − new messagebox(MB_OK|MB_ICONSTOP, ( response.title ? response.title : 'Error fetching comment data' ), response.error);
+ − break;
+ − default:
+ − alert(ajax.responseText);
+ − break;
+ − }
+ − }
+ − });
+ − }
+ −
+ − function renderComments(data)
+ − {
+ −
+ − var html = '';
+ −
+ − // Header
+ −
+ − html += '<h3>Article Comments</h3>';
+ −
+ − var ns = ( strToPageID(title)[1]=='Article' ) ? 'article' : ( strToPageID(title)[1].toLowerCase() ) + ' page';
+ −
+ − // Counters
+ − if ( data.auth_mod_comments )
+ − {
+ − var cnt = ( data.auth_mod_comments ) ? data.count_total : data.count_appr;
+ − if ( cnt == 0 ) cnt = 'no';
+ − var s = ( cnt == 1 ) ? '' : 's';
+ − var is = ( cnt == 1 ) ? 'is' : 'are';
+ − html += "<p id=\"comment_status\">There "+is+" " + cnt + " comment"+s+" on this "+ns+".";
+ − if ( data.count_unappr > 0 )
+ − {
+ − html += ' <span style="color: #D84308">' + data.count_unappr + ' of those are unapproved.</span>';
+ − }
+ − html += '</p>';
+ − }
+ − else
+ − {
+ − var cnt = data.count_appr;
+ − if ( cnt == 0 ) cnt = 'no';
+ − var s = ( cnt == 1 ) ? '' : 's';
+ − var is = ( cnt == 1 ) ? 'is' : 'are';
+ − html += "<p id=\"comment_status\">There "+is+" " + cnt + " comment"+s+" on this "+ns+".";
+ − if ( data.count_unappr > 0 )
+ − {
+ − var s = ( data.count_unappr == 1 ) ? '' : 's';
+ − var is = ( data.count_unappr == 1 ) ? 'is' : 'are';
+ − html += ' However, there '+is+' '+data.count_unappr+' additional comment'+s+' awaiting approval.';
+ − }
+ − html += '</p>';
+ − }
+ −
+ − // Comment display
+ −
+ − if ( data.count_total > 0 )
+ − {
+ − comment_render_track = 0;
+ − var commentpages = new paginator(data.comments, _render_comment, 0, 10, data);
+ − html += commentpages.html;
+ − }
+ −
+ − if ( data.auth_post_comments )
+ − {
+ −
+ − // Posting form
+ −
+ − html += '<h3>Got something to say?</h3>';
+ − html += '<p>If you have comments or suggestions on this article, you can shout it out here.';
+ − if ( data.approval_needed )
+ − html+=' Before your post will be visible to the public, a moderator will have to approve it.';
+ − html += ' <a id="leave_comment_button" href="#" onclick="displayCommentForm(); return false;">Leave a comment...</a></p>';
+ − html += '<div id="comment_form" style="display: none;">';
+ − html += ' <table border="0">';
+ − html += ' <tr><td>Your name/screen name:</td><td>';
+ − if ( data.user_id > 1 ) html += data.username + '<input id="commentform_name" type="hidden" value="'+data.username+'" size="40" />';
+ − else html += '<input id="commentform_name" type="text" size="40" />';
+ − html += ' </td></tr>';
+ − html += ' <tr><td>Comment subject:</td><td><input id="commentform_subject" type="text" size="40" /></td></tr>';
+ − html += ' <tr><td>Comment:</td><td><textarea id="commentform_message" rows="15" cols="50"></textarea></td></tr>';
+ − if ( !data.logged_in && data.guest_posting == '1' )
+ − {
+ − html += ' <tr><td>Visual confirmation:<br /><small>Please enter the confirmation code seen in the image on the right into the box. If you cannot read the code, please click on the image to generate a new one. This helps to prevent automated bot posting.</small></td><td>';
+ − html += ' <img alt="CAPTCHA image" src="'+makeUrlNS('Special', 'Captcha/' + data.captcha)+'" onclick="this.src=\''+makeUrlNS('Special', 'Captcha/' + data.captcha)+'/\'+Math.floor(Math.random()*10000000);" style="cursor: pointer;" /><br />';
+ − html += ' Confirmation code: <input type="text" size="8" id="commentform_captcha" />';
+ − html += ' <!-- This input is used to track the ID of the CAPTCHA image --> <input type="hidden" id="commentform_captcha_id" value="'+data.captcha+'" />';
+ − html += ' </td></tr>';
+ − }
+ − html += ' <tr><td colspan="2" style="text-align: center;"><input type="button" onclick="submitComment();" value="Submit comment" /></td></tr>';
+ − html += ' </table>';
+ − html += '</div>';
+ −
+ − }
+ −
+ − document.getElementById('ajaxEditContainer').innerHTML = html;
+ −
+ − for ( i = 0; i < data.comments.length; i++ )
+ − {
+ − document.getElementById('comment_source_'+i).value = data.comments[i].comment_source;
+ − }
+ −
+ − }
+ −
+ − var _render_comment = function(this_comment, data)
+ − {
+ − var i = comment_render_track;
+ − comment_render_track++;
+ − var parser = new templateParser(comment_template);
+ − var tplvars = new Object();
+ −
+ − if ( this_comment.approved != '1' && !data.auth_mod_comments )
+ − return '';
+ −
+ − tplvars.ID = i;
+ − tplvars.DATETIME = this_comment.time;
+ − tplvars.SUBJECT = this_comment.subject;
+ − tplvars.DATA = this_comment.comment_data;
+ − tplvars.SIGNATURE = this_comment.signature;
+ −
+ − if ( this_comment.approved != '1' )
+ − tplvars.SUBJECT += ' <span style="color: #D84308">(Unapproved)</span>';
+ −
+ − // Name
+ − tplvars.NAME = this_comment.name;
+ − if ( this_comment.user_id > 1 )
+ − tplvars.NAME = '<a href="' + makeUrlNS('User', this_comment.name) + '">' + this_comment.name + '</a>';
+ −
+ − // User level
+ − tplvars.USER_LEVEL = 'Guest';
+ − if ( this_comment.user_level >= data.user_level.member ) tplvars.USER_LEVEL = 'Member';
+ − if ( this_comment.user_level >= data.user_level.mod ) tplvars.USER_LEVEL = 'Moderator';
+ − if ( this_comment.user_level >= data.user_level.admin ) tplvars.USER_LEVEL = 'Administrator';
+ −
+ − // Send PM link
+ − tplvars.SEND_PM_LINK=(this_comment.user_id>1 && data.logged_in)?'<a onclick="window.open(this.href); return false;" href="'+ makeUrlNS('Special', 'PrivateMessages/Compose/To/' + ( this_comment.name.replace(/ /g, '_') )) +'">Send private message</a><br />':'';
+ −
+ − // Add buddy link
+ − tplvars.ADD_BUDDY_LINK=(this_comment.user_id>1 && data.logged_in && this_comment.is_buddy != 1)?'<a onclick="window.open(this.href); return false;" href="'+ makeUrlNS('Special', 'PrivateMessages/FriendList/Add/' + ( this_comment.name.replace(/ /g, '_') )) +'">Add to buddy list</a><br />':'';
+ −
+ − // Edit link
+ − tplvars.EDIT_LINK='<a href="#edit_'+i+'" onclick="editComment(\''+i+'\', this); return false;" id="cmteditlink_'+i+'">edit</a>';
+ −
+ − // Delete link
+ − tplvars.DELETE_LINK='<a href="#delete_'+i+'" onclick="deleteComment(\''+i+'\'); return false;">delete</a>';
+ −
+ − // Moderation: (Un)approve link
+ − var appr = ( this_comment.approved == 1 ) ? 'Unapprove' : 'Approve';
+ − tplvars.MOD_APPROVE_LINK='<a href="#approve_'+i+'" id="comment_approve_'+i+'" onclick="approveComment(\''+i+'\'); return false;">'+appr+'</a>';
+ −
+ − // Moderation: Delete post link
+ − tplvars.MOD_DELETE_LINK='<a href="#mod_del_'+i+'" onclick="deleteComment(\''+i+'\'); return false;">Delete</a>';
+ −
+ − var tplbool = new Object();
+ −
+ − tplbool.signature = ( this_comment.signature == '' ) ? false : true;
+ − tplbool.can_edit = ( data.auth_edit_comments && ( ( this_comment.user_id == data.user_id && data.logged_in ) || data.auth_mod_comments ) );
+ − tplbool.auth_mod = data.auth_mod_comments;
+ − tplbool.is_friend = ( this_comment.is_buddy == 1 && this_comment.is_friend == 1 );
+ − tplbool.is_foe = ( this_comment.is_buddy == 1 && this_comment.is_friend == 0 );
+ −
+ − if ( tplbool.is_friend )
+ − tplvars.USER_LEVEL += '<br /><b>On your friend list</b>';
+ − else if ( tplbool.is_foe )
+ − tplvars.USER_LEVEL += '<br /><b>On your foe list</b>';
+ −
+ − parser.assign_vars(tplvars);
+ − parser.assign_bool(tplbool);
+ −
+ − return '<div id="comment_holder_' + i + '"><input type="hidden" value="'+this_comment.comment_id+'" /><input type="hidden" id="comment_source_'+i+'" />' + parser.run() + '</div>';
+ − }
+ −
+ − function displayCommentForm()
+ − {
+ − document.getElementById('leave_comment_button').style.display = 'none';
+ − document.getElementById('comment_form').style.display = 'block';
+ − }
+ −
+ − function hideCommentForm()
+ − {
+ − document.getElementById('leave_comment_button').style.display = 'inline';
+ − document.getElementById('comment_form').style.display = 'none';
+ − }
+ −
+ − function editComment(id, link)
+ − {
+ − var ctr = document.getElementById('subject_'+id);
+ − var subj = ( ctr.firstChild ) ? trim(ctr.firstChild.nodeValue) : ''; // If there's a span in there that says 'unapproved', this eliminates it
+ − ctr.innerHTML = '';
+ − var ipt = document.createElement('input');
+ − ipt.id = 'subject_edit_'+id;
+ − ipt.value = subj;
+ − ctr.appendChild(ipt);
+ −
+ − var src = document.getElementById('comment_source_'+id).value;
+ − var cmt = document.getElementById('comment_'+id);
+ − cmt.innerHTML = '';
+ − var ta = document.createElement('textarea');
+ − ta.rows = '10';
+ − ta.cols = '40';
+ − ta.value = src;
+ − ta.id = 'comment_edit_'+id;
+ − cmt.appendChild(ta);
+ −
+ − link.style.fontWeight = 'bold';
+ − link.innerHTML = 'save';
+ − link.onclick = function() { var id = this.id.substr(this.id.indexOf('_')+1); saveComment(id, this); return false; };
+ − }
+ −
+ − function saveComment(id, link)
+ − {
+ − var data = document.getElementById('comment_edit_'+id).value;
+ − var subj = document.getElementById('subject_edit_'+id).value;
+ − var div = document.getElementById('comment_holder_'+id);
+ − var real_id = div.getElementsByTagName('input')[0]['value'];
+ − var req = {
+ − 'mode' : 'edit',
+ − 'id' : real_id,
+ − 'local_id' : id,
+ − 'data' : data,
+ − 'subj' : subj
+ − };
+ − link.style.fontWeight = 'normal';
+ − link.innerHTML = 'edit';
+ − link.onclick = function() { var id = this.id.substr(this.id.indexOf('_')+1); editComment(id, this); return false; };
+ − ajaxComments(req);
+ − }
+ −
+ − function deleteComment(id)
+ − {
+ − if ( !shift )
+ − {
+ − var c = confirm('Do you really want to delete this comment?');
+ − if(!c)
+ − return false;
+ − }
+ − var div = document.getElementById('comment_holder_'+id);
+ − var real_id = div.getElementsByTagName('input')[0]['value'];
+ − var req = {
+ − 'mode' : 'delete',
+ − 'id' : real_id,
+ − 'local_id' : id
+ − };
+ − ajaxComments(req);
+ − }
+ −
+ − function submitComment()
+ − {
+ − var name = document.getElementById('commentform_name').value;
+ − var subj = document.getElementById('commentform_subject').value;
+ − var text = document.getElementById('commentform_message').value;
+ − if ( document.getElementById('commentform_captcha') )
+ − {
+ − var captcha_code = document.getElementById('commentform_captcha').value;
+ − var captcha_id = document.getElementById('commentform_captcha_id').value;
+ − }
+ − else
+ − {
+ − var captcha_code = '';
+ − var captcha_id = '';
+ − }
+ − if ( subj == '' )
+ − {
+ − new messagebox(MB_OK|MB_ICONSTOP, 'Input validation failed', 'Please enter a subject for your comment.');
+ − return false;
+ − }
+ − if ( text == '' )
+ − {
+ − new messagebox(MB_OK|MB_ICONSTOP, 'Input validation failed', 'Please enter some text for the body of your comment .');
+ − return false;
+ − }
+ − var req = {
+ − 'mode' : 'submit',
+ − 'name' : name,
+ − 'subj' : subj,
+ − 'text' : text,
+ − 'captcha_code' : captcha_code,
+ − 'captcha_id' : captcha_id
+ − };
+ − ajaxComments(req);
+ − }
+ −
+ − function redrawComment(data)
+ − {
+ − if ( data.subj )
+ − {
+ − document.getElementById('subject_' + data.id).innerHTML = data.subj;
+ − }
+ − if ( data.approved && data.approved != '1' )
+ − {
+ − document.getElementById('subject_' + data.id).innerHTML += ' <span style="color: #D84308">(Unapproved)</span>';
+ − }
+ − if ( data.approved && ( typeof(data.approve_updated) == 'string' && data.approve_updated == 'yes' ) )
+ − {
+ − var appr = ( data.approved == '1' ) ? 'Unapprove' : 'Approve';
+ − document.getElementById('comment_approve_'+data.id).innerHTML = appr;
+ −
+ − // Update approval status
+ − var p = document.getElementById('comment_status');
+ − var count = p.firstChild.nodeValue.split(' ')[2];
+ −
+ − if ( p.firstChild.nextSibling )
+ − {
+ − var span = p.firstChild.nextSibling;
+ − var is = ( data.approved == '1' ) ? -1 : 1;
+ − var n_unapp = parseInt(span.firstChild.nodeValue.split(' ')[0]) + is;
+ − n_unapp = n_unapp + '';
+ − }
+ − else
+ − {
+ − var span = document.createElement('span');
+ − p.innerHTML += ' ';
+ − span.innerHTML = ' ';
+ − span.style.color = '#D84308';
+ − var n_unapp = '1';
+ − p.appendChild(span);
+ − }
+ − span.innerHTML = n_unapp + ' of those are unapproved.';
+ − if ( n_unapp == '0' )
+ − p.removeChild(span);
+ − }
+ − if ( data.text )
+ − {
+ − document.getElementById('comment_' + data.id).innerHTML = data.text;
+ − }
+ − if ( data.src )
+ − {
+ − document.getElementById('comment_source_' + data.id).value = data.src;
+ − }
+ − }
+ −
+ − function approveComment(id)
+ − {
+ − var div = document.getElementById('comment_holder_'+id);
+ − var real_id = div.getElementsByTagName('input')[0]['value'];
+ − var req = {
+ − 'mode' : 'approve',
+ − 'id' : real_id,
+ − 'local_id' : id
+ − };
+ − ajaxComments(req);
+ − }
+ −
+ − // Does the actual DOM object removal
+ − function annihiliateComment(id) // Did I spell that right?
+ − {
+ − // Approved?
+ − var p = document.getElementById('comment_status');
+ −
+ − if(document.getElementById('comment_approve_'+id))
+ − {
+ − var appr = document.getElementById('comment_approve_'+id).firstChild.nodeValue;
+ − if ( p.firstChild.nextSibling && appr == 'Approve' )
+ − {
+ − var span = p.firstChild.nextSibling;
+ − var t = span.firstChild.nodeValue;
+ − var n_unapp = ( parseInt(t.split(' ')[0]) ) - 1;
+ − if ( n_unapp == 0 )
+ − p.removeChild(span);
+ − else
+ − span.firstChild.nodeValue = n_unapp + t.substr(t.indexOf(' '));
+ − }
+ − }
+ −
+ − var div = document.getElementById('comment_holder_'+id);
+ − div.parentNode.removeChild(div);
+ − var t = p.firstChild.nodeValue.split(' ');
+ − t[2] = ( parseInt(t[2]) - 1 ) + '';
+ − delete(t.toJSONString);
+ − if ( t[2] == '1' )
+ − {
+ − t[1] = 'is';
+ − t[3] = 'comment';
+ − }
+ − else
+ − {
+ − t[1] = 'are';
+ − t[3] = 'comments';
+ − }
+ − t = implode(' ', t);
+ − p.firstChild.nodeValue = t;
+ − }
+ −
+ − function materializeComment(data)
+ − {
+ − // Intelligently get an ID
+ −
+ − var i = 0;
+ − var brother;
+ − while ( true )
+ − {
+ − var x = document.getElementById('comment_holder_'+i);
+ − if(!x)
+ − break;
+ − brother = x;
+ − i++;
+ − }
+ −
+ − var parser = new templateParser(comment_template);
+ − var tplvars = new Object();
+ −
+ − if ( data.approved != '1' && !data.auth_mod_comments )
+ − return false;
+ −
+ − tplvars.ID = i;
+ − tplvars.DATETIME = data.time;
+ − tplvars.SUBJECT = data.subject;
+ − tplvars.DATA = data.comment_data;
+ − tplvars.SIGNATURE = data.signature;
+ −
+ − tplvars.NAME = data.name;
+ − if ( data.user_id > 1 )
+ − tplvars.NAME = '<a href="' + makeUrlNS('User', data.name) + '">' + data.name + '</a>';
+ −
+ − if ( data.approved != '1' )
+ − tplvars.SUBJECT += ' <span style="color: #D84308">(Unapproved)</span>';
+ −
+ − // User level
+ − tplvars.USER_LEVEL = 'Guest';
+ − if ( data.user_level >= data.user_level_list.member ) tplvars.USER_LEVEL = 'Member';
+ − if ( data.user_level >= data.user_level_list.mod ) tplvars.USER_LEVEL = 'Moderator';
+ − if ( data.user_level >= data.user_level_list.admin ) tplvars.USER_LEVEL = 'Administrator';
+ −
+ − // Send PM link
+ − tplvars.SEND_PM_LINK=(data.user_id>1)?'<a onclick="window.open(this.href); return false;" href="'+ makeUrlNS('Special', 'PrivateMessages/Compose/To/' + ( data.name.replace(/ /g, '_') )) +'">Send private message</a><br />':'';
+ −
+ − // Add buddy link
+ − tplvars.ADD_BUDDY_LINK=(data.user_id>1)?'<a onclick="window.open(this.href); return false;" href="'+ makeUrlNS('Special', 'PrivateMessages/FriendList/Add/' + ( data.name.replace(/ /g, '_') )) +'">Add to buddy list</a><br />':'';
+ −
+ − // Edit link
+ − tplvars.EDIT_LINK='<a href="#edit_'+i+'" onclick="editComment(\''+i+'\', this); return false;" id="cmteditlink_'+i+'">edit</a>';
+ −
+ − // Delete link
+ − tplvars.DELETE_LINK='<a href="#delete_'+i+'" onclick="deleteComment(\''+i+'\'); return false;">delete</a>';
+ −
+ − // Moderation: (Un)approve link
+ − var appr = ( data.approved == 1 ) ? 'Unapprove' : 'Approve';
+ − tplvars.MOD_APPROVE_LINK='<a href="#approve_'+i+'" id="comment_approve_'+i+'" onclick="approveComment(\''+i+'\'); return false;">'+appr+'</a>';
+ −
+ − // Moderation: Delete post link
+ − tplvars.MOD_DELETE_LINK='<a href="#mod_del_'+i+'" onclick="deleteComment(\''+i+'\'); return false;">Delete</a>';
+ −
+ − var tplbool = new Object();
+ −
+ − tplbool.signature = ( data.signature == '' ) ? false : true;
+ − tplbool.can_edit = ( data.auth_edit_comments && ( ( data.user_id == data.user_id && data.logged_in ) || data.auth_mod_comments ) );
+ − tplbool.auth_mod = data.auth_mod_comments;
+ −
+ − parser.assign_vars(tplvars);
+ − parser.assign_bool(tplbool);
+ −
+ − var div = document.createElement('div');
+ − div.id = 'comment_holder_'+i;
+ −
+ − div.innerHTML = '<input type="hidden" value="'+data.comment_id+'" /><input type="hidden" id="comment_source_'+i+'" />' + parser.run();
+ −
+ − if ( brother )
+ − {
+ − brother.parentNode.insertBefore(div, brother.nextSibling);
+ − }
+ − else
+ − {
+ − // No comments in ajaxEditContainer, insert it after the header
+ − var aec = document.getElementById("ajaxEditContainer");
+ − aec.insertBefore(div, aec.firstChild.nextSibling.nextSibling);
+ − }
+ −
+ − document.getElementById('comment_source_'+i).value = data.comment_source;
+ −
+ − var p = document.getElementById('comment_status');
+ − var t = p.firstChild.nodeValue.split(' ');
+ − var n = ( isNaN(parseInt(t[2])) ) ? 0 : parseInt(t[2]);
+ − t[2] = ( n + 1 ) + '';
+ − delete(t.toJSONString);
+ − if ( t[2] == '1' )
+ − {
+ − t[1] = 'is';
+ − t[3] = 'comment';
+ − }
+ − else
+ − {
+ − t[1] = 'are';
+ − t[3] = 'comments';
+ − }
+ − t = implode(' ', t);
+ − p.firstChild.nodeValue = t;
+ −
+ − if(document.getElementById('comment_approve_'+i))
+ − {
+ − var appr = document.getElementById('comment_approve_'+i).firstChild.nodeValue;
+ − if ( p.firstChild.nextSibling && appr == 'Approve' )
+ − {
+ − var span = p.firstChild.nextSibling;
+ − var t = span.firstChild.nodeValue;
+ − var n_unapp = ( parseInt(t.split(' ')[0]) ) - 1;
+ − if ( n_unapp == 0 )
+ − p.removeChild(span);
+ − else
+ − span.firstChild.nodeValue = n_unapp + t.substr(t.indexOf(' '));
+ − }
+ − else if ( appr == 'Approve' && !p.firstChild.nextSibling )
+ − {
+ − var span = document.createElement('span');
+ − p.innerHTML += ' ';
+ − span.innerHTML = '1 of those are unapproved.';
+ − span.style.color = '#D84308';
+ − var n_unapp = '1';
+ − p.appendChild(span);
+ − }
+ − }
+ −
+ − }
+ −
+ − function htmlspecialchars(text)
+ − {
+ − text = text.replace(/</g, '<');
+ − text = text.replace(/>/g, '>');
+ − return text;
+ − }
+ −
+ − // Equivalent to PHP trim() function
+ − function trim(text)
+ − {
+ − text = text.replace(/^([\s]+)/, '');
+ − text = text.replace(/([\s]+)$/, '');
+ − return text;
+ − }
+ −
+ − // Equivalent to PHP implode() function
+ − function implode(chr, arr)
+ − {
+ − if ( typeof ( arr.toJSONString ) == 'function' )
+ − delete(arr.toJSONString);
+ −
+ − var ret = '';
+ − var c = 0;
+ − for ( var i in arr )
+ − {
+ − if(i=='toJSONString')continue;
+ − if ( c > 0 )
+ − ret += chr;
+ − ret += arr[i];
+ − c++;
+ − }
+ − return ret;
+ − }
+ −
+ − function nl2br(text)
+ − {
+ − var regex = new RegExp(unescape('%0A'), 'g');
+ − return text.replace(regex, '<br />' + unescape('%0A'));
+ − }
+ −