(cm)
| 2207 | // seen text (can be empty), which is stored in prevInput (we must |
| 2208 | // not reset the textarea when typing, because that breaks IME). |
| 2209 | function readInput(cm) { |
| 2210 | var input = cm.display.input, prevInput = cm.display.prevInput, doc = cm.doc; |
| 2211 | // Since this is called a *lot*, try to bail out as cheaply as |
| 2212 | // possible when it is clear that nothing happened. hasSelection |
| 2213 | // will be the case when there is a lot of text in the textarea, |
| 2214 | // in which case reading its value would be expensive. |
| 2215 | if (!cm.state.focused || hasSelection(input) || isReadOnly(cm) || cm.options.disableInput) return false; |
| 2216 | var text = input.value; |
| 2217 | // If nothing changed, bail. |
| 2218 | if (text == prevInput && !cm.somethingSelected()) return false; |
| 2219 | // Work around nonsensical selection resetting in IE9/10 |
| 2220 | if (ie && !ie_upto8 && cm.display.inputHasSelection === text) { |
| 2221 | resetInput(cm); |
| 2222 | return false; |
| 2223 | } |
| 2224 | |
| 2225 | var withOp = !cm.curOp; |
| 2226 | if (withOp) startOperation(cm); |
| 2227 | cm.display.shift = false; |
| 2228 | |
| 2229 | // Find the part of the input that is actually new |
| 2230 | var same = 0, l = Math.min(prevInput.length, text.length); |
| 2231 | while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same; |
| 2232 | var inserted = text.slice(same), textLines = splitLines(inserted); |
| 2233 | |
| 2234 | // When pasing N lines into N selections, insert one line per selection |
| 2235 | var multiPaste = cm.state.pasteIncoming && textLines.length > 1 && doc.sel.ranges.length == textLines.length; |
| 2236 | |
| 2237 | // Normal behavior is to insert the new text into every selection |
| 2238 | for (var i = doc.sel.ranges.length - 1; i >= 0; i--) { |
| 2239 | var range = doc.sel.ranges[i]; |
| 2240 | var from = range.from(), to = range.to(); |
| 2241 | // Handle deletion |
| 2242 | if (same < prevInput.length) |
| 2243 | from = Pos(from.line, from.ch - (prevInput.length - same)); |
| 2244 | // Handle overwrite |
| 2245 | else if (cm.state.overwrite && range.empty() && !cm.state.pasteIncoming) |
| 2246 | to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length)); |
| 2247 | var updateInput = cm.curOp.updateInput; |
| 2248 | var changeEvent = {from: from, to: to, text: multiPaste ? [textLines[i]] : textLines, |
| 2249 | origin: cm.state.pasteIncoming ? "paste" : cm.state.cutIncoming ? "cut" : "+input"}; |
| 2250 | makeChange(cm.doc, changeEvent); |
| 2251 | signalLater(cm, "inputRead", cm, changeEvent); |
| 2252 | // When an 'electric' character is inserted, immediately trigger a reindent |
| 2253 | if (inserted && !cm.state.pasteIncoming && cm.options.electricChars && |
| 2254 | cm.options.smartIndent && range.head.ch < 100 && |
| 2255 | (!i || doc.sel.ranges[i - 1].head.line != range.head.line)) { |
| 2256 | var mode = cm.getModeAt(range.head); |
| 2257 | if (mode.electricChars) { |
| 2258 | for (var j = 0; j < mode.electricChars.length; j++) |
| 2259 | if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) { |
| 2260 | indentLine(cm, range.head.line, "smart"); |
| 2261 | break; |
| 2262 | } |
| 2263 | } else if (mode.electricInput) { |
| 2264 | var end = changeEnd(changeEvent); |
| 2265 | if (mode.electricInput.test(getLine(doc, end.line).text.slice(0, end.ch))) |
| 2266 | indentLine(cm, range.head.line, "smart"); |
no test coverage detected