linenumbers.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. function withLineNumbers(highlight, options = {}) {
  2. const opts = Object.assign({ class: "codejar-linenumbers", wrapClass: "codejar-wrap", width: "35px", backgroundColor: "rgba(128, 128, 128, 0.15)", color: "" }, options);
  3. let lineNumbers;
  4. return function (editor) {
  5. highlight(editor);
  6. if (!lineNumbers) {
  7. lineNumbers = init(editor, opts);
  8. editor.addEventListener("scroll", () => lineNumbers.style.top = `-${editor.scrollTop}px`);
  9. }
  10. const code = editor.textContent || "";
  11. //const linesCount = code.replace(/\n+$/, "\n").split("\n").length + 1;
  12. const linesCount = code.split("\n").length;
  13. let text = "";
  14. for (let i = 1; i < linesCount; i++) {
  15. text += `${i}\n`;
  16. }
  17. lineNumbers.innerText = text;
  18. };
  19. }
  20. function init(editor, opts) {
  21. const css = getComputedStyle(editor);
  22. const wrap = document.createElement("div");
  23. wrap.className = opts.wrapClass;
  24. wrap.style.position = "relative";
  25. const gutter = document.createElement("div");
  26. gutter.className = opts.class;
  27. wrap.appendChild(gutter);
  28. // Add own styles
  29. gutter.style.position = "absolute";
  30. gutter.style.top = "0px";
  31. gutter.style.left = "0px";
  32. gutter.style.bottom = "0px";
  33. gutter.style.width = opts.width;
  34. gutter.style.overflow = "hidden";
  35. gutter.style.backgroundColor = opts.backgroundColor;
  36. gutter.style.color = opts.color || css.color;
  37. gutter.style.setProperty("mix-blend-mode", "difference");
  38. // Copy editor styles
  39. gutter.style.fontFamily = css.fontFamily;
  40. gutter.style.fontSize = css.fontSize;
  41. gutter.style.lineHeight = css.lineHeight;
  42. gutter.style.paddingTop = css.paddingTop;
  43. gutter.style.paddingLeft = css.paddingLeft;
  44. gutter.style.borderTopLeftRadius = css.borderTopLeftRadius;
  45. gutter.style.borderBottomLeftRadius = css.borderBottomLeftRadius;
  46. // Add line numbers
  47. const lineNumbers = document.createElement("div");
  48. lineNumbers.style.position = "relative";
  49. lineNumbers.style.top = "0px";
  50. gutter.appendChild(lineNumbers);
  51. // Tweak editor styles
  52. editor.style.paddingLeft = `calc(${opts.width} + ${gutter.style.paddingLeft})`;
  53. editor.style.whiteSpace = "pre";
  54. // Swap editor with a wrap
  55. editor.parentNode.insertBefore(wrap, editor);
  56. wrap.appendChild(editor);
  57. return lineNumbers;
  58. }