Popups in a Safari extension - javascript

Im trying to build my first safari extension and Im at a loss on a few basic concepts.
The first hurdle is making a popup window open from a toolbar button, just like the Ebay Safari extension.
http://anywhere.ebay.com/browser/safari/welcome/

Read this: http://net.tutsplus.com/tutorials/other/how-to-create-a-safari-extension-from-scratch/
It describes how to have something happen when a toolbar button is pressed, you would just put it the middle of this:
<script>
// Set up the Listener
safari.application.addEventListener("command", performCommand, false);
// Function to perform when event is received
function performCommand(event) {
// Make sure event comes from the button
if (event.command == "open-nettuts") {
**YOUR FUNCTION**
}
}
</script>

As far as I know, Safari does not allow us to create a "popup" the way Chrome does. For my Safari extension I am using jQueryUI to create my popup. You can also use YUI or Mootools. In taking apart the eBay and Twitter extensions I see they're using an iframe. Just how they're implementing it I don't know since jquery doesn't allow you to modify the contents of an iframe (correct me if I'm wrong here).
But to answer your question, your button will send an event to an injected script. That script can have code similar to this:
$('body').append('<div id="mypopup">');
var myPopup = $('#mypopup').dialog({
'autoOpen' : false ,
'draggable' : false,
'modal' : false,
'resizable' : false,
'title' : 'My Popup'
});
function messageHandler(msgEvent) {
var messageName = msgEvent.name;
var messageData = msgEvent.message;
if (messageName === 'buttonPushed') {
if (myPopup.dialog('isOpen')) {
myPopup.dialog('close');
return;
}
$('#mypopup').children().empty(); // Clear out any crap should it exist
$('#mypopup').append(someHTML);
myPopup.dialog('open');
return;
}
}
}
This is a very basic example. In mine there is a toolbar, and a host of other things. Plus you have to have REALLY specific CSS rules to protect your popup's CSS from being clobbered by every site in the world.
I have also thought about using global.html to open the "popup" window but as far as I can tell, all it can do is open a window. I don't see any facilities for setting attributes like size, etc. If there are, I'd go that route since your popup would then be protected from CSS as it's in its own window.

I think under Safari its called a popover, thats what you mean?
two things that i noticed:
if there is no command set (on the toolbar item), the popover automatically displays when clicking the toolbar button
If there is a command set, then the user need to click and keep the toolbar button pressed until the popover shows.

Related

How do I use javascript or jquery to check if named window exists

