How can i access elements in a iframe of a cordova WKWebview ios app? - ios

I want to access elements of our website that is embedded in a iframe of our ios App.
It has the same problem as file access.
SecurityError: Blocked a frame with origin "file://" from accessing a cross origin frame...
The file access problem is solved through this plugin https://github.com/globules-io/cordova-plugin-ios-xhr.
But access in a iframe is not solved.
How can i access elements in a iframe of a cordova WKWebview ios app?

I've run into a similar issue in my Cordova apps with WkWebView. You'll need to get the iframe to run under the "same-origin" of your app. This is the only workaround I've found. It involves writing content directly to the iframe, rather than giving it a src="...". This way, iframe runs as same-origin as parent. (Anything loaded via src="file://..." is treated as unique-origin in WkWebView, so blocks any cross-frame JavaScript.)
function frameEl_injectHtml(frameEl, injectHtml) {
// frameEl must exist in DOM before its contentWindow is accessible.
if (!frameEl.contentWindow) { alert("frameInjectHtml() but frameEl not (yet or anymore) in DOM."); return; }
frameEl.contentWindow.document.open('text/htmlreplace');
frameEl.contentWindow.document.write(injectHtml);
frameEl.contentWindow.document.close();
}
// Create <frame>, insert into DOM, and inject content.
var frameHtml = "<html><head></head>" +
"<body style='background-color:#eee; color:#000;'>" +
"iframe body" +
"<script>window.parent.alert('iframe even same-origin as parent.');</script>" +
"</body></html>";
var frameEl = document.createElement('iframe');
frameEl.src = "about:blank";
document.body.appendChild(frameEl);
frameEl_injectHtml(frameEl, frameHtml);
You'll have to load the contents of the website pages somehow outside of this workaround, e.g. with an ajax call.

Related

How to get WebView URL in W10 Mobile (UWP) (Xamarin forms)

I'm developing an application for W10 Mobile (UWP) in Xamarin forms and I have implemented a WebView and I tried to get the URL of this but it is more complicated than I thought at first, I tried to get it through the source property, but not is possible, I would appreciate a help.
You could create an event handler to the navigation completed event.
With that you can check the URL
example:
WebView browser = new WebView();
browser.Navigated += OnNavigatedHandler;
public void OnNavigatedHandler (object sender, WebNavigatedEventArgs args){
Console.WriteLine ("Navigated to: " + args.Url);
}
I'm having trouble getting the URL of the browser in real time, the way you indicate I enter an infinite loop, I have a binding in my WebView on the SourceProperty in the view model called URL, when there is a change in the URL property I detect it thanks to PropertyChanged, the problem is that the event navigated only runs when updating the value of the URL property which causes the infinite loop to load the WebView infinitely. Is there any other way to get the URL?
I have uploaded in Pastebin the classes of the test project I am using:
View: pastebin.com/msyu9dJF
ViewModel: pastebin.com/LaCfC31c
BaseViewModel: pastebin.com/i6GCFbbe

Android webview jwplayer7 cannot read property 'jwplayer.volume' of null

I have an app that is using a webview to launch an html that loads JWP7 and throws an error Uncaught TypeError :cannot read property 'jwplayer.volume' of null
The same page is loading perfectly on mobile and desktop browsers.
I tried to add in the javascript of the html after the jwplayer.js is being called and before the setup, the following code:
if (typeof jwplayer.volume == "undefined" || typeof jwplayer.volume == null )
jwplayer.volume = 10;
I do see the new volume property using a desktop/mobile browser but it doesn't changes the TypeError in the webview, probably because the TypeError is thrown while running the jwplayer.js script, before it reaches my javascript check.
When i'm Using the JWP6 everything is working perfectly.
Any suggestions on how to fix it?
I inspected the jwplayer.js code.
And saw that it reads the last settings of Volume (jwplayer.volume) and Mute (jwplayer.mute) from the LocalStorage; instead of from cookie.
(Probably JWPlayer 6 was using cookies.)
So, you need to enable LocalStorage access in your WebView; like you do for JavaScript.
Sample code below.
WebView webView = (WebView) findViewById(R.id.webview);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true); // This will allow access
webView.setWebViewClient(new WebViewClient());
/* WebView.setWebContentsDebuggingEnabled(true); // This is to inspect your WebView from desktop Chrome. (>= API 19) You may not want to include this in production. */
webView.loadUrl(url);
JW Player doesn't support using the web player in Android or iOS webview; however, there are native mobile SDKs available to support in-app video: developer.jwplayer.com/android-sdk

Print styles overriding screen styles after AirPrint in iOS webview

