How to highlight selected text in web view in android - javascript

Below java script code is working in normal html, while using below script in android, it is not working.
Code
function highlight(colour) {
var range, sel;
if (window.getSelection) {
// Non-IE case
sel = window.getSelection();
if (sel.getRangeAt) {
range = sel.getRangeAt(0);
}
document.designMode = "on";
if (range) {
sel.removeAllRanges();
sel.addRange(range);
}
// Use HiliteColor since some browsers apply BackColor to the whole block
if ( !document.execCommand("HiliteColor", false, colour) ) {
document.execCommand("BackColor", false, colour);
}
document.designMode = "off";
} else if (document.selection && document.selection.createRange) {
// IE case
range = document.selection.createRange();
range.execCommand("BackColor", false, colour);
}
}
Please someone suggest me how to highlight selected text in webview.

Just a first check: Have you enabled Javascript?
this.webView.getSettings().setJavaScriptEnabled(true);

Related

Javascript document.execCommand "bold" not working in chrome

I;m creating a text editor, and I'm using document.execCommand for styling purposes on my div, which is contend Editable. All other functions like underlining, italicizing, justifying, etc.. work, except for bold. I can't figure out why. Here is the code I'm using:
function makeEditableAndHighlight(styleType, optParam) {
if(typeof(optParam) == "undefined" || optParam == null){
optParam = null;
}
var range, sel = window.getSelection();
if (sel.rangeCount && sel.getRangeAt) {
range = sel.getRangeAt(0);
}
document.designMode = "on";
if (range) {
sel.removeAllRanges();
sel.addRange(range);
}
// Use HiliteColor since some browsers apply BackColor to the whole block
/*if (!document.execCommand("HiliteColor", false, colour)) {
document.execCommand("BackColor", false, colour);
}*/
document.execCommand(styleType, false, optParam);
document.designMode = "off";
}
function changeTextStyle(styleType, optParam){
if(typeof(optParam) == "undefined" || optParam == null){
optParam = null;
}
var range;
if (window.getSelection) {
// IE9 and non-IE
try {
/*if (!document.execCommand("BackColor", false, colour)) {
makeEditableAndHighlight(colour);
}*/
if (!document.execCommand(styleType, false, optParam)) {
makeEditableAndHighlight(styleType, optParam);
}
} catch (ex) {
makeEditableAndHighlight(styleType, optParam)
}
} else if (document.selection && document.selection.createRange) {
// IE <= 8 case
range = document.selection.createRange();
range.execCommand(styleType, false, optParam);
//range.execCommand("BackColor", false, colour);
}
}
I call it by using changeTextStyle("bold"); or whatever style inside the quotation marks.
This code has been working perfectly for every other style command, except bold. I'm calling it through the click of a button and it applies the style to the contenteditable div. I did get it to work once, and that was if the all the div contents were selected, other than that it won't work at all. any help would be nice, thanks!
Try this
<button id="bold" onclick="FormatText('bold');"> </button>
And for Save selection and Restore selection use following code
function saveSel() {
if (window.getSelection)//non IE Browsers
{
savedRange = window.getSelection().getRangeAt(0);
}
else if (document.selection)//IE
{
savedRange = document.selection.createRange();
}
}
//to restore sel
function restoreSel() {
$('#contenteditableId').focus();
if (savedRange != null) {
if (window.getSelection)//non IE and there is already a selection
{
var s = window.getSelection();
if (s.rangeCount > 0)
s.removeAllRanges();
s.addRange(savedRange);
}
else if (document.createRange)//non IE and no selection
{
window.getSelection().addRange(savedRange);
}
else if (document.selection)//IE
{
savedRange.select();
}
}
}
And call Savesel on Focusout event of your Contenteditable
$("#contenteditableId").focusout(function () {
saveSel();
});
At last Call restoreSel
function FormatText(command, option) {
restoreSel();
document.execCommand(command, false, option);
}
I use document.queryCommandState("bold"); for bold. It works for me.
I had a similar problem. In my case "span" tag makes an issue it has font-weight 700, After deep analysis, I figure out if span tag font weight is more than 500 (600, 700, 800, bold, bolder etc) create this issue, even if it's not inside "contenteditable" still it creates a problem. Just remove style font-weight 700 and add <b> instead resolve my issue. Hope it helps someone.

During string search using window.find() a dialog box appear

I am trying to search string and highlight those string. But during search a find dialog box appear. How can I disable the find dialog box ?
Here is my code -->
function doSearch(text) {
if (window.find && window.getSelection) {
document.designMode = "on";
var sel = window.getSelection();
sel.collapse(document.body, 0);
while (window.find(text)) {
document.execCommand("HiliteColor", false, "yellow");
sel.collapseToEnd();
}
document.designMode = "off";
} else if (document.body.createTextRange) {
var textRange = document.body.createTextRange();
while (textRange.findText(text)) {
textRange.execCommand("BackColor", false, "yellow");
textRange.collapse(false);
}
}
}
Firefox has a bug wherein it will display the find dialog box with window.find() if it has a blank argument:
https://bugzilla.mozilla.org/show_bug.cgi?id=672395
So if anyone is having this problem, you likely need to check the argument you're sending to window.find().