Here is the scenario. I have a static audio player in the footer of a site. If you go to another page, the audio player reloads. Not an issue because it's an audio stream not a static file. There is also a link in this footer that when clicked will cause the entire static footer to disappear and a window to pop up with the audio stream. Of course the problem is that if someone reloads the page or goes to another one the footer will reload. The pop up window is named through the same javascript that popped up the window. This is also a problem if they leave the website and come back. I would like to figure out a way to run a check on the window loading to see if a window with a specific name is still open. So, if when I clicked on a button to get this pop up window I also named the window "Radio" then it would check to see if a window with the name radio exists. So something like:
if window.name("Radio).exists then $(".radio").remove();
Something that runs after the document is ready. I just need a way to see if that named window is open then I can go from there.
Here's the jquery I have in the footer:
$(".lnk1,#xx").click(function() {
$("div").remove("#fixedBar")
});
$( document ).ready(function() {
$(".radio2").html('<audio src="http://www.live365.com/play/372874/" type="audio/mpeg" autoplay="autoplay" preload="auto" controls="controls"></audio>');});
Here's the HTML where I create the pop up link:
<div class="radioBar"><a class="lnk1" style="font-size:125%;text-align:center;" href="javascript://" onclick="window.open('/live365', 'live365',',width=400,height=550,resizable=yes,scrollbars=no,menubar=no'); return true;"><span style="padding:0 0 0 1%;">Click To Pop Out Player</span></a><div id="container1" class="radio2"></div></div>
Keep in mind that it's possible someone might leave the website so I don't think that using the window.opener is going to work here. I can use php, javascript, jquery, css, html, and if desperate, sledge hammer. :) Thanks in advance for any ideas.
<--->EDIT<--->
Here are some details I left out:
I'm using straight HTML5 audio in wordpress and since mediaelement.js hates streaming audio and is basically crap in wordpress, I had to create a custom template and then float it statically in an iframe at the bottom of the website. This added some complexities with other links on a page that might remove the frame. So based on the answer left by Jack I put the following javascript/jquery code in my wordpress template.
$( document ).ready(function() {
if (window.localStorage.radioOut === "1") {
$("#fBar").remove();
}
$(".lnk2,#xx").click(function() {
$("div").remove("#fbar");
window.localStorage.radioOut = "1"
});
$(".radio2").html('<audio src="http://www.live365.com/play/372874/" type="audio/mpeg" autoplay="autoplay" preload="auto" controls="controls"></audio>');
});
in the html of the same template I added a class of lnk2 to the link on the page. In other parts of the site I added a class of lnk1 to all links that pop up the player on the entire site. I added additional code to the footer of the site:
$(".lnk1").click(function() {
$("div").remove(".fixedBar")
});
if (window.localStorage.radioOut === "1") {
$(".fixedBar").remove();
}
So far this works perfectly as I have another template that handles the pop up audio player and it has it's own header. Since I deduced that the other aspect of the code is to change the value of local storage should that pop up window be closed and since I had two different pop up players that both used the same header, I added this code to the header file.
window.addEventListener("beforeunload", function (event) {
window.localStorage.radioOut = "0"
});
This is now live on the website and so far it appears to be working perfectly.
If anyone is interested you can find it here:
http://www.kgraradio.com
KUDOS to Jack and everyone else who helped.
It sounds like you just want to track the state of the popup being open. I'd just use localStorage instead since I don't think you'll be able to do what you're talking about.
When the popup is opened do:
window.localStorage.radioOut = "1"
In the popup itself:
window.addEventListener("beforeunload", function (event) {
window.localStorage.radioOut = "0"
});
Then on your page just do:
if (window.localStorage.radioOut === "1") {
$(".radio").remove();
}
You could have the click function that launches the pop out also set a cookie. When the user leaves the site, then returns, you could have a check that looks for the cookie. If the cookie exists, hide the footer bar, else, show it.
Since you are using jQuery, a cookie plugin could make it simpler https://cdnjs.com/libraries/jquery-cookie.
Maybe something like:
$(window).load(function() {
if (!$.cookie('playerPop')) {
$('.radio').show;
}
});
$(".lnk1,#xx").click(function() {
$("div").hide("#fixedBar");
$.cookie('playerPop', {
path: '/',
expires: 1
});
});
You could use a technique like this to detect the closing of the popup: http://www.sitepoint.com/jquery-capture-close-popup-window/.
Not only would closing the popup remove the cookie, but it would be cool if you "popped the player back into the page" by showing the footer bar again.
since storage events fire on all tabs on the same domain (except on the tab setting the value), they can be used to poll for other tabs.
Listen for marco storage events on the popup tab, and trigger a polo event when they occur:
addEventListener("storage", function(e){
if(e.key=='marco') localStorage.polo = e.newValue;
});
On the main page, trigger a new marco storage event and listen for a polo event:
addEventListener("storage", function(e){
if(e.key=='polo' && e.newValue == localStorage.marco){
$(".radio").remove();
}
});
localStorage.marco=Math.random();
this works on all tabs, iframes, and popups (at once), so it's a bit more flexible than looking for only popups.

IncludeCSS not working on IE

I want to create a browserAction on my extension and when I click on the browserAction's icon open an options page (similar what we can do in chrome). I created the code to do what I am describing, and when I click on the icon on FF, all works fine and the page style looks well. On IE11 instead, when I click on the icon, the page is showed without any style.
I uploaded to my resources, all the files I needed, my options.html, css/style.css and my images. Here is my code...
And my background.js looks like this:
appAPI.ready(function($) {
// Sets the initial browser icon
appAPI.browserAction.setResourceIcon('48x48.png');
// Sets the tooltip for the button
appAPI.browserAction.setTitle('My title');
// Sets the initial onClick event handler for the button
appAPI.browserAction.onClick(function(){
appAPI.openURL({
resourcePath: "options.html",
where: "tab",
focus: true
});
});
});
and my extension.js like this:
if (document.title == "My options page title") {
appAPI.resources.includeCSS('css/style.css');
}
The code above, check if it is the page I want based on its title (it is not a nice way, I know, but I am testing right now... if you have some advice about that, I will appreciate too)
What am I doing wrong?
#Crossrider support: my app id is 81180
Thanks for your help
The options.html page runs in an isolated context (i.e. extension.js is not guaranteed to run on it on all browsers) and hence you should embed the CSS in the HTML page.
[Disclosure: I am a Crossrider employee]

Creating an HTML dialog pop-up in chrome extension

