Skip to content
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

[Core] Replace merge implementation in utils/styles with Object.assign #3124

Merged
merged 1 commit into from
Feb 4, 2016

Conversation

newoga
Copy link
Contributor

@newoga newoga commented Feb 1, 2016

This PR splits of the some of the work that was started in #2986 that switched our merge implementation to Object.assign.

The essence of this PR is to pave the way to start using Object.assign for merging styles instead of a merge utility method. The problem we ran into was that Chrome's Object.assign implementation currently has a bug in which the keys were not always ordered properly (which sometimes led to styling bugs because of the order style properties were defined). This PR includes a babel transformation step (that needs to be reviewed) that uses the same implementation as babel-plugin-transform-object-assign from the babel repository, except it will not use the native Object.assign when found.

Note: This does not replace browser's Object.assign, it simply uses a different method (similar to a ponyfill).

@@ -30,6 +30,7 @@
},
"homepage": "http://material-ui.com/",
"dependencies": {
"assign": "git://github.com/newoga/assign.git",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we continue to pursue this PR, we should probably tag release rather than work of master at the very least and possibly publish to npm too. Though just wanted to run this implementation by you first (and confirm what we should name these).

Copy link
Member

Choose a reason for hiding this comment

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

Same comment than for the babel plugin.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah originally I wanted to design the plugin to create a file with the right implementation in the build output, but I couldn't figure out how to do it and I didn't see an easy way to resolve relative paths for components in babel, so making it a package with a static import name was easiest.

@alitaheri
Copy link
Member

This looks good to me, great job with the transformer 👍 👍

You say it doesn't replace the browsers Object.assign. But didn't Chrome have an issue with it? isn't that why we weren't using _extend?

@newoga
Copy link
Contributor Author

newoga commented Feb 1, 2016

You say it doesn't replace the browsers Object.assign. But didn't Chrome have an issue with it? isn't that why we weren't using _extend?

Yes kind of, both _extend and this transform technically replaces all your uses of Object.assign with another method that replicates or copies the Object.assign implementation. The only difference between this transform and _extend is if Object.assign is found in the browser, it isn't used. Small difference! 😄

@alitaheri
Copy link
Member

Oh, right my bad. I misunderstood 😅

@newoga
Copy link
Contributor Author

newoga commented Feb 1, 2016

Oh, right my bad. I misunderstood 😅

No problem, I wrote it in a really confusing way. 😄

@oliviertassinari
I was able to make a change to my babel plugin that fixes the issue about using Object.assign multiple times. I was able to test it and it looks like this approach is working.

@@ -51,6 +52,7 @@
"babel-loader": "^6.2.0",
"babel-plugin-add-module-exports": "^0.1.2",
"babel-plugin-transform-dev-warning": "^0.1.0",
"babel-plugin-transform-object-assign": "git://github.com/newoga/babel-plugin-transform-object-assign.git",
Copy link
Member

Choose a reason for hiding this comment

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

It would be good to publish it. If it's just designed to be used with material-ui and won't help the comminity, we can even consider moving the source code to this repository.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you have a preference as to what we call it?
babel-plugin-transform-inject-object-assign
babel-plugin-transform-replace-object-assign
{any other ideas}

Copy link
Member

Choose a reason for hiding this comment

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

babel-plugin-transform-replace-object-assign 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good.

@newoga newoga force-pushed the mergeStyles-to-Object.assign branch from 3efd665 to 752a027 Compare February 2, 2016 22:53
@newoga
Copy link
Contributor Author

newoga commented Feb 2, 2016

@oliviertassinari @alitaheri FYI - I published the plugin and assign implementation to npm and switched this to pull from there instead of github. 😄

@newoga newoga changed the title [WIP] [Core] Replace merge implementation in utils/styles with Object.assign [Core] Replace merge implementation in utils/styles with Object.assign Feb 3, 2016
@alitaheri
Copy link
Member

Beautiful work @newoga 👍 👍 😍

@newoga
Copy link
Contributor Author

newoga commented Feb 3, 2016

Beautiful work @newoga 👍 👍 😍

Thanks! We're making a lot of progress! 🎉

@oliviertassinari
Copy link
Member

@newoga Nice job! Can we rebase and squash down the commit? Let's merge this 🎉 🚀.

@oliviertassinari
Copy link
Member

I have checked the babel-plugin-transform-replace-object-assign plugin
and npm run browser:prd is working fine 👍 .
It's transforming

export const mergeStyles = (...args) => Object.assign({}, ...args);
export const mergeStyles2 = (...args) => Object.assign({}, ...args);

into

var _simpleAssign = require('simple-assign');

var _simpleAssign2 = _interopRequireDefault(_simpleAssign);

var mergeStyles = exports.mergeStyles = function mergeStyles() {
  for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
    args[_key] = arguments[_key];
  }

  return _simpleAssign2.default.apply(undefined, [{}].concat(args));
};
var mergeStyles2 = exports.mergeStyles2 = function mergeStyles2() {
  for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
    args[_key2] = arguments[_key2];
  }

  return _simpleAssign2.default.apply(undefined, [{}].concat(args));
};

