Site Navigation

Monday, October 29, 2007

bug 104 - resize event firing errors in IE on Maximize or Restore

Issue: #104
Affects: IE5, IE5.5, IE6, IE7, IE8 Beta 1, IE8 Beta 2, IE8 PR1, IE8 RC1
Partially Fixed in: IE7 & IE8* (see details below)
Fixed in: IE9 RC 1 (in IE9 standards mode only)

The resize event when applied to the window, will fire when the browser is resized.

In IE, it fires continually while stretching a window, and in other browsers only when the dragging stops and a new window size is set. (this isn't the bug, just a minor difference in the way each browser works)

The bug, is that IE will fire multiple resize events for a single resize of the browser, when Maximizing or Restoring the window.

In IE6, a Maximize or Restore window setting will trigger 3 (three!) resize events.

You can do this by right-clicking the task bar and choosing from the context menu, or by double-clicking the title bar of the browser.

In IE7, they fixed this! Well, not quite. In IE7, it now fires 2 (two!) resize events. Well, I suppose that 1 invalid resize event, is better than 2 invalid resize events, but suffice to say, there is still a significant bug here. This incorrect behavior is still seen in IE8 builds up until IE8 RC1.


Example:

<script>
window.onresize = function(){
alert('resizing: Offset: ' +
document.body.offsetWidth + ', ' +
document.body.offsetHeight +
'\nScroll: ' +
document.body.scrollWidth + ', ' +
document.body.scrollHeight);
};
</script>



Known Workarounds: None. If you need to ensure that a function is called only once for this kind of resize, you may want to store the current width and height dimensions as variables, then onresize, compare them against the stored size. If they are both a match, ignore the event. (e.g. there was no resize)


Related Issues: None.

Saturday, October 27, 2007

bug 109 - JavaScript prompt() in IE - How did this not get fixed in IE7?!

Issue: #109
Affects: IE5, IE5.5, IE6, IE7, IE8, IE9 PP1, IE9 PP2, IE9 PP3, IE9 PP4, IE9 RC 1
Note this issue affects all versions of IE, but any version of IE below 5 is ignored.
Status: Microsoft has confirmed this will NOT be fixed in IE8 RTM

MSIE Feedback ID: 333954

The JavaScript prompt() method has been in Web Browsers that support JavaScript since day 1. The concept is simple. Provide a modal dialog, that displays a message, and allows the user to input a value.

Example: (from Firefox)

prompt() dialog in Firefox 2 on Windows XP

prompt() dialog in Firefox on Windows 95/98/98SE/ME/2000

You've seen a "prompt" dialog of one kind or another in almost every windowed computer application in existance. It is by far, the easiest way to "halt" current activities, and ask the user for a value.

Unfortunately, this dialog, the "3rd trickiest" of the (only 3) available JavaScript dialogs in the web browser, is horribly broken... in fact, it hasn't even been patched once since its original design, made available in 1995! (That's 12 years ago for those without calculators!)




So, how is it broken?


  1. Display position is wrong, and awkward

  2. Button display is inconsistant with other dialogs

  3. The text input box is extremely large (redundanly so)

  4. The dialog does not scale

  5. The message in the dialog gets truncated

  6. The dialog does not declare the hostname of the site that launched it

  7. Did we mention that it is ugly?

  8. Whats with the title and the "script prompt" line?

  9. Where is the icon for this message box?

  10. Oh, and it doesn't handle DBCS (Double Byte Character Sets)

  11. (bug 139) - It doesn't center on the browser window



Try it yourself! Create new folder

Compare it with the alert() and confirm() dialogs

Now lets take a look at each of those closely:

1 Display Position

If every other utility dialog appears nicely centered in the browser display, why does the prompt dialog appear about 50px from the top left corner of the screen? How is this consistant? Would this not likely cover the most important content on the screen below, such that the first thing a user would need to do is move it to see what the prompt is related to?

2 Button Display

What is with the odd right-aligned stacked OK/Cancel buttons? Is this typically used anywhere else in Windows? No! So why does this dialog need to differ? What happened to consistancy for the user?

3 Text Input Box Size

