Dialog.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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. * @constructor
  32. * @param {Element} relativeToElement
  33. * @param {WebInspector.DialogDelegate} delegate
  34. */
  35. WebInspector.Dialog = function(relativeToElement, delegate)
  36. {
  37. this._delegate = delegate;
  38. this._relativeToElement = relativeToElement;
  39. this._glassPane = new WebInspector.GlassPane();
  40. // Install glass pane capturing events.
  41. this._glassPane.element.tabIndex = 0;
  42. this._glassPane.element.addEventListener("focus", this._onGlassPaneFocus.bind(this), false);
  43. this._element = this._glassPane.element.createChild("div");
  44. this._element.tabIndex = 0;
  45. this._element.addEventListener("focus", this._onFocus.bind(this), false);
  46. this._element.addEventListener("keydown", this._onKeyDown.bind(this), false);
  47. this._closeKeys = [
  48. WebInspector.KeyboardShortcut.Keys.Enter.code,
  49. WebInspector.KeyboardShortcut.Keys.Esc.code,
  50. ];
  51. delegate.show(this._element);
  52. this._position();
  53. this._windowResizeHandler = this._position.bind(this);
  54. window.addEventListener("resize", this._windowResizeHandler, true);
  55. this._delegate.focus();
  56. }
  57. /**
  58. * @return {WebInspector.Dialog}
  59. */
  60. WebInspector.Dialog.currentInstance = function()
  61. {
  62. return WebInspector.Dialog._instance;
  63. }
  64. /**
  65. * @param {Element} relativeToElement
  66. * @param {WebInspector.DialogDelegate} delegate
  67. */
  68. WebInspector.Dialog.show = function(relativeToElement, delegate)
  69. {
  70. if (WebInspector.Dialog._instance)
  71. return;
  72. WebInspector.Dialog._instance = new WebInspector.Dialog(relativeToElement, delegate);
  73. }
  74. WebInspector.Dialog.hide = function()
  75. {
  76. if (!WebInspector.Dialog._instance)
  77. return;
  78. WebInspector.Dialog._instance._hide();
  79. }
  80. WebInspector.Dialog.prototype = {
  81. _hide: function()
  82. {
  83. if (this._isHiding)
  84. return;
  85. this._isHiding = true;
  86. this._delegate.willHide();
  87. delete WebInspector.Dialog._instance;
  88. this._glassPane.dispose();
  89. window.removeEventListener("resize", this._windowResizeHandler, true);
  90. },
  91. _onGlassPaneFocus: function(event)
  92. {
  93. this._hide();
  94. },
  95. _onFocus: function(event)
  96. {
  97. this._delegate.focus();
  98. },
  99. _position: function()
  100. {
  101. this._delegate.position(this._element, this._relativeToElement);
  102. },
  103. _onKeyDown: function(event)
  104. {
  105. if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Tab.code) {
  106. event.preventDefault();
  107. return;
  108. }
  109. if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Enter.code)
  110. this._delegate.onEnter();
  111. if (this._closeKeys.indexOf(event.keyCode) >= 0) {
  112. this._hide();
  113. event.consume(true);
  114. }
  115. }
  116. };
  117. /**
  118. * @constructor
  119. * @extends {WebInspector.Object}
  120. */
  121. WebInspector.DialogDelegate = function()
  122. {
  123. }
  124. WebInspector.DialogDelegate.prototype = {
  125. /**
  126. * @param {Element} element
  127. */
  128. show: function(element)
  129. {
  130. element.appendChild(this.element);
  131. this.element.addStyleClass("dialog-contents");
  132. element.addStyleClass("dialog");
  133. },
  134. /**
  135. * @param {Element} element
  136. * @param {Element} relativeToElement
  137. */
  138. position: function(element, relativeToElement)
  139. {
  140. var offset = relativeToElement.offsetRelativeToWindow(window);
  141. var positionX = offset.x + (relativeToElement.offsetWidth - element.offsetWidth) / 2;
  142. positionX = Number.constrain(positionX, 0, window.innerWidth - element.offsetWidth);
  143. var positionY = offset.y + (relativeToElement.offsetHeight - element.offsetHeight) / 2;
  144. positionY = Number.constrain(positionY, 0, window.innerHeight - element.offsetHeight);
  145. element.style.left = positionX + "px";
  146. element.style.top = positionY + "px";
  147. },
  148. focus: function() { },
  149. onEnter: function() { },
  150. willHide: function() { },
  151. __proto__: WebInspector.Object.prototype
  152. }