Android: window.getSelection() does not work in webview - javascript

I have an app with a webview and I have been trying to get user-selected text from the body of the webview. You would think that the operating system would be able to handle something like the way iOS does, but this one of the many places where Android is utterly inadequate. I've probed this website and google and found nothing that could help me. My app, luckily has a javascript interface, to communicate with a script that we load into the webview. I thought i could use javascript to select the text from the webview. In chrome i can do this with the following bit of javascript:
window.getSelection.toString();
Right now i have a button which calls a function in my js file that will run the above command and return it's results to a method in my javascript interface. That message will toast the result of my javascript function. So i select text and then press this button. The only problem is that my toast message returns the following message:
javascript returned:
when it should return
javascript returned: <my selected text>
When i remove the '.toString(); part from my javascript command and select text and press a button i get teh following message
javascript returned: undefined
Why isn't this working?
Here's my code in context. This is hte javascript that gets called:
myNameSpace.getTextSelection = function()
{
var str;
if (window.getSelection){
str = window.getSelection().toString();
} else {
str = 'does not';
}
window.myJSHandler.getSelectedText(str);
};
and here's the java function it is calling
public void getSelectedText(String text)
{
String str = "function called. it returned: " + text;
Toast.makeText(getApplicationContext(), str, Toast.LENGTH_LONG).show();
}

Got solution which works for me
//I am using below line of code which works in both android and web browsers.
function getSelectedText() {
var selection = null;
if (window.getSelection) {
selection = window.getSelection();
} else if (typeof document.selection != "undefined") {
selection = document.selection;
}
var selectedRange = selection.getRangeAt(0);
console.log(selectedRange.toString());
}
NOTE : Don't call this method in post or inside any runnable interface as post or any runnable interface make delay in calling this method(Method call happens after browser selection release). Just call this method like
webView.loadUrl("javascript:getSelectedText()");

Because the text selection is happens in android on a separate class WebTextView so if we tryies to get the selected word using javascript method -
var range = window.getSelection ();
but this functions returns nothing if you want the selected word you can use reflection for that in case if you want that i will add that code later.

Related

How to call a function with an event handler if the function requires the event to compile

I am currently working on a project where I need to call a script function on an event. This function is called when text is pasted into a textarea. The function copies the pasted text into an array and iterates through the array looking for the code value of Unicode right apostrophe (8217). It then replaces any found right apostrophe's with a single quote. The function works as expected. However I am running this function on 8 different pages and want to clean my code up. I placed the script into a js file that is called on every page in the project so if any more cases it is needed are found it will be easy to implement.
The function is being called with:
<script>
var instructions = document.getElementById("specialInstructions");
instructions.addEventListener("paste", pasteToPlainText);
</script>
The function in the js file is:
function pasteToPlainText(event){
var plainText;
var replaceList;
replaceList = new Array();
//converts the pasted text to plain text
if (event.clipboardData && event.clipboardData.getData){
plainText = event.currentTarget.clipboardData.getData('text/plain');
}else if (window.clipboardData){
plainText = event.currentTarget.clipboardData.getData('text/plain');
}
for (var index = 0; index < plainText.length; index++){
var rightApostropheCheck = plainText.charCodeAt(index);
//Unicode for right apostrophe is 8217 (Used in outlook email)
//Without this conversion a right apostrophe is put on screen.
// The note is unable to save with a right apostrophe
if (rightApostropheCheck == 8217){
// replaces a right apostrophe with a single quote (apostrophe)
replaceList.push("'");
}else{
// pushes all other text to the list that is printed to screen
replaceList.push(plainText[index]);
}
}
event.preventDefault();
if (event.clipboardData) {
content = replaceList.join("");
document.execCommand('insertText', false, content);
}else if (window.clipboardData) {
content = replaceList.join("");
document.selection.createRange().pasteHTML(content);
}
}
I get the error: Uncaught TypeError: Cannot read properties of undefined (reading 'clipboardData')
On the first if statement.
Any help or advice will be greatly appreciated. Thank you.
Update:
I found a solution. making the event listener with a bind statement makes sure the function is not called on load. That was the problem as the page loaded the function was called without any information. so it had undefined errors and null errors. The correct way to call the function is as follows.
<script>
var terms = document.getElementById("Terms");
terms.addEventListener("paste", pasteToPlainText.bind(terms));
</script>

How can I copy text to the clipboard in an Automator JavaScript?