I'm working on a Chrome extension that will pop up a dialog box in the center of the screen when the user hits a keyboard shortcut. It will then use JavaScript to asynchronously load in content from the MediaWiki API. But I'm having difficulty figuring out how to create and display a dialog with JavaScript. I don't want to use the Chrome html-popup browser action, because it appears off in the corner of the screen.
I know how to use JavaScript to display an existing HTML dialog box, as this answer explains, but I don't know how to insert one into the DOM. I don't want to use JavaScript's alert function, since that opens a separate window. So is there a way to create and display an HTML modal dialog when an event triggers a JavaScript function in a chrome extension?
You should be able to use the javascript for the answer you linked to open that dialog whenever you want by injecting your javascript via a content script. Google has documentation for this here: https://developer.chrome.com/extensions/content_scripts
Basically, a content script runs on whatever pages you tell it to. So you could tell it to run on all web pages (configured via the manifest). This content script would add your listener, and then append your dialog to the body tage (or wherever, body is usually safe).
The code would look something like:
$(document).on( 'keypress', 'body', function( e ){
var code = e.keyCode || e.which;
if( code = /*whatever, key shortcut listener*/ ) {
document.body.innerHTML += '<dialog>This is a dialog.<br><button>Close</button></dialog>';
var dialog = document.querySelector("dialog")
dialog.querySelector("button").addEventListener("click", function() {
dialog.close()
})
dialog.showModal()
}
});
You may want to add safety code to check for your body tag; it's on normal pages but specialty pages may error (such as chrome://*).
As long as this runs on your content script, and your content script runs on your desired pages, you can run whatever listeners/dom changers you want this way.
You don't need to add a permission for a public api. You only need to add a permission if the site doesn't allow cross origin requests.
Also, adding the listener for your keyboard shortcut using a web listener through a content script is not a good solution, since it requires a permission warning, and is generally not efficient. Instead, you should use Chrome's commands api with activetab. Your extension will only be started when the user hits the keyboard shortcut, and the user can customize the shortcut via the shortcuts link at the bottom of chrome://extensions.
To do this, add "permissions": [ "activeTab" ] to your manifest. Then add your key combo:
"commands": { "showcontentdialog": { "suggested_key": { "default": "Ctrl+Shift+Y" }, "description": "show content dialog" } }
Next, setup your background page listener and inject your content script when the user hits those keys:
chrome.commands.onCommand.addListener(function(command) {
if(command.name == "showcontentdialog") {
chrome.tabs.executeScript({ file: "main.js" })
}
})
Also, you should use appendChild instead of setting innerHTML, like this:
var dialog = document.createElement("dialog")
dialog.textContent = "This is a dialog"
var button = document.createElement("button")
button.textContent = "Close"
dialog.appendChild(button)
button.addEventListener("click", function() {
dialog.close()
})
document.body.appendChild(dialog)
dialog.showModal()

How can I make a function get called after a page has finished loading

I am trying to modify a firefox addon to my personal needs.
Currently my code is this:
var wwatch = Components.classes[NS_WINDOWWATCHER_CONTRACTID].getService(nsIWindowWatcher);
var myWnd = wwatch.openWindow(wwatch.activeWindow, "http://www.google.com", "Test",
"width=600, height=300", null);
myWnd.addEventListener("load", function(e) { alert("inner"); }, false); // doesn't work
// myWnd.onload = function() { alert("inner"); }; // fails totally
I want to show an alert box when the page is finished loading.
With above code the window gets created and the web page gets loaded.
But I don't get an alert box.
Please tell me, how I can achieve that.
I am new to Javascript and I don't even know how to debug this.
The Javascript debugger of Firefox didn't break on any of above lines, although they are obviously executed.
The addon which I am adapting to my needs is Torrentserver Handler.
The problem with opening a content window is that the content hasn't started loading, and all your carefully attached event listeners get destroyed when it does.
One approach is to open a chrome browser window and pass it the page that you want it to open. You can then think about adding event handlers as if you were an overlay.
Another approach is to keep with opening the content window, but use one of the various methods to extract the associated chrome window thus giving you somewhere to attach your event handlers.

The proper way to handle popup closing

I'm looking for close event for popup. I've found one for XUL, but I need it for HTML.
Popup has closed property.
>>> var popup = open('http://example.com/', 'popup', 'height=400,width=500');
>>> popup.closed
false
Well, I can check it once at half second.
function open_popup() {
var popup = open('http://example.com/', 'popup', 'height=450,width=450');
var timer = setInterval(function(){
if (popup.closed) {
alert('popup closed!');
clearInterval(timer);
}
}, 500);
}
I've tested it on Chrome 4.0.249.27, Opera 10.10, Safari 4.0.4, and Firefox 3.5.5. All works fine.
But setInterval bother me. It is ugly. Is there a better way of doing this?
UPDATE:
I use popups for authentication dialog (oAuth, actually). I wanna send some data to parent window after popup close (through postMessage).
Page inside popup from another domain. So, I can not add any event (unload) to it due security restrictions.
I can not use iframe due to iframe buster script. So, I can not use any fancy jQuery modal dialogs.
I can not edit anything inside popup.
You might want to look into the unload event, take a look at Javascript: Popups
edit: as you've said you cannot edit anything inside the popup, there really aren't any options left. I believe your current setInterval code does the job just fine. You should ask yourself if realtime detection of the popup closing is absolutely critical. That 500 milliseconds timer certainly won't strain hardly any resources or bring someones computer to its knees.
I have used jQuery Dialog and it has a close event
http://jqueryui.com/demos/dialog/.
Am not sure if I understand your question right,why do you want to use the timer ?
Use window.opener in the pop-up window. i.e. something like:
onunload = opener.alert('popup closed');
or
onunload = opener.nameOfAFunction();

Categories

Resources