<?xml version="1.0" encoding="ISO-8859-1"?>
<rss version="2.0">
	<channel>
		<title>Blog</title>
		<link>http://www.sitecrafting.com/blog/browser-bugs/</link>
		<description></description>
		<language>en-us</language>
		<pubDate>Wed, 16 May 2012 23:22:03 PDT</pubDate>
		<lastBuildDate>Wed, 16 May 2012 23:22:03 PDT</lastBuildDate>
		<generator>SiteCrafting.com GearBox 1.1 (beta)</generator>
		
		<item>
			<title>Strange Behavior with Opera 9 and Safari</title>
			<link>http://www.sitecrafting.com/blog/strange-behavior-opera-9-safari/</link>
			<description>While I was working on the latest site for Airstream, I came on some extremely weird behavior concerning the navigation. First off, the designers did an extremely good job with the visuals. On the other hand, I had to be really creative to figure out how to make various parts of the site work.Here's some background for how the navigation was supposed to work: there are five sections to the site, and each section has sub sections that show up in the navigation bar, depending on what your current location is. Navigation and sub-navigation. Also, the navigation area has a graphical background that can't change. Since the PNG spec isn't fully supported by IE yet, we had to go with GIF or JPG graphics. Here's what it is supposed to look like (and what we ended up with):Initially, I had decided to put all the navigation data on each page.  Each navigation section would have the section image, and a div for the  sub-navigation. The sub-navigation would be set to display: none; unless the parent div had the class active, when it would be display: inline;#nav_list div {&amp;nbsp;&amp;nbsp; &amp;nbsp;float: left;&amp;nbsp;&amp;nbsp; &amp;nbsp;border-right: 2px dotted #555;}#nav_list div div&amp;nbsp; {&amp;nbsp;&amp;nbsp; &amp;nbsp;display: none;&amp;nbsp;&amp;nbsp; &amp;nbsp;border: none;&amp;nbsp;&amp;nbsp; &amp;nbsp;padding: 0;&amp;nbsp;&amp;nbsp; &amp;nbsp;margin: 0;}#nav_list div.active .subnav {&amp;nbsp;&amp;nbsp; &amp;nbsp;display: inline;&amp;nbsp;&amp;nbsp; &amp;nbsp;margin: 0;&amp;nbsp;&amp;nbsp; &amp;nbsp;padding: 0;&amp;nbsp;&amp;nbsp; &amp;nbsp;margin-top: -140px;&amp;nbsp;&amp;nbsp; &amp;nbsp;height: 141px;&amp;nbsp;&amp;nbsp; &amp;nbsp;width: 241px;&amp;nbsp;&amp;nbsp; &amp;nbsp;background: url('../images/nav_background_off.gif') repeat-y 30px;&amp;nbsp;&amp;nbsp; &amp;nbsp;margin-left: 6px;&amp;nbsp;&amp;nbsp; &amp;nbsp;border-right: 2px dotted #555;}There were a few issues that came up while creating the site that related to this CSS,  such as if the overall height of the sub-navigation was zero (the sum  of the margin and height), the layout breaks. I didn't understand at  the time why this was happening, but after going to An Event Apart  Seattle, I can see why it happens. (A zero height means that an item  doesn't exist. This might be an interesting way to show and hide  elements...)Anyhoo, this all worked fine in Firefox while I was developing it. IE was another issue, but IE is an issue in itself.  (The active sub-nav item has a lime background, so it's easier to see what I'm talking about.)When I went to test this site in Safari and Opera, the craziness started to happen. Here's what it looked like in Opera:And here's Safari:The strangest part of this behavior is that both Opera 9 and Safari have passed the ACID 2 test, and yet here they have totally different results. Fixing this didn't involve any CSS  trickery, it actually ended up being somewhat less-than-elegant.  Because I didn't have to be too concerned about the page resizing  (fixed width design), I simply set position: absolute; on the active .subnav. This forced it to start at a specific location, rather than where ever it pleased. I am guessing that the .subnav was set to display: block; although I didn't specifically define it. Setting the it to position: relative;  may have worked as well, but I didn't try it. I'm really curious to  find out why Opera 9 and Safari behaved so differently with the same CSS and HTML, and why Firefox was able to render the CSS as expected.</description>
			<pubDate>Mon, 09 Oct 2006 11:31:00 PDT</pubDate>
		</item>
			
		<item>
			<title>The &lt;select&gt; Tag and innerHTML</title>
			<link>http://www.sitecrafting.com/blog/ltselectgt-tag-innerhtml/</link>
			<description>While I was working on a recent project, I ran into a weird bug with IE 6. I was using some AJAX to dynamically fill a &amp;lt;select&amp;gt; tag with options depending on what element was selected from the tag's parent. It worked fine, and quite seamlessly in Firefox, but broke for inexplicable reasons in IE.I was using a php script to get all the selectable options, and then passing that back to the javascript handler to be inserted into the document. The problem was that, apparently, you can't use the .innerHTML property to set content on a select tag.This makes no sense, for two reasons: 1) Microsoft created the innerHTML property, and it doesn't work in their software and 2) All you really need to do is find the node, and replace it's children with some abritrary string. It's not terribly complicated. Every other (modern) browser seems to handle it perfectly fine.After Mark had pointed out that fact, I just used the php script to return an entire select element with the options already populated, but that broke the event listener I had placed on the tag to change the select options for that select's children. But that was quick and easy to fix: just reload the event listener on the completion of the AJAX call.I've gotten to the point that most browser inconsistencies don't really faze me. I know what to expect and how to work around it, but this one really threw me for a loop. So, take note developers, &amp;lt;select&amp;gt; + innerHTML = broken. But you should really be using the DOM anyways.</description>
			<pubDate>Wed, 13 Dec 2006 16:12:00 PST</pubDate>
		</item>
			
		<item>
			<title>Safari and PNG Headaches</title>
			<link>http://www.sitecrafting.com/blog/safari-png-headaches/</link>
			<description>I just finished coding a new photography contest application for a client, and our graphic designer alerted me to some weirdness that Safari has with PNG images. To make a long story quite short, Safari doesn't translate PNG colors to match CSS colors reliably; it darkens them just a bit. The details are beyond me, so instead check out this article for those, and you can see an example in this image. The example labeled &quot;Your Version&quot; is the Safari rendering, and the box labeled &quot;Our Version&quot; is the Firefox rendering.For you, this means that you shouldn't use PNG images where color matching is important, use GIF instead. However, if PNG use becomes more widespread, hopefully the treatment of PNG images by browsers and OSs will become more standard and can replace GIFs - which have fewer colors and larger filesizes.</description>
			<pubDate>Fri, 16 Mar 2007 10:48:00 PDT</pubDate>
		</item>
			
		<item>
			<title>Onload Collisions and How to Fix them</title>
			<link>http://www.sitecrafting.com/blog/onload-collisions-to-fix/</link>
			<description>There is no other variable more fought over then the coveted window.onload. Its job is to run a function after a page has been loaded. The problem is that there is only one variable, and therefore only one function can run. Once you have set this you would think you are in the clear. That is until another script comes in and overwrites onload.But all can be made well in JavaScript land once one of four choices is made. I give four ways to get around this problem, and suggest a way for modern browsers to be rid of this problem once and for all.JavaScript, love it or hate it, it's here to stay. In the last generation of web design it was abused to accomplish silly things like turning your mouse into a analog clock or, my favorite, change the color of the background depending on where your mouse was on the page (I almost had a seizure when I first saw that one).Since then we have learned to separate our pages into three parts: Information (HTML), Presentation (CSS), and Function (JS). The latter is where I have found my niche in recent years. The web is now flooded with JavaScripts that do everything. Most of which require the page to be loaded before doing any work. This isn't an issue because there is a variable aptly named window.onload. To make a function run after the page has loaded, you just assign it to this variable.And there in lies the problem: there is only one variable. Only the last script that assigns to this variable will run successfully. In the past this generally wasn't an issue because you were the author and rarely had mismanaged conflicts. But times have changed.With only one onload variable what are we to do. Well, I have discovered 4 options: check and wrap it, make onload an array, wrap onload with a function, make onload a function that sends an event. Each of these have their pros and cons. I'll discuss them briefly below.Check and WrapThis method is a quick check to see if anything is already set to run onload. If there is, then you create a function that first runs what ever was in the onload, then does what ever you need it to. It should look something like this:if(window.onload != undefined) {&amp;nbsp;&amp;nbsp; &amp;nbsp;var tempFunct = window.onload;&amp;nbsp;&amp;nbsp; &amp;nbsp;window.onload = function() {&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;tempFunct();&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;yourFunction();&amp;nbsp;&amp;nbsp; &amp;nbsp;}} else window.onload = yourFunction;The advantage of this is that there is that you don't have to rewrite any old code, nor do you have to load any code before had. But the downsides are numerous. First, if you find yourself with a dozen onloads, then you will be in a very deep chain of functions, and that will slow things down. Also, if your tempFunct variable is overwritten then a link in the chain is broken, and nothing after it will run. Lastly, if someone changes the onload variable after you, your whole chain is gone.Onload ArrayAs a way of getting around these problem, I believe that modern browsers should allow onload to be an array of functions. The browser could then iterate over the array, running every function it encounters. This would allow for many more functions to get access to this crucial resource. I came up with a quick way to accomplish this now in preparation for browser integration.window.onload = function() {&amp;nbsp;&amp;nbsp; &amp;nbsp;for(var key in onload.functs)&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;onload.functs[key]();}onload.functs = [];onload.push = function(funct) {&amp;nbsp;&amp;nbsp; &amp;nbsp;onload.functs.push(funct);}This would give the onload variable the ability to have the push method to add functions. To add a function, you would use:onload.push(yourFunction);// ORonload.push(function() {&amp;nbsp;&amp;nbsp; &amp;nbsp;yourFunction();});Simple, isn't it? This fixes most of the cons in the check and wrap method, but still have some problems. If another script still uses the old onload method then, again, the whole chain is broken.Onload WrapperThe major problem with the Onload Array is legacy code messing up your functions. You could update your code, but that is a lot of work. So there is the thrid method, the onload wrapper. This is very similar to the onload array in the sense that it stores functions in an array and pulls them out using onload. But the difference is that you call a function to add it to the onload. This function can then detect if old code has overwritten the onload variable. The code is as follows:var onDomReady = function(funct) {&amp;nbsp;&amp;nbsp; &amp;nbsp;if(window.onload != onDomReady.run) onDomReady.functs.push(window.onload);&amp;nbsp;&amp;nbsp; &amp;nbsp;onDomReady.functs.push(funct);&amp;nbsp;&amp;nbsp; &amp;nbsp;window.onload = onDomReady.run;}onDomReady.run = function() {&amp;nbsp;&amp;nbsp; &amp;nbsp;for(var key in onDomReady.functs)&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;if(onDomReady.functs[key]) onDomReady.functs[key]();}onDomReady.functs = [];To use this method you:function onLoadKiller() {&amp;nbsp;&amp;nbsp; &amp;nbsp;alert('onload killer');}onload = function() {&amp;nbsp;&amp;nbsp; &amp;nbsp;alert('onload');}onDomReady(function() {&amp;nbsp;&amp;nbsp; &amp;nbsp;alert('onDomReady');});onload = onLoadKiller;onDomReady();The code above will display three alert boxes. The first one is caused because the onload variable is set to a function that created the 'onload' alert. The onDomReady function then adds both the onload (the 'onload' alert) and the 'onDomReady' alert. Then the onload gets overwritten by onLoadKiller. We take that pecky guy out by running the onDomReady() function again, which fixes the chain. (And all is well in JS land)This gets around all the set backs of the first two methods, except that, again, setting that pesky onload variable will blow out your chain. Luckily, this code has a way to get around that by simply rerunning the onDomReady() function without any parameters. This will allow you to insert this line of code where ever you find a colision and it will repair the chain. There is always a downside, namely that if two places set onload consecutively without a onDomReady() in-between, the first will be lost.Event Driven OnloadThe final method uses something completely different for the onload. Rather then setting this variable, you attach a function to an event (the 'load' event). This gives you the ability to add multiple functions to onload without collisions. Events are exactly how Prototype and other frameworks deal with onload. The downside is again that the change will require a rewrite of old code, and there for isn't much better then the first two.Browser ImprovementsAs I hinted at earlier, I believe we need a way to natively allow more functions to run onload. The easiest way I see to accomplish this is to allow the onload variable to be an array, and run every function associated with it. While this wouldn't fix some of the problems in old scripts, it would be a way to move foreward and allow many more scripts to be run concurently within the browser.ConclusionSo what's a scripter to do? There is no good answer for this. Each situation is different. Below I break it down into which category each method is useful for.If you are starting your code base from scratch, I would suggest the Onload Array. This would give fall-foreward compatibility and would start to pressure browser makers to include this kind of onload scheme.If you already have a code base, but know it fairly well, then the Onload Wrapper is a good option. It is the most forgiving when breaking the chain, and will repair itself as much as possible.If you have a large code base, and really don't know how things interact, then the check and wrap is a good choice. It will protect your little chunk of code while preserving anyone else's (assuming you are tagging on to the end of the chain).Lastly, if you are writing a script from scratch, and it needs to interact with an unknown environment, then your best bet is to go event driven. It's like taking a higher path where you don't monkey around with those lesser scripts still using the onload variable.</description>
			<pubDate>Tue, 22 Jul 2008 16:41:00 PDT</pubDate>
		</item>
			
		<item>
			<title>Styling Inputs is Hard</title>
			<link>http://www.sitecrafting.com/blog/styling-inputs-hard/</link>
			<description>  Internet Explorer 6 is just too old to support all the fun CSS tricks of the modern web. The Input Type selector is one of the most problematic. I suggest a quick jQuery function to get around this.  Styling inputs is a pain. The input element has several different types, all of which are displayed in completely different ways. Briefly, they are:    Text   Password   Checkbox   Radio As you can see, setting the width of all input elements will have unintended consequences for some input types. There are some common tricks to get around this. One is to add a special class to text and password boxes. Another is to use a CSS2 selector &quot;input[type=password], input[type=text] { (css) }&quot;. The problem with this last method is Internet Explorer 6 doesn't support it. So what are we to do?I created a script that will iterate though all input elements and append it's type to the class attribute. While this is a bit dirty, it does give us the ability to style these elements separately from each other without leaving IE6 in the dust.$(function() {    $('input').each(function() {&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $(this).addClass(this.type);&amp;nbsp;&amp;nbsp;&amp;nbsp; });});</description>
			<pubDate>Mon, 19 Jan 2009 14:35:00 PST</pubDate>
		</item>
			
		<item>
			<title>Percentage Width Margin Table IE Bug</title>
			<link>http://www.sitecrafting.com/blog/percentage-width-margin-table-ie/</link>
			<description>Internet Explorer has its share of bad bugs. IE6 in particular is well known for it laundry list of CSS bugs. While troubleshooting some code for a newsletter I discovered a rather&amp;nbsp;bizarre&amp;nbsp;one. After testing, I found that it affects everything from IE6 to the recently released IE8. It is mostly just for fun because the chances of running into it are pretty slim.The HTML looks something like this:&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;div style=&quot;width: 100%;&quot;&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;p style=&quot;margin-left: 100%&quot;&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Content&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/p&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;The structure of this bug is a table cell with a block-level element inside with a css width of a percentage. Inside that is another block-level element with a margin as a percentage. The table cell, for some reason, expands to more then a million pixels. In the code above, nothing can be added to fix this problem (i.e., body width, table width, cell width, or any combination). Changing the width or margin to any percentage only changes the scale of the&amp;nbsp;extremely&amp;nbsp;large table cell. Switching from margin to padding doesn't seem to fix it either.&amp;nbsp;Interestingly enough, changing the margin-left to margin grows the table cell both height and width. Or, if the width is changed to a height, it still expands.&amp;nbsp;        I don't know a great deal of the inner workings of Trident (IE's layout system), but my guess is that some how the table cell is given a huge width when a margin is detected and then attempts to size itself like elastic to its contents. This would cause the div to see that the width is very large and set it's pixel size accordingly. But, this is nothing other then a guess. Does anyone have any better&amp;nbsp;hypothesis? Post your thoughts below.</description>
			<pubDate>Mon, 27 Apr 2009 18:35:00 PDT</pubDate>
		</item>
			
		<item>
			<title>Adobe's BrowserLab Goes Live</title>
			<link>http://www.sitecrafting.com/blog/adobes-browserlab-goes-live/</link>
			<description>  It is an unfortunate fact of internet life that not all browsers are made equal. Pages viewed in Firefox may look completely different in Internet Explorer or Safari. Most developers consider this a very frustrating part of the development process, and often wish there was an easier way to test things out. Enter Adobe's BrowserLab. Given a publicly accessible URL, BrowserLab will generate full-size images that depict how a given page will appear in various browsers.  The free service Browsershots and the paid service Litmus also attempt  to address this need, but Adobe's offering is the first to bring  together both a well-designed interface and a price tag of $0.One of the most useful features of BrowserLab are the viewing options available. Aside from the standard 1-up view (viewing the page with a single browser) a 2-up view is also available. This will render a page in two browsers of your choice side-by-side and will even lock scrolling to make it easier to compare the two.The &quot;Onion Skin&quot; view is the third option, which is a unique view that will lay one browser's view over another. This view comes with a slider that allows you to transition from one browser to the other. If you want everything consistent down to the last pixel, this is going to be your favorite.While the selection of available browsers is not comprehensive, it does cover the most common use scenarios which is acceptable for most cases. Opera and Google Chrome are the most obvious omissions from the list. While not a deal-breaker for me, it is something to be aware of if compatibility with browsers is important for your project. Another shortcoming is that, being images, you cannot interact with the page being tested. This means that testing for JavaScript and CSS events is not possible.Adobe's offering is very compelling, and currently holds the crown, at least in my opinion, for the most effective cost-free option for testing multiple browsers. It's sleek interface, viewing options, and reasonable selection of browsers make it a snap to ensure your site looks consistent across the board.</description>
			<pubDate>Fri, 23 Oct 2009 08:30:00 PDT</pubDate>
		</item>
			
		<item>
			<title>jQuery and Cufon Don't Mix!</title>
			<link>http://www.sitecrafting.com/blog/jquery-cufon-dont-mix/</link>
			<description>When using Sizzle (the selector engine in jQuery 1.3+, Prototype 1.7+, dojo, and others) and Cufon together, you need to make sure that your selectors are excluding Cufon elements. Internet Explorer 7 and Internet Explorer 8 both have a bug that cause Sizzle to break for some selectors with VML elements. I'll describe the problem, and some simple fixes, after the break.We recently ran into a strange JavaScript error in IE 7 and 8 where the browser would inexplicably fail, and give no indication as to why. After some in-depth analysis of Sizzle and jQuery, it turns out that our font replacement script caused Sizzle to fizzle out.The ProblemCustom fonts have always been a pain. There's plenty of ways to do it, which I won't go over here. One solution is a script called Cufon. With the use of javascript, simple things like headers and banners can be easily converted into the font of your choice. To do this, the javascript replaces the text with those vector graphics (SVG or VML) that show up on the page as new HTML entities (actually they aren't quite HTML, more on that later).Sizzle is a very powerful framework that looks up elements using CSS selectors. We've talk a lot about it here on this blog, though we usually do so in the context of jQuery. It's selectors give Sizzle considerable power over how to manipulate elements. As an example, lets quickly dive into the &quot;:text&quot; selector. Below is some fake code to show kind of what it does.function getTextElements(parent)&amp;nbsp; {&amp;nbsp;&amp;nbsp; &amp;nbsp;var elems = (parent || document).getElementsByTagName('*');&amp;nbsp;&amp;nbsp; &amp;nbsp;var elem;&amp;nbsp;&amp;nbsp; &amp;nbsp;var text = [];&amp;nbsp;&amp;nbsp; &amp;nbsp;for(var i = 0, len = elems.length; i&amp;lt; len; i += 1) {&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;elem = elems[i];&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;if('text' === elem.type) {&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;text.push(elems[i]);&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&amp;nbsp;&amp;nbsp; &amp;nbsp;}&amp;nbsp;&amp;nbsp; &amp;nbsp;return text;}The real Sizzle is more complicated, so I've simplified it here. But the core of the problem is within this code. The offending line is &quot;'text' === elem.type&quot;. If you want to view this in Sizzle, it's located on line 524, here.The IE7+8 bug occurs when asking a VML object for a property that has not been defined. Because Cufon uses VML in IE7+8, any time a Cufon generated element leaks into a Sizzle form selector, it will break. What's worse, this error is very difficult to detect. The browser puts out a generic error code 0 with a equally generic message of &quot;Failed&quot;. Who would think a common selector would break a popular browser like IE7 or IE8?What is Affected?Which selectors are affected? Any selector that uses undefined VML properties. That is pretty much all of the input selectors. But here's a list: (with jQuery 1.4.2 error codes):enabled (Line: 82, Char: 168, Error: Failed, Code: 0):text (Line: 83, Char: 18, Error: Failed, Code: 0):radio (Line: 83, Char: 59, Error: Failed, Code: 0):checkbox (Line: 83, Char: 104, Error: Failed, Code: 0):file (Line: 83, Char: 148, Error: Failed, Code: 0):password (Line: 83, Char: 192, Error: Failed, Code: 0):submit (Line: 83, Char: 238, Error: Failed, Code: 0):image (Line: 83, Char: 281, Error: Failed, Code: 0):reset (Line: 83, Char: 323, Error: Failed, Code: 0):button (Line: 83, Char: 366, Error: Failed, Code: 0)The FixSo what do we do about this? Oddly enough, the fix is a performance trick. In the example above, just be specific about what element tags you are looking for. Since &quot;:text&quot; only applies to inputs, you can use &quot;input:text&quot; instead. This will yield the same results, but will do so with much quicker lookups. This is because the browser can use the native getElementsByTagName to get the specific tags. My example code is changed below.function getTextElements(parent) {&amp;nbsp;&amp;nbsp; &amp;nbsp;var elems = (parent || document).getElementsByTagName('input');&amp;nbsp;&amp;nbsp; &amp;nbsp;var elem;&amp;nbsp;&amp;nbsp; &amp;nbsp;var text = [];&amp;nbsp;&amp;nbsp; &amp;nbsp;for(var i = 0, len = elems.length; i&amp;lt; len; i += 1) {&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;elem = elems[i];&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;if('text' === elem.type) {&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;text.push(elems[i]);&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&amp;nbsp;&amp;nbsp; &amp;nbsp;}&amp;nbsp;&amp;nbsp; &amp;nbsp;return text;}The code is almost the exact same, except now elems doesn't include things like divs, spans, paragraphs, or those pesky VMLs. Since those can't be text inputs anyways this is a considerable speed up. Generally speaking, it is a good idea to use an ID, then tag name, before any other selectors as a way to narrow down the elements before the heavy lifting by the selector engine.I reported this to the Sizzle group two months ago, but unfortunately they haven't fixed it yet. Since these are both widely used libraries, I'm doing a write up on this to help other developers avoid this disastrous and obscure issue. If you find more selector errors like this with Cufon (or VML in general), let me know and I'll add it to the list. I suspect, but have not tested, that other VML based libraries are susceptible to the same bug (like the various canvas libraries).Update: (2010-07-14)After digging into this further, it turns out there are a bunch more selectors that will bomb in IE 7 and 8. I've reported it here. Here's just a few:.class (Line: 80, Char: 316, Error: Failed, Code:   0)[name=name] (Line: 88, Char: 381, Error: Failed, Code:   0)* (Line: 91, Char: 437, Error: Failed, Code:   0)[style] (Line: 86, Char: 381, Error: Failed, Code:   0)It turns out just about every attribute selector bombs (a class is just a fancy attribute). This is really bad new for anyone who uses Cufon. My recommendation is to only use Cufon on non IE browsers. Luckily, IE has long supported custom fonts in other ways.If this post was helpful to you please help pass the word by liking it, thanks all!</description>
			<pubDate>Thu, 29 Apr 2010 10:30:00 PDT</pubDate>
		</item>
			
		<item>
			<title>Objects and Params and Embeds, Oh My!</title>
			<link>http://www.sitecrafting.com/blog/objects-params-embeds-oh-my-1/</link>
			<description>  The newest Firefox update (3.6.9) sees object tags as a security threat. That means bad news for Fx users that use an outside source, such as a popup window, to embed video or script into their site content.    Since the recent Firefox update (3.6.9), a strange thing happened to our video and script embedding tools. Firefox has deemed the object tag a security threat and will now strip all the tags commonly used for embedding scripts and video inside of a rich text editor (RTE). That includes the following tags: object, param and embed.We did find a small workaround for up-to-date Firefox users to embed objects. Since the stripping process is somewhere in the submission process of our popup window inserting the script, we can force the object tag in the source. Basically, the short term solution is to embed the code in &quot;view source&quot; mode of any RTE and stay away from any fancy, external interface for more easily inserting these elements. But never fear, a long term solution is in the works when we can gather more details about this update.Perhaps this is Firefox's way of nudging developers to use more of the HTML5 specific tags, like the video tag. Are we going to find some of our other legacy tags disappearing in the near future? What say you?Link to Mozilla.org Security Advisory 2010-61  </description>
			<pubDate>Fri, 10 Sep 2010 16:25:00 PDT</pubDate>
		</item>
			
		<item>
			<title>Browser Cache and Multiple Tabs</title>
			<link>http://www.sitecrafting.com/blog/browser-cache-multiple-tabs/</link>
			<description>  While writing a PHP script this weekend I ran into an interesting   problem. The script watches for an empty text file to be filed with   text. It does this with a sleeping loop and compares the file size every   second or so. This works really well for one browser tab. But when I   had two tabs, in parallel, the second one wouldn't display anything   until the previous one had completed. So I wrote up the following test   case.  $i = 10;while(--$i) {&amp;nbsp;&amp;nbsp; &amp;nbsp;echo &quot;$i&quot;;&amp;nbsp;&amp;nbsp; &amp;nbsp;flush();&amp;nbsp;&amp;nbsp; &amp;nbsp;sleep(1);}echo &quot;Done&quot;;This will count down from 10 to 0, then echo &quot;Done&quot;. The flush() command will send the current HTML to the browser, giving it a chance to render the content it's been sent so far.When running this on a single tab it worked as expected. With two tabs open, the second one would remain blank until the first tab had completed the count down. Then the second tab would display the count down all at once. So what's happening?After a little research, and some talk around the office, it turns out the browser does some odd things when loading the same page on two tabs. IE, Chrome, and Safari all have the same behavior. Each tab/window is independent and load separately. Firefox does this also, except the second tab waits for the first one to load before loading itself (sometimes pulling from cache, sometimes downloading anew). Opera does something completely strange. It keeps the two windows synced, such that giving a gap of a few seconds between tab refreshes still show the same point in the count down.Each browser has it's own way of handling multiple tabs with the same address, and there is no clear standard on what the behavior should be. From a developer stand point, I think IE and Webkit (Safari and Chrome) have it correct. Keeping the two tabs separate makes the most sense and this behavior makes the developer have to worry less about parallelism (race cases, timing, rendering issues, etc.).Browser Versions tested:Firefox 3.6.11Opera 10.63Chrome 7.0.517.41Safari 5.0.2Internet Explorer 6, 7, 8 So how do you think the browsers should behave in these cases?</description>
			<pubDate>Mon, 25 Oct 2010 10:40:00 PDT</pubDate>
		</item>
			
		<item>
			<title>Don't call IFrames bad names!</title>
			<link>http://www.sitecrafting.com/blog/dont-call-iframes-bad-names/</link>
			<description>Internet Explorer has a long history of trying to do their own thing. They meet most standards, but always implement their own. One of these non-standard features is how IE handles the NAME property. Here are two examples of how this breaks:The first is a long know &quot;feature&quot; that usually is forgotten when troubleshooting. Here's what happens. Let's say you have the following code block. What would you expect document.getElementById('description') would return in IE?&amp;lt; html&amp;gt;&amp;lt; head&amp;gt;&amp;lt; meta name=&quot;description&quot; value=&quot;a demo&quot; /&amp;gt;&amp;lt; body&amp;gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt; form&amp;gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt; textarea id=&quot;description&quot; name=&quot;description&quot;&amp;gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt; /form&amp;gt;&amp;lt; /body&amp;gt;&amp;lt; /html&amp;gt;If you said textarea, you'd be wrong. That's what all other browses return, but IE has decided that it with return the meta description tag instead. You may run into the me problem with anything with the ID of keywords. The second issue is one that took two hours of solve yesterday. Our Rich Text Editor uses an iframe as a way to prevent memory leaks and encapsulate it's special code in a secure way. We created the following code on one site. What side effect does this code have?&amp;lt; html&amp;gt;&amp;lt; head&amp;gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt; script src=&quot;rte.js&quot;&amp;gt;&amp;lt; body&amp;gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt; form&amp;gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt; iframe name=&quot;body&quot; src=&quot;rte.html&quot;/&amp;gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt; /form&amp;gt;&amp;lt; /body&amp;gt;&amp;lt; /html&amp;gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;Turns out, this changes document.body to the iframe. Is that strange or what? It will see that a iframe is named body, and will create a shortcut to it through the document object. What this breaks is any call to document.body.appendChild(), or document.body.innerHTML. It also makes the following possible.&amp;lt; iframe name=&quot;getElementById&quot;/&amp;gt;IE has just mapped document.getElementById to your new iframe. Now, all JavaScript that requires the use of this function is completely broken. Doesn't that seem crazy?As a helpful guide, here are some of the ID and NAME values you want to stay away from: (important ones are in bold)META tag name conflicts: (bad ids)descriptionkeywordsauthorgeneratorrevisedcopyrightdistributionprogidratingresource-typerevisit-afterrobotsAny custom meta tag names...document property conflicts: (bad iframe names)namespaceslastModifiedonstorageparentNodeonstoragecommitnodeTypefileCreatedDateonbeforeeditfocusbgColoroncontextmenuonrowexitembedsscriptsonactivatemimeTypealinkColoronmousemovecompatibleonselectstartoncontrolselectbodyprotocolonkeypressonrowenteronmousedownvlinkColorURLonreadystatechangedoctypeonbeforedeactivateappletsfileModifiedDateonmouseoverdirmediadefaultCharsetfirstChildpluginsonafterupdateondragstartoncellchangecookiedocumentElementnextSiblingnamePropreferrerondatasetcompleteonmousewheelonerrorupdateonselectionchangelastChildondblclickonkeyuplocationformstitleonrowsinsertedpreviousSiblingcompatModeonmouseuponkeydownonrowsdeletedocumentModeonfocusoutfgColorondatasetchangedonmouseoutparentWindownodeNameonpropertychangeonstoponhelplinkColoronbeforeactivateimagesreadyStateframesallonbeforeupdateonclickchildNodesonfocusinanchorsselectionfileUpdatedDatedomainsecurityfileSizeownerDocumentondataavailablestyleSheetsnodeValueattributesactiveElementimplementationlinksURLUnencodedondeactivate</description>
			<pubDate>Mon, 15 Nov 2010 12:03:48 PST</pubDate>
		</item>
			
		<item>
			<title>Attributes and Casing</title>
			<link>http://www.sitecrafting.com/blog/attributes-casing/</link>
			<description>Internet Explorer just doesn't like to play well with others. Case in point: I was working on some JavaScript using jQuery where I noticed a strain bug. My data attributes were camel casing differently in Firefox and IE7. So I loaded up Chrome and saw it matched Firefox. I'm sure you can see where this is going. So here's the issue:Given the following HTML: (spaces added)&amp;lt; div data-elem-ID=&quot;1&quot;&amp;gt;&amp;lt; /div&amp;gt;Internet Explorer returns the innerHTML in a non-normalized way: (Link to test code)          
                            
                              
                            
&amp;nbsp;Browser                            
&amp;nbsp;innerHTML                            
&amp;nbsp;attribute[0].name                            
&amp;nbsp;jQuery.data()                                
                 
                            
&amp;nbsp;IE8 (and lower)                            
&amp;nbsp;&amp;lt; DIV data-elem-ID=&quot;1&quot;&amp;gt;&amp;lt; /div&amp;gt;                            
&amp;nbsp;data-elem-ID                            
&amp;nbsp;elemID                              
                            
&amp;nbsp;IE9+                            
&amp;nbsp;&amp;lt; div data-elem-ID=&quot;1&quot;&amp;gt;&amp;lt; /div&amp;gt;                            
&amp;nbsp;data-elem-ID                            
&amp;nbsp;elemID                              
                            
&amp;nbsp;Others                            
&amp;nbsp;&amp;lt; div data-elem-id=&quot;1&quot;&amp;gt;&amp;lt; /div&amp;gt;                            
&amp;nbsp;data-elem-id                            
&amp;nbsp;elemId      JavaScript is strict about it's casing, and this one character difference is enough to make the property undefined. In our case, I am going to suggest developers follow the spec and use lowercase names for HTML5 data- attributes. This will bypass the browser inconsistency completely. On the plus side, the jQuery Data function normalizes this problem for you, so you don't have to worry about it.As a side note, while looking into this I found a bug in the latest jQuery (1.6.4). Looks like there is a regression where the jQuery.data() function returns an empty object in IE. I have reported it here.    
Update 2011-09-30:    
The jQuery team closed the bug as it's considered spec. HTML5 data-* attribute requires the attribute to be in all lower case. So the code above is invalid HTML5. That said, it is still processed by the browsers and will give you trouble. Stay safe and keep your attributes in lower case.
        </description>
			<pubDate>Wed, 28 Sep 2011 09:27:00 PDT</pubDate>
		</item>
			
	</channel>
</rss>
		
