1010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis// Use of this source code is governed by a BSD-style license that can be 3010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis// found in the LICENSE file. 4010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis'use strict'; 6010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 7010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis/** 8010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * @fileoverview Implements an element that is hidden by default, but 9010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * when shown, dims and (attempts to) disable the main document. 10010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * 11010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * You can turn any div into an overlay. Note that while an 12010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * overlay element is shown, its parent is changed. Hiding the overlay 13010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * restores its original parentage. 14010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * 15010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis */ 1666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.requireStylesheet('ui.overlay'); 1766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 1866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.require('base.properties'); 1966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.require('base.events'); 202da489cd246702bee5938545b18a6f710ed214bcJamie Gennisbase.require('ui'); 2166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 2266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.exportTo('ui', function() { 23010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis /** 24010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * Manages a full-window div that darkens the window, disables 25010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * input, and hosts the currently-visible overlays. You shouldn't 26010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * have to instantiate this directly --- it gets set automatically. 27010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * @param {Object=} opt_propertyBag Optional properties. 28010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * @constructor 29010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * @extends {HTMLDivElement} 30010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis */ 3166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var OverlayRoot = ui.define('div'); 32010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis OverlayRoot.prototype = { 33010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis __proto__: HTMLDivElement.prototype, 34010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis decorate: function() { 35010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.classList.add('overlay-root'); 3666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 3766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 3866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.createToolBar_(); 39010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 40010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.contentHost = this.ownerDocument.createElement('div'); 41010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.contentHost.classList.add('content-host'); 42010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 43010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.tabCatcher = this.ownerDocument.createElement('span'); 44010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.tabCatcher.tabIndex = 0; 45010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 46010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.appendChild(this.contentHost); 47010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 4866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.onKeydown_ = this.onKeydown_.bind(this); 4966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.onFocusIn_ = this.onFocusIn_.bind(this); 50010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.addEventListener('mousedown', this.onMousedown_.bind(this)); 51010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis }, 52010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 5366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis toggleToolbar: function(show) { 5466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (show) { 5566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (this.contentHost.firstChild) 5666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.contentHost.insertBefore(this.contentHost.firstChild, 5766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.toolbar_); 5866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis else 5966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.contentHost.appendChild(this.toolbar_); 6066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } else { 6166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (this.toolbar_.parentElement) 6266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.contentHost.removeChild(this.toolbar_); 6366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 6466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 6566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 6666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis createToolBar_: function() { 6766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.toolbar_ = this.ownerDocument.createElement('div'); 6866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.toolbar_.className = 'tool-bar'; 6966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.exitButton_ = this.ownerDocument.createElement('span'); 7066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.exitButton_.className = 'exit-button'; 7166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.exitButton_.textContent = 'x'; 7266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.exitButton_.title = 'Close Overlay (esc)'; 7366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.toolbar_.appendChild(this.exitButton_); 7466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 7566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 76010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis /** 77010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * Adds an overlay, attaching it to the contentHost so that it is visible. 78010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis */ 79010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis showOverlay: function(overlay) { 80010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // Reparent this to the overlay content host. 81010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis overlay.oldParent_ = overlay.parentNode; 82010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.contentHost.appendChild(overlay); 83010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.contentHost.appendChild(this.tabCatcher); 84010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 85010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // Show the overlay root. 86010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.ownerDocument.body.classList.add('disabled-by-overlay'); 87010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 88010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // Bring overlay into focus. 89010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis overlay.tabIndex = 0; 90010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis var focusElement = 91010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis overlay.querySelector('button, input, list, select, a'); 92010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (!focusElement) { 93010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis focusElement = overlay; 94010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 95010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis focusElement.focus(); 96010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 97010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // Listen to key and focus events to prevent focus from 98010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // leaving the overlay. 9966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.ownerDocument.addEventListener('focusin', this.onFocusIn_, true); 10066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis overlay.addEventListener('keydown', this.onKeydown_); 101010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis }, 102010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 103010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis /** 104010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * Clicking outside of the overlay will de-focus the overlay. The 105010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * next tab will look at the entire document to determine the focus. 106010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * For certain documents, this can cause focus to "leak" outside of 107010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * the overlay. 108010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis */ 109010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis onMousedown_: function(e) { 110010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (e.target == this) { 111010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis e.preventDefault(); 112010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 113010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis }, 114010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 115010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis /** 116010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * Prevents forward-tabbing out of the overlay 117010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis */ 118010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis onFocusIn_: function(e) { 119010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (e.target == this.tabCatcher) { 120010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis window.setTimeout(this.focusOverlay_.bind(this), 0); 121010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 122010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis }, 123010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 124010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis focusOverlay_: function() { 125010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.contentHost.firstChild.focus(); 126010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis }, 127010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 128010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis /** 129010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * Prevent the user from shift-tabbing backwards out of the overlay. 130010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis */ 131010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis onKeydown_: function(e) { 13288448d9ae4dfff1805045790ef5f32495d62abccJeff Brown if (e.keyCode == 9 && // tab 133010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis e.shiftKey && 134010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis e.target == this.contentHost.firstChild) { 135010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis e.preventDefault(); 136010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 137010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis }, 138010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 139010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis /** 140010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * Hides an overlay, attaching it to its original parent if needed. 141010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis */ 142010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis hideOverlay: function(overlay) { 143010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // hide the overlay root 144010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.visible = false; 145010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.ownerDocument.body.classList.remove('disabled-by-overlay'); 146010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.lastFocusOut_ = undefined; 147010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 148010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // put the overlay back on its previous parent 149010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis overlay.parentNode.removeChild(this.tabCatcher); 150010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (overlay.oldParent_) { 151010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis overlay.oldParent_.appendChild(overlay); 152010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis delete overlay.oldParent_; 153010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } else { 154010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.contentHost.removeChild(overlay); 155010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 156010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 157010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // remove listeners 15866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis overlay.removeEventListener('keydown', this.onKeydown_); 15966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.ownerDocument.removeEventListener('focusin', this.onFocusIn_); 160010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 161010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis }; 162010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 163010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis /** 164010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * Creates a new overlay element. It will not be visible until shown. 165010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * @param {Object=} opt_propertyBag Optional properties. 166010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * @constructor 167010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * @extends {HTMLDivElement} 168010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis */ 16966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var Overlay = ui.define('div'); 170010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 171010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis Overlay.prototype = { 172010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis __proto__: HTMLDivElement.prototype, 173010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 174010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis /** 175010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis * Initializes the overlay element. 176010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis */ 177010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis decorate: function() { 178010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis // create the overlay root on this document if its not present 179010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (!this.ownerDocument.querySelector('.overlay-root')) { 180010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis var overlayRoot = this.ownerDocument.createElement('div'); 18166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis ui.decorate(overlayRoot, OverlayRoot); 182010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.ownerDocument.body.appendChild(overlayRoot); 183010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 184010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 185010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis this.classList.add('overlay'); 18666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.visible_ = false; 18766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.obeyCloseEvents = false; 1882da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.additionalCloseKeyCodes = []; 1892da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.onKeyDown = this.onKeyDown.bind(this); 1902da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.onKeyPress = this.onKeyPress.bind(this); 1912da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.onDocumentClick = this.onDocumentClick.bind(this); 19266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.addEventListener('visibleChange', 19366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis Overlay.prototype.onVisibleChange_.bind(this), true); 19466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.obeyCloseEvents = true; 195010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis }, 196010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 19766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis get visible() { 19866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return this.visible_; 19966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 20066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 20166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis set visible(newValue) { 20266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis base.setPropertyAndDispatchChange(this, 'visible', newValue); 20366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 20466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 20566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis get obeyCloseEvents() { 20666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return this.obeyCloseEvents_; 20766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 20866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 20966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis set obeyCloseEvents(newValue) { 21066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis base.setPropertyAndDispatchChange(this, 'obeyCloseEvents', newValue); 21166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var overlayRoot = this.ownerDocument.querySelector('.overlay-root'); 21266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis // Currently the toolbar only has the close button. 21366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis overlayRoot.toggleToolbar(newValue); 21466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 21566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 21666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis get toolbar() { 21766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return this.ownerDocument.querySelector('.overlay-root .tool-bar'); 21866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 21966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 22066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis onVisibleChange_: function() { 221010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis var overlayRoot = this.ownerDocument.querySelector('.overlay-root'); 222010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis if (this.visible) { 22366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis overlayRoot.setAttribute('visible', 'visible'); 224010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis overlayRoot.showOverlay(this); 2252da489cd246702bee5938545b18a6f710ed214bcJamie Gennis document.addEventListener('keydown', this.onKeyDown, true); 2262da489cd246702bee5938545b18a6f710ed214bcJamie Gennis document.addEventListener('keypress', this.onKeyPress, true); 2272da489cd246702bee5938545b18a6f710ed214bcJamie Gennis document.addEventListener('click', this.onDocumentClick, true); 228010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } else { 22966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis overlayRoot.removeAttribute('visible'); 2302da489cd246702bee5938545b18a6f710ed214bcJamie Gennis document.removeEventListener('keydown', this.onKeyDown, true); 2312da489cd246702bee5938545b18a6f710ed214bcJamie Gennis document.removeEventListener('keypress', this.onKeyPress, true); 2322da489cd246702bee5938545b18a6f710ed214bcJamie Gennis document.removeEventListener('click', this.onDocumentClick, true); 233010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis overlayRoot.hideOverlay(this); 234010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 2352da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 2362da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2372da489cd246702bee5938545b18a6f710ed214bcJamie Gennis onKeyDown: function(e) { 23866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (!this.obeyCloseEvents) 2392da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return; 2402da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 24188448d9ae4dfff1805045790ef5f32495d62abccJeff Brown if (e.keyCode == 27) { // escape 2422da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.visible = false; 2432da489cd246702bee5938545b18a6f710ed214bcJamie Gennis e.preventDefault(); 2442da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return; 2452da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 2462da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 2472da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2482da489cd246702bee5938545b18a6f710ed214bcJamie Gennis onKeyPress: function(e) { 24966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (!this.obeyCloseEvents) 2502da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return; 2512da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2522da489cd246702bee5938545b18a6f710ed214bcJamie Gennis for (var i = 0; i < this.additionalCloseKeyCodes.length; i++) { 2532da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (e.keyCode == this.additionalCloseKeyCodes[i]) { 2542da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.visible = false; 2552da489cd246702bee5938545b18a6f710ed214bcJamie Gennis e.preventDefault(); 2562da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return; 2572da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 2582da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 2592da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 2602da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2612da489cd246702bee5938545b18a6f710ed214bcJamie Gennis onDocumentClick: function(e) { 26266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (!this.obeyCloseEvents) 2632da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return; 2642da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var target = e.target; 2652da489cd246702bee5938545b18a6f710ed214bcJamie Gennis while (target !== null) { 2662da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (target === this) 2672da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return; 2682da489cd246702bee5938545b18a6f710ed214bcJamie Gennis target = target.parentNode; 2692da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 2702da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.visible = false; 2712da489cd246702bee5938545b18a6f710ed214bcJamie Gennis e.preventDefault(); 2722da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return; 273010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis } 2742da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 275010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis }; 276010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis 277010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis return { 278010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis Overlay: Overlay 279010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis }; 280010583560e0e6db74fe50b840bce46ba6537de63Jamie Gennis}); 281