Skip to content

IE9 fixes - to make SVG maps compatible #1332

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Feb 1, 2017
Merged

IE9 fixes - to make SVG maps compatible #1332

merged 9 commits into from
Feb 1, 2017

Conversation

alexcjohnson
Copy link
Collaborator

A bunch of random fixes for IE9 behavior, only one was actually in maps, oddly enough (so some edge cases may have been broken in other plot types too), but all of which are accessed by maps.

  • classList
  • instanceof d3.selection -> seems to work for built-in types and some user-defined types, but for some reason d3.selection broke it, replaced with duck typing
  • console[fn].apply - I guess these aren't regular functions in IE9, so if there's no apply just call the function once for each argument.
  • When an invalid attribute value is provided, IE9 throws an error rather than just using a default value. Choropleth with no explicit line width was trying to set undefinedpx via drawing.dashLine, which in all other browsers silently defaulted to 1px. I made this explicit at the supplyDefaults level, while at the same time defaulting to 0px in dashLine so this can't cause further problems.

cc @chriddyp @etpinard

Given the scattered nature of these fixes, it's probably worthwhile to have someone spend some time manually trying out more plots & behaviors, ideally on a real local copy of IE9 rather than Browserstack. I saw some sporadic glitches with drag interactions, including one where it seemed like the hover effects were pointing to the old point locations... but couldn't reproduce so I'm concerned it was just an artifact of tunneling through Browserstack.

if(node.type === 'MemberExpression') {
var parts = node.source().split('.');
if(parts[parts.length - 1] === 'classList') {
logs.push(file + ' : contains .classList (IE failure)');
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was hoping eslint would have an option for IE compatibility (actually not even IE11 supports classList on SVG elements, apparently)... but I don't see one, so I added it in here. Confirmed that before the change I made to modebar.js it failed this test.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great idea!

function consoleFn(name, hasApply, messages) {
var out = function() {
var args = [];
for(var i = 0; i < arguments.length; i++) args.push(arguments[i]);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because toEqual doesn't think arguments is a regular array

@@ -112,6 +112,7 @@ drawing.lineGroupStyle = function(s, lw, lc, ld) {
};

drawing.dashLine = function(s, dash, lineWidth) {
lineWidth = +lineWidth || 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. Maybe this also fixes #166 ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe - I'll try that tonight and see if it implies any further fixes. Any other IE issues I should include in my testing?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this does fix #166 - and 4aa1a45 should catch any of these nanpx or undefinedpx errors, at least as long as they go through d3.

Will investigate the other two tomorrow, they may be related.

@etpinard etpinard added status: reviewable bug something broken labels Jan 30, 2017
@@ -5,6 +5,7 @@
<script type="text/javascript" src="../plotly.js/dist/extras/mathjax/MathJax.js?config=TeX-AMS-MML_SVG"></script>
<script type="text/javascript" src="../plotly.js/build/plotly.js" charset="utf-8"></script>
<script type="text/javascript" src="../plotly.js/dist/plotly-geo-assets.js" charset="utf-8"></script>
<script type="text/javascript" src="../plotly.js/test/image/strict-d3.js" charset="utf-8"></script>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great idea here!

First, I was thinking adding this to the image test index might lead to some very annoying debugging sessions when things go wrong. But, by adding it to the test-dashboard as well essentially make my concerns disappear (except for devs that don't use the test-dashboard cc @rreusser @monfera).

Alternatively, we could mock the d3.selection.prototype only in the ie9_test.js bundle test and test each ie9 falback one by one.

It comes down to choosing between a solution with great coverage (yours) and a less intrusive solution that might lead to less 🤕 down the road. I'm ok with both.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've talked before about wanting a way to report errors out of the image tester - printing the stack trace to a blank image or something. My vote would be to leave this in and work toward that goal. Being strict here will help us even outside IE, as we really never want to implicitly rely on browser defaults.

IE puts a space between numbers in transforms,
even if you set them with a comma
src/lib/index.js Outdated
@@ -451,8 +451,12 @@ lib.addStyleRule = function(selector, styleString) {
else lib.warn('addStyleRule failed');
};

lib.getTranslate = function(element) {
// TODO (alexcjohnson): the following translate/scale functions should
// get moved to components/drawing rather than the generic lib.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't want to move all of these (along with all their references and tests) without a discussion, but I did write a new one before finding this in here and discovering that it already tests the behavior I needed it to have for IE.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 for moving getTranslate and setTranslate out of Lib. Maybe putting them into Drawing would make the most sense?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's where I put mine before noticing these. Great, I'll move them in there.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in 66baf51

Any final comments @etpinard ?

// Chrome and FF display \n, \r, or \r\n as a space in this mode.
// I feel like at some point we turned these into <br> but currently we don't so
// I'm just going to cement what we do now in Chrome and FF
_str = _str.replace(NEWLINES, ' ');
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell this is purely a bug in IE - though one that persists from 9 through 11... the affected text is invisible, even though getBoundingClientRect() on its node shows the correct position and shape, and it reappears when you take out the newline character.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🥇 debugging.

@@ -123,7 +125,8 @@ describe('hover info', function() {

expect(d3.selectAll('g.axistext').size()).toEqual(0);
expect(d3.selectAll('g.hovertext').size()).toEqual(1);
expect(d3.selectAll('g.hovertext').select('text').html()).toEqual('hover text');
expect(d3.selectAll('g.hovertext').select('text').html())
.toEqual('hover text with spaces not newlines');
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of the image tests in 2105930 actually changed results with the fix there, but they would all have resulted in invisible text in IE before the fix. But this test confirms that we do sanitize newlines for IE compatibility.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicely done.

@etpinard
Copy link
Contributor

etpinard commented Feb 1, 2017

💃

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug something broken
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants