Difference between innerhtml and outerhtml in cocoa WebView - objective-c

I am using cocoa webview for rich text editing in my application. Just confused with innerHtml and outerHtml method avaiable in webkit.
Can anyone explain what is the difference between
[(DOMHTMLElement *)[[[webView mainFrame] DOMDocument] documentElement] outerHTML];
AND
[(DOMHTMLElement *)[[[webView mainFrame] DOMDocument] documentElement] outerText];

innerHTML is a property of a DOM element that represents the HTML
inside the element, i.e. between the opening and closing tags. It has
been widely copied, however implementations vary (probably because it
has no published standard[1]) particularly in how they treat element
attributes.
outerHTML is similar to innerHTML, it is an element property that
includes the opening an closing tags as well as the content. It
hasn't been as widely copied as innerHTML so it remains more-or-less
IE only.
<p id="pid">welcome</p>
innerHTML of element "pid" == welcome
outerHTML of element "pid" == <p id="pid">welcome</p>
and whereAs
innerText The textual content of the container.
outerText Same as innerText when accessed for read; replaces the whole element when assigned a new value.
<p id="pid">welcome</p>
innerText of element "pid" == welcome
outerText of element "pid" == welcome

Suppose we have a page loaded to webview with html
<html>
<head><title>Your Title</title></head>
<body>
<h1>Heading</h1>
<p id="para" >hi <b>Your_Name</b></p>
</body>
<html>
NOW.
[(DOMHTMLElement *)[[webView mainFrame] DOMDocument] documentElement]
will returen the DOMHTMLElement "html" and
outerHTML will return the complete html as
<html>
<head><title>Your Title</title></head>
<body>
<h1>Heading</hi>
<p id="para">hi <b>Your_Name</b></p>
</body>
<html>
outerText will return html as
Heading
hi Your_Name
for example if we take example of p tag in this case
outerHTML will return - <p id="para">hi <b>Your_Name</b></p>
outerText will return - hi Your_Name
innerHTML will return - hi <b>Your_Name</b>
innerText will return - hi Your_Name
i have explained it with the help of example where definition for these 4 terms already explained in the answer below.

<!DOCTYPE html>
<html>
<head>
<title>innerHTML and outerHTML | Javascript Usages</title>
</head>
<body>
<div id="replace">REPLACE By inner or outer HTML</div>
<script>
userwant = "inner";
userwant = "outer";
if (userwant = "inner") {
document.querySelector("#replace").innerHTML;
// this will remove just message: 'REPLACE By inner or outer HTML' //
} else if (userwant = "outer") {
document.querySelector("#replace").outerHTML;
// this will remove all element <div> ~ </div> by the message: 'REPLACE By inner or outer HTML' //
};
</script>
</body>
</html>

Related

Context Dictionary isn't being passed with render in view

Alright, I've been poking around the internet for a solution to that there's something obvious that I'm missing but so far no good.
I'm currently having trouble with passing a context dictionary to a template in Django via my view. So far everything else seems to return, except for the dictionary that I'm passing to the template.
def search_subjects(request):
"""
This is our search view, at present it collects queries relating to:
- Subject ID
- Study Name
- Date Range Start
- Date Range Start
Then validates these entries, after which it redirects to the search
results view.
:param request:
:return: Redirect to search results if search button is pressed and form fields
are valid or renders this view again if this request is not POST
"""
if request.method == 'POST':
form = SearchForm(request.POST)
if form.is_valid():
search_dict = {}
search = form.save(commit=False)
search.subject_search = request.POST['subject_search']
search.study_search = request.POST['subject_search']
if request.POST['date_range_alpha'] and \
dateparse.parse_datetime(request.POST['date_range_alpha']):
search.date_range_alpha = request.POST['date_ranch_alpha']
else:
search.date_range_alpha = EPOCH_TIME
if request.POST['date_range_omega'] and \
dateparse.parse_datetime(request.POST['date_range_omega']):
with_tz = dateparse.parse_datetime(request.POST['date_range_omega'])
search.date_range_omega = with_tz
else:
search.date_range_omega = timezone.now()
search.save()
for k, v in form.data.items():
search_dict[k] = v
print(search_dict)
return render(request, 'dicoms/search_results.html', search_dict)
else:
form = SearchForm()
return render(request, 'dicoms/search.html', {'form': form})
And my template here:
!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Search Results</title>
</head>
<body>
Here's what you searched for:
<div>{{ search_dict }}</div>
</body>
</html>
The page that I'm getting back:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Search Results</title>
</head>
<body>
Here's what you searched for:
<div></div>
</body>
</html>
What on earth am I missing here?
Ok, so I walked away from this for a bit and managed to solve it. I wasn't passing a context dictionary correctly. Fix can be seen below.:
search.save()
context = {'search': search}
return render(request, 'dicoms/search_results.html', context)
Adjusting the template accordingly:
Here's what you searched for:
<div>{{ search.subject_search }}</div>
<div>{{ search.study_search }}</div>
<div>{{ search.date_range_alpha }}</div>
<div>{{ search.date_range_omega }}</div>
Results in:
Here's what you searched for:
<div>herp </div>
<div>herp </div>
<div>Jan. 1, 1970, midnight</div>
<div>Feb. 26, 2019, 11:05 p.m.</div>
Had I trusted in django and simply passed the whole search object in the beginning I wouldn't have ended up here. But you live and learn.

