blob: d3d506e1570f398e145da5b80f76b0633a090d68 [file] [log] [blame]
<html>
<head>
<script src="../editing.js" language="JavaScript" type="text/JavaScript" ></script>
<style type="text/css">
div.popup {
color: black !important;
background: yellow !important;
padding: 0.5em !important;
position: absolute !important;
z-index: 20000 !important;
display: none;
}
</style>
<script type="text/javascript">
function getAbsolutePosition(element) {
var r = { x: element.offsetLeft, y: element.offsetTop };
if (element.offsetParent) {
var tmp = getAbsolutePosition(element.offsetParent);
r.x += tmp.x;
r.y += tmp.y;
}
return r;
}
function runTest1() {
if (!window.testRunner)
return;
testRunner.waitUntilDone();
testRunner.dumpAsText();
e = document.getElementById("mouse_target");
r = getAbsolutePosition(e);
x = r.x + e.offsetLeft + e.offsetWidth / 2;
y = r.y + e.offsetTop + e.offsetHeight / 2;
eventSender.mouseMoveTo(x, y);
window.setTimeout("runTest2()", 400);
}
function runTest2() {
e = document.getElementById("select_target");
r = getAbsolutePosition(e);
setSelectionCommand(e, 0, e, 1);
eventSender.mouseMoveTo(0, 0);
window.setTimeout("runTest3()", 200);
}
function runTest3() {
copyCommand();
testRunner.notifyDone();
}
function MPP_bind(fn, self, var_args) {
var boundargs = fn.boundArgs_ || [];
boundargs = boundargs.concat(Array.prototype.slice.call(arguments, 2));
if (typeof fn.boundSelf_ != 'undefined') {
self = fn.boundSelf_;
}
if (typeof fn.foundFn_ != 'undefined') {
fn = fn.boundFn_;
}
var newfn = function() {
var args = boundargs.concat(Array.prototype.slice.call(arguments));
return fn.apply(self, args);
}
newfn.boundArgs_ = boundargs;
newfn.boundSelf_ = self;
newfn.boundFn_ = fn;
return newfn;
};
function PersonPopup() {
this.pointerPosX = 0;
this.pointerPosY = 0;
this.pointerOnTargetElement = false;
this.targetPosX = 0;
this.targetPosY = 0;
this.targetWidth = 0;
this.targetHeight = 0;
this.targetElement = 0;
this.delayed = false;
this.visible = false;
this.pointerOutsidePopup = false;
this.showTimerID = -1;
this.hideTimerID = -1;
window.addEventListener('load',
MPP_bind(this.handleOnLoad_, this), null);
};
PersonPopup.prototype.getPointerX_ = function(e) {
var x, scrollLeft;
if (e.pageX) {
x = e.pageX;
} else if (e.clientX) {
x = e.clientX + document.scrollingElement.scrollLeft;
} else {
x = 0;
}
return x;
};
PersonPopup.prototype.getPointerY_ = function(e) {
var y, scrollTop;
if (e.pageY) {
y = e.pageY;
} else if (e.clientY) {
y = e.clientY + document.scrollingElement.scrollTop;
} else {
y = 0;
}
return y;
};
PersonPopup.prototype.pointerCloseEnough_ = function(x, y) {
var POINTER_TOLERANCE = 5;
if (this.pointerOutsidePopup) {
if ((x >= this.targetPosX) &&
(x <= this.targetPosX + this.targetWidth) &&
(y >= this.targetPosY) &&
(y <= this.targetPosY + this.targetHeight)) {
this.pointerOutsidePopup = false;
return true;
}
} else {
if ((x >= this.targetPosX - POINTER_TOLERANCE) &&
(x <= this.targetPosX + this.targetWidth +
POINTER_TOLERANCE) &&
(y >= this.targetPosY - POINTER_TOLERANCE) &&
(y <= this.targetPosY + this.targetHeight +
POINTER_TOLERANCE)) {
this.pointerOutsidePopup = false;
return true;
}
}
return false;
};
PersonPopup.prototype.handleMouseMove_ = function(e) {
if ((this.delayed) || (this.visible)) {
e = e || window.event;
var x = this.getPointerX_(e);
var y = this.getPointerY_(e);
if (this.pointerCloseEnough_(x, y)) {
if (this.hideTimerID) {
window.clearTimeout(this.hideTimerID);
this.hideTimerID = -1;
}
} else {
if (this.hideTimerID == -1) {
this.hideTimerID = window.setTimeout(MPP_bind(this.hide_, this),
200);
}
}
}
};
PersonPopup.prototype.resizeElement_ = function(el, x, y, w, h) {
if (x != false) {
el.style.left = x + 'px';
}
if (y != false) {
el.style.top = y + 'px';
}
if (w != false) {
el.style.width = w + 'px';
}
if (h != false) {
el.style.height = h + 'px';
}
};
PersonPopup.prototype.show_ = function() {
this.showTimerID = -1;
if (this.hideTimerID != -1) {
this.delayed = false;
return;
}
if (!this.pointerOnTargetElement) {
this.delayed = false;
return;
}
this.resizeElement_(this.popupDetailedElement,
this.targetPosX, this.targetPosY,
this.targetWidth, false);
this.popupDetailedElement.style.display = 'block';
this.popupDetailedElement.innerHTML = "<a href='http://dnede.com' id='select_target'>Select</a>";
this.popupDetailedElement.style.visibility = 'visible';
this.visible = true;
this.delayed = false;
};
PersonPopup.prototype.hide_ = function() {
this.hideTimerID = -1;
this.popupDetailedElement.style.display = 'none';
this.visible = false;
this.delayed = false;
};
PersonPopup.prototype.handleAnchorMouseMove_ = function(e) {
e = e || window.event;
var targetElement = (e.target) ? e.target : e.srcElement;
this.pointerOnTargetElement = true;
if (targetElement == this.targetElement) {
this.x = this.getPointerX_(e);
this.y = this.getPointerY_(e);
} else {
this.handleAnchorMouseOver_(e);
}
};
PersonPopup.prototype.handleAnchorMouseOver_ = function(e) {
e = e || window.event;
var targetElement = (e.target) ? e.target : e.srcElement;
if (this.visible &&
(targetElement == this.targetElement) &&
(this.hideTimerID == -1)) {
return;
}
this.x = this.getPointerX_(e);
this.y = this.getPointerY_(e);
if (this.visible &&
(targetElement != this.targetElement) &&
(this.pointerCloseEnough_(this.x, this.y))) {
return;
}
if (this.delayed && (this.targetElement == targetElement)) {
return;
}
this.targetElement = targetElement;
var screenWidth = self.innerWidth;
var screenHeight = self.innerHeight;
var scrollTop = document.documentElement.scrollTop;
var scrollLeft = document.documentElement.scrollLeft;
this.targetWidth = 12.7 * 26;
this.targetHeight = 12.7 * 13;
this.targetPosX = Math.floor(this.x + 15);
this.targetPosY = Math.floor(this.y + 20);
if (this.showTimerID != -1) {
window.clearTimeout(this.showTimerID);
}
if (this.visible) {
this.popupDetailedElement.style.display = 'none';
this.showTimerID =
window.setTimeout(MPP_bind(this.show_, this), 200);
} else {
this.showTimerID =
window.setTimeout(MPP_bind(this.show_, this), 350);
}
this.delayed = true;
this.pointerOutsidePopup = true;
};
PersonPopup.prototype.handleMouseOut_ = function(e) {
if ((this.delayed) || (this.visible)) {
this.pointerOnTargetElement = false;
e = e || window.event;
if (e) {
var from = null;
if (e.relatedTarget) {
from = e.relatedTarget;
} else if (e.toElement) {
from = e.toElement;
}
var targetElement = (e.target) ? e.target : e.srcElement;
try {
if ((from == null) || (from.tagName == 'HTML') ||
(from.tagName.substring(0, 3) == 'xul')) {
this.hideTimerID =
window.setTimeout(MPP_bind(this.hide_, this),
200);
}
} catch(e) {
}
}
}
};
PersonPopup.prototype.handleOnLoad_ = function(e) {
e = e || window.event;
this.popupDetailedElement = document.createElement('div');
this.popupDetailedElement.
setAttribute('id','popup_detailed');
this.popupDetailedElement.className = 'popup';
this.popupDetailedElement.style.display = 'none';
this.popupDetailedElement.style.position = 'absolute';
this.popupDetailedElement.innerHTML = '&nbsp;';
document.body.appendChild(this.popupDetailedElement);
document.body.onmousemove = MPP_bind(this.handleMouseMove_, this);
document.body.onmouseout = MPP_bind(this.handleMouseOut_, this);
this.enablePopupsForChildElements(document);
runTest1();
};
PersonPopup.prototype.enablePopupsForChildElements = function(el) {
var els = el.getElementsByTagName('*');
for (var i = 0, item; item = els[i]; i++) {
if (item.className.indexOf('showPersonPopup') != -1) {
item.onmouseover = MPP_bind(this.handleAnchorMouseOver_, this);
item.onmousemove = MPP_bind(this.handleAnchorMouseMove_, this);
}
}
};
var personPopup = new PersonPopup();
</script>
</head>
<body>
<p class="byline">
<a class="showPersonPopup" id="mouse_target" href="dummy">Mouse Over</a>
</p>
<div id="log_div">
This test checks the fix for https://bugs.webkit.org/show_bug.cgi?id=18506. To test it manually:
<li/> Hover mouse over "Mouse Over" link
<li/> Quickly jump to the yellow box that pops up and select "Select" link
<li/> Move mouse away so that pop up disappears
<li/> Press the "Copy" keyboard accelerator - this should not cause any crash
</div>
</body>
</html>