const CLASSNAME = "SongbirdXMLTreeView"; const CONTRACTID = "@skrul.com/songbird-xml-tree-view;1"; const CID = Components.ID("{389086cd-00d3-43b9-b47d-6bf7bebeac52}"); const DEBUG = false; const Cc = Components.classes; const Ci = Components.interfaces; function XMLTreeView() { this._delegate = null; this._tree = null; this._document = null; this._root = null; this._rowElements = null; this._cells = null; } function d(s) { if(DEBUG) { dump(">>>>>>>>>>>>> XMLTreeView: " + s + "\n"); } } // nsISupports XMLTreeView.prototype.QueryInterface = function(aIID) { if(!aIID.equals(Ci.nsISupports) && !aIID.equals(Ci.sbIXMLTreeView)) throw Components.results.NS_ERROR_NO_INTERFACE; return this; } // sbIXMLTreeView XMLTreeView.prototype.__defineSetter__("delegate", function(delegate) { this._delegate = delegate; }); XMLTreeView.prototype.__defineGetter__("delegate", function() { return this._delegate; }); XMLTreeView.prototype.__defineSetter__("document", function(document) { this._rowElements = []; this._cells = []; this._document = document; this._root = document.documentElement; var nl = this._root.childNodes; for(var i = 0; i < nl.length; i++) { var n = nl.item(i); if(n.nodeType == Ci.nsIDOMNode.ELEMENT_NODE) { this._rowElements.push(n); } } if(this._tree) { this._tree.invalidate(); } }); XMLTreeView.prototype.__defineGetter__("document", function() { return this._document; }); // nsITreeView XMLTreeView.prototype.__defineGetter__("rowCount", function() { if(this._document) { return this._rowElements.length; } else { return 0; } }); XMLTreeView.prototype.__defineGetter__("selection", function() { return this._selection; }); XMLTreeView.prototype.__defineSetter__("selection", function(selection) { this._selection = selection; }); XMLTreeView.prototype.getRowProperties = function(index, properties) { return null; } XMLTreeView.prototype.getCellProperties = function(row, col, properties) { return null; } XMLTreeView.prototype.getColumnProperties = function(col, properties) { return null; } XMLTreeView.prototype.isContainer = function(index) { return false; } XMLTreeView.prototype.isContainerOpen = function(index) { return false; } XMLTreeView.prototype.isContainerEmpty = function(index) { return false; } XMLTreeView.prototype.isSeparator = function(index) { return false; } XMLTreeView.prototype.isSorted = function() { return false; } XMLTreeView.prototype.canDrop = function(index, orientation) { return false; } XMLTreeView.prototype.drop = function(row, orientation) { // do nothing } XMLTreeView.prototype.getParentIndex = function(rowIndex) { return -1; } XMLTreeView.prototype.hasNextSibling = function(rowIndex, afterIndex) { // XXX: Is this right? return false; } XMLTreeView.prototype.getLevel = function(index) { return 0; } XMLTreeView.prototype.getImageSrc = function(row, col) { var cell = this._getCell(row, col.index); var rv = cell.getAttribute("src"); if(this._delegate) { return this._delegate.getImageSrc(this._rowElements[row], cell, rv); } else { return rv; } } XMLTreeView.prototype.getProgressMode = function(row, col) { return null; } XMLTreeView.prototype.getCellValue = function(row, col) { var cell = this._getCell(row, col.index); var rv = cell.getAttribute("value"); if(this._delegate) { return this._delegate.getCellValue(this._rowElements[row], cell, rv); } else { return rv; } } XMLTreeView.prototype.getCellText = function(row, col) { var cell = this._getCell(row, col.index); var rv = this._getNodeText(cell); if(this._delegate) { return this._delegate.getCellText(this._rowElements[row], cell, rv); } else { return rv; } } XMLTreeView.prototype.setTree = function(tree) { this._tree = tree; } XMLTreeView.prototype.toggleOpenState = function(index) { // do nothing } XMLTreeView.prototype.cycleHeader = function(col) { // do nothing } XMLTreeView.prototype.selectionChanged = function() { // do nothing } XMLTreeView.prototype.cycleCell = function(row, col) { // do nothing } XMLTreeView.prototype.isEditable = function(row, col) { return false; } XMLTreeView.prototype.setCellValue = function(row, col, value) { // do nothing } XMLTreeView.prototype.setCellText = function(row, col, value) { // do nothing } XMLTreeView.prototype.performAction = function(action) { // do nothing } XMLTreeView.prototype.performActionOnRow = function(action, row) { // do nothing } XMLTreeView.prototype.performActionOnCell = function(action, row, col) { // do nothing } XMLTreeView.prototype._getCell = function(rowIndex, colIndex) { var row = this._cells[rowIndex]; if(!row) { var rowElement = this._rowElements[rowIndex]; row = []; var nl = rowElement.childNodes; for(var i = 0; i < nl.length; i++) { var n = nl.item(i); if(n.nodeType == Ci.nsIDOMNode.ELEMENT_NODE) { row.push(n); } } this._cells[rowIndex] = row; } return row[colIndex]; } XMLTreeView.prototype._getNodeText = function(node) { var nl = node.childNodes; var s = ""; for(var i = 0; i < nl.length; i++) { var n = nl.item(i); if(n.nodeType == Ci.nsIDOMNode.TEXT_NODE) { s += n.nodeValue; } } return s; } /** * XPCOM Registration */ var Module = new Object(); Module.registerSelf = function(compMgr, fileSpec, location, type) { compMgr = compMgr.QueryInterface(Ci.nsIComponentRegistrar); compMgr.registerFactoryLocation(CID, CLASSNAME, CONTRACTID, fileSpec, location, type); } Module.getClassObject = function(compMgr, cid, iid) { if(!cid.equals(CID)) { throw Components.results.NS_ERROR_NOT_IMPLEMENTED; } if(!iid.equals(Ci.nsIFactory)) { throw Components.results.NS_ERROR_NO_INTERFACE; } return Factory; } Module.canUnload = function(compMgr) { return true; } var Factory = {}; Factory.createInstance = function(outer, iid) { if(outer != null) { throw Components.results.NS_ERROR_NO_AGGREGATION; } return new XMLTreeView(); } function NSGetModule(compMgr, fileSpec) { return Module; }