Using Javascript to change background-color back and forth?

I'm developing a Chrome Extension. I have this function here:
function makeEditableAndHighlight(colour) {
var range, sel = window.getSelection();
if (sel.rangeCount && sel.getRangeAt) {
range = sel.getRangeAt(0);
}
document.designMode = "on";
if (range) {
sel.removeAllRanges();
sel.addRange(range);
}
// Use HiliteColor since some browsers apply BackColor to the whole block
if (!document.execCommand("HiliteColor", false, colour)) {
document.execCommand("BackColor", false, colour);
}
document.designMode = "off";
}
function highlight(colour) {
var range, sel;
if (window.getSelection) {
// IE9 and non-IE
try {
if (!document.execCommand("BackColor", false, colour)) {
makeEditableAndHighlight(colour);
}
} catch (ex) {
makeEditableAndHighlight(colour)
}
} else if (document.selection && document.selection.createRange) {
// IE <= 8 case
range = document.selection.createRange();
range.execCommand("BackColor", false, colour);
}
}
I use it to highlight (background-color to yellow) a piece of selected text. The problem is with de-highlighting it.
I did this:
function body() {
document.getElementsByTagName("body")[0].addEventListener(
"click",
function(event){
highlight('transparent');
}
);
}
Problem with that is:
1) It requires the text to still be selected, but the click de-selects it, so it only works if you re-select the exact same text, and actually click ON IT.
2) It seems to make the page run much slower, even lock it at times.
What I would love to do is this:
When I click away, anywhere, the text is de-highlighted and de-selected (basically, set highlight to transparent or whatever it was before whenever the text gets de-selected).
What do?
P.S - Javascript only. If you have a way of using jQuery, let me know, but keep in mind I have to use it inside a content.js filed for a Chrome Extension.
use can use following code for unhighlighting. this will work fine. :)
document.designMode = 'on';
document.execCommand("undo", false, 'span');
document.designMode = 'off';
Here "span" is the element which is created by.
document.execCommand("HiliteColor", false, colour)

Selecting Text through JavaScript

I want to select text thats is on a Html page and make it BOLD, I am using the following Code
<script type="text/javascript" >
function getSelectedText(){
if(window.getSelection){ ;
return window.getSelection().toString();
}
else if(document.getSelection){;
return document.getSelection();
}
else if(document.selection){ ;
return document.selection.createRange().text;
}
}
$(document).ready(function(){
$("*").live("mouseup",
function() {
selection = getSelectedText();
alert(selection);
if(selection.length >= 3) {
$(this).html($(this).html().replace(selection, "<b>" + selection + "</b>") );
}
}
);
});
</script>
This Code works Fine But when the text is in two different paragraphs/ Div or if there is a link between the text then it doesnt seem to work.
How Could i Make it Work ?
If you want to do some kind of highlighting of the current selection, using the built-in document.execCommand() is the easiest way. It works in all major browsers.
The following should do what you want on any selection, including ones spanning multiple elements. In non-IE browsers it turns on designMode, applies a background colour and then switches designMode off again.
UPDATE
Fixed to work in IE 9.
function makeEditableAndHighlight(colour) {
var range, sel = window.getSelection();
if (sel.rangeCount && sel.getRangeAt) {
range = sel.getRangeAt(0);
}
document.designMode = "on";
if (range) {
sel.removeAllRanges();
sel.addRange(range);
}
// Use HiliteColor since some browsers apply BackColor to the whole block
if (!document.execCommand("HiliteColor", false, colour)) {
document.execCommand("BackColor", false, colour);
}
document.designMode = "off";
}
function highlightSelection(colour) {
var range;
if (window.getSelection) {
// IE9 and non-IE
try {
if (!document.execCommand("BackColor", false, colour)) {
makeEditableAndHighlight(colour);
}
} catch (ex) {
makeEditableAndHighlight(colour)
}
} else if (document.selection && document.selection.createRange) {
// IE <= 8 case
range = document.selection.createRange();
range.execCommand("BackColor", false, colour);
}
}
document.onmouseup = function() {
highlightSelection("red");
};
Live example: http://jsfiddle.net/eBqBU/9/
a=document.getElementById('elementID').innerHTML;
variable 'a' will get the string value of anything inside the element with an id 'elementID'.
Is this ok?
Everything you need (based on your comments) can be found here: http://www.awesomehighlighter.com/webliter.js
I don't have time to extract the relevant parts but take a look for example in Webliter.prototype.highlight (just search for this in that file)
You can also use jQuery for example this plugin: http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html

Insert text at cursor in a content editable div

