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

Use ownerDocument instead of global document #2721

Merged
merged 1 commit into from Sep 9, 2019

Conversation

@yamachig
Copy link
Contributor

commented Aug 18, 2019

It seems that on Microsoft Edge, you cannot appendChild an Element from different Document.
This causes a problem, for example, when you are using StyleSheetManager with a new window created by window.open, like this code:

import React from 'react';
import { createPortal } from 'react-dom';
import styled, {StyleSheetManager} from 'styled-components';

export const NewWindow = props => {
  const [newWindowBody, setNewWindowBody] = React.useState(null);
  const unloaded = React.useRef(false);

  React.useEffect(() => {
    if (!unloaded.current && !newWindowBody) {
      const w = window.open("about:blank");

      w.addEventListener('load', () => {
        setNewWindowBody(w.document.body);
      });

      w.addEventListener('unload', () => {
        unloaded.current = true;
        setNewWindowBody(null);
      });

      setNewWindowBody(w.document.body);
    }
  });

  return newWindowBody && createPortal(
    <StyleSheetManager target={newWindowBody}>
      {props.children}
    </StyleSheetManager>,
    newWindowBody,
  );
}

const Button = styled.button`
  border: none;
  background: palevioletred;
  color: white;
`;

export const TestNewWindow = () => {
  return (
    <NewWindow>
      <Button>
        Hello from new window!
      </Button>
    </NewWindow>
  )
}

This code throws an error on Edge, but not on Chrome or Firefox. (I tested with Microsoft Edge 44.18362.267.0.)

I replaced the global document variables with dynamically created Document from ownerDocument so that the code works properly on Edge.

Copy link
Contributor

left a comment

This looks good to me!

@probablyup

This comment has been minimized.

Copy link
Contributor

commented Aug 21, 2019

@yamachig could you add a changelog entry and if possible also submit the same PR against canary?

Thanks!

@yamachig

This comment has been minimized.

Copy link
Contributor Author

commented Aug 22, 2019

@probablyup thank you for reviewing! OK, I added a changelog entry and submitted the same PR #2726 against canary.

Copy link
Contributor

left a comment

Thanks!

const el = document.createElement('style');
let targetDocument = document;
if(target) targetDocument = target.ownerDocument;
else if(tagEl) targetDocument = tagEl.ownerDocument;

This comment has been minimized.

Copy link
@Jessidhia

Jessidhia Sep 6, 2019

Contributor

I'd write this as:

const targetDocument = target ? target.ownerDocument : tagEl ? tagEl.ownerDocument : document

but that's just my anti-mutability bias 🤷‍♀

This comment has been minimized.

Copy link
@yamachig

yamachig Sep 8, 2019

Author Contributor

@Jessidhia thank you for reviewing! I agree with anti-mutability, though, the eslint rule (no-nested-ternary) didn't let me do so :)

if(target) targetDocument = target.ownerDocument;
else if(tagEl) targetDocument = tagEl.ownerDocument;

const el = targetDocument.createElement('style');

This comment has been minimized.

Copy link
@Jessidhia

Jessidhia Sep 6, 2019

Contributor

Interesting that this causes no security issues; apparently any <style> tags' associated StyleSheet are considered same-origin. https://html.spec.whatwg.org/multipage/semantics.html#the-style-element:concept-css-style-sheet-origin-clean-flag

This can still break for CSP reasons, though, but it'd break regardless of whether we use CSSOM or child text nodes.

@Jessidhia

This comment has been minimized.

Copy link
Contributor

commented Sep 6, 2019

Looks like the travis config / vm is way broken.

@probablyup

This comment has been minimized.

Copy link
Contributor

commented Sep 9, 2019

@yamachig rebase when you get a chance

@yamachig yamachig dismissed stale reviews from Jessidhia and probablyup via daea21a Sep 9, 2019
@yamachig yamachig force-pushed the yamachig:use-ownerDocument branch from fa460b8 to daea21a Sep 9, 2019
@yamachig

This comment has been minimized.

Copy link
Contributor Author

commented Sep 9, 2019

@probablyup OK, I rebased. Is that correct?

@probablyup

This comment has been minimized.

Copy link
Contributor

commented Sep 9, 2019

Yeah looks like CI is passing now, good.

@probablyup probablyup merged commit f3e2266 into styled-components:master Sep 9, 2019
1 check passed
1 check passed
continuous-integration/travis-ci/pr The Travis CI build passed
Details
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.