/* Scripts for cnprog.com Project Name: Lanai All Rights Resevred 2008. CNPROG.COM */ var lanai = { /** * Finds any
tags which aren't registered for
* pretty printing, adds the appropriate class name and invokes prettify.
*/
highlightSyntax: function(){
var styled = false;
$("pre code").parent().each(function(){
if (!$(this).hasClass('prettyprint')){
$(this).addClass('prettyprint');
styled = true;
}
});
if (styled){
prettyPrint();
}
}
};
var Vote = function(){
// All actions are related to a question
var questionId;
//question slug to build redirect urls
var questionSlug;
// The object we operate on actually. It can be a question or an answer.
var postId;
var questionAuthorId;
var currentUserId;
var answerContainerIdPrefix = 'answer-container-';
var voteContainerId = 'vote-buttons';
var imgIdPrefixAccept = 'answer-img-accept-';
var imgClassPrefixFavorite = 'question-img-favorite';
var imgIdPrefixQuestionVoteup = 'question-img-upvote-';
var imgIdPrefixQuestionVotedown = 'question-img-downvote-';
var imgIdPrefixAnswerVoteup = 'answer-img-upvote-';
var imgIdPrefixAnswerVotedown = 'answer-img-downvote-';
var divIdFavorite = 'favorite-number';
var commentLinkIdPrefix = 'comment-';
var voteNumberClass = "vote-number";
var offensiveIdPrefixQuestionFlag = 'question-offensive-flag-';
var offensiveIdPrefixAnswerFlag = 'answer-offensive-flag-';
var offensiveClassFlag = 'offensive-flag';
var questionControlsId = 'question-controls';
var removeQuestionLinkIdPrefix = 'question-delete-link-';
var removeAnswerLinkIdPrefix = 'answer-delete-link-';
var questionSubscribeUpdates = 'question-subscribe-updates';
var acceptAnonymousMessage = $.i18n._('insufficient privilege');
var acceptOwnAnswerMessage = $.i18n._('cannot pick own answer as best');
var pleaseLogin = ""
+ $.i18n._('please login') + "";
var pleaseSeeFAQ = $.i18n._('please see') + "faq";
var favoriteAnonymousMessage = $.i18n._('anonymous users cannot select favorite questions')
var voteAnonymousMessage = $.i18n._('anonymous users cannot vote') + pleaseLogin;
var upVoteRequiredScoreMessage = $.i18n._('>15 points requried to upvote') + pleaseSeeFAQ;
var downVoteRequiredScoreMessage = $.i18n._('>100 points required to downvote') + pleaseSeeFAQ;
var voteOwnDeniedMessage = $.i18n._('cannot vote for own posts');
var voteRequiredMoreVotes = $.i18n._('daily vote cap exhausted') + pleaseSeeFAQ;
var voteDenyCancelMessage = $.i18n._('cannot revoke old vote') + pleaseSeeFAQ;
var offensiveConfirmation = $.i18n._('please confirm offensive');
var offensiveAnonymousMessage = $.i18n._('anonymous users cannot flag offensive posts') + pleaseLogin;
var offensiveTwiceMessage = $.i18n._('cannot flag message as offensive twice') + pleaseSeeFAQ;
var offensiveNoFlagsLeftMessage = $.i18n._('flag offensive cap exhausted') + pleaseSeeFAQ;
var offensiveNoPermissionMessage = $.i18n._('need >15 points to report spam') + pleaseSeeFAQ;
var removeConfirmation = $.i18n._('confirm delete');
var removeAnonymousMessage = $.i18n._('anonymous users cannot delete/undelete');
var recoveredMessage = $.i18n._('post recovered');
var deletedMessage = $.i18n._('post deleted');
var VoteType = {
acceptAnswer : 0,
questionUpVote : 1,
questionDownVote : 2,
favorite : 4,
answerUpVote: 5,
answerDownVote:6,
offensiveQuestion : 7,
offensiveAnswer:8,
removeQuestion: 9,
removeAnswer:10,
questionSubscribeUpdates:11,
questionUnsubscribeUpdates:12
};
var getFavoriteButton = function(){
var favoriteButton = 'div.'+ voteContainerId +' img[class='+ imgClassPrefixFavorite +']';
return $(favoriteButton);
};
var getFavoriteNumber = function(){
var favoriteNumber = '#'+ divIdFavorite ;
return $(favoriteNumber);
};
var getQuestionVoteUpButton = function(){
var questionVoteUpButton = 'div.'+ voteContainerId +' img[id^='+ imgIdPrefixQuestionVoteup +']';
return $(questionVoteUpButton);
};
var getQuestionVoteDownButton = function(){
var questionVoteDownButton = 'div.'+ voteContainerId +' img[id^='+ imgIdPrefixQuestionVotedown +']';
return $(questionVoteDownButton);
};
var getAnswerVoteUpButtons = function(){
var answerVoteUpButton = 'div.'+ voteContainerId +' img[id^='+ imgIdPrefixAnswerVoteup +']';
return $(answerVoteUpButton);
};
var getAnswerVoteDownButtons = function(){
var answerVoteDownButton = 'div.'+ voteContainerId +' img[id^='+ imgIdPrefixAnswerVotedown +']';
return $(answerVoteDownButton);
};
var getAnswerVoteUpButton = function(id){
var answerVoteUpButton = 'div.'+ voteContainerId +' img[id='+ imgIdPrefixAnswerVoteup + id + ']';
return $(answerVoteUpButton);
};
var getAnswerVoteDownButton = function(id){
var answerVoteDownButton = 'div.'+ voteContainerId +' img[id='+ imgIdPrefixAnswerVotedown + id + ']';
return $(answerVoteDownButton);
};
var getOffensiveQuestionFlag = function(){
var offensiveQuestionFlag = '#question-table span[class='+ offensiveClassFlag +']';
return $(offensiveQuestionFlag);
};
var getOffensiveAnswerFlags = function(){
var offensiveQuestionFlag = 'div.answer span[class='+ offensiveClassFlag +']';
return $(offensiveQuestionFlag);
};
var getremoveQuestionLink = function(){
var removeQuestionLink = 'div#question-controls a[id^='+ removeQuestionLinkIdPrefix +']';
return $(removeQuestionLink);
};
var getquestionSubscribeUpdatesCheckbox = function(){
return $('#' + questionSubscribeUpdates);
};
var getremoveAnswersLinks = function(){
var removeAnswerLinks = 'div.answer-controls a[id^='+ removeAnswerLinkIdPrefix +']';
return $(removeAnswerLinks);
};
var setVoteImage = function(voteType, undo, object){
var flag = undo ? "" : "-on";
var arrow = (voteType == VoteType.questionUpVote || voteType == VoteType.answerUpVote) ? "up" : "down";
object.attr("src", scriptUrl + "content/images/vote-arrow-"+ arrow + flag +".png");
// if undo voting, then undo the pair of arrows.
if(undo){
if(voteType == VoteType.questionUpVote || voteType == VoteType.questionDownVote){
$(getQuestionVoteUpButton()).attr("src", scriptUrl + "content/images/vote-arrow-up.png");
$(getQuestionVoteDownButton()).attr("src", scriptUrl + "content/images/vote-arrow-down.png");
}
else{
$(getAnswerVoteUpButton(postId)).attr("src", scriptUrl + "content/images/vote-arrow-up.png");
$(getAnswerVoteDownButton(postId)).attr("src", scriptUrl + "content/images/vote-arrow-down.png");
}
}
};
var setVoteNumber = function(object, number){
var voteNumber = object.parent('div.'+ voteContainerId).find('div.'+ voteNumberClass);
$(voteNumber).text(number);
};
var bindEvents = function(){
// accept answers
if(questionAuthorId == currentUserId){
var acceptedButtons = 'div.'+ voteContainerId +' img[id^='+ imgIdPrefixAccept +']';
$(acceptedButtons).unbind('click').click(function(event){
Vote.accept($(event.target));
});
}
// set favorite question
var favoriteButton = getFavoriteButton();
favoriteButton.unbind('click').click(function(event){
Vote.favorite($(event.target));
});
// question vote up
var questionVoteUpButton = getQuestionVoteUpButton();
questionVoteUpButton.unbind('click').click(function(event){
Vote.vote($(event.target), VoteType.questionUpVote);
});
var questionVoteDownButton = getQuestionVoteDownButton();
questionVoteDownButton.unbind('click').click(function(event){
Vote.vote($(event.target), VoteType.questionDownVote);
});
var answerVoteUpButton = getAnswerVoteUpButtons();
answerVoteUpButton.unbind('click').click(function(event){
Vote.vote($(event.target), VoteType.answerUpVote);
});
var answerVoteDownButton = getAnswerVoteDownButtons();
answerVoteDownButton.unbind('click').click(function(event){
Vote.vote($(event.target), VoteType.answerDownVote);
});
getOffensiveQuestionFlag().unbind('click').click(function(event){
Vote.offensive(this, VoteType.offensiveQuestion);
});
getOffensiveAnswerFlags().unbind('click').click(function(event){
Vote.offensive(this, VoteType.offensiveAnswer);
});
getremoveQuestionLink().unbind('click').click(function(event){
Vote.remove(this, VoteType.removeQuestion);
});
getquestionSubscribeUpdatesCheckbox().unbind('click').click(function(event){
if (this.checked){
Vote.vote($(event.target), VoteType.questionSubscribeUpdates);
}
else {
Vote.vote($(event.target), VoteType.questionUnsubscribeUpdates);
}
});
getremoveAnswersLinks().unbind('click').click(function(event){
Vote.remove(this, VoteType.removeAnswer);
});
};
var submit = function(object, voteType, callback) {
$.ajax({
type: "POST",
cache: false,
dataType: "json",
url: scriptUrl + $.i18n._("questions/") + questionId + "/" + $.i18n._("vote/"),
data: { "type": voteType, "postId": postId },
error: handleFail,
success: function(data){callback(object, voteType, data)}});
};
var handleFail = function(xhr, msg){
alert("Callback invoke error: " + msg);
};
// callback function for Accept Answer action
var callback_accept = function(object, voteType, data){
if(data.allowed == "0" && data.success == "0"){
showMessage(object, acceptAnonymousMessage);
}
else if(data.allowed == "-1"){
showMessage(object, acceptOwnAnswerMessage);
}
else if(data.status == "1"){
object.attr("src", scriptUrl + "content/images/vote-accepted.png");
$("#"+answerContainerIdPrefix+postId).removeClass("accepted-answer");
$("#"+commentLinkIdPrefix+postId).removeClass("comment-link-accepted");
}
else if(data.success == "1"){
var acceptedButtons = 'div.'+ voteContainerId +' img[id^='+ imgIdPrefixAccept +']';
$(acceptedButtons).attr("src", scriptUrl + "content/images/vote-accepted.png");
var answers = ("div[id^="+answerContainerIdPrefix +"]");
$(answers).removeClass("accepted-answer");
var commentLinks = ("div[id^="+answerContainerIdPrefix +"] div[id^="+ commentLinkIdPrefix +"]");
$(commentLinks).removeClass("comment-link-accepted");
object.attr("src", scriptUrl + "content/images/vote-accepted-on.png");
$("#"+answerContainerIdPrefix+postId).addClass("accepted-answer");
$("#"+commentLinkIdPrefix+postId).addClass("comment-link-accepted");
}
else{
showMessage(object, data.message);
}
};
var callback_favorite = function(object, voteType, data){
if(data.allowed == "0" && data.success == "0"){
showMessage(object, favoriteAnonymousMessage.replace("{{QuestionID}}", questionId));
}
else if(data.status == "1"){
object.attr("src", scriptUrl + "content/images/vote-favorite-off.png");
var fav = getFavoriteNumber();
fav.removeClass("my-favorite-number");
if(data.count == 0)
data.count = '';
fav.text(data.count);
}
else if(data.success == "1"){
object.attr("src", scriptUrl + "content/images/vote-favorite-on.png");
var fav = getFavoriteNumber();
fav.text(data.count);
fav.addClass("my-favorite-number");
}
else{
showMessage(object, data.message);
}
};
var callback_vote = function(object, voteType, data){
if(data.allowed == "0" && data.success == "0"){
showMessage(object, voteAnonymousMessage.replace("{{QuestionID}}", questionId));
}
else if (data.allowed == "-3"){
showMessage(object, voteRequiredMoreVotes);
}
else if (data.allowed == "-2"){
if (voteType == VoteType.questionUpVote || voteType == VoteType.answerUpVote){
showMessage(object, upVoteRequiredScoreMessage);
}
else if (voteType == VoteType.questionDownVote || voteType == VoteType.answerDownVote){
showMessage(object, downVoteRequiredScoreMessage);
}
}
else if (data.allowed == "-1"){
showMessage(object, voteOwnDeniedMessage);
}
else if (data.status == "2"){
showMessage(object, voteDenyCancelMessage);
}
else if (data.status == "1"){
setVoteImage(voteType, true, object);
setVoteNumber(object, data.count);
}
else if (data.success == "1"){
setVoteImage(voteType, false, object);
setVoteNumber(object, data.count);
if (data.message.length > 0){
showMessage(object, data.message);
}
}
};
var callback_offensive = function(object, voteType, data){
object = $(object);
if (data.allowed == "0" && data.success == "0"){
showMessage(object, offensiveAnonymousMessage.replace("{{QuestionID}}", questionId));
}
else if (data.allowed == "-3"){
showMessage(object, offensiveNoFlagsLeftMessage);
}
else if (data.allowed == "-2"){
showMessage(object, offensiveNoPermissionMessage);
}
else if (data.status == "1"){
showMessage(object, offensiveTwiceMessage);
}
else if (data.success == "1"){
$(object).children('span[class=darkred]').text("("+ data.count +")");
}
};
var callback_remove = function(object, voteType, data){
if (data.allowed == "0" && data.success == "0"){
showMessage(object, removeAnonymousMessage.replace("{{QuestionID}}", questionId));
}
else if (data.success == "1"){
if (voteType == VoteType.removeQuestion){
window.location.href = scriptUrl + $.i18n._("questions/");
}
else {
if (removeActionType == 'delete'){
postNode.addClass('deleted');
postRemoveLink.innerHTML = $.i18n._('undelete');
showMessage(object, deletedMessage);
}
else if (removeActionType == 'undelete') {
postNode.removeClass('deleted');
postRemoveLink.innerHTML = $.i18n._('delete');
showMessage(object, recoveredMessage);
}
}
}
};
return {
init : function(qId, qSlug, questionAuthor, userId){
questionId = qId;
questionSlug = qSlug;
questionAuthorId = questionAuthor;
currentUserId = userId;
bindEvents();
},
// Accept answer public function
accept: function(object){
postId = object.attr("id").substring(imgIdPrefixAccept.length);
submit(object, VoteType.acceptAnswer, callback_accept);
},
favorite: function(object){
if (!currentUserId || currentUserId.toUpperCase() == "NONE"){
showMessage(object, favoriteAnonymousMessage.replace("{{QuestionID}}", questionId));
return false;
}
submit(object, VoteType.favorite, callback_favorite);
},
vote: function(object, voteType){
if (!currentUserId || currentUserId.toUpperCase() == "NONE"){
showMessage(object, voteAnonymousMessage.replace("{{QuestionID}}", questionId).replace("{{questionSlug}}", questionSlug));
return false;
}
if (voteType == VoteType.answerUpVote){
postId = object.attr("id").substring(imgIdPrefixAnswerVoteup.length);
}
else if (voteType == VoteType.answerDownVote){
postId = object.attr("id").substring(imgIdPrefixAnswerVotedown.length);
}
submit(object, voteType, callback_vote);
},
offensive: function(object, voteType){
if (!currentUserId || currentUserId.toUpperCase() == "NONE"){
showMessage($(object), offensiveAnonymousMessage.replace("{{QuestionID}}", questionId));
return false;
}
if (confirm(offensiveConfirmation)){
postId = object.id.substr(object.id.lastIndexOf('-') + 1);
submit(object, voteType, callback_offensive);
}
},
remove: function(object, voteType){
if (!currentUserId || currentUserId.toUpperCase() == "NONE"){
showMessage($(object), removeAnonymousMessage.replace("{{QuestionID}}", questionId));
return false;
}
bits = object.id.split('-');
postId = bits.pop();/* this seems to be used within submit! */
postType = bits.shift();
var do_proceed = false;
if (postType == 'answer'){
postNode = $('#answer-container-' + postId);
postRemoveLink = object;
if (postNode.hasClass('deleted')){
removeActionType = 'undelete';
do_proceed = true;
}
else {
removeActionType = 'delete';
do_proceed = confirm(removeConfirmation);
}
}
else {
do_proceed = confirm(removeConfirmation);
}
if (do_proceed) {
submit($(object), voteType, callback_remove);
}
}
}
} ();
// site comments
function createComments(type) {
var objectType = type;
var jDivInit = function(id) {
return $("#comments-container-" + objectType + '-' + id);
};
var appendLoaderImg = function(id) {
appendLoader("#comments-container-" + objectType + '-' + id);
};
var canPostComments = function(id) {
var jHidden = $("#can-post-comments-" + objectType + '-' + id);
return jHidden.val().toLowerCase() == "true";
};
var renderForm = function(id) {
var formId = "form-comments-" + objectType + "-" + id;
var jDiv = $('#comments-link-' + objectType + "-" + id).parent();
$(jDiv).css('background','none');
$(jDiv).css('padding-left',0);
if (canPostComments(id)) {
if (jDiv.find("#" + formId).length == 0) {
var form = '';
jDiv.append(form);
setupFormValidation("#" + formId,
{ comment: { required: true, minlength: 10} }, '',
function() { postComment(id, formId); });
}
}
else {
var divId = "comments-rep-needed-" + objectType + '-' + id;
if (jDiv.find("#" + divId).length == 0) {
jDiv.append('' + $.i18n._('to comment, need') + ' ' + + repNeededForComments + ' ' + $.i18n._('community karma points') + '' + $.i18n._('please see') + 'faq
'); } } }; var getComments = function(id, jDiv) { //appendLoaderImg(id); $.getJSON(scriptUrl + objectType + "s/" + id + "/" + $.i18n._("comments/") , function(json) { showComments(id, json); }); }; var showComments = function(id, json) { var jDiv = jDivInit(id); //jDiv = jDiv.find("div.comments"); // this div should contain any fetched comments.. //jDiv.find("div[id^='comment-" + objectType + "-'" + "]").remove(); // clean previous calls.. jDiv.children().remove(); removeLoader(); if (json && json.length > 0) { for (var i = 0; i < json.length; i++) renderComment(jDiv, json[i]); jDiv.children().show(); } }; var renderDeleteCommentIcon = function(post_id, delete_url){ if (canPostComments(post_id)){ var html = ''; var img = scriptUrl + "content/images/close-small.png"; var imgHover = scriptUrl + "content/images/close-small-hover.png"; html += ''; return html; } else{ return ''; } } // {"Id":6,"PostId":38589,"CreationDate":"an hour ago","Text":"hello there!","UserDisplayName":"Jarrod Dixon","UserUrl":"/users/3/jarrod-dixon","DeleteUrl":null} var renderComment = function(jDiv, json) { var html = ' '; jDiv.append(html); }; var postComment = function(id, formId) { //appendLoaderImg(id); var formSelector = "#" + formId; var textarea = $(formSelector + " textarea"); //todo fix url translations!!! $.ajax({ type: "POST", url: scriptUrl + objectType + "s/" + id + "/" + $.i18n._("comments/"), dataType: "json", data: { comment: textarea.val() }, success: function(json) { showComments(id, json); textarea.val(""); commentsFactory[objectType].updateTextCounter(textarea); enableSubmitButton(formSelector); }, error: function(res, textStatus, errorThrown) { removeLoader(); showMessage(formSelector, res.responseText); enableSubmitButton(formSelector); } }); }; // public methods.. return { init: function() { // Setup "show comments" clicks.. $("a[id^='comments-link-" + objectType + "-" + "']").unbind("click").click(function() { commentsFactory[objectType].show($(this).attr("id").substr(("comments-link-" + objectType + "-").length)); }); var cBox = $("[id^='comments-container-" + objectType + "']"); cBox.each( function(i){ var post_id = $(this).attr('id').replace('comments-container-' + objectType + '-', ''); $(this).children().each( function(i){ var comment_id = $(this).attr('id').replace('comment-',''); var delete_url = scriptUrl + objectType + 's/' + post_id + '/' + $.i18n._('comments/') + comment_id + '/' + $.i18n._('delete/'); var html = $(this).html(); var CommentsClass; if (objectType == 'question'){ CommentsClass = questionComments; } else if (objectType == 'answer') { CommentsClass = answerComments; } var delete_icon = $(this).find('img.delete-icon'); delete_icon.click(function(){CommentsClass.deleteComment($(this),comment_id,delete_url);}); delete_icon.unbind('mouseover').bind('mouseover', function(){ $(this).attr('src',scriptUrl + 'content/images/close-small-hover.png'); } ); delete_icon.unbind('mouseout').bind('mouseout', function(){ $(this).attr('src',scriptUrl + 'content/images/close-small.png'); } ); } ); }); }, show: function(id) { var jDiv = jDivInit(id); getComments(id, jDiv); renderForm(id); jDiv.show(); var link = $('#comments-link-' + objectType + '-' + id); if (canPostComments(id)) link.parent().find("textarea").get(0).focus(); link.remove(); }, hide: function(id) { var jDiv = jDivInit(id); var len = jDiv.children("div.comments").children().length; var anchorText = len == 0 ? $.i18n._('add a comment') : $.i18n._('comments') + ' (' + len + ")"; jDiv.hide(); jDiv.siblings("a").unbind("click").click(function() { commentsFactory[objectType].show(id); }).html(anchorText); jDiv.children("div.comments").children().hide(); }, deleteComment: function(jImg, id, deleteUrl) { if (confirm($.i18n._('confirm delete comment'))) { jImg.hide(); $.post(deleteUrl, { dataNeeded: "forIIS7" }, function(json) { var par = jImg.parent(); par.remove(); }, "json"); } }, updateTextCounter: function(textarea) { var length = textarea.value ? textarea.value.length : 0; var color = length > 270 ? "#f00" : length > 200 ? "#f60" : "#999"; var jSpan = $(textarea).siblings("span.text-counter"); jSpan.html($.i18n._('can write') + (300 - length) + ' ' + $.i18n._('characters')).css("color", color); } }; } var questionComments = createComments('question'); var answerComments = createComments('answer'); $().ready(function() { questionComments.init(); answerComments.init(); }); var commentsFactory = {'question' : questionComments, 'answer' : answerComments}; /* Prettify http://www.apache.org/licenses/LICENSE-2.0 */ var PR_SHOULD_USE_CONTINUATION = true; var PR_TAB_WIDTH = 8; var PR_normalizedHtml; var PR; var prettyPrintOne; var prettyPrint; function _pr_isIE6() { var isIE6 = navigator && navigator.userAgent && /\bMSIE 6\./.test(navigator.userAgent); _pr_isIE6 = function() { return isIE6; }; return isIE6; } (function() { function wordSet(words) { words = words.split(/ /g); var set = {}; for (var i = words.length; --i >= 0; ) { var w = words[i]; if (w) { set[w] = null; } } return set; } var FLOW_CONTROL_KEYWORDS = "break continue do else for if return while "; var C_KEYWORDS = FLOW_CONTROL_KEYWORDS + "auto case char const default " + "double enum extern float goto int long register short signed sizeof " + "static struct switch typedef union unsigned void volatile "; var COMMON_KEYWORDS = C_KEYWORDS + "catch class delete false import " + "new operator private protected public this throw true try "; var CPP_KEYWORDS = COMMON_KEYWORDS + "alignof align_union asm axiom bool " + "concept concept_map const_cast constexpr decltype " + "dynamic_cast explicit export friend inline late_check " + "mutable namespace nullptr reinterpret_cast static_assert static_cast " + "template typeid typename typeof using virtual wchar_t where "; var JAVA_KEYWORDS = COMMON_KEYWORDS + "boolean byte extends final finally implements import instanceof null " + "native package strictfp super synchronized throws transient "; var CSHARP_KEYWORDS = JAVA_KEYWORDS + "as base by checked decimal delegate descending event " + "fixed foreach from group implicit in interface internal into is lock " + "object out override orderby params readonly ref sbyte sealed " + "stackalloc string select uint ulong unchecked unsafe ushort var "; var JSCRIPT_KEYWORDS = COMMON_KEYWORDS + "debugger eval export function get null set undefined var with " + "Infinity NaN "; var PERL_KEYWORDS = "caller delete die do dump elsif eval exit foreach for " + "goto if import last local my next no our print package redo require " + "sub undef unless until use wantarray while BEGIN END "; var PYTHON_KEYWORDS = FLOW_CONTROL_KEYWORDS + "and as assert class def del " + "elif except exec finally from global import in is lambda " + "nonlocal not or pass print raise try with yield " + "False True None "; var RUBY_KEYWORDS = FLOW_CONTROL_KEYWORDS + "alias and begin case class def" + " defined elsif end ensure false in module next nil not or redo rescue " + "retry self super then true undef unless until when yield BEGIN END "; var SH_KEYWORDS = FLOW_CONTROL_KEYWORDS + "case done elif esac eval fi " + "function in local set then until "; var ALL_KEYWORDS = (CPP_KEYWORDS + CSHARP_KEYWORDS + JSCRIPT_KEYWORDS + PERL_KEYWORDS + PYTHON_KEYWORDS + RUBY_KEYWORDS + SH_KEYWORDS); var PR_STRING = 'str'; var PR_KEYWORD = 'kwd'; var PR_COMMENT = 'com'; var PR_TYPE = 'typ'; var PR_LITERAL = 'lit'; var PR_PUNCTUATION = 'pun'; var PR_PLAIN = 'pln'; var PR_TAG = 'tag'; var PR_DECLARATION = 'dec'; var PR_SOURCE = 'src'; var PR_ATTRIB_NAME = 'atn'; var PR_ATTRIB_VALUE = 'atv'; var PR_NOCODE = 'nocode'; function isWordChar(ch) { return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); } function spliceArrayInto(inserted, container, containerPosition, countReplaced) { inserted.unshift(containerPosition, countReplaced || 0); try { container.splice.apply(container, inserted); } finally { inserted.splice(0, 2); } } var REGEXP_PRECEDER_PATTERN = function() { var preceders = ["!", "!=", "!==", "#", "%", "%=", "&", "&&", "&&=", "&=", "(", "*", "*=", "+=", ",", "-=", "->", "/", "/=", ":", "::", ";", "<", "<<", "<<=", "<=", "=", "==", "===", ">", ">=", ">>", ">>=", ">>>", ">>>=", "?", "@", "[", "^", "^=", "^^", "^^=", "{", "|", "|=", "||", "||=", "~", "break", "case", "continue", "delete", "do", "else", "finally", "instanceof", "return", "throw", "try", "typeof"]; var pattern = '(?:' + '(?:(?:^|[^0-9.])\\.{1,3})|' + '(?:(?:^|[^\\+])\\+)|' + '(?:(?:^|[^\\-])-)'; for (var i = 0; i < preceders.length; ++i) { var preceder = preceders[i]; if (isWordChar(preceder.charAt(0))) { pattern += '|\\b' + preceder; } else { pattern += '|' + preceder.replace(/([^=<>:&])/g, '\\$1'); } } pattern += '|^)\\s*$'; return new RegExp(pattern); } (); var pr_amp = /&/g; var pr_lt = //g; var pr_quot = /\"/g; function attribToHtml(str) { return str.replace(pr_amp, '&').replace(pr_lt, '<').replace(pr_gt, '>').replace(pr_quot, '"'); } function textToHtml(str) { return str.replace(pr_amp, '&').replace(pr_lt, '<').replace(pr_gt, '>'); } var pr_ltEnt = /</g; var pr_gtEnt = />/g; var pr_aposEnt = /'/g; var pr_quotEnt = /"/g; var pr_ampEnt = /&/g; var pr_nbspEnt = / /g; function htmlToText(html) { var pos = html.indexOf('&'); if (pos < 0) { return html; } for (--pos; (pos = html.indexOf('', pos + 1)) >= 0; ) { var end = html.indexOf(';', pos); if (end >= 0) { var num = html.substring(pos + 3, end); var radix = 10; if (num && num.charAt(0) === 'x') { num = num.substring(1); radix = 16; } var codePoint = parseInt(num, radix); if (!isNaN(codePoint)) { html = (html.substring(0, pos) + String.fromCharCode(codePoint) + html.substring(end + 1)); } } } return html.replace(pr_ltEnt, '<').replace(pr_gtEnt, '>').replace(pr_aposEnt, "'").replace(pr_quotEnt, '"').replace(pr_ampEnt, '&').replace(pr_nbspEnt, ' '); } function isRawContent(node) { return 'XMP' === node.tagName; } function normalizedHtml(node, out) { switch (node.nodeType) { case 1: var name = node.tagName.toLowerCase(); out.push('<', name); for (var i = 0; i < node.attributes.length; ++i) { var attr = node.attributes[i]; if (!attr.specified) { continue; } out.push(' '); normalizedHtml(attr, out); } out.push('>'); for (var child = node.firstChild; child; child = child.nextSibling) { normalizedHtml(child, out); } if (node.firstChild || !/^(?:br|link|img)$/.test(name)) { out.push('<\/', name, '>'); } break; case 2: out.push(node.name.toLowerCase(), '="', attribToHtml(node.value), '"'); break; case 3: case 4: out.push(textToHtml(node.nodeValue)); break; } } var PR_innerHtmlWorks = null; function getInnerHtml(node) { if (null === PR_innerHtmlWorks) { var testNode = document.createElement('PRE'); testNode.appendChild(document.createTextNode('\n