active-line.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. // Because sometimes you need to style the cursor's line.
  2. //
  3. // Adds an option 'styleActiveLine' which, when enabled, gives the
  4. // active line's wrapping <div> the CSS class "CodeMirror-activeline",
  5. // and gives its background <div> the class "CodeMirror-activeline-background".
  6. (function(mod) {
  7. if (typeof exports == "object" && typeof module == "object") // CommonJS
  8. mod(require("../../lib/codemirror"));
  9. else if (typeof define == "function" && define.amd) // AMD
  10. define(["../../lib/codemirror"], mod);
  11. else // Plain browser env
  12. mod(CodeMirror);
  13. })(function(CodeMirror) {
  14. "use strict";
  15. var WRAP_CLASS = "CodeMirror-activeline";
  16. var BACK_CLASS = "CodeMirror-activeline-background";
  17. CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) {
  18. var prev = old && old != CodeMirror.Init;
  19. if (val && !prev) {
  20. cm.state.activeLines = [];
  21. updateActiveLines(cm, cm.listSelections());
  22. cm.on("beforeSelectionChange", selectionChange);
  23. } else if (!val && prev) {
  24. cm.off("beforeSelectionChange", selectionChange);
  25. clearActiveLines(cm);
  26. delete cm.state.activeLines;
  27. }
  28. });
  29. function clearActiveLines(cm) {
  30. for (var i = 0; i < cm.state.activeLines.length; i++) {
  31. cm.removeLineClass(cm.state.activeLines[i], "wrap", WRAP_CLASS);
  32. cm.removeLineClass(cm.state.activeLines[i], "background", BACK_CLASS);
  33. }
  34. }
  35. function sameArray(a, b) {
  36. if (a.length != b.length) return false;
  37. for (var i = 0; i < a.length; i++)
  38. if (a[i] != b[i]) return false;
  39. return true;
  40. }
  41. function updateActiveLines(cm, ranges) {
  42. var active = [];
  43. for (var i = 0; i < ranges.length; i++) {
  44. var line = cm.getLineHandleVisualStart(ranges[i].head.line);
  45. if (active[active.length - 1] != line) active.push(line);
  46. }
  47. if (sameArray(cm.state.activeLines, active)) return;
  48. cm.operation(function() {
  49. clearActiveLines(cm);
  50. for (var i = 0; i < active.length; i++) {
  51. cm.addLineClass(active[i], "wrap", WRAP_CLASS);
  52. cm.addLineClass(active[i], "background", BACK_CLASS);
  53. }
  54. cm.state.activeLines = active;
  55. });
  56. }
  57. function selectionChange(cm, sel) {
  58. updateActiveLines(cm, sel.ranges);
  59. }
  60. });