scrollbar.js 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  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. * An abstract class representing a native scrollbar control.
  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 ScrollBar = function(parent) {
  47. this.element = dom.createElement("div");
  48. this.element.className = "ace_scrollbar ace_scrollbar" + this.classSuffix;
  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. this.setVisible(false);
  54. this.skipEvent = false;
  55. event.addListener(this.element, "scroll", this.onScroll.bind(this));
  56. event.addListener(this.element, "mousedown", event.preventDefault);
  57. };
  58. (function() {
  59. oop.implement(this, EventEmitter);
  60. this.setVisible = function(isVisible) {
  61. this.element.style.display = isVisible ? "" : "none";
  62. this.isVisible = isVisible;
  63. };
  64. }).call(ScrollBar.prototype);
  65. /**
  66. * Represents a vertical scroll bar.
  67. * @class VScrollBar
  68. **/
  69. /**
  70. * Creates a new `VScrollBar`. `parent` is the owner of the scroll bar.
  71. * @param {DOMElement} parent A DOM element
  72. * @param {Object} renderer An editor renderer
  73. *
  74. * @constructor
  75. **/
  76. var VScrollBar = function(parent, renderer) {
  77. ScrollBar.call(this, parent);
  78. this.scrollTop = 0;
  79. // in OSX lion the scrollbars appear to have no width. In this case resize the
  80. // element to show the scrollbar but still pretend that the scrollbar has a width
  81. // of 0px
  82. // in Firefox 6+ scrollbar is hidden if element has the same width as scrollbar
  83. // make element a little bit wider to retain scrollbar when page is zoomed
  84. renderer.$scrollbarWidth =
  85. this.width = dom.scrollbarWidth(parent.ownerDocument);
  86. this.inner.style.width =
  87. this.element.style.width = (this.width || 15) + 5 + "px";
  88. };
  89. oop.inherits(VScrollBar, ScrollBar);
  90. (function() {
  91. this.classSuffix = '-v';
  92. /**
  93. * Emitted when the scroll bar, well, scrolls.
  94. * @event scroll
  95. * @param {Object} e Contains one property, `"data"`, which indicates the current scroll top position
  96. **/
  97. this.onScroll = function() {
  98. if (!this.skipEvent) {
  99. this.scrollTop = this.element.scrollTop;
  100. this._emit("scroll", {data: this.scrollTop});
  101. }
  102. this.skipEvent = false;
  103. };
  104. /**
  105. * Returns the width of the scroll bar.
  106. * @returns {Number}
  107. **/
  108. this.getWidth = function() {
  109. return this.isVisible ? this.width : 0;
  110. };
  111. /**
  112. * Sets the height of the scroll bar, in pixels.
  113. * @param {Number} height The new height
  114. **/
  115. this.setHeight = function(height) {
  116. this.element.style.height = height + "px";
  117. };
  118. /**
  119. * Sets the inner height of the scroll bar, in pixels.
  120. * @param {Number} height The new inner height
  121. * @deprecated Use setScrollHeight instead
  122. **/
  123. this.setInnerHeight = function(height) {
  124. this.inner.style.height = height + "px";
  125. };
  126. /**
  127. * Sets the scroll height of the scroll bar, in pixels.
  128. * @param {Number} height The new scroll height
  129. **/
  130. this.setScrollHeight = function(height) {
  131. this.inner.style.height = height + "px";
  132. };
  133. /**
  134. * Sets the scroll top of the scroll bar.
  135. * @param {Number} scrollTop The new scroll top
  136. **/
  137. this.setScrollTop = function(scrollTop) {
  138. // on chrome 17+ for small zoom levels after calling this function
  139. // this.element.scrollTop != scrollTop which makes page to scroll up.
  140. if (this.scrollTop != scrollTop) {
  141. this.skipEvent = true;
  142. this.scrollTop = this.element.scrollTop = scrollTop;
  143. }
  144. };
  145. }).call(VScrollBar.prototype);
  146. /**
  147. * Represents a horisontal scroll bar.
  148. * @class HScrollBar
  149. **/
  150. /**
  151. * Creates a new `HScrollBar`. `parent` is the owner of the scroll bar.
  152. * @param {DOMElement} parent A DOM element
  153. * @param {Object} renderer An editor renderer
  154. *
  155. * @constructor
  156. **/
  157. var HScrollBar = function(parent, renderer) {
  158. ScrollBar.call(this, parent);
  159. this.scrollLeft = 0;
  160. // in OSX lion the scrollbars appear to have no width. In this case resize the
  161. // element to show the scrollbar but still pretend that the scrollbar has a width
  162. // of 0px
  163. // in Firefox 6+ scrollbar is hidden if element has the same width as scrollbar
  164. // make element a little bit wider to retain scrollbar when page is zoomed
  165. this.height = renderer.$scrollbarWidth;
  166. this.inner.style.height =
  167. this.element.style.height = (this.height || 15) + 5 + "px";
  168. };
  169. oop.inherits(HScrollBar, ScrollBar);
  170. (function() {
  171. this.classSuffix = '-h';
  172. /**
  173. * Emitted when the scroll bar, well, scrolls.
  174. * @event scroll
  175. * @param {Object} e Contains one property, `"data"`, which indicates the current scroll left position
  176. **/
  177. this.onScroll = function() {
  178. if (!this.skipEvent) {
  179. this.scrollLeft = this.element.scrollLeft;
  180. this._emit("scroll", {data: this.scrollLeft});
  181. }
  182. this.skipEvent = false;
  183. };
  184. /**
  185. * Returns the height of the scroll bar.
  186. * @returns {Number}
  187. **/
  188. this.getHeight = function() {
  189. return this.isVisible ? this.height : 0;
  190. };
  191. /**
  192. * Sets the width of the scroll bar, in pixels.
  193. * @param {Number} width The new width
  194. **/
  195. this.setWidth = function(width) {
  196. this.element.style.width = width + "px";
  197. };
  198. /**
  199. * Sets the inner width of the scroll bar, in pixels.
  200. * @param {Number} width The new inner width
  201. * @deprecated Use setScrollWidth instead
  202. **/
  203. this.setInnerWidth = function(width) {
  204. this.inner.style.width = width + "px";
  205. };
  206. /**
  207. * Sets the scroll width of the scroll bar, in pixels.
  208. * @param {Number} width The new scroll width
  209. **/
  210. this.setScrollWidth = function(width) {
  211. this.inner.style.width = width + "px";
  212. };
  213. /**
  214. * Sets the scroll left of the scroll bar.
  215. * @param {Number} scrollTop The new scroll left
  216. **/
  217. this.setScrollLeft = function(scrollLeft) {
  218. // on chrome 17+ for small zoom levels after calling this function
  219. // this.element.scrollTop != scrollTop which makes page to scroll up.
  220. if (this.scrollLeft != scrollLeft) {
  221. this.skipEvent = true;
  222. this.scrollLeft = this.element.scrollLeft = scrollLeft;
  223. }
  224. };
  225. }).call(HScrollBar.prototype);
  226. exports.ScrollBar = VScrollBar; // backward compatibility
  227. exports.ScrollBarV = VScrollBar; // backward compatibility
  228. exports.ScrollBarH = HScrollBar; // backward compatibility
  229. exports.VScrollBar = VScrollBar;
  230. exports.HScrollBar = HScrollBar;
  231. });