Are users expected to write a novel in this dialog? What if the prompt is "How many books would you like to order?" This input suggests that only numbers in the {Seventy trillion billion...} are expected. We don't think that the text box should be small, but this box is like 1/3 to 1/2 the screen size!

4 Dialog does not scale

If you have a large message, the dialog doesn't stretch to accomodate it, like the alert() or confirm() dialogs do. Considering that scaling was implemented for these 2 dialogs, would it not have occured as an important consideration when designing the prompt dialog?

5 Hostname not declared

This is a new feature of modern web browsers, designed to help alert users to any odd XSS (Cross Site Scripting) hacks that might get them to divulge sensitive information. AFAIK, Opera was the first to have this, with Mozilla Firefox following suit. Developers were quite confused when IE7 shipped without adding this simple security feature.


6 The message in the dialog gets truncated

prompt() dialog in IE7 on Windows XP

prompt() dialog in IE 5/6 on Windows 95/98/98SE/ME/2000

This (due in part because of #4 above) is the biggest issue. Presenting any message other than "How many", or "What is your name" requires some thought because if your message is anything longer than a quick sentence, the content will get truncated!

7 Ugly. Just plain ugly

Normally a feature being ugly doesn't count as a bug, but in this case I disagree. Since the dialog does look ugly, and has not changed in 12 years, it highlights that this browser (now in version 7) hasn't been given the attention it needs and is not up to par with modern browsers.


8 Title / message

Why is the title "Explorer User Prompt" instead of "Microsoft Internet Explorer"?
What is the "Script Prompt" all about?
This dialog is not very user friendly.

9 Missing message box icon

Standard message boxes (mini dialogs) like this in Windows have an icon. The .alert() dialog has an exclamation icon, the .confirm() dialog has a question mark icon etc. So where is the question mark icon for the prompt dialog?

Sample dialogs:


Firefox .alert();

Firefox .confirm();

Firefox close tabs dialog

Yet another IE dialog with an icon

10 No support for DBCS (Double Byte Character Sets
You can see this article on MSDN for more details, but there is no realistic workaround available.

As Web Developers build their sites and applications (which are getting more and more complex) it never ceases to amaze them that such a simple borwser feature has been given such neglect.


Example:

<script type="text/javascript">
prompt('You need to enter a name for this new mailbox.\n' +
'Please ensure that it does not contain spaces quotes or the percent symbol.\n' +
'You can change the name at a later time if desired.','Friends');
</script>



Known Workarounds: None. You can attempt to simulate a dialog, for user input using floating elements above the page, however you will need to build the entire "dialog" and will have to add code to enable draging etc.


Related Issues: None.

bug 245 - setAttribute "style" does not work in IE

Issue: #245
Affects: IE6, IE7

As discussed in bug 242, IE does not allow using the DOM Method .setAttribute( name, value ); for many attributes. Some just don't work, other throw errors. For the style attribute IE just ignores the request.

Example:

<script type="text/javascript">
var myObj = docuement.getElementById('myDiv');
myObj.setAttribute('style', 'border:1px dashed #663399;font-weight:bold;');
</script>


You can access each individual style property and set them seperately using DOM 0 techniques (Basically the IE4 way), or you can use the workaround listed below.


Known Workarounds: One. Set the style property's .cssText value when dealing with IE.

Example Workaround Code:

<script type="text/javascript">
var myObj = docuement.getElementById('myDiv');
//use browser sniffing to determine if IE or Opera (ugly, but required)
var isOpera, isIE = false;
if(typeof(window.opera) != 'undefined'){isOpera = true;}
if(!isOpera && navigator.userAgent.indexOf('Internet Explorer')){isIE = true);

var styleData = 'border:1px dashed #663399;font-weight:bold;';
if(!isIE){
//use the correct DOM Method
myObj.setAttribute('style', styleData);
} else {
//use the .cssText hack
myObj.style.setAttribute('cssText', styleData);
}
</script>



Related Issues: bug 242.

Friday, October 26, 2007

bug 341 - the button element submits the wrong value in IE

Issue: #341
Affects: IE5, IE5.5, IE6, IE7
Fixed in: IE8 Beta 1

The button element in HTML, just like an input element (of type button) is designed (by spec) to submit the contents of the value attribute when it is pressed to submit a form. However in Internet Explorer, this functionality is broken as it submits the innerHTML of the button element rather than the contents of the value attribute.

Example:

<button value="true_content" name="doAction">
<span style="font-weight:bold;">Please</span> click <em>Me</em>!
</button>


If a user clicked this button, the server should get a parameter called "doAction" with a value of "true_content". IE on the other hand, will return the same parameter, with the value ' <span style="font-weight:bold;">Please</span> click <em>Me</em>!'.


Known Workarounds: None. See MSDN for the latest news on when the button element will be fixed.


Related Issues: bug 101.

Wednesday, October 24, 2007

bug 235 - createElement is broken in IE

Issue: #235
Affects: IE6, IE7

According to the DOM specs for ECMAScript, adding an input field should be as easy as the code snippet below.

Example:

<script type="text/javascript">
var myNewField = document.createElement('input');
myNewField.setAttribute('name', 'tags');
//set any other attributes...
//add to the DOM
document.getElementsByTagName('form')[0].appendChild( myNewField );
</script>


However, if you try this in IE, it will "appear" to work, until you submit the page, or attempt to query the field by name.

IE (for reasons unknown) did not set the name attribute. (seriously, try it!)

The solution is exposed in this MSDN article, whereby IE allows a (horribly) invalid parameter to the createElement() method to get around this bug.


Known Workarounds: One.

You will need to determine if the current browser is IE, then, execute the applicable createElement call.

Example Workaround Code:

<script type="text/javascript">
//use browser sniffing to determine if IE or Opera (ugly, but required)
var isOpera, isIE = false;
if(typeof(window.opera) != 'undefined'){isOpera = true;}
if(!isOpera && navigator.userAgent.indexOf('Internet Explorer')){isIE = true);

var myNewField = null;
if(!isIE){
myNewField = document.createElement('input');
myNewField.setAttribute('name', 'tags');
} else {
myNewField = document.createElement('<input name="tags"/>');
}
//set any other attributes...
//add to the DOM
document.getElementsByTagName('form')[0].appendChild( myNewField );
</script>




Related Issues: bug 242, bug 237.

Wednesday, October 17, 2007

bug 256 - DOM nodeType constants are not in IE and Opera

Issue: #256
Affects: IE5, IE5.5 IE6, IE7, IE8, Opera 8.2, Opera 9.2
Fixed in: Opera 9.50 alpha 1 build 9500
MSIE Feedback ID: 339307
Status: Microsoft has confirmed this will NOT be fixed in IE8 RTM

The ECMAScript specification for the DOM provides a set list of element types or nodeTypes... Text Elements, Node Elements, Comments, etc. They are numbered integers, with a Constant defined for easy to read comparison purposes. The only problem is, that they are not Constants at all, in IE or Opera.

NodeTypes:

interface Node {
// NodeType
const unsigned short ELEMENT_NODE = 1;
const unsigned short ATTRIBUTE_NODE = 2;
const unsigned short TEXT_NODE = 3;
const unsigned short CDATA_SECTION_NODE = 4;
const unsigned short ENTITY_REFERENCE_NODE = 5;
const unsigned short ENTITY_NODE = 6;
const unsigned short PROCESSING_INSTRUCTION_NODE = 7;
const unsigned short COMMENT_NODE = 8;
const unsigned short DOCUMENT_NODE = 9;
const unsigned short DOCUMENT_TYPE_NODE = 10;
const unsigned short DOCUMENT_FRAGMENT_NODE = 11;
const unsigned short NOTATION_NODE = 12;
//...
}


Example:

<script type="text/javascript">
var obj = document.getElementById('someID');
var textContent [];
for(var i=0;i<obj.childNodes.length;i++){
if(obj.childNodes.item(i).nodeType == TEXT_NODE){
textContent.push( obj.childNodes.item(i) );
}
}
alert('The inner text without HTML tags is: ' + textContent.join(', '));
</script>


In a spec compliant browser, the code should be able to test against the TEXT_NODE constant.


Known Workarounds: One. It is extra processing, but each element type can be defined as globals at the begining of every page.

Example Workaround Code:

<script type="text/javascript">
(function(){
var NodeTypes = ['ELEMENT', 'ATTRIBUTE', 'TEXT', 'CDATA_SECTION',
'ENTITY_REFERENCE', 'ENTITY', 'PROCESSING_INSTRUCTION',
'COMMENT', 'DOCUMENT', 'DOCUMENT_TYPE',
'DOCUMENT_FRAGMENT', 'NOTATION'];
for(var i=0i<NodeTypes.length;i++){
window[NodeTypes[i] + '_NODE'] = (i + 1);
}
})();
</script>



Related Issues: None.

Tuesday, October 16, 2007

What If? - DOM Method Improvements

What If?

"Missing Methods" in the ECMAScript specification.

Having a complete specification for ECMAScript's DOM manipulation is great, however in time (as with any API) you yearn for some additional features.

IMHO, these methods would be great additions to the current spec.

Additions:

Object Element
getElementsByTagName(name, depth)
This method returns a NodeList.
The name parameter is of type DOMString.
The depth parameter is of type unsigned long.

With the optional depth parameter, developers can request what level of nesting they specifically wish to return.
If omitted, zero or negative, the default behavior of all matching child nodes is returned.

If requested, only elements at the requested level would be returned.

Example:
var allChildCells = myTable.getElementsByTagName('td');
var directCells = myTable.getElementsByTagName('td', 1);
var grandChildCells = myTable.getElementsByTagName('td', 2);

getElementsByClassName(class)
It is already on the way in HTML 5 (Web Applications 1.0)!
Better yet, it is real! Firefox 3 already has it!
And so does Opera 9.5!
And so does WebKit!

Object Node
insertAfter(newChild,refChild)
This method returns a Node.
The newChild parameter is of type Node.
The refChild parameter is of type Node.

Similar to the insertBefore method, except the newChild is inserted
after the refChild in the DOM tree.


Object NodeList
remove(index)
This method returns a NodeList.
The index parameter is of type unsigned long.

When a NodeList is returned from a method like .getElementsByTagName(name) it is
often desired to "filter" out undesired items.
Currently this is only possible by "casting" to an Array (a.k.a. iterate over the
NodeList and copy to an Array)



Ok, so not exactly a browser bug... but some interesting ideas.

What do you think? What methods would you add/modify?


Have your say!

bug 124 - setting innerHTML problem no.1 in IE

Issue: #124
Affects: IE6, IE7, IE8 Beta 1, IE8 Beta 2, IE8 PR1

Setting the .innerHTML in IE can fail in the following scenario.
If you add multiple lines of content (e.g. with line beaks) to an empty element with the overflow set to auto.

Example:

<div id="test" style="border:1px solid #ff0000;height:200px;overflow:auto;">before</div>
<script type="text/javascript">
var divObj = document.getElementById('test');
divObj.innerHTML = 'first<br/>second<br/>third';
</script>


You would expect to see the div content update to display:

first
second
third


However IE will update the DOM, but not the content on screen. IE doesn't update the visible height of the DIV, resulting in the "second, and third" not showing.


Known Workarounds: None.


Related Issues: None.

Thursday, October 4, 2007

bug 142 - appendChild doesn't work on a script tag in IE

Issue: #142
Affects: IE6, IE7, IE8 Beta 1, IE8 Beta 2, IE8 PR1, IE8 RC1

Using the DOM to generate elements is ideal, but when you want to generate a script tag, you can't use the DOM in IE.

Example:

<script type="text/javascript">
var scriptTag = document.createElement('script');
scriptTag.appendChild( document.createTextNode('var now = new Date();alert(now.getTime());') );
var bodyTag = document.getElementsByTagName('body')[0];
bodyTag.appendChild( scriptTag );
</script>


In all browsers except IE, this will append a script element to the page, with code as the content.


Known Workarounds: One. For IE, we have to divert from the spec., and use the .text property instead.

Example Workaround Code:

<script type="text/javascript">
var scriptTag = document.createElement('script');
scriptTag.text = 'var now = new Date();alert(now.getTime());';
var bodyTag = document.getElementsByTagName('body')[0];
bodyTag.appendChild( scriptTag );
</script>



Related Issues: None.