Open PDF in the PhoneGap App that is made in HTML and CSS - css

I have a strange problem with my iPad App in Phone Gap. The problem is that I have to open PDF document in my app through links and when I click the link which opens the PDF, it shows me the PDF document with no back link.
Hence, when I open the PDF document in my app through a link, it takes me to a dead end and there is no way I can go back to the main page of my app.
My question is that how can I have a Top-Bar, when I open a PDF which could take me back to my home page? Any internal element for the iPad may be?
Thanks a lot.

Try using the In App Browser plugin.
If you're using a later Phonegap / Cordova version (2.8.0, 2.9.0 etc) it should come with it - nothing else to install.
http://docs.phonegap.com/en/2.9.0/cordova_inappbrowser_inappbrowser.md.html#InAppBrowser
It will allow you to open the PDF in the a new 'window' that overlays your app. It has a 'Done' button that users can use to close it and return to your app when they are finished.
You would open the PDF using the In-App Browser, using something like this:
window.open('http://whitelisted-url.com/pdftoopen.pdf', '_blank');
I.e. the _blank option triggers the In-App Browser plugin. If you were to use _system instead it might open it in iBooks (just guessing there - not 100% sure if it would use iBooks).

Try prefixing https://docs.google.com/viewer?url= in the URL
like, window.open('https://docs.google.com/viewer?url=http://www.example.com/example.pdf&embedded=true', '_blank', 'location=yes');

Try this to open any kind of documents from URL using following steps:
install this plugin : cordova plugin add https://github.com/ti8m/DocumentHandler
use this code :
handleDocumentWithURL(function() { console.log('success'); }, function(error) { console.log('failure'); if (error == 53) { console.log('No app that handles this file type.'); } }, 'http://www.example.com/path/to/document.pdf');
It works for me both on Android and IOS. I used it for open images and PDF files.
Android : It opens files using system apps if available, otherwise it give an error, which you can handle.
IOS : It opens files in popup like view with Done button and Option button.
It doesn't show your docs URL.
Source is available here : https://github.com/ti8m/DocumentHandler

Thanks asgeo1,
I solved it by using window.open().
<img src="images/samplens.jpg" border="0" />
Hope it helps.

I've ended up using WebIntent
as described here. The tricky part was to modify WebIntent.java to properly identify file type:
String type = obj.has("type") ? obj.getString("type") : null;
// New code starts
Uri uri = obj.has("url") ? Uri.parse(obj.getString("url")) : null;
String extension = MimeTypeMap.getFileExtensionFromUrl(obj.getString("url"));
if(extension != null){
MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
type = mimeTypeMap.getMimeTypeFromExtension(extension);
}
// New code ends
JSONObject extras = obj.has("extras") ? obj.getJSONObject("extras") : null;

Related

gLightBox tries to open a Vimeo video instead of an image

