3 <script src=
"../editing.js" language=
"JavaScript" type=
"text/JavaScript" ></script>
4 <style type=
"text/css">
6 color: black
!important
;
7 background: yellow
!important
;
8 padding: 0.5em !important
;
9 position: absolute
!important
;
10 z-index: 20000 !important
;
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
);
26 if (!window
.testRunner
)
28 testRunner
.waitUntilDone();
29 testRunner
.dumpAsText();
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);
40 e
= document
.getElementById("select_target");
41 r
= getAbsolutePosition(e
);
43 setSelectionCommand(e
, 0, e
, 1);
44 eventSender
.mouseMoveTo(0, 0);
45 window
.setTimeout("runTest3()", 200);
50 testRunner
.notifyDone();
53 function MPP_bind(fn
, self
, var_args
) {
54 var boundargs
= fn
.boundArgs_
|| [];
55 boundargs
= boundargs
.concat(Array
.prototype.slice
.call(arguments
, 2));
57 if (typeof fn
.boundSelf_
!= 'undefined') {
61 if (typeof fn
.foundFn_
!= 'undefined') {
65 var newfn = function() {
66 var args
= boundargs
.concat(Array
.prototype.slice
.call(arguments
));
67 return fn
.apply(self
, args
);
70 newfn
.boundArgs_
= boundargs
;
71 newfn
.boundSelf_
= self
;
77 function PersonPopup() {
81 this.pointerOnTargetElement
= false;
86 this.targetHeight
= 0;
87 this.targetElement
= 0;
91 this.pointerOutsidePopup
= false;
93 this.showTimerID
= -1;
94 this.hideTimerID
= -1;
96 window
.addEventListener('load',
97 MPP_bind(this.handleOnLoad_
, this), null);
101 PersonPopup
.prototype.getPointerX_ = function(e
) {
106 } else if (e
.clientX
) {
107 x
= e
.clientX
+ document
.scrollingElement
.scrollLeft
;
114 PersonPopup
.prototype.getPointerY_ = function(e
) {
119 } else if (e
.clientY
) {
120 y
= e
.clientY
+ document
.scrollingElement
.scrollTop
;
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;
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;
152 PersonPopup
.prototype.handleMouseMove_ = function(e
) {
153 if ((this.delayed
) || (this.visible
)) {
154 e
= e
|| window
.event
;
156 var x
= this.getPointerX_(e
);
157 var y
= this.getPointerY_(e
);
159 if (this.pointerCloseEnough_(x
, y
)) {
160 if (this.hideTimerID
) {
161 window
.clearTimeout(this.hideTimerID
);
162 this.hideTimerID
= -1;
165 if (this.hideTimerID
== -1) {
166 this.hideTimerID
= window
.setTimeout(MPP_bind(this.hide_
, this),
173 PersonPopup
.prototype.resizeElement_ = function(el
, x
, y
, w
, h
) {
175 el
.style
.left
= x
+ 'px';
178 el
.style
.top
= y
+ 'px';
181 el
.style
.width
= w
+ 'px';
184 el
.style
.height
= h
+ 'px';
188 PersonPopup
.prototype.show_ = function() {
189 this.showTimerID
= -1;
191 if (this.hideTimerID
!= -1) {
192 this.delayed
= false;
195 if (!this.pointerOnTargetElement
) {
196 this.delayed
= false;
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';
206 this.delayed
= false;
209 PersonPopup
.prototype.hide_ = function() {
210 this.hideTimerID
= -1;
211 this.popupDetailedElement
.style
.display
= 'none';
212 this.visible
= false;
213 this.delayed
= false;
216 PersonPopup
.prototype.handleAnchorMouseMove_ = function(e
) {
217 e
= e
|| window
.event
;
219 var targetElement
= (e
.target
) ? e
.target
: e
.srcElement
;
221 this.pointerOnTargetElement
= true;
223 if (targetElement
== this.targetElement
) {
224 this.x
= this.getPointerX_(e
);
225 this.y
= this.getPointerY_(e
);
228 this.handleAnchorMouseOver_(e
);
232 PersonPopup
.prototype.handleAnchorMouseOver_ = function(e
) {
233 e
= e
|| window
.event
;
234 var targetElement
= (e
.target
) ? e
.target
: e
.srcElement
;
237 (targetElement
== this.targetElement
) &&
238 (this.hideTimerID
== -1)) {
242 this.x
= this.getPointerX_(e
);
243 this.y
= this.getPointerY_(e
);
246 (targetElement
!= this.targetElement
) &&
247 (this.pointerCloseEnough_(this.x
, this.y
))) {
251 if (this.delayed
&& (this.targetElement
== targetElement
)) {
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);
265 if (this.showTimerID
!= -1) {
266 window
.clearTimeout(this.showTimerID
);
270 this.popupDetailedElement
.style
.display
= 'none';
272 window
.setTimeout(MPP_bind(this.show_
, this), 200);
275 window
.setTimeout(MPP_bind(this.show_
, this), 350);
279 this.pointerOutsidePopup
= true;
282 PersonPopup
.prototype.handleMouseOut_ = function(e
) {
283 if ((this.delayed
) || (this.visible
)) {
285 this.pointerOnTargetElement
= false;
287 e
= e
|| window
.event
;
292 if (e
.relatedTarget
) {
293 from = e
.relatedTarget
;
294 } else if (e
.toElement
) {
298 var targetElement
= (e
.target
) ? e
.target
: e
.srcElement
;
301 if ((from == null) || (from.tagName
== 'HTML') ||
302 (from.tagName
.substring(0, 3) == 'xul')) {
304 window
.setTimeout(MPP_bind(this.hide_
, this),
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
= ' ';
323 document
.body
.appendChild(this.popupDetailedElement
);
325 document
.body
.onmousemove
= MPP_bind(this.handleMouseMove_
, this);
326 document
.body
.onmouseout
= MPP_bind(this.handleMouseOut_
, this);
327 this.enablePopupsForChildElements(document
);
332 PersonPopup
.prototype.enablePopupsForChildElements = function(el
) {
333 var els
= el
.getElementsByTagName('*');
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);
343 var personPopup
= new PersonPopup();
348 <a class=
"showPersonPopup" id=
"mouse_target" href=
"dummy">Mouse Over
</a>
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