I’m building a URL Link functionality to selected text in my app.
- I select a text.
- Click on Link button.
- Enter URL in modal popup.
- Click save.
- I again click on Link button.
- Update URL in modal popup.
- Click save.
So far so good. I was able to create and update a URL to a selected text in my html. However this breaks when I add empty space before selected text. For example,
- I select the word “highlight” inside
<div id="content">
. - Click on Link button.
- Enter URL.
- Click on save button.
- Now I place the cursor before “highlight” and add two empty space.
- Click on Link button.
- Click on Save button.
- This remove the two empty space I added before the word “highlight”.
Please can you assist on what I’m missing?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Text Highlighter</title>
<style>
.highlighted {
color: blue;
}
#popup {
display: none;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: white;
padding: 20px;
border: 1px solid #ccc;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
z-index: 9999;
}
</style>
</head>
<body>
<div id="content" contentEditable="plaintext-only">Select and highlight this text</div>
<button id="linkIcon">Link</button>
<!-- Popup -->
<div id="popup">
<input type="text" id="selectedText" readonly>
<input type="text" id="urlInput" placeholder="Enter URL">
<button id="saveBtn">Save</button>
</div>
<script>
var textSelected = false;
var lastUrl = "";
document.addEventListener("DOMContentLoaded", function() {
var contentDiv = document.getElementById("content");
var linkIcon = document.getElementById("linkIcon");
var popup = document.getElementById("popup");
var selectedText = document.getElementById("selectedText");
var urlInput = document.getElementById("urlInput");
var selectionRange; // To store selection range
var originalSelection = ""; // To store original selection
var lastAnchorText = "";
// Function to get selected text
function getSelectedText() {
if (window.getSelection) {
return window.getSelection().toString();
} else if (document.selection && document.selection.type != "Control") {
return document.selection.createRange().text;
}
return "";
}
// Function to check if an anchor element already exists in the selection range
function getExistingAnchor() {
var nodes = selectionRange.cloneContents().childNodes;
for (var i = 0; i < nodes.length; i++) {
if (nodes[i].nodeName === "A") {
return nodes[i];
}
}
return null;
}
// Function to check if there is an existing link in the content
function checkExistingLink() {
if (!textSelected) {
return false;
}
var anchor = getExistingAnchor();
if (anchor) {
var existingLink = anchor.href;
if (existingLink !== "") {
urlInput.value = existingLink;
selectedText.value = anchor.innerText;
popup.style.display = "block";
originalSelection = anchor.innerText;
return true;
}
}
return false;
}
// Event listener for link icon click
linkIcon.addEventListener("click", function() {
if (!checkExistingLink()) {
var selection = getSelectedText().trim();
if (selection !== "") {
selectionRange = window.getSelection().getRangeAt(0); // Store selection range
originalSelection = selection; // Store original selection
selectedText.value = selection;
if (lastUrl !== "") {
urlInput.value = lastUrl;
} else {
urlInput.value = "https://";
}
popup.style.display = "block";
} else {
alert("Please select some text first.");
}
}
});
// Event listener for save button click
document.getElementById("saveBtn").addEventListener("click", function() {
var url = urlInput.value.trim();
if (originalSelection !== "") {
if (url !== "") {
var existingAnchor = getExistingAnchor();
var newNode;
if (existingAnchor) {
existingAnchor.href = url;
existingAnchor.innerText = originalSelection;
newNode = existingAnchor;
} else {
newNode = document.createElement("a");
newNode.href = url;
newNode.innerText = originalSelection; // Use original selection
newNode.classList.add("highlighted");
}
// Insert the anchor element directly at the selection range
selectionRange.deleteContents();
selectionRange.insertNode(newNode);
popup.style.display = "none";
originalSelection = ""; // Reset original selection
lastUrl = url; // Update lastUrl
textSelected = true;
} else {
alert("Please enter a URL.");
}
} else {
alert("No text selected.");
}
});
});
</script>
</body>
</html>