How to get text from selected text to end of page - javascript

I want to get all text from the selected text to end of page, that mean just the text we see on page. But when i try this, it also get text in tag 'script', 'noscript'... and other tags which not show on page:
function getTextFromCursor(){
count=0;
var allText ="";
if(window.getSelection){
var selection = window.getSelection();
var selRange = selection.getRangeAt(0);
var range = document.createRange();
range.setStart(selRange.startContainer, selRange.startOffset);
var theBody = document.getElementsByTagName('body')[0];
var lastEl = theBody.lastElementChild;
range.setEndAfter(lastEl);
allText = range.toString();
}
return allText;
}
How could i only get the text which show on page ?

The TextRange module of my Rangy library could help. It allows you to work on text as the user sees it on the page, more or less. With it, your example could be achieved with
function getTextFromCursor() {
var selection = rangy.getSelection();
var selRange = selection.getRangeAt(0);
var range = rangy.createRange();
range.selectNodeContents(document.body);
range.setStart(selRange.startContainer, selRange.startOffset);
return range.text();
}

Add the range to the selection, and use selection.toString() instead.
selection.addRange(range);
allText = selection.toString();

Related

How to insert markdown formatting inside a contenteditable div

I am working on a markdown editor in HTML and JS, which previously used textarea but I started moving it to a contenteditable div recently due to the limitations it had, tried a lot but I cannot get it working, I just need a basic function to insert markdown ** around a selection, but there seems to be something wrong with contenteditable divs, anyone has any idea how to fix?
function editorInsertFormatting(txtarea, text) {
var selectStart = txtarea.selectionStart;
var selectEnd = txtarea.selectionEnd;
var scrollPos = txtarea.scrollTop;
var caretPos = txtarea.selectionStart;
var front = txtarea.value.substring(0, caretPos);
var back = txtarea.value.substring(
txtarea.selectionEnd,
txtarea.value.length
);
var middle = txtarea.value.substring(caretPos, txtarea.selectionEnd);
txtarea.value = front + text + middle + text + back;
if (selectStart !== selectEnd) {
txtarea.selectionStart = selectStart + text.length;
txtarea.selectionEnd = selectEnd + text.length;
} else {
txtarea.selectionStart = selectStart + text.length;
txtarea.selectionEnd = txtarea.selectionStart;
}
txtarea.focus();
txtarea.scrollTop = scrollPos;
editorLiveParser();
}
Take a look at window.getSelection(), selection.getRangeAt(), and document.execCommand, but it's a very big mountain you're going to climb.
Here's a simple starting point...
var sel = window.getSelection();
var range = sel.getRangeAt(0);
var range0 = range.cloneRange();
range.collapse(true);
document.execCommand('insertText', false, '!!!START!!!');
sel.removeAllRanges();
sel.addRange(range0);
range0.collapse(false);
document.execCommand('insertText', false, '!!!END!!!');
See https://jsfiddle.net/Abeeee/o0e481q3/1/ for a running example

Insert text before each line of the selected text in javascript

