// History.js - implements an item history viewer // history configuration: // domEl - element to install into // dataSource - current data source // dsRow - row of owning item // toolbar - toolbar for selected item // scrolling - this view scrolls on its own FIRSTCLASS.apps.history = function(config) { this._domEl = config.domElement; this._ds = config.dataSource; this._dsr = config.dsRow; this._toolbar = config.toolbar; var that = this; var html = []; this._versByDate = []; // array of version dates, keyed by version this._commDates = []; // array of comment dates, keyed by messageid this._versTypes = []; this._versTypes[FIRSTCLASS.objTypes.file] = true; this._versTypes[FIRSTCLASS.objTypes.formdoc] = true; this._versTypes[FIRSTCLASS.objTypes.odocument] = true; this._versTypes[FIRSTCLASS.objTypes.fcfile] = true; this.calcVersionID(this._dsr); // item template if (!FIRSTCLASS.apps.history._rowTemplateEl) { FIRSTCLASS.apps.history._rowTemplateEl = document.createElement("div"); var template = []; template.push(""); template.push(""); template.push(""); template.push(""); template.push(""); template.push(""); template.push("
"); template.push("
"); template.push(""); template.push("
"); template.push("
 
"); template.push("
"); template.push("
"); template.push("
"); template.push("
"); FIRSTCLASS.apps.history._rowTemplateEl.innerHTML = template.join(""); } this._lvEl = document.createElement("div"); this._domEl.appendChild(this._lvEl); this._newMessageInlineElement = document.createElement("div"); YAHOO.util.Dom.addClass(this._newMessageInlineElement, 'fcInlineComposeMessage'); this._domEl.appendChild(this._newMessageInlineElement); if (config.scrolling) { YAHOO.util.Dom.addClass(this._lvEl, "fcHistoryList"); } YAHOO.util.Dom.addClass(this._lvEl, "fcDiscloseSingleLine"); // version mapper listener this._mapProc = { onRow: function(row) { if (that.rowFilter(row) && (row.typedef.objtype == that._dsr.typedef.objtype)) { that.calcVersionID(row); } } }; this._ds.addRowListener(this._mapProc); var mapCallback = { completed: function() { if (that._mapProc) { // remove mapper listener that._ds.removeRowListener(that._mapProc); // add row preprocessor listener that._rowProc = { onRow: function(row) { if (that.rowFilter(row) && (row.typedef.objtype == that._dsr.typedef.objtype)) { that.calcVersionID(row); } } }; that._commDates = []; that._ds.addRowListener(that._rowProc); that._ds.fetchRowsByThread(that._dsr.threadid, mapCallback); that.createListView(); that._selRow = null; that._mapProc = null; } } }; this._ds.activate(); this._ds.fetchRowsByThread(this._dsr.threadid, mapCallback); }; // instantiate the list view once the data is in FIRSTCLASS.apps.history.prototype.createListView = function() { if (!this._lv) { var that = this; var lvConfig = { rowHandler: this, domElement: this._lvEl, dataSource: this._ds, fillOnScroll: false, threading: { format: "bycolumn", column: "versionID", sortfunc: function(row1, row2) { return that.commentSort(row1, row2); }, threadsortfunc: function(row1, row2) { return that.versionSort(row1, row2); }, originRowIsHeader: true, collapseRead: true, displayThreadContributors: true }, listenForNavKeys: true, selectionFollowsScroll: false, rowFilter: function(row) { return that.rowFilter(row); }, drawOffScreen: false }; this._myFeed = new FIRSTCLASS.layout.Feed( { allowReplies: false, listView: null, dataSource: this._ds, thumbnailClickLoadsItem: true }); this._lv = new FIRSTCLASS.layout.ListView(lvConfig); this._myFeed.listView = this._lv; // punch in after // replace feed toolbar if one is passed in if (this._toolbar) { this._myFeed.toolBarDomElement.innerHTML = ""; this._myFeed.toolBar = new FIRSTCLASS.ui.toolBar({ domElement: this._myFeed.toolBarDomElement, buttons: this._toolbar }); } this.activate(); } }; // history vars FIRSTCLASS.apps.history.prototype._domEl = null; FIRSTCLASS.apps.history.prototype._ds = null; FIRSTCLASS.apps.history.prototype._dsr = null; FIRSTCLASS.apps.history.prototype._lv = null; FIRSTCLASS.apps.history.prototype._commEl = null; FIRSTCLASS.apps.history.prototype._versEl = null; // history functions FIRSTCLASS.apps.history.prototype.rowFromEvent = function(evt){ var tg = evt.target; if (!tg) { tg = evt.srcElement; } if (tg && this._lv) { var row = this._lv._rowmap[tg.id]; while (tg && !row && tg !== this._lv.contentsDomElement) { tg = tg.parentNode; row = this._lv._rowmap[tg.id]; } if (row) { return {"el":tg, "row":row}; } else { return null; } } else { return null; } }; FIRSTCLASS.apps.history.prototype.createRow = function(row) { var myRowEl = document.createElement("div"); var table = FIRSTCLASS.apps.history._rowTemplateEl.firstChild.cloneNode(true); var html = "
"; myRowEl.innerHTML = html; myRowEl = myRowEl.firstChild; myRowEl.appendChild(table); this.updateRow(row, myRowEl); return myRowEl; }; FIRSTCLASS.apps.history.prototype.updateRow = function(row, element, oldrow) { var html = []; var img = {}; var itemstr = null; // unread handling if (row.status.unread) { YAHOO.util.Dom.addClass(element, "unread"); } else { YAHOO.util.Dom.removeClass(element, "unread"); if (oldrow && oldrow.status.unread) { YAHOO.util.Dom.addClass(element, "recentlyread"); } } var table = element.firstChild; var messageDomElement = table.childNodes[0].childNodes[2].childNodes[1].childNodes[0].childNodes[0].childNodes[1].childNodes[0].childNodes[0]; YAHOO.util.Dom.addClass(messageDomElement,"fcMessageContents"); var imgDomElement = table.childNodes[0].childNodes[2].childNodes[1].childNodes[0].childNodes[0].childNodes[0].childNodes[0].childNodes[0]; var versDomElement = table.childNodes[0].childNodes[1].childNodes[1]; var toolBarDomElement = FIRSTCLASS.ui.Dom.getChildByClassName('fclvrowtoolbar', table); YAHOO.util.Dom.addClass(toolBarDomElement,"fcMessageToolBar"); // version var version = 1; if (row.col8090) { version = row.col8090; } var latest = (row.messageid == this._dsr.messageid) ? true : false; var isVersion = this._versTypes[row.typedef.objtype] ? true : false; if (isVersion) { itemstr = FIRSTCLASS.locale.history.version; itemstr = itemstr.replace("$version$",version); if (latest) { itemstr += FIRSTCLASS.locale.history.latest; } versDomElement.innerHTML = itemstr; } // name, date, action html = []; var nameEl = table.childNodes[0].childNodes[2].childNodes[1].childNodes[0].childNodes[0].childNodes[0].childNodes[1].lastChild; itemstr = null; switch (row.typedef.objtype) { case FIRSTCLASS.objTypes.file: // a document or external document case FIRSTCLASS.objTypes.fcfile: case FIRSTCLASS.objTypes.formdoc: if (version == 1) { itemstr = FIRSTCLASS.locale.history.uploaded; } else { itemstr = FIRSTCLASS.locale.history.updated; } break; case FIRSTCLASS.objTypes.odocument: // a wiki if (version == 1) { itemstr = FIRSTCLASS.locale.history.created; } else { itemstr = FIRSTCLASS.locale.history.updated; } break; default: // treat as a comment itemstr = FIRSTCLASS.locale.history.commented; break; } var nm = row.name; if (row.col8082) { nm = row.col8082; } if (row.creatorcid) { html.push("
 "); } else { html.push("
