summaryrefslogtreecommitdiffstats
path: root/toolkit/content/tests/widgets/tree_shared.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/content/tests/widgets/tree_shared.js')
-rw-r--r--toolkit/content/tests/widgets/tree_shared.js1405
1 files changed, 0 insertions, 1405 deletions
diff --git a/toolkit/content/tests/widgets/tree_shared.js b/toolkit/content/tests/widgets/tree_shared.js
deleted file mode 100644
index b157bdf56..000000000
--- a/toolkit/content/tests/widgets/tree_shared.js
+++ /dev/null
@@ -1,1405 +0,0 @@
-var columns_simpletree =
-[
- { name: "name", label: "Name", key: true, properties: "one two" },
- { name: "address", label: "Address" }
-];
-
-var columns_hiertree =
-[
- { name: "name", label: "Name", primary: true, key: true, properties: "one two" },
- { name: "address", label: "Address" },
- { name: "planet", label: "Planet" },
- { name: "gender", label: "Gender", cycler: true }
-];
-
-// XXXndeakin still to add some tests for:
-// cycler columns, checkbox cells, progressmeter cells
-
-// this test function expects a tree to have 8 rows in it when it isn't
-// expanded. The tree should only display four rows at a time. If editable,
-// the cell at row 1 and column 0 must be editable, and the cell at row 2 and
-// column 1 must not be editable.
-function testtag_tree(treeid, treerowinfoid, seltype, columnstype, testid)
-{
- // Stop keystrokes that aren't handled by the tree from leaking out and
- // scrolling the main Mochitests window!
- function preventDefault(event) {
- event.preventDefault();
- }
- document.addEventListener("keypress", preventDefault, false);
-
- var multiple = (seltype == "multiple");
-
- var tree = document.getElementById(treeid);
- var treerowinfo = document.getElementById(treerowinfoid);
- var rowInfo;
- if (testid =="tree view")
- rowInfo = getCustomTreeViewCellInfo();
- else
- rowInfo = convertDOMtoTreeRowInfo(treerowinfo, 0, { value: -1 });
- var columnInfo = (columnstype == "simple") ? columns_simpletree : columns_hiertree;
-
- is(tree.view.selection.currentColumn, null, testid + " initial currentColumn");
- is(tree.selType, seltype == "multiple" ? "" : seltype, testid + " seltype");
-
- // note: the functions below should be in this order due to changes made in later tests
-
- // select the first column in cell selection mode so that the selection
- // functions can be tested
- if (seltype == "cell")
- tree.view.selection.currentColumn = tree.columns[0];
-
- testtag_tree_columns(tree, columnInfo, testid);
- testtag_tree_TreeSelection(tree, testid, multiple);
- testtag_tree_TreeSelection_UI(tree, testid, multiple);
- if (seltype == "cell")
- testtag_tree_TreeSelection_UI_cell(tree, testid, rowInfo);
-
- testtag_tree_TreeView(tree, testid, rowInfo);
-
- is(tree.editable, false, "tree should not be editable");
- // currently, the editable flag means that tree editing cannot be invoked
- // by the user. However, editing can still be started with a script.
- is(tree.editingRow, -1, testid + " initial editingRow");
- is(tree.editingColumn, null, testid + " initial editingColumn");
-
- testtag_tree_UI_editing(tree, testid, rowInfo);
-
- is(tree.editable, false, "tree should not be editable after testtag_tree_UI_editing");
- // currently, the editable flag means that tree editing cannot be invoked
- // by the user. However, editing can still be started with a script.
- is(tree.editingRow, -1, testid + " initial editingRow (continued)");
- is(tree.editingColumn, null, testid + " initial editingColumn (continued)");
-
- var ecolumn = tree.columns[0];
- ok(!tree.startEditing(1, ecolumn), "non-editable trees shouldn't start editing");
- is(tree.editingRow, -1, testid + " failed startEditing shouldn't set editingRow");
- is(tree.editingColumn, null, testid + " failed startEditing shouldn't set editingColumn");
-
- tree.editable = true;
-
- ok(tree.startEditing(1, ecolumn), "startEditing should have returned true");
- is(tree.editingRow, 1, testid + " startEditing editingRow");
- is(tree.editingColumn, ecolumn, testid + " startEditing editingColumn");
- is(tree.getAttribute("editing"), "true", testid + " startEditing editing attribute");
-
- tree.stopEditing(true);
- is(tree.editingRow, -1, testid + " stopEditing editingRow");
- is(tree.editingColumn, null, testid + " stopEditing editingColumn");
- is(tree.hasAttribute("editing"), false, testid + " stopEditing editing attribute");
-
- tree.startEditing(-1, ecolumn);
- is(tree.editingRow == -1 && tree.editingColumn == null, true, testid + " startEditing -1 editingRow");
- tree.startEditing(15, ecolumn);
- is(tree.editingRow == -1 && tree.editingColumn == null, true, testid + " startEditing 15 editingRow");
- tree.startEditing(1, null);
- is(tree.editingRow == -1 && tree.editingColumn == null, true, testid + " startEditing null column editingRow");
- tree.startEditing(2, tree.columns[1]);
- is(tree.editingRow == -1 && tree.editingColumn == null, true, testid + " startEditing non editable cell editingRow");
-
- tree.startEditing(1, ecolumn);
- var inputField = tree.inputField;
- is(inputField instanceof Components.interfaces.nsIDOMXULTextBoxElement, true, testid + "inputField");
- inputField.value = "Changed Value";
- tree.stopEditing(true);
- is(tree.view.getCellText(1, ecolumn), "Changed Value", testid + "edit cell accept");
-
- // this cell can be edited, but stopEditing(false) means don't accept the change.
- tree.startEditing(1, ecolumn);
- inputField.value = "Second Value";
- tree.stopEditing(false);
- is(tree.view.getCellText(1, ecolumn), "Changed Value", testid + "edit cell no accept");
-
- tree.editable = false;
-
- // do the sorting tests last as it will cause the rows to rearrange
- // skip them for the custom tree view
- if (testid !="tree view")
- testtag_tree_TreeView_rows_sort(tree, testid, rowInfo);
-
- testtag_tree_wheel(tree);
-
- document.removeEventListener("keypress", preventDefault, false);
-
- SimpleTest.finish();
-}
-
-function testtag_tree_columns(tree, expectedColumns, testid)
-{
- testid += " ";
-
- var columns = tree.columns;
-
- is(columns instanceof TreeColumns, true, testid + "columns is a TreeColumns");
- is(columns.count, expectedColumns.length, testid + "TreeColumns count");
- is(columns.length, expectedColumns.length, testid + "TreeColumns length");
-
- var treecols = tree.getElementsByTagName("treecols")[0];
- var treecol = treecols.getElementsByTagName("treecol");
-
- var x = 0;
- var primary = null, sorted = null, key = null;
- for (var c = 0; c < expectedColumns.length; c++) {
- var adjtestid = testid + " column " + c + " ";
- var column = columns[c];
- var expectedColumn = expectedColumns[c];
- is(columns.getColumnAt(c), column, adjtestid + "getColumnAt");
- is(columns.getNamedColumn(expectedColumn.name), column, adjtestid + "getNamedColumn");
- is(columns.getColumnFor(treecol[c]), column, adjtestid + "getColumnFor");
- if (expectedColumn.primary)
- primary = column;
- if (expectedColumn.sorted)
- sorted = column;
- if (expectedColumn.key)
- key = column;
-
- // XXXndeakin on Windows and Linux, some columns are one pixel to the
- // left of where they should be. Could just be a rounding issue.
- var adj = 1;
- is(column.x + adj >= x, true, adjtestid + "position is after last column " +
- column.x + "," + column.width + "," + x);
- is(column.width > 0, true, adjtestid + "width is greater than 0");
- x = column.x + column.width;
-
- // now check the TreeColumn properties
- is(column instanceof TreeColumn, true, adjtestid + "is a TreeColumn");
- is(column.element, treecol[c], adjtestid + "element is treecol");
- is(column.columns, columns, adjtestid + "columns is TreeColumns");
- is(column.id, expectedColumn.name, adjtestid + "name");
- is(column.index, c, adjtestid + "index");
- is(column.primary, primary == column, adjtestid + "column is primary");
-
- is(column.cycler, "cycler" in expectedColumn && expectedColumn.cycler,
- adjtestid + "column is cycler");
- is(column.selectable, true, adjtestid + "column is selectable");
- is(column.editable, "editable" in expectedColumn && expectedColumn.editable,
- adjtestid + "column is editable");
-
- is(column.type, "type" in expectedColumn ? expectedColumn.type : 1, adjtestid + "type");
-
- is(column.getPrevious(), c > 0 ? columns[c - 1] : null, adjtestid + "getPrevious");
- is(column.getNext(), c < columns.length - 1 ? columns[c + 1] : null, adjtestid + "getNext");
-
- // check the view's getColumnProperties method
- var properties = tree.view.getColumnProperties(column);
- var expectedProperties = expectedColumn.properties;
- is(properties, expectedProperties ? expectedProperties : "", adjtestid + "getColumnProperties");
- }
-
- is(columns.getFirstColumn(), columns[0], testid + "getFirstColumn");
- is(columns.getLastColumn(), columns[columns.length - 1], testid + "getLastColumn");
- is(columns.getPrimaryColumn(), primary, testid + "getPrimaryColumn");
- is(columns.getSortedColumn(), sorted, testid + "getSortedColumn");
- is(columns.getKeyColumn(), key, testid + "getKeyColumn");
-
- is(columns.getColumnAt(-1), null, testid + "getColumnAt under");
- is(columns.getColumnAt(columns.length), null, testid + "getColumnAt over");
- is(columns.getNamedColumn(""), null, testid + "getNamedColumn null");
- is(columns.getNamedColumn("unknown"), null, testid + "getNamedColumn unknown");
- is(columns.getColumnFor(null), null, testid + "getColumnFor null");
- is(columns.getColumnFor(tree), null, testid + "getColumnFor other");
-}
-
-function testtag_tree_TreeSelection(tree, testid, multiple)
-{
- testid += " selection ";
-
- var selection = tree.view.selection;
- is(selection instanceof Components.interfaces.nsITreeSelection, true,
- testid + "selection is a TreeSelection");
- is(selection.single, !multiple, testid + "single");
-
- testtag_tree_TreeSelection_State(tree, testid + "initial", -1, []);
- is(selection.shiftSelectPivot, -1, testid + "initial shiftSelectPivot");
-
- selection.currentIndex = 2;
- testtag_tree_TreeSelection_State(tree, testid + "set currentIndex", 2, []);
- tree.currentIndex = 3;
- testtag_tree_TreeSelection_State(tree, testid + "set tree.currentIndex", 3, []);
-
- // test the select() method, which should deselect all rows and select
- // a single row
- selection.select(1);
- testtag_tree_TreeSelection_State(tree, testid + "select 1", 1, [1]);
- selection.select(3);
- testtag_tree_TreeSelection_State(tree, testid + "select 2", 3, [3]);
- selection.select(3);
- testtag_tree_TreeSelection_State(tree, testid + "select same", 3, [3]);
-
- selection.currentIndex = 1;
- testtag_tree_TreeSelection_State(tree, testid + "set currentIndex with single selection", 1, [3]);
-
- tree.currentIndex = 2;
- testtag_tree_TreeSelection_State(tree, testid + "set tree.currentIndex with single selection", 2, [3]);
-
- // check the toggleSelect method. In single selection mode, it only toggles on when
- // there isn't currently a selection.
- selection.toggleSelect(2);
- testtag_tree_TreeSelection_State(tree, testid + "toggleSelect 1", 2, multiple ? [2, 3] : [3]);
- selection.toggleSelect(2);
- selection.toggleSelect(3);
- testtag_tree_TreeSelection_State(tree, testid + "toggleSelect 2", 3, []);
-
- // the current index doesn't change after a selectAll, so it should still be set to 1
- // selectAll has no effect on single selection trees
- selection.currentIndex = 1;
- selection.selectAll();
- testtag_tree_TreeSelection_State(tree, testid + "selectAll 1", 1, multiple ? [0, 1, 2, 3, 4, 5, 6, 7] : []);
- selection.toggleSelect(2);
- testtag_tree_TreeSelection_State(tree, testid + "toggleSelect after selectAll", 2,
- multiple ? [0, 1, 3, 4, 5, 6, 7] : [2]);
- selection.clearSelection();
- testtag_tree_TreeSelection_State(tree, testid + "clearSelection", 2, []);
- selection.toggleSelect(3);
- selection.toggleSelect(1);
- if (multiple) {
- selection.selectAll();
- testtag_tree_TreeSelection_State(tree, testid + "selectAll 2", 1, [0, 1, 2, 3, 4, 5, 6, 7]);
- }
- selection.currentIndex = 2;
- selection.clearSelection();
- testtag_tree_TreeSelection_State(tree, testid + "clearSelection after selectAll", 2, []);
-
- // XXXndeakin invertSelection isn't implemented
- // selection.invertSelection();
-
- is(selection.shiftSelectPivot, -1, testid + "shiftSelectPivot set to -1");
-
- // rangedSelect and clearRange set the currentIndex to the endIndex. The
- // shiftSelectPivot property will be set to startIndex.
- selection.rangedSelect(1, 3, false);
- testtag_tree_TreeSelection_State(tree, testid + "rangedSelect no augment",
- multiple ? 3 : 2, multiple ? [1, 2, 3] : []);
- is(selection.shiftSelectPivot, multiple ? 1 : -1,
- testid + "shiftSelectPivot after rangedSelect no augment");
- if (multiple) {
- selection.select(1);
- selection.rangedSelect(0, 2, true);
- testtag_tree_TreeSelection_State(tree, testid + "rangedSelect augment", 2, [0, 1, 2]);
- is(selection.shiftSelectPivot, 0, testid + "shiftSelectPivot after rangedSelect augment");
-
- selection.clearRange(1, 3);
- testtag_tree_TreeSelection_State(tree, testid + "rangedSelect augment", 3, [0]);
-
- // check that rangedSelect can take a start value higher than end
- selection.rangedSelect(3, 1, false);
- testtag_tree_TreeSelection_State(tree, testid + "rangedSelect reverse", 1, [1, 2, 3]);
- is(selection.shiftSelectPivot, 3, testid + "shiftSelectPivot after rangedSelect reverse");
-
- // check that setting the current index doesn't change the selection
- selection.currentIndex = 0;
- testtag_tree_TreeSelection_State(tree, testid + "currentIndex with range selection", 0, [1, 2, 3]);
- }
-
- // both values of rangedSelect may be the same
- selection.rangedSelect(2, 2, false);
- testtag_tree_TreeSelection_State(tree, testid + "rangedSelect one row", 2, [2]);
- is(selection.shiftSelectPivot, 2, testid + "shiftSelectPivot after selecting one row");
-
- if (multiple) {
- selection.rangedSelect(2, 3, true);
-
- // a start index of -1 means from the last point
- selection.rangedSelect(-1, 0, true);
- testtag_tree_TreeSelection_State(tree, testid + "rangedSelect -1 existing selection", 0, [0, 1, 2, 3]);
- is(selection.shiftSelectPivot, 2, testid + "shiftSelectPivot after -1 existing selection");
-
- selection.currentIndex = 2;
- selection.rangedSelect(-1, 0, false);
- testtag_tree_TreeSelection_State(tree, testid + "rangedSelect -1 from currentIndex", 0, [0, 1, 2]);
- is(selection.shiftSelectPivot, 2, testid + "shiftSelectPivot -1 from currentIndex");
- }
-
- // XXXndeakin need to test out of range values but these don't work properly
-/*
- selection.select(-1);
- testtag_tree_TreeSelection_State(tree, testid + "rangedSelect augment -1", -1, []);
-
- selection.select(8);
- testtag_tree_TreeSelection_State(tree, testid + "rangedSelect augment 8", 3, [0]);
-*/
-}
-
-function testtag_tree_TreeSelection_UI(tree, testid, multiple)
-{
- testid += " selection UI ";
-
- var selection = tree.view.selection;
- selection.clearSelection();
- selection.currentIndex = 0;
- tree.focus();
-
- var keydownFired = 0;
- var keypressFired = 0;
- function keydownListener(event)
- {
- keydownFired++;
- }
- function keypressListener(event) {
- keypressFired++;
- }
-
- // check that cursor up and down keys navigate up and down
- // select event fires after a delay so don't expect it. The reason it fires after a delay
- // is so that cursor navigation allows quicking skimming over a set of items without
- // actually firing events in-between, improving performance. The select event will only
- // be fired on the row where the cursor stops.
- window.addEventListener("keydown", keydownListener, false);
- window.addEventListener("keypress", keypressListener, false);
-
- synthesizeKeyExpectEvent("VK_DOWN", {}, tree, "!select", "key down");
- testtag_tree_TreeSelection_State(tree, testid + "key down", 1, [1], 0);
-
- synthesizeKeyExpectEvent("VK_UP", {}, tree, "!select", "key up");
- testtag_tree_TreeSelection_State(tree, testid + "key up", 0, [0], 0);
-
- synthesizeKeyExpectEvent("VK_UP", {}, tree, "!select", "key up at start");
- testtag_tree_TreeSelection_State(tree, testid + "key up at start", 0, [0], 0);
-
- // pressing down while the last row is selected should not fire a select event,
- // as the selection won't have changed. Also the view is not scrolled in this case.
- selection.select(7);
- synthesizeKeyExpectEvent("VK_DOWN", {}, tree, "!select", "key down at end");
- testtag_tree_TreeSelection_State(tree, testid + "key down at end", 7, [7], 0);
-
- // pressing keys while at the edge of the visible rows should scroll the list
- tree.treeBoxObject.scrollToRow(4);
- selection.select(4);
- synthesizeKeyExpectEvent("VK_UP", {}, tree, "!select", "key up with scroll");
- is(tree.treeBoxObject.getFirstVisibleRow(), 3, testid + "key up with scroll");
-
- tree.treeBoxObject.scrollToRow(0);
- selection.select(3);
- synthesizeKeyExpectEvent("VK_DOWN", {}, tree, "!select", "key down with scroll");
- is(tree.treeBoxObject.getFirstVisibleRow(), 1, testid + "key down with scroll");
-
- // accel key and cursor movement adjust currentIndex but should not change
- // the selection. In single selection mode, the selection will not change,
- // but instead will just scroll up or down a line
- tree.treeBoxObject.scrollToRow(0);
- selection.select(1);
- synthesizeKeyExpectEvent("VK_DOWN", { accelKey: true }, tree, "!select", "key down with accel");
- testtag_tree_TreeSelection_State(tree, testid + "key down with accel", multiple ? 2 : 1, [1]);
- if (!multiple)
- is(tree.treeBoxObject.getFirstVisibleRow(), 1, testid + "key down with accel and scroll");
-
- tree.treeBoxObject.scrollToRow(4);
- selection.select(4);
- synthesizeKeyExpectEvent("VK_UP", { accelKey: true }, tree, "!select", "key up with accel");
- testtag_tree_TreeSelection_State(tree, testid + "key up with accel", multiple ? 3 : 4, [4]);
- if (!multiple)
- is(tree.treeBoxObject.getFirstVisibleRow(), 3, testid + "key up with accel and scroll");
-
- // do this three times, one for each state of pageUpOrDownMovesSelection,
- // and then once with the accel key pressed
- for (let t = 0; t < 3; t++) {
- let testidmod = "";
- if (t == 2)
- testidmod = " with accel"
- else if (t == 1)
- testidmod = " rev";
- var keymod = (t == 2) ? { accelKey: true } : { };
-
- var moveselection = tree.pageUpOrDownMovesSelection;
- if (t == 2)
- moveselection = !moveselection;
-
- tree.treeBoxObject.scrollToRow(4);
- selection.currentIndex = 6;
- selection.select(6);
- var expected = moveselection ? 4 : 6;
- synthesizeKeyExpectEvent("VK_PAGE_UP", keymod, tree, "!select", "key page up");
- testtag_tree_TreeSelection_State(tree, testid + "key page up" + testidmod,
- expected, [expected], moveselection ? 4 : 0);
-
- expected = moveselection ? 0 : 6;
- synthesizeKeyExpectEvent("VK_PAGE_UP", keymod, tree, "!select", "key page up again");
- testtag_tree_TreeSelection_State(tree, testid + "key page up again" + testidmod,
- expected, [expected], 0);
-
- expected = moveselection ? 0 : 6;
- synthesizeKeyExpectEvent("VK_PAGE_UP", keymod, tree, "!select", "key page up at start");
- testtag_tree_TreeSelection_State(tree, testid + "key page up at start" + testidmod,
- expected, [expected], 0);
-
- tree.treeBoxObject.scrollToRow(0);
- selection.currentIndex = 1;
- selection.select(1);
- expected = moveselection ? 3 : 1;
- synthesizeKeyExpectEvent("VK_PAGE_DOWN", keymod, tree, "!select", "key page down");
- testtag_tree_TreeSelection_State(tree, testid + "key page down" + testidmod,
- expected, [expected], moveselection ? 0 : 4);
-
- expected = moveselection ? 7 : 1;
- synthesizeKeyExpectEvent("VK_PAGE_DOWN", keymod, tree, "!select", "key page down again");
- testtag_tree_TreeSelection_State(tree, testid + "key page down again" + testidmod,
- expected, [expected], 4);
-
- expected = moveselection ? 7 : 1;
- synthesizeKeyExpectEvent("VK_PAGE_DOWN", keymod, tree, "!select", "key page down at start");
- testtag_tree_TreeSelection_State(tree, testid + "key page down at start" + testidmod,
- expected, [expected], 4);
-
- if (t < 2)
- tree.pageUpOrDownMovesSelection = !tree.pageUpOrDownMovesSelection;
- }
-
- tree.treeBoxObject.scrollToRow(4);
- selection.select(6);
- synthesizeKeyExpectEvent("VK_HOME", {}, tree, "!select", "key home");
- testtag_tree_TreeSelection_State(tree, testid + "key home", 0, [0], 0);
-
- tree.treeBoxObject.scrollToRow(0);
- selection.select(1);
- synthesizeKeyExpectEvent("VK_END", {}, tree, "!select", "key end");
- testtag_tree_TreeSelection_State(tree, testid + "key end", 7, [7], 4);
-
- // in single selection mode, the selection doesn't change in this case
- tree.treeBoxObject.scrollToRow(4);
- selection.select(6);
- synthesizeKeyExpectEvent("VK_HOME", { accelKey: true }, tree, "!select", "key home with accel");
- testtag_tree_TreeSelection_State(tree, testid + "key home with accel", multiple ? 0 : 6, [6], 0);
-
- tree.treeBoxObject.scrollToRow(0);
- selection.select(1);
- synthesizeKeyExpectEvent("VK_END", { accelKey: true }, tree, "!select", "key end with accel");
- testtag_tree_TreeSelection_State(tree, testid + "key end with accel", multiple ? 7 : 1, [1], 4);
-
- // next, test cursor navigation with selection. Here the select event will be fired
- selection.select(1);
- var eventExpected = multiple ? "select" : "!select";
- synthesizeKeyExpectEvent("VK_DOWN", { shiftKey: true }, tree, eventExpected, "key shift down to select");
- testtag_tree_TreeSelection_State(tree, testid + "key shift down to select",
- multiple ? 2 : 1, multiple ? [1, 2] : [1]);
- is(selection.shiftSelectPivot, multiple ? 1 : -1,
- testid + "key shift down to select shiftSelectPivot");
- synthesizeKeyExpectEvent("VK_UP", { shiftKey: true }, tree, eventExpected, "key shift up to unselect");
- testtag_tree_TreeSelection_State(tree, testid + "key shift up to unselect", 1, [1]);
- is(selection.shiftSelectPivot, multiple ? 1 : -1,
- testid + "key shift up to unselect shiftSelectPivot");
- if (multiple) {
- synthesizeKeyExpectEvent("VK_UP", { shiftKey: true }, tree, "select", "key shift up to select");
- testtag_tree_TreeSelection_State(tree, testid + "key shift up to select", 0, [0, 1]);
- is(selection.shiftSelectPivot, 1, testid + "key shift up to select shiftSelectPivot");
- synthesizeKeyExpectEvent("VK_DOWN", { shiftKey: true }, tree, "select", "key shift down to unselect");
- testtag_tree_TreeSelection_State(tree, testid + "key shift down to unselect", 1, [1]);
- is(selection.shiftSelectPivot, 1, testid + "key shift down to unselect shiftSelectPivot");
- }
-
- // do this twice, one for each state of pageUpOrDownMovesSelection, however
- // when selecting with the shift key, pageUpOrDownMovesSelection is ignored
- // and the selection always changes
- var lastidx = tree.view.rowCount - 1;
- for (let t = 0; t < 2; t++) {
- let testidmod = (t == 0) ? "" : " rev";
-
- // If the top or bottom visible row is the current row, pressing shift and
- // page down / page up selects one page up or one page down. Otherwise, the
- // selection is made to the top or bottom of the visible area.
- tree.treeBoxObject.scrollToRow(lastidx - 3);
- selection.currentIndex = 6;
- selection.select(6);
- synthesizeKeyExpectEvent("VK_PAGE_UP", { shiftKey: true }, tree, eventExpected, "key shift page up");
- testtag_tree_TreeSelection_State(tree, testid + "key shift page up" + testidmod,
- multiple ? 4 : 6, multiple ? [4, 5, 6] : [6]);
- if (multiple) {
- synthesizeKeyExpectEvent("VK_PAGE_UP", { shiftKey: true }, tree, "select", "key shift page up again");
- testtag_tree_TreeSelection_State(tree, testid + "key shift page up again" + testidmod,
- 0, [0, 1, 2, 3, 4, 5, 6]);
- // no change in the selection, so no select event should be fired
- synthesizeKeyExpectEvent("VK_PAGE_UP", { shiftKey: true }, tree, "!select", "key shift page up at start");
- testtag_tree_TreeSelection_State(tree, testid + "key shift page up at start" + testidmod,
- 0, [0, 1, 2, 3, 4, 5, 6]);
- // deselect by paging down again
- synthesizeKeyExpectEvent("VK_PAGE_DOWN", { shiftKey: true }, tree, "select", "key shift page down deselect");
- testtag_tree_TreeSelection_State(tree, testid + "key shift page down deselect" + testidmod,
- 3, [3, 4, 5, 6]);
- }
-
- tree.treeBoxObject.scrollToRow(1);
- selection.currentIndex = 2;
- selection.select(2);
- synthesizeKeyExpectEvent("VK_PAGE_DOWN", { shiftKey: true }, tree, eventExpected, "key shift page down");
- testtag_tree_TreeSelection_State(tree, testid + "key shift page down" + testidmod,
- multiple ? 4 : 2, multiple ? [2, 3, 4] : [2]);
- if (multiple) {
- synthesizeKeyExpectEvent("VK_PAGE_DOWN", { shiftKey: true }, tree, "select", "key shift page down again");
- testtag_tree_TreeSelection_State(tree, testid + "key shift page down again" + testidmod,
- 7, [2, 3, 4, 5, 6, 7]);
- synthesizeKeyExpectEvent("VK_PAGE_DOWN", { shiftKey: true }, tree, "!select", "key shift page down at start");
- testtag_tree_TreeSelection_State(tree, testid + "key shift page down at start" + testidmod,
- 7, [2, 3, 4, 5, 6, 7]);
- synthesizeKeyExpectEvent("VK_PAGE_UP", { shiftKey: true }, tree, "select", "key shift page up deselect");
- testtag_tree_TreeSelection_State(tree, testid + "key shift page up deselect" + testidmod,
- 4, [2, 3, 4]);
- }
-
- // test when page down / page up is pressed when the view is scrolled such
- // that the selection is not visible
- if (multiple) {
- tree.treeBoxObject.scrollToRow(3);
- selection.currentIndex = 1;
- selection.select(1);
- synthesizeKeyExpectEvent("VK_PAGE_DOWN", { shiftKey: true }, tree, eventExpected,
- "key shift page down with view scrolled down");
- testtag_tree_TreeSelection_State(tree, testid + "key shift page down with view scrolled down" + testidmod,
- 6, [1, 2, 3, 4, 5, 6], 3);
-
- tree.treeBoxObject.scrollToRow(2);
- selection.currentIndex = 6;
- selection.select(6);
- synthesizeKeyExpectEvent("VK_PAGE_UP", { shiftKey: true }, tree, eventExpected,
- "key shift page up with view scrolled up");
- testtag_tree_TreeSelection_State(tree, testid + "key shift page up with view scrolled up" + testidmod,
- 2, [2, 3, 4, 5, 6], 2);
-
- tree.treeBoxObject.scrollToRow(2);
- selection.currentIndex = 0;
- selection.select(0);
- // don't expect the select event, as the selection won't have changed
- synthesizeKeyExpectEvent("VK_PAGE_UP", { shiftKey: true }, tree, "!select",
- "key shift page up at start with view scrolled down");
- testtag_tree_TreeSelection_State(tree, testid + "key shift page up at start with view scrolled down" + testidmod,
- 0, [0], 0);
-
- tree.treeBoxObject.scrollToRow(0);
- selection.currentIndex = 7;
- selection.select(7);
- // don't expect the select event, as the selection won't have changed
- synthesizeKeyExpectEvent("VK_PAGE_DOWN", { shiftKey: true }, tree, "!select",
- "key shift page down at end with view scrolled up");
- testtag_tree_TreeSelection_State(tree, testid + "key shift page down at end with view scrolled up" + testidmod,
- 7, [7], 4);
- }
-
- tree.pageUpOrDownMovesSelection = !tree.pageUpOrDownMovesSelection;
- }
-
- tree.treeBoxObject.scrollToRow(4);
- selection.select(5);
- synthesizeKeyExpectEvent("VK_HOME", { shiftKey: true }, tree, eventExpected, "key shift home");
- testtag_tree_TreeSelection_State(tree, testid + "key shift home",
- multiple ? 0 : 5, multiple ? [0, 1, 2, 3, 4, 5] : [5], multiple ? 0 : 4);
-
- tree.treeBoxObject.scrollToRow(0);
- selection.select(3);
- synthesizeKeyExpectEvent("VK_END", { shiftKey: true }, tree, eventExpected, "key shift end");
- testtag_tree_TreeSelection_State(tree, testid + "key shift end",
- multiple ? 7 : 3, multiple ? [3, 4, 5, 6, 7] : [3], multiple ? 4 : 0);
-
- // pressing space selects a row, pressing accel + space unselects a row
- selection.select(2);
- selection.currentIndex = 4;
- synthesizeKeyExpectEvent(" ", {}, tree, "select", "key space on");
- // in single selection mode, space shouldn't do anything
- testtag_tree_TreeSelection_State(tree, testid + "key space on", 4, multiple ? [2, 4] : [2]);
-
- if (multiple) {
- synthesizeKeyExpectEvent(" ", { accelKey: true }, tree, "select", "key space off");
- testtag_tree_TreeSelection_State(tree, testid + "key space off", 4, [2]);
- }
-
- // check that clicking on a row selects it
- tree.treeBoxObject.scrollToRow(0);
- selection.select(2);
- selection.currentIndex = 2;
- if (0) { // XXXndeakin disable these tests for now
- mouseOnCell(tree, 1, tree.columns[1], "mouse on row");
- testtag_tree_TreeSelection_State(tree, testid + "mouse on row", 1, [1], 0,
- tree.selType == "cell" ? tree.columns[1] : null);
- }
-
- // restore the scroll position to the start of the page
- sendKey("HOME");
-
- window.removeEventListener("keydown", keydownListener, false);
- window.removeEventListener("keypress", keypressListener, false);
- is(keydownFired, multiple ? 63 : 40, "keydown event wasn't fired properly");
- is(keypressFired, multiple ? 2 : 1, "keypress event wasn't fired properly");
-}
-
-function testtag_tree_UI_editing(tree, testid, rowInfo)
-{
- testid += " editing UI ";
-
- // check editing UI
- var ecolumn = tree.columns[0];
- var rowIndex = 2;
- var inputField = tree.inputField;
-
- // temporary make the tree editable to test mouse double click
- var wasEditable = tree.editable;
- if (!wasEditable)
- tree.editable = true;
-
- // if this is a container save its current open status
- var row = rowInfo.rows[rowIndex];
- var wasOpen = null;
- if (tree.view.isContainer(row))
- wasOpen = tree.view.isContainerOpen(row);
-
- // Test whether a keystroke can enter text entry, and another can exit.
- if (tree.selType == "cell")
- {
- tree.stopEditing(false);
- ok(!tree.editingColumn, "Should not be editing tree cell now");
- tree.view.selection.currentColumn = ecolumn;
- tree.currentIndex = rowIndex;
-
- const isMac = (navigator.platform.indexOf("Mac") >= 0);
- const StartEditingKey = isMac ? "RETURN" : "F2";
- sendKey(StartEditingKey);
- is(tree.editingColumn, ecolumn, "Should be editing tree cell now");
- sendKey("ESCAPE");
- ok(!tree.editingColumn, "Should not be editing tree cell now");
- is(tree.currentIndex, rowIndex, "Current index should not have changed");
- is(tree.view.selection.currentColumn, ecolumn, "Current column should not have changed");
- }
-
- mouseDblClickOnCell(tree, rowIndex, ecolumn, testid + "edit on double click");
- is(tree.editingColumn, ecolumn, testid + "editing column");
- is(tree.editingRow, rowIndex, testid + "editing row");
-
- // ensure that we don't expand an expandable container on edit
- if (wasOpen != null)
- is(tree.view.isContainerOpen(row), wasOpen, testid + "opened container node on edit");
-
- // ensure to restore editable attribute
- if (!wasEditable)
- tree.editable = false;
-
- var ci = tree.currentIndex;
-
- // cursor navigation should not change the selection while editing
- var testKey = function(key) {
- synthesizeKeyExpectEvent(key, {}, tree, "!select", "key " + key + " with editing");
- is(tree.editingRow == rowIndex && tree.editingColumn == ecolumn && tree.currentIndex == ci,
- true, testid + "key " + key + " while editing");
- }
-
- testKey("VK_DOWN");
- testKey("VK_UP");
- testKey("VK_PAGE_DOWN");
- testKey("VK_PAGE_UP");
- testKey("VK_HOME");
- testKey("VK_END");
-
- // XXXndeakin figure out how to send characters to the textbox
- // inputField.inputField.focus()
- // synthesizeKeyExpectEvent(inputField.inputField, "b", null, "");
- // tree.stopEditing(true);
- // is(tree.view.getCellText(0, ecolumn), "b", testid + "edit cell");
-
- // Restore initial state.
- tree.stopEditing(false);
-}
-
-function testtag_tree_TreeSelection_UI_cell(tree, testid, rowInfo)
-{
- testid += " selection UI cell ";
-
- var columns = tree.columns;
- var firstcolumn = columns[0];
- var secondcolumn = columns[1];
- var lastcolumn = columns[columns.length - 1];
- var secondlastcolumn = columns[columns.length - 2];
- var selection = tree.view.selection;
-
- selection.clearSelection();
- selection.currentIndex = -1;
- selection.currentColumn = firstcolumn;
- is(selection.currentColumn, firstcolumn, testid + " first currentColumn");
-
- // no selection yet so nothing should happen when the left and right cursor keys are pressed
- synthesizeKeyExpectEvent("VK_RIGHT", {}, tree, "!select", "key right no selection");
- testtag_tree_TreeSelection_State(tree, testid + "key right no selection", -1, [], null, firstcolumn);
-
- selection.currentColumn = secondcolumn;
- synthesizeKeyExpectEvent("VK_LEFT", {}, tree, "!select", "key left no selection");
- testtag_tree_TreeSelection_State(tree, testid + "key left no selection", -1, [], null, secondcolumn);
-
- selection.select(2);
- selection.currentIndex = 2;
- if (0) { // XXXndeakin disable these tests for now
- mouseOnCell(tree, 1, secondlastcolumn, "mouse on cell");
- testtag_tree_TreeSelection_State(tree, testid + "mouse on cell", 1, [1], null, secondlastcolumn);
- }
-
- tree.focus();
-
- // selection is set, so it should move when the left and right cursor keys are pressed
- tree.treeBoxObject.scrollToRow(0);
- selection.select(1);
- selection.currentIndex = 1;
- selection.currentColumn = secondcolumn;
- synthesizeKeyExpectEvent("VK_LEFT", {}, tree, "!select", "key left in second column");
- testtag_tree_TreeSelection_State(tree, testid + "key left in second column", 1, [1], 0, firstcolumn);
-
- synthesizeKeyExpectEvent("VK_LEFT", {}, tree, "!select", "key left in first column");
- testtag_tree_TreeSelection_State(tree, testid + "key left in first column", 1, [1], 0, firstcolumn);
-
- selection.currentColumn = secondlastcolumn;
- synthesizeKeyExpectEvent("VK_RIGHT", {}, tree, "!select", "key right in second last column");
- testtag_tree_TreeSelection_State(tree, testid + "key right in second last column", 1, [1], 0, lastcolumn);
-
- synthesizeKeyExpectEvent("VK_RIGHT", {}, tree, "!select", "key right in last column");
- testtag_tree_TreeSelection_State(tree, testid + "key right in last column", 1, [1], 0, lastcolumn);
-
- synthesizeKeyExpectEvent("VK_UP", {}, tree, "!select", "key up in second row");
- testtag_tree_TreeSelection_State(tree, testid + "key up in second row", 0, [0], 0, lastcolumn);
-
- synthesizeKeyExpectEvent("VK_UP", {}, tree, "!select", "key up in first row");
- testtag_tree_TreeSelection_State(tree, testid + "key up in first row", 0, [0], 0, lastcolumn);
-
- synthesizeKeyExpectEvent("VK_DOWN", {}, tree, "!select", "key down in first row");
- testtag_tree_TreeSelection_State(tree, testid + "key down in first row", 1, [1], 0, lastcolumn);
-
- var lastidx = tree.view.rowCount - 1;
- tree.treeBoxObject.scrollToRow(lastidx - 3);
- selection.select(lastidx);
- selection.currentIndex = lastidx;
- synthesizeKeyExpectEvent("VK_DOWN", {}, tree, "!select", "key down in last row");
- testtag_tree_TreeSelection_State(tree, testid + "key down in last row", lastidx, [lastidx], lastidx - 3, lastcolumn);
-
- synthesizeKeyExpectEvent("VK_HOME", {}, tree, "!select", "key home");
- testtag_tree_TreeSelection_State(tree, testid + "key home", 0, [0], 0, lastcolumn);
-
- synthesizeKeyExpectEvent("VK_END", {}, tree, "!select", "key end");
- testtag_tree_TreeSelection_State(tree, testid + "key end", lastidx, [lastidx], lastidx - 3, lastcolumn);
-
- for (var t = 0; t < 2; t++) {
- var testidmod = (t == 0) ? "" : " rev";
-
- // scroll to the end, subtract 3 because we want lastidx to appear
- // at the end of view
- tree.treeBoxObject.scrollToRow(lastidx - 3);
- selection.select(lastidx);
- selection.currentIndex = lastidx;
- var expectedrow = tree.pageUpOrDownMovesSelection ? lastidx - 3 : lastidx;
- synthesizeKeyExpectEvent("VK_PAGE_UP", {}, tree, "!select", "key page up");
- testtag_tree_TreeSelection_State(tree, testid + "key page up" + testidmod,
- expectedrow, [expectedrow],
- tree.pageUpOrDownMovesSelection ? lastidx - 3 : 0, lastcolumn);
-
- tree.treeBoxObject.scrollToRow(1);
- selection.select(1);
- selection.currentIndex = 1;
- expectedrow = tree.pageUpOrDownMovesSelection ? 4 : 1;
- synthesizeKeyExpectEvent("VK_PAGE_DOWN", {}, tree, "!select", "key page down");
- testtag_tree_TreeSelection_State(tree, testid + "key page down" + testidmod,
- expectedrow, [expectedrow],
- tree.pageUpOrDownMovesSelection ? 1 : lastidx - 3, lastcolumn);
-
- tree.pageUpOrDownMovesSelection = !tree.pageUpOrDownMovesSelection;
- }
-
- // now check navigation when there is unselctable column
- secondcolumn.element.setAttribute("selectable", "false");
- secondcolumn.invalidate();
- is(secondcolumn.selectable, false, testid + "set selectable attribute");
-
- if (columns.length >= 3) {
- selection.select(3);
- selection.currentIndex = 3;
- // check whether unselectable columns are skipped over
- selection.currentColumn = firstcolumn;
- synthesizeKeyExpectEvent("VK_RIGHT", {}, tree, "!select", "key right unselectable column");
- testtag_tree_TreeSelection_State(tree, testid + "key right unselectable column",
- 3, [3], null, secondcolumn.getNext());
-
- synthesizeKeyExpectEvent("VK_LEFT", {}, tree, "!select", "key left unselectable column");
- testtag_tree_TreeSelection_State(tree, testid + "key left unselectable column",
- 3, [3], null, firstcolumn);
- }
-
- secondcolumn.element.removeAttribute("selectable");
- secondcolumn.invalidate();
- is(secondcolumn.selectable, true, testid + "clear selectable attribute");
-
- // check to ensure that navigation isn't allowed if the first column is not selectable
- selection.currentColumn = secondcolumn;
- firstcolumn.element.setAttribute("selectable", "false");
- firstcolumn.invalidate();
- synthesizeKeyExpectEvent("VK_LEFT", {}, tree, "!select", "key left unselectable first column");
- testtag_tree_TreeSelection_State(tree, testid + "key left unselectable first column",
- 3, [3], null, secondcolumn);
- firstcolumn.element.removeAttribute("selectable");
- firstcolumn.invalidate();
-
- // check to ensure that navigation isn't allowed if the last column is not selectable
- selection.currentColumn = secondlastcolumn;
- lastcolumn.element.setAttribute("selectable", "false");
- lastcolumn.invalidate();
- synthesizeKeyExpectEvent("VK_RIGHT", {}, tree, "!select", "key right unselectable last column");
- testtag_tree_TreeSelection_State(tree, testid + "key right unselectable last column",
- 3, [3], null, secondlastcolumn);
- lastcolumn.element.removeAttribute("selectable");
- lastcolumn.invalidate();
-
- // now check for cells with selectable false
- if (!rowInfo.rows[4].cells[1].selectable && columns.length >= 3) {
- // check whether unselectable cells are skipped over
- selection.select(4);
- selection.currentIndex = 4;
-
- selection.currentColumn = firstcolumn;
- synthesizeKeyExpectEvent("VK_RIGHT", {}, tree, "!select", "key right unselectable cell");
- testtag_tree_TreeSelection_State(tree, testid + "key right unselectable cell",
- 4, [4], null, secondcolumn.getNext());
-
- synthesizeKeyExpectEvent("VK_LEFT", {}, tree, "!select", "key left unselectable cell");
- testtag_tree_TreeSelection_State(tree, testid + "key left unselectable cell",
- 4, [4], null, firstcolumn);
-
- tree.treeBoxObject.scrollToRow(1);
- selection.select(3);
- selection.currentIndex = 3;
- selection.currentColumn = secondcolumn;
-
- synthesizeKeyExpectEvent("VK_DOWN", {}, tree, "!select", "key down unselectable cell");
- testtag_tree_TreeSelection_State(tree, testid + "key down unselectable cell",
- 5, [5], 2, secondcolumn);
-
- tree.treeBoxObject.scrollToRow(4);
- synthesizeKeyExpectEvent("VK_UP", {}, tree, "!select", "key up unselectable cell");
- testtag_tree_TreeSelection_State(tree, testid + "key up unselectable cell",
- 3, [3], 3, secondcolumn);
- }
-
- // restore the scroll position to the start of the page
- sendKey("HOME");
-}
-
-function testtag_tree_TreeView(tree, testid, rowInfo)
-{
- testid += " view ";
-
- var columns = tree.columns;
- var view = tree.view;
-
- is(view instanceof Components.interfaces.nsITreeView, true, testid + "view is a TreeView");
- is(view.rowCount, rowInfo.rows.length, testid + "rowCount");
-
- testtag_tree_TreeView_rows(tree, testid, rowInfo, 0);
-
- // note that this will only work for content trees currently
- view.setCellText(0, columns[1], "Changed Value");
- is(view.getCellText(0, columns[1]), "Changed Value", "setCellText");
-
- view.setCellValue(1, columns[0], "Another Changed Value");
- is(view.getCellValue(1, columns[0]), "Another Changed Value", "setCellText");
-}
-
-function testtag_tree_TreeView_rows(tree, testid, rowInfo, startRow)
-{
- var r;
- var columns = tree.columns;
- var view = tree.view;
- var length = rowInfo.rows.length;
-
- // methods to test along with the functions which determine the expected value
- var checkRowMethods =
- {
- isContainer: function(row) { return row.container },
- isContainerOpen: function(row) { return false },
- isContainerEmpty: function(row) { return (row.children != null && row.children.rows.length == 0) },
- isSeparator: function(row) { return row.separator },
- getRowProperties: function(row) { return row.properties },
- getLevel: function(row) { return row.level },
- getParentIndex: function(row) { return row.parent },
- hasNextSibling: function(row) { return r < startRow + length - 1; }
- };
-
- var checkCellMethods =
- {
- getCellText: function(row, cell) { return cell.label },
- getCellValue: function(row, cell) { return cell.value },
- getCellProperties: function(row, cell) { return cell.properties },
- isEditable: function(row, cell) { return cell.editable },
- isSelectable: function(row, cell) { return cell.selectable },
- getImageSrc: function(row, cell) { return cell.image },
- getProgressMode: function(row, cell) { return cell.mode }
- };
-
- var failedMethods = { };
- var checkMethod, actual, expected;
- var containerInfo = null;
- var toggleOpenStateOK = true;
-
- for (r = startRow; r < length; r++) {
- var row = rowInfo.rows[r];
- for (var c = 0; c < row.cells.length; c++) {
- var cell = row.cells[c];
-
- for (checkMethod in checkCellMethods) {
- expected = checkCellMethods[checkMethod](row, cell);
- actual = view[checkMethod](r, columns[c]);
- if (actual !== expected) {
- failedMethods[checkMethod] = true;
- is(actual, expected, testid + "row " + r + " column " + c + " " + checkMethod + " is incorrect");
- }
- }
- }
-
- // compare row properties
- for (checkMethod in checkRowMethods) {
- expected = checkRowMethods[checkMethod](row, r);
- if (checkMethod == "hasNextSibling") {
- actual = view[checkMethod](r, r);
- }
- else {
- actual = view[checkMethod](r);
- }
- if (actual !== expected) {
- failedMethods[checkMethod] = true;
- is(actual, expected, testid + "row " + r + " " + checkMethod + " is incorrect");
- }
- }
-/*
- // open and recurse into containers
- if (row.container) {
- view.toggleOpenState(r);
- if (!view.isContainerOpen(r)) {
- toggleOpenStateOK = false;
- is(view.isContainerOpen(r), true, testid + "row " + r + " toggleOpenState open");
- }
- testtag_tree_TreeView_rows(tree, testid + "container " + r + " ", row.children, r + 1);
- view.toggleOpenState(r);
- if (view.isContainerOpen(r)) {
- toggleOpenStateOK = false;
- is(view.isContainerOpen(r), false, testid + "row " + r + " toggleOpenState close");
- }
- }
-*/
- }
-
- for (var failedMethod in failedMethods) {
- if (failedMethod in checkRowMethods)
- delete checkRowMethods[failedMethod];
- if (failedMethod in checkCellMethods)
- delete checkCellMethods[failedMethod];
- }
-
- for (checkMethod in checkRowMethods)
- is(checkMethod + " ok", checkMethod + " ok", testid + checkMethod);
- for (checkMethod in checkCellMethods)
- is(checkMethod + " ok", checkMethod + " ok", testid + checkMethod);
- if (toggleOpenStateOK)
- is("toggleOpenState ok", "toggleOpenState ok", testid + "toggleOpenState");
-}
-
-function testtag_tree_TreeView_rows_sort(tree, testid, rowInfo)
-{
- // check if cycleHeader sorts the columns
- var columnIndex = 0;
- var view = tree.view;
- var column = tree.columns[columnIndex];
- var columnElement = column.element;
- var sortkey = columnElement.getAttribute("sort");
- if (sortkey) {
- view.cycleHeader(column);
- is(tree.getAttribute("sort"), sortkey, "cycleHeader sort");
- is(tree.getAttribute("sortDirection"), "ascending", "cycleHeader sortDirection ascending");
- is(columnElement.getAttribute("sortDirection"), "ascending", "cycleHeader column sortDirection");
- is(columnElement.getAttribute("sortActive"), "true", "cycleHeader column sortActive");
- view.cycleHeader(column);
- is(tree.getAttribute("sortDirection"), "descending", "cycleHeader sortDirection descending");
- is(columnElement.getAttribute("sortDirection"), "descending", "cycleHeader column sortDirection descending");
- view.cycleHeader(column);
- is(tree.getAttribute("sortDirection"), "", "cycleHeader sortDirection natural");
- is(columnElement.getAttribute("sortDirection"), "", "cycleHeader column sortDirection natural");
- // XXXndeakin content view isSorted needs to be tested
- }
-
- // Check that clicking on column header sorts the column.
- var columns = getSortedColumnArray(tree);
- is(columnElement.getAttribute("sortDirection"), "",
- "cycleHeader column sortDirection");
-
- // Click once on column header and check sorting has cycled once.
- mouseClickOnColumnHeader(columns, columnIndex, 0, 1);
- is(columnElement.getAttribute("sortDirection"), "ascending",
- "single click cycleHeader column sortDirection ascending");
-
- // Now simulate a double click.
- mouseClickOnColumnHeader(columns, columnIndex, 0, 2);
- if (navigator.platform.indexOf("Win") == 0) {
- // Windows cycles only once on double click.
- is(columnElement.getAttribute("sortDirection"), "descending",
- "double click cycleHeader column sortDirection descending");
- // 1 single clicks should restore natural sorting.
- mouseClickOnColumnHeader(columns, columnIndex, 0, 1);
- }
-
- // Check we have gone back to natural sorting.
- is(columnElement.getAttribute("sortDirection"), "",
- "cycleHeader column sortDirection");
-
- columnElement.setAttribute("sorthints", "twostate");
- view.cycleHeader(column);
- is(tree.getAttribute("sortDirection"), "ascending", "cycleHeader sortDirection ascending twostate");
- view.cycleHeader(column);
- is(tree.getAttribute("sortDirection"), "descending", "cycleHeader sortDirection ascending twostate");
- view.cycleHeader(column);
- is(tree.getAttribute("sortDirection"), "ascending", "cycleHeader sortDirection ascending twostate again");
- columnElement.removeAttribute("sorthints");
- view.cycleHeader(column);
- view.cycleHeader(column);
-
- is(columnElement.getAttribute("sortDirection"), "",
- "cycleHeader column sortDirection reset");
-}
-
-// checks if the current and selected rows are correct
-// current is the index of the current row
-// selected is an array of the indicies of the selected rows
-// column is the selected column
-// viewidx is the row that should be visible at the top of the tree
-function testtag_tree_TreeSelection_State(tree, testid, current, selected, viewidx, column)
-{
- var selection = tree.view.selection;
-
- if (!column)
- column = (tree.selType == "cell") ? tree.columns[0] : null;
-
- is(selection.count, selected.length, testid + " count");
- is(tree.currentIndex, current, testid + " currentIndex");
- is(selection.currentIndex, current, testid + " TreeSelection currentIndex");
- is(selection.currentColumn, column, testid + " currentColumn");
- if (viewidx !== null && viewidx !== undefined)
- is(tree.treeBoxObject.getFirstVisibleRow(), viewidx, testid + " first visible row");
-
- var actualSelected = [];
- var count = tree.view.rowCount;
- for (var s = 0; s < count; s++) {
- if (selection.isSelected(s))
- actualSelected.push(s);
- }
-
- is(compareArrays(selected, actualSelected), true, testid + " selection [" + selected + "]");
-
- actualSelected = [];
- var rangecount = selection.getRangeCount();
- for (var r = 0; r < rangecount; r++) {
- var start = {}, end = {};
- selection.getRangeAt(r, start, end);
- for (var rs = start.value; rs <= end.value; rs++)
- actualSelected.push(rs);
- }
-
- is(compareArrays(selected, actualSelected), true, testid + " range selection [" + selected + "]");
-}
-
-function testtag_tree_column_reorder()
-{
- // Make sure the tree is scrolled into the view, otherwise the test will
- // fail
- var testframe = window.parent.document.getElementById("testframe");
- if (testframe) {
- testframe.scrollIntoView();
- }
-
- var tree = document.getElementById("tree-column-reorder");
- var numColumns = tree.columns.count;
-
- var reference = [];
- for (let i = 0; i < numColumns; i++) {
- reference.push("col_" + i);
- }
-
- // Drag the first column to each position
- for (let i = 0; i < numColumns - 1; i++) {
- synthesizeColumnDrag(tree, i, i + 1, true);
- arrayMove(reference, i, i + 1, true);
- checkColumns(tree, reference, "drag first column right");
- }
-
- // And back
- for (let i = numColumns - 1; i >= 1; i--) {
- synthesizeColumnDrag(tree, i, i - 1, false);
- arrayMove(reference, i, i - 1, false);
- checkColumns(tree, reference, "drag last column left");
- }
-
- // Drag each column one column left
- for (let i = 1; i < numColumns; i++) {
- synthesizeColumnDrag(tree, i, i - 1, false);
- arrayMove(reference, i, i - 1, false);
- checkColumns(tree, reference, "drag each column left");
- }
-
- // And back
- for (let i = numColumns - 2; i >= 0; i--) {
- synthesizeColumnDrag(tree, i, i + 1, true);
- arrayMove(reference, i, i + 1, true);
- checkColumns(tree, reference, "drag each column right");
- }
-
- // Drag each column 5 to the right
- for (let i = 0; i < numColumns - 5; i++) {
- synthesizeColumnDrag(tree, i, i + 5, true);
- arrayMove(reference, i, i + 5, true);
- checkColumns(tree, reference, "drag each column 5 to the right");
- }
-
- // And to the left
- for (let i = numColumns - 6; i >= 5; i--) {
- synthesizeColumnDrag(tree, i, i - 5, false);
- arrayMove(reference, i, i - 5, false);
- checkColumns(tree, reference, "drag each column 5 to the left");
- }
-
- // Test that moving a column after itself does not move anything
- synthesizeColumnDrag(tree, 0, 0, true);
- checkColumns(tree, reference, "drag to itself");
- is(document.treecolDragging, null, "drag to itself completed");
-
- // XXX roc should this be here???
- SimpleTest.finish();
-}
-
-function testtag_tree_wheel(aTree)
-{
- const deltaModes = [
- WheelEvent.DOM_DELTA_PIXEL, // 0
- WheelEvent.DOM_DELTA_LINE, // 1
- WheelEvent.DOM_DELTA_PAGE // 2
- ];
- function helper(aStart, aDelta, aIntDelta, aDeltaMode)
- {
- aTree.treeBoxObject.scrollToRow(aStart);
- var expected;
- if (!aIntDelta) {
- expected = aStart;
- }
- else if (aDeltaMode != WheelEvent.DOM_DELTA_PAGE) {
- expected = aStart + aIntDelta;
- }
- else if (aIntDelta > 0) {
- expected = aStart + aTree.treeBoxObject.getPageLength();
- }
- else {
- expected = aStart - aTree.treeBoxObject.getPageLength();
- }
-
- if (expected < 0) {
- expected = 0;
- }
- if (expected > aTree.view.rowCount - aTree.treeBoxObject.getPageLength()) {
- expected = aTree.view.rowCount - aTree.treeBoxObject.getPageLength();
- }
- synthesizeWheel(aTree.body, 1, 1,
- { deltaMode: aDeltaMode, deltaY: aDelta,
- lineOrPageDeltaY: aIntDelta });
- is(aTree.treeBoxObject.getFirstVisibleRow(), expected,
- "testtag_tree_wheel: vertical, starting " + aStart +
- " delta " + aDelta + " lineOrPageDelta " + aIntDelta +
- " aDeltaMode " + aDeltaMode);
-
- aTree.treeBoxObject.scrollToRow(aStart);
- // Check that horizontal scrolling has no effect
- synthesizeWheel(aTree.body, 1, 1,
- { deltaMode: aDeltaMode, deltaX: aDelta,
- lineOrPageDeltaX: aIntDelta });
- is(aTree.treeBoxObject.getFirstVisibleRow(), aStart,
- "testtag_tree_wheel: horizontal, starting " + aStart +
- " delta " + aDelta + " lineOrPageDelta " + aIntDelta +
- " aDeltaMode " + aDeltaMode);
- }
-
- var defaultPrevented = 0;
-
- function wheelListener(event) {
- defaultPrevented++;
- }
- window.addEventListener("wheel", wheelListener, false);
-
- deltaModes.forEach(function(aDeltaMode) {
- var delta = (aDeltaMode == WheelEvent.DOM_DELTA_PIXEL) ? 5.0 : 0.3;
- helper(2, -delta, 0, aDeltaMode);
- helper(2, -delta, -1, aDeltaMode);
- helper(2, delta, 0, aDeltaMode);
- helper(2, delta, 1, aDeltaMode);
- helper(2, -2 * delta, 0, aDeltaMode);
- helper(2, -2 * delta, -1, aDeltaMode);
- helper(2, 2 * delta, 0, aDeltaMode);
- helper(2, 2 * delta, 1, aDeltaMode);
- });
-
- window.removeEventListener("wheel", wheelListener, false);
- is(defaultPrevented, 48, "wheel event default prevented");
-}
-
-function synthesizeColumnDrag(aTree, aMouseDownColumnNumber, aMouseUpColumnNumber, aAfter)
-{
- var columns = getSortedColumnArray(aTree);
-
- var down = columns[aMouseDownColumnNumber].element;
- var up = columns[aMouseUpColumnNumber].element;
-
- // Target the initial mousedown in the middle of the column header so we
- // avoid the extra hit test space given to the splitter
- var columnWidth = down.boxObject.width;
- var splitterHitWidth = columnWidth / 2;
- synthesizeMouse(down, splitterHitWidth, 3, { type: "mousedown"});
-
- var offsetX = 0;
- if (aAfter) {
- offsetX = columnWidth;
- }
-
- if (aMouseUpColumnNumber > aMouseDownColumnNumber) {
- for (let i = aMouseDownColumnNumber; i <= aMouseUpColumnNumber; i++) {
- let move = columns[i].element;
- synthesizeMouse(move, offsetX, 3, { type: "mousemove"});
- }
- }
- else {
- for (let i = aMouseDownColumnNumber; i >= aMouseUpColumnNumber; i--) {
- let move = columns[i].element;
- synthesizeMouse(move, offsetX, 3, { type: "mousemove"});
- }
- }
-
- synthesizeMouse(up, offsetX, 3, { type: "mouseup"});
-}
-
-function arrayMove(aArray, aFrom, aTo, aAfter)
-{
- var o = aArray.splice(aFrom, 1)[0];
- if (aTo > aFrom) {
- aTo--;
- }
-
- if (aAfter) {
- aTo++;
- }
-
- aArray.splice(aTo, 0, o);
-}
-
-function getSortedColumnArray(aTree)
-{
- var columns = aTree.columns;
- var array = [];
- for (let i = 0; i < columns.length; i++) {
- array.push(columns.getColumnAt(i));
- }
-
- array.sort(function(a, b) {
- var o1 = parseInt(a.element.getAttribute("ordinal"));
- var o2 = parseInt(b.element.getAttribute("ordinal"));
- return o1 - o2;
- });
- return array;
-}
-
-function checkColumns(aTree, aReference, aMessage)
-{
- var columns = getSortedColumnArray(aTree);
- var ids = [];
- columns.forEach(function(e) {
- ids.push(e.element.id);
- });
- is(compareArrays(ids, aReference), true, aMessage);
-}
-
-function mouseOnCell(tree, row, column, testname)
-{
- var rect = tree.boxObject.getCoordsForCellItem(row, column, "text");
-
- synthesizeMouseExpectEvent(tree.body, rect.x, rect.y, {}, tree, "select", testname);
-}
-
-function mouseClickOnColumnHeader(aColumns, aColumnIndex, aButton, aClickCount)
-{
- var columnHeader = aColumns[aColumnIndex].element;
- var columnHeaderRect = columnHeader.getBoundingClientRect();
- var columnWidth = columnHeaderRect.right - columnHeaderRect.left;
- // For multiple click we send separate click events, with increasing
- // clickCount. This simulates the common behavior of multiple clicks.
- for (let i = 1; i <= aClickCount; i++) {
- // Target the middle of the column header.
- synthesizeMouse(columnHeader, columnWidth / 2, 3,
- { button: aButton,
- clickCount: i }, null);
- }
-}
-
-function mouseDblClickOnCell(tree, row, column, testname)
-{
- // select the row we will edit
- var selection = tree.view.selection;
- selection.select(row);
- tree.treeBoxObject.ensureRowIsVisible(row);
-
- // get cell coordinates
- var rect = tree.treeBoxObject.getCoordsForCellItem(row, column, "text");
-
- synthesizeMouse(tree.body, rect.x, rect.y, { clickCount: 2 }, null);
-}
-
-function compareArrays(arr1, arr2)
-{
- if (arr1.length != arr2.length)
- return false;
-
- for (let i = 0; i < arr1.length; i++) {
- if (arr1[i] != arr2[i])
- return false;
- }
-
- return true;
-}
-
-function convertProperties(arr)
-{
- var results = [];
- var count = arr.Count();
- for (let i = 0; i < count; i++)
- results.push(arr.GetElementAt(i).QueryInterface(Components.interfaces.nsIAtom).toString());
-
- results.sort();
- return results.join(" ");
-}
-
-function convertDOMtoTreeRowInfo(treechildren, level, rowidx)
-{
- var obj = { rows: [] };
-
- var parentidx = rowidx.value;
-
- treechildren = treechildren.childNodes;
- for (var r = 0; r < treechildren.length; r++) {
- rowidx.value++;
-
- var treeitem = treechildren[r];
- if (treeitem.hasChildNodes()) {
- var treerow = treeitem.firstChild;
- var cellInfo = [];
- for (var c = 0; c < treerow.childNodes.length; c++) {
- var cell = treerow.childNodes[c];
- cellInfo.push({ label: "" + cell.getAttribute("label"),
- value: cell.getAttribute("value"),
- properties: cell.getAttribute("properties"),
- editable: cell.getAttribute("editable") != "false",
- selectable: cell.getAttribute("selectable") != "false",
- image: cell.getAttribute("src"),
- mode: cell.hasAttribute("mode") ? parseInt(cell.getAttribute("mode")) : 3 });
- }
-
- var descendants = treeitem.lastChild;
- var children = (treerow == descendants) ? null :
- convertDOMtoTreeRowInfo(descendants, level + 1, rowidx);
- obj.rows.push({ cells: cellInfo,
- properties: treerow.getAttribute("properties"),
- container: treeitem.getAttribute("container") == "true",
- separator: treeitem.localName == "treeseparator",
- children: children,
- level: level,
- parent: parentidx });
- }
- }
-
- return obj;
-}