simplescrollbars.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // CodeMirror, copyright (c) by Marijn Haverbeke and others
  2. // Distributed under an MIT license: https://codemirror.net/LICENSE
  3. ;(function (mod) {
  4. if (typeof exports == 'object' && typeof module == 'object')
  5. // CommonJS
  6. mod(require('../../lib/codemirror'))
  7. else if (typeof define == 'function' && define.amd)
  8. // AMD
  9. define(['../../lib/codemirror'], mod)
  10. // Plain browser env
  11. else mod(CodeMirror)
  12. })(function (CodeMirror) {
  13. 'use strict'
  14. function Bar(cls, orientation, scroll) {
  15. this.orientation = orientation
  16. this.scroll = scroll
  17. this.screen = this.total = this.size = 1
  18. this.pos = 0
  19. this.node = document.createElement('div')
  20. this.node.className = cls + '-' + orientation
  21. this.inner = this.node.appendChild(document.createElement('div'))
  22. var self = this
  23. CodeMirror.on(this.inner, 'mousedown', function (e) {
  24. if (e.which != 1) return
  25. CodeMirror.e_preventDefault(e)
  26. var axis = self.orientation == 'horizontal' ? 'pageX' : 'pageY'
  27. var start = e[axis],
  28. startpos = self.pos
  29. function done() {
  30. CodeMirror.off(document, 'mousemove', move)
  31. CodeMirror.off(document, 'mouseup', done)
  32. }
  33. function move(e) {
  34. if (e.which != 1) return done()
  35. self.moveTo(startpos + (e[axis] - start) * (self.total / self.size))
  36. }
  37. CodeMirror.on(document, 'mousemove', move)
  38. CodeMirror.on(document, 'mouseup', done)
  39. })
  40. CodeMirror.on(this.node, 'click', function (e) {
  41. CodeMirror.e_preventDefault(e)
  42. var innerBox = self.inner.getBoundingClientRect(),
  43. where
  44. if (self.orientation == 'horizontal') where = e.clientX < innerBox.left ? -1 : e.clientX > innerBox.right ? 1 : 0
  45. else where = e.clientY < innerBox.top ? -1 : e.clientY > innerBox.bottom ? 1 : 0
  46. self.moveTo(self.pos + where * self.screen)
  47. })
  48. function onWheel(e) {
  49. var moved = CodeMirror.wheelEventPixels(e)[self.orientation == 'horizontal' ? 'x' : 'y']
  50. var oldPos = self.pos
  51. self.moveTo(self.pos + moved)
  52. if (self.pos != oldPos) CodeMirror.e_preventDefault(e)
  53. }
  54. CodeMirror.on(this.node, 'mousewheel', onWheel)
  55. CodeMirror.on(this.node, 'DOMMouseScroll', onWheel)
  56. }
  57. Bar.prototype.setPos = function (pos, force) {
  58. if (pos < 0) pos = 0
  59. if (pos > this.total - this.screen) pos = this.total - this.screen
  60. if (!force && pos == this.pos) return false
  61. this.pos = pos
  62. this.inner.style[this.orientation == 'horizontal' ? 'left' : 'top'] = pos * (this.size / this.total) + 'px'
  63. return true
  64. }
  65. Bar.prototype.moveTo = function (pos) {
  66. if (this.setPos(pos)) this.scroll(pos, this.orientation)
  67. }
  68. var minButtonSize = 10
  69. Bar.prototype.update = function (scrollSize, clientSize, barSize) {
  70. var sizeChanged = this.screen != clientSize || this.total != scrollSize || this.size != barSize
  71. if (sizeChanged) {
  72. this.screen = clientSize
  73. this.total = scrollSize
  74. this.size = barSize
  75. }
  76. var buttonSize = this.screen * (this.size / this.total)
  77. if (buttonSize < minButtonSize) {
  78. this.size -= minButtonSize - buttonSize
  79. buttonSize = minButtonSize
  80. }
  81. this.inner.style[this.orientation == 'horizontal' ? 'width' : 'height'] = buttonSize + 'px'
  82. this.setPos(this.pos, sizeChanged)
  83. }
  84. function SimpleScrollbars(cls, place, scroll) {
  85. this.addClass = cls
  86. this.horiz = new Bar(cls, 'horizontal', scroll)
  87. place(this.horiz.node)
  88. this.vert = new Bar(cls, 'vertical', scroll)
  89. place(this.vert.node)
  90. this.width = null
  91. }
  92. SimpleScrollbars.prototype.update = function (measure) {
  93. if (this.width == null) {
  94. var style = window.getComputedStyle ? window.getComputedStyle(this.horiz.node) : this.horiz.node.currentStyle
  95. if (style) this.width = parseInt(style.height)
  96. }
  97. var width = this.width || 0
  98. var needsH = measure.scrollWidth > measure.clientWidth + 1
  99. var needsV = measure.scrollHeight > measure.clientHeight + 1
  100. this.vert.node.style.display = needsV ? 'block' : 'none'
  101. this.horiz.node.style.display = needsH ? 'block' : 'none'
  102. if (needsV) {
  103. this.vert.update(measure.scrollHeight, measure.clientHeight, measure.viewHeight - (needsH ? width : 0))
  104. this.vert.node.style.bottom = needsH ? width + 'px' : '0'
  105. }
  106. if (needsH) {
  107. this.horiz.update(measure.scrollWidth, measure.clientWidth, measure.viewWidth - (needsV ? width : 0) - measure.barLeft)
  108. this.horiz.node.style.right = needsV ? width + 'px' : '0'
  109. this.horiz.node.style.left = measure.barLeft + 'px'
  110. }
  111. return { right: needsV ? width : 0, bottom: needsH ? width : 0 }
  112. }
  113. SimpleScrollbars.prototype.setScrollTop = function (pos) {
  114. this.vert.setPos(pos)
  115. }
  116. SimpleScrollbars.prototype.setScrollLeft = function (pos) {
  117. this.horiz.setPos(pos)
  118. }
  119. SimpleScrollbars.prototype.clear = function () {
  120. var parent = this.horiz.node.parentNode
  121. parent.removeChild(this.horiz.node)
  122. parent.removeChild(this.vert.node)
  123. }
  124. CodeMirror.scrollbarModel.simple = function (place, scroll) {
  125. return new SimpleScrollbars('CodeMirror-simplescroll', place, scroll)
  126. }
  127. CodeMirror.scrollbarModel.overlay = function (place, scroll) {
  128. return new SimpleScrollbars('CodeMirror-overlayscroll', place, scroll)
  129. }
  130. })