How to detect page loading error from extension? - javascript

Is there a way to detect if tab shows 'error page'?
I mean, for example, if user enters any http://non-existing-url.com or just site is unavailable.
Anything similar to Chrome's webNavigation.onErrorOccured event.
If there is no similar event, perhaps there is a way to check Tab http status (200, 404, 502, 0, etc...)?

Whoops didn't see this topic. Here is how you can do it look for about:neterror load
from: mozillaZine :: Detecting “problem loading page” in firefox
have to read the docuri through the webNavigation of the browser. because the window.location is different
anyways the docuri is real nice when an error it happens. it clearly tells you whats wrong with it in the e parameter.
theese are examples of some docuris that load:
about:neterror?e=dnsNotFound&u=http%3A//www.cu.reporterror%28%27afew/&c=UTF-8&d=Firefox%20can%27t%20find%20the%20server%20at%20www.cu.reporterror%28%27afew.
about:neterror?e=malformedURI&u=about%3Abalk&c=&d=The%20URL%20is%20not%20valid%20and%20cannot%
you can see the first one is dnsNotFound and the second one is malformedURI
var listenToPageLoad_IfProblemLoadingPage = function(event) {
var win = event.originalTarget.defaultView;
var webnav = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation);
//console.log('webnav:', webnav, 'webnav of selectedtab:', window.gBrowser.webNavigation);
var docuri = webnav.document.documentURI; //can also try event.originalTarget.linkedBrowser.webNavigation.document.documentURI <<i didnt test this linkedBrowser theory but its gotta be something like that
var location = win.location + ''; //I add a " + ''" at the end so it makes it a string so we can use string functions like location.indexOf etc
if (win.frameElement) {
// Frame within a tab was loaded. win should be the top window of
// the frameset. If you don't want do anything when frames/iframes
// are loaded in this web page, uncomment the following line:
// return;
// Find the root document:
//win = win.top;
if (docuri.indexOf('about:neterror') == 0) {
Components.utils.reportError('IN FRAME - PROBLEM LOADING PAGE LOADED docuri = "' + docuri + '"');
}
} else {
if (docuri.indexOf('about:neterror') == 0) {
Components.utils.reportError('IN TAB - PROBLEM LOADING PAGE LOADED docuri = "' + docuri + '"');
}
}
}
window.gBrowser.addEventListener('DOMContentLoaded', listenToPageLoad_IfProblemLoadingPage, false);

Related

Reload Parent Window without POST

I am trying to reload a parent window (same domain) with javascript from within an iframe.
window.parent.location.href = window.parent.location.href;
does not work here for some reason (no javascript errors).
I don't believe it is a problem with same origin policy, as the following works:
window.parent.location.reload();
The problem with this option is if the last request was a POST, it gets reloaded as POST.
Any ideas why the first option wouldn't work? Otherwise, is there another method that will reload the page without resubmitting any form data (e.g. perform a fresh GET request to the parent page URL)?
I have also tried:
top.frames.location.href = top.frames.location.href;
window.opener.location.href = window.opener.location.href
and various other iterations.
I tried this code:
window.location.href = window.location.href;
in an ordinary page (no frames) and it had no effect either. The browser must detect that it is the same URL being displayed and conclude that no action needs to be taken.
What you can do is add a dummy GET parameter and change it to force the browser to reload. The first load might look like this (with POST data included, not shown here of course):
http://www.example.com/page.html?a=1&b=2&dummy=32843493294348
Then to reload:
var dummy = Math.floor(Math.random() * 100000000000000);
window.parent.location.href = window.parent.location.href.replace(/dummy=[0-9]+/, "dummy=" + dummy);
Phari's answer worked for me, with a few adjustments to fit my use case:
var rdm = Math.floor(Math.random() * 100000000000000);
var url = window.parent.location.href;
if (url.indexOf("rdm") > 0) {
window.parent.location.href = url.replace(/rdm=[0-9]+/, "rdm=" + rdm);
} else {
var hsh = "";
if (url.indexOf("#") > 0) {
hash = "#" + url.split('#')[1];
url = url.split('#')[0];
}
if (url.indexOf("?") > 0) {
url = url + "&rdm=" + rdm + hsh;
} else {
url = url + "?rdm=" + rdm + hsh;
}
window.parent.location.href = url;
}
I'm sure this could be more efficient, but works ok.

