<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>
