1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/** 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * @fileoverview This file provides utility functions for position popups. 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */ 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochcr.define('cr.ui', function() { 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch /** 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * Type def for rects as returned by getBoundingClientRect. 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * @typedef { {left: number, top: number, width: number, height: number, 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * right: number, bottom: number}} 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */ 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch var Rect; 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch /** 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * Enum for defining how to anchor a popup to an anchor element. 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * @enum {number} 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */ 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const AnchorType = { 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch /** 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * The popup's right edge is aligned with the left edge of the anchor. 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * The popup's top edge is aligned with the top edge of the anchor's top 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * edge. 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */ 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BEFORE: 1, // p: right, a: left, p: top, a: top 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch /** 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * The popop's left edge is aligned with the right edge of the anchor. 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * The popup's top edge is aligned with the top edge of the anchor's top 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * edge. 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */ 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AFTER: 2, // p: left a: right, p: top, a: top 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch /** 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * The popop's bottom edge is aligned with the top edge of the anchor. 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * The popup's left edge is aligned with the left edge of the anchor's top 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * edge. 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */ 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ABOVE: 3, // p: bottom, a: top, p: left, a: left 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch /** 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * The popop's top edge is aligned with the bottom edge of the anchor. 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * The popup's left edge is aligned with the left edge of the anchor's top 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * edge. 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */ 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BELOW: 4 // p: top, a: bottom, p: left, a: left 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch /** 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * Helper function for positionPopupAroundElement and positionPopupAroundRect. 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * @param {!Rect} anchorRect The rect for the anchor. 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * @param {!HTMLElement} popupElement The element used for the popup. 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * @param {AnchorType} type The type of anchoring to do. 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */ 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch function positionPopupAroundRect(anchorRect, popupElement, type) { 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch var popupRect = popupElement.getBoundingClientRect(); 60201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch var availRect; 61201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch var ownerDoc = popupElement.ownerDocument; 62201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch var cs = ownerDoc.defaultView.getComputedStyle(popupElement); 63201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch var docElement = ownerDoc.documentElement; 64201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 65201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (cs.position == 'fixed') { 66201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // For 'fixed' positioned popups, the available rectangle should be based 67201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // on the viewport rather than the document. 68201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch availRect = { 69201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch height: docElement.clientHeight, 70201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch width: docElement.clientWidth, 71201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch top: 0, 72201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch bottom: docElement.clientHeight, 73201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch left: 0, 74201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch right: docElement.clientWidth 75201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch }; 76201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } else { 77201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch availRect = popupElement.offsetParent.getBoundingClientRect(); 78201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 79201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick var rtl = cs.direction == 'rtl'; 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Flip BEFORE, AFTER based on RTL. 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rtl) { 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (type == AnchorType.BEFORE) 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch type = AnchorType.AFTER; 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else if (type == AnchorType.AFTER) 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch type = AnchorType.BEFORE; 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Flip type based on available size 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (type) { 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case AnchorType.BELOW: 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (anchorRect.bottom + popupRect.height > availRect.height && 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch popupRect.height <= anchorRect.top) { 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch type = AnchorType.ABOVE; 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case AnchorType.ABOVE: 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (popupRect.height > anchorRect.top && 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch anchorRect.bottom + popupRect.height <= availRect.height) { 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch type = AnchorType.BELOW; 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case AnchorType.AFTER: 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (anchorRect.right + popupRect.width > availRect.width && 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch popupRect.width <= anchorRect.left) { 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch type = AnchorType.BEFORE; 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case AnchorType.BEFORE: 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (popupRect.width > anchorRect.left && 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch anchorRect.right + popupRect.width <= availRect.width) { 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch type = AnchorType.AFTER; 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // flipping done 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch var style = popupElement.style; 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Reset all directions. 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch style.left = style.right = style.top = style.bottom = 'auto' 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Primary direction 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (type) { 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case AnchorType.BELOW: 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (anchorRect.bottom + popupRect.height <= availRect.height) 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch style.top = anchorRect.bottom + 'px'; 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch style.bottom = '0'; 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case AnchorType.ABOVE: 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (availRect.height - anchorRect.top >= 0) 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch style.bottom = availRect.height - anchorRect.top + 'px'; 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch style.top = '0'; 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case AnchorType.AFTER: 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (anchorRect.right + popupRect.width <= availRect.width) 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch style.left = anchorRect.right + 'px'; 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch style.right = '0'; 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case AnchorType.BEFORE: 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (availRect.width - anchorRect.left >= 0) 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch style.right = availRect.width - anchorRect.left + 'px'; 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch style.left = '0'; 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Secondary direction 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (type) { 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case AnchorType.BELOW: 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case AnchorType.ABOVE: 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rtl) { 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // align right edges 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (anchorRect.right - popupRect.width >= 0) { 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch style.right = availRect.width - anchorRect.right + 'px'; 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // align left edges 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (anchorRect.left + popupRect.width <= availRect.width) { 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch style.left = anchorRect.left + 'px'; 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // not enough room on either side 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch style.right = '0'; 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // align left edges 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (anchorRect.left + popupRect.width <= availRect.width) { 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch style.left = anchorRect.left + 'px'; 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // align right edges 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (anchorRect.right - popupRect.width >= 0) { 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch style.right = availRect.width - anchorRect.right + 'px'; 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // not enough room on either side 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch style.left = '0'; 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case AnchorType.AFTER: 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case AnchorType.BEFORE: 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // align top edges 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (anchorRect.top + popupRect.height <= availRect.height) { 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch style.top = anchorRect.top + 'px'; 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // align bottom edges 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (anchorRect.bottom - popupRect.height >= 0) { 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch style.bottom = availRect.height - anchorRect.bottom + 'px'; 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // not enough room on either side 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch style.top = '0'; 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch /** 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * Positions a popup element relative to an anchor element. The popup element 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * should have position set to absolute and it should be a child of the body 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * element. 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * @param {!HTMLElement} anchorElement The element that the popup is anchored 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * to. 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * @param {!HTMLElement} popupElement The popup element we are positioning. 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * @param {AnchorType} type The type of anchoring we want. 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */ 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch function positionPopupAroundElement(anchorElement, popupElement, type) { 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch var anchorRect = anchorElement.getBoundingClientRect(); 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch positionPopupAroundRect(anchorRect, popupElement, type); 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch /** 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * Positions a popup around a point. 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * @param {number} x The client x position. 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * @param {number} y The client y position. 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * @param {!HTMLElement} popupElement The popup element we are positioning. 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */ 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch function positionPopupAtPoint(x, y, popupElement) { 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch var rect = { 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch left: x, 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch top: y, 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch width: 0, 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch height: 0, 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch right: x, 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bottom: y 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch positionPopupAroundRect(rect, popupElement, AnchorType.BELOW); 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Export 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return { 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AnchorType: AnchorType, 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch positionPopupAroundElement: positionPopupAroundElement, 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch positionPopupAtPoint: positionPopupAtPoint 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}); 241