aFarkas / html5shiv

This script is the defacto way to enable use of HTML5 sectioning elements in legacy Internet Explorer.
http://paulirish.com/2011/the-history-of-the-html5-shiv/
9.88k stars 2.56k forks source link

Incompatibility with Highcharts #21

Closed dmnd closed 12 years ago

dmnd commented 12 years ago

When html5shiv is present on a page, Highcharts charts render in grey. See this forum post for more details.

superohm commented 12 years ago

Hi,

All my highchart graph was down.... Did you have any idea when you can fixed this trouble ?

Regards, Guillaume

dmitry-ivanov commented 12 years ago

Hello!

Would it be fixed soon? And where can I get an old version which is stable with highcharts?

Thanks.

patrickberkeley commented 12 years ago

I'm seeing this issue too.

aFarkas commented 12 years ago

@maindgit and others

I can not give any timeframe, but we are working on this.

Until then, you can use the older version 2.2 or can try the innerShiv-branch, which might become next version

patrickberkeley commented 12 years ago

Thanks @aFarkas. Highcharts works with html5shim v2.2.

aFarkas commented 12 years ago

@patrickberkeley

could you also try the innerShiv-branch? It should also work and like I sayed, I want to become this version the next version.

dmitry-ivanov commented 12 years ago

@aFarkas, thanks. I've checked "older version 2.2" and "innerShiv-branch" both - and the're both work correctly with highcharts.

PS: can you plz comment here when the trunk version (http://html5shiv.googlecode.com/svn/trunk/html5.js) would also supply them?...

patrickberkeley commented 12 years ago

@aFarkas the innerShiv-branch works with highcharts too.

superohm commented 12 years ago

@aFarkas thanks a lot

romanbsd commented 12 years ago

Is innerShiv-branch considered production ready?

aFarkas commented 12 years ago

@romanbsd

Yes this branch can be considered as production ready. The only problem with this is, that this version removes a great feature automatically fixing dynamic HTML5 creation (This is why some tests are failing) and I can not say, wether this will be the next version.


I really would like to have some opinion about this especially from @jonathantneal, @paulirish, @jdalton and @rwldrn.

To sumarize our current issues and how the innerShiv helps:

Performance

I think we can improve current performance and make the current implementation 2-3 times faster, but it will be always 10-20 times slower than unshived implementation (I could live with this, simply because I don't think, that this would generate a botttleneck).

Generated DOM-element does not behave right

For example: a shived DOM element currently has always a document fragment as a parentNode, although it should be null. This happens simply by touching element.document.

var elem = document.createElement('div');
elem.parentNode; //-> null
elem.document;
elem.parentNode; //-> bam: document fragment

I haven't found a way to remove the parentNode or create a shived element without a parent.

The innerShiv branch simply removes our automatic fixing features and provides a simple API to create DOM object from a string using. This way, we can guarantee, that html5shiv won't break anything and still comes with a solution for dynamically generating HTML5 elements.

What do you guys think?

paulirish commented 12 years ago

also ping @remy and @jdbartlett

The html5shiv with both print-protection and createElement duckpunch has been live through the 2 google code project since dec 22nd. (modernizr is still not touching createElement)

I'm actually surprised we havent had more reports of issues... So due to that, I'm kind of thinking keeping the createElement|Fragment duckpunches is okay.

redoPop commented 12 years ago

I agree with @paulirish -- the innerShiv branch is important for these edge cases, but the createElement duckpunch makes the innerHTML fix more accessible to devs and causes surprisingly few issues, so I think it's worth keeping in the mainline.

aFarkas commented 12 years ago

Ok, this means:

I work on improving performance next days. + We need a solution for those people having those issues. Which should be an optout configuration.

Something like:

html5shiv.noDynamic = true;

Do you have any suggestions on naming this option?

remy commented 12 years ago

What's the actual code in highcharts trigging this issue?

I'm just wary that adding a config option may be overlooked and a developer would just get stuck looking at grey charts.

(I can see a counter argument btw)

On 24 Jan 2012, at 23:09, Alexander Farkas wrote:

Ok, this means:

I work on improving performance next days. + We need a solution for those people having those issues. Which should be an optout configuration.

Something like:

html5shiv.noDynamic = true;

Do you have any suggestions on naming this option?


Reply to this email directly or view it on GitHub: https://github.com/aFarkas/html5shiv/issues/21#issuecomment-3642545

jonathantneal commented 12 years ago

I too would love to know what's actually causing the problem.

redoPop commented 12 years ago

+1 opt-out configuration! How about:

html5shiv.fixDomMethods = false;
remy commented 12 years ago

I can see all kinds of dumb with this, but it's kinda useful

html5shiv.compatibilityMode = true;

It's suitable vague and allows you to fix things in the future too.

On 24 Jan 2012, at 23:19, joe bartlett wrote:

+1 opt-out configuration! How about:

html5shiv.fixDomMethods = false;


Reply to this email directly or view it on GitHub: https://github.com/aFarkas/html5shiv/issues/21#issuecomment-3642722

jonathantneal commented 12 years ago

For performance we could cut documentCreateElementReplaceFunction and change the way we shiv a document to not use replace and use a for loop. This would remove a function, a join, and a replace; and add a for loop.

for (var i = 0, l = html5.elements.length; i < l; ++i) {
    documentCreateElement(html5.elements[i]);
}
aFarkas commented 12 years ago

I can not point you to the exact code of highcharts, but the following commit fixes this issue.

@jonathantneal

Yeah, I made a performance test on this and this makes html5shiv significant faster. We can also split the shivDocument into to parts. shivDommethods and shivHoleDocument, with this we won't search for head element so often.

jonathantneal commented 12 years ago

Alex, your commit basically tells the shiv not to shiv a element. Should we maintain a list of unshiv-worthy elements or is this a very specific patch for a very specific element?

From what Google tells me, <fill> is a VML element. So, if IE is having issues with shived VML elements then we could either create a list of elements we will not fill or have some kind of detection for VML elements.

remy commented 12 years ago

Initially I'm thinking it feels wrong to maintain a list of unshivable elements - but on the heavy other hand, this is the /only/ bug raised on the new shiv.

Arguably if it kills the issue - and there's no more or a very limited number of additions, as clunky as it might seem, I think it's the right move.

On 24 Jan 2012, at 23:31, Jonathan wrote:

Alex, your commit basically tells the shiv not to shiv a element. Should we maintain a list of unshiv-worthy elements or is this a very specific patch for a very specific element?


Reply to this email directly or view it on GitHub: https://github.com/aFarkas/html5shiv/issues/21#issuecomment-3642892

jonathantneal commented 12 years ago

VML elements may also respond to a check of tagUrn.

if (element.canHaveChildren && element.tagUrn !== 'urn:schemas-microsoft-com:vml') {
    html5.shivDocument(element.document);
}
remy commented 12 years ago

If that's the bad boy causing all this fuss, then I like it.

I was thinking whether this might affect SVG, but at the same time, SVG isn't supported in IE below 9 - which doesn't need the html5 shiv - so ... we're okay?

aFarkas commented 12 years ago

My checkin was stupid, did the exact opposite, of what I thought. tagUrn is always an empty string inside of the highcharts demo.

I will look deeper into this issue. Beside this, we have the optout. I have called it fixDomMethods, but I'm open to change it.

jonathantneal commented 12 years ago

You've made the two files so different and now I don't have time to clean this up. I want it cleaned up badly.

jdalton commented 12 years ago

1) I don't think the populated parentNode concern is a big one.

If you work with IE at all you know of its issues:

<p id="foo">Hello World</p>
<script>
var elem = document.createElement('div');
var before = elem.parentNode;
elem.document;
var after = elem.parentNode;

// alerts smth like [ null, [object], null ] in IE < 9
alert(['' + before, '' + after, '' + elem.parentElement]);

var elem = document.getElementById('foo');
before = elem.parentNode;
document.body.removeChild(elem);
after = elem.parentNode;

// alerts smth like [ [object], [object], null ] in IE < 9
alert(['' + before, '' + after, '' + elem.parentElement]);
</script>

and should know that elem.parentElement is a better check of if the element has a parent node in cases where it matters.

jdalton commented 12 years ago

2) Has anyone contacted Highcharts as this may be a bug on their part?

