1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/accessible/tests/mochitest/events/test_tree.xul Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,348 @@ 1.4 +<?xml version="1.0"?> 1.5 +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> 1.6 +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" 1.7 + type="text/css"?> 1.8 + 1.9 +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" 1.10 + title="DOM TreeRowCountChanged and a11y name change events."> 1.11 + 1.12 + <script type="application/javascript" 1.13 + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> 1.14 + 1.15 + <script type="application/javascript" 1.16 + src="../treeview.js" /> 1.17 + 1.18 + <script type="application/javascript" 1.19 + src="../common.js" /> 1.20 + <script type="application/javascript" 1.21 + src="../events.js" /> 1.22 + 1.23 + <script type="application/javascript"> 1.24 + <![CDATA[ 1.25 + 1.26 + //////////////////////////////////////////////////////////////////////////// 1.27 + // Invoker's checkers 1.28 + 1.29 + /** 1.30 + * Check TreeRowCountChanged event. 1.31 + */ 1.32 + function rowCountChangedChecker(aMsg, aIdx, aCount) 1.33 + { 1.34 + this.type = "TreeRowCountChanged"; 1.35 + this.target = gTree; 1.36 + this.check = function check(aEvent) 1.37 + { 1.38 + var propBag = aEvent.detail.QueryInterface(Components.interfaces.nsIPropertyBag2); 1.39 + var index = propBag.getPropertyAsInt32("index"); 1.40 + is(index, aIdx, "Wrong 'index' data of 'treeRowCountChanged' event."); 1.41 + 1.42 + var count = propBag.getPropertyAsInt32("count"); 1.43 + is(count, aCount, "Wrong 'count' data of 'treeRowCountChanged' event."); 1.44 + } 1.45 + this.getID = function getID() 1.46 + { 1.47 + return aMsg + "TreeRowCountChanged"; 1.48 + } 1.49 + } 1.50 + 1.51 + /** 1.52 + * Check TreeInvalidated event. 1.53 + */ 1.54 + function treeInvalidatedChecker(aMsg, aStartRow, aEndRow, aStartCol, aEndCol) 1.55 + { 1.56 + this.type = "TreeInvalidated"; 1.57 + this.target = gTree; 1.58 + this.check = function check(aEvent) 1.59 + { 1.60 + var propBag = aEvent.detail.QueryInterface(Components.interfaces.nsIPropertyBag2); 1.61 + try { 1.62 + var startRow = propBag.getPropertyAsInt32("startrow"); 1.63 + } catch (e if e.name == 'NS_ERROR_NOT_AVAILABLE') { 1.64 + startRow = null; 1.65 + } 1.66 + is(startRow, aStartRow, 1.67 + "Wrong 'startrow' of 'treeInvalidated' event on " + aMsg); 1.68 + 1.69 + try { 1.70 + var endRow = propBag.getPropertyAsInt32("endrow"); 1.71 + } catch (e if e.name == 'NS_ERROR_NOT_AVAILABLE') { 1.72 + endRow = null; 1.73 + } 1.74 + is(endRow, aEndRow, 1.75 + "Wrong 'endrow' of 'treeInvalidated' event on " + aMsg); 1.76 + 1.77 + try { 1.78 + var startCol = propBag.getPropertyAsInt32("startcolumn"); 1.79 + } catch (e if e.name == 'NS_ERROR_NOT_AVAILABLE') { 1.80 + startCol = null; 1.81 + } 1.82 + is(startCol, aStartCol, 1.83 + "Wrong 'startcolumn' of 'treeInvalidated' event on " + aMsg); 1.84 + 1.85 + try { 1.86 + var endCol = propBag.getPropertyAsInt32("endcolumn"); 1.87 + } catch (e if e.name == 'NS_ERROR_NOT_AVAILABLE') { 1.88 + startCol = null; 1.89 + } 1.90 + is(endCol, aEndCol, 1.91 + "Wrong 'endcolumn' of 'treeInvalidated' event on " + aMsg); 1.92 + } 1.93 + this.getID = function getID() 1.94 + { 1.95 + return "TreeInvalidated on " + aMsg; 1.96 + } 1.97 + } 1.98 + 1.99 + /** 1.100 + * Check name changed a11y event. 1.101 + */ 1.102 + function nameChangeChecker(aMsg, aRow, aCol) 1.103 + { 1.104 + this.type = EVENT_NAME_CHANGE; 1.105 + 1.106 + function targetGetter() 1.107 + { 1.108 + var acc = getAccessible(gTree); 1.109 + 1.110 + var tableAcc = getAccessible(acc, [nsIAccessibleTable]); 1.111 + return tableAcc.getCellAt(aRow, aCol); 1.112 + } 1.113 + Object.defineProperty(this, "target", { get: targetGetter }); 1.114 + 1.115 + this.getID = function getID() 1.116 + { 1.117 + return aMsg + "name changed"; 1.118 + } 1.119 + } 1.120 + 1.121 + /** 1.122 + * Check name changed a11y event for a row. 1.123 + */ 1.124 + function rowNameChangeChecker(aMsg, aRow) 1.125 + { 1.126 + this.type = EVENT_NAME_CHANGE; 1.127 + 1.128 + function targetGetter() 1.129 + { 1.130 + var acc = getAccessible(gTree); 1.131 + return acc.getChildAt(aRow + 1); 1.132 + } 1.133 + Object.defineProperty(this, "target", { get: targetGetter }); 1.134 + 1.135 + this.getID = function getID() 1.136 + { 1.137 + return aMsg + "name changed"; 1.138 + } 1.139 + } 1.140 + 1.141 + //////////////////////////////////////////////////////////////////////////// 1.142 + // Invokers 1.143 + 1.144 + /** 1.145 + * Set tree view. 1.146 + */ 1.147 + function setTreeView() 1.148 + { 1.149 + this.invoke = function setTreeView_invoke() 1.150 + { 1.151 + gTreeBox.view = gView; 1.152 + } 1.153 + 1.154 + this.getID = function setTreeView_getID() { return "set tree view"; } 1.155 + 1.156 + this.eventSeq = [ 1.157 + new invokerChecker(EVENT_REORDER, gTree) 1.158 + ]; 1.159 + }; 1.160 + 1.161 + /** 1.162 + * Insert row at 0 index and checks TreeRowCountChanged and TreeInvalidated 1.163 + * event. 1.164 + */ 1.165 + function insertRow() 1.166 + { 1.167 + this.invoke = function insertRow_invoke() 1.168 + { 1.169 + gView.appendItem("last"); 1.170 + gTreeBox.rowCountChanged(0, 1); 1.171 + } 1.172 + 1.173 + this.eventSeq = 1.174 + [ 1.175 + new rowCountChangedChecker("insertRow: ", 0, 1), 1.176 + new treeInvalidatedChecker("insertRow", 0, 5, null, null) 1.177 + ]; 1.178 + 1.179 + this.getID = function insertRow_getID() 1.180 + { 1.181 + return "insert row"; 1.182 + } 1.183 + } 1.184 + 1.185 + /** 1.186 + * Invalidates first column and checks six name changed events for each 1.187 + * treeitem plus TreeInvalidated event. 1.188 + */ 1.189 + function invalidateColumn() 1.190 + { 1.191 + this.invoke = function invalidateColumn_invoke() 1.192 + { 1.193 + // Make sure accessible subtree of XUL tree is created otherwise no 1.194 + // name change events for cell accessibles are emitted. 1.195 + var tree = getAccessible(gTree); 1.196 + var child = tree.firstChild; 1.197 + var walkDown = true; 1.198 + while (child != tree) { 1.199 + if (walkDown) { 1.200 + var grandChild = child.firstChild; 1.201 + if (grandChild) { 1.202 + child = grandChild; 1.203 + continue; 1.204 + } 1.205 + } 1.206 + 1.207 + var sibling = child.nextSibling; 1.208 + if (sibling) { 1.209 + child = sibling; 1.210 + walkDown = true; 1.211 + continue; 1.212 + } 1.213 + 1.214 + child = child.parent; 1.215 + walkDown = false; 1.216 + } 1.217 + 1.218 + // Fire 'TreeInvalidated' event by InvalidateColumn() 1.219 + var firstCol = gTree.columns.getFirstColumn(); 1.220 + for (var i = 0; i < gView.rowCount; i++) 1.221 + gView.setCellText(i, firstCol, "hey " + String(i) + "x0"); 1.222 + 1.223 + gTreeBox.invalidateColumn(firstCol); 1.224 + } 1.225 + 1.226 + this.eventSeq = 1.227 + [ 1.228 + new nameChangeChecker("invalidateColumn: ", 0, 0), 1.229 + new nameChangeChecker("invalidateColumn: ", 1, 0), 1.230 + new nameChangeChecker("invalidateColumn: ", 2, 0), 1.231 + new nameChangeChecker("invalidateColumn: ", 3, 0), 1.232 + new nameChangeChecker("invalidateColumn: ", 4, 0), 1.233 + new nameChangeChecker("invalidateColumn: ", 5, 0), 1.234 + new treeInvalidatedChecker("invalidateColumn", null, null, 0, 0) 1.235 + ]; 1.236 + 1.237 + this.getID = function invalidateColumn_getID() 1.238 + { 1.239 + return "invalidate column"; 1.240 + } 1.241 + } 1.242 + 1.243 + /** 1.244 + * Invalidates second row and checks name changed event for first treeitem 1.245 + * (note, there are two name changed events on linux due to different 1.246 + * accessible tree for xul:tree element) plus TreeInvalidated event. 1.247 + */ 1.248 + function invalidateRow() 1.249 + { 1.250 + this.invoke = function invalidateRow_invoke() 1.251 + { 1.252 + // Fire 'TreeInvalidated' event by InvalidateRow() 1.253 + var colCount = gTree.columns.count; 1.254 + var column = gTree.columns.getFirstColumn(); 1.255 + while (column) { 1.256 + gView.setCellText(1, column, "aloha 1x" + String(column.index)); 1.257 + column = column.getNext(); 1.258 + } 1.259 + 1.260 + gTreeBox.invalidateRow(1); 1.261 + } 1.262 + 1.263 + this.eventSeq = 1.264 + [ 1.265 + new nameChangeChecker("invalidateRow: ", 1, 0), 1.266 + new nameChangeChecker("invalidateRow: ", 1, 1), 1.267 + new rowNameChangeChecker("invalidateRow: ", 1), 1.268 + new treeInvalidatedChecker("invalidateRow", 1, 1, null, null) 1.269 + ]; 1.270 + 1.271 + this.getID = function invalidateRow_getID() 1.272 + { 1.273 + return "invalidate row"; 1.274 + } 1.275 + } 1.276 + 1.277 + //////////////////////////////////////////////////////////////////////////// 1.278 + // Test 1.279 + 1.280 + var gTree = null; 1.281 + var gTreeBox = null; 1.282 + var gTreeView = null; 1.283 + var gQueue = null; 1.284 + 1.285 + // gA11yEventDumpID = "debug"; 1.286 + gA11yEventDumpToConsole = true; // debuggin 1.287 + 1.288 + function doTest() 1.289 + { 1.290 + // Initialize the tree 1.291 + gTree = document.getElementById("tree"); 1.292 + gTreeBox = gTree.treeBoxObject; 1.293 + gView = new nsTableTreeView(5); 1.294 + 1.295 + // Perform actions 1.296 + gQueue = new eventQueue(); 1.297 + 1.298 + gQueue.push(new setTreeView()); 1.299 + gQueue.push(new insertRow()); 1.300 + gQueue.push(new invalidateColumn()); 1.301 + gQueue.push(new invalidateRow()); 1.302 + 1.303 + gQueue.invoke(); 1.304 + } 1.305 + 1.306 + SimpleTest.waitForExplicitFinish(); 1.307 + addA11yLoadEvent(doTest); 1.308 + ]]> 1.309 + </script> 1.310 + 1.311 + <hbox flex="1" style="overflow: auto;"> 1.312 + <body xmlns="http://www.w3.org/1999/xhtml"> 1.313 + <a target="_blank" 1.314 + href="https://bugzilla.mozilla.org/show_bug.cgi?id=368835" 1.315 + title="Fire TreeViewChanged/TreeRowCountChanged events."> 1.316 + Mozilla Bug 368835 1.317 + </a><br/> 1.318 + <a target="_blank" 1.319 + href="https://bugzilla.mozilla.org/show_bug.cgi?id=308564" 1.320 + title="No accessibility events when data in a tree row changes."> 1.321 + Mozilla Bug 308564 1.322 + </a><br/> 1.323 + <a target="_blank" 1.324 + href="https://bugzilla.mozilla.org/show_bug.cgi?id=739524" 1.325 + title="replace TreeViewChanged DOM event on direct call from XUL tree."> 1.326 + Mozilla Bug 739524 1.327 + </a><br/> 1.328 + <a target="_blank" 1.329 + href="https://bugzilla.mozilla.org/show_bug.cgi?id=743568" 1.330 + title="Thunderbird message list tree emitting incorrect focus signals after message deleted."> 1.331 + Mozilla Bug 743568 1.332 + </a> 1.333 + <p id="display"></p> 1.334 + <div id="content" style="display: none"> 1.335 + </div> 1.336 + <pre id="test"> 1.337 + </pre> 1.338 + </body> 1.339 + 1.340 + <vbox id="debug"/> 1.341 + <tree id="tree" flex="1"> 1.342 + <treecols> 1.343 + <treecol id="col1" flex="1" primary="true" label="column"/> 1.344 + <treecol id="col2" flex="1" label="column 2"/> 1.345 + </treecols> 1.346 + <treechildren id="treechildren"/> 1.347 + </tree> 1.348 + </hbox> 1.349 + 1.350 +</window> 1.351 +