tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

treeview.js (6898B)


      1 /* import-globals-from common.js */
      2 /* import-globals-from events.js */
      3 
      4 /**
      5 * Helper method to start a single XUL tree test.
      6 */
      7 function loadXULTreeAndDoTest(aDoTestFunc, aTreeID, aTreeView) {
      8  var doTestFunc = aDoTestFunc ? aDoTestFunc : gXULTreeLoadContext.doTestFunc;
      9  var treeID = aTreeID ? aTreeID : gXULTreeLoadContext.treeID;
     10  var treeView = aTreeView ? aTreeView : gXULTreeLoadContext.treeView;
     11 
     12  let treeNode = getNode(treeID);
     13 
     14  gXULTreeLoadContext.queue = new eventQueue();
     15  gXULTreeLoadContext.queue.push({
     16    treeNode,
     17 
     18    eventSeq: [new invokerChecker(EVENT_REORDER, treeNode)],
     19 
     20    invoke() {
     21      this.treeNode.view = treeView;
     22    },
     23 
     24    getID() {
     25      return "Load XUL tree " + prettyName(treeID);
     26    },
     27  });
     28  gXULTreeLoadContext.queue.onFinish = function () {
     29    SimpleTest.executeSoon(doTestFunc);
     30    return DO_NOT_FINISH_TEST;
     31  };
     32  gXULTreeLoadContext.queue.invoke();
     33 }
     34 
     35 /**
     36 * Analogy of addA11yLoadEvent, nice helper to load XUL tree and start the test.
     37 */
     38 function addA11yXULTreeLoadEvent(aDoTestFunc, aTreeID, aTreeView) {
     39  gXULTreeLoadContext.doTestFunc = aDoTestFunc;
     40  gXULTreeLoadContext.treeID = aTreeID;
     41  gXULTreeLoadContext.treeView = aTreeView;
     42 
     43  addA11yLoadEvent(loadXULTreeAndDoTest);
     44 }
     45 
     46 function nsTableTreeView(aRowCount) {
     47  this.__proto__ = new nsTreeView();
     48 
     49  for (var idx = 0; idx < aRowCount; idx++) {
     50    this.mData.push(new treeItem("row" + String(idx) + "_"));
     51  }
     52 }
     53 
     54 function nsTreeTreeView() {
     55  this.__proto__ = new nsTreeView();
     56 
     57  this.mData = [
     58    new treeItem("row1"),
     59    new treeItem("row2_", true, [
     60      new treeItem("row2.1_"),
     61      new treeItem("row2.2_"),
     62    ]),
     63    new treeItem("row3_", false, [
     64      new treeItem("row3.1_"),
     65      new treeItem("row3.2_"),
     66    ]),
     67    new treeItem("row4"),
     68  ];
     69 }
     70 
     71 function nsTreeView() {
     72  this.mTree = null;
     73  this.mData = [];
     74 }
     75 
     76 nsTreeView.prototype = {
     77  // ////////////////////////////////////////////////////////////////////////////
     78  // nsITreeView implementation
     79 
     80  get rowCount() {
     81    return this.getRowCountIntl(this.mData);
     82  },
     83  setTree: function setTree(aTree) {
     84    this.mTree = aTree;
     85  },
     86  getCellText: function getCellText(aRow, aCol) {
     87    var data = this.getDataForIndex(aRow);
     88    if (aCol.id in data.colsText) {
     89      return data.colsText[aCol.id];
     90    }
     91 
     92    return data.text + aCol.id;
     93  },
     94  getCellValue: function getCellValue(aRow) {
     95    var data = this.getDataForIndex(aRow);
     96    return data.value;
     97  },
     98  getRowProperties: function getRowProperties() {
     99    return "";
    100  },
    101  getCellProperties: function getCellProperties(aIndex, aCol) {
    102    if (!aCol.cycler) {
    103      return "";
    104    }
    105 
    106    var data = this.getDataForIndex(aIndex);
    107    return this.mCyclerStates[data.cyclerState];
    108  },
    109  getColumnProperties: function getColumnProperties() {
    110    return "";
    111  },
    112  getParentIndex: function getParentIndex(aRowIndex) {
    113    var info = this.getInfoByIndex(aRowIndex);
    114    return info.parentIndex;
    115  },
    116  hasNextSibling: function hasNextSibling() {},
    117  getLevel: function getLevel(aIndex) {
    118    var info = this.getInfoByIndex(aIndex);
    119    return info.level;
    120  },
    121  getImageSrc: function getImageSrc() {},
    122  isContainer: function isContainer(aIndex) {
    123    var data = this.getDataForIndex(aIndex);
    124    return data.open != undefined;
    125  },
    126  isContainerOpen: function isContainerOpen(aIndex) {
    127    var data = this.getDataForIndex(aIndex);
    128    return data.open;
    129  },
    130  isContainerEmpty: function isContainerEmpty(aIndex) {
    131    var data = this.getDataForIndex(aIndex);
    132    return data.open == undefined;
    133  },
    134  isSeparator: function isSeparator() {},
    135  isSorted: function isSorted() {},
    136  toggleOpenState: function toggleOpenState(aIndex) {
    137    var data = this.getDataForIndex(aIndex);
    138 
    139    data.open = !data.open;
    140    var rowCount = this.getRowCountIntl(data.children);
    141 
    142    if (data.open) {
    143      this.mTree.rowCountChanged(aIndex + 1, rowCount);
    144    } else {
    145      this.mTree.rowCountChanged(aIndex + 1, -rowCount);
    146    }
    147  },
    148  selectionChanged: function selectionChanged() {},
    149  cycleHeader: function cycleHeader() {},
    150  cycleCell: function cycleCell(aRow, aCol) {
    151    var data = this.getDataForIndex(aRow);
    152    data.cyclerState = (data.cyclerState + 1) % 3;
    153 
    154    this.mTree.invalidateCell(aRow, aCol);
    155  },
    156  isEditable: function isEditable() {
    157    return true;
    158  },
    159  setCellText: function setCellText(aRow, aCol, aValue) {
    160    var data = this.getDataForIndex(aRow);
    161    data.colsText[aCol.id] = aValue;
    162  },
    163  setCellValue: function setCellValue(aRow, aCol, aValue) {
    164    var data = this.getDataForIndex(aRow);
    165    data.value = aValue;
    166 
    167    this.mTree.invalidateCell(aRow, aCol);
    168  },
    169 
    170  // ////////////////////////////////////////////////////////////////////////////
    171  // public implementation
    172 
    173  appendItem: function appendItem(aText) {
    174    this.mData.push(new treeItem(aText));
    175  },
    176 
    177  // ////////////////////////////////////////////////////////////////////////////
    178  // private implementation
    179 
    180  getDataForIndex: function getDataForIndex(aRowIndex) {
    181    return this.getInfoByIndex(aRowIndex).data;
    182  },
    183 
    184  getInfoByIndex: function getInfoByIndex(aRowIndex) {
    185    var info = {
    186      data: null,
    187      parentIndex: -1,
    188      level: 0,
    189      index: -1,
    190    };
    191 
    192    this.getInfoByIndexIntl(aRowIndex, info, this.mData, 0);
    193    return info;
    194  },
    195 
    196  getRowCountIntl: function getRowCountIntl(aChildren) {
    197    var rowCount = 0;
    198    for (var childIdx = 0; childIdx < aChildren.length; childIdx++) {
    199      rowCount++;
    200 
    201      var data = aChildren[childIdx];
    202      if (data.open) {
    203        rowCount += this.getRowCountIntl(data.children);
    204      }
    205    }
    206 
    207    return rowCount;
    208  },
    209 
    210  getInfoByIndexIntl: function getInfoByIndexIntl(
    211    aRowIdx,
    212    aInfo,
    213    aChildren,
    214    aLevel
    215  ) {
    216    var rowIdx = aRowIdx;
    217    for (var childIdx = 0; childIdx < aChildren.length; childIdx++) {
    218      var data = aChildren[childIdx];
    219 
    220      aInfo.index++;
    221 
    222      if (rowIdx == 0) {
    223        aInfo.data = data;
    224        aInfo.level = aLevel;
    225        return -1;
    226      }
    227 
    228      if (data.open) {
    229        var parentIdx = aInfo.index;
    230        rowIdx = this.getInfoByIndexIntl(
    231          rowIdx - 1,
    232          aInfo,
    233          data.children,
    234          aLevel + 1
    235        );
    236 
    237        if (rowIdx == -1) {
    238          if (aInfo.parentIndex == -1) {
    239            aInfo.parentIndex = parentIdx;
    240          }
    241          return 0;
    242        }
    243      } else {
    244        rowIdx--;
    245      }
    246    }
    247 
    248    return rowIdx;
    249  },
    250 
    251  mCyclerStates: ["cyclerState1", "cyclerState2", "cyclerState3"],
    252 };
    253 
    254 function treeItem(aText, aOpen, aChildren) {
    255  this.text = aText;
    256  this.colsText = {};
    257  this.open = aOpen;
    258  this.value = "true";
    259  this.cyclerState = 0;
    260  if (aChildren) {
    261    this.children = aChildren;
    262  }
    263 }
    264 
    265 /**
    266 * Used in conjunction with loadXULTreeAndDoTest and addA11yXULTreeLoadEvent.
    267 */
    268 var gXULTreeLoadContext = {
    269  doTestFunc: null,
    270  treeID: null,
    271  treeView: null,
    272  queue: null,
    273 };