I haven't worked much with VML so take this with a grain of salt, but when I have and in all the snippets I've quickly Google'd where other devs create VML elements a namespace, like v:, is used:

// something like this
doc.createElement('<rvml:' + tagName + ' class="rvml">');
// or
doc.createElement('<' + tagName + ' xmlns="urn:schemas-microsoft.com:vml" class="rvml">');
// or this
function pushElement( name ) {
  var attrs = me[ attrsPrefix + name ];
  if( attrs ) {
    m.push( tagStart + name );
    pushAttrs( attrs );
    m.push( subElEnd );
  }
}
var nsPrefix = 'pievml';
var tagStart = '<' + nsPrefix + ':';
var m = [ tagStart, tag, ' id="', me.elId, '" style="', me.getStyleCssText(), '" ', me.defaultAttrs ];
pushAttrs( me[ attrsPrefix ] );
m.push( '>' );
pushElement( 'fill' );
m.push( '</' + nsPrefix + ':' + tag + '>' );
var result = m.join( '' );

(also I did some basic tests in IE8 and a namespace was required to get the fill to render as well)

jdalton commented 12 years ago

3) We should add unit tests for creating elements like document.createElement('<div>') which is allowed in IE < 9.

jdalton commented 12 years ago

Here is a post referencing errors creating fill and stroke elements in IE before the HTML5shiv update: (though no details on how to recreate the error)

patrickberkeley commented 12 years ago

@jdalton Here's the link to the Highcharts forum post on this issue. It's gotten no love.

jdalton commented 12 years ago

So I dug into this and Highcharts is doing smth like:

document.createElement('<stroke color="black" opacity="0.1" xmlns="urn:schemas-microsoft-com:vml"  style="display:inline-block;behavior:url(#default#VML);"/>');

Simply replacing the element.document.createElement and restoring it is enough to break it.

element.document.createElement = [element.document.createElement, element.document.createElement=function(){}][0];

@aFarkas' patch checking for xmlns and tagUrn should be alright as the element will have one or the other. Though it could be simplified to just:

if (html5.fixDomMethods && element.canHaveChildren && !(element.xmlns || element.tagUrn)){
  html5.shivDom(element.document);  
} 

to avoid other potential gotchas.

jdalton commented 12 years ago

Here is a page to experiment with: http://jsbin.com/esihak

paulirish commented 12 years ago

Sweet. afarkas commited a fix in c993fe02582fb1e05ed6cabeaad3160f75fa89a3 then shorted it with jdalton's help: aaeb7da4de048e7d963a1eabb94d533b88adb683

Lastly added a test in 65f83d89ca5a4e7d3abdb25c7c78b841562a1a85 and closed the issue. Boom, lookin good.

Thanks everyone!