scrollbar.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /* ***** BEGIN LICENSE BLOCK *****
  2. * Distributed under the BSD license:
  3. *
  4. * Copyright (c) 2010, Ajax.org B.V.
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are met:
  9. * * Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * * Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * * Neither the name of Ajax.org B.V. nor the
  15. * names of its contributors may be used to endorse or promote products
  16. * derived from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  19. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21. * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
  22. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  24. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  25. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  27. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. *
  29. * ***** END LICENSE BLOCK ***** */
  30. define(function(require, exports, module) {
  31. "use strict";
  32. var oop = require("./lib/oop");
  33. var dom = require("./lib/dom");
  34. var event = require("./lib/event");
  35. var EventEmitter = require("./lib/event_emitter").EventEmitter;
  36. /**
  37. * A set of methods for setting and retrieving the editor's scrollbar.
  38. * @class ScrollBar
  39. **/
  40. /**
  41. * Creates a new `ScrollBar`. `parent` is the owner of the scroll bar.
  42. * @param {DOMElement} parent A DOM element
  43. *
  44. * @constructor
  45. **/
  46. var ScrollBarV = function(parent, renderer) {
  47. this.element = dom.createElement("div");
  48. this.element.className = "ace_scrollbar";
  49. this.inner = dom.createElement("div");
  50. this.inner.className = "ace_scrollbar-inner";
  51. this.element.appendChild(this.inner);
  52. parent.appendChild(this.element);
  53. // in OSX lion the scrollbars appear to have no width. In this case resize the
  54. // element to show the scrollbar but still pretend that the scrollbar has a width
  55. // of 0px
  56. // in Firefox 6+ scrollbar is hidden if element has the same width as scrollbar
  57. // make element a little bit wider to retain scrollbar when page is zoomed
  58. renderer.$scrollbarWidth =
  59. this.width = dom.scrollbarWidth(parent.ownerDocument);
  60. renderer.$scrollbarWidth =
  61. this.width = dom.scrollbarWidth(parent.ownerDocument);
  62. this.fullWidth = this.width;
  63. this.inner.style.width =
  64. this.element.style.width = (this.width || 15) + 5 + "px";
  65. this.setVisible(false);
  66. this.element.style.overflowY = "scroll";
  67. event.addListener(this.element, "scroll", this.onScrollV.bind(this));
  68. event.addListener(this.element, "mousedown", event.preventDefault);
  69. };
  70. var ScrollBarH = function(parent, renderer) {
  71. this.element = dom.createElement("div");
  72. this.element.className = "ace_scrollbar-h";
  73. this.inner = dom.createElement("div");
  74. this.inner.className = "ace_scrollbar-inner";
  75. this.element.appendChild(this.inner);
  76. parent.appendChild(this.element);
  77. // in OSX lion the scrollbars appear to have no width. In this case resize the
  78. // element to show the scrollbar but still pretend that the scrollbar has a width
  79. // of 0px
  80. // in Firefox 6+ scrollbar is hidden if element has the same width as scrollbar
  81. // make element a little bit wider to retain scrollbar when page is zoomed
  82. this.height = renderer.$scrollbarWidth;
  83. this.fullHeight = this.height;
  84. this.inner.style.height =
  85. this.element.style.height = (this.height || 15) + 5 + "px";
  86. this.setVisible(false);
  87. this.element.style.overflowX = "scroll";
  88. event.addListener(this.element, "scroll", this.onScrollH.bind(this));
  89. event.addListener(this.element, "mousedown", event.preventDefault);
  90. };
  91. (function() {
  92. oop.implement(this, EventEmitter);
  93. this.setVisible = function(show) {
  94. if (show) {
  95. this.element.style.display = "";
  96. if (this.fullWidth)
  97. this.width = this.fullWidth;
  98. if (this.fullHeight)
  99. this.height = this.fullHeight;
  100. } else {
  101. this.element.style.display = "none";
  102. this.height = this.width = 0;
  103. }
  104. };
  105. /**
  106. * Emitted when the scroll bar, well, scrolls.
  107. * @event scroll
  108. * @param {Object} e Contains one property, `"data"`, which indicates the current scroll top position
  109. **/
  110. this.onScrollV = function() {
  111. if (!this.skipEvent) {
  112. this.scrollTop = this.element.scrollTop;
  113. this._emit("scroll", {data: this.scrollTop});
  114. }
  115. this.skipEvent = false;
  116. };
  117. this.onScrollH = function() {
  118. if (!this.skipEvent) {
  119. this.scrollLeft = this.element.scrollLeft;
  120. this._emit("scroll", {data: this.scrollLeft});
  121. }
  122. this.skipEvent = false;
  123. };
  124. /**
  125. * Returns the width of the scroll bar.
  126. * @returns {Number}
  127. **/
  128. this.getWidth = function() {
  129. return this.width;
  130. };
  131. this.getHeight = function() {
  132. return this.height;
  133. };
  134. /**
  135. * Sets the height of the scroll bar, in pixels.
  136. * @param {Number} height The new height
  137. **/
  138. this.setHeight = function(height) {
  139. this.element.style.height = height + "px";
  140. };
  141. this.setWidth = function(width) {
  142. this.element.style.width = width + "px";
  143. };
  144. /**
  145. * Sets the inner height of the scroll bar, in pixels.
  146. * @param {Number} height The new inner height
  147. **/
  148. this.setInnerHeight = function(height) {
  149. this.inner.style.height = height + "px";
  150. };
  151. this.setInnerWidth = function(width) {
  152. this.inner.style.width = width + "px";
  153. };
  154. /**
  155. * Sets the scroll top of the scroll bar.
  156. * @param {Number} scrollTop The new scroll top
  157. **/
  158. // on chrome 17+ for small zoom levels after calling this function
  159. // this.element.scrollTop != scrollTop which makes page to scroll up.
  160. this.setScrollTop = function(scrollTop) {
  161. if (this.scrollTop != scrollTop) {
  162. this.skipEvent = true;
  163. this.scrollTop = this.element.scrollTop = scrollTop;
  164. }
  165. };
  166. this.setScrollLeft = function(scrollLeft) {
  167. if (this.scrollLeft != scrollLeft) {
  168. this.skipEvent = true;
  169. this.scrollLeft = this.element.scrollLeft = scrollLeft;
  170. }
  171. };
  172. }).call(ScrollBarV.prototype);
  173. ScrollBarH.prototype = ScrollBarV.prototype;
  174. exports.ScrollBar = ScrollBarV; // backward compatibility
  175. exports.ScrollBarV = ScrollBarV;
  176. exports.ScrollBarH = ScrollBarH;
  177. });