Firefox webextension - confirm function causes extension popup to close immediately - firefox

I would like to port an existing fully functional Chrome extension to Firefox, everything seems to work except the confirm() function behavior.
When the user clicks a specific button in the popup.html page, he is asked to confirm the action.
Chrome successfully prompts the dialog, I then get a Boolean back as soon as "ok" or "cancel" button is clicked, code related to the boolean returned is executed.
Firefox behavior feels buggy on the other hand. The confirm dialog prompts too but the extension popup is instantly dismissed, preventing further code in the click event handler to execute.
manifest.json : …, "default_popup": "popup.html", …
popup.html :
…
<script src="js/popup.js"></script>
</body>
popup.js :
removeButton.addEventListener('click', function () {
// Firefox: calling confirm() closes the popup.html page ...
// ... terminating event handler code
if (confirm("Please confirm you wish to remove this item.")) {
// …
}
});
Is there something to do about it or should I stop using confirm() and find a workaround ?
EDIT - Workaround solution
As a workaround, I set a 3 seconds countdown when the button is clicked and change its caption every second. Before time is up, if the user click again, the final action gets cancelled, otherwise final action is performed.
let log = document.querySelector('p')
,resetInterval = null
;
document.getElementById('resetbtn').addEventListener('click', function(e) {
if (!resetInterval) {
// Create a countdown and delete data when time is up.
e.target.content = e.target.innerHTML;
resetInterval = setInterval( function() {
var counter = +(e.target.innerHTML.trim().match(/\d+/)||[4])[0];
if (counter == 1) {
// Sending command to bacground page
// chrome.runtime.sendMessage({command:'remove'}, function (){
e.target.innerHTML = e.target.content;
resetInterval && clearInterval(resetInterval);
resetInterval = null;
log.innerHTML = 'Perform action…';
// });
} else e.target.innerHTML = 'Reset in '+(counter-1)+'s';
}, 1000);
log.innerHTML = '';
} else {
resetInterval && clearInterval(resetInterval);
e.target.innerHTML = e.target.content;
resetInterval = null;
log.innerHTML = 'Action aborted';
}
});
<button type="button" id="resetbtn">Reset</button>
<p></p>

Popout windows are designed to be dismissed when you move focus to another window. You can’t use dialogs (new windows) from the popout as they’re moving focus and thus dismissing the popout.

Related

Laravel+Vue | Do something and prevent back button if certain condition

As we know, in mobile web-browser, if you click back button, the web-app will go to previous page, right?
But what if I want to make a certain condition which will prevent the web-app to go to previous page.
For example, if a SweetAlert2 dialog is popped-up, the back button will close the SweetAlert2 dialog.. but if there is no SweetAlert2 dialog, the back button will go to previous page..
The code I expected is like below:
export default {
mounted() {
document.addEventListener("backbutton", function(){
if(is_swal_open){
close_swal_dialog();
return false; // NOTE: i expected this should prevent from go to previous page
}
});
},
}
What you can do is warn the user:
if(is_swal_open)
{
window.onbeforeunload = function() { return "Your warning here."; };
}
or add an event listener like so:
window.addEventListener('beforeunload', function (e) {
if(is_swal_open)
{
// Cancel the event
e.preventDefault();
// Chrome requires returnValue to be set
e.returnValue = '';
}
});

Clicking if element is clickable in protractor

on website I have sometimes additional button with restoring autosaved data filled in the form, which pops in random moments (sometimes someone tests something and close form, which causing the popup button). I tried with Continue if element is not visible in protractor with following code:
let DoNotRefillBtn=element.all(by.className('modal-button-no'));
var isApproachable = function(element) {
return element.isPresent().then(function (present) {
return present
? element.isDisplayed()
: false;
});
};
describe(...)
it('Open the form:', function () {
browser.driver.get('foo');
browser.sleep(1000);
isApproachable(DoNotRefillBtn).then(function(approachable) {
if (approachable) {
DoNotRefillBtn.click();
browser.sleep(500);
}
else {
browser.sleep(300);
}
});
It clicks correctly, but after clicking, it throws error Failed: element not visible on line DoNotRefillBtn.click();.
Why does the program clicks and throws an error that thing is not clickable (after it was clicked)?
I used a workaround, the button comes with the status message "Do you want to refill the form?". So when I check for the status message and click the button, seems to be working:
let StatusMessage=element.all(by.className('status-message'));
let DoNotRefillBtn=element.all(by.className('modal-button-no'));
var isApproachable = function(element) {
return element.isPresent().then(function (present) {
return present
? element.isDisplayed()
: false;
});
};
describe(...)
it('Open the form:', function () {
browser.driver.get('foo');
browser.sleep(1000);
isApproachable(StatusMessage.get(8)).then(function(approachable) {
if (approachable) {
DoNotRefillBtn.get(0).click();
browser.sleep(500);
}
});
});
});
StatusMessage.get(8) is 8 because there are some more messages with the same class, but not displayed. I counted which status-message is that one and it seems to be working - closes popup if displayed, but skipping when it's not.
Propably checking the button and clicking it gives some problems

