UNPKG

react-mde

Version:
98 lines (97 loc) 4.03 kB
"use strict"; /*! * The MIT License Copyright (c) 2018 Dmitriy Kubyshkin Copied from https://github.com/grassator/insert-text-at-cursor */ Object.defineProperty(exports, "__esModule", { value: true }); exports.insertText = void 0; /** * Inserts the given text at the cursor. If the element contains a selection, the selection * will be replaced by the text. */ function insertText(input, text) { // Most of the used APIs only work with the field selected input.focus(); // IE 8-10 if (document.selection) { var ieRange = document.selection.createRange(); ieRange.text = text; // Move cursor after the inserted text ieRange.collapse(false /* to the end */); ieRange.select(); return; } // Webkit + Edge var isSuccess = document.execCommand("insertText", false, text); if (!isSuccess) { var start = input.selectionStart; var end = input.selectionEnd; // Firefox (non-standard method) if (typeof input.setRangeText === "function") { input.setRangeText(text); } else { if (canManipulateViaTextNodes(input)) { var textNode = document.createTextNode(text); var node = input.firstChild; // If textarea is empty, just insert the text if (!node) { input.appendChild(textNode); } else { // Otherwise we need to find a nodes for start and end var offset = 0; var startNode = null; var endNode = null; // To make a change we just need a Range, not a Selection var range = document.createRange(); while (node && (startNode === null || endNode === null)) { var nodeLength = node.nodeValue.length; // if start of the selection falls into current node if (start >= offset && start <= offset + nodeLength) { range.setStart((startNode = node), start - offset); } // if end of the selection falls into current node if (end >= offset && end <= offset + nodeLength) { range.setEnd((endNode = node), end - offset); } offset += nodeLength; node = node.nextSibling; } // If there is some text selected, remove it as we should replace it if (start !== end) { range.deleteContents(); } // Finally insert a new node. The browser will automatically // split start and end nodes into two if necessary range.insertNode(textNode); } } else { // For the text input the only way is to replace the whole value :( var value = input.value; input.value = value.slice(0, start) + text + value.slice(end); } } // Correct the cursor position to be at the end of the insertion input.setSelectionRange(start + text.length, start + text.length); // Notify any possible listeners of the change var e = document.createEvent("UIEvent"); e.initEvent("input", true, false); input.dispatchEvent(e); } } exports.insertText = insertText; function canManipulateViaTextNodes(input) { if (input.nodeName !== "TEXTAREA") { return false; } var browserSupportsTextareaTextNodes; if (typeof browserSupportsTextareaTextNodes === "undefined") { var textarea = document.createElement("textarea"); textarea.value = "1"; browserSupportsTextareaTextNodes = !!textarea.firstChild; } return browserSupportsTextareaTextNodes; }