I have some text where I can add my text before and after selection :
Hello, I can insert text before and after this by javascript.
1. How to insert text
2. before each line
a. if text is separeted by /g
For surround selection I'm using this code:
function surroundSelection(textBefore, textAfter, color) {
if (window.getSelection) {
var sel = window.getSelection();
var selectedText = sel.toString();
if(selectedText.trim() != "") {
if (sel.rangeCount > 0) {
var range = sel.getRangeAt(0);
var startNode = range.startContainer, startOffset = range.startOffset;
var startTextNode = document.createElement(\'span\');
startTextNode.style.backgroundColor = color;
var startTextNode_t = document.createTextNode(textBefore);
startTextNode.appendChild(startTextNode_t);
var endTextNode = document.createElement(\'span\');
endTextNode.style.backgroundColor = color;
var endTextNode_t = document.createTextNode(textAfter);
endTextNode.appendChild(endTextNode_t);
var boundaryRange = range.cloneRange();
boundaryRange.collapse(false);
boundaryRange.insertNode(endTextNode);
boundaryRange.setStart(startNode, startOffset);
boundaryRange.collapse(true);
boundaryRange.insertNode(startTextNode);
range.setStartAfter(startTextNode);
range.setEndBefore(endTextNode);
sel.removeAllRanges();
sel.addRange(range);
}
}
}
}
The result after selecting text can be :
**!!its_my_text_start!!**Hello, I can insert text before and after this by javascript.
1. How to insert text
2. before each line **!!its_my_text_end!!**
a. if text is separeted by /g
But now I need to select text of the list, and put my text at the beginning and at the end of each element, which separeted by /g.
For example:
Hello, I can insert text before and after this by javascript.
**El_1_start** 1. How to insert text **El_1_end**
**El_2_start** 2. before each line **El_2_end**
**El_3_start** a. if text is separeted by /g **El_3_end**
How can I do this by using window.getSelection?

How to leave the caret at its current position when replace a text in contenteditable element

I have a <span contenteditable="true">. When I move to a new line after a list or a table, I get
<div><br></div>
so to get new paragraph instead, I replace the div using
myContentEditableElement.addEventListener('keyup', function(){
if(this.innerHTML.indexOf('<div><br></div>') != -1) {
this.innerHTML = this.innerHTML.replace(/<div><br><\/div>/g,'<p><br></p>');
}
});
Now the caret moves to the start of my contenteditable element. But I need it leaves at its current position i.e. inside of the new paragraph.
I've tried
var range = document.createRange();
range.selectNodeContents(this);
var selection = window.getSelection();
range.setStart(selection.anchorNode, selection.anchorOffset);
selection.removeAllRanges();
selection.addRange(range);
but it doesn't help
I have found the answer by myself:
if(~this.innerHTML.indexOf('<div><br></div>')) {
var newLine = document.createElement('p');
newLine.innerHTML = '<br>';
var selection = window.getSelection();
var newDivNode = selection.anchorNode;
this.insertBefore(newLine, newDivNode);
this.removeChild(newDivNode);
var range = document.createRange();
range.setStart(newLine, 0);
range.setStart(newLine, 0);
selection.removeAllRanges();
selection.addRange(range);
}

Hightlight the multiple line text of div

I want to highlight the text of div tag.
It works when There is a single line but does not work for multiple:
function SelectChar(el, iStart, iLength) {
var div = el
if (document.createRange) {
var textNode = div.firstChild;
if (textNode.data.length > 1) {
var rangeObj = document.createRange();
rangeObj.setStart(textNode, iStart);
rangeObj.setEnd(textNode, iLength);
selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(rangeObj);
}
}
}
where textbox is content editable div tag.
UPDATE
<div contenteditable="true" id="textbox">The
text
is given
and</div>
Any suggestion please?
This is the plugin auto.js that is used to suggest the word..in that I want to do selection portion for multiple line text in div tag
AutoSuggestControl.prototype.typeAhead = function (sSuggestion /*:String*/) {
// debugger
//check for support of typeahead functionality
var range = document.createRange();
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
if (selection) {
var lastSpace = this.textbox.innerText.lastIndexOf(" ");
var lastQuote = this.textbox.innerText.lastIndexOf("'");
var lastHypen = this.textbox.innerText.lastIndexOf("-");
var lastDoubleQuote = this.textbox.innerText.lastIndexOf('"');
var lastEnter = this.textbox.innerText.lastIndexOf("\n");
var lastIndex = Math.max(lastSpace, lastEnter, lastQuote, lastHypen, lastDoubleQuote) + 1;
var contentStripped = this.textbox.innerText.substring(0, lastIndex);
var lastWord = this.textbox.innerText.substring(lastIndex, this.textbox.innerText.length);
this.textbox.innerText = contentStripped + sSuggestion; //.replace(lastWord,"");
var start = this.textbox.innerText.length - sSuggestion.replace(lastWord, "").length;
var end = this.textbox.innerText.length;
SelectChar(document.getElementById("textbox"), start, end);
}
};
jsfiddle

Set caret position right after the inserted element in a contentEditable div

I'm inserting an element into a contentEditable div but the browser sets the position of the cursor before the inserted element. Is it possible to set the cursor right after the inserted element so that the user keeps typing without having to re-adjust the cursor position?
The following function will do it. DOM Level 2 Range objects make this easy in most browsers. In IE, you need to insert a marker element after the node you're inserting, move the selection to it and then remove it.
Live example: http://jsfiddle.net/timdown/4N4ZD/
Code:
function insertNodeAtCaret(node) {
if (typeof window.getSelection != "undefined") {
var sel = window.getSelection();
if (sel.rangeCount) {
var range = sel.getRangeAt(0);
range.collapse(false);
range.insertNode(node);
range = range.cloneRange();
range.selectNodeContents(node);
range.collapse(false);
sel.removeAllRanges();
sel.addRange(range);
}
} else if (typeof document.selection != "undefined" && document.selection.type != "Control") {
var html = (node.nodeType == 1) ? node.outerHTML : node.data;
var id = "marker_" + ("" + Math.random()).slice(2);
html += '<span id="' + id + '"></span>';
var textRange = document.selection.createRange();
textRange.collapse(false);
textRange.pasteHTML(html);
var markerSpan = document.getElementById(id);
textRange.moveToElementText(markerSpan);
textRange.select();
markerSpan.parentNode.removeChild(markerSpan);
}
}
Alternatively, you could use my Rangy library. The equivalent code there would be
function insertNodeAtCaret(node) {
var sel = rangy.getSelection();
if (sel.rangeCount) {
var range = sel.getRangeAt(0);
range.collapse(false);
range.insertNode(node);
range.collapseAfter(node);
sel.setSingleRange(range);
}
}
If you're inserting an empty div, p or span, I believe there needs to be "something" inside the newly created element for the range to grab onto -- and in order to put the caret inside there.
Here's my hack that seems to work OK in Chrome. The idea is simply to put a temporary string inside the element, then remove it once the caret is in there.
// Get the selection and range
var idoc = document; // (In my case it's an iframe document)
var sel = idoc.getSelection();
var range = sel.getRangeAt(0);
// Create a node to insert
var p = idoc.createElement("p"); // Could be a div, span or whatever
// Add "something" to the node.
var temp = idoc.createTextNode("anything");
p.appendChild(temp);
// -- or --
//p.innerHTML = "anything";
// Do the magic (what rangy showed above)
range.collapse(false);
range.insertNode( p );
range = range.cloneRange();
range.selectNodeContents(p);
range.collapse(false);
sel.removeAllRanges();
sel.addRange(range);
// Clear the non
p.removeChild(p.firstChild);
// -- or --
//p.innerHTML = "";
Here's what worked for me, using Rangy, in a VueJS context.
// When the user clicks the button to open the popup to enter
// the URL, run this function to save the location of the user's
// selection and the selected text.
newSaveSel: function() {
if (this.savedSel) {
rangy.removeMarkers(this.savedSel);
}
// Save the location of the selected text
this.savedSel = rangy.saveSelection();
// Save the selected text
this.savedSelText = rangy.getSelection().toString();
this.showLinkPopup = true;
console.log('newSavedSel', this.savedSel);
},
surroundRange: function() {
// Restore the user's selected text. This is necessary since
// the selection is lost when the user stars entering text.
if (this.savedSel) {
rangy.restoreSelection(this.savedSel, true);
this.savedSel = null;
}
// Surround the selected text with the anchor element
var sel = rangy.getSelection();
var range = sel.rangeCount ? sel.getRangeAt(0) : null;
if (range) {
// Create the new anchor element
var el = document.createElement("a");
el.style.backgroundColor = "pink";
el.href = this.anchorHref;
el.innerHTML = this.savedSelText;
if (this.checked) {
el.target = "_blank";
}
// Delete the originally selected text
range.deleteContents();
// Insert the anchor tag
range.insertNode(el);
// Ensure that the caret appears at the end
sel.removeAllRanges();
range = range.cloneRange();
range.selectNode(el);
range.collapse(false);
sel.addRange(range);
this.showLinkPopup = false;
}
},

Categories