Can't unbind keypress; pressing 'enter' in searchbar passes the window.location/document.location I specified and goes to the wrong page

I'm working on a page that is part of a pre-existing site. There is some script attached to the page that is overriding my searchbar 'enter' presses, so that every time I press enter it goes to the site-search page instead of my events-search page. This is my function:
$(".searchBox").keypress(function (e) {
var key = e.which;
if (key == 13) // the enter key code
{
var searchTerms = $(this).val();
var newQueryString = updateQueryStringParameter(resetPage(document.URL), "q", searchTerms);
window.location.href = newQueryString;
}
});
By stepping through it, I can see that it is hitting each line of my method, including window.location.href... but then it keeps going, and loads the wrong page even though newQueryString is correct.
I tried using document.location isntead of window.location.href, and I tried unbinding my searchbox
$(document).ready(function () {
$(".searchBox").unbind();
}
but it didn't work...
You can use preventDefault() method to stop the default event propagation.
$("#myForm").submit(function(event){
event.preventDefault();
});
http://api.jquery.com/event.preventdefault/

Firefox Bootstrapped Add-On Injecting before load

Is it possible to add event listeners for a document before a page has been navigated to using a Bootstrapped add-on? I would like to see what page the user wants to navigate to as well as later after the page loads to inspect the DOM. I need to run code in the HTML content context.
In the past I used a toolbar XUL and included javascript within it and it would load before the HTML page loaded.
i looked into doing stuff before DOMContentLoaded sometime ago and found out there is a document inserted observer.
order of events after running research code at bottom
readystate changes to interactive (i think multiple times, not sure)
readystate changes to complete
DOMContentLoaded event fires
load event fires (Sometimes load doesnt fire, if you might have to change addEventListener with capture arugment (3rd argument) as false or true)
apparently there should be readystate loading before all of this but i can never catch it i dont know why.
after running the code in scratchpad, browser environemnt of course, then load a new page and watch the error console it will throw these reports in this order:
ready state changed! ("interactive") Scratchpad/4:18
02:28:07.873 ready state changed! ("complete") Scratchpad/4:18
02:28:07.874 DOMContentLoaded event fired! Scratchpad/4:53
02:28:07.938 Load event fired! Scratchpad/4:45
here is the research code. it adds a the listeners and observer to see whats firing.
var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
var os = Cc['#mozilla.org/observer-service;1'].getService(Ci.nsIObserverService);
var LMObserver;
function myObserver() {
this.register();
}
myObserver.prototype = {
observe: function (subject, topic, data) {
//Cu.reportError(subject);
//Cu.reportError(data);
//i think subject is window element
subject.onreadystatechange = function () {
//loading
//interactive
//complete
Cu.reportError('ready state changed! ("' + subject.readyState + '")');
//var body = subject.documentElement.querySelector('body')
//you want to change title so you would do that here do something like: if (subject.readystate == 'complete') { subject.title = 'blah blah' }
//Cu.reportError('has body element: ' + body)
}
},
register: function () {
os.addObserver(this, 'document-element-inserted', false);
},
unregister: function () {
os.removeObserver(this, 'document-element-inserted', false);
}
};
//below this is the DOMContentLoaded thing i put this here so we can see what fires in what order
var pageLoad = function(event) {
var win = event.originalTarget.defaultView;
if (win && win.frameElement) {
return;
}
Cu.reportError('Load event fired!');
}
var pageDOMContentLoaded = function(event) {
var win = event.originalTarget.defaultView;
if (win && win.frameElement) {
return;
}
Cu.reportError('DOMContentLoaded event fired!');
}
LMObserver = new myObserver;
gBrowser.addEventListener("load", pageLoad, true);
gBrowser.addEventListener("DOMContentLoaded", pageDOMContentLoaded, true);
//gBrowser.removeEventListener("load", pageLoad, true);
//gBrowser.removeEventListener("DOMContentLoaded", pageDOMContentLoaded, true);
//LMObserver.unregister();
Here's some more indepth research on load events added with true or false as capture argument: https://github.com/Noitidart/event-listener-experiment-DOMC-and-load/blob/master/bootstrap.js

safari extension: Sending message from injected script to popover

im busy with creating a bookmaker extension in safari and running up against the following issue. In my popover i've a iframe which includes a button. When that button (submit button) is clicked the following message must be send:
window.addEventListener('message', function(e){
if(e.data.command == 'closeSymbalooBookmarker'){
window.setTimeout(function(){
window.close();
}, 2000);
}
});
as you can see this close the popover in 2 seconds (the above script is made in chrome extension).
I need to send a message from the inject script to a popover so i can close the popover in the popover window. Or is there some other way to that?
Thank u.
The global page is the best place to receive messages from an injected script.
Do something like this:
global.js
safari.application.addEventListener('message', handleMessage, false);
function handleMessage(msg) {
if (msg.name === 'hidepopover') {
safari.extension.popovers[0].hide()
}
}
injected.js
setTimeout(function() {
safari.self.tab.dispatchMessage('hidepopover');
}, 2000);

Resources