Send text to Text Field

How to send Text in text area field using geb & Spock?
Using just Selenium & the sendKeys I am able to send the text.
But unable to implement using geb spock.
this[field] = value - Not working
element.sendKeys(""); - Working
You probably want to look into the use of Geb Modules, particularly the Text Area module.
Taken from the documentation:
Given the html…
<html>
<body>
<textarea name="language"/>
</body>
</html>
It can be used this way…
def textarea = $(name: "language").module(Textarea)
textarea.text = "Groovy"
assert textarea.text == "Groovy"
<html>
<body>
<textarea name="language" id = "id1"/>
</body>
</html>
=====================================================
//content definition
textarea = { $(#id1") }
//updating value
textarea.value("your value")
OR
textarea << "your value"

How can an nodelist created by getElementsByClassname or getElementsByTagName display its values as string

What I know about getElementsByClassName / getElementsByTagName is that both create a nodelist of the elements in question and that the nodelist elements are treated as objects I have a problem where I want to display the innerHTML of the elements inside of the nodelist but because they are objects this seems to be impossible.
Example:
<!DOCTYPE html>
<head>
<link rel="stylesheet" type="text/css" href="stylesheet.css">
<script src="javascript.js"></script>
</head>
<body>
<p id="pp"></p>
<button onclick="test()">push to test</button>
<p>dog</p>
<p>cat</p>
<p>snake</p>
</body>
//javascript.js file
function test() {
var paragraph = document.getElementsByTagName("p"),
para1 = paragraph[0].innerHTML,
ansBox = document.getElementById("pp");
ansBox.innerHTML = para1;
}
This is condensed version of a longer code. I think that the para1 variable should be a string and then the assignment statement should assign that string to the ansBox.innerHTML but instead I get nothing. I have reworked several versions of this code none work. How can you get the text elements inside of a nodelist to display in the ansBox?
Your script is loaded but your DOM hasn't loaded yet if you load your script inside head like that
<!DOCTYPE html>
<head>
<link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>
<body>
<p id="pp"></p>
<button onclick="test()">push to test</button>
<p>dog</p>
<p>cat</p>
<p>snake</p>
<script src="javascript.js"></script> <!-- load it here -->
</body>
Also paragraph[0] and ansBox refer to the same DOM HTMLParagraphElement just so you know which does not have anything inside (It is empty to begin with)
In the JavaScript code above, you took the HTML inside an empty element and then assign it to itself, and of course you get an empty value.

C# Selenium Webdriver (Firefox) iFrame does not allow text to be entered via sendKeys

I'm using latest Selenium Firefox (2.53.0)
Previously code was working when performing the following
1) Finding the iFrame by Xpath iframe class
IWebElement detailFrame = `Driver_Lib.Instance.FindElement(By.XPath("//iframe[#class='cke_wysiwyg_frame cke_reset']"));`
2) Switching to that frame by
Driver_Lib.Instance.SwitchTo().Frame(detailFrame);
3) finding the p tag within the iFrame by
IWebElement freeText = Driver_Lib.Instance.FindElement(By.TagName("p"));
4) Inserting a simple string to the iframe text box
freeText.SendKeys("this is some text");
5) switching from the iFrame back to the main contentwindow by
Driver_Lib.Instance.SwitchTo().DefaultContent();
Here is the code part from the application
<iframe class="cke_wysiwyg_frame cke_reset" frameborder="0" src="" style="width: 100%; height: 100%;" title="Rich Text Editor, ctl00_ctl00_MainContentPlaceHolder_PageContent_mlcEditor_CKEditor" aria-describedby="cke_61" tabindex="0" allowtransparency="true">
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<title data-cke-title="Rich Text Editor, ctl00_ctl00_MainContentPlaceHolder_PageContent_mlcEditor_CKEditor">Rich Text Editor, ctl00_ctl00_MainContentPlaceHolder_PageContent_mlcEditor_CKEditor</title>
<style data-cke-temp="1">
<link href="https://myUrl/contents.css" rel="stylesheet" type="text/css">
<style data-cke-temp="1">
</head>
<body class="cke_editable cke_editable_themed cke_contents_ltr cke_show_borders" contenteditable="true" spellcheck="false">
<p>
<br _moz_editor_bogus_node="TRUE">
</p>
</body>
</html>
</iframe>
The test I am running is a simple one, open up that page, insert some text, save.
It not inserting the text into the iFrame. I am totally puzzled as to why.
Has anyone else found this issue at all?
Many thanks
I have removed the exception, this was a redHerring.
the iFrame can not have text entered into it
hi all I've found the solution:~ here is the summary of what was happening:
1) The iFrame was being located by xPath.
2) the SwitchTo() method used placed focus in the detailFrame instance of IWebElement
3) What was not happening was the p tag could not be located as it was contained withing a CSS Body Class that.
The solution was staring me in the face the whole time! so simple!!
I did this:
IWebElement detailFrame = Driver_Lib.Instance.FindElement(By.XPath("//iframe[#class='cke_wysiwyg_frame cke_reset']"));
Driver_Lib.Instance.SwitchTo().Frame(detailFrame);
IWebElement freeText = Driver_Lib.Instance.FindElement(By.TagName("body"));
freeText.SendKeys("This is a free text question created by Automation Smoke Test");
Driver_Lib.Instance.SwitchTo().DefaultContent();
So as you see, simply locating the 1st instance of the body tag!