I'm using gLightBox on my website here and everytime I click on an image, the pop-up attempts to convert the image into a Vimeo iframe embed which is not expected behavior.
When I look at it from my local machine, it works fine and looks like this:
However, when I look at it from my live site, it looks like this:
If you go to inspect the markup, you'll see that the lightbox is attempting to load a Vimeo video, but it should really just load the image.
I am hosting this server on GoDaddy.
Would anyone know how to fix this problem?
Thank you!
In your webpage, the img src has '?' sign after the 'jpg' extension which caused glightbox failed to recognize the filename type as image.
So, in the glightbox.js remove the '$' sign in the match function:
if (url.match(/\.(jpeg|jpg|jpe|gif|png|apn|webp|svg)$/) !== null) {
return 'image';
}
that is:
if (url.match(/\.(jpeg|jpg|jpe|gif|png|apn|webp|svg)/) !== null) {

Provide WebView with Url to Asset

In my Uno UWP project, I can view an html Asset file (w/ Content BuildAction), stored in my shared project, using the following:
var myAssetUri = new Uri("ms-appx-web:///Assets/Html/index.html");
myWebView.Navigate(myAssetUri);
However, this does not work with Android or WASM (not yet tried on other platforms). On WASM, I get a blank page. On Android, I get a page with the message:
The webpage at ms-appx-web:///Assets/Html/index.html could not be loaded because:
net::ERR_UNKNOWN_URL_SCHEME
When I look at the package folders for both platforms, I do find my html file:
WASM: bin/Debug/netstardard2.0/dist/package_.../Assets/Html/index.html
Android: (unziping my app's apk) assets/Html/index.html
so, I am guessing I'm not doing something right ... but I don't know what that might be.
The cause is simple: WebView not implemented yet on Wasm nor Skia.
This is the solution after hours investing!!
For you proyect write this line:
var myAssetUri = new Uri("file:///android_asset/Assets/Assets/Html/index.html");
This work 100%

fastest way to get all links and images from a webpage?

So this isn't relly a problem but more like automate thingy...
I built a website and had to copy loads of content from previous webpage. I did that by copy-pasting the content from old page to the new page made with wordpress.
All link and images in the content still point to the old page. So I'd like to find something like a webscraping tools which would analyze list of selected links and then output would be all link pointing outside of my webpage and list of all images that I have to download
Considering that your old and new websites are going to have the same URL structure, here is a bookmarklet that you can save as a bookmark to your toolbar.
To make your job easy, open an old website page, and simply click on the bookmarklet button you've saved (code below). This code will replace the links from old website to new website. The images will be treated similarly. Next, you can copy the updated content and paste it into the editor of your new website (wordpress admin).
On the developer's console (F12 key), you will get a list of all the images that you have to download.
javascript:(function(){
var jqscript = document.createElement('script');
jqscript.onload = function() {
// treat the <a> tags
jQuery('#my-content-container').find('a[href^="http://my-old-website.com"]').each(function(i, anchor) {
jQuery(anchor).attr('href', jQuery(anchor).attr('href').replace('http://my-old-website.com', 'http://my-new-website.com/new-directory'));
});
// treat the <img> tags, and make a list of images to download
var images_to_download = [];
jQuery('#my-content-container').find('img').each(function(i, image) {
images_to_download.push(jQuery(image).attr('src'));
jQuery(image).attr('src', jQuery(image).attr('src').replace('http://my-old-website.com', 'http://my-new-website.com/new-directory'));
});
// output a list of images to the developer console
console.log(images_to_download);
};
jqscript.src = "//ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js";
}());
P.S. To save this bookmarklet code, rightclick the toolbar of your browser and create a new bookmark, and enter the above code as the Location/URL.
This is just an option you should think about: You could use absolute path instead of Relative path, this will help you reuse code without to have to remap every link in it.
Relatif Path :
Read about my Tahiti vacation.
Absolute path :
Read about my Tahiti vacation.

Ionic: External link in iframe opens in webview (embed youtube player)

In my ionic (v1.2.4) app there is an embedded youtube player with a link "watch on youtube". If a user clicks this link, youtube website is opened in web view of cordova. It destroys current state of my app. I want to open that link in system's web browser (cordova in app browser plugin).
Same with any link in any iframe (vimeo, soundcloud...)
This link can't be modified with JS from outside the iframe, because cross domain security issues. So i can't update target attribute from _blank to _system.
Show a dialog onbeforeunload is not really an option because it looks ugly :)
Is there a possibility to avoid a page being loaded into the same webview or in the system's web browser?
Breaking links by using iframe's sandbox attribute is not an option because it breaks youtube player completely.
Thanks and cheers
ps: i asked this question here but couldn't get any helpful information
Thanks thepio for the hint with allow-intent and allow-navigation. First time i really digged into cordova-whitelist-plugin. Finally i fixed my issue on android by setting the correct allow attributes in config.xml
<!-- Allow links to web pages to open in a browser -->
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
No allow-navigation for android. Perfect white label solution. Couldn't find out how to do this on iOS, because iOS needs allow-navigation attributes to load iframe content at all.
To fix my issues on iOS in a dirty way, i added this to my config.xml:
<platform name="ios">
<allow-navigation href="https://w.soundcloud.com/player/*"/>
<allow-navigation href="https://www.youtube.com/embed/*"/>
<allow-navigation href="https://player.vimeo.com/video/*"/>
</platform>
Now only the iframe content itself is loaded. Lucky me, every link (watch on YouTube, share, like on vimeo...) inside the iframe is pointing to another domain/subdomain so it is blocked on iOS.
If there are any suggestions, how to create a white label solution for iOS, i am all ears.
Thanks
Ok, this is kind of a hardcore solutions for this and should probably be re-written/coded. This solution uses a cordova hook and opens ALL links with http or https protocol to a native web browser when they are clicked from a a-tag. For example <a href="https://www.youtube.com/embed">. This does not only affect iframes but all links.
Be careful since this might affect some unwanted links in your app.
I'm running
Cordova 6.1.1
Cordova-ios 4.1.1
Cordova-android 5.1.1
First of all you need to create a hook in the hooks/after_platform_add folder. This will run the hook only when you use ionic platform add <platform> or cordova platform add <platform>. If you do not have a folder called after_platform_add just create one. Then create a file "01_ios_external_links_hook.js".
Also please read Cordova hooks documentation:
https://cordova.apache.org/docs/en/latest/guide/appdev/hooks/
There are several ways of defining hooks and creating folders for them seems to be deprecated so you should use the config.xml to attach hooks.
https://cordova.apache.org/docs/en/latest/guide/appdev/hooks/index.html#via-hooks-directory-deprecated
You can call your file anything and if you are doing it with folders just remember to add access rights to the file. Typically in terminal:
chmod +x project/hooks/after_platform_add/01_ios_external_links_hook.js.
Please note that this fix is intended only for iOS devices since on android you can handle this with setting <allow-intent href="http://*/*" /> and setting <access origin="*" />. But on the latest Cordova-ios and whitelist-plugin you need to set <allow-navigation href="*.youtube.com" /> or similar to allow the content of iframe to load on iOS. This will lead to a situation which you described which is that external urls from the iframe will open in the webview.
But back to the solution. This is the code which I have inside the 01_ios_external_links.js file:
#!/usr/bin/env node
var fs = require('fs');
var replace = require('replace');
if (fs.existsSync('platforms/ios/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewDelegate.m')) {
console.log('platforms/ios/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewDelegate.m - FOUND: fixing');
replace({
regex: /.*BOOL shouldLoad = YES;*./g,
replacement: 'BOOL shouldLoad = YES; NSURL * requesturl = [request URL]; NSString * url = [[request URL]absoluteString]; NSString * documenturl = [[request mainDocumentURL]absoluteString]; if ((navigationType == UIWebViewNavigationTypeLinkClicked && ([[requesturl scheme] isEqualToString:#"http"] || [[requesturl scheme] isEqualToString:#"https"])) || (([url isEqualToString:documenturl]) && ([[requesturl scheme] isEqualToString:#"http"] || [[requesturl scheme] isEqualToString:#"https"]))) { [[UIApplication sharedApplication] openURL:requesturl]; return NO;}',
paths: ['platforms/ios/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewDelegate.m'],
recursive: true,
silent: true,
});
} else {
console.log('platforms/ios/CordovaLib/Classes/Private/Plugins/CDVUIWebViewEngine/CDVUIWebViewDelegate.m - NOT FOUND');
}
Please note that this is a risky operation to be done, but I had no other means of dealing with this problem at the time. The above code searches if there is a file called CDVUIWebViewDelegate.m in the path given and then tries to find a piece of code in there and replace it with another piece of code. But in a nutshell the code above will modify the platform specific code for iOS in the CDVUIWebViewDelegate and add a if statement of the following kind to this file:
NSURL * requesturl = [request URL];
NSString * url = [[request URL]absoluteString]; // URL that was requested
NSString * documenturl = [[request mainDocumentURL]absoluteString]; // Main document URL
if ((navigationType == UIWebViewNavigationTypeLinkClicked && ([[requesturl scheme] isEqualToString:#"http"] || [[requesturl scheme] isEqualToString:#"https"])) || (([url isEqualToString:documenturl]) && ([[requesturl scheme] isEqualToString:#"http"] || [[requesturl scheme] isEqualToString:#"https"]))) {
[[UIApplication sharedApplication] openURL:requesturl]; // forward to application router
return NO;
}
Consider that I'm not a objective-c coder and this is all new to myself also and I made this solution because I did not find any other solutions to my problem which worked. The above if statement could and should be modified to your needs. I have only used this code on development environment and will need to investigate further and improve this method before implementing it to a production environment.
Remember that you need to remove and add the platform for this to take effect. This only occurs when adding a platform as stated above.
But that is it. Now your iOS application will open all urls in a native browser. Hopefully this helps you in the right direction for finding a (better?) solution to this problem.
I also faced the same problem and was able to solve with the following code.
$('iframe#youtube').get(0).contentWindow.open = function (url) {
cordova.InAppBrowser.open(url, "_system");
};
This code works only on iOS.

Phonegap: InAppBrowser insertCSS file

I'm trying to create an app that loads a website and then adds some custom CSS to adjust it to a mobile device.
I'm using window.open to load the page successfully, and I have a callback on loadstop where I'm calling browser.insertCSS, this is where the problem is.
If I do something like this:
browser.insertCSS({code:"body{background-color:red;}");
The style is applied correctly. However if I do this:
browser.insertCSS({file:"mobile-style.css");
And add the same CSS to the file, it doesn't get loaded
I have tried different paths (putting the file in the www folder, in the css folder, in the same folder as the JS file, and referencing it with "./mobile-style.css", "mobile-style.css", "/www/mobile-style.css", "/mobile-style.css" but none of them seem to load the file correctly.
I saw another post What should file paths fed to insertCSS() be relative to? where this same question was asked, but there is no accepted answer (I have tried the suggestion there and it doesn't work).
Any help would be greatly appreciated.
Thanks
Will
you have to wait until your inAppBrowser page loading finishes.
You must add an event listener:
var inApp = window.open('mypage.html', '_blank', 'location=no');
inApp.addEventListener('loadstop', function(){
inApp.insertCSS({
file: 'inAppStyle.css'
},onSuccess);
});
EDITED
Use this path for your android projects file:///android_asset/{your folder}
INFO: https://github.com/apache/cordova-plugin-file/blob/master/doc/index.md#android-file-system-layout
I couldn't find the right local path. Instead, I just uploaded the css file to the web and provided a regular URL
file: 'http://mywebsite.com/path-if-needed/my.css'
Not ideal to have an external dependency, but not a big deal since InAppBrowser itself requires internet access.
I probably know why it won't work, it is because your path isn't right, this css file should not put in www folder, neither the cordova project folder, u should put it into the server, for example, if ur browser is to visit http://192.168.1.1/admin, then the cordova only fetch this file when the browser is under the 192.168.1.1/admin, it fetch the file under the server directory.I don't know if u use any debug tool , if u use one, it's easy to find out what went wrong, ur console will log the error which path it fetch the css file and didn't get it.
If you want to add an external CSS file stored locally in the APP's sandbox and not around in the Internet, this is the only way, that is, you get the external file, you store it into a string variable, and then you insert such code into the Browser.
var inAppBrowserRef = cordova.InAppBrowser.open(url, "_blank", "location=no");
//when load stops call loadedCallbackFunction
inAppBrowserRef.addEventListener('loadstop', loadedCallbackFunction);
function loadedCallbackFunction() {
console.log("InAppBrowser Window loaded");
$.ajax({
type: "GET",
url: cordova.file.applicationDirectory + "www/css/myExternalCSS.css",
dataType: "text",
success: function (CSScode) {
inAppBrowserRef.insertCSS(
{ code: JScode},
function(){
console.log("CSS code Inserted Succesfully into inApp Browser Window");
});
},
error: function () {
console.error("Ajax Error");
}
});
}
You need the cordova-plugin-inappbrowser

Resources