Editing tests should use testRunner instead of layoutTestController
[WebKit-https.git] / LayoutTests / editing / pasteboard / copy-crash.html
1 <html>
2   <head>
3     <script src="../editing.js" language="JavaScript" type="text/JavaScript" ></script>
4     <style type="text/css">
5       div.popup {
6         color: black !important;
7         background: yellow !important;
8         padding: 0.5em !important;
9         position: absolute !important;
10         z-index: 20000 !important;
11         display: none;
12       }
13     </style>
14     <script type="text/javascript">
15       function getAbsolutePosition(element) {
16         var r = { x: element.offsetLeft, y: element.offsetTop };
17         if (element.offsetParent) {
18           var tmp = getAbsolutePosition(element.offsetParent);
19           r.x += tmp.x;
20           r.y += tmp.y;
21         }
22         return r;
23       }
24
25       function runTest1() {
26         if (!window.testRunner)
27           return;
28         testRunner.waitUntilDone();
29         testRunner.dumpAsText();
30
31         e = document.getElementById("mouse_target");
32         r = getAbsolutePosition(e);
33         x = r.x + e.offsetLeft + e.offsetWidth / 2;
34         y = r.y + e.offsetTop + e.offsetHeight / 2;
35         eventSender.mouseMoveTo(x, y);
36         window.setTimeout("runTest2()", 400);
37       }
38
39       function runTest2() {
40         e = document.getElementById("select_target");
41         r = getAbsolutePosition(e);
42
43         setSelectionCommand(e, 0, e, 1);
44         eventSender.mouseMoveTo(0, 0);
45         window.setTimeout("runTest3()", 200);
46       }
47
48       function runTest3() {
49         copyCommand();
50         testRunner.notifyDone();
51       }
52
53       function MPP_bind(fn, self, var_args) {
54         var boundargs = fn.boundArgs_ || [];
55         boundargs = boundargs.concat(Array.prototype.slice.call(arguments, 2));
56
57         if (typeof fn.boundSelf_ != 'undefined') {
58           self = fn.boundSelf_;
59         }
60
61         if (typeof fn.foundFn_ != 'undefined') {
62           fn = fn.boundFn_;
63         }
64
65         var newfn = function() {
66           var args = boundargs.concat(Array.prototype.slice.call(arguments));
67           return fn.apply(self, args);
68         }
69
70         newfn.boundArgs_ = boundargs;
71         newfn.boundSelf_ = self;
72         newfn.boundFn_ = fn;
73
74         return newfn;
75       };
76
77       function PersonPopup() {
78         this.pointerPosX = 0;
79         this.pointerPosY = 0;
80
81         this.pointerOnTargetElement = false;
82
83         this.targetPosX = 0;
84         this.targetPosY = 0;
85         this.targetWidth = 0;
86         this.targetHeight = 0;
87         this.targetElement = 0;
88
89         this.delayed = false;
90         this.visible = false;
91         this.pointerOutsidePopup = false;
92
93         this.showTimerID = -1;
94         this.hideTimerID = -1;
95
96         window.addEventListener('load',
97                                 MPP_bind(this.handleOnLoad_, this), null);
98
99       };
100
101       PersonPopup.prototype.getPointerX_ = function(e) {
102         var x, scrollLeft;
103
104         if (e.pageX) {
105           x = e.pageX;
106         } else if (e.clientX) {
107           x = e.clientX + document.body.scrollLeft;
108         } else {
109           x = 0;
110         }
111         return x;
112       };
113
114       PersonPopup.prototype.getPointerY_ = function(e) {
115         var y, scrollTop;
116
117         if (e.pageY) {
118           y = e.pageY;
119         } else if (e.clientY) {
120           y = e.clientY + document.body.scrollTop;
121         } else {
122           y = 0;
123         }
124         return y;
125       };
126
127       PersonPopup.prototype.pointerCloseEnough_ = function(x, y) {
128         var POINTER_TOLERANCE = 5;
129         if (this.pointerOutsidePopup) {
130           if ((x >= this.targetPosX) &&
131               (x <= this.targetPosX + this.targetWidth) &&
132               (y >= this.targetPosY) &&
133               (y <= this.targetPosY + this.targetHeight)) {
134             this.pointerOutsidePopup = false;
135             return true;
136           }
137         } else {
138           if ((x >= this.targetPosX - POINTER_TOLERANCE) &&
139               (x <= this.targetPosX + this.targetWidth +
140                     POINTER_TOLERANCE) &&
141               (y >= this.targetPosY - POINTER_TOLERANCE) &&
142               (y <= this.targetPosY + this.targetHeight +
143                     POINTER_TOLERANCE)) {
144             this.pointerOutsidePopup = false;
145             return true;
146           }
147         }
148
149         return false;
150       };
151
152       PersonPopup.prototype.handleMouseMove_ = function(e) {
153         if ((this.delayed) || (this.visible)) {
154           e = e || window.event;
155
156           var x = this.getPointerX_(e);
157           var y = this.getPointerY_(e);
158
159           if (this.pointerCloseEnough_(x, y)) {
160             if (this.hideTimerID) {
161               window.clearTimeout(this.hideTimerID);
162               this.hideTimerID = -1;
163             }
164           } else {
165             if (this.hideTimerID == -1) {
166               this.hideTimerID = window.setTimeout(MPP_bind(this.hide_, this),
167                                                    200);
168             }
169           }
170         }
171       };
172
173       PersonPopup.prototype.resizeElement_ = function(el, x, y, w, h) {
174         if (x != false) {
175           el.style.left = x + 'px';
176         }
177         if (y != false) {
178           el.style.top = y + 'px';
179         }
180         if (w != false) {
181           el.style.width = w + 'px';
182         }
183         if (h != false) {
184           el.style.height = h + 'px';
185         }
186       };
187
188       PersonPopup.prototype.show_ = function() {
189         this.showTimerID = -1;
190
191         if (this.hideTimerID != -1) {
192           this.delayed = false;
193           return;
194         }
195         if (!this.pointerOnTargetElement) {
196           this.delayed = false;
197           return;
198         }
199         this.resizeElement_(this.popupDetailedElement,
200                             this.targetPosX, this.targetPosY,
201                             this.targetWidth, false);
202         this.popupDetailedElement.style.display = 'block';
203         this.popupDetailedElement.innerHTML = "<a href='http://dnede.com' id='select_target'>Select</a>";
204         this.popupDetailedElement.style.visibility = 'visible';
205         this.visible = true;
206         this.delayed = false;
207       };
208
209       PersonPopup.prototype.hide_ = function() {
210         this.hideTimerID = -1;
211         this.popupDetailedElement.style.display = 'none';
212         this.visible = false;
213         this.delayed = false;
214       };
215
216       PersonPopup.prototype.handleAnchorMouseMove_ = function(e) {
217         e = e || window.event;
218
219         var targetElement = (e.target) ? e.target : e.srcElement;
220
221         this.pointerOnTargetElement = true;
222
223         if (targetElement == this.targetElement) {
224           this.x = this.getPointerX_(e);
225           this.y = this.getPointerY_(e);
226
227         } else {
228           this.handleAnchorMouseOver_(e);
229         }
230       };
231
232       PersonPopup.prototype.handleAnchorMouseOver_ = function(e) {
233         e = e || window.event;
234         var targetElement = (e.target) ? e.target : e.srcElement;
235
236         if (this.visible &&
237             (targetElement == this.targetElement) &&
238             (this.hideTimerID == -1)) {
239           return;
240         }
241
242         this.x = this.getPointerX_(e);
243         this.y = this.getPointerY_(e);
244
245         if (this.visible &&
246             (targetElement != this.targetElement) &&
247             (this.pointerCloseEnough_(this.x, this.y))) {
248           return;
249         }
250
251         if (this.delayed && (this.targetElement == targetElement)) {
252           return;
253         }
254
255         this.targetElement = targetElement;
256         var screenWidth = self.innerWidth;
257         var screenHeight = self.innerHeight;
258         var scrollTop = document.documentElement.scrollTop;
259         var scrollLeft = document.documentElement.scrollLeft;
260         this.targetWidth = 12.7 * 26;
261         this.targetHeight = 12.7 * 13;
262         this.targetPosX = Math.floor(this.x + 15);
263         this.targetPosY = Math.floor(this.y + 20);
264
265         if (this.showTimerID != -1) {
266           window.clearTimeout(this.showTimerID);
267         }
268
269         if (this.visible) {
270           this.popupDetailedElement.style.display = 'none';
271           this.showTimerID =
272             window.setTimeout(MPP_bind(this.show_, this), 200);
273         } else {
274           this.showTimerID =
275             window.setTimeout(MPP_bind(this.show_, this), 350);
276         }
277
278         this.delayed = true;
279         this.pointerOutsidePopup = true;
280       };
281
282       PersonPopup.prototype.handleMouseOut_ = function(e) {
283         if ((this.delayed) || (this.visible)) {
284
285           this.pointerOnTargetElement = false;
286
287           e = e || window.event;
288
289           if (e) {
290             var from = null;
291
292             if (e.relatedTarget) {
293               from = e.relatedTarget;
294             } else if (e.toElement) {
295               from = e.toElement;
296             }
297
298             var targetElement = (e.target) ? e.target : e.srcElement;
299
300             try {
301               if ((from == null) || (from.tagName == 'HTML') ||
302                   (from.tagName.substring(0, 3) == 'xul')) {
303                 this.hideTimerID =
304                   window.setTimeout(MPP_bind(this.hide_, this),
305                                     200);
306               }
307             } catch(e) {
308
309             }
310           }
311         }
312       };
313
314       PersonPopup.prototype.handleOnLoad_ = function(e) {
315         e = e || window.event;
316         this.popupDetailedElement = document.createElement('div');
317         this.popupDetailedElement.
318             setAttribute('id','popup_detailed');
319         this.popupDetailedElement.className = 'popup';
320         this.popupDetailedElement.style.display = 'none';
321         this.popupDetailedElement.style.position = 'absolute';
322         this.popupDetailedElement.innerHTML = '&nbsp;';
323         document.body.appendChild(this.popupDetailedElement);
324
325         document.body.onmousemove = MPP_bind(this.handleMouseMove_, this);
326         document.body.onmouseout = MPP_bind(this.handleMouseOut_, this);
327         this.enablePopupsForChildElements(document);
328         
329         runTest1();
330       };
331
332       PersonPopup.prototype.enablePopupsForChildElements = function(el) {
333         var els = el.getElementsByTagName('*');
334
335         for (var i = 0, item; item = els[i]; i++) {
336           if (item.className.indexOf('showPersonPopup') != -1) {
337             item.onmouseover = MPP_bind(this.handleAnchorMouseOver_, this);
338             item.onmousemove = MPP_bind(this.handleAnchorMouseMove_, this);
339           }
340         }
341       };
342       
343       var personPopup = new PersonPopup();
344     </script>
345   </head>
346   <body>
347     <p class="byline">
348         <a class="showPersonPopup" id="mouse_target" href="dummy">Mouse Over</a>
349     </p>
350     <div id="log_div">
351       This test checks the fix for https://bugs.webkit.org/show_bug.cgi?id=18506. To test it manually:
352       <li/> Hover mouse over "Mouse Over" link
353       <li/> Quickly jump to the yellow box that pops up and select "Select" link
354       <li/> Move mouse away so that pop up disappears
355       <li/> Press the "Copy" keyboard accelerator - this should not cause any crash
356     </div>
357   </body>
358 </html>