1/* 2 * Copyright (C) 2012 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31/** 32 * @constructor 33 * @param {Element} relativeToElement 34 * @param {WebInspector.DialogDelegate} delegate 35 */ 36WebInspector.Dialog = function(relativeToElement, delegate) 37{ 38 this._delegate = delegate; 39 this._relativeToElement = relativeToElement; 40 41 this._glassPane = new WebInspector.GlassPane(); 42 // Install glass pane capturing events. 43 this._glassPane.element.tabIndex = 0; 44 this._glassPane.element.addEventListener("focus", this._onGlassPaneFocus.bind(this), false); 45 46 this._element = this._glassPane.element.createChild("div"); 47 this._element.tabIndex = 0; 48 this._element.addEventListener("focus", this._onFocus.bind(this), false); 49 this._element.addEventListener("keydown", this._onKeyDown.bind(this), false); 50 this._closeKeys = [ 51 WebInspector.KeyboardShortcut.Keys.Enter.code, 52 WebInspector.KeyboardShortcut.Keys.Esc.code, 53 ]; 54 55 delegate.show(this._element); 56 57 this._position(); 58 this._windowResizeHandler = this._position.bind(this); 59 window.addEventListener("resize", this._windowResizeHandler, true); 60 this._delegate.focus(); 61} 62 63/** 64 * @return {WebInspector.Dialog} 65 */ 66WebInspector.Dialog.currentInstance = function() 67{ 68 return WebInspector.Dialog._instance; 69} 70 71/** 72 * @param {Element} relativeToElement 73 * @param {WebInspector.DialogDelegate} delegate 74 */ 75WebInspector.Dialog.show = function(relativeToElement, delegate) 76{ 77 if (WebInspector.Dialog._instance) 78 return; 79 WebInspector.Dialog._instance = new WebInspector.Dialog(relativeToElement, delegate); 80} 81 82WebInspector.Dialog.hide = function() 83{ 84 if (!WebInspector.Dialog._instance) 85 return; 86 WebInspector.Dialog._instance._hide(); 87} 88 89WebInspector.Dialog.prototype = { 90 _hide: function() 91 { 92 if (this._isHiding) 93 return; 94 this._isHiding = true; 95 96 this._delegate.willHide(); 97 98 delete WebInspector.Dialog._instance; 99 this._glassPane.dispose(); 100 window.removeEventListener("resize", this._windowResizeHandler, true); 101 }, 102 103 _onGlassPaneFocus: function(event) 104 { 105 this._hide(); 106 }, 107 108 _onFocus: function(event) 109 { 110 this._delegate.focus(); 111 }, 112 113 _position: function() 114 { 115 this._delegate.position(this._element, this._relativeToElement); 116 }, 117 118 _onKeyDown: function(event) 119 { 120 if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Tab.code) { 121 event.preventDefault(); 122 return; 123 } 124 125 if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Enter.code) 126 this._delegate.onEnter(); 127 128 if (this._closeKeys.indexOf(event.keyCode) >= 0) { 129 this._hide(); 130 event.consume(true); 131 } 132 } 133}; 134 135/** 136 * @constructor 137 * @extends {WebInspector.Object} 138 */ 139WebInspector.DialogDelegate = function() 140{ 141} 142 143WebInspector.DialogDelegate.prototype = { 144 /** 145 * @param {Element} element 146 */ 147 show: function(element) 148 { 149 element.appendChild(this.element); 150 this.element.addStyleClass("dialog-contents"); 151 element.addStyleClass("dialog"); 152 }, 153 154 /** 155 * @param {Element} element 156 * @param {Element} relativeToElement 157 */ 158 position: function(element, relativeToElement) 159 { 160 var offset = relativeToElement.offsetRelativeToWindow(window); 161 162 var positionX = offset.x + (relativeToElement.offsetWidth - element.offsetWidth) / 2; 163 positionX = Number.constrain(positionX, 0, window.innerWidth - element.offsetWidth); 164 165 var positionY = offset.y + (relativeToElement.offsetHeight - element.offsetHeight) / 2; 166 positionY = Number.constrain(positionY, 0, window.innerHeight - element.offsetHeight); 167 168 element.style.left = positionX + "px"; 169 element.style.top = positionY + "px"; 170 }, 171 172 focus: function() { }, 173 174 onEnter: function() { }, 175 176 willHide: function() { }, 177 178 __proto__: WebInspector.Object.prototype 179} 180 181