Safari Extension Showing Popover Different Window - javascript

I'm trying to build a Safari Extension where when a user hits Command+B it will show the popover. Using the code below it works but always shows the popover on a different window not the current window/tab. I would like it to display the popover on the current window instead of switching to a different window and opening the popover there. It works perfectly if there is only one Safari window open but starts to have problems when multiple windows are open.
Any ideas?
Global Page File:
<script>
safari.application.addEventListener('message', function (e) {
if (e.name == 'Show Popover') {
safari.extension.toolbarItems[0].showPopover();
}
}, false);
</script>
Injected Content:
document.addEventListener("keydown", keydown);
function keydown(event) {
if ( event.metaKey && event.keyCode == 66) {
event.preventDefault();
safari.self.tab.dispatchMessage('Show Popover', {});
}
}

This is because you are manually selecting the first toolbarItem here;
safari.extension.toolbarItems[0].showPopover();
You need to determine which toolbarItem the popover needs to appear on;
Something like this;
var toolBarID = 'my_id';
var activeItem = safari.extension.toolbarItems.filter(function (button) {
return button.identifier == toolBarID && button.browserWindow == safari.application.activeBrowserWindow;
})[0];
You then use this object for the showPopover function;
activeItem.showPopover();
Hope this helps

Related

How to prevent default behavior when middle click on a link (browsers' extensions)

In my Firefox's & Google Chrome's extensions I can prevent default behavior when middle click on a link like this:
function onClick(e) {
var url = getLink(e);
if (e.button == 1) { // Middle Click
// prevent opening a link
e.preventDefault();
e.stopPropagation();
// do something with a link
// url ...
}
}
if (browser == "chrome")
document.addEventListener("auxclick", onClick); // for Google Chrome (old "click" event doesn't prevent opening link with middle click but they added "auxclick" for this)
else if (browser == "firefox")
document.addEventListener("click", onClick); // for Firefox (still works)
also https://developers.google.com/web/updates/2016/10/auxclick, https://developer.mozilla.org/en-US/docs/Web/Events/auxclick
I'm also trying to do this for my Microsoft Edge's extension, but seems middle click event for this browser doesn't work at all:
function onClick(e) {
var url = getLink(e);
if (e.button == 1) { // Middle Click
alert("hello"); // isn't working for Microsoft Edge
}
}
document.addEventListener("click", onClick);
So instead of this for Microsoft Edge I use:
document.addEventListener("mousedown", function(e) {
var target = e.target || e.srcElement;
while (target) {
if (target instanceof HTMLAnchorElement)
break;
target = target.parentNode;
}
if (e.button == 1 && target.href != null) {
alert("hello"); // works when middle click on a link
// but these preventing doesn't works here:
e.preventDefault();
e.stopPropagation();
// link will still be opened in a new tab
}
});
But this method doesn't prevent link from opening in a new tab when middle click
How can I make Microsoft Edge behave like Google Chrome or Firefox?
it seems the latest version of Edge has event listener auxclick now, the same as Chrome, because Edge is based on Chromium engine now, not EdgeHTML

How to open a new tab trigger by the scroll button

I'm making a php/html app which show some data in a table, when the user clicks in the row (<tr>) jquery open that record.
This is the code:
$.fn.linkRow = function(element) {
thisRow = this.find('tbody tr');
thisRow.on('click', function() {
hrefLocation = $(this).find('td.link:first a').attr('href');
if (hrefLocation) {
window.location.href = hrefLocation;
};
}).addClass((thisRow.has('td.link')) ? 'pointer' : '');
return this;
};
The fact is: The user can't open a record in a new tab. The only way is copy&paste the href... And my users won't do that.
If make some research about the event fired by the scroll button and how to open a new tab, the later is almost impossible, so... Does anyone can figure a way?
EDIT: I mean the mouse-wheel... Normally this open a link in a new tab.
PS: I have to use tables, In some point I will make a css-based table layout for that (no javascript needed), but I can't do it in this version of the software.
Thanks!
This is the final code:
$.fn.linkRow = function(element) {
thisRow = this.find('tbody tr');
thisRow.not('a').on('mouseup', function(e) {
hrefLocation = $(this).find('td.link:first a:first').attr('href');
if ( hrefLocation ) {
if (e.which == 2) {
window.open(hrefLocation);
}
else{
window.location.href = hrefLocation;
}
};
}).addClass( ( thisRow.has('td.link') ) ? 'pointer' : '' );
return this;
};
BUT... The mouse-wheel click does not work for what I intend:
If you click a link (a tag) > open a new tab
If you click a no link (any other tag) > it will scroll based on your mouse position. if you move your mouse up, it scrolls up and so
So... I works but I definitively need to make a no-javascript solution.
If you want to have the links open in a new tab and not in the same page, you need to replace
window.location.href = hrefLocation;
with
window.open(hrefLocation);
Change click with mouseup and catch e.with with value 2 (middle button):
$.fn.linkRow = function(element) {
thisRow = this.find('tbody tr');
thisRow.on('mouseup', function(e) {
hrefLocation = $(this).find('td.link:first a').attr('href');
if ( hrefLocation ) {
if (e.which == 2) {
window.open(hrefLocation);
}
else{
window.location.href = hrefLocation;
}
};
}).addClass( ( thisRow.has('td.link') ) ? 'pointer' : '' );
return this;
};
Try with the following method
$(document).scroll(function(){
if(!tabOpen){
window.open('url', 'window name', 'window settings');
tabOpen = true;
}
});
I faced a similar problem a few months ago.
Either you wrap every td-content into a normal a-Tag (and use _target="blank"), no javascript required in this case!
...or you use js:
thisRow.click(function(){
window.open('url', 'window name', 'window settings');
return false;
});
window.open() will do the trick but it also depends on the browser configuration
Not sure what you mean with the scroll button, but if it's the mouse-wheel then you can use this script to fire events on wheel-up/-down.
http://brandonaaron.net/code/mousewheel/demos
I'm unsure if you want to know how to make an middle click event with jquery or if you want to know how to open a new tab but here goes:
Middle click event:
$("tr").live('mousedown', function(e) {
if( (e.which == 2) ) {
alert("middle button");
}
e.preventDefault();
});
New tab:
As all the others are saying, use the following:
window.open(href);
With both middle click and open link:
$("tr").live('mousedown', function(e) {
if( (e.which == 2) ) {
window.open(href);
}
e.preventDefault();
});
EDIT:
Some sources:
Jquery: detect if middle or right mouse button is clicked, if so, do this:
The answer to Detect middle button click (scroll button) with jQuery can also help solve some compatibility issues with IE
To open in a new tab use:
window.open(hrefLocation);
window.open(hrefLocation,'_blank'); //Or this
window.open(hrefLocation,'_newtab'); //Or this
One of these should work.

iPhone Javascript Confirm Dialog Bug

I have a javascript confirm dialog popping up, but when I tap 'Cancel', then after the dialog closes, tap anywhere on the screen, the dialog pops up again. It only happens the one extra time, then you can tap on the page again without the dialog popping up.
I'm only seeing this on iPhone/iPad running iOS 5.0.1. I don't have an iOS 6 device, so I'm not sure it's happening there.
Here's the code I'm using:
$(bpm.remoteAppDivName).on('tap', 'a.delete-pending-payment', function(event) {
if (isJQMGhostClick(event)) { return false; }
var deleteGlobalPaymentURL = $(this).attr('href');
var confirmMsg = confirm ("Are you sure you want to do that?");
if (confirmMsg === true){
window.location = '/index.htm';
}
event.preventDefault();
return false;
});
var lastclickpoint, curclickpoint;
var isJQMGhostClick = function(event){
curclickpoint = event.clientX+'x'+event.clientY;
var ret=false;
if (lastclickpoint === curclickpoint) {
ret=true;
} else {
ret=false;
}
lastclickpoint = curclickpoint;
return ret;
}
Here's a link to the problem page: http://www.5280skateparks.com/dev/confirmBug.htm
Any help would be extremely appreciated.
UPDATE: I just confirmed that it's happening on iOS 6.0.1 as well.
This is the jQuery Mobile "Ghost Click" discussed in some detail here and here. On the forum page, a solution was proposed, which I have reproduced below with a small bug fix:
var lastclickpoint, curclickpoint;
var isJQMGhostClick = function(event){
curclickpoint = event.clientX+'x'+event.clientY;
var ret=false;
if (lastclickpoint === curclickpoint) {
ret=true;
} else {
ret=false;
}
lastclickpoint = curclickpoint;
return ret;
}
I have modified this code slightly to not always expect a pair of clicks. This function now works correctly in the case of 0 ghost clicks and more than 2 ghost clicks. You can use it by checking isJQMGhostClick(event) at the beginning of your tap handler and ignoring the event if the isJQMGhostClick function returns true.

How to open popover with keyboard shortcut? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Keyboard shortcuts with jQuery
I want to display a popover window using a shortcut key instead of clicking the icon on the toolbar.
Do you have any good idea?
Thank you for your help.
Abody97's answer tells you how to determine if a certain key combo has been pressed. If you're not sure how to get that key combo to show the popover, this is what you need. Unfortunately, Safari makes this needlessly complicated.
In the global script, you'll need a function like the following to show a popover, given its ID and the ID of the toolbar item that should show it:
function showPopover(toolbarItemId, popoverId) {
var toolbarItem = safari.extension.toolbarItems.filter(function (button) {
return button.identifier == toolbarItemId && button.browserWindow == safari.application.activeBrowserWindow;
})[0];
var popover = safari.extension.popovers.filter(function (popover) {
return popover.identifier == popoverId;
})[0];
toolbarItem.popover = popover;
toolbarItem.showPopover();
}
You'll also need code to call this function in your global script's message listener, like the following (this sample does not assume you already have a message listener in place):
safari.application.addEventListener('message', function (e) {
if (e.name == 'Show Popover') {
showPopover(e.message.toolbarItemId, e.message.popoverId);
}
}, false);
Finally, in your injected script, the function that listens for the key combo needs to call dispatchMessage, as below:
safari.self.tab.dispatchMessage('Show Popover', {
toolbarItemId : 'my_pretty_toolbar_item',
popoverId : 'my_pretty_popover'
});
(Stick that in place of showPopUp() in Abody97's code sample.)
Note: If you only have one toolbar item and one popover (and never plan to add more), then it becomes much simpler. Assuming you've already assigned the popover to the toolbar item in Extension Builder, you can just use
safari.extension.toolbarItems[0].showPopover();
in place of the call to showPopover in the global message listener, and omit the message value in the call to dispatchMessage in the injected script.
Assuming your shortcut is Ctrl + H for instance, this should do:
var ctrlDown = false;
$(document).keydown(function(e) {
if(e.keyCode == 17) ctrlDown = true;
}).keyup(function(e) {
if(e.keyCode == 17) ctrlDown = false;
});
$(document).keydown(function(e) {
if(ctrlDown && e.keyCode == 72) showPopUp(); //72 is for h
});
Here's a reference for JavaScript keyCodes: little link.
Here's a little demo: little link. (It uses Ctrl + M to avoid browser-hotkey conflicts).
I believe this could help you: http://api.jquery.com/keypress/
In the following example, you check if "return/enter" is pressed (which has the number 13).
$("#whatever").keypress(function(event) {
if( event.which == 13 ) {
alert("Return key was pressed!");
}
});

Problem with event.target in IE

I'm writing js for a status update system to be used on various pages throughout a app that I'm working. I am really just starting to get more comfortable with javascript so it has been somewhat of a challenge to get to the point where I have everything now.
The status system is basically a facebook clone. For the most part everything is supposed to function the way that facebook's status updates and status comments do. The intended behavior is that when the user clicks in the status textarea, the div under the status textarea slides out revealing the submit button as well as some other checkboxes.
If the user clicks anywhere else on the page except a link or any element that has the class prevent_slideup the div slides up hiding the submit button and any checkboxes.
I'm using a document.body click function to determine what the user clicked on so I know which form elements to hide if I should even hide them. I do not want this slideup to take place on a textarea if that textarea has focus or the user is selecting a checkbox that goes with that form. Hence the prevent_slideup class. I also do not want to bother running the slideup logic if the user has clicked on a link. I'd prefer they just leave the page without having to wait for the animation.
The code that I was using to accomplish this task can be found in the $(document.body).click(function (e) section below where I'm doing a .is('a') check on the event target.
This code works as expected in chrome and firefox, however in ie when a link is clicked for the first time it seems that the element stored in var target is actually a div instead of an anchor. What ends up happening is that the submit div slides up and the user is not taken to the link that they just clicked on. If a link is clicked a second time the user is taken to the page as you would expect.
It seems to me that there's some kind of a lag in ie as to what the current event being fired is.
The entire status module is working other than this one strange ie bug regarding the users click on the link not being carried out the first time that they click a link after opening the status textarea. Does anything jump out in this script that would explain this behavior or does anyone have any other advice?
Thanks in advance for your help.
$(document).ready(function(){
$("textarea.autoresize").autoResize();
});
$(document.body).click(function (e){
var target = e.target || e.srcElement;
console.log(target);
console.log($(target).is('a'));
if($(target).hasClass('prevent_slideup') || $(target).is('a'))
{
return true;
}
else
{
var active_element = document.activeElement;
var active_status_id = $(active_element).attr('data-status_id');
var active_has_data_status_id = (typeof active_status_id !== 'undefined' && active_status_id !== false) ? true : false;
$('textarea').each(function(){
if($(this).hasClass('status_comment_textarea'))
{
var status_id = $(this).attr('data-status_id');
if($('#comment_textarea_'+status_id).val() === '' && (!active_has_data_status_id || active_status_id !== status_id))
{
hide_status_comment_submit(status_id);
}
}
else if($(this).attr('id') === 'status_textarea')
{
if($('#status_textarea').val() === '' && $(active_element).attr('id') !== 'status_textarea')
{
$('#status_textarea').html($("#status_textarea").attr('placeholder'));
hide_status_submit();
}
}
});
return true;
}
});
$("#status_textarea").live('click', function(){
if($('#status_textarea').val() === $("#status_textarea").attr('placeholder'))
{
$('#status_textarea').html('');
}
show_status_submit();
return false;
});
$(".comment_toggle").live('click', function(){
var status_id = $(this).attr('data-status_id');
show_status_comment_submit(status_id);
return false;
});
$(".status_comment_submit").live('click', function(){
var status_id = $(this).attr('data-status_id');
$('#status_comment_submit_wrapper_'+status_id).addClass('status_comment_submit_successful');
return false;
});
$(".show_hidden_comments").live('click', function(){
var status_id = $(this).attr('data-status_id');
$('#status_hidden_comments_'+status_id).show();
$(this).hide();
return false;
});
function hide_status_submit()
{
$("#status_textarea").removeAttr('style');
$("#status_textarea").blur();
$("#status_block").removeClass('padding_b10');
$("#status_submit_wrapper").slideUp("fast");
return false;
}
function show_status_submit()
{
if ($("#status_submit_wrapper").is(":hidden"))
{
$("#status_block").addClass('padding_b10');
$("#status_submit_wrapper").slideDown('fast');
}
return false;
}
function hide_status_comment_submit(status_id)
{
if(!$('#status_comment_submit_wrapper_'+status_id).is(":hidden"))
{
$('#status_comment_submit_wrapper_'+status_id).hide();
$('#fake_comment_input_'+status_id).show();
$('#comment_textarea_'+status_id).removeAttr('style');
}
return false;
}
function show_status_comment_submit(status_id)
{
if($('#status_comment_submit_wrapper_'+status_id).is(":hidden"))
{
$('#fake_comment_input_'+status_id).hide();
$('#status_comment_submit_wrapper_'+status_id).show();
$('#comment_textarea_'+status_id).focus();
}
return false;
}
function status_comment_submit_successful()
{
hide_status_comment_submit($('.status_comment_submit_successful').attr('data-status_id'));
$('.status_comment_submit_successful').removeClass('status_comment_submit_successful');
return false;
}
I figured out that there were two main issues with my script...
1.) The document.body function and the #status_textarea live click funtioins were conflicting with each other.
2.) After adding the logic for the #status_textarea function into the document.body function I noticed that the script still didn't quite work as expected in internet explorer unless I had an alert in the function. The problem at this point was that the autoresize plugin that I'm using on the textarea was also conflicting with the document.body function.
I was able to rectify the situation by adding a dummy text input and hiding the status textarea. On click of the dummy text input the status textarea is shown and the the dummy text input is hidden. I have no idea why this worked, but it seems to have solved my problems.

Categories