/* name: CommentManager purpose: controller */ function CommentManager() { //required wired.utils.HttpPool.js //properties this.models = new Array(); this.views = new Array(); this.httpPool; this.proxy; this.story_id; this.forum_id; this.dom_container; this.requests = new Array(); //by id this.icon_collapsed = "http://a1112.g.akamai.net/7/1112/492/2002091469/www.wired.com/news/v/20020914/images/wiredBB/arrow_11x11.gif"; this.icon_expanded = "http://a1112.g.akamai.net/7/1112/492/2002091469/www.wired.com/news/v/20020914/images/wiredBB/arrow_down_11x11.gif"; this.icon_loading = "http://a1112.g.akamai.net/7/1112/492/2002091469/www.wired.com/news/v/20020914/images/wiredBB/spin_arrow_11x11.gif"; this.reg_url; this.login_url; this.is_loggedin; this.last_sent; //timestamp of when the last post was made this.doExpand; //methods this.setExpandOn = _CommentManager_setExpandOn; this.setStoryId = _CommentManager_setStoryId; this.setForumId = _CommentManager_setForumId; this.setProxy = _CommentManager_setProxy; this.addComment = _CommentManager_addComment; this.getModel = _CommentManager_getModel; this.getView = _CommentManager_getView; this.getModelById = _CommentManager_getModelById; this.getViewById = _CommentManager_getViewById; this.setSrcUrl = _CommentManager_setSrcUrl; this.getData = _CommentManager_getData; this.getMessage = _CommentManager_getMessage; this.getReplies = _CommentManager_getReplies; this.load = _CommentManager_load; this.setContainer = _CommentManager_setContainer; this.setPostTxt = _CommentManager_setPostTxt; this.setPostForm = _CommentManager_setPostForm; this.setPostFrame = _CommentManager_setPostFrame; this.addActiveRequest = _CommentManager_addActiveRequest; this.isActiveRequest = _CommentManager_isActiveRequest; this.removeActiveRequest = _CommentManager_removeActiveRequest; this.getActiveRequestCount = _CommentManager_getActiveRequestCount; this.reply = _CommentManager_reply; this.reset = _CommentManager_reset; this.report = _CommentManager_report; this.send_report= _CommentManager_send_report; this.post = _CommentManager_post; this.setUsername = _CommentManager_setUsername; //this.getUsername = _CommentManager_getUsername; this.getCommentCount = _CommentManager_getCommentCount; this.setCommentCount = _CommentManager_setCommentCount; this.setLoggedIn = _CommentManager_setLoggedIn; this.removeReplies = _CommentManager_removeReplies; this.register = _CommentManager_register; this.login = _CommentManager_login; this.logout = _CommentManager_logout; this.setRegistrationUrl = _CommentManager_setRegistrationUrl; this.setLoginUrl = _CommentManager_setLoginUrl; this.setLogoutUrl = _CommentManager_setLogoutUrl; this.handleData = _CommentManager_handleData; this.fetchXml = _CommentManager_fetchXml; this.proxyRequest = _CommentManager_proxyRequest; this.sendRequest = _CommentManager_sendRequest; this.hideData = _CommentManager_hideData; this.inDomain = _CommentManager_inDomain; this.isFlood = _CommentManager_isFlood; //constructor this.init = _CommentManager_init; { this.init(); } } function _CommentManager_setExpandOn(bool) { this.doExpand = bool; } function _CommentManager_isFlood() { var retVal = false; if (this.last_sent) { var now = new Date(); retVal = (now - this.last_sent)<10000?true:false; } return retVal; } function _CommentManager_setSrcUrl(src) { this.src_url = src; } function _CommentManager_setLoggedIn(bool) { this.is_loggedin = bool; } function _CommentManager_register() { //send the browser along to the registration url var url = this.reg_url; var cb = window.location.href; url = url + "&m_EMAIL=anon@wired.com&m_CBURL=" + cb; window.location.href = url; } function _CommentManager_login() { //send the browser along to the registration url var url = this.login_url; var cb = window.location.href; url = url + "&m_CBURL=" + cb; window.location.href = url; } function _CommentManager_logout() { //send the browser along to the registration url var url = this.logout_url; var cb = window.location.href; url = url + "&m_CBURL=" + cb; window.location.href = url; } function _CommentManager_setRegistrationUrl(url) { this.reg_url = url; } function _CommentManager_setLoginUrl(url) { this.login_url = url; } function _CommentManager_setCommentCount(num) { this.comment_count = num; } function _CommentManager_getCommentCount() { return (this.comment_count)?this.comment_count:0; } function _CommentManager_reply(id) { var view = this.getViewById(id); if (view) view.formatReply(); } function _CommentManager_reset(id) { var view = this.getViewById(id); if (view) view.reset(true); else { //hack - shouldn't have the classname here var el = (isIE)?document.getElementById(this.dom_post_textarea.id):this.dom_post_textarea; if (el) { el.value = ""; el.className = "top_post_small"; } } } function _CommentManager_sendRequest(action,id,isPost,complaint) { //don't do the same thing if (this.isActiveRequest(action, id)) return; //notify the model that it's being reloaded var mdl = this.getModelById(id); if (mdl && action!='report') mdl.updateStatus("loading"); //cache buster var d = new Date(); var dStr = d.getHours() + "-" + d.getMinutes() + d.getSeconds() + d.getMilliseconds(); var proxyUrl = this.src_url; if (proxyUrl) { var url = proxyUrl + "?f=" + this.forum_id + "&d=" + dStr + "&action=" + action + "&id=" + id; url += "&comment_id=" + id + "&complaint=" + escape(complaint); this.fetchXml(url, id, action, isPost); } else return null; } function _CommentManager_proxyRequest(action,id,isPost,complaint,force) { //don't do the same thing if (this.isActiveRequest(action, id)) return; //notify the model that it's being reloaded var mdl = this.getModelById(id); if (mdl && action!='report') mdl.updateStatus("loading"); //cache buster var d = new Date(); var dStr = d.getHours() + "-" + d.getMinutes() + d.getSeconds() + d.getMilliseconds(); //sadie modified to have javascript make httprequest directly to php. was: var proxyUrl = this.proxy; var proxyUrl = this.src_url; //but if this.proxy is set, we should use it if( this.proxy ) { proxyUrl = this.proxy; } if (proxyUrl) { //var url = proxyUrl + "?f=" + this.forum_id + "&d=" + dStr + "&action=" + action + "&id=" + id + "&src_url=" + this.src_url; //url += "&comment_id=" + id + "&complaint=" + complaint; var url = proxyUrl + "?f=" + this.forum_id + "&d=" + dStr + "&action=" + action + "&id=" + id; url += "&comment_id=" + id + "&complaint=" + complaint; //alert( "debug: " + url ); this.fetchXml(url, id, action, isPost, force); } else return null; } function _CommentManager_load(isPost) { //initializes the models for top-level comments if (!this.story_id) return false; //get the comments this.proxyRequest('article_comments', this.story_id, isPost); //get stats (count, ids, etc) this.proxyRequest('story_stats', this.story_id, isPost); return true; } function _CommentManager_setContainer(el) { this.dom_container = el; } function _CommentManager_setStoryId(id) { this.story_id = id; } function _CommentManager_setForumId(id) { this.forum_id = id; } function _CommentManager_setProxy(url) { this.proxy = url; } function _CommentManager_init() { this.httpPool = new HttpPool(); this.httpPool.init(5); this.is_loggedin = (document.cookie.indexOf("MAYA_SSO_49")>-1)?true:false; //alert(document.cookie); } function _CommentManager_addComment(node, parent_id, force) { var id = getElementTextNS("", "post_id", node, 0); if (!id || id=='n/a') return false; //first - handle the view var view = (this.views['vw-' + id])?this.views['vw-' + id]:new view_Comment(this); this.views['vw-' + id] = view; //next - handle the model var mdl = (this.models['mdl-' + id])?this.models['mdl-' + id]:new model_Comment(this); this.models['mdl-' + id] = mdl; //handle nesting var vwParent = this.getViewById(parent_id); if (vwParent) view.setParent(vwParent); var mdParent = this.getModelById(parent_id); if (mdParent) mdl.setParent(mdParent); //then have the view listen to the model for changes mdl.addListener(view); mdl.update(node); if (force) this.getData(id, force); } function _CommentManager_load() { //initializes the models for top-level comments if (!this.story_id) return false; //get the comments this.proxyRequest('article_comments', this.story_id); //get stats (count, ids, etc) this.proxyRequest('story_stats', this.story_id); return true; } function _CommentManager_setContainer(el) { this.dom_container = el; } function _CommentManager_setStoryId(id) { this.story_id = id; } function _CommentManager_setForumId(id) { this.forum_id = id; } function _CommentManager_setProxy(url) { this.proxy = url; } function _CommentManager_setLogoutUrl(url) { this.logout_url = url; } function _CommentManager_getModel(node) { var id = getElementTextNS("", "post_id", node, 0); if (!id || id=='n/a') return false; return this.models['mdl-' + id]; } function _CommentManager_getView(node) { var id = getElementTextNS("", "post_id", node, 0); if (!id || id=='n/a') return false; return this.views['vw-' + id]; } function _CommentManager_getViewById(id) { return this.views['vw-' + id]; } function _CommentManager_getModelById(id) { return this.models['mdl-' + id]; } function _CommentManager_hideData(id) { var mdl = this.getModelById(id); var view = this.getViewById(id); if (view) { view.dom_body.style.display = 'none'; view.dom_icon.src = view.icon_collapsed; } } function _CommentManager_getData(id,force) { var mdl = this.getModelById(id); var view = this.getViewById(id); if (view.formatted && mdl.loaded && !force) { //if the model data is loaded and the view has formatted it for display then //just treat this as a visibility toggle view.dom_body.style.display = (view.dom_body.style.display=='none')?'':'none'; view.dom_icon.src = (view.dom_body.style.display=='none')?view.icon_collapsed:view.icon_expanded; } else { if (mdl.loaded && view.formatted) { view.dom_body.style.display = ''; view.dom_icon.src = view.icon_expanded; } else { this.getMessage(id,force); this.getReplies(id,false,force); } } } function _CommentManager_getMessage(id,force) { this.proxyRequest('body', id, false, null, force); } function _CommentManager_getReplies(id, isPost, force) { this.proxyRequest('replies', id, isPost, null, force); } function _CommentManager_handleData(req, id, action, isPost, force) { // // req = XMLHTTP object // id = post id // action = reply, body, story_stats, report // size = # of individual requests spawned for the data request // auto = if this was system run as opposed to user run // //handle req error if (!req || req.status != 200) return; var dXml = req.responseXML; if (!dXml) return; //alert("debug:\n\n" + action + "\n\n" + req.responseText); var view = this.getViewById(id); var mdl = this.getModelById(id); switch (action) { case "report": alert("This comment has been reported to the moderator."); //alert("DEBUG:\n\n" + req.responseText); break; case "story_stats": //this sets up up the id params needed to post comments, and a few other things var nMessages = dXml.getElementsByTagName("message"); if (nMessages) { var nMessage = nMessages[0]; var topic_id = getElementTextNS("", "topic_id", nMessage, 0); var forum_id = getElementTextNS("", "forum_id", nMessage, 0); var replies = getElementTextNS("", "topic_replies", nMessage, 0); //now pop the data var frm = document.getElementById("reply_form"); if (frm && topic_id !="n/a" && forum_id!="n/a") { var et = frm.elements['t']; et.value = topic_id; //var ef = frm.elements['f']; //ef.value = forum_id; } this.setCommentCount(parseInt(replies)); var eCount = document.getElementById("comment_count"); //hack - this should be a property if (eCount && replies!="") eCount.innerHTML = "("+ (parseInt(replies)+1) +")" } break; default: var container = (view)?view.dom_replies:this.dom_container; //removed this and modified the view object to insert each new element to the top /* if (action!="body") { if (view) view.removeReplies(); else this.removeReplies(); } */ if (isIE) { //it appears there is an issue with IE not parsing XML that Firefox is Ok with //ref: http://nubertool.hotwired.com/news/business/1,1367,66965,00.html?tw=wn_5bizhead } var nlMessages = dXml.getElementsByTagName("message"); var total_count = nlMessages.length; for (var i=0; i < nlMessages.length; i++) { var nMsg = nlMessages[i]; manager.addComment(nMsg,id,force); } //alert( "debug:\n\nhandleData default case\nnlMessages:" + nlMessages + "\ntotal_count:" + total_count + "\nmanager.getCommentCount:" + manager.getCommentCount() ); break; } //mark this request as no longer active this.removeActiveRequest(action, id); if (this.getActiveRequestCount(id)==0) { if (mdl) mdl.updateStatus("loaded"); this.reset(id); } } function _CommentManager_removeReplies() { //this is necessarily to ensure the proper re-ordering of replies //as they're received from the mt var dReplies = this.dom_container; var len = dReplies.childNodes.length; for (var i=0; i < len; i++) { dReplies.removeChild(dReplies.childNodes[0]); } } function _CommentManager_addActiveRequest(action, id) { //first - claim an object from the pool var reqPool = this.httpPool; var req = reqPool.claimObject(); if (!req) return null; //next - record where the object is being used var aRequestSet = (this.requests['req-' + id])?this.requests['req-' + id]:new Array(); aRequestSet[action] = req; this.requests['req-' + id] = aRequestSet; return req; } function _CommentManager_isActiveRequest(action, id) { var aRequestSet = (this.requests['req-' + id])?this.requests['req-' + id]:new Array(); if (aRequestSet[action]) return true; else return false; } function _CommentManager_removeActiveRequest(action, id) { //first - restore the req object to the pool var aRequestSet = (this.requests['req-' + id])?this.requests['req-' + id]:new Array(); this.httpPool.releaseObject(aRequestSet[action]); //next - create a new array without the current action var aClean = new Array(); for(var p in aRequestSet) { if (p!=action) aClean[p] = aRequestSet[p]; } this.requests['req-' + id] = aClean; } function _CommentManager_getActiveRequestCount(id) { var aRequestSet = (this.requests['req-' + id])?this.requests['req-' + id]:new Array(); var num = 0; for (var p in aRequestSet) { num++; } return num; } function _CommentManager_setPostForm(obj) { this.dom_postform = obj; } function _CommentManager_setPostFrame(obj) { this.dom_postframe = obj; } function _CommentManager_setPostTxt(obj) { this.dom_post_textarea = obj; } // posts form to php interface for both top level comments and replies // id is not passed in for top level comments // for replies, id is id of parent post (post being responded to) function _CommentManager_post(id) { if (!this.is_loggedin) { alert("You must first Register or Login to use this feature.\n\nIf you have logged in and are still seeing this message please refresh your browser and try again.\n\nIf all else fails send us a note to newsprod@wired.com."); return; } if (this.isFlood()) { alert("It has been too soon since your last post. Wait a few seconds and try again!"); return; } // gets model and view of parent if current post is reply var mdl = this.getModelById(id); var view = this.getViewById(id); var path = (mdl)?mdl.parent_path + "," + id:id; if (path) path = path.replace("undefined", "0"); var frm = this.dom_postform; //post id var ep = frm.elements['p']; ep.value = (id)?id:""; //topic id var et = frm.elements['t']; //form id var ef = frm.elements['f']; //parent path var epath = frm.elements['post_path']; if (epath) { epath.value = path; } var eSub = frm.elements["subject"]; var eMsg = frm.elements["message"]; var txt = (view)?view.dom_current_textarea:document.getElementById(this.dom_post_textarea.id); eMsg.value = txt.value; if (txt.value=="") { alert("Please enter your comment in the space provided and then click Post."); return; } //the subject is the first 50 characters of the message eSub.value = txt.value.substr(0,50); frm.elements['post'].click(); //frm.submit(); this.last_sent = new Date(); if (id) { //this is risky - what if the post action takes more that 1/2 a second? window.setTimeout("manager.getReplies(" + id + ",true)", 500); } else { //this is risky - what if the post action takes more that 1/2 a second? window.setTimeout("manager.load(true)", 500); } } function _CommentManager_report(id) { var view = this.getViewById(id); if (view) view.formatReport(); } function _CommentManager_setUsername(name) { this.username = name; } function _CommentManager_send_report(id) { var view = this.getViewById(id); if (view && view.dom_report) { var model = view.model; var complaint = view.dom_report_txt.value; var user = this.username; var id = model.id; if (this.inDomain()) { //if it's in the same domain - call it directly this.proxyRequest('report', id, false, complaint); } else { //otherwise, user the proxy this.proxyRequest('report', id, false, complaint); } } } function _CommentManager_inDomain() { //check to see if the client is in the same domain as the mt try { var domain = window.location.host; var src_domain = this.src_url.substr(this.src_url.indexOf("http://")+7,this.src_url.indexOf("/",8)-7); if (src_domain.indexOf(":")) src_domain = src_domain.substr(0,src_domain.indexOf(":")); domain = domain.substr(domain.indexOf(".")); src_domain = src_domain.substr(src_domain.indexOf(".")); if (domain == src_domain) return true; else return false; } catch (e) { return false; } } function _CommentManager_fetchXml(url, id, action, isPost, force) { //this assumes the pool had been initiatized //alert( "debug:\n\n" + url ); var req = this.addActiveRequest(action, id); if (!req) { window.setTimeout("manager.fetchXml('"+url+"', "+id+", '"+action+"', "+isPost+","+force+")", 500); //try again in 1/2 second } else { //var method = (isPost)?"POST":"GET"; //alert("debug: url we feed to httprequest: " + url ); req.open("GET", url, true); req.onreadystatechange = function() { if (req.readyState == 4) { manager.handleData(req,id,action,isPost,force); } } req.send(null); return req; } }