I have a contenteditable div where I need to insert text at the caret position,
This can be easily done in IE by document.selection.createRange().text = "banana"
Is there a similar way of implementing this in Firefox/Chrome?
(I know a solution exists here , but it can't be used in contenteditable div, and looks clumsy)
Thank you!
The following function will insert text at the caret position and delete the existing selection. It works in all the mainstream desktop browsers:
function insertTextAtCaret(text) {
var sel, range;
if (window.getSelection) {
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
range.insertNode( document.createTextNode(text) );
}
} else if (document.selection && document.selection.createRange) {
document.selection.createRange().text = text;
}
}
UPDATE
Based on comment, here's some code for saving and restoring the selection. Before displaying your context menu, you should store the return value of saveSelection in a variable and then pass that variable into restoreSelection to restore the selection after hiding the context menu and before inserting text.
function saveSelection() {
if (window.getSelection) {
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
return sel.getRangeAt(0);
}
} else if (document.selection && document.selection.createRange) {
return document.selection.createRange();
}
return null;
}
function restoreSelection(range) {
if (range) {
if (window.getSelection) {
sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (document.selection && range.select) {
range.select();
}
}
}
Get a Selection Object with window.getSelection().
Use Selection.getRangeAt(0).insertNode() to add a textnode.
If necessary, move the cursor position behind the added text with Selection.modify(). (Not standardized, but this feature is supported in Firefox, Chrome and Safari)
function insertTextAtCursor(text)
{
let selection = window.getSelection();
let range = selection.getRangeAt(0);
range.deleteContents();
let node = document.createTextNode(text);
range.insertNode(node);
for(let position = 0; position != text.length; position++)
{
selection.modify("move", "right", "character");
};
}
UPD: since ~2020 solution is obsoleted (despite it can work yet)
// <div contenteditable id="myeditable">
// const editable = document.getElementById('myeditable')
// editable.focus()
// document.execCommand('insertHTML', false, '<b>B</b>anana')
document.execCommand('insertText', false, 'banana')
I have used next code to insert icons in chat msg
<div class="chat-msg-text" id="chat_message_text" contenteditable="true"></div>
<script>
var lastCaretPos = 0;
var parentNode;
var range;
var selection;
$(function(){
$('#chat_message_text').focus();
$('#chat_message_text').on('keyup mouseup',function (e){
selection = window.getSelection();
range = selection.getRangeAt(0);
parentNode = range.commonAncestorContainer.parentNode;
});
})
function insertTextAtCursor(text) {
if($(parentNode).parents().is('#chat_message_text') || $(parentNode).is('#chat_message_text') )
{
var span = document.createElement('span');
span.innerHTML=text;
range.deleteContents();
range.insertNode(span);
//cursor at the last with this
range.collapse(false);
selection.removeAllRanges();
selection.addRange(range);
}
else
{
msg_text = $("#chat_message_text").html()
$("#chat_message_text").html(text+msg_text).focus()
}
}
</script>
If you are working with rich editors (like DraftJs) but have no access to their APIs (e.g. modifying from an extension), these are the solutions I've found:
Dispatching a beforeinput event, this is the recommended way, and most editors support
target.dispatchEvent(new InputEvent("beforeinput", {
inputType: "insertText",
data: text,
bubbles: true,
cancelable: true
}))
Dispatching a paste event
const data = new DataTransfer();
data.setData(
'text/plain',
text
);
target.dispatchEvent(new ClipboardEvent("paste", {
dataType: "text/plain",
data: text,
bubbles: true,
clipboardData: data,
cancelable: true
}));
This last one uses 2 different methods:
Using data and dataType properties. This one works in Firefox
Using clipboardData property. Which works in Chrome but not in Firefox? https://github.com/facebook/draft-js/issues/616#issuecomment-426047799 . Though It's supposed to work in Firefox, maybe I don't know how to use it or there's a bug.
If you want to replace all existing text, you have to select it first
function selectTargetText(target) {
const selection = window.getSelection();
const range = document.createRange();
range.selectNodeContents(target);
selection.removeAllRanges();
selection.addRange(range);
}
selectTargetText(target)
// wait for selection before dispatching the `beforeinput` event
document.addEventListener("selectionchange",()=>{
target.dispatchEvent(new InputEvent("beforeinput", {
inputType: "insertText",
data: text,
bubbles: true,
cancelable: true
}))
},{once: true})
Pasting plain text can be handled with the following code.
const editorEle = document.getElementById('editor');
// Handle the `paste` event
editorEle.addEventListener('paste', function (e) {
// Prevent the default action
e.preventDefault();
// Get the copied text from the clipboard
const text = e.clipboardData
? (e.originalEvent || e).clipboardData.getData('text/plain')
: // For IE
window.clipboardData
? window.clipboardData.getData('Text')
: '';
if (document.queryCommandSupported('insertText')) {
document.execCommand('insertText', false, text);
} else {
// Insert text at the current position of caret
const range = document.getSelection().getRangeAt(0);
range.deleteContents();
const textNode = document.createTextNode(text);
range.insertNode(textNode);
range.selectNodeContents(textNode);
range.collapse(false);
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
}
});
just an easier method with jquery:
copy the entire content of the div
var oldhtml=$('#elementID').html();
var tobejoined='<span>hii</span>';
//element with new html would be
$('#elementID').html(oldhtml+tobejoined);
simple!

Categories