|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 function test() { |
|
5 waitForExplicitFinish(); |
|
6 |
|
7 newWindowWithTabView(onTabViewWindowLoaded, null, 1000, 800); |
|
8 } |
|
9 |
|
10 function onTabViewWindowLoaded(win) { |
|
11 let contentWindow = win.document.getElementById("tab-view").contentWindow; |
|
12 let [originalTab] = win.gBrowser.visibleTabs; |
|
13 |
|
14 ok(win.TabView.isVisible(), "Tab View is visible"); |
|
15 is(contentWindow.GroupItems.groupItems.length, 1, "There is only one group"); |
|
16 let currentActiveGroup = contentWindow.GroupItems.getActiveGroupItem(); |
|
17 |
|
18 // Create a group |
|
19 // Note: 150 x 150 should be larger than the minimum size for a group item |
|
20 let firstBox = new contentWindow.Rect(80, 80, 160, 160); |
|
21 let firstGroup = new contentWindow.GroupItem([], { bounds: firstBox, |
|
22 immediately: true }); |
|
23 ok(firstGroup.getBounds().equals(firstBox), "This group got its bounds"); |
|
24 |
|
25 // Create a second group |
|
26 let secondBox = new contentWindow.Rect(80, 280, 160, 160); |
|
27 let secondGroup = new contentWindow.GroupItem([], { bounds: secondBox, |
|
28 immediately: true }); |
|
29 ok(secondGroup.getBounds().equals(secondBox), "This second group got its bounds"); |
|
30 |
|
31 // A third group is created later, but multiple functions need access to it. |
|
32 let thirdGroup = null; |
|
33 |
|
34 is(secondGroup.getBounds().top - firstGroup.getBounds().bottom, 40, |
|
35 "There's currently 40 px between the first group and second group"); |
|
36 |
|
37 let endGame = function() { |
|
38 firstGroup.container.parentNode.removeChild(firstGroup.container); |
|
39 firstGroup.close(); |
|
40 thirdGroup.container.parentNode.removeChild(thirdGroup.container); |
|
41 thirdGroup.close(); |
|
42 |
|
43 win.close(); |
|
44 ok(win.closed, "new window is closed"); |
|
45 finish(); |
|
46 } |
|
47 |
|
48 let continueWithPart2 = function() { |
|
49 |
|
50 ok(firstGroup.getBounds().equals(firstBox), "The first group should still have its bounds"); |
|
51 |
|
52 // Create a third group |
|
53 let thirdBox = new contentWindow.Rect(80, 280, 200, 160); |
|
54 thirdGroup = new contentWindow.GroupItem([], { bounds: thirdBox, |
|
55 immediately: true }); |
|
56 ok(thirdGroup.getBounds().equals(thirdBox), "This third group got its bounds"); |
|
57 |
|
58 is(thirdGroup.getBounds().top - firstGroup.getBounds().bottom, 40, |
|
59 "There's currently 40 px between the first group and third group"); |
|
60 |
|
61 // Just move it to the left and drop it. |
|
62 checkSnap(thirdGroup, 0, 0, contentWindow, function(snapped){ |
|
63 ok(!snapped,"Offset: Just move it to the left and drop it"); |
|
64 |
|
65 // Move the second group up 10 px. It shouldn't snap yet. |
|
66 checkSnap(thirdGroup, 0, -10, contentWindow, function(snapped){ |
|
67 ok(!snapped,"Offset: Moving up 10 should not snap"); |
|
68 |
|
69 // Move the second group up 10 px. It now should snap. |
|
70 checkSnap(thirdGroup, 0, -10, contentWindow, function(snapped){ |
|
71 ok(snapped,"Offset: Moving up 10 again should snap!"); |
|
72 endGame(); |
|
73 }); |
|
74 }); |
|
75 }); |
|
76 }; |
|
77 |
|
78 let part1 = function() { |
|
79 // Just pick it up and drop it. |
|
80 checkSnap(secondGroup, 0, 0, contentWindow, function(snapped){ |
|
81 ok(!snapped,"Right under: Just pick it up and drop it"); |
|
82 |
|
83 // Move the second group up 10 px. It shouldn't snap yet. |
|
84 checkSnap(secondGroup, 0, -10, contentWindow, function(snapped){ |
|
85 ok(!snapped,"Right under: Moving up 10 should not snap"); |
|
86 |
|
87 // Move the second group up 10 px. It now should snap. |
|
88 checkSnap(secondGroup, 0, -10, contentWindow, function(snapped){ |
|
89 ok(snapped,"Right under: Moving up 10 again should snap!"); |
|
90 // cheat by removing the second group, so that we disappear immediately |
|
91 secondGroup.container.parentNode.removeChild(secondGroup.container); |
|
92 secondGroup.close(); |
|
93 continueWithPart2(); |
|
94 }); |
|
95 }); |
|
96 }); |
|
97 } |
|
98 |
|
99 part1(); |
|
100 } |
|
101 |
|
102 function simulateDragDrop(tabItem, offsetX, offsetY, contentWindow) { |
|
103 // enter drag mode |
|
104 let dataTransfer; |
|
105 |
|
106 EventUtils.synthesizeMouse( |
|
107 tabItem.container, 1, 1, { type: "mousedown" }, contentWindow); |
|
108 let event = contentWindow.document.createEvent("DragEvents"); |
|
109 event.initDragEvent( |
|
110 "dragenter", true, true, contentWindow, 0, 0, 0, 0, 0, |
|
111 false, false, false, false, 1, null, dataTransfer); |
|
112 tabItem.container.dispatchEvent(event); |
|
113 |
|
114 // drag over |
|
115 if (offsetX || offsetY) { |
|
116 let Ci = Components.interfaces; |
|
117 let utils = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor). |
|
118 getInterface(Ci.nsIDOMWindowUtils); |
|
119 let rect = tabItem.getBounds(); |
|
120 for (let i = 1; i <= 5; i++) { |
|
121 let left = rect.left + 1 + Math.round(i * offsetX / 5); |
|
122 let top = rect.top + 1 + Math.round(i * offsetY / 5); |
|
123 utils.sendMouseEvent("mousemove", left, top, 0, 1, 0); |
|
124 } |
|
125 event = contentWindow.document.createEvent("DragEvents"); |
|
126 event.initDragEvent( |
|
127 "dragover", true, true, contentWindow, 0, 0, 0, 0, 0, |
|
128 false, false, false, false, 0, null, dataTransfer); |
|
129 tabItem.container.dispatchEvent(event); |
|
130 } |
|
131 |
|
132 // drop |
|
133 EventUtils.synthesizeMouse( |
|
134 tabItem.container, 0, 0, { type: "mouseup" }, contentWindow); |
|
135 event = contentWindow.document.createEvent("DragEvents"); |
|
136 event.initDragEvent( |
|
137 "drop", true, true, contentWindow, 0, 0, 0, 0, 0, |
|
138 false, false, false, false, 0, null, dataTransfer); |
|
139 tabItem.container.dispatchEvent(event); |
|
140 } |
|
141 |
|
142 function checkSnap(item, offsetX, offsetY, contentWindow, callback) { |
|
143 let firstTop = item.getBounds().top; |
|
144 let firstLeft = item.getBounds().left; |
|
145 let onDrop = function() { |
|
146 let snapped = false; |
|
147 item.container.removeEventListener('drop', onDrop, false); |
|
148 if (item.getBounds().top != firstTop + offsetY) |
|
149 snapped = true; |
|
150 if (item.getBounds().left != firstLeft + offsetX) |
|
151 snapped = true; |
|
152 callback(snapped); |
|
153 }; |
|
154 item.container.addEventListener('drop', onDrop, false); |
|
155 simulateDragDrop(item, offsetX, offsetY, contentWindow); |
|
156 } |
|
157 |