/** * Class Description * @namespace FIRSTCLASS.util * @module DataSource * @requires yahoo dom event connection logger json * @optional * @title Data Source */ /** * Constructor definition * @class DataSource * @constructor * @param {Object} config a configuration object for this DataSource * @param {string} config.containerBaseUrl (required) the url for the container to open * @param {number} config.requestGranularity (optional) the number of items to fetch by default */ FIRSTCLASS.util.DataSource = function(config) { if (config.logTime) { config.logTime("New DataSource containerBaseUrl: \"" + config.containerBaseUrl +"\""); } var that = this; this._rowListeners = []; this._dataListeners = []; this._isFilled = false; this._isRefilling = false; this._isFetching = false; this._newDataInterval = null; this._config = { requestGranularity: 20, pollRequestGranularity: 5, temporaryPollRequestGranularity: 5, requestType:"GET", defaultRequestGranularity: 20, pluginStr: "Templates=JS&JSON=2", active: true, docbodies: false, messagebodies: false, serversort: "&Table=-0_0", itemrequest: true, pollInterval: 5000, fetchNewDelay: 100, fetchThreads: false, tackon: "" }; for (var i in config) { this._config[i] = config[i]; } if (config.isSameRow) { this.compareRows = config.isSameRow; } if (config.prePopulateData) { this._data = config.prePopulateData; this._config.dataPreLoaded = true; } if (config.useobjid) { this._config.useobjid = true; } if (config.paramStr) { this._config.paramStr = config.paramStr; } this._state = {currentDataIndex:1, requestGranularity: this._config.requestGranularity, hasMoreRows: true}; this._unreadState = {currentDataIndex:0, requestGranularity: this._config.requestGranularity}; this._watchState = {currentDataIndex:0, requestGranularity: this._config.requestGranularity, timeout:false, fetching: false}; this._objTypeState = {currentDataIndex:0, requestGranularity: this._config.requestGranularity, hasMoreRows: true}; if (config.symbioticDataSource) { this._config.symbioticDataSource = config.symbioticDataSource; this._config.symbioticDataSource.dataSource.addDataListener({ onHeaderData:function(data, contents) { switch (data) { case that._config.symbioticDataSource.key: that.loadData(contents, that._state); break; default: } }, filter: function(dataname) { switch (dataname) { case that._config.symbioticDataSource.key: return true; default: return false; } } }); } this.start(); }; FIRSTCLASS.util.DataSource.prototype.start = function() { if (this._config.loadUnreadImmediate) { this.fetchUnreadRows(); } else if (this._config.reloadFullOnPoll) { this._config.autoLoad = true; this.refillTimeout = window.setTimeout(function() { that.reFill() }, this._config.pollInterval); this.performFill(); } else if (this._config.loadFull) { this.performFill(); } else if (this._config.objTypePriority) { this.fetchRowsByObjType(this._config.objTypePriority, this._config.backVersionsImmediate); } else if (this._config.fetchThreadID) { this.fetchRowsByThread(this._config.fetchThreadID); } else if (!this._config.dataPreLoaded && !this._config.symbioticDataSource) { this.fetchRows(); } }; FIRSTCLASS.util.DataSource.prototype.close = function() { if (!this._config.masterDS) { var baseUrl = this._config.containerBaseUrl; if (this._config.useobjid && this._data && this._data.objid) { baseUrl = FIRSTCLASS.session.baseURL + "__OBJID_" + this._data.objid + "/"; } if (baseUrl.indexOf("?") >= 0) { baseUrl += "&"; } else { baseUrl += "?"; } baseUrl += "Close=0"; var tmpConnManagerRequest = YAHOO.util.Connect.asyncRequest("GET",baseUrl); } }; FIRSTCLASS.util.DataSource.prototype.open = function() { if (!this._config.masterDS && this._data) { this._data.objid = false; this.fetchRows(false, false, {startIndex:0,endIndex:1}); /* var baseUrl = this._config.containerBaseUrl; if (this._config.useobjid && this._data && this._data.objid) { baseUrl = FIRSTCLASS.session.baseURL + "__OBJID_" + this._data.objid + "/"; } if (baseUrl.indexOf("?") >= 0) { baseUrl += "&"; } else { baseUrl += "?"; } baseUrl += "Close=0"; var tmpConnManagerRequest = YAHOO.util.Connect.asyncRequest("GET",baseUrl);*/ } }; FIRSTCLASS.util.DataSource.prototype.dispose = function() { this.deactivate(); this.clearRowListeners(); this.clearDataListeners(); this._data = null; window.clearTimeout(this.refillTimeout); }; /** * Create a "slave" dataSource from this one, set up to read data on its own, but to * perform list-level updates through the master. Config just overrides master config, * with watch and auto load functions disabled. * * If this ds is a slave itself, a new peer slave to the master DS is created. * * Live updates are handled by listening to the master DS. **/ FIRSTCLASS.util.DataSource.prototype.createSlave = function(config) { if (this._config.masterDS) { return this._config.masterDS.createSlave(config); } var newDS = null; var newCfg = {}; FIRSTCLASS.lang.deepCopyObjData(newCfg, this._config); FIRSTCLASS.lang.deepCopyObjData(newCfg, config); var newData = {}; if (this._data) { var rtmp = this._data.records; this._data.records = []; FIRSTCLASS.lang.deepCopyObjData(newData, this._data); this._data.records = rtmp; } newData.records = []; newCfg.autoLoad = false; newCfg.prePopulateData = newData; newCfg.watchForNew = false; newCfg.watchForTinkle = false; newCfg.masterDS = this; newCfg.dataPreLoaded = true; newDS = new FIRSTCLASS.util.DataSource(newCfg); newDS._rowQueue = []; newDS._rowQueueNewDel = false; if (newDS) { // listener functions newDS.onRow = function(row, isNewDelivery) { if (!this.filter || this.filter(row)) { var newRow = {}; FIRSTCLASS.lang.deepCopyObjData(newRow, row); newRow.mRow = row; // keep master-row pointer this._rowQueue.push(newRow); if (isNewDelivery) { this._rowQueueNewDel = true; } } }; newDS.onRowChanged = function(row) { if (!this.filter || this.filter(row)) { var newRow = {}; FIRSTCLASS.lang.deepCopyObjData(newRow, row); newRow.mRow = row; var rowDeltas = {}; rowDeltas.records = []; rowDeltas.records.push(newRow); this.loadData(rowDeltas, this._watchState); } }; newDS.onRowsChanged = function(rows) { var rowDeltas = { records: [] }; var row = {}; for (var i in rows) { row = rows[i]; var newRow = {}; FIRSTCLASS.lang.deepCopyObjData(newRow, row); newRow.mRow = row; if (!this.filter || this.filter(row)) { rowDeltas.records.push(newRow); } } this.loadData(rowDeltas, this._watchState); }; newDS.onRowDeleted = function(row) { if (this._data && this._data.records) { for (var i = 0; i < this._data.records.length; i++) { if (this.compareRows(row, this._data.records[i])) { this._data.records[i].status.deleted = true; this.notifyRowDeleted(this._data.records[i]); } } } }; newDS.fillFinished = function() { if (this._rowQueue.length > 0) { var newData = {}; newData.records = this._rowQueue; this._rowQueue = []; this.loadData(newData, this._rowQueueNewDel ? this._watchState : this._objTypeState); this._rowQueueNewDel = false; } }; this.addRowListener(newDS, true); } return newDS; }; /** * Public static variables definitions */ FIRSTCLASS.util.DataSource.objTypeToUrlParameter = function(objType) { switch (objType) { case FIRSTCLASS.objTypes.odocument: case FIRSTCLASS.objTypes.formdoc: return "Documents"; case FIRSTCLASS.objTypes.file: case FIRSTCLASS.objTypes.fcfile: return "Files"; default: return "Both"; } }; FIRSTCLASS.util.DataSource.prototype.deactivate = function() { this.writeLog("DataSource deactivating"); this._config.active = false; if (this._watchState.connManagerRequest) { YAHOO.util.Connect.abort(this._watchState.connManagerRequest, null, false); this._watchState.connManagerRequest = null; this._watchState.fetching = false; } if (this._connManagerRequest) { YAHOO.util.Connect.abort(this._connManagerRequest, null, false); this._connManagerRequest = null; } }; FIRSTCLASS.util.DataSource.prototype.activate = function(firstactivate) { this.writeLog("DataSource activating, firstactivate: " + firstactivate); if (!this._config.active) { this._config.active = true; var that = this; if (this._config.watchForNew && this._watchState.watching) { this._watchState.timeout = window.setTimeout(function() { that.fetchNewRows(); that._watchState.timeout = false; }, this._config.pollInterval); } if (this._config.watchForTinkle && this._watchState.watching) { if (!firstactivate) { this.fetchRows(false, false, false, true); } this._watchState.timeout = window.setTimeout(function() { that.watchForTinkle(false, true); that._watchState.timeout = false; }, this._config.pollInterval); } } }; FIRSTCLASS.util.DataSource.prototype.isActive = function() { return this._config.active; }; FIRSTCLASS.util.DataSource.prototype.writeLog = function(message) { if (this._config.logTime) { this._config.logTime(message + " container: " + this._config.containerBaseUrl); } }; /** * generates an url to the data for the specified indices * * @Method DataSource.generateDataURL * @param {Object} config (required) an object that defines the request. * @param {int} config.startIndex (required) the first index to fetch * @param {int} config.endIndex (required) the last index to fetch * @return {string} the constructed url to the data */ FIRSTCLASS.util.DataSource.prototype.generateDataURL = function(config) { var date = new Date(); var param = "Both"; var paramStr = ""; var sortStr = "&Table=-0_0"; var showStr = "&Show=12"; var doFile = false, doDoc = false; if (typeof config.backVersions != "undefined" && !config.backVersions) { showStr = ""; } if (config.baseUrl.indexOf("Search") >= 0) { sortStr = "&Table=0_0"; } else if (this._config.serversort == false) { sortStr = "&Table=0_0"; } else if (this._config.serversort) { sortStr = this._config.serversort; } if (config.objType) { if (typeof config.objType == "number") { param = FIRSTCLASS.util.DataSource.objTypeToUrlParameter(config.objType) + "=1"; if (config.objType == FIRSTCLASS.objTypes.odocument) { doDoc = true; } else if (config.objType == FIRSTCLASS.objTypes.file) { doFile = true; } } else if (typeof config.objType == "object") { param = ""; for (var i = 0; i < config.objType.length; i++) { if (i != 0) { param += "&"; } param += FIRSTCLASS.util.DataSource.objTypeToUrlParameter(config.objType[i]) + "=1"; if (config.objType[i] == FIRSTCLASS.objTypes.odocument) { doDoc = true; } else if (config.objType[i] == FIRSTCLASS.objTypes.file) { doFile = true; } } } } if (config.allunread) { param = "Leaves"; } var indexStr = "1"; if (config.objType) { paramStr = "&" + param + "&NS=1"; if (doDoc) { if (doFile) { paramStr += "&ColFilter=0_(6)|8113_!()"; } else { paramStr += "&ColFilter=8113_()"; } } } else if (config.replyObjType) { paramStr = "&Leaves&Show=12&ColFilter=8091_(" + config.replyObjType + ")"; } else if (config.threadid) { var arr = config.threadid.split("-"); var threadid = arr[0] + "_" + arr[1]; paramStr = "&Leaves&Show=12&ColFilter=11_(" + threadid + ")"; } else if (config.loadFull) { paramStr = ""; /* if (config.notouch) { showStr = "&Show=12&Touch=1"; } else { showStr = "&Show=12&Touch=0"; }*/ showStr = "&Show=12&Touch=0"; } else if (typeof config.startIndex != "undefined" && typeof config.endIndex != "undefined") { var modifier = ""; if (this._config.fetchThreads) { modifier = "GR"; } if (config.endIndex > config.startIndex) { indexStr = modifier + config.startIndex + "-" + config.endIndex; } paramStr = "&" + param + "=" + indexStr; if (config.allunread) { paramStr += "&Filter=2" + sortStr; } else { paramStr += sortStr; } } else if (config.unread) { paramStr = "&Touch=1&Leaves&LD="; if (this._watchState.lastrow) { paramStr = "&LastRow=" + this._watchState.lastrow.messageid + paramStr; } if (false && this._config.fetchThreads) { sortStr = "&Table=-3_9"; paramStr = "&Touch=1&Leaves&BFThreads&LD="; } else { sortStr = "&Table=-0_0" } if (this._data) { paramStr += this._data.lastdelivery; } else { paramStr += "0"; } paramStr += sortStr; } else if (config.tinkle) { paramStr = "&Touch=1&TNKL="; if (this._data) { paramStr += this._data.lastupdate; } else { paramStr += "0"; } paramStr += sortStr; } else if (config.uri) { paramStr = "&Leaves=1&ColFilter=13_(" + config.uri + ")"; } else if (config.name) { paramStr = "&Leaves=1&ColFilter=9_(" + config.name + ")"; } else if (config.cid) { if (typeof config.cid == "string" && config.cid.indexOf("CID") == 0) { config.cid = config.cid.slice(3); } paramStr = "&Leaves=1&ColFilter=20_(" + config.cid + ")"; } else if (this._config.itemrequest) { paramStr = "&" + param + "=" + indexStr + sortStr; } else { paramStr = sortStr; } if (config.nosymbiosis) { paramStr += "&NS=1" } if (this._config.docbodies) { paramStr += "&DB=1"; } if (this._config.messagebodies) { paramStr += "&MB=1"; } var baseUrl = config.baseUrl; if (this._config.useobjid && this._data && this._data.objid) { baseUrl = FIRSTCLASS.session.baseURL + "__OBJID_" + this._data.objid + "/"; } if (baseUrl.indexOf("?") != -1) { baseUrl += "&"; } else { if (baseUrl.charAt(baseUrl.length - 1) != "/") { baseUrl = baseUrl + "/"; } baseUrl += "?"; } if (this._config.paramStr) { paramStr = this._config.paramStr + paramStr; } if (this._config.closeParam) { paramStr = paramStr + this._config.closeParam; } if (config.params) { paramStr = paramStr + config.params; } paramStr += "&TS=" + date.getTime(); if (this._config.isRadForm) { var url = baseUrl + this._config.pluginStr; if (this._config.paramStr) { url += this._config.paramStr; } return url + this._config.tackon; } return baseUrl + this._config.pluginStr + showStr + paramStr + this._config.tackon; }; /** * adds a row listener to the datasource, filling it if we already have data * * @Method DataSource.addRowListener * @param {Object} listener * @param {function} listener.onRow(row) (optional) a function that's called when a new row is added to the DataSource * @param {function} listener.onRowChanged(row) (optional) a function that's called when a row is modified in the DataSource * @param {function} listener.filter (optional) a row filter that checks to see if a row is allowed to be sent to the listener's onRow and onRowChanged callbacks (returns true/false) */ FIRSTCLASS.util.DataSource.prototype.hasMoreListeners = function() { return (this._rowListeners.length > 0 || this._dataListeners.length > 0); } FIRSTCLASS.util.DataSource.prototype.addRowListener = function(listener, suppressCatchup) { for (var i = 0; i < this._rowListeners.length; i++) { if (this._rowListeners[i] == listener) { return; } } this._rowListeners[this._rowListeners.length] = listener; if (this._data && this._data.records && listener.onRow && !suppressCatchup) { for (var j = 0; j < this._data.records.length; j++) { if (!listener.filter || listener.filter(this._data.records[j])) { listener.onRow(this._data.records[j], this, true, j < this._data.records.length-1); } } } if (listener.fillFinished && !suppressCatchup) { listener.fillFinished(false, true); } }; FIRSTCLASS.util.DataSource.prototype.removeRowListener = function(listener) { for (var i = 0; i < this._rowListeners.length; i++) { if (this._rowListeners[i] == listener) { this._rowListeners.splice(i,1); return; } } }; FIRSTCLASS.util.DataSource.prototype.clearRowListeners = function() { while(this._rowListeners.length > 0) { this._rowListeners.pop(); } } /** * calls the rowListeners' onRow function on a new row * * @Method DataSource.notifyNewRow * @param {Object} row (required) the new row */ FIRSTCLASS.util.DataSource.prototype.notifyNewRow = function(row, isNewDelivery) { this.writeLog("notifyNewRow called with: " + row.messageid); this.writeLog("notifyNewRow has: " + this._rowListeners.length + " listeners"); for (var i = 0; i < this._rowListeners.length; i++) { var listener = this._rowListeners[i]; if (typeof listener.onRow != "undefined" && (!listener.filter || listener.filter(row, isNewDelivery))) { listener.onRow(row, this, true, false); this.writeLog("notifyNewRows notifying with row: " + row.messageid); } if (listener.fillFinished) { listener.fillFinished(isNewDelivery); } this.writeLog("notifyNewRow finished!"); } }; /** * calls the rowListeners' onRow function on a set of new rows * * @Method DataSource.notifyNewRows * @param {Array} rows (required) the new rows */ FIRSTCLASS.util.DataSource.prototype.notifyNewRows = function(rows, atEnd, isNewDelivery) { this.writeLog("notifyNewRows called with: " + rows.length + " rows, iamslave: " + (typeof this._config.masterDS != "undefined")); this.writeLog("notifyNewRows has: " + this._rowListeners.length + " listeners"); for (var i = 0; i < this._rowListeners.length; i++) { var listener = this._rowListeners[i]; if (typeof listener.onThread != "undefined") { var threads = []; for (var j = 0; j < rows.length; j++) { this.writeLog("listener " + i + ", testing row: " + rows[j].messageid); if (!listener.filter || listener.filter(rows[j], isNewDelivery)) { if (threads[rows[j].threadid]) { threads[rows[j].threadid].push(rows[j]); } else { threads[rows[j].threadid] = [rows[j]]; } } } for (var j in threads) { this.writeLog("listener " + i + ", Notifying thread: " + j); listener.onThread(threads[j], isNewDelivery); } } else if (typeof listener.onRows !== "undefined") { var fRows = []; for (var j = 0; j < rows.length; j++) { this.writeLog("listener " + i + ", testing row: " + rows[j].messageid); if (!listener.filter || listener.filter(rows[(atEnd) ? j : rows.length - j - 1], isNewDelivery)) { fRows.push(rows[(atEnd) ? j : rows.length - j - 1]); this.writeLog("listener " + i + ", Notifying rows: " + fRows[fRows.length-1].messageid); } } if (fRows.length > 0) { listener.onRows(fRows, this, atEnd, rows.length > 10); } } else if (typeof listener.onRow != "undefined") { for (var j = 0; j < rows.length; j++) { this.writeLog("listener " + i + ", testing row: " + rows[j].messageid); if (!listener.filter || listener.filter(rows[(atEnd) ? j : rows.length - j - 1], isNewDelivery)) { this.writeLog("listener " + i + ", Notifying row: " + rows[(atEnd) ? j : rows.length - j - 1].messageid); listener.onRow(rows[(atEnd) ? j : rows.length - j - 1], this, atEnd, rows.length > 10); } } } if (listener.fillFinished) { listener.fillFinished(isNewDelivery); } this.writeLog("notifyNewRows finished"); } }; FIRSTCLASS.util.DataSource.prototype.fillPage = function(listener, pagenum, nperpage, cb) { if (this._data) { var startindex = (pagenum-1)*nperpage; var rowcount = 0; for (var i = 0; i < this._data.records.length && rowcount < pagenum*nperpage; i++) { if (!listener.filter || listener.filter(this._data.records[i],false)) { if (rowcount >= startindex) { listener.onRow(this._data.records[i], this, true); } rowcount++; } } if (listener.fillFinished) { listener.fillFinished(); } if (cb && cb.completed) { cb.completed(); } } }; /** * calls the rowListeners' onRowChanged function on a modified row * * @Method DataSource.notifyRowChanged * @param {Array} rows (required) the modified row */ FIRSTCLASS.util.DataSource.prototype.notifyRowChanged = function(row, oldrow) { this.writeLog("notifyRowChanged called with: " + row.messageid); this.writeLog("notifyRowChanged called with: " + this._rowListeners.length + " listeners"); for (var i = 0; i < this._rowListeners.length; i++) { var listener = this._rowListeners[i]; if (listener.onRowChanged && (!listener.filter || listener.filter(row))) { this.writeLog("notifyRowChanged notifying listener: " + i); listener.onRowChanged(row, this, oldrow); } if (listener.fillFinished) { listener.fillFinished(); } this.writeLog("notifyRowChanged finished!"); } }; FIRSTCLASS.util.DataSource.prototype.notifyRowsChanged = function(rows, oldrows) { this.writeLog("notifyRowsChanged called with: " + rows.length + " rows"); this.writeLog("notifyRowsChanged called with: " + this._rowListeners.length + " listeners"); for (var i = 0; i < this._rowListeners.length; i++) { var listener = this._rowListeners[i]; if (listener.onRowsChanged) { var allowedrows = []; if (listener.filter) { for (var j in rows) { if (listener.filter(rows[j])) { this.writeLog("notifyRowsChanged allowing: " + rows[j].messageid); allowedrows.push(rows[j]); } } } else { allowedrows = rows; } this.writeLog("notifyRowsChanged notifying listener with: " + allowedrows.length + " rows"); listener.onRowsChanged(allowedrows, this); } else if (listener.onRowChanged) { for (var j in rows) { if (listener.onRowChanged && (!listener.filter || listener.filter(rows[j]))) { this.writeLog("notifyRowsChanged notifying with row: " + rows[j].messageid); listener.onRowChanged(rows[j], this, oldrows[j]); } } } if (listener.fillFinished) { listener.fillFinished(); } this.writeLog("notifyRowsChanged finished!"); } }; /** * calls the rowListeners' onRowDeleted function on a deleted row * * @Method DataSource.notifyRowDeleted * @param {Array} rows (required) the modified row */ FIRSTCLASS.util.DataSource.prototype.notifyRowDeleted = function(row) { for (var i = 0; i < this._rowListeners.length; i++) { var listener = this._rowListeners[i]; if (listener.onRowDeleted) { listener.onRowDeleted(row, this); } if (listener.fillFinished) { listener.fillFinished(); } } }; /** * adds a container data listener to the datasource, filling it if we already have data * * @Method DataSource.addDataListener * @param {Object} listener * @param {function} listener.onHeaderData(data) (optional) a function that's called when new container data is received * @param {function} listener.filter (optional) a data filter that checks to see if the listener cares about a specific piece of data (returns true/false) */ FIRSTCLASS.util.DataSource.prototype.addDataListener = function(listener) { for (var i = 0; i < this._dataListeners.length; i++) { if (this._dataListeners[i] == listener) { return; } } this._dataListeners[this._dataListeners.length] = listener; if (listener.onHeaderData && this._data) { for (var key in this._data) { this.notifyHeaderData(key, this._data[key]); if (!listener.filter || listener.filter(key)) { listener.onHeaderData(this._data[key], this._data[this._data[key]]); } } } }; FIRSTCLASS.util.DataSource.prototype.clearDataListeners = function() { while(this._dataListeners.length > 0) { this._dataListeners.pop(); } } /** * calls the rowListeners' onHeaderData function on a modified row * * @Method DataSource.notifyHeaderData * @param {Array} rows (required) the modified row */ FIRSTCLASS.util.DataSource.prototype.notifyHeaderData = function(data, contents) { for (var i = 0; i < this._dataListeners.length; i++) { var listener = this._dataListeners[i]; if (typeof listener.onHeaderData != "undefined" && (!listener.filter || listener.filter(data))) { listener.onHeaderData(data, contents); } } }; FIRSTCLASS.util.DataSource.prototype.notifyChatInvites = function(invites) { for (var i = 0; i < invites.objids.length; i++) { this.notifyChatInvite(invites[i]); } }; FIRSTCLASS.util.DataSource.prototype.notifyChatInvite = function(invite) { for (var i = 0; i < this._dataListeners.length; i++) { var listener = this._dataListeners[i]; if (listener.onChatInvite) { listener.onChatInvite(invite); } } }; FIRSTCLASS.util.DataSource.prototype.getAcl = function() { if (this._config.masterDS) { return this._config.masterDS.getAcl(); } if (this._data && this._data.acl) { return this._data.acl; } else { return -1; } }; FIRSTCLASS.util.DataSource.prototype.getTags = function() { if (this._overrideTags) { return this._overrideTags; } else if (this._data && this._data.tags) { return this._data.tags; } else { return false; } }; FIRSTCLASS.util.DataSource.prototype.setTags = function(tags) { this.notifyHeaderData("tags", tags); this._overrideTags = tags; }; /** * fills the entire container, requestGranularity rows at a time * * @Method DataSource.performFill */ FIRSTCLASS.util.DataSource.prototype.performFill = function(granularity) { if (!granularity) { granularity = 100; } if (!this._isFilled || this._config.reloadFullOnPoll) { if (!this._config.loadFull) { this._config.autoLoad = true; this._state.requestGranularity = granularity; } this.fetchRows(); } }; FIRSTCLASS.util.DataSource.prototype.reFill = function() { this._isRefilling = true; this._state.hasMoreRows = true; if (this._config.reloadFullOnPoll) { this._state.currentDataIndex = 0; this._state.requestGranularity = 100; } else { this._state.requestGranularity = this._state.currentDataIndex; } this._state.currentDataIndex = 0; for (var i = 0; i < this._rowListeners.length; i++) { var listener = this._rowListeners[i]; if (listener.onRefill) { listener.onRefill(this); } } this.fetchRows(); var that = this; if (this._config.reloadFullOnPoll) { this.refillTimeout = window.setTimeout(function() { that.reFill(); }, this._config.pollInterval); } }; /** * fills the entire container of the selected objTypes, requestGranularity rows at a time * * @Method DataSource.performFill * @param {Array} objTypes (required) an array of objTypes to fill */ FIRSTCLASS.util.DataSource.prototype.performFillByObjType = function(objTypes) { if (!this._isFilled) { this.fetchRowsByObjType(objTypes); } }; FIRSTCLASS.util.DataSource.prototype.isLoading = function() { if (!this._connManagerRequest) { return false; } return YAHOO.util.Connect.isCallInProgress(this._connManagerRequest); }; /** * fetches more rows into the DataSource, as governed by this._config * * @Method DataSource.fetchRows */ FIRSTCLASS.util.DataSource.prototype.fetchRows = function(callbacks, ignorenosymbio, indices, notouch, ignoreactive) { this.writeLog("fetchRows called: " ); var that = this; if (this._isFilled || (!this._config.active && !ignoreactive)) { return; } if (!this._connManagerRequest || !this.isLoading()) { this.writeLog("fetchRows fetching"); if ((this._config.watchForNew || this._config.watchForTinkle) && this._watchState.fetching) { YAHOO.util.Connect.abort(this._watchState.connManagerRequest, null, false); that._watchState.connManagerRequest = null; this._watchState.wasfetching = true; } if (this._isFetching) { return; } else { this._isFetching = true;} this.writeLog("Fetching Rows " + this._state.currentDataIndex + " to " + (this._state.currentDataIndex+this._state.requestGranularity)); var urlcfg = { baseUrl: this._config.containerBaseUrl, startIndex: this._state.currentDataIndex }; if (notouch) { urlcfg.notouch = notouch; } if (indices) { urlcfg.startIndex = indices.startIndex; urlcfg.endIndex = indices.endIndex; } else { if (!this._config.reloadFullOnPoll) { var granularity = this._config.initialRequestGranularity; if (this._state.currentDataIndex != 1 || !granularity) { granularity = this._state.requestGranularity; } urlcfg.endIndex = urlcfg.startIndex+granularity; } if (this._config.loadFull || this._config.reloadFullOnPoll) { urlcfg.loadFull = true; } } if (this._config.nosymbiomainfetch && !ignorenosymbio) { urlcfg.nosymbiosis = true; } if (callbacks) { this._state.callbacks = callbacks; } this._connManagerRequest = YAHOO.util.Connect.asyncRequest(this._config.requestType, this.generateDataURL(urlcfg), { success: this.fetchRowsSuccess, failure: this.fetchRowsFailure, scope: this }); } }; FIRSTCLASS.util.DataSource.prototype.fetchRowsSuccess = function (response) { var that = this; var callbacks = this._state.callbacks; that.writeLog("DataSource received Success"); that._onSuccess(response, that._state); if (callbacks && callbacks.completed) { callbacks.completed(); } if (that._config.nosymbiomainfetch && !that._config.symbioseeded) { // perform fetch again, with symbiosis that.fetchRows({completed:function() {that._config.symbioseeded = true;}}, true); } that.writeLog("DataSource Finished Processing"); // we aborted the watch to fetch more rows, start it again if (that._config.watchForNew && that._watchState.wasfetching) { that._watchState.wasfetching = false; that._watchState.fetching = false; that.fetchNewRows(); } else if (that._config.watchForTinkle && that._watchState.wasfetching) { that._watchState.wasfetching = false; that._watchState.fetching = false; that.watchForTinkle(); } }; FIRSTCLASS.util.DataSource.prototype.fetchRowsFailure = function (response) { var that = this; var callbacks = this._state.callbacks; that._onFailure(response, that._state); if (callbacks && callbacks.failed) { callbacks.failed(); } }; /** * fetches more rows into the DataSource, as governed by this._config * * @Method DataSource.fetchRowsByObjType */ FIRSTCLASS.util.DataSource.prototype.fetchRowsByObjType = function(objType, backVersions) { var that = this; var objTypes = []; if (typeof objType === "string") { objTypes.push(objType); } else { objTypes = objType; } if (this._isFilled || !this._config.active) { return; } if (typeof backVersions == "undefined") { backVersions = true; } var connReq = YAHOO.util.Connect.asyncRequest(this._config.requestType, this.generateDataURL({ baseUrl: this._config.containerBaseUrl, startIndex: this._objTypeState.currentDataIndex + 1, objType: objTypes, backVersions: backVersions }), { success: this.fetchRowsByObjTypeSuccess, failure: this.fetchRowsByObjTypeFailure, scope: this } ); }; FIRSTCLASS.util.DataSource.prototype.fetchRowsByObjTypeSuccess = function(response) { this._onSuccess(response, this._objTypeState); }; FIRSTCLASS.util.DataSource.prototype.fetchRowsByObjTypeFailure = function(response) { this._onFailure(response, this._objTypeState); }; FIRSTCLASS.util.DataSource.prototype.fetchRowsByThread = function(threadID, callbacks) { var that = this; if (this._isFilled || !this._config.active) { return; } var urlcfg = { baseUrl: this._config.containerBaseUrl, threadid: threadID }; this.fetchRowsByThreadCallbacks = callbacks; var tmpConnManagerRequest = YAHOO.util.Connect.asyncRequest(this._config.requestType, this.generateDataURL(urlcfg), { success:this.fetchRowsByThreadSuccess, failure:this.fetchRowsByThreadFailure, scope:this } ); }; FIRSTCLASS.util.DataSource.prototype.fetchRowsByThreadSuccess = function(response) { var that = this; var callbacks = this.fetchRowsByThreadCallbacks;// = callbacks that._onSuccess(response, that._objTypeState); if (callbacks && callbacks.completed) { callbacks.completed(); } }; FIRSTCLASS.util.DataSource.prototype.fetchRowsByThreadFailure = function(response) { var that = this; var callbacks = this.fetchRowsByThreadCallbacks; that._onSuccess(response, that._objTypeState); if (callbacks && callbacks.completed) { callbacks.completed(); } } /** * fetches more rows into the DataSource, as governed by this._config * * @Method DataSource.fetchRows */ FIRSTCLASS.util.DataSource.prototype.fetchUnreadRows = function(callbacks) { var that = this; if (this._isFilled) { return; } this._state.fetchUnreadRowsCallbacks = callbacks; var tmpConnManagerRequest = YAHOO.util.Connect.asyncRequest(this._config.requestType, this.generateDataURL({ baseUrl: this._config.containerBaseUrl, allunread: true, startIndex: this._unreadState.currentDataIndex + 1, endIndex: this._unreadState.currentDataIndex+this._state.requestGranularity }), { success: this.fetchUnreadRowsSuccess, failure: this.fetchUnreadRowsFailure, scope: this } ); }; FIRSTCLASS.util.DataSource.prototype.fetchUnreadRowsSuccess = function (response) { var that = this; var callbacks = this._state.fetchUnreadRowsCallbacks; this._state.fetchUnreadRowsCallbacks = null; that._onSuccess(response, that._unreadState); if (callbacks && callbacks.completed) { callbacks.completed(); } }; FIRSTCLASS.util.DataSource.prototype.fetchUnreadRowsFailure = function (response) { var that = this; var callbacks = this._state.fetchUnreadRowsCallbacks; this._state.fetchUnreadRowsCallbacks = null; that._onFailure(response, that._unreadState); if (callbacks && callbacks.failed) { callbacks.failed(); } }; // get a row by name into the ds, and return it via callback FIRSTCLASS.util.DataSource.prototype.getRowByName = function(name, callback) { var that = this; if (this._isFilled && false) { this.getRowCompleted(true, "name", name, callback); } else { var tmpConnManagerRequest = YAHOO.util.Connect.asyncRequest(this._config.requestType, this.generateDataURL({ baseUrl: this._config.containerBaseUrl, name: name }), { success:function (response) { that._onSuccess(response, that._objTypeState); that.getRowCompleted(true, "name", name, callback); }, failure:function (response) { that._onFailure(response, that._objTypeState); that.getRowCompleted(false, "name", name, callback); } } ); }; return; }; // get a row by sys id into the ds, and return it via callback FIRSTCLASS.util.DataSource.prototype.getRowBySysid = function(sysid, callbacks) { var that = this; if (this._isFilled && false) { this.getRowCompleted(true, "uri", sysid, callback); } else { var tmpConnManagerRequest = YAHOO.util.Connect.asyncRequest(this._config.requestType, this.generateDataURL({ baseUrl: this._config.containerBaseUrl, uri: sysid }), { success:function (response) { that._onSuccess(response, that._objTypeState); that.getRowCompleted(true, "uri", sysid, callbacks); }, failure:function (response) { that._onFailure(response, that._objTypeState); that.getRowCompleted(false, "uri", sysid, callbacks); } } ); }; return; }; FIRSTCLASS.util.DataSource.prototype.getRowByCID = function(cid, callbacks) { var that = this; if (this._isFilled && false) { this.getRowCompleted(true, "cid", cid, callback); } else { var tmpConnManagerRequest = YAHOO.util.Connect.asyncRequest(this._config.requestType, this.generateDataURL({ baseUrl: this._config.containerBaseUrl, cid:cid }), { success:function (response) { that._onSuccess(response, that._objTypeState); that.getRowCompleted(true, "cid", cid, callbacks); }, failure:function (response) { that._onFailure(response, that._objTypeState); that.getRowCompleted(false, "cid", cid, callbacks); } } ); }; return; }; // grab the target row and call the callbacks on completion of a "getRowBy" function FIRSTCLASS.util.DataSource.prototype.getRowCompleted = function(success, column, key, callback) { var s = success; if (s) { if (callback && callback.success) { var rows = this.query(column, key, true); if (rows && rows.length) callback.success(rows[0][1]); else s = false; }; }; if (!s && callback.failure) callback.failure(); return; }; FIRSTCLASS.util.DataSource.prototype.fetchItem = function(row, callbacks) { var that = this; if (typeof row == "string") { for (var i = 0; i < this._data.records.length; i++) { if (this._data.records[i].uri == row) { row = this._data.records[i]; break; } } } var uri = this.getItemUrl(row, true); var tmpConnManagerRequest = YAHOO.util.Connect.asyncRequest(this._config.requestType, this.generateDataURL({ baseUrl: uri, backVersions: false }), { success:function (response) { // parse JSON data and append it to our current data list var newdata = []; try { newdata = FIRSTCLASS.lang.JSON.parse(response.responseText); } catch(x){ ////YAHOO.log("JSON Parse Failed", "error", "DataSource.js"); return; } row.itemdata = newdata; var rows = [row]; that.processIncomingContent(rows); rows = null; that.notifyRowChanged(row); if (callbacks && callbacks.completed) { callbacks.completed(row); } }, failure:function (response) { that._onFailure(response, {"row": row}); if (callbacks && callbacks.failed) { callbacks.failed(); } } } ); }; /** * checks for new rows at the beginning of the container * * @Method DataSource.fetchNewRows */ FIRSTCLASS.util.DataSource.prototype.fetchNewRows = function(callbacks) { this.writeLog("fetchNewRows called"); if (this._config.masterDS) { this._config.masterDS.fetchNewRows(callbacks); return; } if (this._config.active && this._watchState.fetching == false) { this.writeLog("fetchNewRows fetching"); this._watchState.fetching = true; this._watchState.callbacks = callbacks; var that = this; //YAHOO.log("checking for new rows"); that._watchState.connManagerRequest = YAHOO.util.Connect.asyncRequest(this._config.requestType, this.generateDataURL({ baseUrl: this._config.containerBaseUrl, unread: true }), { success: this.fetchNewRowsSuccess, failure: this.fetchNewRowsFailure, abort: this.fetchNewRowsAbort, scope: this, timeout: 60000 }); } }; FIRSTCLASS.util.DataSource.prototype.fetchNewRowsSuccess = function (response) { this.writeLog("fetchNewRows Succeeded"); var that = this; var callbacks = that._watchState.callbacks; that._watchState.callbacks = null; that._watchState.fetching = false; that._onSuccess(response, that._watchState); if (callbacks && callbacks.completed) { callbacks.completed(); } }; FIRSTCLASS.util.DataSource.prototype.fetchNewRowsFailure = function (response) { this.writeLog("fetchNewRows failed"); var that = this; var callbacks = that._watchState.callbacks; that._watchState.callbacks = null; that._watchState.fetching = false; if ( response.status == -1 && that._config.active ) { window.setTimeout(function() { that.fetchNewRows(); }, that._config.pollInterval); } else { that._onFailure(response, that._watchState); } if (callbacks && callbacks.failed) { callbacks.failed(); } }; FIRSTCLASS.util.DataSource.prototype.fetchNewRowsAbort = function (response) { this.writeLog("fetchNewRows aborted"); var that = this; var callbacks = that._watchState.callbacks; that._watchState.callbacks = null; that._watchState.fetching = false; // timeout probably if ( response.status == -1 && that._config.active ) { window.setTimeout(function() { that.fetchNewRows(); }, that._config.pollInterval); } if (callbacks && callbacks.failed) { callbacks.failed(); } }; FIRSTCLASS.util.DataSource.prototype.watchForTinkle = function(callbacks, reFetch) { if (this._config.active && this._watchState.fetching == false) { this._watchState.fetching = true; var that = this; //YAHOO.log("checking for new rows"); var url = this.generateDataURL({baseUrl: this._config.containerBaseUrl, tinkle: true}); if (reFetch) { url = this.generateDataURL({baseUrl: this._config.containerBaseUrl, startIndex: 1, loadFull: true}); } that._watchState.connManagerRequest = YAHOO.util.Connect.asyncRequest(this._config.requestType, url, { success: this.watchForTinkleSuccess, failure: this.watchForTinkleFailure, abort: this.watchForTinkleAbort, scope: this }); } }; FIRSTCLASS.util.DataSource.prototype.watchForTinkleSuccess = function (response) { var that = this; var callbacks = that._watchState.callbacks; that._watchState.callbacks = null; that._watchState.fetching = false; that._onSuccess(response, that._watchState); if (callbacks && callbacks.completed) { callbacks.completed(); } }; FIRSTCLASS.util.DataSource.prototype.watchForTinkleFailure = function (response) { var that = this; var callbacks = that._watchState.callbacks; that._watchState.callbacks = null; that._watchState.fetching = false; if ( response.status == -1 && that._config.active ) { window.setTimeout(function() { that.watchForTinkle(callbacks); }, that._config.pollInterval); } else { that._onFailure(response, that._watchState); } if (callbacks && callbacks.failed) { callbacks.failed(); } }; FIRSTCLASS.util.DataSource.prototype.watchForTinkleAbort = function (response) { var that = this; var callbacks = that._watchState.callbacks; that._watchState.callbacks = null; that._watchState.fetching = false; // timeout probably if ( response.status == -1 && that._config.active ) { window.setTimeout(function() { that.watchForTinkle(callbacks); }, that._config.pollInterval); } if (callbacks && callbacks.failed) { callbacks.failed(); } }; FIRSTCLASS.util.DataSource.prototype.deleteThread = function(row, callbacks) { if (this._config.masterDS) { this._config.masterDS.deleteThread(row, callbacks); } else { var threadid = row.threadid.replace('-', '_'); var postData = FIRSTCLASS.lang.uesc('FieldID:1001=LONG') + '=299&' + FIRSTCLASS.lang.uesc('FieldID:1002=STRING') + '=' + FIRSTCLASS.lang.uesc('11_(' + threadid + ')'); YAHOO.util.Connect.resetDefaultHeaders(); YAHOO.util.Connect.setDefaultPostHeader(true); var tmpConnManagerRequest = YAHOO.util.Connect.asyncRequest("POST", FIRSTCLASS.lang.ensureSlashUrl(this._config.containerBaseUrl) + FIRSTCLASS.opCodes.FileOp, false, postData); } for (var j in this._data.records) { if (this._data.records[j].threadid == row.threadid) { this.notifyRowDeleted(row); row.status.deleted = true; } } }; FIRSTCLASS.util.DataSource.prototype.deleteRow = function(row, callbacks) { if (row.mRow) { this._config.masterDS.deleteRow(row.mRow, callbacks); } else { var that = this; //YAHOO.log("Deleting Row"); var uri = this.getItemUrl(row, false, false); var url = FIRSTCLASS.lang.removeSlashUrl(uri); if (url.indexOf("?") >= 0) { url += "&"; } else { url += "?"; } url += this._config.pluginStr + "&Delete=1"; var tmpConnManagerRequest = YAHOO.util.Connect.asyncRequest(this._config.requestType, url, { success:function (response) { that.notifyRowDeleted(row); row.status.deleted = true; if (callbacks && callbacks.completed) { callbacks.completed(); } }, failure:function (response) { if (callbacks && callbacks.failed) { callbacks.failed(); } } } ); } }; FIRSTCLASS.util.DataSource.prototype.markAllAsRead = function() { if (this._config.masterDS) { this._config.masterDS.markAllAsRead(); } else { var url = this._config.containerBaseUrl +"?Unread=-1"; var that = this; YAHOO.util.Connect.asyncRequest('GET',url, { success: function(evt) { var rows = []; var oldrows = []; for (var i in that._data.records) { var row = that._data.records[i]; if (row.status.unread) { oldrows.push(row); row.status.unread = false; rows.push(row); that._data.records[i] = row; } } that.notifyRowsChanged(rows,oldrows); rows = null; oldrows = null; } }); } }; FIRSTCLASS.util.DataSource.prototype.toggleUnRead = function(row, newvalue, callbacks) { var that = this; if (row.mRow) { this._config.masterDS.toggleUnRead(row.mRow, newvalue, callbacks); } else { //YAHOO.log("Toggling Row"); var uri = this.getItemUrl(row, true, false); var setVal = row.status.unread ? 0 : 1; if (typeof newvalue == "number") { setVal = newvalue > 0 ? 1 : 0; } else if (typeof newvalue == "boolean") { setVal = newvalue ? 1 : 0; } var param = "&Unread=" + ((setVal == 0) ? "-1" : "1"); uri = FIRSTCLASS.lang.removeSlashUrl(uri); if (uri.indexOf("?") >= 0) { uri += "&"; } else { uri += "?"; } var oldkeys = { status: { unread: 1 }, onlyunread: true }; row.status.unread = setVal; that.notifyRowChanged(row, oldkeys); if (callbacks) { this._state.toggleUnreadCallbacks = callbacks; } var tmpConnManagerRequest = YAHOO.util.Connect.asyncRequest(this._config.requestType, uri + this._config.pluginStr + param, { success: this.toggleUnReadSuccess, failure: this.toggleUnReadFailure, scope: this } ); } }; FIRSTCLASS.util.DataSource.prototype.toggleUnReadSuccess = function(response) { var callbacks = this._state.toggleUnreadCallbacks; this._state.toggleUnreadCallbacks = null; if (callbacks && callbacks.completed) { callbacks.completed(); } }; FIRSTCLASS.util.DataSource.prototype.toggleUnReadFailure = function(response) { var callbacks = this._state.toggleUnreadCallbacks; this._state.toggleUnreadCallbacks = null; if (callbacks && callbacks.failed) { callbacks.failed(); } }; FIRSTCLASS.util.DataSource.prototype.toggleUnreadRows = function(rows) { var form = []; for (var i in rows) { form.push(rows[i].uri); } var postData = FIRSTCLASS.lang.uesc('FieldID:1001=LONG') + '=167' + FIRSTCLASS.lang.uesc('FieldID:1003=LONG') + '=0&TO=' + form.join(";"); var tmpConnManagerRequest = YAHOO.util.Connect.asyncRequest("POST", FIRSTCLASS.lang.ensureSlashUrl(this._config.containerBaseUrl) + FIRSTCLASS.opCodes.FileOp, false, postData); for (var i in to) { to[i].status.unread = 0; this.notifyRowChanged(to[i]); } }; FIRSTCLASS.util.DataSource.prototype.updateContainerFieldData = function(fields) { var form = {}; var field = {}; form.elements = []; form.action = FIRSTCLASS.lang.ensureSlashUrl(this.getContainerUrl()) + FIRSTCLASS.opCodes.FormSave; field.name = "Charset"; field.value = "UTF-8"; form.elements.push(field); // send tag for (var i in fields) { var info = fields[i]; field = {}; field.name = "FieldID:" + info.id + "=" + info.type; field.value = info.value; form.elements.push(field); } // post it FIRSTCLASS.util.submitForm(form); }; FIRSTCLASS.util.DataSource.prototype.updateFieldData = function(therow, fields) { var form = {}; var field = {}; form.elements = []; form.action = FIRSTCLASS.lang.ensureSlashUrl(this.getContainerUrl()) + FIRSTCLASS.opCodes.FormSave; var row = FIRSTCLASS.lang.removeSlashUrl(therow.uri); if (therow.typedef.objtype == FIRSTCLASS.objTypes.file) { if (row.indexOf("FCItemURL=") > 0) { row = row.slice(row.indexOf("FCItemURL=") + 10); } } if (row.indexOf("?") > 0) { row = row.slice(0, row.indexOf("?")); } field.name = "Charset"; field.value = "UTF-8"; form.elements.push(field); field.name = "Close"; field.value = "-1"; form.elements.push(field); // send tag for (var i in fields) { var info = fields[i]; field = {}; field.name = "LFieldID_" + info.id + "." + row + "=" + info.type; field.value = info.value; form.elements.push(field); } // post it FIRSTCLASS.util.submitForm(form); }; FIRSTCLASS.util.DataSource.prototype.watchItem = function(row, callbacks) { var that = this; if (row.mRow) { this._config.masterDS.watchItem(row.mRow, callbacks); } else { var uri = this.getItemUrl(row, false, false); var param = "&Watch=1"; var url = FIRSTCLASS.lang.removeSlashUrl(uri); if (url.indexOf("?") >= 0) { url += "&"; } else { url += "?"; } url += this._config.pluginStr + param; var tmpConnManagerRequest = YAHOO.util.Connect.asyncRequest(this._config.requestType, url, { success:function (response) { row.status.watched = 1; that.notifyRowChanged(row); if (callbacks && callbacks.completed) { callbacks.completed(); } }, failure:function (response) { if (callbacks && callbacks.failed) { callbacks.failed(); } } } ); } }; FIRSTCLASS.util.DataSource.prototype.getItemUrl = function(row, praw, retain, absolute) { var uri = row.uri; var raw = typeof praw != "undefined" && praw; if (row.uri.indexOf(FIRSTCLASS.session.baseURL) == -1) { uri = FIRSTCLASS.lang.ensureSlashUrl(FIRSTCLASS.lang.ensureSlashUrl(this._config.containerBaseUrl) + row.uri) + (raw?"":"?Show=2"); if (uri.indexOf(FIRSTCLASS.session.baseURL) == -1) { uri = FIRSTCLASS.lang.ensureSlashUrl(FIRSTCLASS.session.baseURL) + uri; } if (absolute && uri.indexOf(FIRSTCLASS.session.domain) == -1) { uri = FIRSTCLASS.lang.removeSlashUrl(FIRSTCLASS.session.domain) + uri; } } if (uri.indexOf("?FCItemURL=") > 0 && !retain) { var sp = uri.split("?FCItemURL="); var sp2 = sp[0].split("/"); sp2[sp2.length-1] = "" uri = sp2.join("/") + sp[1]; } return uri; } FIRSTCLASS.util.DataSource.prototype.getContainerUrl = function() { return this._config.containerBaseUrl; } FIRSTCLASS.util.DataSource.prototype.getPermalinkContainerUrl = function() { if (this._data.cid) { return "__Open-Conf/CID" + this._data.cid; } var uri = this._config.containerBaseUrl.replace("FAV1", "FV1").replace("FOV1", "FV1").replace("FLV1", "FV1"); var idx = uri.indexOf(FIRSTCLASS.session.baseURL); if (idx >= 0 && uri.length - idx > FIRSTCLASS.session.baseURL.length) { return uri.substr(idx+FIRSTCLASS.session.baseURL.length); } return uri; } FIRSTCLASS.util.DataSource.prototype.getPermalink = function(row) { return "#" + FIRSTCLASS.lang.ensureSlashUrl(this.getPermalinkContainerUrl()) + FIRSTCLASS.util.generateThreadContextParameter(row , true) }; FIRSTCLASS.util.DataSource.prototype.compareRows = function(row1, row2) { return row1.uri == row2.uri; }; /** * changes the granularity of requests dispatched by this datasource * * @Method DataSource.setRequestGranularity * @param {int} granularity (required) the new granularity */ FIRSTCLASS.util.DataSource.prototype.setRequestGranularity = function(granularity) { this._state.requestGranularity = granularity; }; FIRSTCLASS.util.DataSource.prototype._onSuccess = function(response, state) { if (!this._config.active) { // deactivated, parsing the data could cause serious issues return; } // parse JSON data and append it to our current data list var newdata = []; var that = this; try { //var text = response.responseText.replace(/\\\'/g,"'"); //newdata = FIRSTCLASS.lang.JSON.parse(text); newdata = FIRSTCLASS.lang.JSON.parse(response.responseText); that.writeLog("JSON Parse Finished"); } catch(x){ that.writeLog("JSON Parse Failed"); //YAHOO.log("JSON Parse Failed", "error", "DataSource.js"); if (response.responseText && response.responseText.indexOf("YUI/x138") > 0) { window.location = FIRSTCLASS.session.baseURL; // we had a logout, and are being returned the login page return; } if (state == that._watchState) { window.setTimeout(function() { if (that._config.active) { if (that._config.watchForTinkle) { that.watchForTinkle(); } else { that.fetchNewRows(); } } }, this._config.pollInterval); } if (this._config.isRadForm && response.responseText == "") { this._isFetching = false; window.setTimeout(function() { that.fetchRows(); }, this._config.pollInterval); } return; } if (typeof newdata.turi == "string" && newdata.turi.indexOf("S-138") >= 0) { window.location = FIRSTCLASS.session.baseURL; return; } if (newdata.error) { switch(newdata.error.code) { case 1010: window.location = FIRSTCLASS.session.baseURL; return; // case 1030: default: // handle more errors here var date = new Date(); newdata = { records: [ { typedef:{ objtype: FIRSTCLASS.objTypes.message, subtype: 0, isleaf: true }, status: { unread: 0, complete: true }, creatorcid: 0, name: FIRSTCLASS.locale.datasource.error.owner, subject: FIRSTCLASS.locale.datasource.error.subject, uid: 0, cid: "CID0", lastmod: date, lastmods: (date.getTime()/1000), messageid: "0", threadid: "0000-1111", icon: { id: 0 }, col8063: FIRSTCLASS.locale.errors.getErrorString(newdata.error), uri: "" } ] }; this.deactivate(); } } var hasMoreRows = this.loadData(newdata, state); //YAHOO.log("_onSuccess", "notification", "DataSource.js"); if (hasMoreRows && this._config.autoLoad) { if (this._config.autoLoadUntilRow) { for (var i in newdata.records) { if (newdata.records[i].uri == this._config.autoLoadUntilRow.uri) { this._config.autoLoad = false; break; } } } if (this._config.autoLoad && this._data.numitems && false) { window.setTimeout(function(){ that.fetchRows(false,false, {startIndex:that._state.currentDataIndex+1, endIndex:that._data.numitems.total}); }, 1000); } else if (this._config.autoLoad) { window.setTimeout(function(){ that.fetchRows(); }, 1000); } } else if (!hasMoreRows && !this._isRefilling) { //YAHOO.log("Container Filled, no more records available"); state.hasMoreRows = false; for (var i = 0; i < this._rowListeners.length; i++) { var listener = this._rowListeners[i]; if (listener.onFillCompleted) { listener.onFillCompleted(this); } } /*if (this._config.watchForNew) { this.fetchNewRows(); }*/ } if (this._isRefilling) { this._isRefilling = false; state.requestGranularity = this._config.defaultRequestGranularity; } this._isFetching = false; this.parseContainerData(newdata); if (state == this._state && this._config.watchForNew && !this._watchState.watching && !this._watchState.timeout) { this._watchState.watching = true; state.timeout = window.setTimeout(function() { if (that._config.active) { that.fetchNewRows(); state.timeout = false; } },this._config.pollInterval); } if (this._config.watchForNew && state === this._watchState && !state.timeout && !this._watchState.fetching) { if (newdata.records && newdata.records.length) { this.writeLog("Updating lastrow:" + newdata.records[0].messageid); this._watchState.lastrow = newdata.records[0]; } state.timeout = window.setTimeout(function() { if (that._config.active) { that.fetchNewRows(); state.timeout = false; } },this._config.pollInterval); } if (state == this._state && this._config.watchForTinkle && !this._watchState.watching && !this._watchState.timeout) { this._watchState.watching = true; state.timeout = window.setTimeout(function() { if (that._config.active) { that.watchForTinkle(); state.timeout = false; } },this._config.pollInterval); } if (this._config.watchForTinkle && state === this._watchState && !state.timeout && !this._watchState.fetching) { state.timeout = window.setTimeout(function() { if (that._config.active) { that.watchForTinkle(); state.timeout = false; } },this._config.pollInterval); } }; FIRSTCLASS.util.DataSource.prototype.getThreadFunction = function(threads, threadcb) { var that = this; return function() { if (threads.length > 0) { that.fetchRowsByThread(threads.pop(), threadcb); } threads = null; }; }; FIRSTCLASS.util.DataSource.prototype.loadData = function(newdata, state) { // then for each new row, call our rowListeners var hasMoreRows = true; if (newdata.records && newdata.records.length > 0) { this.processIncomingContent(newdata.records); var rowsToInsert = []; var deletedRows = []; var visitedRows = []; var changedRows = []; var oldRows = []; if (this._data) { if (!this._data.records) { this._data.records = []; } var latestrow = false; for (var i = 0; i < newdata.records.length; i++) { var insert = true; var row = newdata.records[i]; var maxversion = 0; for (var j = 0; j < this._data.records.length; j++) { if (this.compareRows(this._data.records[j], newdata.records[i])) { var oldrow = this._data.records[j]; if (newdata.records[i].status.deleted) { this._data.records[j] = newdata.records[i]; this.notifyRowDeleted(this._data.records[j]); } else if (this._config.compareRows && !this._config.compareRows(this._data.records[j], newdata.records[i])) { if (this._data.records[j].col8090 && !newdata.records[i].col8090) { newdata.records[i].col8090 = this._data.records[j].col8090; } if (this._data.records[j].mRow) { newdata.records[i].mRow = this._data.records[j].mRow; } this._data.records[j] = newdata.records[i]; changedRows.push(this._data.records[j]); if (oldrow.itemdata && !this._data.records[j].itemdata) { this._data.records[j].itemdata = oldrow.itemdata; oldrow.itemdata = false; } oldRows.push(oldrow); } else if (!this._config.compareRows && !FIRSTCLASS.lang.objDataEqual(newdata.records[i], this._data.records[j])) { if (this._data.records[j].col8090 && !newdata.records[i].col8090) { newdata.records[i].col8090 = this._data.records[j].col8090; } if (this._data.records[j].mRow) { newdata.records[i].mRow = this._data.records[j].mRow; } this._data.records[j] = newdata.records[i]; changedRows.push(this._data.records[j]); if (oldrow.itemdata && !this._data.records[j].itemdata) { this._data.records[j].itemdata = oldrow.itemdata; oldrow.itemdata = false; } oldRows.push(oldrow); } visitedRows[j] = true; insert = false; break; } if (state == this._watchState && (row.typedef.objtype == FIRSTCLASS.objTypes.fcfile || row.typedef.objtype == FIRSTCLASS.objTypes.file || row.typedef.objtype == FIRSTCLASS.objTypes.odocument) && row.status.backversion == 0) { if (this._data.records[j].threadid == row.threadid && this._data.records[j].col8090 && maxversion < this._data.records[j].col8090) { // don't count unsaved wikis if ((this._data.records[j].typedef.objtype != FIRSTCLASS.objTypes.odocument) || this._data.records[j].col8082) { maxversion = this._data.records[j].col8090; } this._data.records[j].status.backversion = 1; } } } if (maxversion > 0) { row.col8090 = maxversion + 1; } if (insert) { rowsToInsert.push(newdata.records[i]); } if (!latestrow || latestrow && latestrow.parsedDate < newdata.records[i].parsedDate) { latestrow = newdata.records[i]; } } if (changedRows.length) { this.notifyRowsChanged(changedRows, oldRows); } /*if (latestrow) { if (this._watchState.lastrow && latestrow.parsedDate > this._watchState.lastrow.parsedDate || !this._watchState.lastrow) { this._watchState.lastrow = latestrow; } }*/ if (this._config.reloadFullOnPoll || this._config.loadFull) { for (var i = this._data.records.length-1; i > 0; i--) { if (!visitedRows[i]) { this.notifyRowDeleted(this._data.records[i]); this._data.records.splice(i,1); } } } if (state == this._state && this._config.fetchThreads) { var nthreads = 0; var lastthread = ""; for (var i in rowsToInsert) { if (rowsToInsert[i].threadid != lastthread) { nthreads++; lastthread = rowsToInsert[i].threadid; } } this.writeLog("loadData received " + nthreads + " threads"); state.currentDataIndex += nthreads; } else if (state == this._watchState && this._config.fetchThreads && this._config.watchForNew) { var threads = []; for (var i in rowsToInsert) { if (rowsToInsert[i].threadid != threads[threads.length-1]) { threads.push(rowsToInsert[i].threadid); this.writeLog("loadData found Thread " + rowsToInsert[i].threadid + " name " + rowsToInsert[i].subject + rowsToInsert[i].col8010); } } var that = this; var threadcb = { completed: this.getThreadFunction(threads, threadcb), scope: this }; if (threads.length > 0) { this.fetchRowsByThread(threads.pop(), threadcb); } } else { state.currentDataIndex += rowsToInsert.length; } this._data.records = this._data.records.concat(rowsToInsert); if (rowsToInsert.length > 0) { this.notifyNewRows(rowsToInsert, (state != this._watchState), (state == this._watchState)); } if (rowsToInsert.length == 0 || state == this._objTypeState) { hasMoreRows = false; } } else { var latestrow = false; for (var i = 0; i < newdata.records.length; i++) { for (var j = i+1; j < newdata.records.length; j++) { if (this.compareRows(newdata.records[j], newdata.records[i])) { visitedRows[j] = true; } } if (newdata.records[i].status.deleted) { visitedRows[i] = true; } if ((!latestrow || latestrow && latestrow.parsedDate < newdata.records[i].parsedDate) && newdata.records[i].typedef && newdata.records[i].typedef.isleaf) { latestrow = newdata.records[i]; } } if (latestrow) { this.writeLog("Updating lastrow:" + latestrow.messageid); this._watchState.lastrow = latestrow; } for (var i = newdata.records.length-1; i >= 0; i--) { if (visitedRows[i]) { newdata.records.splice(i,1); } } this._data = newdata; if (state == this._state && this._config.fetchThreads) { var nthreads = 0; var lastthread = ""; for (var i in newdata.records) { if (newdata.records[i].threadid != lastthread) { nthreads++; lastthread = newdata.records[i].threadid; } } this.writeLog("loadData received " + nthreads + " threads"); state.currentDataIndex += nthreads; //newdata.records.pop(); } else { state.currentDataIndex += newdata.records.length; } this.notifyNewRows(newdata.records, true); if (newdata.records.length == 0) { hasMoreRows = false; } } } else { hasMoreRows = false; } return hasMoreRows; }; FIRSTCLASS.util.DataSource.prototype._onFailure = function(response, data) { this.writeLog("_onFailure called!"); //YAHOO.log("_onFailure", "notification", "DataSource.js"); switch (response.status) { case -1: // aborted //case 0: // communications failure default: } var failuredata = []; try { failuredata = FIRSTCLASS.lang.JSON.parse(response.responseText); if (!failuredata.error.loggedin) { // not logged in, redirect to login page window.location = FIRSTCLASS.session.baseURL; //alert("ERROR: " + failuredata.error.str); } else { switch(failuredata.error.code) { case 1081: // not found if (data && data.row) { this.notifyRowDeleted(data.row); } default: // fall thru intentional var date = new Date(); var fakedata = { records: [ { typedef:{ objtype: FIRSTCLASS.objTypes.message, subtype: 0, isleaf: true }, status: { unread: 0, complete: true }, creatorcid: 0, name: FIRSTCLASS.locale.datasource.error.owner, subject: FIRSTCLASS.locale.datasource.error.subject, uid: 0, cid: "CID0", lastmod: date, lastmods: (date.getTime()/1000), messageid: "0", threadid: "0000-1111", icon: { id: 0 }, col8063: FIRSTCLASS.locale.errors.getErrorString(failuredata.error), uri: "" } ] }; this.loadData(fakedata, this._state); this.deactivate(); //alert("ERROR: " + failuredata.error.str); } } } catch(x) { //YAHOO.log("JSON Parse Failed", "error", "DataSource.js"); if (response.responseText && response.responseText.indexOf("YUI/x138") > 0) { window.location = FIRSTCLASS.session.baseURL; // we had a logout, and are being returned the login page } } for (var i = 0; i < this._rowListeners.length; i++) { var listener = this._rowListeners[i]; if (listener.onFillCompleted) { listener.onFillCompleted(this); } } this._isFetching = false; }; FIRSTCLASS.util.DataSource.prototype.processIncomingContent = function(rows) { var del = document.createElement("div"); for (var j in rows) { var row = rows[j]; if (row.itemdata && row.itemdata.body) { if (!row.itemdata.expandedBody) { row.itemdata.expandedBody = this.expandContent(row,row.itemdata.body); if (typeof row.itemdata.expandedBody == "undefined") { row.itemdata.expandedBody = ""; } } } if(row.col8063 && row.col8063 != ""){ if (!row.expandedPreview && row.col8063) { row.expandedPreview = this.expandContent(row,row.col8063); del.innerHTML = row.expandedPreview; row.expandedPreview = del.innerHTML; if (typeof row.expandedPreview == "undefined") { row.expandedPreview = ""; } } } if (row.lastmods) { row.parsedDate = new Date(); row.parsedDate.setTime(row.lastmods*1000); } else if (row.lastmod) { row.parsedDate = Date.parse(row.lastmod); } } }; FIRSTCLASS.util.DataSource.prototype.expandContent = function(row,content) { content = content.parseURLS(); content = FIRSTCLASS.util.url.expandImageUrls(this.getItemUrl(row),content); content = FIRSTCLASS.util.url.processLinkTargets(content); return content; }; FIRSTCLASS.util.DataSource.prototype.parseContainerData = function(newdata) { if (!this._data) { this._data = {}; } if (newdata.chat && newdata.chat.length) { if (!this._data.chat || this._data.chat.length == 0) { this._data.chat = newdata.chat; this.notifyChatInvites(this._data.chat); } else { for (var i = 0; i < newdata.chat.length; i++) { var found = false; for (var j = 0; j < this._data.chat.length; j++) { if (newdata.chat[i] == this._data.chat[j]) { found = true; break; } } if (!found) { this._data.chat.push(newdata.chat[i]); this.notifyChatInvite(newdata.chat[i]); } } } } if (this._data && newdata.lastdelivery) { this._data.lastdelivery = newdata.lastdelivery; } for (var key in newdata) { this.notifyHeaderData(key, newdata[key]); if (key != "records") { this._data[key] = newdata[key]; } if (key == "broadcasts") { this.updateShout(newdata[key]); } } }; FIRSTCLASS.util.DataSource.prototype.query = function(column, str, caseinsensitive, compareFunc) { var rows = []; var search = str; if (caseinsensitive) { search = str.toLowerCase(); } if (this._data && this._data.records && this._data.records.length > 0) { for (var i = 0; i < this._data.records.length; i++) { var key = this._data.records[i][column]; if (key) { if(caseinsensitive) { key = key.toLowerCase(); } var compare = false; if (compareFunc) { compare = compareFunc(key, search); } else if (typeof key == "string") { compare = (key.indexOf(search) >= 0); } else { compare = ((""+key) == search); } if (compare) { rows.push([this._data.records[i][column],this._data.records[i]]); } } } } return rows; }; FIRSTCLASS.util.DataSource.prototype.getYAHOOWidgetDataSource = function(column, caseinsensitive, compareFunc) { var that = this; var func = function(string) { return that.query(column, string, caseinsensitive, compareFunc); }; return {dataSource:new YAHOO.widget.DS_JSFunction(func), formatResult:function(result, query) { return result[0]; }}; }; FIRSTCLASS.util.DataSource.prototype.getYAHOOUtilDataSource = function() { var that = this; var getRecords = function(oRequest) { return that._data.records; }; var dataSource = new YAHOO.util.DataSource(getRecords,{ responseType:YAHOO.util.DataSource.TYPE_JSON, responseSchema: { fields: this.getColumns() }, maxCacheEntries: 4096 }); return dataSource; }; FIRSTCLASS.util.DataSource.prototype.getYAHOOUtilDataSourceFunc = function() { var that = this; var getRecords = function(oRequest) { return that._data.records; }; var dataSource = new YAHOO.util.DataSource(getRecords,{ responseType:YAHOO.util.DataSource.TYPE_JSON, responseSchema: { fields: this.getColumns() }, maxCacheEntries: 4096 }); return dataSource; }; FIRSTCLASS.util.DataSource.prototype.getColumns = function() { var cols = []; if (this._data && this._data.records) { for (var mkey in this._data.records[0]) { cols.push(mkey); } } return cols; }; FIRSTCLASS.util.DataSource.prototype.hasMoreRows = function() { if (this._data && this._data.records && this._data.numitems && this._data.numitems.both) { return this._data.records.length != this._data.numitems.both; } return this._state.hasMoreRows; }; FIRSTCLASS.util.DataSource.prototype.updateShout = function(shouts) { FIRSTCLASS.ui.navBar.updateShoutBox(shouts); }; YAHOO.register("fcDataSource", FIRSTCLASS.util.DataSource, {version: "0.0.1", build: "1"});