I'm trying to navigate within a webpage that has been loaded from a remote server in my WebView control (Cocoa application). I would like to navigate to a particular tag that i can see in the HTML code of that page. The purpose of this all is to show the part of the HTML page that is of my interest at the top of the WebView control.
I know that in HTML code you can navigate by using something like #MIDDLE, #TOP etc. However, is this possible to do from outside of the HTML code using the WebView API?
Thanks for your reply in advance!
I found the answer to my question with the help of an other question (How to scroll HTML page to given anchor using jQuery or Javascript?).
The piece of code below does the trick for me. It searches for HTML elements with attribute: class = "container" in the HTML data that is loaded in the WebView component self.webView.
-(void) scrollMyImportantHTMLPartInView
{
// Get a list of HTML elements that contain attribute class = "container" (eg. <div class "container">)
DOMNodeList *nodeList = [[[self.webView mainFrame] DOMDocument] getElementsByClassName: #"container"];
if( nodeList && nodeList.length >= 1 ) {
// get the first node (class = "container") from the list
DOMNode *domNode = [nodeList item:0];
// Make sure it's a DOM element type
if( domNode.nodeType == DOM_ELEMENT_NODE ) {
// It's now save to cast from DOMNode* to DOMElement*
DOMElement* domElement = (DOMElement*) domNode;
// Scroll begining of HTML node into view
[domElement scrollIntoView: YES];
}
}
}
Related
Context
I am building a React app (rails-react) where I have a parent component GameTracker that has some child components; namely, EquipmentPanel and PinnedPanels. I have added a pinned-panels-container div in the parent component where I want to move panels from the EquipmentPanel when I click on a 'pin' button.
<div id='container'>
<EquipmentPanel pinPanel={this.pinPanel}/>
<div id='tracker-contents'>
{this.state.pinnedPanels.length > 0 &&
<div id='pinned-panels-container'>
<h2>Pinned Panels</h2>
{this.state.pinnedPanels}
</div>}
</div>
</div>
Approach
The way I plan to do this is create a pinPanel() function in the parent component GameTracker, and pass it as a prop to its child, EquipmentPanel. The child then adds the button, and calls pinPanel(div), with div being the specific div/panel I want to pin.
pinPanel(panel) {
let newPanel = panel.current.cloneNode(true)
var parser = new DOMParser();
var htmlDoc = parser.parseFromString(newPanel.innerHTML, 'text/html');
newPanel = htmlDoc
let newPinnedPanels = this.state.pinnedPanels
newPinnedPanels.push(newPanel)
this.setState({
pinnedPanels: newPinnedPanels
})
}
Error
Now, whenever I pin a panel, React gives me:
Uncaught Error: Objects are not valid as a React child (found: [object HTMLDocument]).
If you meant to render a collection of children, use an array instead.
If I try to use an array, as the error message recommends, I get the same error. If I don't use DOMParser(), (which I found here), I get the same error, with the following difference: found: [object HTMLDivElement].
My question is, is there any way in React to clone a div with all its contents, pass it to another component through state, and render it in another component that is not its parent or child? I basically want to copy/paste a div.
Edit: If I try to assign it by .innerHTML, the end result is a panel with [object HTMLDocument] as a string inside.
Unsure if this is considered a proper answer, but I made it work with DOM manipulation. Feels hacky, but it works. If someone has any insight, it is of course welcome.
let newPanel = panel.current.cloneNode(true)
if (this.pinnedPanelsRef.current.innerHTML.includes(newPanel.children[0].innerHTML)) {
this.pinnedPanelsRef.current.innerHTML = this.pinnedPanelsRef.current.innerHTML.replace(newPanel.children[0].innerHTML, "")
}
else {
this.pinnedPanelsRef.current.innerHTML += newPanel.children[0].innerHTML
}
I still feel like there is a much more elegant solution that I am failing to reach.
On the html for my page I have a <script id="pagedata"></script> element which I would like to add an element to only if a certain partial is rendered. In my layout.cshtml I have the following:
#if (Brand != null)
{
#Html.Partial("_UseApp");
}
And in my _UseApp.cshtml:
#{
var iosAppUrl = // retrieve iosLink from our CRM database
var androidUrl = // retrieve android link from our CRM database
// Here I want to add the above variables to the <script id=pagedata> in the html page. Something
like this:
PageData.AddPageData("appstore", iosAppUrl);
PageData.AddPageData("playstore", androidUrl);
I cannot work out how to do this - I set breakpoints in the UseApp.cshtml file and the file is being called, but I don't know how to add these script elements. I don't want to just add them into the layout file because I want to keep the app logic separate. Can anyone help? Thanks
My approach to this would be to use jQuery, as reading HTML elements in C# is rather difficult.
In the script below, it checks if the HTML exists, and if it does, we will assign an attribute to it. The second argument in attr() will be your link, note that you can use C# to get the value from your Db, by using the model or ViewBag.
#section Scripts{
<script>
$(document).ready(function () { // on ready
if ($("#replaceWithYourId").length) { // check if ID exists
$("#pagedata").attr("data-playstore", "link") // use jQuery attr method.
}
});
</script>
}
I have an aspx page that inherits the IHttpHandler class.
On page load I issued a call to an Impersonation class in which it renders the content under a different username than that currently logged in. But the problem is when impersonated I call a function back on the code behind in the aspx page that needs to access a div tag in order to insert content to it via an object tag and it doesn't find the tag anymore. Any clue as to why? Or to how am I able to build tags from the code behind in such a situation?
The impersonation function I used is based off of : https://www.codeproject.com/Articles/107940/Back-to-Basic-ASP-NET-Runtime-Impersonation.aspx
And this is the function that is called when impersonated within my aspx page:
public void FUNCTION() //This is called from the impersonation function above
{
report = Session[Document];
string url = "http://localhost/PATH" + report.toString();
HtmlGenericControl objReport = new HtmlGenericControl();
objReport.TagName = "object";
objReport.Attributes.Add("data", url);
Control cntrl = Page.FindControl("objReportFrame");
if (cntrl != null)
cntrl.Controls.Add(objReport);
}
I am using a template tag in a webkit browser (JavaFX WebView 2.2) to store elements that I may clone and append on the main part of the document.
However, I can't access its content using templateElement.content (the HTML5 standard). Instead, I use jQuery to get the elements inside the template TAG with the selector "#templateElement div".
Seems the template tag is not yet fully supported (inner scripts also run), although its contents are not rendered.
My fear is that, when the template tag becomes supported, the way to get its contents will break and my page will stop working.
What is the recommended way of getting template contents regardless future implementation changes?
HTML:
<template id="templateElement">
<div>Clone Me!</div>
</template>
JavaScript:
function getContentsCurrent() {
var toBeCloned = $("#templateElement div")[0];
//append where needed...
}
function getContentsFuture() {
var toBeCloned = templateElement.content.getElementsByTagName("div")[0];
//append where needed...
}
EDIT
I think jQuery won't be able to handle this automatically, even in the future, because the template "innerHTML" is purposely routed to content so that it becomes inaccessible to the DOM (so no selector touches it accidentally).
You could test if the content feature exists before:
function getContents() {
var toBeCloned;
if ( templateElement.content )
toBeCloned = templateElement.content.getElementsByTagName("div")[0];
else
toBeCloned = templateElement.querySelector("div");
//append where needed...
}
Another way:
var content = templateElement.content || templateElement
var toBeCloned = content.querySelector( "div" )
//...
I have a question about window's 8 apps Webview Control , is there anyway to use css to manage the look of the webview , i'm using it here to view a returned contents of a feeded html data but as you can see it's striped from all the CSS , so is there anyway that I can manage the CSS for the Webview ?
UPATED : This is the code
void ItemListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// this code to populate the web view
// with the content of the selected blog post.
// I'm passing the selected item from the previous items' page
// and then pouplate the web view with the selected item Contents of the feed
if (this.UsingLogicalPageNavigation()) this.InvalidateVisualState();
Selector list = sender as Selector;
FeedItem selectedItem = list.SelectedItem as FeedItem;
if (selectedItem != null)
{
this.contentView.NavigateToString(selectedItem.Contents);
}
else
{
this.contentView.NavigateToString("");
}
}
If you navigate with NavigateToString() - you can put your css inside of the html string that you navigate to. Otherwise - it should just work and we would need more details for what you are actually doing.