Using CEFSharp to edit <textarea> - javascript

I am able to edit a regular textbox within an iFrame in CefSharp like so:
Browser1.GetBrowser().GetFrame("iFrame1").ExecuteJavaScriptAsync("document.getElementById('ElementID').value=" + '\'' + "1234" + '\'');
However, because a textarea doesn't have a value:
<iframe id="iFrame1" name="iFrame1">
<textarea name="txtareaname" id="txtareaname1">sometexthere</textarea>
</iframe>
I am unable to execute a similar line of code to edit the text in the textarea:
textarea.Browser1.GetBrowser().GetFrame("iFrame1").ExecuteJavaScriptAsync("document.getElementById('txtareaname1').value=" + '\'' + "1234" + '\'');
I have also tried:
textarea.Browser1.GetBrowser().GetFrame("iFrame1").ExecuteJavaScriptAsync("document.getElementById('txtareaname1').innertext=" + '\'' + "1234" + '\'');
How do I adjust my code to edit this textarea?

OP: However, because a textarea doesn't have a value I am unable to
execute a similar line of code to edit the text in the textarea.
The assumption is wrong, setting value attribute works fine for teaxtarea.
You should just make sure the document, including the iframe has been loaded and you have selected the correct iframe using correct name and then you have selected the correct textarea using correct id.
Example
Here is a minimal complete verifiable example which shows how you can find the iframe and set the value of a textarea inside the iframe.
To make the example independent from externals sources and make verification easier, instead of initializing iframe using its src attribute, I've initialized iframe using script.
protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
var content = new HtmlString(#"
<!DOCTYPE html>
<html>
<body>
<iframe id=""iFrame1"" name=""iFrame1"" src=""about:blank""></iframe>
<script>
var doc = document.getElementById('iFrame1').contentWindow.document;
doc.open();
doc.write('<html><head><title></title></head><body>' +
'Address:<br>' +
'<textarea id=""myTextarea"">342 Alvin RoadDucksburg</textarea>' +
'</body></html>');
doc.close();
</script>
</body>
</html>
");
var browser = new ChromiumWebBrowser(content)
{ Dock = DockStyle.None, Size = new Size(400, 200), Location = new Point(8, 42) };
Controls.Add(browser);
var button = new Button() { Text = "Click Me", Location = new Point(8, 8) };
Controls.Add(button);
button.Click += (obj, args) => {
browser.GetBrowser().GetFrame("iFrame1")
.ExecuteJavaScriptAsync("document.getElementById('myTextarea').value=" +
"'Fifth Avenue, New York City'");
};
}

Related

WKWebView and InnerText with newline

I am currently working on implementing a web view inside of my iOS application using Xamarin. My webView is a WkWebView. My issue is that any time the text I am passing in has a new line it fails to display. However, testing my function in my browser (chrome) along with Safari I see that it executes just fine. I did some searching and I also tried to replace the \n character with \r\n, but that did not solve my issue. What am I missing?
C#:
private void BuildText(FormEntries entry, FormResponseAnswers formAnswers) {
string function = "buildText('" + entry.Text + "', '" + formAnswers.Answer + "');";
var javaScriptCmd = (NSString)function;
webView.EvaluateJavaScript(javaScriptCmd, null);
}
formAnswers.Answer that is causing the issue is:
"Hello world from the device, I do not know how well this will display our data at all. But we will see how this works. I wonder, if I were to add enter keys will it work?\n\n\nI kinda doubt it. ";
JS:
function buildText(entryText, answer) {
var answerAreaDiv = document.getElementById('answerArea');
var holder = document.createElement('div');
holder.classList.add('holder');
var entryLabel = document.createElement("label");
entryLabel.textContent = entryText + ':';
var answerLabel = document.createElement("label");
answerLabel.innerText = answer;
holder.appendChild(entryLabel);
holder.appendChild(answerLabel);
answerAreaDiv.appendChild(holder);
}
HTML:
<body>
<div id="answerArea">
</div>
</body>
HTML elements don't line break unless you explicitly ask them to; line breaks such as \n are treated as spaces. Try inserting HTML instead, so that you can replace your newline with a <br>:
answerLabel.innerHTML = answer.replace(/\n/g, '<br>');
Example:
document.body.appendChild(document.createElement('label')).innerHTML = `first line
second line`.replace(/\n/g, '<br>');

Can Not Set Value of DOM Element Unless New Value Is Strictly Numeric