but it would be good to add some tests inside https://github.com/newoga/babel-plugin-transform-replace-object-assign.

@newoga newoga force-pushed the mergeStyles-to-Object.assign branch from bd577db to 50b2ccb Compare February 3, 2016 15:23
@newoga
Copy link
Contributor Author

newoga commented Feb 3, 2016

but it would be good to add some tests inside https://github.com/newoga/babel-plugin-transform-replace-object-assign.

I agree, @oliviertassinari. I was thinking the same thing when I was writing it, but didn't get around to looking into good test approaches for babel plugins. I just saw how you did it here. I'll use that approach to check for actual and expected for what you showed above, and also make sure there is a test for multiple uses of Object.assign which I fixed. I'll try to get that done tonight.

I rebased this branch for now. If we feel comfortable enough merging this as is, it should be good to go, otherwise later today after the tests is fine too!

@oliviertassinari
Copy link
Member

If we feel comfortable enough merging this as is, it should be good to go, otherwise later today after the tests is fine too!

I would say, let's wait for the tests 👍😁.
You can also use https://github.com/oliviertassinari/babel-plugin-transform-react-remove-prop-types/tree/master/test/fixtures as a source of inspiration.

@newoga
Copy link
Contributor Author

newoga commented Feb 3, 2016

Sounds good!

You can also use https://github.com/oliviertassinari/babel-plugin-transform-react-remove-prop-types/tree/master/test/fixtures as a source of inspiration.

Thanks for sharing, that's a great reference.

The commit allows us to start using `Object.assign` for merging styles instead of this `mergeStyles` utility method. Chrome's currently has a bug in which its `Object.assign` implementation does not consistently or keys of merged objects. This sometimes led to styling bugs because some style properties rendered to the DOM in the wrong order (see mui#2986). This commit includes a babel transformation step that replaces all uses of `Object.assign` with the implementation at `simple-assign` and ignores the browser's native Object.assign implementation.

Signed-off-by: Neil Gabbadon <neil.gabbadon@emikra.com>
@newoga newoga force-pushed the mergeStyles-to-Object.assign branch from 50b2ccb to bf766b0 Compare February 4, 2016 04:15
@newoga
Copy link
Contributor Author

newoga commented Feb 4, 2016

@oliviertassinari Thanks for letting me use your babel plugin as a guide for making mine! I've added tests and setup the build in travis-ci!

Let me know if there are any additional scenarios that are worth testing for. No changes were made to src, but I still made a patch release anyway and updated the dependency here to be sure.

oliviertassinari added a commit that referenced this pull request Feb 4, 2016
[Core] Replace merge implementation in utils/styles with Object.assign
@oliviertassinari oliviertassinari merged commit 66fcbfa into mui:master Feb 4, 2016
@oliviertassinari
Copy link
Member

@newoga Awesome! Thanks 💯

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core Infrastructure work going on behind the scenes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants