(doc, from, to, options, type)
| 151 | |
| 152 | // Create a marker, wire it up to the right lines, and |
| 153 | export function markText(doc, from, to, options, type) { |
| 154 | // Shared markers (across linked documents) are handled separately |
| 155 | // (markTextShared will call out to this again, once per |
| 156 | // document). |
| 157 | if (options && options.shared) return markTextShared(doc, from, to, options, type) |
| 158 | // Ensure we are in an operation. |
| 159 | if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type) |
| 160 | |
| 161 | let marker = new TextMarker(doc, type), diff = cmp(from, to) |
| 162 | if (options) copyObj(options, marker, false) |
| 163 | // Don't connect empty markers unless clearWhenEmpty is false |
| 164 | if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false) |
| 165 | return marker |
| 166 | if (marker.replacedWith) { |
| 167 | // Showing up as a widget implies collapsed (widget replaces text) |
| 168 | marker.collapsed = true |
| 169 | marker.widgetNode = eltP("span", [marker.replacedWith], "CodeMirror-widget") |
| 170 | if (!options.handleMouseEvents) marker.widgetNode.setAttribute("cm-ignore-events", "true") |
| 171 | if (options.insertLeft) marker.widgetNode.insertLeft = true |
| 172 | } |
| 173 | if (marker.collapsed) { |
| 174 | if (conflictingCollapsedRange(doc, from.line, from, to, marker) || |
| 175 | from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker)) |
| 176 | throw new Error("Inserting collapsed marker partially overlapping an existing one") |
| 177 | seeCollapsedSpans() |
| 178 | } |
| 179 | |
| 180 | if (marker.addToHistory) |
| 181 | addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN) |
| 182 | |
| 183 | let curLine = from.line, cm = doc.cm, updateMaxLine |
| 184 | doc.iter(curLine, to.line + 1, line => { |
| 185 | if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine) |
| 186 | updateMaxLine = true |
| 187 | if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0) |
| 188 | addMarkedSpan(line, new MarkedSpan(marker, |
| 189 | curLine == from.line ? from.ch : null, |
| 190 | curLine == to.line ? to.ch : null)) |
| 191 | ++curLine |
| 192 | }) |
| 193 | // lineIsHidden depends on the presence of the spans, so needs a second pass |
| 194 | if (marker.collapsed) doc.iter(from.line, to.line + 1, line => { |
| 195 | if (lineIsHidden(doc, line)) updateLineHeight(line, 0) |
| 196 | }) |
| 197 | |
| 198 | if (marker.clearOnEnter) on(marker, "beforeCursorEnter", () => marker.clear()) |
| 199 | |
| 200 | if (marker.readOnly) { |
| 201 | seeReadOnlySpans() |
| 202 | if (doc.history.done.length || doc.history.undone.length) |
| 203 | doc.clearHistory() |
| 204 | } |
| 205 | if (marker.collapsed) { |
| 206 | marker.id = ++nextMarkerId |
| 207 | marker.atomic = true |
| 208 | } |
| 209 | if (cm) { |
| 210 | // Sync editor state |
no test coverage detected