(doc, from, to, options, type)
| 5873 | |
| 5874 | // Create a marker, wire it up to the right lines, and |
| 5875 | function markText(doc, from, to, options, type) { |
| 5876 | // Shared markers (across linked documents) are handled separately |
| 5877 | // (markTextShared will call out to this again, once per |
| 5878 | // document). |
| 5879 | if (options && options.shared) { return markTextShared(doc, from, to, options, type) } |
| 5880 | // Ensure we are in an operation. |
| 5881 | if (doc.cm && !doc.cm.curOp) { return operation(doc.cm, markText)(doc, from, to, options, type) } |
| 5882 | |
| 5883 | var marker = new TextMarker(doc, type), diff = cmp(from, to); |
| 5884 | if (options) { copyObj(options, marker, false); } |
| 5885 | // Don't connect empty markers unless clearWhenEmpty is false |
| 5886 | if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false) |
| 5887 | { return marker } |
| 5888 | if (marker.replacedWith) { |
| 5889 | // Showing up as a widget implies collapsed (widget replaces text) |
| 5890 | marker.collapsed = true; |
| 5891 | marker.widgetNode = eltP("span", [marker.replacedWith], "CodeMirror-widget"); |
| 5892 | if (!options.handleMouseEvents) { marker.widgetNode.setAttribute("cm-ignore-events", "true"); } |
| 5893 | if (options.insertLeft) { marker.widgetNode.insertLeft = true; } |
| 5894 | } |
| 5895 | if (marker.collapsed) { |
| 5896 | if (conflictingCollapsedRange(doc, from.line, from, to, marker) || |
| 5897 | from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker)) |
| 5898 | { throw new Error("Inserting collapsed marker partially overlapping an existing one") } |
| 5899 | seeCollapsedSpans(); |
| 5900 | } |
| 5901 | |
| 5902 | if (marker.addToHistory) |
| 5903 | { addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN); } |
| 5904 | |
| 5905 | var curLine = from.line, cm = doc.cm, updateMaxLine; |
| 5906 | doc.iter(curLine, to.line + 1, function (line) { |
| 5907 | if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine) |
| 5908 | { updateMaxLine = true; } |
| 5909 | if (marker.collapsed && curLine != from.line) { updateLineHeight(line, 0); } |
| 5910 | addMarkedSpan(line, new MarkedSpan(marker, |
| 5911 | curLine == from.line ? from.ch : null, |
| 5912 | curLine == to.line ? to.ch : null)); |
| 5913 | ++curLine; |
| 5914 | }); |
| 5915 | // lineIsHidden depends on the presence of the spans, so needs a second pass |
| 5916 | if (marker.collapsed) { doc.iter(from.line, to.line + 1, function (line) { |
| 5917 | if (lineIsHidden(doc, line)) { updateLineHeight(line, 0); } |
| 5918 | }); } |
| 5919 | |
| 5920 | if (marker.clearOnEnter) { on(marker, "beforeCursorEnter", function () { return marker.clear(); }); } |
| 5921 | |
| 5922 | if (marker.readOnly) { |
| 5923 | seeReadOnlySpans(); |
| 5924 | if (doc.history.done.length || doc.history.undone.length) |
| 5925 | { doc.clearHistory(); } |
| 5926 | } |
| 5927 | if (marker.collapsed) { |
| 5928 | marker.id = ++nextMarkerId; |
| 5929 | marker.atomic = true; |
| 5930 | } |
| 5931 | if (cm) { |
| 5932 | // Sync editor state |
no test coverage detected