Initial add of defaria.com
[clearscm.git] / defaria.com / blogs / Status / mt.js
1 // The cookie name to use for storing the blog-side comment session cookie.
2 var mtCookieName = "mt_blog_user";
3 var mtCookieDomain = ".defaria.com";
4 var mtCookiePath = "/";
5 var mtCookieTimeout = 14400;
6
7
8 function mtHide(id) {
9     var el = (typeof id == "string") ? document.getElementById(id) : id;
10     if (el) el.style.display = 'none';
11 }
12
13
14 function mtShow(id) {
15     var el = (typeof id == "string") ? document.getElementById(id) : id;
16     if (el) el.style.display = 'block';
17 }
18
19
20 function mtAttachEvent(eventName,func) {
21     var onEventName = 'on' + eventName;
22     var old = window[onEventName];
23     if( typeof old != 'function' )
24         window[onEventName] = func;
25     else {
26         window[onEventName] = function( evt ) {
27             old( evt );
28             return func( evt );
29         };
30     }
31 }
32
33
34 function mtFireEvent(eventName,param) {
35     var fn = window['on' + eventName];
36     if (typeof fn == 'function') return fn(param);
37     return;
38 }
39
40 if(!this.JSON){JSON={};}(function(){function f(n){return n<10?'0'+n:n;}if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(key){return this.getUTCFullYear()+'-'+f(this.getUTCMonth()+1)+'-'+f(this.getUTCDate())+'T'+f(this.getUTCHours())+':'+f(this.getUTCMinutes())+':'+f(this.getUTCSeconds())+'Z';};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf();};}var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==='string'?c:'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4);})+'"':'"'+string+'"';}function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==='object'&&typeof value.toJSON==='function'){value=value.toJSON(key);}if(typeof rep==='function'){value=rep.call(holder,key,value);}switch(typeof value){case'string':return quote(value);case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';}gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==='[object Array]'){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||'null';}v=partial.length===0?'[]':gap?'[\n'+gap+partial.join(',\n'+gap)+'\n'+mind+']':'['+partial.join(',')+']';gap=mind;return v;}if(rep&&typeof rep==='object'){length=rep.length;for(i=0;i<length;i+=1){k=rep[i];if(typeof k==='string'){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}else{for(k in value){if(Object.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}v=partial.length===0?'{}':gap?'{\n'+gap+partial.join(',\n'+gap)+'\n'+mind+'}':'{'+partial.join(',')+'}';gap=mind;return v;}}if(typeof JSON.stringify!=='function'){JSON.stringify=function(value,replacer,space){var i;gap='';indent='';if(typeof space==='number'){for(i=0;i<space;i+=1){indent+=' ';}}else if(typeof space==='string'){indent=space;}rep=replacer;if(replacer&&typeof replacer!=='function'&&(typeof replacer!=='object'||typeof replacer.length!=='number')){throw new Error('JSON.stringify');}return str('',{'':value});};}if(typeof JSON.parse!=='function'){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==='object'){for(k in value){if(Object.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v;}else{delete value[k];}}}}return reviver.call(holder,key,value);}cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4);});}if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof reviver==='function'?walk({'':j},''):j;}throw new SyntaxError('JSON.parse');};}}());
41
42 var MT = window.MT || {};
43
44 MT.cons = function () {
45   return {
46     LOG : 'log',
47     WARN : 'warn',
48     DEBUG : 'debug',
49     INFO : 'info',
50     ERR : 'error',
51     JSON : 'json'
52   };
53 }();
54
55
56 MT.core = function (o) {
57   var _debug = false;
58   
59   return {
60     
61     connect : function (url,respType,respHandler) {
62       var xh = mtGetXmlHttp();
63       if (!xh) return false;
64       
65       xh.onreadystatechange = function() {
66         if ( xh.readyState == 4 ) {
67           if ( xh.status && ( xh.status != 200 ) ) {
68             // error - ignore
69           } else {
70             switch (respType) {
71               case 'json':
72                 respHandler(JSON.parse(xh.responseText));
73                 break;
74                 
75               case 'xml':
76                 break;
77                 
78               case 'text':
79                 break;
80             }
81           }
82         }
83       };
84       
85       xh.open('GET',url);
86       xh.send(null);
87     },
88     
89     getEl : function (el) {
90       return MT.util.checkNodeType(el)==='element' ? id : (document.getElementById(el) || false);
91     },
92     
93     addEvent : function (el,type,func,obj) {
94       if(!obj && document.addEventListener) {
95         el.addEventListener(type,func,false);
96       } else if(obj && document.addEventListener) {
97         el.addEventListener(type,function () {
98           func.call(obj,event);
99         },false);
100       } else {
101         if(obj) {
102           el.attachEvent('on' + type,function () {
103             func.call(obj,event);
104           });
105         } else {
106           el.attachEvent('on' + type,function () {          
107             func.call(el,event);
108           });
109         }
110       }
111     },
112     
113     
114     log : function (level,msg) {
115       if(_debug && window.console) {
116         switch(level) {
117           case 'warn':
118           case 'debug':
119           case 'info':
120           case 'error':
121           case 'log':
122             console[level](msg);
123             break;
124             
125           default:
126             return false; 
127         }
128       } else {
129         return false;
130       }
131     }
132   }
133 }();
134
135
136 MT.util = function () {
137   return {
138     toggleVisibility : {
139       show : function () {
140         var i = arguments.length;
141         
142         while(i--) {
143           if(MT.util.checkNodeType(arguments[i])==='element') {
144             arguments[i].style.visibility = 'visible';
145           } else {
146             MT.core.getEl(arguments[i]).style.visibility = 'visible';
147           }
148         }
149       },
150       
151       hide : function () {
152         var i = arguments.length;
153         while(i--) {
154           if(MT.util.checkNodeType(arguments[i])==='element') {
155             arguments[i].style.visibility = 'hidden';
156           } else {
157             MT.core.getEl(arguments[i]).style.visibility = 'hidden';
158           }
159         }
160       }
161     },
162     
163     toggleDisplay : {
164       show : function () {
165         var i = arguments.length;
166         while(i--) {
167           if(MT.util.checkNodeType(arguments[i])==='element') {
168             arguments[i].style.display = '';
169           } else {
170             MT.core.getEl(arguments[i]).style.display = '';
171           }
172         }
173       },
174       
175       hide : function () {
176         var i = arguments.length;
177         while(i--) {
178           if(MT.util.checkNodeType(arguments[i])==='element') {
179             arguments[i].style.display = 'none';
180           } else {
181             MT.core.getEl(arguments[i]).style.display = 'none';
182           }
183         }
184       }
185     },
186     
187     
188     findDefiningParent : function (origin) {
189       if(MT.util.checkNodeType(origin)==='element') {
190         for(var node=origin.parentNode;node.parentNode;node=node.parentNode) {
191           if((node.hasAttribute && node.hasAttribute('id')) || node.getAttribute('id')) {
192             return node;
193           }
194         }
195       }
196       return false;
197     },
198     
199     
200     checkNodeType : function (obj) {
201       if (obj && obj.nodeName){
202         switch (obj.nodeType) {
203           case 1: return 'element';
204           case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace';
205         }
206       }
207     }
208   }
209 }();
210
211
212 (function () {
213   var M = MT.core,
214       c = MT.cons,
215       u = MT.util,
216       cache,
217       isLoading,
218       direction,
219       currentComments,
220       commentAnchor,
221       commentArrId,
222       commentsPerPage,
223       commentsTotalPages,
224       loadingIcon,
225       pageNum,
226       commentsOffset,
227       totalComments,
228       entryID,
229       commentContentDiv,
230       topNav,
231       nav,
232       currentCommentsSpan,
233       topCurrentCommentsSpan;
234             
235   M.addEvent(window,'load',_init);
236   
237   /**
238    * Initializes the class
239    * 
240    * @return void
241    */
242   function _init () {
243     if(!MT.entryCommentCount) {
244       return;
245     }
246     
247     _initializeVariables();
248     _setCommentOffset(false);
249     _checkForAnchor();
250                 _setCurrentComments();
251     _toggleNavLinks();
252     _initializeEvents();
253   }
254   
255   
256   function _initializeVariables() {
257     cache = {};
258     isLoading = false;
259     commentAnchor = '';
260     commentArrId = '';
261     commentsPerPage = MT.commentsPerPage || 50;
262     currentComments = '';
263     direction = 'ascend';
264     entryID = MT.entryID;
265     totalComments = MT.entryCommentCount;
266     commentsTotalPages = Math.ceil(totalComments / commentsPerPage);
267     pageNum = 1;
268     
269     loadingIcon = "<img title='Loading...' src='http://defaria.com/mt/mt-static/images/indicator.white.gif' alt='Loading' />";
270     
271     commentContentDiv = M.getEl("comments-content");
272     topNav = M.getEl("top-comment-nav");
273     nav = M.getEl("comment-nav");
274     
275     currentCommentsSpan = M.getEl("current-comments");
276     topCurrentCommentsSpan = M.getEl("top-current-comments");
277   }
278   
279   function _initializeEvents() {
280     if (commentsPerPage < totalComments) {
281       M.addEvent(nav,'click',_handleEvents);
282       M.addEvent(topNav,'click',_handleEvents);
283     }
284   }
285   
286   
287   function _checkForAnchor() {
288     var found = String(window.location.hash).match( /comment-(\d{1,6})/ );
289                 
290                 if (found) {
291                   M.log(c.DEBUG,found);
292                         if (!Object.prototype.hasOwnProperty.call(M.getEl(found[0]), 'className')) {
293                                 if (_findIdMatch(found[1])) {
294                         pageNum = Math.floor(commentArrId / commentsPerPage) + 1;
295                         M.log(c.DEBUG,'Comment Array Id: ' + commentArrId);
296                         M.log(c.DEBUG,'Comments Per Page: ' + commentsPerPage);
297                         M.log(c.DEBUG,'Page Number: ' + pageNum);
298                         M.log(c.DEBUG,'Comment Offset: ' + _getCommentOffset());
299                         _updateComments();
300                 }
301                         }
302                 }
303   }
304   
305   
306   function _setCommentOffset() {
307     commentsOffset = commentsPerPage * (pageNum-1);
308   }
309   
310   
311   function _getCommentOffset() {
312     return commentsOffset;
313   }
314   
315   
316   function _handleEvents (e) {
317     var origin = e.target || e.srcElement,
318         parentId;
319         
320     // stupid IE
321     origin = origin.id && M.getEl(origin.id) || false;
322
323     if(origin) {
324       parentId = u.checkNodeType(origin.parentNode)==='element' && origin.parentNode.getAttribute('id') && origin.parentNode.id;
325     } else {
326       return false;
327     }
328     
329     switch(origin.nodeName) {
330       case 'A':
331         switch (parentId) {
332           case 'prev-comments':
333           case 'top-prev-comments':
334             if(e.preventDefault) {
335               e.preventDefault();
336             } else {
337               e.returnValue =   false;
338             }
339             if(!isLoading) {
340               _previousPage();
341             }
342             break;
343           case 'next-comments':
344           case 'top-next-comments':
345             if(e.preventDefault) {
346               e.preventDefault();
347             } else {
348               e.returnValue =   false;
349             }
350             if(!isLoading) {
351               _nextPage();
352             }
353             break;
354         }
355         break;
356     }
357   }
358   
359   
360   function _toggleNavLinks () {
361     M.log(c.DEBUG,M.getEl('top-prev-comments'));
362     if(pageNum <= commentsTotalPages && pageNum !== 1) {
363       u.toggleVisibility.show('prev-comments');
364       u.toggleVisibility.show('top-prev-comments');
365     }
366     
367     if(pageNum >= 1 && pageNum !== commentsTotalPages) {
368       u.toggleVisibility.show('next-comments');
369       u.toggleVisibility.show('top-next-comments');
370     }
371     
372     if(pageNum===1 || nav.style.visibility==='hidden') {
373       u.toggleVisibility.hide('prev-comments');
374       u.toggleVisibility.hide('top-prev-comments');
375     }
376     
377     if(pageNum===commentsTotalPages || nav.style.visibility==='hidden') {
378       u.toggleVisibility.hide('next-comments');
379       u.toggleVisibility.hide('top-next-comments');
380     }
381   }
382   
383   
384   function _nextPage () {
385     if(pageNum < commentsTotalPages) {
386       pageNum++;
387       _updateComments();
388     }
389   }
390   
391   
392   function _previousPage() {
393     if(pageNum > 1) {
394       pageNum--;
395       _updateComments();
396     }
397   }
398   
399   
400   function _findIdMatch (id) {
401     var len = MT.commentIds.length;
402     
403         while (len--) {
404                 if (MT.commentIds[len] == id) {
405                         commentAnchor = "comment-" + id;
406                         commentArrId = len;
407                         return true;
408                 }
409         }
410         
411         return false;
412   }
413   
414   
415   function _setCurrentComments() {
416     var commentsOnPage = pageNum != commentsTotalPages ? commentsOffset + commentsPerPage : totalComments;
417     
418     _setCurrentCommentsContent([commentsOffset+1," - ",commentsOnPage].join(''));
419   }
420   
421   
422   function _setCurrentCommentsContent(currentCommentsHTML) {
423     currentCommentsSpan.innerHTML = currentCommentsHTML;
424     topCurrentCommentsSpan.innerHTML = currentCommentsHTML;
425   }
426   
427   
428   function _setCommentContent(commentHTML) {
429     commentContentDiv.innerHTML = commentHTML;
430   }
431   
432   
433   function _updateComments() {
434     var comments, jsonUrl, cacheKey, offset;
435     isLoading = true;
436     _setCurrentCommentsContent(loadingIcon);
437     _setCommentOffset();
438
439     offset   = _getCommentOffset();
440     cacheKey = [direction, entryID, commentsPerPage, offset]
441         .join('-')
442         .replace(/[^a-zA-Z0-9-]/g, '');
443     jsonUrl  = [
444         "http://defaria.com/mt/mt-comments.cgi?__mode=comment_listing&direction=",
445         direction,
446         "&entry_id=",
447         entryID,
448         "&limit=",
449         commentsPerPage,
450         "&offset=",
451         offset,
452         "&cacheKey=",
453         cacheKey,
454         "&jsonp=mtUpdateCommentsCallback",
455         "&ts=",
456         new Date().getTime()
457       ].join('');
458         
459         if (!commentAnchor) {
460       commentAnchor = "comments-content";
461     }
462
463     if(cache.hasOwnProperty(cacheKey)) {
464       _refreshComments(cache[cacheKey]);
465       isLoading = false;
466     } else {
467       var script = document.createElement('script');
468       script.src = jsonUrl;
469       (document.getElementsByTagName('head'))[0].appendChild(script);
470     }
471   }
472
473   window['mtUpdateCommentsCallback'] = function(json) {
474     cache[json.cacheKey] = json.comments;
475     _refreshComments(json.comments);
476     isLoading = false;
477   }
478   
479   
480   function _refreshComments(commentData) {
481     _setCommentContent(commentData);
482     _setCurrentComments();
483     window.location.hash = 'reset';
484     window.location.hash = commentAnchor;
485     _toggleNavLinks();
486   }
487 })();
488
489
490 function mtRelativeDate(ts, fds) {
491     var now = new Date();
492     var ref = ts;
493     var delta = Math.floor((now.getTime() - ref.getTime()) / 1000);
494
495     var str;
496     if (delta < 60) {
497         str = 'moments ago';
498     } else if (delta <= 86400) {
499         // less than 1 day
500         var hours = Math.floor(delta / 3600);
501         var min = Math.floor((delta % 3600) / 60);
502         if (hours == 1)
503             str = '1 hour ago';
504         else if (hours > 1)
505             str = '2 hours ago'.replace(/2/, hours);
506         else if (min == 1)
507             str = '1 minute ago';
508         else
509             str = '2 minutes ago'.replace(/2/, min);
510     } else if (delta <= 604800) {
511         // less than 1 week
512         var days = Math.floor(delta / 86400);
513         var hours = Math.floor((delta % 86400) / 3600);
514         if (days == 1)
515             str = '1 day ago';
516         else if (days > 1)
517             str = '2 days ago'.replace(/2/, days);
518         else if (hours == 1)
519             str = '1 hour ago';
520         else
521             str = '2 hours ago'.replace(/2/, hours);
522     }
523     return str ? str : fds;
524 }
525
526
527 function mtEditLink(entry_id, author_id) {
528     
529     
530 }
531
532
533 function mtCommentFormOnFocus() {
534     // if CAPTCHA is enabled, this causes the captcha image to be
535     // displayed if it hasn't been already.
536     mtShowCaptcha();
537 }
538
539
540 var mtCaptchaVisible = false;
541 function mtShowCaptcha() {
542     var u = mtGetUser();
543     if ( u && u.is_authenticated ) return;
544     if (mtCaptchaVisible) return;
545     var div = document.getElementById('comments-open-captcha');
546     if (div) {
547         div.innerHTML = '';
548         mtCaptchaVisible = true;
549     }
550 }
551
552
553
554 var is_preview;
555 var user;
556
557 function mtSetUser(u) {
558     if (u) {
559         // persist this
560         user = u;
561         mtSaveUser();
562         // sync up user greeting
563         mtFireEvent('usersignin');
564     }
565 }
566
567
568 function mtEscapeJS(s) {
569     s = s.replace(/'/g, "&apos;");
570     return s;
571 }
572
573
574 function mtUnescapeJS(s) {
575     s = s.replace(/&apos;/g, "'");
576     return s;
577 }
578
579
580 function mtBakeUserCookie(u) {
581     var str = "";
582     if (u.name) str += "name:'" + mtEscapeJS(u.name) + "';";
583     if (u.url) str += "url:'" + mtEscapeJS(u.url) + "';";
584     if (u.email) str += "email:'" + mtEscapeJS(u.email) + "';";
585     if (u.is_authenticated) str += "is_authenticated:'1';";
586     if (u.profile) str += "profile:'" + mtEscapeJS(u.profile) + "';";
587     if (u.userpic) str += "userpic:'" + mtEscapeJS(u.userpic) + "';";
588     if (u.sid) str += "sid:'" + mtEscapeJS(u.sid) + "';";
589     str += "is_trusted:'" + (u.is_trusted ? "1" : "0") + "';";
590     str += "is_author:'" + (u.is_author ? "1" : "0") + "';";
591     str += "is_banned:'" + (u.is_banned ? "1" : "0") + "';";
592     str += "can_post:'" + (u.can_post ? "1" : "0") + "';";
593     str += "can_comment:'" + (u.can_comment ? "1" : "0") + "';";
594     str = str.replace(/;$/, '');
595     return str;
596 }
597
598
599 function mtUnbakeUserCookie(s) {
600     if (!s) return;
601
602     var u = {};
603     var m;
604     while (m = s.match(/^((name|url|email|is_authenticated|profile|userpic|sid|is_trusted|is_author|is_banned|can_post|can_comment):'([^']+?)';?)/)) {
605         s = s.substring(m[1].length);
606         if (m[2].match(/^(is|can)_/)) // boolean fields
607             u[m[2]] = m[3] == '1' ? true : false;
608         else
609             u[m[2]] = mtUnescapeJS(m[3]);
610     }
611     if (u.is_authenticated) {
612         u.is_anonymous = false;
613     } else {
614         u.is_anonymous = true;
615         u.can_post = false;
616         u.is_author = false;
617         u.is_banned = false;
618         u.is_trusted = false;
619     }
620     return u;
621 }
622
623
624 function mtGetUser() {
625     if (!user) {
626         var cookie = mtGetCookie(mtCookieName);
627         if (!cookie) return;
628         user = mtUnbakeUserCookie(cookie);
629         if (! user) {
630             user = {};
631             user.is_anonymous = true;
632             user.can_post = false;
633             user.is_author = false;
634             user.is_banned = false;
635             user.is_trusted = false;
636         }
637     }
638     return user;
639 }
640
641
642 var mtFetchedUser = false;
643
644 function mtFetchUser(cb) {
645     if (!cb) cb = 'mtSetUser';
646     if ( ( cb == 'mtSetUser' ) && mtGetUser() ) {
647         var url = document.URL;
648         url = url.replace(/#.+$/, '');
649         url += '#comments-form';
650         location.href = url;
651     } else {
652         // we aren't using AJAX for this, since we may have to request
653         // from a different domain. JSONP to the rescue.
654         mtFetchedUser = true;
655         var u = mtGetUser();
656         var script = document.createElement('script');
657         var ts = new Date().getTime();
658         script.src = 'http://defaria.com/mt/mt-comments.cgi?__mode=userinfo&blog_id=8&jsonp=' + cb + '&ts=' + ts + '&sid=' + u.sid;
659         (document.getElementsByTagName('head'))[0].appendChild(script);
660     }
661 }
662
663 function mtVerifySession(cb) {
664     if (!cb) return;
665     var script = document.createElement('script');
666     var ts = new Date().getTime();
667     var u = mtGetUser();
668     script.src = 'http://defaria.com/mt/mt-comments.cgi?__mode=verify_session&blog_id=8&jsonp=' + cb + '&ts=' + ts + '&sid=' + u.sid;
669     (document.getElementsByTagName('head'))[0].appendChild(script);
670 }
671
672
673
674 function mtRememberMeOnClick(b) {
675     if (!b.checked)
676         mtClearUser(b.form);
677     return true;
678 }
679
680
681
682 var mtRequestSubmitted = false;
683 function mtCommentOnSubmit(f) {
684     if (!mtRequestSubmitted) {
685         mtRequestSubmitted = true;
686
687         if (f.armor)
688             f.armor.value = 'daa5a781478cd9a33628b0de8974f6ec865c9477';
689         if (f.bakecookie && f.bakecookie.checked)
690             mtSaveUser(f);
691
692         // disable submit buttons
693         if (f.preview_button) f.preview_button.disabled = true;
694         if (f.post) f.post.disabled = true;
695
696         var u = mtGetUser();
697         if ( !is_preview && ( u && u.is_authenticated ) ) {
698             // validate session; then submit
699             mtVerifySession('mtCommentSessionVerify');
700             return false;
701         }
702
703         return true;
704     }
705     return false;
706 }
707
708 function mtCommentSessionVerify(app_user) {
709     var f = document['comments_form'];
710     if ( app_user && app_user.verified ) {
711         f.submit();
712     } else {
713         alert('Your session has expired. Please sign in again to comment.');
714         mtClearUser();
715         mtFireEvent('usersignin');
716
717         mtShow('comments-form');
718         mtHide('comments-open-footer');
719
720     }
721 }
722
723 function mtUserOnLoad() {
724     var u = mtGetUser();
725
726     // if the user is authenticated, hide the 'anonymous' fields
727     // and any captcha input if already shown
728     if ( document.getElementById('comments-form')) {
729         if ( u && u.is_authenticated ) {
730             mtShow('comments-form');
731             mtHide('comments-open-data');
732             if (mtCaptchaVisible)
733                 mtHide('comments-open-captcha');
734         } else {
735
736             mtHide('comments-form');
737
738         }
739         if ( u && u.is_banned )
740             mtHide('comments-form');
741
742         // if we're previewing a comment, make sure the captcha
743         // field is visible
744         if (is_preview)
745             mtShowCaptcha();
746         else
747             mtShowGreeting();
748
749         // populate anonymous comment fields if user is cookied as anonymous
750         var cf = document['comments_form'];
751         if (cf) {
752             if (u && u.is_anonymous) {
753                 if (u.email) cf.email.value = u.email;
754                 if (u.name) cf.author.value = u.name;
755                 if (u.url) cf.url.value = u.url;
756                 if (cf.bakecookie)
757                     cf.bakecookie.checked = u.name || u.email;
758             } else {
759                 if (u && u.sid && cf.sid)
760                     cf.sid.value = u.sid;
761             }
762             if (cf.post && cf.post.disabled)
763                 cf.post.disabled = false;
764             if (cf.preview_button && cf.preview_button.disabled)
765                 cf.preview_button.disabled = false;
766             mtRequestSubmitted = false;
767         }
768     }
769 }
770
771
772
773
774 function mtEntryOnLoad() {
775     var cf = document['comments_form'];
776     if (cf && cf.preview) cf.preview.value = '';
777     mtHide('trackbacks-info');
778     mtHide('comment-greeting');
779     mtHide('comments-form');
780     mtFireEvent('usersignin');
781 }
782
783 function mtEntryOnUnload() {
784     if (mtRequestSubmitted) {
785         var cf = document['comments_form'];
786         if (cf) {
787             if (cf.post && cf.post.disabled)
788                 cf.post.disabled = false;
789             if (cf.preview_button && cf.preview_button.disabled)
790                 cf.preview_button.disabled = false;
791         }
792         mtRequestSubmitted = false;
793     }
794     return true;
795 }
796
797 mtAttachEvent('usersignin', mtUserOnLoad);
798
799
800
801 function mtSignIn() {
802     var doc_url = document.URL;
803     doc_url = doc_url.replace(/#.+/, '');
804     var url = 'http://defaria.com/mt/mt-comments.cgi?__mode=login&blog_id=8';
805     if (is_preview) {
806         if ( document['comments_form'] ) {
807             var entry_id = document['comments_form'].entry_id.value;
808             url += '&entry_id=' + entry_id;
809         } else {
810             url += '&return_url=http%3A%2F%2Fdefaria.com%2Fblogs%2FStatus%2F';
811         }
812     } else {
813         url += '&return_url=' + encodeURIComponent(doc_url);
814     }
815     mtClearUser();
816     location.href = url;
817 }
818
819 function mtSignInOnClick(sign_in_element) {
820     var el;
821     if (sign_in_element) {
822         // display throbber
823         el = document.getElementById(sign_in_element);
824         if (!el)  // legacy MT 4.x element id
825             el = document.getElementById('comment-form-external-auth');
826     }
827     if (el)
828         el.innerHTML = 'Signing in... <span class="status-indicator">&nbsp;</span>';
829
830     mtClearUser(); // clear any 'anonymous' user cookie to allow sign in
831     mtSignIn();
832     return false;
833 }
834
835 function mtSetUserOrLogin(u) {
836     if (u && u.is_authenticated) {
837         mtSetUser(u);
838     } else {
839         // user really isn't logged in; so let's do this!
840         mtSignIn();
841     }
842 }
843
844
845 function mtSignOut(entry_id) {
846     mtClearUser();
847     var doc_url = document.URL;
848     doc_url = doc_url.replace(/#.+/, '');
849     var url = 'http://defaria.com/mt/mt-comments.cgi?__mode=handle_sign_in&static=0&logout=1&blog_id=8';
850     if (is_preview) {
851         if ( document['comments_form'] ) {
852             var entry_id = document['comments_form'].entry_id.value;
853             url += '&entry_id=' + entry_id;
854         } else {
855             url += '&return_url=http%3A%2F%2Fdefaria.com%2Fblogs%2FStatus%2F';
856         }
857     } else {
858         url += '&return_url=' + encodeURIComponent(doc_url);
859     }
860     location.href = url;
861 }
862
863
864 function mtSignOutOnClick() {
865     mtSignOut();
866     return false;
867 }
868
869
870
871 function mtShowGreeting() {
872
873     var reg_reqd = true;
874
875     var cf = document['comments_form'];
876     if (!cf) return;
877
878     var el = document.getElementById('comment-greeting');
879     if (!el)  // legacy MT 4.x element id
880         el = document.getElementById('comment-form-external-auth');
881     if (!el) return;
882
883     var eid = cf.entry_id;
884     var entry_id;
885     if (eid) entry_id = eid.value;
886
887     var phrase;
888     var u = mtGetUser();
889
890     if ( u && u.is_authenticated ) {
891         if ( u.is_banned ) {
892             phrase = 'You do not have permission to comment on this blog. (\<a href=\"javas\cript:void(0);\" onclick=\"return mtSignOutOnClick();\"\>sign out\<\/a\>)';
893         } else {
894             var user_link;
895             if ( u.is_author ) {
896                 user_link = '<a href="http://defaria.com/mt/mt-comments.cgi?__mode=edit_profile&blog_id=8&return_url=' + encodeURIComponent( location.href );
897                 user_link += '">' + u.name + '</a>';
898             } else {
899                 // registered user, but not a user with posting rights
900                 if (u.url)
901                     user_link = '<a href="' + u.url + '">' + u.name + '</a>';
902                 else
903                     user_link = u.name;
904             }
905             // TBD: supplement phrase with userpic if one is available.
906             phrase = 'Thanks for signing in, __NAME__. (\<a href=\"javas\cript:void(0)\" onclick=\"return mtSignOutOnClick();\"\>sign out\<\/a\>)';
907             phrase = phrase.replace(/__NAME__/, user_link);
908         }
909     } else {
910         if (reg_reqd) {
911             phrase = '\<a href=\"javas\cript:void(0)\" onclick=\"return mtSignInOnClick(\'comment-greeting\')\"\>Sign in\<\/a\> to comment.';
912         } else {
913             phrase = '\<a href=\"javas\cript:void(0)\" onclick=\"return mtSignInOnClick(\'comment-greeting\')\"\>Sign in\<\/a\> to comment, or comment anonymously.';
914         }
915     }
916     el.innerHTML = phrase;
917
918 }
919
920
921
922 function mtReplyCommentOnClick(parent_id, author) {
923     mtShow('comment-form-reply');
924
925     var checkbox = document.getElementById('comment-reply');
926     var label = document.getElementById('comment-reply-label');
927     var text = document.getElementById('comment-text');
928
929     // Populate label with new values
930     var reply_text = 'Replying to \<a href=\"#comment-__PARENT__\" onclick=\"location.href=this.href; return false\"\>comment from __AUTHOR__\<\/a\>';
931     reply_text = reply_text.replace(/__PARENT__/, parent_id);
932     reply_text = reply_text.replace(/__AUTHOR__/, author);
933     label.innerHTML = reply_text;
934
935     checkbox.value = parent_id; 
936     checkbox.checked = true;
937     try {
938         // text field may be hidden
939         text.focus();
940     } catch(e) {
941     }
942
943     mtSetCommentParentID();
944 }
945
946
947 function mtSetCommentParentID() {
948     var checkbox = document.getElementById('comment-reply');
949     var parent_id_field = document.getElementById('comment-parent-id');
950     if (!checkbox || !parent_id_field) return;
951
952     var pid = 0;
953     if (checkbox.checked == true)
954         pid = checkbox.value;
955     parent_id_field.value = pid;
956 }
957
958
959 function mtSaveUser(f) {
960     // We can't reliably store the user cookie during a preview.
961     if (is_preview) return;
962
963     var u = mtGetUser();
964
965     if (f && (!u || u.is_anonymous)) {
966         if ( !u ) {
967             u = {};
968             u.is_authenticated = false;
969             u.can_comment = true;
970             u.is_author = false;
971             u.is_banned = false;
972             u.is_anonymous = true;
973             u.is_trusted = false;
974         }
975         if (f.author != undefined) u.name = f.author.value;
976         if (f.email != undefined) u.email = f.email.value;
977         if (f.url != undefined) u.url = f.url.value;
978     }
979
980     if (!u) return;
981
982     var cache_period = mtCookieTimeout * 1000;
983
984     // cache anonymous user info for a long period if the
985     // user has requested to be remembered
986     if (u.is_anonymous && f && f.bakecookie && f.bakecookie.checked)
987         cache_period = 365 * 24 * 60 * 60 * 1000;
988
989     var now = new Date();
990     mtFixDate(now);
991     now.setTime(now.getTime() + cache_period);
992
993     var cmtcookie = mtBakeUserCookie(u);
994     mtSetCookie(mtCookieName, cmtcookie, now, mtCookiePath, mtCookieDomain,
995         location.protocol == 'https:');
996 }
997
998
999 function mtClearUser() {
1000     user = null;
1001     mtDeleteCookie(mtCookieName, mtCookiePath, mtCookieDomain,
1002         location.protocol == 'https:');
1003 }
1004
1005
1006 function mtSetCookie(name, value, expires, path, domain, secure) {
1007     if (domain && ( domain.match(/^\.?localhost$/) || domain.match(/^[0-9\.]+$/) ))
1008         domain = null;
1009     var curCookie = name + "=" + encodeURIComponent(value) +
1010         (expires ? "; expires=" + expires.toGMTString() : "") +
1011         (path ? "; path=" + path : "") +
1012         (domain ? "; domain=" + domain : "") +
1013         (secure ? "; secure" : "");
1014     document.cookie = curCookie;
1015 }
1016
1017
1018 function mtGetCookie(name) {
1019     var prefix = name + '=';
1020     var c = document.cookie;
1021     var cookieStartIndex = c.indexOf(prefix);
1022     if (cookieStartIndex == -1)
1023         return '';
1024     var cookieEndIndex = c.indexOf(";", cookieStartIndex + prefix.length);
1025     if (cookieEndIndex == -1)
1026         cookieEndIndex = c.length;
1027     var this_cookie = c.substring(cookieStartIndex + prefix.length, cookieEndIndex);
1028     if ( this_cookie.match(/\%u/i) ) {
1029         return '';
1030     }
1031     return decodeURIComponent( this_cookie );
1032 }
1033
1034
1035 function mtDeleteCookie(name, path, domain, secure) {
1036     if (mtGetCookie(name)) {
1037         if (domain && domain.match(/^\.?localhost$/))
1038             domain = null;
1039         document.cookie = name + "=" +
1040             (path ? "; path=" + path : "") +
1041             (domain ? "; domain=" + domain : "") +
1042             (secure ? "; secure" : "") +
1043             "; expires=Thu, 01-Jan-70 00:00:01 GMT";
1044     }
1045 }
1046
1047 function mtFixDate(date) {
1048     var skew = (new Date(0)).getTime();
1049     if (skew > 0)
1050         date.setTime(date.getTime() - skew);
1051 }
1052
1053
1054 function mtGetXmlHttp() {
1055     if ( !window.XMLHttpRequest ) {
1056         window.XMLHttpRequest = function() {
1057             var types = [
1058                 "Microsoft.XMLHTTP",
1059                 "MSXML2.XMLHTTP.5.0",
1060                 "MSXML2.XMLHTTP.4.0",
1061                 "MSXML2.XMLHTTP.3.0",
1062                 "MSXML2.XMLHTTP"
1063             ];
1064
1065             for ( var i = 0; i < types.length; i++ ) {
1066                 try {
1067                     return new ActiveXObject( types[ i ] );
1068                 } catch( e ) {}
1069             }
1070
1071             return undefined;
1072         };
1073     }
1074     if ( window.XMLHttpRequest )
1075         return new XMLHttpRequest();
1076 }
1077
1078 // BEGIN: fast browser onload init
1079 // Modifications by David Davis, DWD
1080 // Dean Edwards/Matthias Miller/John Resig
1081 // http://dean.edwards.name/weblog/2006/06/again/?full#comment5338
1082
1083 function mtInit() {
1084     // quit if this function has already been called
1085     if (arguments.callee.done) return;
1086
1087     // flag this function so we don't do the same thing twice
1088     arguments.callee.done = true;
1089
1090     // kill the timer
1091     // DWD - check against window
1092     if ( window._timer ) clearInterval(window._timer);
1093
1094     // DWD - fire the window onload now, and replace it
1095     if ( window.onload && ( window.onload !== window.mtInit ) ) {
1096         window.onload();
1097         window.onload = function() {};
1098     }
1099
1100
1101     mtInitCommenter();
1102
1103
1104 }
1105
1106 /* for Mozilla/Opera9 */
1107 if (document.addEventListener) {
1108     document.addEventListener("DOMContentLoaded", mtInit, false);
1109 }
1110
1111 /* for Internet Explorer */
1112 /*@cc_on @*/
1113 /*@if (@_win32)
1114 document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
1115 var script = document.getElementById("__ie_onload");
1116 script.onreadystatechange = function() {
1117     if (this.readyState == "complete") {
1118         mtInit(); // call the onload handler
1119     }
1120 };
1121 /*@end @*/
1122
1123 /* for Safari */
1124 if (/WebKit/i.test(navigator.userAgent)) { // sniff
1125     _timer = setInterval(function() {
1126         if (/loaded|complete/.test(document.readyState)) {
1127             mtInit(); // call the onload handler
1128         }
1129     }, 10);
1130 }
1131
1132 /* for other browsers */
1133 window.onload = mtInit;
1134
1135 // END: fast browser onload init
1136
1137
1138
1139
1140 function mtLoggedIn(ott) {
1141     var script = document.createElement('script');
1142     var ts = new Date().getTime();
1143     script.src = 'http://defaria.com/mt/mt-comments.cgi?__mode=userinfo&jsonp=mtSaveUserInfo&ott=' + ott;
1144     (document.getElementsByTagName('head'))[0].appendChild(script);
1145 }
1146
1147 function mtRefreshUserInfo(sid) {
1148     var script = document.createElement('script');
1149     var ts = new Date().getTime();
1150     script.src = 'http://defaria.com/mt/mt-comments.cgi?__mode=userinfo&jsonp=mtSaveUserInfo&sid=' + sid;
1151     (document.getElementsByTagName('head'))[0].appendChild(script);
1152 }
1153
1154 function mtSaveUserInfo (u) {
1155     if ( u.error ) {
1156         if ( !user ) {
1157             alert('The sign-in attempt was not successful; Please try again.');
1158         }
1159         return;
1160     }
1161     user = null;
1162     var cmtcookie = mtBakeUserCookie(u);
1163     var now = new Date();
1164     var cache_period = mtCookieTimeout * 1000;
1165
1166     // cache anonymous user info for a long period if the
1167     // user has requested to be remembered
1168     mtFixDate(now);
1169     now.setTime(now.getTime() + cache_period);
1170     mtSetCookie(mtCookieName, cmtcookie, now, mtCookiePath, mtCookieDomain,
1171         location.protocol == 'https:');
1172     mtFireEvent('usersignin');
1173 }
1174
1175 function mtInitCommenter () {
1176     /***
1177      * If request contains a '#_login' or '#_logout' hash, use this to
1178      * also delete the blog-side user cookie, since we're coming back from
1179      * a login, logout or edit profile operation.
1180      */
1181
1182     var hash = ( window.location.hash );
1183     hash.match( /^#_(.*)$/ );
1184     var command = RegExp.$1 || '';
1185     if ( command === 'refresh' ) {
1186         // Back from profile edit screen.
1187         // Reload userinfo with current session ID.
1188         var u = mtGetUser();
1189         user  = null;
1190         mtRefreshUserInfo(u.sid);
1191     }
1192     else if ( command === 'logout' ) {
1193         // clear any logged in state
1194         mtClearUser();
1195         mtFireEvent('usersignin');
1196     }
1197     else if ( command.match( /^login_(.*)$/ ) ) {
1198         var sid = RegExp.$1;
1199         mtLoggedIn(sid);
1200     }
1201     else {
1202         mtFireEvent('usersignin');
1203     }
1204 }
1205
1206