0c33138cdb65ed09442c572a9abd367468bb90468d863950a4ed4cdf8a42d38c7e42bb0a329c9fed5721bb8f59a040abc6d5cd3702397038617289e6dc7802 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import { gecko, ie, ie_version, mobile, webkit, chrome, chrome_version } from "../util/browser.js"
  2. import { elt, eltP } from "../util/dom.js"
  3. import { scrollerGap } from "../util/misc.js"
  4. import { getGutters, renderGutters } from "./gutters.js"
  5. // The display handles the DOM integration, both for input reading
  6. // and content drawing. It holds references to DOM nodes and
  7. // display-related state.
  8. export function Display(place, doc, input, options) {
  9. let d = this
  10. this.input = input
  11. // Covers bottom-right square when both scrollbars are present.
  12. d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler")
  13. d.scrollbarFiller.setAttribute("cm-not-content", "true")
  14. // Covers bottom of gutter when coverGutterNextToScrollbar is on
  15. // and h scrollbar is present.
  16. d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler")
  17. d.gutterFiller.setAttribute("cm-not-content", "true")
  18. // Will contain the actual code, positioned to cover the viewport.
  19. d.lineDiv = eltP("div", null, "CodeMirror-code")
  20. // Elements are added to these to represent selection and cursors.
  21. d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1")
  22. d.cursorDiv = elt("div", null, "CodeMirror-cursors")
  23. // A visibility: hidden element used to find the size of things.
  24. d.measure = elt("div", null, "CodeMirror-measure")
  25. // When lines outside of the viewport are measured, they are drawn in this.
  26. d.lineMeasure = elt("div", null, "CodeMirror-measure")
  27. // Wraps everything that needs to exist inside the vertically-padded coordinate system
  28. d.lineSpace = eltP("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv],
  29. null, "position: relative; outline: none")
  30. let lines = eltP("div", [d.lineSpace], "CodeMirror-lines")
  31. // Moved around its parent to cover visible view.
  32. d.mover = elt("div", [lines], null, "position: relative")
  33. // Set to the height of the document, allowing scrolling.
  34. d.sizer = elt("div", [d.mover], "CodeMirror-sizer")
  35. d.sizerWidth = null
  36. // Behavior of elts with overflow: auto and padding is
  37. // inconsistent across browsers. This is used to ensure the
  38. // scrollable area is big enough.
  39. d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;")
  40. // Will contain the gutters, if any.
  41. d.gutters = elt("div", null, "CodeMirror-gutters")
  42. d.lineGutter = null
  43. // Actual scrollable element.
  44. d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll")
  45. d.scroller.setAttribute("tabIndex", "-1")
  46. // The element in which the editor lives.
  47. d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror")
  48. // See #6982. FIXME remove when this has been fixed for a while in Chrome
  49. if (chrome && chrome_version === 105) d.wrapper.style.clipPath = "inset(0px)"
  50. // This attribute is respected by automatic translation systems such as Google Translate,
  51. // and may also be respected by tools used by human translators.
  52. d.wrapper.setAttribute('translate', 'no')
  53. // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported)
  54. if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0 }
  55. if (!webkit && !(gecko && mobile)) d.scroller.draggable = true
  56. if (place) {
  57. if (place.appendChild) place.appendChild(d.wrapper)
  58. else place(d.wrapper)
  59. }
  60. // Current rendered range (may be bigger than the view window).
  61. d.viewFrom = d.viewTo = doc.first
  62. d.reportedViewFrom = d.reportedViewTo = doc.first
  63. // Information about the rendered lines.
  64. d.view = []
  65. d.renderedView = null
  66. // Holds info about a single rendered line when it was rendered
  67. // for measurement, while not in view.
  68. d.externalMeasured = null
  69. // Empty space (in pixels) above the view
  70. d.viewOffset = 0
  71. d.lastWrapHeight = d.lastWrapWidth = 0
  72. d.updateLineNumbers = null
  73. d.nativeBarWidth = d.barHeight = d.barWidth = 0
  74. d.scrollbarsClipped = false
  75. // Used to only resize the line number gutter when necessary (when
  76. // the amount of lines crosses a boundary that makes its width change)
  77. d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null
  78. // Set to true when a non-horizontal-scrolling line widget is
  79. // added. As an optimization, line widget aligning is skipped when
  80. // this is false.
  81. d.alignWidgets = false
  82. d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null
  83. // Tracks the maximum line length so that the horizontal scrollbar
  84. // can be kept static when scrolling.
  85. d.maxLine = null
  86. d.maxLineLength = 0
  87. d.maxLineChanged = false
  88. // Used for measuring wheel scrolling granularity
  89. d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null
  90. // True when shift is held down.
  91. d.shift = false
  92. // Used to track whether anything happened since the context menu
  93. // was opened.
  94. d.selForContextMenu = null
  95. d.activeTouch = null
  96. d.gutterSpecs = getGutters(options.gutters, options.lineNumbers)
  97. renderGutters(d)
  98. input.init(d)
  99. }