PageRenderTime 61ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/BlogEngine/BlogEngine.NET/Scripts/blog.js

#
JavaScript | 613 lines | 507 code | 71 blank | 35 comment | 123 complexity | f417147fe16bddab272866e71c014a95 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0, BSD-3-Clause
  1. // global object
  2. BlogEngine = {
  3. $: function (id) {
  4. return document.getElementById(id);
  5. }
  6. ,
  7. webRoot: '',
  8. applicationWebRoot: '',
  9. blogInstanceId: '',
  10. // internationalization (injected into the <head> by BlogBasePage)
  11. i18n: {
  12. hasRated: '',
  13. savingTheComment: '',
  14. comments: '',
  15. commentWasSaved: '',
  16. commentWaitingModeration: '',
  17. cancel: '',
  18. filter: '',
  19. apmlDescription: '',
  20. beTheFirstToRate: '',
  21. currentlyRated: '',
  22. ratingHasBeenRegistered: '',
  23. rateThisXStars: ''
  24. }
  25. ,
  26. setFlag: function (iso) {
  27. if (iso.length > 0)
  28. BlogEngine.comments.flagImage.src = BlogEngine.webRoot + "pics/flags/" + iso + ".png";
  29. else
  30. BlogEngine.comments.flagImage.src = BlogEngine.webRoot + "pics/pixel.gif";
  31. }
  32. ,
  33. // Shows the preview of the comment
  34. showCommentPreview: function () {
  35. var oPreview = this.$('preview');
  36. var oCompose = this.$('compose');
  37. if (oPreview) oPreview.className = 'selected';
  38. if (oCompose) oCompose.className = '';
  39. this.$('commentCompose').style.display = 'none';
  40. this.$('commentPreview').style.display = 'block';
  41. this.$('commentPreview').innerHTML = '<img src="' + BlogEngine.webRoot + 'pics/ajax-loader.gif" alt="Loading" />';
  42. var argument = this.$('commentPreview').innerHTML;
  43. this.addComment(true);
  44. }
  45. ,
  46. composeComment: function () {
  47. var oPreview = this.$('preview');
  48. var oCompose = this.$('compose');
  49. if (oPreview) oPreview.className = '';
  50. if (oCompose) oCompose.className = 'selected';
  51. this.$('commentPreview').style.display = 'none';
  52. this.$('commentCompose').style.display = 'block';
  53. }
  54. ,
  55. endShowPreview: function (arg, context) {
  56. BlogEngine.$('commentPreview').innerHTML = arg;
  57. }
  58. ,
  59. toggleCommentSavingIndicators: function (bSaving) {
  60. BlogEngine.$("btnSaveAjax").disabled = bSaving;
  61. BlogEngine.$("ajaxLoader").style.display = bSaving ? "inline" : "none";
  62. BlogEngine.$("status").className = "";
  63. BlogEngine.$("status").innerHTML = "";
  64. if (!bSaving) {
  65. BlogEngine.$('commentPreview').innerHTML = "";
  66. BlogEngine.composeComment();
  67. }
  68. }
  69. ,
  70. onCommentError: function (error, context) {
  71. BlogEngine.toggleCommentSavingIndicators(false);
  72. error = error || "Unknown error occurred.";
  73. var iDelimiterPos = error.indexOf("|");
  74. if (iDelimiterPos > 0) {
  75. error = error.substr(0, iDelimiterPos);
  76. // Remove numbers from end of error message.
  77. while (error.length > 0 && error.substr(error.length - 1, 1).match(/\d/)) {
  78. error = error.substr(0, error.length - 1);
  79. }
  80. }
  81. if (document.getElementById('recaptcha_response_field')) {
  82. Recaptcha.reload();
  83. }
  84. if (document.getElementById("spnSimpleCaptchaIncorrect")) document.getElementById("spnSimpleCaptchaIncorrect").style.display = "none";
  85. alert("Sorry, the following error occurred while processing your comment:\n\n" + error);
  86. }
  87. ,
  88. addComment: function (preview) {
  89. var isPreview = preview == true;
  90. if (!isPreview) {
  91. BlogEngine.toggleCommentSavingIndicators(true);
  92. this.$("status").innerHTML = BlogEngine.i18n.savingTheComment;
  93. }
  94. var author = BlogEngine.comments.nameBox.value;
  95. var email = BlogEngine.comments.emailBox.value;
  96. var content = BlogEngine.comments.contentBox.value;
  97. var captcha = BlogEngine.comments.captchaField.value;
  98. var website = BlogEngine.comments.websiteBox ? BlogEngine.comments.websiteBox.value : "";
  99. var country = BlogEngine.comments.countryDropDown ? BlogEngine.comments.countryDropDown.value : "";
  100. var notify = BlogEngine.$("cbNotify") ? BlogEngine.$("cbNotify").checked : false;
  101. var replyToId = BlogEngine.comments.replyToId ? BlogEngine.comments.replyToId.value : "";
  102. var recaptchaResponseField = document.getElementById('recaptcha_response_field');
  103. var recaptchaResponse = recaptchaResponseField ? recaptchaResponseField.value : "";
  104. var recaptchaChallengeField = document.getElementById('recaptcha_challenge_field');
  105. var recaptchaChallenge = recaptchaChallengeField ? recaptchaChallengeField.value : "";
  106. var simpleCaptchaChallengeField = document.getElementById('simpleCaptchaValue');
  107. var simpleCaptchaChallenge = simpleCaptchaChallengeField ? simpleCaptchaChallengeField.value : "";
  108. var avatarInput = BlogEngine.$("avatarImgSrc");
  109. var avatar = (avatarInput && avatarInput.value) ? avatarInput.value : "";
  110. var callback = isPreview ? BlogEngine.endShowPreview : BlogEngine.appendComment;
  111. var argument = author + "-|-" + email + "-|-" + website + "-|-" + country + "-|-" + content + "-|-" + notify + "-|-" + isPreview + "-|-" + captcha + "-|-" + replyToId + "-|-" + avatar + "-|-" + recaptchaResponse + "-|-" + recaptchaChallenge + "-|-" + simpleCaptchaChallenge;
  112. WebForm_DoCallback(BlogEngine.comments.controlId, argument, callback, 'comment', BlogEngine.onCommentError, false);
  113. if (!isPreview && typeof (OnComment) != "undefined")
  114. OnComment(author, email, website, country, content);
  115. }
  116. ,
  117. cancelReply: function () {
  118. this.replyToComment('');
  119. }
  120. ,
  121. replyToComment: function (id) {
  122. // set hidden value
  123. BlogEngine.comments.replyToId.value = id;
  124. // move comment form into position
  125. var commentForm = BlogEngine.$('comment-form');
  126. if (!id || id == '' || id == null || id == '00000000-0000-0000-0000-000000000000') {
  127. // move to after comment list
  128. var base = BlogEngine.$("commentlist");
  129. base.appendChild(commentForm);
  130. // hide cancel button
  131. BlogEngine.$('cancelReply').style.display = 'none';
  132. } else {
  133. // show cancel
  134. BlogEngine.$('cancelReply').style.display = '';
  135. // move to nested position
  136. var parentComment = BlogEngine.$('id_' + id);
  137. var replies = BlogEngine.$('replies_' + id);
  138. // add if necessary
  139. if (replies == null) {
  140. replies = document.createElement('div');
  141. replies.className = 'comment-replies';
  142. replies.id = 'replies_' + id;
  143. parentComment.appendChild(replies);
  144. }
  145. replies.style.display = '';
  146. replies.appendChild(commentForm);
  147. }
  148. BlogEngine.comments.nameBox.focus();
  149. }
  150. ,
  151. appendComment: function (args, context) {
  152. if (context == "comment") {
  153. if (document.getElementById('recaptcha_response_field')) {
  154. Recaptcha.reload();
  155. }
  156. if (document.getElementById("spnSimpleCaptchaIncorrect")) document.getElementById("spnSimpleCaptchaIncorrect").style.display = "none";
  157. if (args == "RecaptchaIncorrect" || args == "SimpleCaptchaIncorrect") {
  158. if (document.getElementById("spnCaptchaIncorrect")) document.getElementById("spnCaptchaIncorrect").style.display = "";
  159. if (document.getElementById("spnSimpleCaptchaIncorrect")) document.getElementById("spnSimpleCaptchaIncorrect").style.display = "";
  160. BlogEngine.toggleCommentSavingIndicators(false);
  161. }
  162. else {
  163. if (document.getElementById("spnCaptchaIncorrect")) document.getElementById("spnCaptchaIncorrect").style.display = "none";
  164. if (document.getElementById("spnSimpleCaptchaIncorrect")) document.getElementById("spnSimpleCaptchaIncorrect").style.display = "none";
  165. var commentList = BlogEngine.$("commentlist");
  166. if (commentList.innerHTML.length < 10)
  167. commentList.innerHTML = "<h1 id='comment'>" + BlogEngine.i18n.comments + "</h1>"
  168. // add comment html to the right place
  169. var id = BlogEngine.comments.replyToId ? BlogEngine.comments.replyToId.value : '';
  170. if (id != '') {
  171. var replies = BlogEngine.$('replies_' + id);
  172. replies.innerHTML += args;
  173. } else {
  174. commentList.innerHTML += args;
  175. commentList.style.display = 'block';
  176. }
  177. // reset form values
  178. BlogEngine.comments.contentBox.value = "";
  179. BlogEngine.comments.contentBox = BlogEngine.$(BlogEngine.comments.contentBox.id);
  180. BlogEngine.toggleCommentSavingIndicators(false);
  181. BlogEngine.$("status").className = "success";
  182. if (!BlogEngine.comments.moderation)
  183. BlogEngine.$("status").innerHTML = BlogEngine.i18n.commentWasSaved;
  184. else
  185. BlogEngine.$("status").innerHTML = BlogEngine.i18n.commentWaitingModeration;
  186. // move form back to bottom
  187. var commentForm = BlogEngine.$('comment-form');
  188. commentList.appendChild(commentForm);
  189. // reset reply to
  190. if (BlogEngine.comments.replyToId) BlogEngine.comments.replyToId.value = '';
  191. if (BlogEngine.$('cancelReply')) BlogEngine.$('cancelReply').style.display = 'none';
  192. }
  193. }
  194. BlogEngine.$("btnSaveAjax").disabled = false;
  195. }
  196. ,
  197. validateAndSubmitCommentForm: function () {
  198. var bBuiltInValidationPasses = Page_ClientValidate('AddComment');
  199. var bNameIsValid = BlogEngine.comments.nameBox.value.length > 0;
  200. document.getElementById('spnNameRequired').style.display = bNameIsValid ? 'none' : '';
  201. var bAuthorNameIsValid = true;
  202. if (BlogEngine.comments.checkName) {
  203. var author = BlogEngine.comments.postAuthor;
  204. var visitor = BlogEngine.comments.nameBox.value;
  205. bAuthorNameIsValid = !this.equal(author, visitor);
  206. }
  207. document.getElementById('spnChooseOtherName').style.display = bAuthorNameIsValid ? 'none' : '';
  208. if (bBuiltInValidationPasses && bNameIsValid && bAuthorNameIsValid) {
  209. BlogEngine.addComment();
  210. return true;
  211. }
  212. return false;
  213. }
  214. ,
  215. addBbCode: function (v) {
  216. try {
  217. var contentBox = BlogEngine.comments.contentBox;
  218. if (contentBox.selectionStart) // firefox
  219. {
  220. var pretxt = contentBox.value.substring(0, contentBox.selectionStart);
  221. var therest = contentBox.value.substr(contentBox.selectionEnd);
  222. var sel = contentBox.value.substring(contentBox.selectionStart, contentBox.selectionEnd);
  223. contentBox.value = pretxt + "[" + v + "]" + sel + "[/" + v + "]" + therest;
  224. contentBox.focus();
  225. }
  226. else if (document.selection && document.selection.createRange) // IE
  227. {
  228. var str = document.selection.createRange().text;
  229. contentBox.focus();
  230. var sel = document.selection.createRange();
  231. sel.text = "[" + v + "]" + str + "[/" + v + "]";
  232. }
  233. }
  234. catch (ex) { }
  235. return;
  236. }
  237. ,
  238. // Searches the blog based on the entered text and
  239. // searches comments as well if chosen.
  240. search: function (root) {
  241. var input = this.$("searchfield");
  242. var check = this.$("searchcomments");
  243. var search = "search.aspx?q=" + encodeURIComponent(input.value);
  244. if (check != null && check.checked)
  245. search += "&comment=true";
  246. top.location.href = root + search;
  247. return false;
  248. }
  249. ,
  250. // Clears the search fields on focus.
  251. searchClear: function (defaultText) {
  252. var input = this.$("searchfield");
  253. if (input.value == defaultText)
  254. input.value = "";
  255. else if (input.value == "")
  256. input.value = defaultText;
  257. }
  258. ,
  259. rate: function (id, rating) {
  260. this.createCallback("rating.axd?id=" + id + "&rating=" + rating, BlogEngine.ratingCallback);
  261. }
  262. ,
  263. ratingCallback: function (response) {
  264. var rating = response.substring(0, 1);
  265. var status = response.substring(1);
  266. if (status == "OK") {
  267. if (typeof OnRating != "undefined")
  268. OnRating(rating);
  269. alert(BlogEngine.i18n.ratingHasBeenRegistered);
  270. }
  271. else if (status == "HASRATED") {
  272. alert(BlogEngine.i18n.hasRated);
  273. }
  274. else {
  275. alert("An error occured while registering your rating. Please try again");
  276. }
  277. }
  278. ,
  279. /// <summary>
  280. /// Creates a client callback back to the requesting page
  281. /// and calls the callback method with the response as parameter.
  282. /// </summary>
  283. createCallback: function (url, callback) {
  284. var http = BlogEngine.getHttpObject();
  285. http.open("GET", url, true);
  286. http.onreadystatechange = function () {
  287. if (http.readyState == 4) {
  288. if (http.responseText.length > 0 && callback != null)
  289. callback(http.responseText);
  290. }
  291. };
  292. http.send(null);
  293. }
  294. ,
  295. /// <summary>
  296. /// Creates a XmlHttpRequest object.
  297. /// </summary>
  298. getHttpObject: function () {
  299. if (typeof XMLHttpRequest != 'undefined')
  300. return new XMLHttpRequest();
  301. try {
  302. return new ActiveXObject("Msxml2.XMLHTTP");
  303. }
  304. catch (e) {
  305. try {
  306. return new ActiveXObject("Microsoft.XMLHTTP");
  307. }
  308. catch (e) { }
  309. }
  310. return false;
  311. }
  312. ,
  313. // Updates the calendar from client-callback
  314. updateCalendar: function (args, context) {
  315. var cal = BlogEngine.$('calendarContainer');
  316. cal.innerHTML = args;
  317. BlogEngine.Calendar.months[context] = args;
  318. }
  319. ,
  320. toggleMonth: function (year) {
  321. var monthList = BlogEngine.$("monthList");
  322. var years = monthList.getElementsByTagName("ul");
  323. for (i = 0; i < years.length; i++) {
  324. if (years[i].id == year) {
  325. var state = years[i].className == "open" ? "" : "open";
  326. years[i].className = state;
  327. break;
  328. }
  329. }
  330. }
  331. ,
  332. // Adds a trim method to all strings.
  333. equal: function (first, second) {
  334. var f = first.toLowerCase().replace(new RegExp(' ', 'gi'), '');
  335. var s = second.toLowerCase().replace(new RegExp(' ', 'gi'), '');
  336. return f == s;
  337. }
  338. ,
  339. /*-----------------------------------------------------------------------------
  340. XFN HIGHLIGHTER
  341. -----------------------------------------------------------------------------*/
  342. xfnRelationships: ['friend', 'acquaintance', 'contact', 'met'
  343. , 'co-worker', 'colleague', 'co-resident'
  344. , 'neighbor', 'child', 'parent', 'sibling'
  345. , 'spouse', 'kin', 'muse', 'crush', 'date'
  346. , 'sweetheart', 'me']
  347. ,
  348. // Applies the XFN tags of a link to the title tag
  349. hightLightXfn: function () {
  350. var content = BlogEngine.$('content');
  351. if (content == null)
  352. return;
  353. var links = content.getElementsByTagName('a');
  354. for (i = 0; i < links.length; i++) {
  355. var link = links[i];
  356. var rel = link.getAttribute('rel');
  357. if (rel && rel != "nofollow") {
  358. for (j = 0; j < BlogEngine.xfnRelationships.length; j++) {
  359. if (rel.indexOf(BlogEngine.xfnRelationships[j]) > -1) {
  360. link.title = 'XFN relationship: ' + rel;
  361. break;
  362. }
  363. }
  364. }
  365. }
  366. }
  367. ,
  368. showRating: function (container, id, raters, rating) {
  369. var div = document.createElement('div');
  370. div.className = 'rating';
  371. var p = document.createElement('p');
  372. div.appendChild(p);
  373. if (raters == 0) {
  374. p.innerHTML = BlogEngine.i18n.beTheFirstToRate;
  375. }
  376. else {
  377. p.innerHTML = BlogEngine.i18n.currentlyRated.replace('{0}', new Number(rating).toFixed(1)).replace('{1}', raters);
  378. }
  379. var ul = document.createElement('ul');
  380. ul.className = 'star-rating small-star';
  381. div.appendChild(ul);
  382. var li = document.createElement('li');
  383. li.className = 'current-rating';
  384. li.style.width = Math.round(rating * 20) + '%';
  385. li.innerHTML = 'Currently ' + rating + '/5 Stars.';
  386. ul.appendChild(li);
  387. for (var i = 1; i <= 5; i++) {
  388. var l = document.createElement('li');
  389. var a = document.createElement('a');
  390. a.innerHTML = i;
  391. a.href = 'rate/' + i;
  392. a.className = this.englishNumber(i);
  393. a.title = BlogEngine.i18n.rateThisXStars.replace('{0}', i.toString()).replace('{1}', i == 1 ? '' : 's');
  394. a.onclick = function () {
  395. BlogEngine.rate(id, this.innerHTML);
  396. return false;
  397. };
  398. l.appendChild(a);
  399. ul.appendChild(l);
  400. }
  401. container.innerHTML = '';
  402. container.appendChild(div);
  403. container.style.visibility = 'visible';
  404. }
  405. ,
  406. applyRatings: function () {
  407. var divs = document.getElementsByTagName('div');
  408. for (var i = 0; i < divs.length; i++) {
  409. if (divs[i].className == 'ratingcontainer') {
  410. var args = divs[i].innerHTML.split('|');
  411. BlogEngine.showRating(divs[i], args[0], args[1], args[2]);
  412. }
  413. }
  414. },
  415. englishNumber: function (number) {
  416. if (number == 1)
  417. return 'one-star';
  418. if (number == 2)
  419. return 'two-stars';
  420. if (number == 3)
  421. return 'three-stars';
  422. if (number == 4)
  423. return 'four-stars';
  424. return 'five-stars';
  425. }
  426. ,
  427. // Adds event to window.onload without overwriting currently assigned onload functions.
  428. // Function found at Simon Willison's weblog - http://simon.incutio.com/
  429. addLoadEvent: function (func) {
  430. var oldonload = window.onload;
  431. if (typeof window.onload != 'function') {
  432. window.onload = func;
  433. }
  434. else {
  435. window.onload = function () {
  436. oldonload();
  437. func();
  438. }
  439. }
  440. }
  441. ,
  442. filterByAPML: function () {
  443. var width = document.documentElement.clientWidth + document.documentElement.scrollLeft;
  444. var height = document.documentElement.clientHeight + document.documentElement.scrollTop;
  445. document.body.style.position = 'static';
  446. var layer = document.createElement('div');
  447. layer.style.zIndex = 2;
  448. layer.id = 'layer';
  449. layer.style.position = 'absolute';
  450. layer.style.top = '0px';
  451. layer.style.left = '0px';
  452. layer.style.height = document.documentElement.scrollHeight + 'px';
  453. layer.style.width = width + 'px';
  454. layer.style.backgroundColor = 'black';
  455. layer.style.opacity = '.6';
  456. layer.style.filter += ("progid:DXImageTransform.Microsoft.Alpha(opacity=60)");
  457. document.body.appendChild(layer);
  458. var div = document.createElement('div');
  459. div.style.zIndex = 3;
  460. div.id = 'apmlfilter';
  461. div.style.position = (navigator.userAgent.indexOf('MSIE 6') > -1) ? 'absolute' : 'fixed';
  462. div.style.top = '200px';
  463. div.style.left = (width / 2) - (400 / 2) + 'px';
  464. div.style.height = '50px';
  465. div.style.width = '400px';
  466. div.style.backgroundColor = 'white';
  467. div.style.border = '2px solid silver';
  468. div.style.padding = '20px';
  469. document.body.appendChild(div);
  470. var p = document.createElement('p');
  471. p.innerHTML = BlogEngine.i18n.apmlDescription;
  472. p.style.margin = '0px';
  473. div.appendChild(p);
  474. var form = document.createElement('form');
  475. form.method = 'get';
  476. form.style.display = 'inline';
  477. form.action = BlogEngine.webRoot;
  478. div.appendChild(form);
  479. var textbox = document.createElement('input');
  480. textbox.type = 'text';
  481. textbox.value = BlogEngine.getCookieValue('url') || 'http://';
  482. textbox.style.width = '320px';
  483. textbox.id = 'txtapml';
  484. textbox.name = 'apml';
  485. textbox.style.background = 'url(' + BlogEngine.webRoot + 'pics/apml.png) no-repeat 2px center';
  486. textbox.style.paddingLeft = '16px';
  487. form.appendChild(textbox);
  488. textbox.focus();
  489. var button = document.createElement('input');
  490. button.type = 'submit';
  491. button.value = BlogEngine.i18n.filter;
  492. button.onclick = function () { location.href = BlogEngine.webRoot + '?apml=' + encodeURIComponent(BlogEngine.$('txtapml').value) };
  493. form.appendChild(button);
  494. var br = document.createElement('br');
  495. div.appendChild(br);
  496. var a = document.createElement('a');
  497. a.innerHTML = BlogEngine.i18n.cancel;
  498. a.href = 'javascript:void(0)';
  499. a.onclick = function () { document.body.removeChild(BlogEngine.$('layer')); document.body.removeChild(BlogEngine.$('apmlfilter')); document.body.style.position = ''; };
  500. div.appendChild(a);
  501. }
  502. ,
  503. getCookieValue: function (name) {
  504. var cookie = new String(document.cookie);
  505. if (cookie != null && cookie.indexOf('comment=') > -1) {
  506. var start = cookie.indexOf(name + '=') + name.length + 1;
  507. var end = cookie.indexOf('&', start);
  508. if (end > start && start > -1)
  509. return cookie.substring(start, end);
  510. }
  511. return null;
  512. }
  513. ,
  514. test: function () {
  515. alert('test');
  516. }
  517. ,
  518. comments: {
  519. flagImage: null,
  520. contentBox: null,
  521. moderation: null,
  522. checkName: null,
  523. postAuthor: null,
  524. nameBox: null,
  525. emailBox: null,
  526. websiteBox: null,
  527. countryDropDown: null,
  528. captchaField: null,
  529. controlId: null,
  530. replyToId: null
  531. }
  532. };
  533. BlogEngine.addLoadEvent(BlogEngine.hightLightXfn);
  534. // add this to global if it doesn't exist yet
  535. if (typeof ($) == 'undefined')
  536. window.$ = BlogEngine.$;
  537. if (typeof (registerCommentBox) != 'undefined')
  538. BlogEngine.addLoadEvent(registerCommentBox);
  539. if (typeof (setupBlogEngineCalendar) != 'undefined')
  540. BlogEngine.addLoadEvent(setupBlogEngineCalendar);
  541. // apply ratings after registerVariables.
  542. BlogEngine.addLoadEvent(BlogEngine.applyRatings);