In my extension I need to work with bookmarks that have part of their URL replaced by some markers. When user opens such bookmark, extension should replace this marker with some value and open new location. To achive this I used nsIWebProgressListener as shown below:
bookmarksResolver: {
onLocationChange: function(aWebProgress, aRequest, aLocation, aFlags) {
if (aLocation) {
try {
// Replace markers
var resolvedLocation = resolveReferences(location);
if (resolvedLocation != location) { // Open new location if markers were found and replaced
aWebProgress.DOMWindow.location.replace(resolvedLocation);
}
}
catch(ex) {
//Logging error
}
}
},
/* Stubs for other listeners */
onStateChange: function(a, b, c, d) {},
onProgressChange: function(a, b, c, d, e, f) {},
onStatusChange: function(a, b, c, d) {},
onSecurityChange: function(a, b, c) {},
QueryInterface: function (aIID) {
if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
aIID.equals(Components.interfaces.nsIWebProgressListener2) ||
aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
aIID.equals(Components.interfaces.nsISupports)) {
return this;
}
else {
throw Components.results.NS_NOINTERFACE;
}
}
},
The problem is that when I try to replace marker in URLs like https://[marker].site.com I get a strange error page displayed (says there's a syntax error on netError.xhtml), then url with replaced marker is opened, but address bar keeps showing https://[marker].site.com URL.
Question #1: do I use onLocationChange properly here? Maybe, another method should be used?
Question #2: what do I do to prevent this error from happening?
UPD: Used onStateChange instead of onLocationChange and used flags STATE_TRANSFERRING | STATE_IS_DOCUMENT because catching flags STATE_START | STATE_IS_DOCUMENT causes serious UI hang before redirection. I also put request cancel method call. It looks like this now:
bookmarksResolver: {
onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) {
var nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
if (aStateFlags & nsIWebProgressListener.STATE_TRANSFERRING
&& aStateFlags & nsIWebProgressListener.STATE_IS_REQUEST) {
try {
var location = aWebProgress.DOMWindow.location.href;
var resolvedLocation = resolveReferences(location);
if (resolvedLocation != location) {
aRequest.cancel(Components.results.NS_BINDING_REDIRECTED);
aWebProgress.DOMWindow.location.href = resolvedLocation;
logger.info('Old URL: [' + location + ']');
logger.info('Redirected to: [' + resolvedLocation + ']');
}
}
catch(ex) {
//Logging error
}
}
},
/* Stubs for other listeners */
onLocationChange: function(a, b, c, d) {},
onProgressChange: function(a, b, c, d, e, f) {},
onStatusChange: function(a, b, c, d) {},
onSecurityChange: function(a, b, c) {},
QueryInterface: function (aIID) {
if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
aIID.equals(Components.interfaces.nsIWebProgressListener2) ||
aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
aIID.equals(Components.interfaces.nsISupports)) {
return this;
}
else {
throw Components.results.NS_NOINTERFACE;
}
}
},
Everything works except RSS pages. Log entries for old location and 'redirected to' show that the markers have been replaced and new URLs are correct. But they're reloaded over and over again because actual URL (which I get from aWebProgress.DOMWindow.location.href) is not changed for some reason and replacement is performed again and again. What is different about loading RSS URL and how to solve this?
Q1: I would prefer onStateChange
Q2: Maybe aRequest.cancel(Components.results.NS_BINDING_REDIRECTED) will end the original request peacefully.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With