Safari print with Javascript produces blank when printing an Iframe

I have read up on all issues regarding Safari and blank printing. It seems that a white flash happens, re-rendering the page, and content of the iframe is lost before a print dialog can grab it.
Here is my javascript - It works in all browsers except safari. It brings up the dialog, but prints a blank page.
function PrintPopupCode(id) {
framedoc = document;
var popupFrame = $(framedoc).find("#" + id + '\\!PopupFrame');
var icontentWindow = popupFrame[0].contentWindow || popupFrame[0].contentDocument;
icontentWindow.focus();
icontentWindow.print();
}
function PrintPopup(id) {
setTimeout(function () { PrintPopupCode(id) }, 3000);
}
I have set a timeout, i previously read it would help if the transfer of content took sometime, but it has not helped.
I have also tried with printElement() function on the icontentWindow variable, but it does not support this method.
Print Element Method
This is all in a .js file, and not on the page. I have tried on the page, but the same thing happens.
Help?
Maybe you should try this:
function PrintPopupCode(id) {
framedoc = document;
var popupFrame = $(framedoc).find("#" + id + '\\!PopupFrame');
var icontentWindow = popupFrame[0].contentWindow || popupFrame[0].contentDocument;
icontentWindow.focus();
setTimeout(icontentWindow.print, 3000);
}
function PrintPopup(id) {
PrintPopupCode(id);
}

Page refresh goes back to home page when using History.js in ie9 and below

I've built a site that uses the History.js plugin to navigate from page to page with AJAX and update the URL accordingly. All works well except in IE; when you refresh the page it essentially loads the content from the first page you came to, not the current pages content. In "decent" browsers it doesn't load the content from any page, it just loads the entire page for that URL, which is what I IE should do.
I'm thinking it doesn't understand what to do with the hash. If you visit http://www.crownacre.voyced.com/contact-us/ it works fine, but when you visit http://www.crownacre.voyced.com/#contact-us/ (with the hash) it doesn't.
I've attempted to redirect the page if it detects a # in the pathname, but there is no way of detecting this as window.location.pathname and History.getHash() returns the path without any hash.
Any suggestions? I've seen a few websites using this plugin that have the same problem, and similar issues on here, but no solution.
Thanks in advance!
I ran into the same problem in my rewrite of tarheelreader.org. I'm using History.js and it is working fine except for the refresh issue in IE8. This hack is working for me.
In my startup code that only runs on initial page load I do:
var url = window.location.href;
if (url.indexOf('#') > -1) {
// ie refresh hack
controller.stateChange();
}
where controller.stateChange() is the state change handler I use for all History changes.
function stateChange() {
// handle changes in the URL
var hist = History.getState(),
url = hist.url,
context = hist.data;
renderUrl(url, context).then(function(title) {
document.title = title;
});
}
You can see all the code in main.js and controller.js at https://github.com/gbishop/TarHeelReaderTheme
Edit
Further exploration has lead to a case where History.js uses the initial URL instead of the root. This hack seems to handle that case.
function stateChange() {
// handle changes in the URL
var hist = History.getState(),
url = hist.url,
bar = window.location.href,
context = hist.data;
//console.log("State changed...", url, context);
if (url != bar && bar.indexOf('#') > -1) {
//console.log('bar = ', bar);
// I think we only get here in IE8
// hack for hash mode urls
var root = History.getRootUrl(),
hashIndex = bar.indexOf('#');
if (root != bar.slice(0, hashIndex)) {
// try to fix the url
url = root + bar.slice(hashIndex);
//console.log('new url =', url);
window.location.href = url;
}
}
renderUrl(url, context).then(function(title) {
document.title = title;
});
}
This worked for me:
<script>
var url = new String(document.location);
if (url.indexOf("#") > -1) {
alert("There is a Hash in the path");
}
</script>
Edit:
function LocationTest()
{
var loc = window.location;
alert(loc.href);
alert(loc.protocol + "//" + loc.host + loc.pathname + loc.search + loc.hash);
alert(loc.href == loc.protocol + "//" + loc.host + loc.pathname + loc.search + loc.hash);
}
Sample Source: window.location explained
Maybe a solution:
Can you please try the History.js unofficial version 1.8a2 of my fork from:
https://github.com/andreasbernhard/history.js
...and give feedback? Thank you very much!

