FIRSTCLASS.layout.ThreadHandler = function(obj) {
this._config = obj;
if (!this._config.threading.coltype) {
this._config.threading.coltype = FIRSTCLASS.layout.ThreadHandler.coltypes.STRING;
}
this.threads = [];
};
FIRSTCLASS.layout.ThreadHandler.prototype.getThread = function(row) {
var threadId = this.getThreadId(row);
var thread = this.threads[threadId];
var isNew = false;
if ( !thread ) {
if (this._config.threadDraw) {
thread = new this._config.threadDraw(row, this, this._config.uniqueid);
} else {
thread = new FIRSTCLASS.layout.Thread(row, this, this._config.uniqueid);
}
isNew = true;
}
this.threads[threadId] = thread;
return {"thread":thread, "isNew": isNew};
};
FIRSTCLASS.layout.ThreadHandler.prototype.handleEvent = function(evt, fcevent) {
var rv = false, thread, uri;
if (evt.type == "click") {
switch (fcevent.fcid) {
case "uncollapser":
thread = this.threads[fcevent.fcattrs];
if (thread) {
thread.unsuppressReadItems(fcevent.clickexpandall);
rv = true;
}
break;
case "collapser":
thread = this.threads[fcevent.fcattrs];
if (thread) {
thread.suppressReadItems();
rv = true;
}
break;
case "collapsed":
thread = this.threads[fcevent.fcattrs];
if (thread) {
uri = fcevent.target.getAttribute("uri");
if (uri) {
thread.unsuppressReadItem(uri);
rv = true;
}
}
break;
default:
}
}
return rv;
};
FIRSTCLASS.layout.ThreadHandler.prototype.removeThread = function(thread) {
for (var i in this.threads) {
if (this.threads[i] == thread) {
this.threads.splice(i,1);
return;
}
}
};
FIRSTCLASS.layout.ThreadHandler.prototype.doreset = function() {
delete this.threads;
this.threads = [];
};
FIRSTCLASS.layout.ThreadHandler.prototype.handleRow = function(row) {
var tid = this.getThreadId(row);
var t = this.getThread(row);
t.handleRow(row);
};
FIRSTCLASS.layout.ThreadHandler.types = {
NONE: 0,
COLUMN: 1,
THREAD: 2,
DATE: 3
};
FIRSTCLASS.layout.ThreadHandler.coltypes = {
STRING: 0,
NUMBER: 1,
DATE: 2,
FRIENDLYDATE: 3
};
FIRSTCLASS.layout.ThreadHandler.prototype.getThreadId = function(row) {
if (this._config.threading.format != FIRSTCLASS.layout.ThreadHandler.types.NONE) {
var tid, dodate = false;
switch (this._config.threading.format) {
case FIRSTCLASS.layout.ThreadHandler.types.THREAD:
return row.threadid;
case FIRSTCLASS.layout.ThreadHandler.types.COLUMN:
tid = row[this._config.threading.column];
if (this._config.threading.coltype != FIRSTCLASS.layout.ThreadHandler.coltypes.FRIENDLYDATE) {
return tid;
}
dodate = true;
break;
default:
dodate = true;
}
if (dodate) {
if (this._config.threading.format == FIRSTCLASS.layout.ThreadHandler.types.DATE) {
tid = row.lastmod;
}
var curDate = new Date();
curDate.setTime(Date.parse(tid));
curDate.setHours(0);
curDate.setMinutes(0);
curDate.setSeconds(0);
curDate.setMilliseconds(0);
return curDate.toLocaleString();
}
} else {
return "";
}
};
FIRSTCLASS.layout.ThreadHandler.prototype.getThreadByElement = function(threadEl) {
var id = threadEl.id;
var strip = this._config.uniqueid+"Thread";
var threadId = id.slice(strip.length, id.length);
var thread = this.threads[threadId];
return thread;
};
FIRSTCLASS.layout.ThreadHandler.prototype.getThreadConfig = function() {
return this._config.threading;
};
FIRSTCLASS.layout.ThreadHandler.prototype.getRowHandler = function() {
return this._config.rowHandler;
};
FIRSTCLASS.layout.Thread = function(row, thandler, uniqueid) {
this.rowDefs = {};
this.rowmap = [];
this.threadid = thandler.getThreadId(row);
this.thandler = thandler;
this.tconfig = thandler.getThreadConfig();
this.rowHandler = thandler.getRowHandler();
this.uniqueid = uniqueid;
this.domElement = document.createElement("DIV");
var html = ["
");
this.domElement.innerHTML = html.join("");
this.domElement = this.domElement.firstChild;
this.getNewThreadHeader(row);
this.domElement.appendChild(this.threadHead);
this.contentsElement = document.createElement("DIV");
html = ["");
this.contentsElement.innerHTML = html.join("");
this.contentsElement = this.contentsElement.firstChild;
if (this.tconfig && this.tconfig.collapseRead) {
this.suppressReadItems();
// YAHOO.util.Dom.addClass(this.contentsElement, 'suppressreaditems');
}
this.domElement.appendChild(this.contentsElement);
this.initRow = row;
this.currentSelection = -1;
var that = this;
this.getListViewContainer = function() {
var container = YAHOO.util.Dom.getAncestorByClassName(that.domElement, "fcListViewContainer");
that.getListViewContainer = function() {
return container;
};
return container;
};
this.getListViewContainerParent = function() {
var container = that.getListViewContainer();
that.getListViewContainerParent = function() {
return container.parentNode;
};
return container.parentNode;
};
};
FIRSTCLASS.layout.Thread.prototype.handleClick = function(element) {
if (YAHOO.util.Dom.isAncestor(this.threadHead, element)) {
if (this._config.toolbarHelper) {
} else {
this.rowHandler.onRowClick(this._headerRow, this.threadHead);
}
}
};
FIRSTCLASS.layout.Thread.prototype.selectNext = function() {
if (this.currentSelection >= 0 && this.currentSelection < this.rowmap.length-1) {
this.currentSelection++;
} else if (this.currentSelection == -1) {
this.currentSelection = 0;
} else {
this.currentSelection = -1;
return false;
}
return this.rowDefs[this.rowmap[this.currentSelection]].domElement;
};
FIRSTCLASS.layout.Thread.prototype.selectPrevious = function() {
if (this.currentSelection > 0 && this.currentSelection < this.rowmap.length) {
this.currentSelection--;
} else if (this.currentSelection == -1) {
this.currentSelection = this.rowmap.length-1;
} else {
this.currentSelection = -1;
return false;
}
return this.rowDefs[this.rowmap[this.currentSelection]].domElement;
};
FIRSTCLASS.layout.Thread.prototype.changeSelection = function(row) {
for (var i = 0; i < this.rowmap.length; i++) {
if (this.rowmap[i] == row.uid) {
this.currentSelection = i;
break;
}
}
var def = this.rowDefs[this.rowmap[this.currentSelection]];
if (!def.domElement) {
if (!def.domElement) {
def.domElement = this.rowHandler.createRow(def.row);
def.domElement.id = def.row._listViewID;
}
YAHOO.util.Dom.removeClass(def.domElement, 'read');
def.recentlyread = true;
YAHOO.util.Dom.addClass(def.domElement, 'recentlyread');
this.contentsElement.appendChild(def.domElement);
}
return def.domElement;
};
FIRSTCLASS.layout.Thread.prototype.getDomElement = function() {
return this.domElement;
};
FIRSTCLASS.layout.Thread.prototype.getNewThreadHeader = function(row) {
this.threadHead = document.createElement("div");
this.threadHead.innerHTML = "";
this.threadHead = this.threadHead.firstChild;
this.updateThreadHeader(row);
};
FIRSTCLASS.layout.Thread.prototype.isQuestion = function(row) {
return row.subject.indexOf("?") > 0 || (row.originalformid && row.originalformid == 143)|| (row.originalformid && row.originalformid == 21001);
};
FIRSTCLASS.layout.Thread.prototype.updateUncollapser = function() {
if (this.tconfig.collapseRead && this._uncollapser) {
var that = this, def, recentlyread, i, row, ncontributors;
var nread = 0;
for (i in this.rowDefs) {
def = this.rowDefs[i];
if (def.domElement) {
recentlyread = def.recentlyread;
if (def.row.uri != that._headerRow.uri && def.row.status.unread == 0 && !recentlyread) {
nread++;
}
} else if (def.row.uri != that._headerRow.uri && def.row.status.unread == 0) {
nread++;
}
}
if (nread > 0) {
var html = "";
if (this.tconfig.displayThreadContributors) {
html += "";
} else {
var showsummary = nread > 1 ? FIRSTCLASS.locale.doSub(FIRSTCLASS.locale.community.feed.mread, [""+nread]) : FIRSTCLASS.locale.community.feed.mread1; // nread + " more read item"+ ((nread==1)?"":"s");
var hidesummary = nread > 1 ? FIRSTCLASS.locale.doSub(FIRSTCLASS.locale.community.feed.hide, [""+nread]) : FIRSTCLASS.locale.community.feed.hide1; // "hide " + nread + " read item"+ ((nread==1)?"":"s");
if (this.tconfig.summaryMode) {
if (this.tconfig.summaryMode === "summary") {
var likes = 0;
var hiddenreplies = 0;
var replies = 0;
for (i in this.rowmap) {
def = this.rowDefs[this.rowmap[i]];
row = def.row;
recentlyread = def.recentlyread;
if (row.uri != that._headerRow.uri) {
if (row.status.unread == 0 && !recentlyread) {
hiddenreplies++;
}
replies++;
}
}
showsummary = "";
hidesummary = "";
if (likes > 0) {
showsummary += likes + " people liked this";
if (hiddenreplies > 0) {
showsummary += ", ";
}
hidesummary = showsummary;
}
if (hiddenreplies > 0) {
showsummary += hiddenreplies > 1 ? FIRSTCLASS.locale.doSub(FIRSTCLASS.locale.community.feed.mreply, [""+hiddenreplies]) : FIRSTCLASS.locale.community.feed.mreply1;// hiddenreplies + " more repl" + ((hiddenreplies > 1)?"ies":"y");
hidesummary += replies > 1 ? FIRSTCLASS.locale.doSub(FIRSTCLASS.locale.community.feed.reply, [""+replies]) : FIRSTCLASS.locale.community.feed.reply1; // replies + " replies";
}
}
}
html = "";
}
this._uncollapser.innerHTML = html;
} else {
this._uncollapser.innerHTML = "";
}
}
};
FIRSTCLASS.layout.Thread.prototype.unsuppressReadItems = function(clickexpandall) {
for (var i = 1; i < this.rowmap.length; i++) {
var rcfg = this.rowDefs[this.rowmap[i]];
if (!rcfg.domElement) {
rcfg.domElement = this.rowHandler.createRow(rcfg.row);
rcfg.domElement.id = rcfg.row._listViewID;
}
this.contentsElement.appendChild(rcfg.domElement);
if (clickexpandall && rcfg.row.status.unread == 0) {
YAHOO.util.Dom.removeClass(rcfg.domElement, 'read');
rcfg.recentlyread = true;
YAHOO.util.Dom.addClass(rcfg.domElement, 'recentlyread');
}
}
YAHOO.util.Dom.removeClass(this.domElement, 'suppressreaditems');
YAHOO.util.Dom.removeClass(this.contentsElement, "fcListViewHiddenThreadBody");
if (clickexpandall) {
this.updateUncollapser();
}
};
FIRSTCLASS.layout.Thread.prototype.unsuppressReadItem = function(uri) {
var i, rcfg, insertBefore, inserted;
for (i = 0; i < this.rowmap.length; i++) {
rcfg = this.rowDefs[this.rowmap[i]];
if (rcfg.row.uri == uri) {
if (!rcfg.domElement) {
rcfg.domElement = this.rowHandler.createRow(rcfg.row);
rcfg.domElement.id = rcfg.row._listViewID;
}
insertBefore = 0;
for (i = 0; i < this.rowmap.length; i++) {
if (this.tconfig.sortfunc(this.rowDefs[this.rowmap[i]].row, rcfg.row) < 0) {
insertBefore = i;//this.rowmap[i];
break;
}
}
inserted = false;
for (i = insertBefore; i < this.rowmap.length; i++) {
if (this.rowDefs[this.rowmap[i]].domElement && this.rowDefs[this.rowmap[i]].domElement.parentNode == this.contentsElement) {
this.contentsElement.insertBefore(rcfg.domElement, this.rowDefs[this.rowmap[i]].domElement);
inserted = true;
break;
}
}
if (!inserted) {
this.contentsElement.appendChild(rcfg.domElement);
}
YAHOO.util.Dom.removeClass(rcfg.domElement, 'read');
rcfg.recentlyread = true;
YAHOO.util.Dom.addClass(rcfg.domElement, 'recentlyread');
break;
}
}
this.updateUncollapser();
};
FIRSTCLASS.layout.Thread.prototype.suppressReadItems = function() {
for (var i = this.rowmap.length-1; i > 0; i--) {
var rcfg = this.rowDefs[this.rowmap[i]];
var recentlyread = rcfg.recentlyread;
if (rcfg.row.status.unread == 0 && !recentlyread) {
this.contentsElement.removeChild(rcfg.domElement);
}
}
YAHOO.util.Dom.addClass(this.domElement, 'suppressreaditems');
if (this.tconfig.hideThreadBody) {
YAHOO.util.Dom.addClass(this.contentsElement, "fcListViewHiddenThreadBody");
}
};
FIRSTCLASS.layout.Thread.prototype.updateThreadHeader = function(row, div) {
var that = this, i, inserted, recentlyread, retval = 1, hdr = this.threadHead;
if (this.tconfig.originRowIsHeader && div) {
//YAHOO.util.Event.purgeElement(hdr, true);
//var d = FIRSTCLASS.ui.Dom.clearElementChildren(hdr);
if (hdr.firstChild) {
recentlyread = YAHOO.util.Dom.hasClass(hdr.firstChild, 'recentlyread');
if (this.tconfig && this.tconfig.collapseRead && this._headerRow.status.unread == 0 && !recentlyread) {
// don't insert
FIRSTCLASS.ui.Dom.clearElementChildren(hdr);
} else if (this.contentsElement.firstChild) {
var insertBefore = 0;
for (i = 0; i < this.rowmap.length; i++) {
if (this.tconfig.sortfunc(this.rowDefs[this.rowmap[i]].row, this._headerRow) < 0) {
insertBefore = i;//this.rowmap[i];
break;
}
}
inserted = false;
for (i = insertBefore; i < this.rowmap.length; i++) {
if (this.rowDefs[this.rowmap[i]].domElement && this.rowDefs[this.rowmap[i]].domElement.parentNode == this.contentsElement) {
this.contentsElement.insertBefore(hdr.firstChild, this.rowDefs[this.rowmap[i]].domElement);
inserted = true;
break;
}
}
if (!inserted) {
this.contentsElement.appendChild(hdr.firstChild);
}
// insertBefore = this.rowDefs[this.rowmap[insertBefore]];
// this.contentsElement.insertBefore(hdr.firstChild, this.contentsElement.firstChild);
} else {
this.contentsElement.appendChild(hdr.firstChild);
}
}
hdr.appendChild(div);
// FIRSTCLASS.ui.Dom.reparentNode(div,hdr);
if (this.isQuestion(row)) {
YAHOO.util.Dom.addClass(hdr.parentNode, "fcThreadQuestion");
} else {
YAHOO.util.Dom.addClass(hdr.parentNode, "fcThreadTopic");
}
retval = 2;
} else if (!this.tconfig.originRowIsHeader) {
var html = [""], curDate;
if (this.tconfig.formatter) {
html.push(this.tconfig.formatter(row));
} else {
switch (this.tconfig.format) {
case FIRSTCLASS.layout.ThreadHandler.types.THREAD:
html.push(row.subject);
break;
case FIRSTCLASS.layout.ThreadHandler.types.COLUMN:
if (this.tconfig.coltype && this.tconfig.coltype == FIRSTCLASS.layout.ThreadHandler.coltypes.FRIENDLYDATE) {
curDate = new Date();
curDate.setTime(Date.parse(this.threadid));
html.push(FIRSTCLASS.util.Date.getFriendlyDateString(curDate));
} else {
html.push(this.threadid);
}
break;
case FIRSTCLASS.layout.ThreadHandler.types.NONE:
break;
//case FIRSTCLASS.layout.ThreadHandler.types.DATE:
default:
curDate = new Date();
curDate.setTime(row.lastmods*1000);
curDate.setHours(0);
curDate.setMinutes(0);
curDate.setSeconds(0);
html.push(FIRSTCLASS.util.Date.getFriendlyDateString(curDate));
//hdr.date = curDate;
break;
}
}
html.push("
");
hdr.innerHTML = html.join("");
}
if (this.tconfig.collapseRead && ! this._uncollapser) {
this._uncollapser = document.createElement("div");
YAHOO.util.Dom.addClass(this._uncollapser, 'uncollapser');
hdr.appendChild(this._uncollapser);
} else if (this.tconfig.collapseRead && this._uncollapser) {
hdr.appendChild(this._uncollapser);
}
this._headerRow = row;
this.updateUncollapser();
//YAHOO.util.Event.purgeElement(hdr, false);
/*YAHOO.util.Event.addListener(hdr, "click", function(evt) {
if (that._headerRow && that.rowHandler.onRowClick) {
that.rowHandler.onRowClick(that._headerRow, hdr.firstChild);
}
});*/
return retval;
};
FIRSTCLASS.layout.Thread.prototype.removeRow = function(row) {
var rcfg = this.rowDefs[row.uid], i;
if (rcfg) {
delete this.rowDefs[row.uid];
if (rcfg.domElement) {
rcfg.domElement.parentNode.removeChild(rcfg.domElement);
YAHOO.util.Dom.removeClass(rcfg.domElement, 'lastthreaditem');
}
YAHOO.util.Dom.addClass(this.contentsElement.lastChild, 'lastthreaditem');
if (rcfg.domElement) {
YAHOO.util.Event.purgeElement(rcfg.domElement, true);
}
for (i = 0; i < this.rowmap.length; i++) {
if (this.rowmap[i] == row.uid) {
this.rowmap.splice(i,1);
if (i == 0) {
if (this.rowmap.length == 0) {
break;// delete the thread
} else {
rcfg = this.rowDefs[this.rowmap[0]];
if (!rcfg.domElement) {
rcfg.domElement = this.rowHandler.createRow(rcfg.row);
rcfg.domElement.id = rcfg.row._listViewID;
}
this.updateThreadHeader(rcfg.row,rcfg.domElement);
}
}
if (i < this.currentSelection) {
this.currentSelection--;
}
break;
}
}
if (this.rowmap.length == 0) {
return 2;
// no more elements, remove this thread
}
return 1; // removed the row successfully
}
return 0; // row wasn't in the thread
};
FIRSTCLASS.layout.Thread.prototype.handleRow = function(row, div, dontsort, isNew) {
if (!this._sortRow) {
this._sortRow = row;
}
var rv = 1; // ok
if (row != this._headerRow) {
YAHOO.util.Dom.removeClass(this.threadHead, "fcThreadNoReplies");
}
var def = this.rowDefs[row.uid];
if (def) {
if (!def.recentlyread && YAHOO.util.Dom.hasClass(def.domElement, 'recentlyread')) {
def.recentlyread = true;
}
if (!this._headerRow || this._headerRow.uri == row.uri) {
this.updateThreadHeader(row, div);
}
} else {
// adding row
var rcfg = {"row":row, "domElement":div};
this.rowDefs[row.uid] = rcfg;
var insertBefore = false;
var i = 0;
if (!dontsort) {
for (i = 0; i < this.rowmap.length; i++) {
if (this.tconfig.sortfunc(this.rowDefs[this.rowmap[i]].row, row) > 0) {
insertBefore = this.rowmap[i];
break;
}
}
} else {
i = this.rowmap.length;
}
if (this.tconfig.originRowIsHeader && i == 0) {
this.rowmap.splice(i, 0, row.uid);
if (this.threadHead) {
this.updateThreadHeader(row, div);
}
} else if (insertBefore) {
this.rowmap.splice(i, 0, row.uid);
if (this.tconfig && this.tconfig.collapseRead && row.status.unread == 0) {
// don't insert
} else if (this.tconfig && this.tconfig.collapseRead && row.status.unread == 1) {
this.contentsElement.appendChild(div);
} else {
this.contentsElement.insertBefore(div, this.rowDefs[insertBefore].domElement);
}
if (insertBefore <= this.currentSelection) {
this.currentSelection++;
}
} else {
this.rowmap[this.rowmap.length] = row.uid;
if (this.tconfig && this.tconfig.collapseRead && row.status.unread == 0 && !isNew) {
// don't insert
} else {
if (isNew) {
YAHOO.util.Dom.removeClass(div, 'read');
rcfg.recentlyread = true;
YAHOO.util.Dom.addClass(div, 'recentlyread');
}
this.contentsElement.appendChild(div);
}
}
YAHOO.util.Dom.removeClass(this.contentsElement.childNodes, 'lastthreaditem');
YAHOO.util.Dom.addClass(this.contentsElement.lastChild, 'lastthreaditem');
}
this.updateUncollapser();
return rv;
};
FIRSTCLASS.layout.Thread.prototype.handleFullThread = function(thread) {
var row, r, rcfg, isheader, i;
this._sortRow = thread[0];
if (this.tconfig.sortfunc) {
thread.sort(this.tconfig.sortfunc);
}
for (i in thread) {
row = thread[i];
rcfg = {"row":row};
isheader = false;
if (thread.length == 1) {
isheader = true;
} else {
isheader = (i == 0);
}
if (!isheader && this.tconfig && this.tconfig.collapseRead && row.status.unread == 0) {
this.rowDefs[row.uid] = rcfg;
this.rowmap[this.rowmap.length] = row.uid;
// don't make the row unless it's the header
} else {
rcfg.domElement = this.rowHandler.createRow(row);
rcfg.domElement.id = row._listViewID;
this.handleRow(row, rcfg.domElement, true);
}
}
/*if (this.tconfig.sortfunc) {
var that = this;
var sortfunc = function(row1, row2) {
return -1*that.tconfig.sortfunc(that.rowDefs[row1].row, that.rowDefs[row2].row);
};
this.rowmap.sort(sortfunc);
}*/
this.updateUncollapser();
if (this.tconfig.blogThreading) {
for (i in this.rowmap) {
r = this.rowDefs[this.rowmap[i]].row;
if (r.typedef.objtype == FIRSTCLASS.objTypes.odocument || r.typedef.objtype == FIRSTCLASS.objTypes.formdoc) {
// not versioned, return the formdoc
this._sortRow = r;
break;
}
}
}
};
FIRSTCLASS.layout.Thread.prototype.sortRow = function() {
if (this._sortRow) {
return this._sortRow;
}
var row = this.rowDefs[this.rowmap[this.rowmap.length-1]].row, r, i;
if (this.tconfig.originRowIsHeader) {
r = this.rowDefs[this.rowmap[0]].row;
if (r.typedef.objtype == FIRSTCLASS.objTypes.fcfile
|| r.typedef.objtype == FIRSTCLASS.objTypes.file
|| r.typedef.objtype == FIRSTCLASS.objTypes.odocument) {
row = r;
}
}
if (this.tconfig.blogThreading) {
for (i in this.rowmap) {
r = this.rowDefs[this.rowmap[i]].row;
if (r.typedef.objtype == FIRSTCLASS.objTypes.odocument || r.typedef.objtype == FIRSTCLASS.objTypes.formdoc) {
// not versioned, return the formdoc
return r;
}
}
}
if (this.tconfig.originRowIsSort) {
row = this.rowDefs[this.rowmap[0]].row;
}
if (!row) {
row = this.initRow;
}
return row;
};
YAHOO.register("fcThread", FIRSTCLASS.layout.Thread, {version: "1.0.0", build: "1"});