active-line.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  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. var WRAP_CLASS = 'CodeMirror-activeline'
  15. var BACK_CLASS = 'CodeMirror-activeline-background'
  16. var GUTT_CLASS = 'CodeMirror-activeline-gutter'
  17. CodeMirror.defineOption('styleActiveLine', false, function (cm, val, old) {
  18. var prev = old == CodeMirror.Init ? false : old
  19. if (val == prev) return
  20. if (prev) {
  21. cm.off('beforeSelectionChange', selectionChange)
  22. clearActiveLines(cm)
  23. delete cm.state.activeLines
  24. }
  25. if (val) {
  26. cm.state.activeLines = []
  27. updateActiveLines(cm, cm.listSelections())
  28. cm.on('beforeSelectionChange', selectionChange)
  29. }
  30. })
  31. function clearActiveLines(cm) {
  32. for (var i = 0; i < cm.state.activeLines.length; i++) {
  33. cm.removeLineClass(cm.state.activeLines[i], 'wrap', WRAP_CLASS)
  34. cm.removeLineClass(cm.state.activeLines[i], 'background', BACK_CLASS)
  35. cm.removeLineClass(cm.state.activeLines[i], 'gutter', GUTT_CLASS)
  36. }
  37. }
  38. function sameArray(a, b) {
  39. if (a.length != b.length) return false
  40. for (var i = 0; i < a.length; i++) if (a[i] != b[i]) return false
  41. return true
  42. }
  43. function updateActiveLines(cm, ranges) {
  44. var active = []
  45. for (var i = 0; i < ranges.length; i++) {
  46. var range = ranges[i]
  47. var option = cm.getOption('styleActiveLine')
  48. if (typeof option == 'object' && option.nonEmpty ? range.anchor.line != range.head.line : !range.empty()) continue
  49. var line = cm.getLineHandleVisualStart(range.head.line)
  50. if (active[active.length - 1] != line) active.push(line)
  51. }
  52. if (sameArray(cm.state.activeLines, active)) return
  53. cm.operation(function () {
  54. clearActiveLines(cm)
  55. for (var i = 0; i < active.length; i++) {
  56. cm.addLineClass(active[i], 'wrap', WRAP_CLASS)
  57. cm.addLineClass(active[i], 'background', BACK_CLASS)
  58. cm.addLineClass(active[i], 'gutter', GUTT_CLASS)
  59. }
  60. cm.state.activeLines = active
  61. })
  62. }
  63. function selectionChange(cm, sel) {
  64. updateActiveLines(cm, sel.ranges)
  65. }
  66. })