selection-pointer.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  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. CodeMirror.defineOption('selectionPointer', false, function (cm, val) {
  15. var data = cm.state.selectionPointer
  16. if (data) {
  17. CodeMirror.off(cm.getWrapperElement(), 'mousemove', data.mousemove)
  18. CodeMirror.off(cm.getWrapperElement(), 'mouseout', data.mouseout)
  19. CodeMirror.off(window, 'scroll', data.windowScroll)
  20. cm.off('cursorActivity', reset)
  21. cm.off('scroll', reset)
  22. cm.state.selectionPointer = null
  23. cm.display.lineDiv.style.cursor = ''
  24. }
  25. if (val) {
  26. data = cm.state.selectionPointer = {
  27. value: typeof val == 'string' ? val : 'default',
  28. mousemove: function (event) {
  29. mousemove(cm, event)
  30. },
  31. mouseout: function (event) {
  32. mouseout(cm, event)
  33. },
  34. windowScroll: function () {
  35. reset(cm)
  36. },
  37. rects: null,
  38. mouseX: null,
  39. mouseY: null,
  40. willUpdate: false,
  41. }
  42. CodeMirror.on(cm.getWrapperElement(), 'mousemove', data.mousemove)
  43. CodeMirror.on(cm.getWrapperElement(), 'mouseout', data.mouseout)
  44. CodeMirror.on(window, 'scroll', data.windowScroll)
  45. cm.on('cursorActivity', reset)
  46. cm.on('scroll', reset)
  47. }
  48. })
  49. function mousemove(cm, event) {
  50. var data = cm.state.selectionPointer
  51. if (event.buttons == null ? event.which : event.buttons) {
  52. data.mouseX = data.mouseY = null
  53. } else {
  54. data.mouseX = event.clientX
  55. data.mouseY = event.clientY
  56. }
  57. scheduleUpdate(cm)
  58. }
  59. function mouseout(cm, event) {
  60. if (!cm.getWrapperElement().contains(event.relatedTarget)) {
  61. var data = cm.state.selectionPointer
  62. data.mouseX = data.mouseY = null
  63. scheduleUpdate(cm)
  64. }
  65. }
  66. function reset(cm) {
  67. cm.state.selectionPointer.rects = null
  68. scheduleUpdate(cm)
  69. }
  70. function scheduleUpdate(cm) {
  71. if (!cm.state.selectionPointer.willUpdate) {
  72. cm.state.selectionPointer.willUpdate = true
  73. setTimeout(function () {
  74. update(cm)
  75. cm.state.selectionPointer.willUpdate = false
  76. }, 50)
  77. }
  78. }
  79. function update(cm) {
  80. var data = cm.state.selectionPointer
  81. if (!data) return
  82. if (data.rects == null && data.mouseX != null) {
  83. data.rects = []
  84. if (cm.somethingSelected()) {
  85. for (var sel = cm.display.selectionDiv.firstChild; sel; sel = sel.nextSibling) data.rects.push(sel.getBoundingClientRect())
  86. }
  87. }
  88. var inside = false
  89. if (data.mouseX != null)
  90. for (var i = 0; i < data.rects.length; i++) {
  91. var rect = data.rects[i]
  92. if (rect.left <= data.mouseX && rect.right >= data.mouseX && rect.top <= data.mouseY && rect.bottom >= data.mouseY) inside = true
  93. }
  94. var cursor = inside ? data.value : ''
  95. if (cm.display.lineDiv.style.cursor != cursor) cm.display.lineDiv.style.cursor = cursor
  96. }
  97. })