michael@0: /** michael@0: * Helper method to start a single XUL tree test. michael@0: */ michael@0: function loadXULTreeAndDoTest(aDoTestFunc, aTreeID, aTreeView) michael@0: { michael@0: var doTestFunc = aDoTestFunc ? aDoTestFunc : gXULTreeLoadContext.doTestFunc; michael@0: var treeID = aTreeID ? aTreeID : gXULTreeLoadContext.treeID; michael@0: var treeView = aTreeView ? aTreeView : gXULTreeLoadContext.treeView; michael@0: michael@0: function loadXULTree(aTreeID, aTreeView) michael@0: { michael@0: this.treeNode = getNode(aTreeID); michael@0: michael@0: this.eventSeq = [ michael@0: new invokerChecker(EVENT_REORDER, this.treeNode) michael@0: ]; michael@0: michael@0: this.invoke = function loadXULTree_invoke() michael@0: { michael@0: this.treeNode.treeBoxObject.view = aTreeView; michael@0: } michael@0: michael@0: this.getID = function loadXULTree_getID() michael@0: { michael@0: return "Load XUL tree " + prettyName(aTreeID); michael@0: } michael@0: } michael@0: michael@0: gXULTreeLoadContext.queue = new eventQueue(); michael@0: gXULTreeLoadContext.queue.push(new loadXULTree(treeID, treeView)); michael@0: gXULTreeLoadContext.queue.onFinish = function() michael@0: { michael@0: SimpleTest.executeSoon(doTestFunc); michael@0: return DO_NOT_FINISH_TEST; michael@0: } michael@0: gXULTreeLoadContext.queue.invoke(); michael@0: } michael@0: michael@0: /** michael@0: * Analogy of addA11yLoadEvent, nice helper to load XUL tree and start the test. michael@0: */ michael@0: function addA11yXULTreeLoadEvent(aDoTestFunc, aTreeID, aTreeView) michael@0: { michael@0: gXULTreeLoadContext.doTestFunc = aDoTestFunc; michael@0: gXULTreeLoadContext.treeID = aTreeID; michael@0: gXULTreeLoadContext.treeView = aTreeView; michael@0: michael@0: addA11yLoadEvent(loadXULTreeAndDoTest); michael@0: } michael@0: michael@0: michael@0: function nsTableTreeView(aRowCount) michael@0: { michael@0: this.__proto__ = new nsTreeView(); michael@0: michael@0: for (var idx = 0; idx < aRowCount; idx++) michael@0: this.mData.push(new treeItem("row" + String(idx) + "_")); michael@0: } michael@0: michael@0: function nsTreeTreeView() michael@0: { michael@0: this.__proto__ = new nsTreeView(); michael@0: michael@0: this.mData = [ michael@0: new treeItem("row1"), michael@0: new treeItem("row2_", true, [new treeItem("row2.1_"), new treeItem("row2.2_")]), michael@0: new treeItem("row3_", false, [new treeItem("row3.1_"), new treeItem("row3.2_")]), michael@0: new treeItem("row4") michael@0: ]; michael@0: } michael@0: michael@0: function nsTreeView() michael@0: { michael@0: this.mTree = null; michael@0: this.mData = []; michael@0: } michael@0: michael@0: nsTreeView.prototype = michael@0: { michael@0: ////////////////////////////////////////////////////////////////////////////// michael@0: // nsITreeView implementation michael@0: michael@0: get rowCount() michael@0: { michael@0: return this.getRowCountIntl(this.mData); michael@0: }, michael@0: setTree: function setTree(aTree) michael@0: { michael@0: this.mTree = aTree; michael@0: }, michael@0: getCellText: function getCellText(aRow, aCol) michael@0: { michael@0: var data = this.getDataForIndex(aRow); michael@0: if (aCol.id in data.colsText) michael@0: return data.colsText[aCol.id]; michael@0: michael@0: return data.text + aCol.id; michael@0: }, michael@0: getCellValue: function getCellValue(aRow, aCol) michael@0: { michael@0: var data = this.getDataForIndex(aRow); michael@0: return data.value; michael@0: }, michael@0: getRowProperties: function getRowProperties(aIndex) { return ""; }, michael@0: getCellProperties: function getCellProperties(aIndex, aCol) michael@0: { michael@0: if (!aCol.cycler) michael@0: return ""; michael@0: michael@0: var data = this.getDataForIndex(aIndex); michael@0: return this.mCyclerStates[data.cyclerState]; michael@0: }, michael@0: getColumnProperties: function getColumnProperties(aCol) { return ""; }, michael@0: getParentIndex: function getParentIndex(aRowIndex) michael@0: { michael@0: var info = this.getInfoByIndex(aRowIndex); michael@0: return info.parentIndex; michael@0: }, michael@0: hasNextSibling: function hasNextSibling(aRowIndex, aAfterIndex) { }, michael@0: getLevel: function getLevel(aIndex) michael@0: { michael@0: var info = this.getInfoByIndex(aIndex); michael@0: return info.level; michael@0: }, michael@0: getImageSrc: function getImageSrc(aRow, aCol) {}, michael@0: getProgressMode: function getProgressMode(aRow, aCol) {}, michael@0: isContainer: function isContainer(aIndex) michael@0: { michael@0: var data = this.getDataForIndex(aIndex); michael@0: return data.open != undefined; michael@0: }, michael@0: isContainerOpen: function isContainerOpen(aIndex) michael@0: { michael@0: var data = this.getDataForIndex(aIndex); michael@0: return data.open; michael@0: }, michael@0: isContainerEmpty: function isContainerEmpty(aIndex) michael@0: { michael@0: var data = this.getDataForIndex(aIndex); michael@0: return data.open == undefined; michael@0: }, michael@0: isSeparator: function isSeparator(aIndex) {}, michael@0: isSorted: function isSorted() {}, michael@0: toggleOpenState: function toggleOpenState(aIndex) michael@0: { michael@0: var data = this.getDataForIndex(aIndex); michael@0: michael@0: data.open = !data.open; michael@0: var rowCount = this.getRowCountIntl(data.children); michael@0: michael@0: if (data.open) michael@0: this.mTree.rowCountChanged(aIndex + 1, rowCount); michael@0: else michael@0: this.mTree.rowCountChanged(aIndex + 1, -rowCount); michael@0: }, michael@0: selectionChanged: function selectionChanged() {}, michael@0: cycleHeader: function cycleHeader(aCol) {}, michael@0: cycleCell: function cycleCell(aRow, aCol) michael@0: { michael@0: var data = this.getDataForIndex(aRow); michael@0: data.cyclerState = (data.cyclerState + 1) % 3; michael@0: michael@0: this.mTree.invalidateCell(aRow, aCol); michael@0: }, michael@0: isEditable: function isEditable(aRow, aCol) michael@0: { michael@0: return true; michael@0: }, michael@0: isSelectable: function isSelectable(aRow, aCol) {}, michael@0: setCellText: function setCellText(aRow, aCol, aValue) michael@0: { michael@0: var data = this.getDataForIndex(aRow); michael@0: data.colsText[aCol.id] = aValue; michael@0: }, michael@0: setCellValue: function setCellValue(aRow, aCol, aValue) michael@0: { michael@0: var data = this.getDataForIndex(aRow); michael@0: data.value = aValue; michael@0: michael@0: this.mTree.invalidateCell(aRow, aCol); michael@0: }, michael@0: performAction: function performAction(aAction) {}, michael@0: performActionOnRow: function performActionOnRow(aAction, aRow) {}, michael@0: performActionOnCell: function performActionOnCell(aAction, aRow, aCol) {}, michael@0: michael@0: ////////////////////////////////////////////////////////////////////////////// michael@0: // public implementation michael@0: michael@0: appendItem: function appendItem(aText) michael@0: { michael@0: this.mData.push(new treeItem(aText)); michael@0: }, michael@0: michael@0: ////////////////////////////////////////////////////////////////////////////// michael@0: // private implementation michael@0: michael@0: getDataForIndex: function getDataForIndex(aRowIndex) michael@0: { michael@0: return this.getInfoByIndex(aRowIndex).data; michael@0: }, michael@0: michael@0: getInfoByIndex: function getInfoByIndex(aRowIndex) michael@0: { michael@0: var info = { michael@0: data: null, michael@0: parentIndex: -1, michael@0: level: 0, michael@0: index: -1 michael@0: }; michael@0: michael@0: this.getInfoByIndexIntl(aRowIndex, info, this.mData, 0); michael@0: return info; michael@0: }, michael@0: michael@0: getRowCountIntl: function getRowCountIntl(aChildren) michael@0: { michael@0: var rowCount = 0; michael@0: for (var childIdx = 0; childIdx < aChildren.length; childIdx++) { michael@0: rowCount++; michael@0: michael@0: var data = aChildren[childIdx]; michael@0: if (data.open) michael@0: rowCount += this.getRowCountIntl(data.children); michael@0: } michael@0: michael@0: return rowCount; michael@0: }, michael@0: michael@0: getInfoByIndexIntl: function getInfoByIndexIntl(aRowIdx, aInfo, michael@0: aChildren, aLevel) michael@0: { michael@0: var rowIdx = aRowIdx; michael@0: for (var childIdx = 0; childIdx < aChildren.length; childIdx++) { michael@0: var data = aChildren[childIdx]; michael@0: michael@0: aInfo.index++; michael@0: michael@0: if (rowIdx == 0) { michael@0: aInfo.data = data; michael@0: aInfo.level = aLevel; michael@0: return -1; michael@0: } michael@0: michael@0: if (data.open) { michael@0: var parentIdx = aInfo.index; michael@0: rowIdx = this.getInfoByIndexIntl(rowIdx - 1, aInfo, data.children, michael@0: aLevel + 1); michael@0: michael@0: if (rowIdx == -1) { michael@0: if (aInfo.parentIndex == -1) michael@0: aInfo.parentIndex = parentIdx; michael@0: return 0; michael@0: } michael@0: } else { michael@0: rowIdx--; michael@0: } michael@0: } michael@0: michael@0: return rowIdx; michael@0: }, michael@0: michael@0: mCyclerStates: [ michael@0: "cyclerState1", michael@0: "cyclerState2", michael@0: "cyclerState3" michael@0: ] michael@0: }; michael@0: michael@0: function treeItem(aText, aOpen, aChildren) michael@0: { michael@0: this.text = aText; michael@0: this.colsText = {}; michael@0: this.open = aOpen; michael@0: this.value = "true"; michael@0: this.cyclerState = 0; michael@0: if (aChildren) michael@0: this.children = aChildren; michael@0: } michael@0: michael@0: function createAtom(aName) michael@0: { michael@0: return Components.classes["@mozilla.org/atom-service;1"] michael@0: .getService(Components.interfaces.nsIAtomService).getAtom(aName); michael@0: } michael@0: michael@0: /** michael@0: * Used in conjunction with loadXULTreeAndDoTest and addA11yXULTreeLoadEvent. michael@0: */ michael@0: var gXULTreeLoadContext = michael@0: { michael@0: doTestFunc: null, michael@0: treeID: null, michael@0: treeView: null, michael@0: queue: null michael@0: };