Is it possible to open a link like this to be opened in Safari by only changing the contents of the HTML file only?
My WebView loads a local HTML page with this source:
Link to Fanpage
How do I make it so that it opens in Safari? By default it should also open in Facebook app if it was downloaded?
It's annoying that it opens the Facebook page on the same webview and the user won't be able to go back to the previous webpage.
Would I have to face a new approach? Thank you.
I looked at other solutions but I don't know what it means by adding a delegate to the webview?
I think you are trying to get get back-history working with anchors on iOS? I have been dealing with the same issue.
Thanks to inspiration from http://www.bennadel.com/, created the following angular directive that fixes this back-history issue. Basically it overrides the default html anchor behavior.
.directive('anchorOpenInNewWin',function() {
return {
restrict : 'A',
link : function($scope,$element,$attrs) {
$element.bind('click touchstart',function(e) {
e.preventDefault();
e.stopPropagation();
location.href = $attrs.href;
});
}
}
});
<a anchor-open-in-new-win href="http://www.google.com" target="_blank">google</a>
This solution could be easily translated into jquery or whatever you are using. Hope this helps
Related
I have a Firefox OS app where I want a link to open outside of the application (the link is to a different site, and opening it in-application would make the application unusable without a force-quite). How do I do that?
Related bug report
If you don't want to change all the links in the application, you can use WebActivities, e.g. like this:
/*
* Open all external links in the browser
*/
$('a[href^=http]').click(function(e){
e.preventDefault();
var activity = new MozActivity({
name: "view",
data: {
type: "url",
url: $(this).attr("href")
}
});
});
Use target="_blank" on the <a> tag:
<a href='http://different.site/' target='_blank'>Different site</a>
Actually, if you send an app with external links without it to the Marketplace, it should be rejected. so watch out :)
It seems like the externally_connectable feature that allows a website to communicate with an extension is still in the dev channel and not yet stable. Are there any other ways to allow a specific website to communicate with my extension, while I wait for this feature to become stable? How have chrome extension developers traditionally done it?
Thanks Rob W for pointing me in the direction of HTML5 messaging. For the benefit of other chrome extension developers, I'm writing about the general problem I was trying to solve and the solution that worked in the end.
I am making a chrome extension that can control music playback on a tab via a popup player. When a user clicks on play/pause/etc on the popup player, the extension should be able to convey that message to the webpage and get back a response stating whether the action was accomplished.
My first approach was to inject a content script into the music player page. The problem is, though, that content scripts operate in a "sandbox" and cannot access native javascript on the page. Therefore, the content script was pretty useless (on its own), because while it could receive commands from the extension, it could not effect any change on the webpage itself.
One thing that worked in my favor was that the website where the music was playing belongs to me, so I could put whatever javascript I wanted there and have it be served from the server. That's exactly what I used to my advantage: I created another javascript file that would reside on the website and communicate with the content script mentioned above, via the window object of the page (i.e. HTML5 messaging). This only works because the content script and the javascript file both exist in the same webpage and can share the window object of the page. Thanks Rob W for pointing me to this capability. Here is an example of how the javascript file on the page can initiate a connection with the content script via the window object:
content_script.js (injected by extension into xyz.com):
window.addEventListener("message", function(event) {
if(event.data.secret_key &&
(event.data.secret_key === "my_secret_key") &&
event.data.source === "page"){
if(event.data.type){
switch(event.data.type) {
case 'init':
console.log("received connection request from page");
window.postMessage({source: "content_script", type: 'init',
secret_key: "my_secret_key"}, "*");
break;
}
}
}
}, false);
onpage.js (resides on server and served along with xyz.com):
window.postMessage({source: "page", type: 'init',
secret_key: "my_secret_key"}, "*");
window.addEventListener("message", function(event) {
if(event.data.secret_key &&
(event.data.secret_key === "my_secret_key") &&
event.data.source === "content_script"){
if(event.data.type){
switch(event.data.type) {
case 'init':
console.log("connection established");
break;
}
}
}
}, false);
I check the secret key just to make sure that the message originates from where I expect it to.
That's it! If anything is unclear, or if you have any questions, feel free to follow up!
You could have an extension inject a content script alongside a web page, and use that to pass messages back and forth between the website and the background page of the extension.
It's tedious, though, and externally connectable is a lot nicer.
(Cross posted here)
Hi,
I have a sandboxed page (specified in my manifest) which is loaded into an iframe in my extension's background page. From within my sandboxed page, I'd like to open a new window and write to it, i.e.:
var win = window.open(); win.document.write('<p>Hello!</p>');
This works from my extension's background page and from regular web pages, but when invoked from either content scripts or my sandboxed page, the window opens, but I cannot access the win object (it's defined, but empty---console.log outputs "Window {}").
I assume this is due to same-origin policies (with every window being given a uinque-origin within the sandboxed environment). However, since the window opens an about:blank page, I'm confused why this would matter.
Is this a feature? Is there a parameter I can add to my manifest to avoid this? And does anyone know of work-arounds that don't involve using postMessage back to my background page? My ideal solution is to have my sandboxed script open a new window and interact with it directly, not with message passing.
I can provide a full example if necessary, but I'm hoping someone might just know off the top of their head. I'm running Chrome 24.0.1312.57 on Mac and 24.0.1312.68 on Ubuntu if that helps.
Thanks,
Hank
Content scripts, by definition, are part of external regular web pages you load so I'm not really sure how your script could work on a "regular web page" but not the content script. Do you mean the code works when you embed it in your own pages, but not in other pages via the content script?
Regardless, if the script is working properly from your background page, you could always try messaging. (more here: http://developer.chrome.com/extensions/messaging.html)
Script for your sandbox/contentscript:
//send message to background page
chrome.extension.sendMessage({todo: "newWindow"});
In background page:
//create a listener
chrome.extension.onMessage.addListener(
function(request, sender) {
if (request.todo === "newWindow") {
//do your stuff here
var win = window.open(); win.document.write('<p>Hello!</p>');
}
});
Per the cross-post here, the issue is indeed that the opened window is given a unique origin. This was intentional as the members of the standards working group (SWG) felt that it would be more secure to not make an exception for about:blank pages where they inherit the sandbox's origin.
However, to get around this issue, at least for my purposes, I can use the following method. First, forget sandboxing. This workaround uses an iframe embedded in a background page with the src url set to data:text/html,.... This gives a unique origin to the iframe so it's no longer in extension space. That means eval can be used and chrome apis cannot be accessed. Unlike in a sandbox, windows opened from the iframe share that same origin as the iframe, allowing created windows to be accessed. For example:
In a background html page:
<html>
<head>
...
<script src="background.js"></script>
...
</head>
<body>
...
<iframe id="myframe"></iframe>
...
</body>
</html>
In background.js:
...
document.getElementById('myframe').setAttribute('src', 'data:text/html,'+
encodeURI('<html><head>'+
'<script src='+chrome.extension.getURL('jquery.js')+'></script>'+
'<script src='+chrome.extension.getURL('myscript.js')+'></script>'+
...
'</head><body></body></html>'
));
...
In myscript.js
jQuery(document).ready(function(){
...
// To receive messages from background.js.
window.addEventListener('message', function(e){ ... } );
// To send messages to background.js.
parent.postMessage({...}, '*');
// To open AND ACCESS a window.
var win = window.open();
win.document.write('Hello'); // Fails in sandbox, works here.
// Eval code, if you want. Can't do this from an extension
// page loaded normally unless you allow eval in your manifest.
// Here, it's okay!
eval( 'var x = window.open(); x.document.write("Hi!")' );
// No chrome apis.
chrome.log( chrome.extension ); // -> undefined
chrome.log( chrome.windows ); // -> undefined
// No direct access to background page (e.g., parent).
chrome.log( parent ); // -> Window with no properties.
...
});
In my jQuery Mobile App, I have a mailto link, its href attribute is dynamically generated and it is 'clicked' via jQuery.Here is the link code:
<a id="mealLink" href="mailto:123#123.com" style="display: none;">This is the mailto
link</a>
A click handler is attached to it like this:
$('#mailLink').bind('click', function() {
window.location.href = $(this).attr('href');
});
Lastly,a function creates the href attribute for the link with emailaddress, subject and message body and click is simulated via jQuery:
$emailAddress= ..
$subject= ....
$body=...
$emailString="mailto:"+$emailAddress+$subject+$body;
$emailLink= $("#mealMail");
$emailLink.attr("href",$emailString);
$emailLink.click();
Now, this code is working perfectly in:
Mozilla desktop
Safari desktop
Android
But not working in:
Safari Mobile
Chrome desktop
Any suggestions?
After searching for complex solutions, I found a much easier solution by chance. The issue here is that if a mailto link is directly clicked, it works in all browsers, but if it is indirectly clicked, such as via jQuery .click() function, it does not work in all browsers. Therefore, here is my implementation:
This is a mail to link
$emailAddress= ..
$subject= ....
$body=...
$emailString="mailto:"+$emailAddress+$subject+$body;
$emailLink= $("#emailLink");
$emailLink.attr("href",$emailString);
Now, depending upon the context of an application, the href parameter of the link can be setup and when this link is clicked, it works. I have tested in following browers:
Mozilla Firefox Desktop
Safari Desktop
Chrome Desktop
Safari mobile on ipad 1
You should not use mailto:
Check if is not better to create a simple "Contact us" form.
But still, take a look at this: i-cant-get-mailto-links-to-open-the-mail-app-from-mobile-safari-when-using-jqto
i wonder if and how it is possible to open a website inside a panel or in an external browser window of the mobile safari! I tried to open a website inside a panel but due to crossdomain problems only the htm without the css was loaded.
any ideas?
thnx!
edit: let's say, we use phoneGap
As far as I know, cross-domain issues do block you from IFRAME solutions for displaying external links inside your app.
Best solution currently is to have links include target="_blank" to force a new browser window to open.
#Stevanicus #Dalar It does open a new window in Mobile Safari if you use Phonegap and allowed domains using phonegap.plist whitelist property, but if you do somthing like
var rateMsg = Ext.Msg.confirm('Title', 'Some message', function(e) {
if(e == 'yes')//If user confirms yes
{
window.open("http://www.example.com", "_blank");//We open a link with _blank to use mobile safari and not your webview
}
});
It does not work.