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

Mailchimp popup widget pollutes global scope with require and define variables #8546

Closed
adamziel opened this issue Jan 17, 2018 · 3 comments
Closed
Assignees
Labels

Comments

@adamziel
Copy link
Contributor

adamziel commented Jan 17, 2018

Steps to reproduce the issue

  1. Create a "MailChimp Subscriber Popup" widget
  2. Open any page where the widget is loaded

What I expected

window.define and window.require to be null

What happened instead

window.define and window.require are set variables.

This is very problematic if e.g. jquery is defined before the widget and jquery-ui is defined after the widget. If define() is available, it will be used to load jquery-ui as you can see here:

https://code.jquery.com/ui/1.12.0/jquery-ui.js

        if ( typeof define === "function" && define.amd ) {

		// AMD. Register as an anonymous module.
		define([ "jquery" ], factory );
	} else {

		// Browser globals
		factory( jQuery );
	}

So in this case, define is indeed available, but jquery was loaded in a "regular" way. It means that jquery-ui will always wait for jquery to be available as a dependency and will never be loaded.

A solution

Set window.define.amd to undefined after the mailchimp embed is loaded:

<script type="text/javascript" data-dojo-config="usePlainJson: true, isDebug: false">
jQuery.getScript( "//downloads.mailchimp.com/js/signup-forms/popup/embed.js", function( data, textStatus, jqxhr ) {
    require(["mojo/signup-forms/Loader"], function(L) {
        L.start({"baseUrl":"mc.us13.list-manage.com","uuid":"xxxx","lid":"xxxx"}) }); 
        window.define.amd = undefined; 
    }
 );
</script>

Why window.define.amd? Because MailChimp script needs require and define functions to remain in the global scope, but scripts like jquery will not use define if window.define.amd is undefined, so it's a win-win (an ugly one but still).

A better solution

Have mailchimp fix that on their end

adamziel added a commit to adamziel/jetpack-mailchimp-fix that referenced this issue Jan 17, 2018
…rom global scope after using a require definition
@jeherve jeherve added [Type] Bug When a feature is broken and / or not performing as intended [Feature] Extra Sidebar Widgets [Pri] Normal [Feature] Shortcodes / Embeds labels Jan 17, 2018
@jeherve
Copy link
Member

jeherve commented Jan 17, 2018

This is very problematic if e.g. jquery is defined before the widget and jquery-ui is defined after the widget.

Do you know of any scenario when this would happen? Both jQuery and jQuery UI are usually loaded in the head, while the shortcode is loaded in the body. Some caching plugins will change that, but did you run into a specific scenario where jQuery and jQuery UI were not loaded right after each other?

@jeherve jeherve added the [Status] Needs Author Reply We need more details from you. This label will be auto-added until the PR meets all requirements. label Jan 17, 2018
adamziel added a commit to adamziel/jetpack-mailchimp-fix that referenced this issue Jan 17, 2018
…ndow.define from global scope and thus breaking mailchimp script, set window.define.amd to fool just real amd modules.

Mailchimp script seem to expect usable definitions of require and define, once we remove them it breaks. Since the purpose of this commit is to fix scripts like jquery-ui that will resort to define() if define.amd is defined - it is enough to unset define.amd. This is a very ugly solution, but it works.
@adamziel
Copy link
Contributor Author

adamziel commented Jan 17, 2018

@jeherve I found this problem by tracking down 903897-zen. Basically as a result of installing some plugins the order of <script> tags became very unfortunate and a jquery-ui calendar broke on a woocommerce page. I agree it can be mitigated by caching plugins, but things breaking unexpectedly is a bad user experience and requires a lot of support time to track down.

@jeherve jeherve removed the [Status] Needs Author Reply We need more details from you. This label will be auto-added until the PR meets all requirements. label Jan 17, 2018
adamziel added a commit to adamziel/jetpack-mailchimp-fix that referenced this issue Jan 25, 2018
jeherve pushed a commit that referenced this issue Jan 25, 2018
* Fix issue #8546 - remove window.require and window.define from global scope after using a require definition

* Fix issue #8546 - instead of removing window.require and window.define from global scope and thus breaking mailchimp script, set window.define.amd to fool just real amd modules.

Mailchimp script seem to expect usable definitions of require and define, once we remove them it breaks. Since the purpose of this commit is to fix scripts like jquery-ui that will resort to define() if define.amd is defined - it is enough to unset define.amd. This is a very ugly solution, but it works.

* Update mailchimp shortcode test to match earlier fix for issue #8546 - test for updated script string.
@kimitrii
Copy link

OMG this helped me so much, Thank you so much for that

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

No branches or pull requests

3 participants