I am writing a simple Automator script in JavaScript (because I’m much more productive in JavaScript). For testing purposes, I simply eval() the input.
The script is:
// Workflow receives current text in any application
function run(input, parameters) {
// 1+2*3
var app = Application.currentApplication()
app.includeStandardAdditions = true
// app.displayDialog(input)
// app.displayDialog(input[0])
result = eval(input[0]) || 0;
app.displayDialog(result)
app.setTheClipboardTo(result)
return result
}
// Copy to Clipboard
I would like to get the result onto the clipboard. As you see above, I have applied the setTheClipboardTo() function.
The Workflow receives the current text.
I have also added the Copy to Clipboard action to the end.
I have tried with or without the setTheClipboardTo() function, and with or without the Copy to Clipboard action. The displayed message has the correct result, but I can’t get it to the clipboard.
I don’t know what I did wrong before, except possibly adding the action at the end. Here is a version that works:
// Workflow receives current text in any application
// Replaces Selection
function run(input, parameters) {
// 1*2*3*4*5*6+7-8-9
// 1 2 3
var app = Application.currentApplication();
app.includeStandardAdditions = true;
// Filter for eval()
expression = input[0].replace(/[^0-9 +\-*\/÷×()]/g,'?')
try {
result = eval(input[0])*1;
} catch(e) {
result = 0
}
app.setTheClipboardTo(result.toString())
return result
}

getSelection.getRangeAt(0) in Google Chrome Extension

I'm trying to determine the position of a selected text in my browser. I need the position to show a tooltip above the selected text. I guess if I get the boundaries, I'm able to calculate the middle of that.
I fiddled around and looked here for suggestions, but couldn't find a solution.
If I'm not mistaken, this seems to be a problem related to Google Chrome?
Please be aware, that I'm trying to create a chrome-extension, so there is no need of testing if it works in Firefox / IE ...
This is all the code which causes the trouble:
var selection = window.getSelection();
// calculate the posiition of the selection
var oRange = selection.getRangeAt(0);
var oRect = oRange.getBoundingClientRect();
console.log(oRect);
(I tried to refer to this example here)
The error is like this:
background.js:20 Uncaught DOMException: Failed to execute 'getRangeAt' on 'Selection': 0 is not a valid index.
If this is doable with jQuery, I don't mind using this as well, I'm not restricted to native JavaScript.
Complete code of my background.js
chrome.contextMenus.create({
"title": "Übersetzen",
"contexts": ["selection"],
"onclick" : clickHandler
});
function clickHandler(e) {
var translateUrl = "https://glosbe.com/gapi/translate?from=eng&dest=deu&format=json&phrase=" + encodeURI(e.selectionText.toLowerCase()) + "&pretty=true";
$.getJSON(translateUrl, callback);
// console.log(data.responseTex);
}
function callback(data) {
var translation = data.tuc[0].phrase.text;
var selection = document.getSelection();
console.log(selection);
// calculate the position of the selection
var oRange = selection.getRangeAt(0);
var oRect = oRange.getBoundingClientRect();
console.log(oRect);
var selection = "";
chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
chrome.tabs.sendMessage(tabs[0].id, {translation: translation}, function(response) {});
});
}
Update: When I run this code directly in the browser-console, it works as expected (If that is useful as a hint)
Update2: Maybe this is important: After selecting the text, I open the context-menu (via mouseclick) and click on an item, but the selection shouldn't be affected by this.
Update3: The code above works fine in an example-HTML page. My Background script seems to get an unfilled object (where there all the values are null)
Update 4: I added the complete code for reference (I also tried chrome.tabs.executeScript - but without success)
You need to get the selection in your content-script, not in the background script. Try calling your "onMessage"-method and use var s = window.getSelection() there. If you log this into the console, it works as expected.

C# + WebBrowser + JavaScript - full load

Good time of day!:).Net 4.0, console. I need to write a parser page in console mode to get the code page in the form in which it is displayed to the user after download, without clicking the buttons, scrolling, and other events. I use this code, but it returns absolutely not what you need. In what ways can I get my desired result? I use other methods or components?
wb = new WebBrowser();
wb.Navigate(linkNorm);
wb.ScriptErrorsSuppressed = true;
wb.DocumentCompleted += new
WebBrowserDocumentCompletedEventHandler(w_DocumentCompleted);
while (wb.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
originalText = wb.DocumentText;
wb.Dispose();
void w_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
Trace.WriteLine(wb.DocumentText);
}
Change method to wb.Document.Body.OuterHtml - not help me. Result is so bad.
I think this is a pretty simple task, probably someone already solved.
Note - i need full HTML text in string-variable after work ALL JS

Javascript call Public function on Activex

I´m trying to call a function from javascript to ActiveX. It worked but now, i have to update the activeX because of Internet Explorer 8 and Windows 7.
But for now, i can´t call the function. When i try, i got a message: Object is not a collection.
What i suppose to do?
Here´s the piece of code:
Public Function Text(strTxt As String) As String
If result Then
Text = "Authenticated"
Else
Text = "Not authenticated"
End If
End Function
In Javascript:
function leDado()
{
try {
var x=document.getElementById("MyActivex")
document.MainForm.resultado.value = x.Text("Test string")
x = 0;
}
catch(e) {
alert(e.message);
}
}
In the form, when i press the button, i call that function.
Can anyone help me?
So you’ve updated the ActiveX object; did that break binary compatibility? If so, did you unregister and re-register the library before testing it? Can you debug the object 'live'?

Categories

Resources