How to add id using dojo.query to search element

I'm trying to add id to a element using dojo.query. I'm not sure if it's possible though. I trying to use the code below to add the id but it's not working.
dojo.query('div[style=""]').attr("id","main-body");
<div style="">
content
</div>
If this is not possible, is there another way to do it? Using javascript or jquery? Thanks.
Your way of adding an id to an element is correct.
The code runs fine for me in Firefox 17 and Chrome 23 but I have an issue in IE9. I suspect you may have the same issue.
In IE9 the query div[style=""] returns no results. The funny thing is,it works fine in compatibility mode!
t seems that in IE9 in normal mode if an HTML element has an inline empty style attribute, that attribute is not being preserved when the element is added to the DOM.
So a solution would be to use a different query to find the divs you want.
You could try to find the divs with an empty style attributes OR with no style attribute at all.
A query like this should work:
div[style=""], div:not([style])
Take a look at the following example:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test Page</title>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/dojo/1.8.2/dojo/dojo.js"></script>
<script type="text/javascript">
dojo.require("dojo.NodeList-manipulate");//just for the innerHTML() function
dojo.addOnLoad(function () {
var nodeListByAttr = dojo.query('div[style=""], div:not([style])');
alert('Search by attribute nodeList length:' + nodeListByAttr.length);
nodeListByAttr.attr("id", "main-body");
var nodeListByID = dojo.query('#main-body');
alert('Search by id nodeList length:' + nodeListByID.length);
nodeListByID.innerHTML('Content set after finding the element by ID');
});
</script>
</head>
<body>
<div style="">
</div>
</body>
</html>
Hope this helps
#Nikanos' answer covers the query issue, I would like to add, that any query returns an array of elements, in case of Dojo it is dojo/NodeList.
The problem is you are about to assign the same id to multiple DOM nodes, especially with query containing div:not([style]). I recommend to use more specific query like first div child of body:
var nodes = dojo.query('body > div:first-child');
nodes.attr("id", "main-body");
To make it more robust, do not manipulate all the nodes, just the first node (even through there should be just one):
dojo.query('body > div:first-child')[0].id = "main-body";
This work also in IE9, see it in action: http://jsfiddle.net/phusick/JN4cz/
The same example written in Modern Dojo: http://jsfiddle.net/phusick/BReda/