1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/components/tabview/test/browser_tabview_snapping.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,157 @@ 1.4 +/* Any copyright is dedicated to the Public Domain. 1.5 + http://creativecommons.org/publicdomain/zero/1.0/ */ 1.6 + 1.7 +function test() { 1.8 + waitForExplicitFinish(); 1.9 + 1.10 + newWindowWithTabView(onTabViewWindowLoaded, null, 1000, 800); 1.11 +} 1.12 + 1.13 +function onTabViewWindowLoaded(win) { 1.14 + let contentWindow = win.document.getElementById("tab-view").contentWindow; 1.15 + let [originalTab] = win.gBrowser.visibleTabs; 1.16 + 1.17 + ok(win.TabView.isVisible(), "Tab View is visible"); 1.18 + is(contentWindow.GroupItems.groupItems.length, 1, "There is only one group"); 1.19 + let currentActiveGroup = contentWindow.GroupItems.getActiveGroupItem(); 1.20 + 1.21 + // Create a group 1.22 + // Note: 150 x 150 should be larger than the minimum size for a group item 1.23 + let firstBox = new contentWindow.Rect(80, 80, 160, 160); 1.24 + let firstGroup = new contentWindow.GroupItem([], { bounds: firstBox, 1.25 + immediately: true }); 1.26 + ok(firstGroup.getBounds().equals(firstBox), "This group got its bounds"); 1.27 + 1.28 + // Create a second group 1.29 + let secondBox = new contentWindow.Rect(80, 280, 160, 160); 1.30 + let secondGroup = new contentWindow.GroupItem([], { bounds: secondBox, 1.31 + immediately: true }); 1.32 + ok(secondGroup.getBounds().equals(secondBox), "This second group got its bounds"); 1.33 + 1.34 + // A third group is created later, but multiple functions need access to it. 1.35 + let thirdGroup = null; 1.36 + 1.37 + is(secondGroup.getBounds().top - firstGroup.getBounds().bottom, 40, 1.38 + "There's currently 40 px between the first group and second group"); 1.39 + 1.40 + let endGame = function() { 1.41 + firstGroup.container.parentNode.removeChild(firstGroup.container); 1.42 + firstGroup.close(); 1.43 + thirdGroup.container.parentNode.removeChild(thirdGroup.container); 1.44 + thirdGroup.close(); 1.45 + 1.46 + win.close(); 1.47 + ok(win.closed, "new window is closed"); 1.48 + finish(); 1.49 + } 1.50 + 1.51 + let continueWithPart2 = function() { 1.52 + 1.53 + ok(firstGroup.getBounds().equals(firstBox), "The first group should still have its bounds"); 1.54 + 1.55 + // Create a third group 1.56 + let thirdBox = new contentWindow.Rect(80, 280, 200, 160); 1.57 + thirdGroup = new contentWindow.GroupItem([], { bounds: thirdBox, 1.58 + immediately: true }); 1.59 + ok(thirdGroup.getBounds().equals(thirdBox), "This third group got its bounds"); 1.60 + 1.61 + is(thirdGroup.getBounds().top - firstGroup.getBounds().bottom, 40, 1.62 + "There's currently 40 px between the first group and third group"); 1.63 + 1.64 + // Just move it to the left and drop it. 1.65 + checkSnap(thirdGroup, 0, 0, contentWindow, function(snapped){ 1.66 + ok(!snapped,"Offset: Just move it to the left and drop it"); 1.67 + 1.68 + // Move the second group up 10 px. It shouldn't snap yet. 1.69 + checkSnap(thirdGroup, 0, -10, contentWindow, function(snapped){ 1.70 + ok(!snapped,"Offset: Moving up 10 should not snap"); 1.71 + 1.72 + // Move the second group up 10 px. It now should snap. 1.73 + checkSnap(thirdGroup, 0, -10, contentWindow, function(snapped){ 1.74 + ok(snapped,"Offset: Moving up 10 again should snap!"); 1.75 + endGame(); 1.76 + }); 1.77 + }); 1.78 + }); 1.79 + }; 1.80 + 1.81 + let part1 = function() { 1.82 + // Just pick it up and drop it. 1.83 + checkSnap(secondGroup, 0, 0, contentWindow, function(snapped){ 1.84 + ok(!snapped,"Right under: Just pick it up and drop it"); 1.85 + 1.86 + // Move the second group up 10 px. It shouldn't snap yet. 1.87 + checkSnap(secondGroup, 0, -10, contentWindow, function(snapped){ 1.88 + ok(!snapped,"Right under: Moving up 10 should not snap"); 1.89 + 1.90 + // Move the second group up 10 px. It now should snap. 1.91 + checkSnap(secondGroup, 0, -10, contentWindow, function(snapped){ 1.92 + ok(snapped,"Right under: Moving up 10 again should snap!"); 1.93 + // cheat by removing the second group, so that we disappear immediately 1.94 + secondGroup.container.parentNode.removeChild(secondGroup.container); 1.95 + secondGroup.close(); 1.96 + continueWithPart2(); 1.97 + }); 1.98 + }); 1.99 + }); 1.100 + } 1.101 + 1.102 + part1(); 1.103 +} 1.104 + 1.105 +function simulateDragDrop(tabItem, offsetX, offsetY, contentWindow) { 1.106 + // enter drag mode 1.107 + let dataTransfer; 1.108 + 1.109 + EventUtils.synthesizeMouse( 1.110 + tabItem.container, 1, 1, { type: "mousedown" }, contentWindow); 1.111 + let event = contentWindow.document.createEvent("DragEvents"); 1.112 + event.initDragEvent( 1.113 + "dragenter", true, true, contentWindow, 0, 0, 0, 0, 0, 1.114 + false, false, false, false, 1, null, dataTransfer); 1.115 + tabItem.container.dispatchEvent(event); 1.116 + 1.117 + // drag over 1.118 + if (offsetX || offsetY) { 1.119 + let Ci = Components.interfaces; 1.120 + let utils = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor). 1.121 + getInterface(Ci.nsIDOMWindowUtils); 1.122 + let rect = tabItem.getBounds(); 1.123 + for (let i = 1; i <= 5; i++) { 1.124 + let left = rect.left + 1 + Math.round(i * offsetX / 5); 1.125 + let top = rect.top + 1 + Math.round(i * offsetY / 5); 1.126 + utils.sendMouseEvent("mousemove", left, top, 0, 1, 0); 1.127 + } 1.128 + event = contentWindow.document.createEvent("DragEvents"); 1.129 + event.initDragEvent( 1.130 + "dragover", true, true, contentWindow, 0, 0, 0, 0, 0, 1.131 + false, false, false, false, 0, null, dataTransfer); 1.132 + tabItem.container.dispatchEvent(event); 1.133 + } 1.134 + 1.135 + // drop 1.136 + EventUtils.synthesizeMouse( 1.137 + tabItem.container, 0, 0, { type: "mouseup" }, contentWindow); 1.138 + event = contentWindow.document.createEvent("DragEvents"); 1.139 + event.initDragEvent( 1.140 + "drop", true, true, contentWindow, 0, 0, 0, 0, 0, 1.141 + false, false, false, false, 0, null, dataTransfer); 1.142 + tabItem.container.dispatchEvent(event); 1.143 +} 1.144 + 1.145 +function checkSnap(item, offsetX, offsetY, contentWindow, callback) { 1.146 + let firstTop = item.getBounds().top; 1.147 + let firstLeft = item.getBounds().left; 1.148 + let onDrop = function() { 1.149 + let snapped = false; 1.150 + item.container.removeEventListener('drop', onDrop, false); 1.151 + if (item.getBounds().top != firstTop + offsetY) 1.152 + snapped = true; 1.153 + if (item.getBounds().left != firstLeft + offsetX) 1.154 + snapped = true; 1.155 + callback(snapped); 1.156 + }; 1.157 + item.container.addEventListener('drop', onDrop, false); 1.158 + simulateDragDrop(item, offsetX, offsetY, contentWindow); 1.159 +} 1.160 +