I worked a little on this one... It was a really fun and instructive exercise.
I mainly started from Maioman's answer.
I made it so that selected text would end up in an anchor with the href provided in the input field... And the selected text remains selected while inputing the link. That is my understanding of your question.
See my working Fiddle : https://jsfiddle.net/Bes7weB/rLmfb043/
Tested to be working on FF 46, Chrome 50, Safari 5.1 and Explorer 11.
Notice that classList is only supported in IE10 and later.
Also, the links are not "clickable" because of the mouseup event.
But you can see the title attribute on mouseover.
I assume you'll save the paragraph's innerHTML to output it somewhere else.
;)
CSS:
a.highlighted { background: blue; color:white; }
HTML:
<h1>Select some text below and click GO!</h1> <br> <p contenteditable="true" tabindex="0"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris nec risus turpis. Donec nisi urna, semper nec ex ac, mollis egestas risus. Donec congue metus massa, nec lacinia tortor ornare ac. Nulla porttitor feugiat lectus ut iaculis. In sagittis tortor et diam feugiat fermentum. Nunc justo ligula, feugiat dignissim consectetur non, tristique vitae enim. Curabitur et cursus velit. Etiam et aliquam urna. Duis pharetra fermentum lectus et fermentum. Phasellus eget nunc ultricies, ornare libero quis, porta justo. Sed euismod, arcu sed tempor venenatis, urna ipsum lacinia eros, ac iaculis leo risus ac est. In hac habitasse platea dictumst. Sed tincidunt rutrum elit, ornare posuere lorem tempor quis. Proin tincidunt, lorem ac luctus dictum, dui mi molestie neque, a sagittis purus leo a nunc. </p><br> <br> <b>Add a link to selected text:</b> <input type="text" id="hrefInput" style="border: solid blue 1px" value="http://www.test.com"> <input type="button" id="gobutton" value="GO!"><br> <span id="errorMsg" style="display:none;">No selected text!</span><br> <input type="button" id="undoButton" value="Undo">
JavaScript:
var p = document.querySelector('p'); var old = p.innerHTML; var HrefInput = document.getElementById("hrefInput"); var GoButton = document.getElementById("gobutton"); var UndoButton = document.getElementById("undoButton"); var errorMsg = document.getElementById("errorMsg"); var idCounter=0; var textSelected=false; UndoButton.addEventListener('focus', function() { console.log("Undo button clicked. Default text reloaded."); restore(); }) GoButton.addEventListener('click', function() { if(!textSelected){ errorMsg.style.display="inline"; errorMsg.style.color="rgb(166, 0, 0)"; errorMsg.style.fontWeight="bold"; return; } console.log("GO button clicked: Link id=a-"+idCounter+" created."); targetId="a-"+idCounter; document.getElementById(targetId).setAttribute("href",HrefInput.value); document.getElementById(targetId).classList.add("createdlink"); document.getElementById(targetId).setAttribute("title",HrefInput.value); document.getElementById(targetId).classList.remove("highlighted"); textSelected=false; idCounter++ }) p.addEventListener('focus', function() { errorMsg.style.display="none"; }); p.addEventListener('mouseup', function() { textSelected=true; console.log("Mouseup event in p : Text selected."); appendanchor(selectText()); // extract the selection HrefInput.focus(); // FireFox HrefInput.blur(); // Needs it. Try without, you'll see. }) function appendanchor(r) { // onmouseup if (!r) return; extracted = r.extractContents(); el = document.createElement('a'); el.setAttribute("id", "a-"+idCounter); el.setAttribute("class", "highlighted"); el.appendChild(extracted); r.insertNode(el) } function selectText() { // onmouseup if (window.getSelection) { console.log("window.getSelection"); sel = window.getSelection(); if (sel.getRangeAt && sel.rangeCount) { // Chrome, FF console.log(sel.getRangeAt(0)); return sel.getRangeAt(0); } else{console.log(sel);} } else if (document.selection && document.selection.createRange) { console.log("elseif"); return document.selection.createRange(); } return null; } function restore() { p.innerHTML = old; textSelected=false; }
<br/>and other stuff but you can't rely on things that is implemented differently across various browsers.