DISCLAIMER: total beginner with regards to browser extensions and javascript.
BACKGROUND:
I'm trying to develop a proof-of-concept Chrome extension that picks up the text from the input fields in the HTML form of the web page loaded into one tab, and enters the same text on analogous fields of the page in another tab.
In my particular example, the source page is a minimal, local HTML file with two input fields ("user name" and "password"), and the destination is the login page for Apple's Developer Website (https://developer.apple.com/account/).
Reading the official guides and questions here, I've put together some code that seems to work.
THE PROBLEM:
Only text consisting of digits (e.g.: "111111") gets copied from one tab to the other. As soon as my input field contains letters (e.g.: "111111a"), nothing happens.
This is the source page (local file:///):
<html>
<head>
<title>Source Page</title>
<meta charset="utf-8" />
<script src="popup.js"></script>
</head>
<body>
<form>
<input id="accountname_src" name="appleId" placeholder="Apple ID" /><br />
<input id="accountpassword_src" name="password" placeholder="Password" />
</form>
</body>
</html>
The destination HTML (Apple's page) has similar input fields with element ids of accountname and accountpassword, respectively.
My extension's script is as follows:
document.addEventListener('DOMContentLoaded', function(){
// The button in the browser action popup:
var button = document.getElementById('autofill');
var sourceTabID = null;
var destTabID = null;
// Get the SOURCE tab id:
chrome.tabs.query({'title': 'Source Page'}, function(tabArray){
sourceTabID = tabArray[0].id;
});
// Get the DESTINATION tab id:
chrome.tabs.query({'title': 'Sign in with your Apple ID - Apple Developer'}, function(tabArray){
destTabID = tabArray[0].id;
});
if (button !== null){
button.addEventListener('click', function(){
// Get entered text from Source page:
chrome.tabs.executeScript(sourceTabID, {file: "read_input.js"}, function(results){
var credentials = results[0];
var userName = String(credentials[0]);
var password = String(credentials[1]);
// Pass values to Apple login page:
var insertUserNameCode = "document.getElementById('accountname').value = " + userName + ";"
var insertPasswordCode = "document.getElementById('accountpassword').value = " + password + ";"
var autofillCode = insertUserNameCode + insertPasswordCode;
chrome.tabs.executeScript(destTabID, {code:autofillCode});
});
//window.close();
});
}
});
of course, the contents of read_input.js are:
var userName = document.getElementById("accountname_src").value;
var password = document.getElementById("accountpassword_src").value;
var attributes = [userName, password];
attributes // (Final expression, passed to callback of executeScript() as 'results')
It feels like there could be a type inference problem somewhere, but can't tell where.
Bonus Question:
I can read the input fields in the source page using an external script (read_input.js above) and the method chrome.tabs.executeScript(..., file:...; but when I try to write the values to the destination tab using a similar approach, the script does not run (that is why I'm using chrome.tabs.executeScript(..., code:... in my code). Any idea what can be happening?
Silly me (again)... Some console.logging led me in the right direction...
I was not escaping the value in the script; these lines:
var insertUserNameCode = "document.getElementById('accountname').value = " + userName + ";"
var insertPasswordCode = "document.getElementById('accountpassword').value = " + password + ";"
...should be:
var insertUserNameCode = "document.getElementById('accountname').value = '" + userName + "';"
var insertPasswordCode = "document.getElementById('accountpassword').value = '" + password + "';"
(added single ticks around the values)
...so that the code ends up as:
document.getElementById('accountname').value = '111111a';
...instead of:
document.getElementById('accountname').value = 111111a;
Still not sure why a numbers-only value works, though.

Document won't load into iframe with changed, but proper, name

What I'm trying to achieve is being able to load contents of href in to one of three iframes, by changing thier names via java.
The problem is: Chrome will always load contents into first iframe, ignoring it's name change, this problem does not occur in Firefox.
function change_name()
{
document.getElementById('frame1').name = "#" ;
document.getElementById('frame2').name = "main_frame" ;
};
.frame {
width:100px;
height:100px;
}
<iframe id="frame1" name="main_frame" class="frame"></iframe>
<iframe id="frame2" name="#" class="frame"></iframe>
<iframe id="frame3" name="#" class="frame"></iframe>
<input type="submit" onclick="change_name()" value="change iframe name"/>
load page into iframe
jsfiddle demonstrating what I'm trying to do: http://jsfiddle.net/514y7v4m/1/
Any help is much appreciated
Stumbled upon this link: http://help.dottoro.com/ljbimuon.php
After some modification of your script, i believe this could be the solution. Changing the contenWindow.name instead of name alone seems to do the trick.
function change_name() {
var one = document.getElementById('frame1');
one.contentWindow.name = "#";
console.log("The name is: " + one.name);
console.log("The name of the window: " + one.contentWindow.name);
var two = document.getElementById('frame2');
two.contentWindow.name = "main_frame";
console.log("The name is: " + two.name);
console.log("The name of the window: " + two.contentWindow.name);
};

Javascript add bold text to a frame

I want to add bold to the (see illustration). If I do this:
p:function{
sel = this.getSelection().getRangeAt(0);
var caretPosition = sel.endOffset;
var existingText = this.iframe[0].contentWindow.document.body.innerText;
var before = existingText.substring(0, caretPosition);
var after = existingText.substring(caretPosition);
this.iframe[0].contentWindow.document.body.innerHTML= before
+'**<b>**(see illustration)**</b>** ' + after;
},
Then all the text that i write after (see illustration becomes bold).
If you want to create an editable iframe with Bold, Italic or other commands you can use the underlying browser commands which you can fire through the execCommand method.
You could see there resources for more information:
https://developer.mozilla.org/en-US/docs/Web/API/document.execCommand
https://developer.mozilla.org/en/docs/Rich-Text_Editing_in_Mozilla
These method is supported by all modern browsers.
I've provided a simple example that shows you how execCommand works
<iframe id = "my-editable">
<html>
<body contenteditable = "true">
</body>
</html>
</iframe>
JavaScript code:
var iframe = document.getElementById('my-editable');
var iframeDoc = iframe.contentWindow.document;
// type and select some text into iframe
// For making selected text to be bold, just execute the following command
iframeDoc.execCommand('bold');
UPDATE
var body = iframeDoc.body;
body.innerHTML = body.innerHTML + '<b>' + 'your bold text' + '</b>' + 'your boldless text'

Create a inputbox which writes to textarea(php)

Just for fun am I creating a chatroom for one of my school classes.
What I'm after is a JavaScript, with a inputbox which pops up, once a button (add url) is pushed, where the user can paste a url which then gets written in the textarea.
I want this feature just so "http://" gets placed in front of the added url.
Been trying with this script (which looks correct to me... but it doesn't work)
<input type="button" id="s_5" onclick="addUrl()">
<script>
function addUrl()
{
var x;
var nettside=prompt("Type in URL:","www.example.com");
if (nettside!=null)
{
x="http://" + nettside + ";
document.getElementById("area").innerHTML=x;
}
}
</script>
yeah, the textarea it's supposed to write to:
<textarea name="txt" id="area" class="typo_vind" placeholder="......" autofocus title="Type your message here, have a great day!"></textarea>
EDIT
HTML:
<input type="button" id="s_5" onclick="javascript:formatText(addUrl())">
JS:
<script>
function addUrl()
{
var x;
var nettside=prompt("Skriv inn lenkeadressen her:","www.testtest.com");
if (nettside!="")
{
x="" + "BESKRIVELSE AV LENKEN" + "";
document.getElementById("area").value=x;
}
}
</script>
Two problems remains.
I don't want that script to clean out the textarea
I don't want the <undefined></undefined> to get added to the end
This is the result with the script as it is now:
<a href=http://www.eksempel.com>__BESKRIVELSE_AV_LENKEN__</a><undefined></undefined>
EDIT 2
Solved the problem where the script cleaned out the texarea with this:
<script>
function addUrl()
{
var x;
var nettside=prompt("Skriv inn lenkeadressen her (uten http://):","www.eksempel.com");
{
x="<a target =_blank href=http://" + nettside + ">" + "__BESKRIVELSE_AV_LENKEN__" + "</a>";
var Field = document.getElementById('area');
var val = Field.value;
var selected_txt = val.substring(Field.selectionStart, Field.selectionEnd);
var before_txt = val.substring(0, Field.selectionStart);
var after_txt = val.substring(Field.selectionEnd, val.length);
Field.value = before_txt + x + after_txt;
}
}
</script>
So now all that's missing is removal of the <undefined></undefined>-tags.
HTML: <input type="button" id="s_5" onclick="javascript:addUrl()">
SOLVED!
You should check the console of your browser - it always notifies about what error has occurred.
You have a typo in this line:
x="http://" + nettside + ";
The ending + " should be deleted.
Also, here:
document.getElementById("area").innerHTML=x;
you should use value instead (normally you do this with for elements):
document.getElementById("area").value=x;
This might not cause problems in the browser you are using, but might lead to strange behaviour under certain circumstances :).

Categories