| 1 | /** |
| 2 | * To create a "drag" interaction, you typically register a mousedown event |
| 3 | * handler on the element where the drag begins. In that handler, you register a |
| 4 | * mouseup handler on the window to determine when the mouse is released, |
| 5 | * wherever that release happens. This works well, except when the user releases |
| 6 | * the mouse over an off-domain iframe. In that case, the mouseup event is |
| 7 | * handled by the iframe and never bubbles up to the window handler. |
| 8 | * |
| 9 | * To deal with this issue, we cover iframes with high z-index divs to make sure |
| 10 | * they don't capture mouseup. |
| 11 | * |
| 12 | * Usage: |
| 13 | * element.addEventListener('mousedown', function() { |
| 14 | * var tarper = new IFrameTarp(); |
| 15 | * tarper.cover(); |
| 16 | * var mouseUpHandler = function() { |
| 17 | * ... |
| 18 | * window.removeEventListener(mouseUpHandler); |
| 19 | * tarper.uncover(); |
| 20 | * }; |
| 21 | * window.addEventListener('mouseup', mouseUpHandler); |
| 22 | * }; |
| 23 | * |
| 24 | * @constructor |
| 25 | */ |
| 26 | function IFrameTarp() { |
| 27 | /** @type {Array.<!HTMLDivElement>} */ |
| 28 | this.tarps = []; |
| 29 | }; |
| 30 | |
| 31 | /** |
| 32 | * Find all the iframes in the document and cover them with high z-index |
| 33 | * transparent divs. |
| 34 | */ |
| 35 | IFrameTarp.prototype.cover = function() { |
| 36 | var iframes = document.getElementsByTagName("iframe"); |
| 37 | for (var i = 0; i < iframes.length; i++) { |
| 38 | var iframe = iframes[i]; |
| 39 | var pos = utils.findPos(iframe), |
| 40 | x = pos.x, |
| 41 | y = pos.y, |
| 42 | width = iframe.offsetWidth, |
| 43 | height = iframe.offsetHeight; |
| 44 | |
| 45 | var div = document.createElement("div"); |
| 46 | div.style.position = "absolute"; |
| 47 | div.style.left = x + 'px'; |
| 48 | div.style.top = y + 'px'; |
| 49 | div.style.width = width + 'px'; |
| 50 | div.style.height = height + 'px'; |
| 51 | div.style.zIndex = 999; |
| 52 | document.body.appendChild(div); |
| 53 | this.tarps.push(div); |
| 54 | } |
| 55 | }; |
| 56 | |
| 57 | /** |
| 58 | * Remove all the iframe covers. You should call this in a mouseup handler. |
| 59 | */ |
| 60 | IFrameTarp.prototype.uncover = function() { |
| 61 | for (var i = 0; i < this.tarps.length; i++) { |
| 62 | this.tarps[i].parentNode.removeChild(this.tarps[i]); |
| 63 | } |
| 64 | this.tarps = []; |
| 65 | }; |
| 66 | |
| 67 | export default IFrameTarp; |