"); } html.push(nm); html.push("
"); nameEl.innerHTML = itemstr.replace("$name$",html.join("")).replace("$date$", "
" + FIRSTCLASS.util.Date.getFriendlyDateTimeString(row.lastmods) + "
"); // author image var picurl = ""; var cid = false; if (row.itemdata && row.itemdata.from) { picurl = FIRSTCLASS.util.User.getSmallProfPicUrlByCid(row.itemdata.from[0].cid); cid = row.itemdata.from[0].cid; } else if (row.creatorcid) { picurl = FIRSTCLASS.util.User.getSmallProfPicUrlByCid(row.creatorcid); cid = row.creatorcid; } else { picurl = FIRSTCLASS.util.User.getSmallProfPicUrlByName(nm); } picurl += "&WidthAA=20&HeightAA=27"; if (row.status.unread) { YAHOO.util.Dom.setStyle(imgDomElement, 'background-image', "url("+picurl+")"); } else { YAHOO.util.Dom.setStyle(imgDomElement, 'background-image', ""); img = document.createElement("img"); img.src = picurl; img.setAttribute('fcid', 'user'); img.setAttribute('fcattrs', nm); if (cid) { img.setAttribute('uid', cid); } YAHOO.util.Dom.addClass(img,'fcHistProfPic'); YAHOO.util.Dom.removeClass(img, 'fcHistPicUnread'); imgDomElement.removeChild(imgDomElement.lastChild); imgDomElement.appendChild(img); } // body/comment html = []; if (row.typedef.objtype == this._dsr.typedef.objtype) { // use comment if any if (row.col8101) { html.push(FIRSTCLASS.lang.mlesc(row.col8101)); } } else if (row.itemdata) { if (row.itemdata.expandedBody) { html.push(row.itemdata.expandedBody); } } else if(row.col8063 && row.col8063 !== "") { html.push(row.expandedPreview); } if (html.length) { messageDomElement.innerHTML = html.join(""); var imgs = messageDomElement.getElementsByTagName("IMG"); for (var i = 0; i < imgs.length; i++) { img = imgs[i]; YAHOO.util.Dom.setStyle(img, "height", "auto"); } } }; FIRSTCLASS.apps.history.prototype.onRowClick = function(row, elem) { this._myFeed.onRowClick(row, elem); }; FIRSTCLASS.apps.history.prototype.onSelectionChange = function(from, to, torow, fromrow) { this._selRow = torow; this._myFeed.onSelectionChange(from, to, torow, fromrow); }; FIRSTCLASS.apps.history.prototype.onCancel = function() { this._newMessageInlineElement.innerHTML = ""; var Y = YAHOO.util.Dom.getY(this._lvEl); var ht = YAHOO.util.Dom.getViewportHeight(); YAHOO.util.Dom.setStyle(this._lvEl, 'height', ht-Y + "px"); }; FIRSTCLASS.apps.Discussion.prototype.onSave = function() { this.onCancel(); }; FIRSTCLASS.apps.history.prototype.handleEvent = function(evt, fcevent) { var rv = false; if (this._lv) { rv = this._lv.thandler.handleEvent(evt, fcevent); } if (this._myFeed && !rv) { rv = this._myFeed.handleEvent(evt, fcevent); } return rv; }; FIRSTCLASS.apps.history.prototype.generateUniqueId = function(row) { return row.messageid; }; FIRSTCLASS.apps.history.prototype.activate = function() { if (this._lv) { this._lv.activate(); } this._ds.activate(); }; FIRSTCLASS.apps.history.prototype.deactivate = function() { if (this._lv) { this._lv.deactivate(); } this._ds.deactivate(); }; FIRSTCLASS.apps.history.prototype.dispose = function() { this.deactivate(); if (this._lv) { this._lv.dispose(); } if (this._rowProc) { this._ds.removeRowListener(this._rowProc); } }; FIRSTCLASS.apps.history.prototype.rowFilter = function(row) { var allow = false; if (this._dsr) { // only allow original thread if (row.threadid == this._dsr.threadid) { // calculate versionID if (row.typedef.objtype == this._dsr.typedef.objtype) { allow = true; } else { // keep date list of comments and suppress duplicates if (this._commDates[row.messageid]) { allow = false; } else { allow = true; this._commDates[row.messageid] = row.lastmods; } } } } if (row.status && row.status.deleted) { allow = false; } // new row not yet saved if ((row.typedef.objtype == FIRSTCLASS.objTypes.odocument) && !row.col8082) { allow = false; } return allow; }; FIRSTCLASS.apps.history.prototype.versionSort = function(row1, row2) { if (row1.versionID > row2.versionID) { return -1; } else if (row1.versionID < row2.versionID) { return 1; } else { return 0; } }; // return a row of the primary objtype with versionID matching passed-in value FIRSTCLASS.apps.history.prototype.getRowByVersion = function(version) { var result = false; if (this._versByDate && this._versByDate[version]) { result = this._versByDate[version]; } return result; }; // calculate "versionID" and add to row - actually the date of the most recent version preceding the row FIRSTCLASS.apps.history.prototype.calcVersionID = function(row) { // if it's a version, add to version map and set version id to item's version number if (row.typedef.objtype == this._dsr.typedef.objtype) { row.versionID = row.col8090; if (this._versByDate[row.col8090]) { if (row.lastmods > this._versByDate[row.col8090].lastmods) { this._versByDate[row.col8090] = row; } } else { this._versByDate[row.col8090] = row; } } else { var vers = this._dsr.col8090, i = 1; // if there are versions, choose the most recent prior to the comment while (i <= this._dsr.col8090) { if (this._versByDate[i] && (this._versByDate[i].lastmods > row.lastmods)) { break; } if (this._versByDate[i]) { vers = i; } i++; } row.versionID = vers; } }; FIRSTCLASS.apps.history.prototype.onRowClick = function(row, domElement) { if (this._lv) { this._lv.changeSelection(domElement, false, true); } }; FIRSTCLASS.apps.history.prototype.commentSort = function(row1, row2) { // sort versions above comments if (row1.typedef.objtype != row2.typedef.objtype) { if (row1.typedef.objtype == this._dsr.typedef.objtype) { return -1; } if (row2.typedef.objtype == this._dsr.typedef.objtype) { return 1; } } // rank comments in date order if (row1.lastmods < row2.lastmods) { return 1; } else if (row1.lastmods > row2.lastmods) { return -1; } else { return 0; } };