Copybara | 854996b | 2021-09-07 19:36:02 +0000 | [diff] [blame] | 1 | /* Copyright 2016 The Chromium Authors. All Rights Reserved. |
| 2 | * |
| 3 | * Use of this source code is governed by a BSD-style |
| 4 | * license that can be found in the LICENSE file or at |
| 5 | * https://developers.google.com/open-source/licenses/bsd |
| 6 | */ |
| 7 | |
| 8 | // functions for dealing with layout and geometry of page elements. |
| 9 | // Requires shapes.js |
| 10 | |
| 11 | /** returns the bounding box of the given DOM node in document space. |
| 12 | * |
| 13 | * @param {Element?} obj a DOM node. |
| 14 | * @return {Rect?} |
| 15 | */ |
| 16 | function nodeBounds(obj) { |
| 17 | if (!obj) return null; |
| 18 | |
| 19 | function fixRectForScrolling(r) { |
| 20 | // Need to take into account scrolling offset of ancestors (IE already does |
| 21 | // this) |
| 22 | for (let o = obj.offsetParent; |
| 23 | o && o.offsetParent; |
| 24 | o = o.offsetParent) { |
| 25 | if (o.scrollLeft) { |
| 26 | r.x -= o.scrollLeft; |
| 27 | } |
| 28 | if (o.scrollTop) { |
| 29 | r.y -= o.scrollTop; |
| 30 | } |
| 31 | } |
| 32 | } |
| 33 | |
| 34 | let refWindow; |
| 35 | if (obj.ownerDocument && obj.ownerDocument.parentWindow) { |
| 36 | refWindow = obj.ownerDocument.parentWindow; |
| 37 | } else if (obj.ownerDocument && obj.ownerDocument.defaultView) { |
| 38 | refWindow = obj.ownerDocument.defaultView; |
| 39 | } else { |
| 40 | refWindow = window; |
| 41 | } |
| 42 | |
| 43 | // IE, Mozilla 3+ |
| 44 | if (obj.getBoundingClientRect) { |
| 45 | let rect = obj.getBoundingClientRect(); |
| 46 | |
| 47 | return new Rect(rect.left + GetScrollLeft(refWindow), |
| 48 | rect.top + GetScrollTop(refWindow), |
| 49 | rect.right - rect.left, |
| 50 | rect.bottom - rect.top, |
| 51 | refWindow); |
| 52 | } |
| 53 | |
| 54 | // Mozilla < 3 |
| 55 | if (obj.ownerDocument && obj.ownerDocument.getBoxObjectFor) { |
| 56 | let box = obj.ownerDocument.getBoxObjectFor(obj); |
| 57 | var r = new Rect(box.x, box.y, box.width, box.height, refWindow); |
| 58 | fixRectForScrolling(r); |
| 59 | return r; |
| 60 | } |
| 61 | |
| 62 | // Fallback to recursively computing this |
| 63 | let left = 0; |
| 64 | let top = 0; |
| 65 | for (let o = obj; o.offsetParent; o = o.offsetParent) { |
| 66 | left += o.offsetLeft; |
| 67 | top += o.offsetTop; |
| 68 | } |
| 69 | |
| 70 | var r = new Rect(left, top, obj.offsetWidth, obj.offsetHeight, refWindow); |
| 71 | fixRectForScrolling(r); |
| 72 | return r; |
| 73 | } |
| 74 | |
| 75 | function GetMousePosition(e) { |
| 76 | // copied from http://www.quirksmode.org/js/events_compinfo.html |
| 77 | let posx = 0; |
| 78 | let posy = 0; |
| 79 | if (e.pageX || e.pageY) { |
| 80 | posx = e.pageX; |
| 81 | posy = e.pageY; |
| 82 | } else if (e.clientX || e.clientY) { |
| 83 | let obj = (e.target ? e.target : e.srcElement); |
| 84 | let refWindow; |
| 85 | if (obj.ownerDocument && obj.ownerDocument.parentWindow) { |
| 86 | refWindow = obj.ownerDocument.parentWindow; |
| 87 | } else { |
| 88 | refWindow = window; |
| 89 | } |
| 90 | posx = e.clientX + GetScrollLeft(refWindow); |
| 91 | posy = e.clientY + GetScrollTop(refWindow); |
| 92 | } |
| 93 | return new Point(posx, posy, window); |
| 94 | } |