Javascript from file gives Uncaught ReferenceError

I am trying to dynamically adjust the height of an iFrame on a web page depending on the content within the iFrame via some JavaScript.
My problem is when I have the script directly on the page in a <script> tag it works fine. When I stuff the code in to a separate js file and link to it- it doesn't work!
<iframe id='StatusModule' onload='FrameManager.registerFrame(this)' src='http://randomdomain.dk/StatusModule.aspx'></iframe>
<script type='text/javascript' src='http://randomdomain.dk/FrameManager.js'></script>
It gives me the error:
Uncaught ReferenceError: FrameManager is not defined
Can this really be true? Has it something to do with the page life cycle?
Ps. I guess the JavaScript code is irrelevant, as we not it works.
UPDATE: I think this might have something to do with secure http (https) and the different browsers in some weird way. I noticed that the script actually worked in Firefox. Or rather I'm not sure if its the script, or just Firefox's functionality that resizes iframes automatically depending on the content. It doesn't give me any error though.
If I then add https to the script url reference, the scripts work in IE and Chrome - but not in Firefox. Function reference error! This just got weird!
UPDATE #2: Its not a Firefox function that resizes the iframe. Its the actual script that works (without https).
UPDATE #3: The JavaScript. Works fine if I put it directly into a script tag.
var FrameManager = {
currentFrameId: '',
currentFrameHeight: 0,
lastFrameId: '',
lastFrameHeight: 0,
resizeTimerId: null,
init: function () {
if (FrameManager.resizeTimerId == null) {
FrameManager.resizeTimerId = window.setInterval(FrameManager.resizeFrames, 0);
}
},
resizeFrames: function () {
FrameManager.retrieveFrameIdAndHeight();
if ((FrameManager.currentFrameId != FrameManager.lastFrameId) || (FrameManager.currentFrameHeight != FrameManager.lastFrameHeight)) {
var iframe = document.getElementById(FrameManager.currentFrameId.toString());
if (iframe == null) return;
iframe.style.height = FrameManager.currentFrameHeight.toString() + "px";
FrameManager.lastFrameId = FrameManager.currentFrameId;
FrameManager.lastFrameHeight = FrameManager.currentFrameHeight;
window.location.hash = '';
}
},
retrieveFrameIdAndHeight: function () {
if (window.location.hash.length == 0) return;
var hashValue = window.location.hash.substring(1);
if ((hashValue == null) || (hashValue.length == 0)) return;
var pairs = hashValue.split('&');
if ((pairs != null) && (pairs.length > 0)) {
for (var i = 0; i < pairs.length; i++) {
var pair = pairs[i].split('=');
if ((pair != null) && (pair.length > 0)) {
if (pair[0] == 'frameId') {
if ((pair[1] != null) && (pair[1].length > 0)) {
FrameManager.currentFrameId = pair[1];
}
} else if (pair[0] == 'height') {
var height = parseInt(pair[1]);
if (!isNaN(height)) {
FrameManager.currentFrameHeight = height;
//FrameManager.currentFrameHeight += 5;
}
}
}
}
}
},
registerFrame: function (frame) {
var currentLocation = location.href;
var hashIndex = currentLocation.indexOf('#');
if (hashIndex > -1) {
currentLocation = currentLocation.substring(0, hashIndex);
}
frame.contentWindow.location = frame.src + '&frameId=' + frame.id + '#' + currentLocation;
}
};
window.setTimeout(FrameManager.init, 0);
UPDATE #4: Alright I did as ShadowWizard and TheZuck suggested:
<script type="text/javascript">
var iframe = document.createElement("iframe");
iframe.src = "http://www.randomdomain.dk/StatusWebModule.aspx";
iframe.width = '100%';
iframe.id = 'StatusModule';
iframe.scrolling = 'no';
if (iframe.attachEvent) {
iframe.attachEvent("onload", function () {
FrameManager.registerFrame(iframe);
});
} else {
iframe.onload = function () {
FrameManager.registerFrame(iframe);
};
}
document.getElementById('framecontainer').appendChild(iframe);
</script>
With HTTP as URL its work on IE and Firefox - not Chrome. If I set it to HTTPS it works on Chrome and IE - Not Firefox. Same error:
"ReferenceError: FrameManager is not defined".
What is going on here?
a couple of things:
I would bet on a race condition when you have two independent
resources which are supposed to be loaded concurrently. You can
easily check this by writing to log (or to document, whichever works
for you) when both finish loading (i.e. add a little script in the
iframe to dynamically add the time to the content or write to log if
you're using chrome, do that in the external script file as well,
and see if they post the time in a specific order when this fails). In your case, if the script appears before the iframe, and you don't mark it as async, it should be loaded before the iframe is fetched, so it would seem strange for the iframe not to find it due to a race condition. I would bet on (3) in that case.
Assuming there is such an issue (and if there isn't now, when you go
out into the real world it will be), a better way to do this is to
make sure both behave well in case the other loads first. In your
case, I would tell the iframe to add itself to a local variable
independent of the script, and would tell the script to check if the
iframe registered when it loads, and after that in recurring
intervals until it finds the iframe.
If the page the script is loaded into is not in the same domain
as the iframe (note that it doesn't matter where the script comes
from, it only matters what the page's domain is), (or even the same
protocol as someone mentioned here), you will not be able to access
the content so you won't be able to resize according to what the
content is. I'm not sure about the onload method, if it's considered part of the wrapping page or part of the internal iframe.
Check out this question, it sounds relevant to your case:
There's also an interesting article here about this.
I think that your frame is loaded before the script, so "FrameManager" does not exist yet when the iframe has finished loading.

Bitly API - JavaScript function to open new window

I am using a script i found here to dynamically generate short link for my Tweet buttons and it works perfectly well, but the only thing i cant seem to do is create the link to open in either a new tab or preferably a popup window.
I have tried several variations of the window.location section of the script but so far I've had no luck. If anybody could point me in the right direct I'd be very grateful.
This is the script I am using...
<script>
var TweetThisLink = {
shorten: function(e) {
// this stops the click, which will later be handled in the response method
e.preventDefault();
// find the link starting at the second 'http://'
var url = this.href.substr(this.href.indexOf('http:', 5));
BitlyClient.shorten(url, 'TweetThisLink.response');
},
response: function(data) {
var bitly_link = null;
for (var r in data.results) {
bitly_link = data.results[r]['shortUrl'];
break;
}
var tweet_text = "Text for the Tweet goes here"
window.location = "http://twitter.com/home?status=" + encodeURIComponent(tweet_text + ' ' + bitly_link + " #Hashtag1 #Hashtag2");
}
}
jQuery('.tweetlink').bind('click', TweetThisLink.shorten);
</script>
Many thanks in advance :)
Normally you could just do window.open:
window.open("http://twitter.com/home?status=" + encodeURIComponent(tweet_text + ' ' + bitly_link + " #Hashtag1 #Hashtag2");
BUT, since you are doing an ajax call before this happens, chances are that this window popup will be blocked by the browser, since the window.open command is no longer associated with the click (browsers allow a certain time before a window.open command falls under non-initiated "popup").
A solution would be to first open the window on click (in your shorten function):
var win = window.open('about:blank');
And then redirect in your response function:
win.location = 'http://twitter.com/etc...';
Demo: http://jsbin.com/usovik/1
Perhaps you're looking for
window.open("http://example.com");

Categories