IE 8 (ONLY) crashes with JavaScript / jQuery calls to plugins - javascript

I'm in need of some help.
I'm building a team bio page it keeps crashing IE8 when I call jQuery plugins.
I'm not sure what is going on and can't even run the IE debugger because it crashes so hard.
Any IE8 / jQuery experts out there willing to take a look and offer some help?
Here is the main team page. Clicking through to any of the links causes the crash in IE8.
I am using:
jQuery Tagsphere, AnythingSlider, and jQuery Cycle.
Thanks in advance for any insight into this.

I had a similar problem, most notably closing iframes with IE8. Stumbled across the following code in jquery-1.6.2, which was intended to solve problems with document.domain. Some comments on the web lead me to believe this was a recent problem. Dropped back to jquery-1.4.4 and the problem was resolved.
CODE SEGMENT FROM JQUERY-1.6.2 FOLLOWS:
// #8138, IE may throw an exception when accessing
// a field from window.location if document.domain has been set
try {
ajaxLocation = location.href;
} catch( e ) {
// Use the href attribute of an A element
// since IE will modify it given document.location
ajaxLocation = document.createElement( "a" );
ajaxLocation.href = "";
ajaxLocation = ajaxLocation.href;
}

Related

Controlling a Firefox Extension via Javascript

Is it possible, using javascript, to control an overlay firefox extension? I've extracted the contents of the extension and have identified what functions/methods I need to run, but they are not accessible within the scope of the console.
Thanks in advance for any ideas.
Yes it possible to interact with other add-ons, given the right circumstances.
My test case here will be com.googlecode.sqlitemanager.openInOwnWindow(), which is part of the SqliteManager addon.
In newer builds (I'm using Nightly), there is the Browser Toolbox. With it is is as simple as opening a toolbox and executing com.googlecode.sqlitemanager.openInOwnWindow() in the Console.
You may instead use the Browser Console (or any chrome enabled WebDev Console for that matter, e.g. the Console of "about:newtab"). But you need some boilerplate code to first find the browser window. So here is the code you can execute there: var bwin = Services.wm.getMostRecentWindow("navigator:browser"); bwin.com.googlecode.sqlitemanager.openInOwnWindow()
Again, enable chrome debugging. Then open a Scratchpad and switch to Chrome in the Environment menu. Now executing com.googlecode.sqlitemanager.openInOwnWindow() in our Scratchpad will work.
You may of course write your own overlay add-on.
As a last resort, patch the add-on itself.
Bootstrapped/SDK add-ons: you can load XPIProvider.jsm (which changed location recently) and get to the bootstrapped scope (run environment of bootstrap.js) via XPIProvider.bootstrapScopes[addonID], and take it from there (use whatever is in the bootstrap scope, e.g. the SDK loader).
Now about the right circumstances: If and how you can interact with a certain add-on depends on the add-on. Add-ons may have global symbols in their overlay and hence browser window, such as in the example I used. Or may use (to some extend) JS code modules. Or have their own custom loader stuff (e.g. AdBlock Plus has their own require()-like stuff and SDK add-ons have their own loader, which isn't exactly easy to infiltate)...
Since your question is rather unspecific, I'll leave it at this.
Edit by question asker: This is correct, however I figured I'd add an example of the code I ended up using in the end, which was in fact taken directly from mozilla's developer network website:
In my chrome js:
var myExtension = {
myListener: function(evt) {
IprPreferences.setFreshIpStatus(true); // replace with whatever you want to 'fire' in the extension
}
}
document.addEventListener("MyExtensionEvent", function(e) { myExtension.myListener(e); }, false, true);
// The last value is a Mozilla-specific value to indicate untrusted content is allowed to trigger the event.
In the web content:
var element = document.createElement("MyExtensionDataElement");
element.setAttribute("attribute1", "foobar");
element.setAttribute("attribute2", "hello world");
document.documentElement.appendChild(element);
var evt = document.createEvent("Events");
evt.initEvent("MyExtensionEvent", true, false);
element.dispatchEvent(evt);
Update for Firefox 47 and up
Things changed drastically in Firefox 47. This is the new way to access it.
var XPIScope = Cu.import('resource://gre/modules/addons/XPIProvider.jsm');
var addonid = 'Profilist#jetpack';
var scope = XPIScope.XPIProvider.activeAddons.get(addonid).bootstrapScope
Old way for < Firefox 47
Update for methods of today
Typically you will do so like this:
If i wanted to get into AdBlocks scope, I check AdBlock id, it is {d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d} so I would go:
var XPIScope = Cu.import('resource://gre/modules/addons/XPIProvider.jsm');
var adblockScope = XPIScope.XPIProvider.bootstrapScopes['{d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}'];
You can now tap into anything there.
Another example, I have an addon installed with id NativeShot#jetpack
I would tap into it like this:
var XPIScope = Cu.import('resource://gre/modules/addons/XPIProvider.jsm');
var nativeshotScope = XPIScope.XPIProvider.bootstrapScopes['NativeShot#jetpack'];
if you do console.log(nativeshotScope) you will see all that is inside.

Cannot access document's title element with jQuery (IE 8)

I'm seeing this issue in Internet Explorer 8, but not in Safari or Firefox. So far, I have not tested in other IE versions.
I am developing my own jQuery plugin and, for this question, I've stripped it down to the two relevant lines.
In IE 8, using the code below, $('title').text() does not do anything. docTitle is blank because title is blank, as if the jQuery selector for <title>, $('title') is not working. (Again, AFAIK, this is just in IE 8)
(function ($) {
$.fn.myPlugin = function (options) {
var title = $('title').text(),
docTitle = escape(title);
};
})(jQuery);
http://jsfiddle.net/sparky672/YMBQ2/
However, using the plain JavaScript code below, document.title is working fine in everything including IE 8...
(function ($) {
$.fn.myPlugin = function (options) {
var docTitle = escape(document.title);
};
})(jQuery);
EDIT:
It does not matter that this code is inside a plugin.
Same result in IE 8 with this...
$(document).ready(function () {
var title = $('title').text();
alert(title);
});
Just to clarify, I am not insisting on using this. In fact, I fixed my plugin by simply using document.title instead. If it wasn't clear initially, I'm just asking why this does not work in IE 8.
Can anyone explain why, or what stupid mistake I may have made here?
EDIT 2:
Here are some jQuery Bug reports on this issue
http://bugs.jquery.com/ticket/7025
http://bugs.jquery.com/ticket/5881
http://bugs.jquery.com/ticket/2755
And dozens of others reporting the same thing. The official response is to state, "document.title is the only reliable cross-browser way and should be used instead" and the Ticket is closed. So there you go.
I guess jQuery iterates over all TextNodes and concatenates its nodeValue. IE stores this value differently than other browsers.
var title = document.getElementsByTagName('title')[ 0 ];
title.firstChild // This would be the Text-Object with the characterdata of the title
// Firefox: [object Text]
// IE: null
This should be the reason you cannot get the textContent with jQuery.text(). title.text seems to be cross browser comp. I only tested it in IE 7 and Firefox 3.6 but you can check the other browser if you like. But why not using document.title?
try using $('title').html() which should work in all browsers

What other options for replacing entire HTML document via W3C DOM?

I am curious about people's experiences with replacing the entire document at runtime in an Ajax web app. It's rare, but I've found a few situations where the app requires an entire page rebuild and everything is present locally without needing another server round-trip.
I can easily prepare the new document as either a new DOM tree or as a String. So I'm evaluating the trade-offs for various approaches.
If I want to use the String approach this seems to work:
document.open();
document.write(newStringDoc);
document.close();
Most browsers do this just fine, but many have a slight flicker when re-rendering. I've noticed that on the 2nd time through Firefox 4.0b7 will just sit there and spin as if it is loading. Hitting the stop button on the location bar seems to complete the page render. (Edit: this appears to be fixed in 4.0b8) Also this method seems to prevent the user from hitting refresh to reload the current URL (it reloads the dynamically generated page).
If I use a new DOM tree approach (which has different advantages/disadvantages in flexibility and speed), then this seems to work:
document.replaceChild(newDomDoc, document.documentElement);
Most browsers seem to handle this perfectly fine without flicker. Unfortunately, IE9 beta throws "DOM Exception: HIERARCHY_REQUEST_ERR (3)" on replaceChild and never completes. I haven't tried the latest preview release to see if this is just a new bug that got fixed. (Edit: this appears to be fixed in RC1.)
My question: does anyone have a different approach than either of these? Does anyone have any other caveats where perhaps a particular browser fundamentally breaks down with one of these approaches?
Update: Perhaps this will add context and help the imagination. Consider a situation where an application is offline. There is no server available to redirect or refresh. The necessary state of the application is already loaded (or stored) client-side. The UI is constructed from client-side templates.
I believe that Gmail uses iframes embedded within a root document. It appears the starting document for at least some of these iframes are just a bare HTML5 document which the parent document then manipulates.
Using an iframe would be another variant on the requirement to replace the current document by replacing the entire child iframe or just its document. The same situation exists though of what approach to attach the new document to the iframe.
I guess I will answer this with my own findings as I'm wrapping up my research on this.
Since the two browsers which have issues with one of these methods are both beta, I've opened bug reports which hopefully will resolve those before their full release:
Firefox 4 Beta: https://bugzilla.mozilla.org/show_bug.cgi?id=615927
Edit: Fixed in FF 4b8.
Internet Explorer 9 Beta: https://connect.microsoft.com/IE/feedback/details/626473
Edit: Fixed in IE9 RC1.
I've also found pretty consistently that this...
document.replaceChild(newDomDoc, document.documentElement);
...is 2-10x faster than this...
var doc = document.open("text/html");
doc.write(newStringDoc);
doc.close();
...even when including the time needed to build the DOM nodes vs. build the HTML string. This might be the reason for the flicker, or perhaps just another supporting argument for the DOM approach. Chrome doesn't have any flicker with either method.
Note the subtle change of storing the returned document which circumvents the bug in Firefox 4.0b7.
Also note this added MIME type which the IE docs claim is "required".
Finally, Internet Explorer seems to have a bit of trouble resolving link tags that were built before the new document is swapped in. Assigning the link href back to itself appears to patch it up.
// IE requires link repair
if (document.createStyleSheet) {
var head = document.documentElement.firstChild;
while (head && (head.tagName||"") !== "HEAD") {
head = head.nextSibling;
}
if (head) {
var link = head.firstChild;
while (link) {
if ((link.tagName||"") === "LINK") {
link.href = link.href;
}
link = link.nextSibling;
}
}
}
One could cover all bases and combine them like this...
var doc = document;
try {
var newRoot = newDoc.toDOM();
doc.replaceChild(newRoot, doc.documentElement);
// IE requires link repair
if (doc.createStyleSheet) {
var head = newRoot.firstChild;
while (head && (head.tagName||"") !== "HEAD") {
head = head.nextSibling;
}
if (head) {
var link = head.firstChild;
while (link) {
if ((link.tagName||"") === "LINK") {
link.href = link.href;
}
link = link.nextSibling;
}
}
}
} catch (ex) {
doc = doc.open("text/html");
doc.write(newDoc.toString());
doc.close();
}
...assuming you have the ability to choose your approach like I do.

Why does TinyMCE require typing something before being able to use the delete key properly?

I have just implemented TinyMCE and it is working fine, except that the user must type something, even a space character, before being able to delete content.
Please tell me if you need more information.
It's a browser bug. There is a hacky workaround I've seen and used in the past; I can't verify it at the moment. If you call the following once the TinyMCE editing iframe has loaded, it may work:
// doc is a reference to the iframe's document
try {
doc.execCommand("Undo", false, false);
} catch (ex) {}
Indeed it is a browser bug (almost FF). My workaround for this resets the design mode:
editor_instance = tinymce.EditorManager.getInstanceById(editor_id); //editor id needed here (ed.id)
editor_instance.getDoc().designMode = 'Off';
editor_instance.getDoc().designMode = 'On';

IE 6/7 Access Denied trying to access a popup window.document

I'm creating a popup window with no URL source using window.open(). I don't give it a URL because soon I'll want to post a form to it. However, in the meantime I'd like to display a short "Now loading..." message so the user isn't looking at a blank page for the 2-3 seconds it'll take the form post to go through.
I tried adding Javascript that just writes to the popup window's document. That worked great in Firefox and IE 8, but failed with an Access Denied message in IE 6 and 7. Anyone know of a way around this? I would love to be able to a) hard-code some HTML into window.open(), b) learn how to update the popup's DOM in this situation, or c) hear about anything anyone can think of.
Below is the code I'm using to spawn the window:
var wref = window.open("", winName, "toolbar=1,resizable=1,menubar=1,location=1,status=1,scrollbars=1,width=800,height=600");
if (wref != null) {
try {wref.opener = self;} catch (exc) {}
// while we wait for the handoff form post to go through, display a simple wait message
$j(wref.document.body).html('Now loading …'); // EPIC FAIL
wref.focus();
IE considers "about:blank" to be a insecure URL and it won't let you talk to it. I would create a "Now Loading..." static HTML file and open that instead.
Test
<script type="text/javascript">
function test() {
window.open('javascript:opener.write(window);', '_name', 'width=200,height=200');
}
function write(w) {
w.document.write("Hello, World.");
}
</script>
Works in IE 6, 7 & 8, Opera 9.6, Firefox 2 & 3.
Does not work in Safari for Windows 3 & 4 or Google Chrome.
When it does work, it results in a pretty ugly URL in the Location box.
If the browser support listed above is acceptable, you can use the solution provided, otherwise I'd do what David said and window.open('Loading.htm' ...) where Loading.htm contains whatever content you want to display (you should probably keep it lightweight otherwise it might take longer to load and render than the form will to POST).
Also note that the winName you supply in IE must NOT have spaces... if so it will fail.
Another workaround is to open an empty "blank.htm" file on your site, then do the document.open() to access it

Categories

Resources