Reputation: 13110
I have a problem that I have been struggling with for a few days now.
I am writing a userInput recording system for firefox with a view to using it to record tests for a web-based application.
I am recording onchange events on form fields and saving them in a store using a contentScript with added listeners to each field's onchange event.
field.addEventListener('change', recordFieldChange);
I am also recording user js confirm responses using an observer-service based override of the window.confirm methods.
var obs = require("observer-service");
obs.add("content-document-global-created", observeWindow);
function observeWindow(subject) {
var window = subject.wrappedJSObject;
var standardConfirm = window.confirm;
window.confirm = function(pMessage) {
response = standardConfirm(pMessage);
recordConfirm(response);
return response;
}
};
The trouble I am having is that any confirm responses where the confirm is triggered by a field change are recorded before the field change, which is the wrong order for running a test.
I think this is because the page's onchange is evaluated before the addon contentscript, is there any way to change this order?
I am hoping for a solution or work around that doesn't use time-outs or changing the basic page content. I also need to able to record confirms caused by other events like page loads.
Upvotes: 0
Views: 452
Reputation: 57651
The problem is that the page and your content script register event handlers on the same element - and the order in which they will be called is undefined (however, I think that Firefox consistently calls onchange
before any listeners added via addEventListener
). You need to get the change
event before the web page does and triggers additional actions. The solution would be catching the event during the capture phase at the top level. In the capture phase the event "sinks in" to the actual element and triggers capturing event listeners before the bubble phase starts and the event goes up again triggering regular event listeners. Something like this should work:
window.addEventListener("change", recordFieldChange, true);
function recordFieldChange(event)
{
var field = event.target;
...
}
This no longer registers the event listener at the individual field but rather at the window
level. Note that this won't help much if the web page listens for a different event like input
or keypress
.
Upvotes: 1