Error on UIWebView with jQuery - javascript

I'm building an ePub reader and I'm loading the html files of every chapter on an UIWebView. When user reaches the end of a chapter, I load on the same webView the next chapter. As I need to execute some jQuery functions in order to create highlights, notes and many extra content, I'm also injecting the jQuery library to the viewer. This is the code I'm using:
- (void)loadBook{
...
[self.bookWebView loadRequest:[NSURLRequest requestWithURL:chapterURL]];
NSString *jQuery = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"jquery" ofType:#"js"] encoding:NSUTF8StringEncoding error:nil];
[self.bookWebView stringByEvaluatingJavaScriptFromString:jQuery];
}
When it loads the first chapter, when webViewDidFinishLoad: is called, $(document).readyfunction is called and all my jQuery code works perfectly. When I switch to the following chapter, the loadBook function is called again with the new URL but this time $(document).ready is not called so when I try to call any of my functions I get the following error: ReferenceError: Can't find variable: $
Why it is not loading jQuery library after my first call?

I ran into this today and Apple's documentation was to no avail. In my case, I was loading from local HTML, JS, and CSS files--NOT from a remote web address. So, this might not do it for you, but it does work for local files.
The following is a workaround. The code is in Swift.
Method:
In your UIWebViewDelegate, create an Int variable that will be incremented when your data is loaded.
Increment it by 1 each time that you load your data (or post the request)
In shouldStartLoadWithRequest, check whether the navigation type is "Other" or not: if it is and the counter variable is greater than 1, return false (NO in Objective-C).
This works because the view is instantiated each time it is presented, so the counter is reset to 0.
Code:
class MyView: ..., UIWebViewDelegate {
var theCounter = 0
...
func myFunctionWhereILoadTheData() {
... load the data (the code in your question)
theCounter += 1
}
...
func webView(webView: UIWebView!, shouldStartLoadWithRequest
request: NSURLRequest!, navigationType: UIWebViewNavigationType) -> Bool {
switch navigationType {
...
.Other:
if theCounter > 1: return false
}
}

Related

What are these Google-calendar events from?

It seems it's fairly common practice to grab the contents of a Google-calendar embed code, and add a stylesheet into it (either manually or through something like a PHP script) and display a custom-styled public calendar.
The odd thing is, I noticed if you click the print button at the top, or the "Google Calendar" in the lower right, it goes to localhost or whatever domain the page is - not the Google calendar.
If you try to trace the "gcal$func$[3]();" onclick through the Chrome devtools, or through Firefox with gcal$func$[3].toSource(); it will not find it or say
"function () {
[native code]
}"
So where is this function coming from, and how can you tweak this to make it open in a new window with the Google url, not the current domain (404)?
According to the Google Calendar embed JS code, the function points to the following code
window.open(Pf(this.c.i.Nb + "/render", "cid", b))
this.c.i.Nb represents the base URL, which is by default the domain where the script runs (in your case that's your domain). However, it's intended to be google.com domain and fortunately, it's very easy to change that. baseURL is one of the parameters in the initialization script (declared in the page you're grabbing) and you just need to configure that to https://www.google.com.
If you use PHP, your code might look like this.
$page = new DOMDocument("1.0", "utf-8");
// grab the Google Calendar code
$page->loadHTMLfile("https://www.google.com/calendar/embed?src=yourcalendar%40gmail.com");
// set up the baseUrl and print the grabbed page
echo str_replace('"baseUrl":"/"', '"baseUrl":"https://www.google.com/"', $page->saveHTML());
Now all the links should work correctly.

javascript and loadUrl error

i know that to run a javascript function in webview we need to load it in loadUrl(). In my program everything works fine javascript gets called when i use it in loadUrl, but instead of running javascript on the same page, loadUrl("javascript:function()") vanishes my previous page and run this javascript "function()" in a totally new blank page..
for eg. i tried to fill a form automatically using command:
view.loadUrl("javascript:document.getElementById('password').value = 'my_passoword'");
what happens is, the page which consists of ID-'password' vanishes and a new blank page generates consisting of 'my_password' only
where is the problem?
Using loadUrl to run javascript loads different page
anonymous self-invoking function works fine.. i.e.
view.loadUrl("javascript:(function(){document.getElementById('password').value = 'sb14november';})()");
and as a loop around i think Bojan Kseneman answer will work too..
thanks to all!! :)
EDIT: This library is only for evaluating JavaScript and it created a new WebView instead of using an existing one :/
You can also try js evaluator library
jsEvaluator.evaluate("put your JavaScript code", new JsCallback() {
#Override
public void onResult(final String result) {
// you get the result here (optional)
}
});

