-->
Bookmark and Share

Bride of Windows

See the demo page for the finished version of the code.

To initialize the resize, the function finds the current cursor position relative to the page and the current position and size of the window, saving these values in the winCtrl variable.

  // Save cursor position.

  if (browser.isIE) {
    winCtrl.xPosition = window.event.x;
    winCtrl.yPosition = window.event.y;
  }
  if (browser.isNS) {
    winCtrl.xPosition = event.pageX;
    winCtrl.yPosition = event.pageY;
  }

  // Save window frame position and current window size.

  winCtrl.oldLeft   = parseInt(this.parentWindow.frame.style.left,  10);
  winCtrl.oldTop    = parseInt(this.parentWindow.frame.style.top,   10);
  winCtrl.oldWidth  = parseInt(this.parentWindow.frame.style.width, 10);
  winCtrl.oldHeight =
    parseInt(this.parentWindow.clientArea.style.height, 10);

  // Set document to capture mousemove and mouseup events.

  if (browser.isIE) {
    document.onmousemove = winResizeDragGo;
    document.onmouseup   = winResizeDragStop;
  }
  if (browser.isNS) {
    document.addEventListener("mousemove", winResizeDragGo,   true);
    document.addEventListener("mouseup"  , winResizeDragStop, true);
    event.preventDefault();
  }

  winCtrl.inResizeDrag = true;

Then, like the move drag, it sets up capturing for the mousemove and mouseup events at the document level and sets a flag in winCtrl to indicate that the resize drag has started.

Resizing the Window

The winResizeDragGo function is also similar to its move counterpart. The only difference being in what operations it performs on the window.

The first step is to set some flags based on the resize direction. Since width and height changes are independent, only four flags are needed even though there are eight possible directions.

  // Set direction flags based on original resize direction.

  north = false;
  south = false;
  east  = false;
  west  = false;
  if (winCtrl.resizeDirection.charAt(0) == "n")
    north = true;
  if (winCtrl.resizeDirection.charAt(0) == "s")
    south = true;
  if (winCtrl.resizeDirection.charAt(0) == "e" ||
      winCtrl.resizeDirection.charAt(1) == "e")
    east = true;
  if (winCtrl.resizeDirection.charAt(0) == "w" ||
      winCtrl.resizeDirection.charAt(1) == "w")
    west = true;

Then it checks the current cursor position to calculate the distance it has moved in both the horizontal and vertical directions from its starting position.

  // Find change in cursor position.

  if (browser.isIE) {
    dx = window.event.x - winCtrl.xPosition;
    dy = window.event.y - winCtrl.yPosition;
  }
  if (browser.isNS) {
    dx = event.pageX - winCtrl.xPosition;
    dy = event.pageY - winCtrl.yPosition;
  }

  // If resizing north or west, reverse corresponding amount.

  if (west)
    dx = -dx;
  if (north)
    dy = -dy;

Note that the distances depend on the original resize direction. For example, if the cursor started on the east edge of the window and moves right, the window width should be increased. But if the cursor started on the west edge and moves right, the window should be made narrower.

These distance values are added to the starting width and height of the window. The function also checks that neither drops below the limits set by the window's minimumWidth and minimumHeight values.

  // Check new size.

  w = winCtrl.oldWidth  + dx;
  h = winCtrl.oldHeight + dy;
  if (w <= winCtrl.active.minimumWidth) {
    w = winCtrl.active.minimumWidth;
    dx = w - winCtrl.oldWidth;
  }
  if (h <= winCtrl.active.minimumHeight) {
    h = winCtrl.active.minimumHeight;
    dy = h - winCtrl.oldHeight;
  }

If the new width or height are below the allowed minimum, they are set to equal the minimum.

Then it performs the resize, changing the frame (and, for IE, the client area) width for east-west resizes, and the client area height for north-south resizes.

  // Resize the window. For IE, keep client area and frame widths in
  // synch.

  if (east || west) {
    winCtrl.active.frame.style.width = w + "px";
    if (browser.isIE)
      winCtrl.active.clientArea.style.width =
        (w - winCtrl.active.widthDiff) + "px";
  }
  if (north || south)
    winCtrl.active.clientArea.style.height = h + "px";

  // Clip the title bar text, if necessary.

  if (east || west) {
    if (w < winCtrl.active.clipTextMinimumWidth)
      winCtrl.active.titleBarText.style.width =
        (winCtrl.minimizedTextWidth + w - winCtrl.active.minimumWidth) +
        "px";
    else
      winCtrl.active.titleBarText.style.width = "";
  }

Then it checks the new frame width to see if it's less than the window's clipTextMinimumWidth value. If so, the title bar text is clipped by calculating and setting a width on the element.

When resizing the window, it may be necessary to move it as well, so that the edge or corner that was under the cursor at the start of resize operation moves with the cursor as it is dragged. For the east and south edges, just resizing the window accomplishes this.

But for the north and west edges, the window needs to be repositioned. The code checks the direction flags and alters the window frame's left and/or top positions as needed.

  // For a north or west resize, move the window.

  if (west)
    winCtrl.active.frame.style.left = (winCtrl.oldLeft - dx) + "px";
  if (north)
    winCtrl.active.frame.style.top  = (winCtrl.oldTop  - dy) + "px";

The last step in the event handler is to cancel the default action as is done with the move drag.