I am working on a hybrid HTML5/iOS app that uses the Safari Webview. We are using AirPrint to allow the user print the contents of the webview. The problem I am having is that after the print dialog is opened, the print styles are taking affect on the screen, and even after printing is complete or canceled do not go away. This does not happen in our Windows or Android versions of the app, which use CEF and Android System Webview respectively. Print styles in those versions of the application are only applied to the print out, as expected.
Anyone have any experience using AirPrint with Safari Webview that could shed some light on a solution? I have considered just adding/removing the link tag containing the CSS with javascript before and after printing, but that feels hacky, and doesn't answer the curious question of why print styles are being applied to the screen.
Any help appreciated! Sorry there is no real way to attach code to this!
Yes, this is indeed a not expected behaviour. However, we can try to solve this using JavaScript.
Theory: When the print is done, let's reload the stylesheets. The browser will paint the page again and hopefully using screen definitions.
Practice: As we don't have a JavaScript callback after printing, you could try reload your stylesheets using the window.onfocus event, as follows:
function updateStylesheets(){
var links = document.getElementsByTagName("link");
for (var x in links) {
var link = links[x];
if (link.getAttribute("type").indexOf("css") > -1) {
link.href = link.href + "?id=" + new Date().getMilliseconds();
}
}
}
window.onfocus = updateStylesheets;
In detail, it grabs all <link> tags and appends a random number after, forcing a reload on the stylesheets.
Please let me know if that worked, I'd be glad to help.

IOS Memory buildup when changing IFRAME src with angular/Embedding youtube in cordova?

I'm afraid im having the same probem as this unasnwered question.
I have a blank IFRAME In my cordova ionic IOS App for embedded YouTube videos.
I change the NG-SRC="" of iframe by clicking Next Video. But upon testing it appears that the phone/cordova/webview is caching the old content of the iframes. I can only get through 20 videos or so before crashing out of memory.
I have tried using angular.element.remove() to remove the iframe as well as setting the iframe src to blank first, and neither seemed to affect how much memory is in use, per Xcode. I've also tried the cordova plugin ClearCache and that didnt clear any memory either.
Please help! Is there a better way to embed youtube in a cordova app?
I have spent weeks working on this all to have it crashing down around me (no pun intended)
My Video view is like:
<ion-view view-title="Random Video">
<iframe id="youtube" sandbox="allow-scripts allow-same-origin" ng-src="{{video.url | trustAsResourceUrl}}" frameborder="0" allowfullscreen></iframe>
<h4>{{video.title}}</h4>
<button ng-click="nextVideo()">
</ion-view>
My controller is like:
angular.module('starter.controllers')
.controller('VideoCtrl', function(VideoService) {
$scope.video = {};
$scope.nextVideo = function() {
$scope.video = null; //doesnt seem to help
//$scope.$destroy(); //doesn't help
//angular.element(document.querySelector( '#youtube' )).attr("src", " ");
//angular.element(document.querySelector( '#youtube' )).remove();
//neither of the above 2 remove any memory
VideoService.getVideo().then(function(response){
$scope.video = response.data;
});
}
$scope.nextVideo();
});
Note, when I load my app onto a website instead, and load in chrome, I can cycle through videos without seeing the memory usage go up (looking at taskmgr.exe at least)
It might seem like setting the iframe to an empty string should be enough, but for some browsers and some situations it isn't. It might be necessary to recursively delete event listeners and elements one by one. Maybe surprisingly, the recursive method (1) below is faster than just setting to an empty string (2):
1.Recursive
while (box.lastChild) {
box.removeChild(box.lastChild);
}
2. Setting empty string
myNode.innerHTML = '';
See https://stackoverflow.com/a/3955238/1158376 for reference.
Additionally, in the recursive approach, one might need to apply special treatment to some items, for example first remove event listeners, nullify functions (http://javascript.crockford.com/memory/leak.html), and use dedicated cleanup methods, like with jQuery (http://javascript.info/tutorial/memory-leaks).
Another strategy you could try is to load a new web page with a fresh iframe for every video you play. Loading a new page should enable the browser to release the previously claimed memory.

Returning values from Webview in BB10

Is it possible to return values from Webview in bb 10??
Example: If I load a Webview for online banking in my app and is there a way to get some data (like reference number of the payment) returning from the Webview to the app
At first you have to add a javascript in the html file that return document.documentElement.innerHTML;
After completely loading the webview call evaluateJavaScript (const QString &script, bb::cascades::JavaScriptWorld::Typeworld world) function, this will evaluate the javascript in the webview.
Lastly you should catch the sigal "javaScriptResult" from this signal you can get all the source of html file as qvariant.
For security sake, you cannot access the html content of the webview, except if you have set it yourself as a string.
You can access a redirection url, but without the Post parameter.

Resources