When does UIWebView start recognising Javascript code

// MARK: - UIWebViewDelegate
func webViewDidFinishLoad(webView: UIWebView) {
let initResponse = self.stringByEvaluatingJavaScriptFromString("initialize('','','',\(isPreview))")
if (initResponse != "") {
isLoaded = true
}
println("\(viewType) initResponse \(initResponse)")
}
In my program, I am attempting to initialise UIWebView by calling a Javascript function. UIWebView is loaded with a local template file.
Apparently, the webview still does not respond to my javascript command even though webViewDidFinishLoad is called.
Therefore, I think there is another moment when web view can actually start accept Javascript calls. In my opinion, it is when document is ready for my locally loaded html file.
But then, how do I know when my UIWebview is ready to receive Javascript code?
For iOS/UIWebView, please have a try on this
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
if (![[webView stringByEvaluatingJavaScriptFromString:#"document.readyState"] isEqualToString:#"complete"])
return;
// Now it's ready
}
and for OS X, this one webView:didFinishLoadForFrame: is what you want.

webViewDidFinishLoad not calling when having javascript content in webpage

I'm using UIWebView in a project. Sometimes it doesn't call the webViewDidFinishLoad method. Because the web page have some javascripts. The method
- (BOOL) webView: (UIWebView *) webView shouldStartLoadWithRequest: (NSURLRequest *) request navigationType: (UIWebViewNavigationType) navigationType
is getting call but webViewDidFinishLoad doesn't. I want to catch that method. Because I'm start an animation when the webview start loading. Then I want to stop this animation when it finished. It's not working with websites having javascript content. Any one have an idea please?
Thanks
webViewDidFinishLoad method gets called when the UIWebView has finished loading the url, in your case since you are calling a javascript, it doesn't load your content, it just calls a javascript function in your already loaded webview. But YES you can catch the javascript actions in the same method you stated as below
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
NSString *url = [[request URL] absoluteString];
if(navigationType == UIWebViewNavigationTypeLinkClicked){
if([url rangeOfString:#"SOMETHING"].length > 0 ){
//if your action returns something appended in your url like the anchors work
//DO YOUR STUFFS
}
}
return TRUE;
}
apparently, the webview in ios checks specifically for "iframe" tags in the html's dom and in case it finds, it creates events based on that tag as well. therefore, a simple however a patchy solution would be adding the following code in the part of the dom that is changing (for example, in the actual template of each section):
<iframe></iframe>
did the trick for me..

Getting content out of WebView In a unit test Android, using java script

I have been able to get content out of WebView using javascript and loadUrl() method having specified an interface thats called from javascript string that is injected into WebView.The problem is that this only works for me when the loadUrl() method is present in onPageFinished() method in the WebView client. What I want to do is I want to get the content out of the WebView (with the content already loaded). The WebView is in an activity instrumentation test case and I can for instance use findAll() method and that works fine. For some reason I can not use loadUrl() and get the desired behaviour (which is injecting javascript and getting content out of the WebView with a help of an interface).
PLease help.
Thanks
Pawel
EDIT:
Just adding code to show what I am doing exactly:
Yes I understand that but my problem is that I am trying to do it within a test case this way:
public void testWebView() throws Exception {
solo.sleep(3000); // wait for views to load on the screen
WebView a=null;
ArrayList<View> views = solo.getCurrentViews(); // I am using solo object to get views for the screen currently loaded
for(View s:views)
{
if (s instanceof WebView)
{
a = (WebView)s; // this is where I get my WebView
}
}
Instrumentation inst = getInstrumentation();
inst.runOnMainSync(new Runnable()
{
public void run()
{
int d =a.findAll("something"); // this method runs fine on the object and i get the desired result
WebSettings settings = a.getSettings();
settings.setJavaScriptEnabled(true);
a.loadUrl("javascript:document.location = document.getElementById('google').getAttribute('href')"); // this javascript is never executed and that is my problem
}
});
}
You can inject javascript in a loaded page much the same way you can do it in desktop browsers - via inline javascript entered into navigation bar.
Bind some Java object so that it can be called from Javascript with WebView:
addJavascriptInterface(javaObjectExposed, "JSname")
Force execute javascript within an existing page by
WebView.loadUrl("javascript:window.JSname.passData("some data from page");");

Categories

Resources