mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Fix rendering into shadow root (#11037)
* Replace skipped unit test with a fixture * Fix crash for custom elements
This commit is contained in:
@@ -62,6 +62,7 @@ class Header extends React.Component {
|
||||
<option value="/date-inputs">Date Inputs</option>
|
||||
<option value="/error-handling">Error Handling</option>
|
||||
<option value="/event-pooling">Event Pooling</option>
|
||||
<option value="/custom-elements">Custom Elements</option>
|
||||
</select>
|
||||
</label>
|
||||
<label htmlFor="react_version">
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import FixtureSet from '../../FixtureSet';
|
||||
import TestCase from '../../TestCase';
|
||||
|
||||
const React = window.React;
|
||||
const ReactDOM = window.ReactDOM;
|
||||
|
||||
class HelloWorld extends React.Component {
|
||||
render() {
|
||||
return <h1>Hello, world!</h1>;
|
||||
}
|
||||
}
|
||||
|
||||
// Babel breaks web components.
|
||||
// https://github.com/w3c/webcomponents/issues/587
|
||||
// eslint-disable-next-line no-new-func
|
||||
const MyElement = new Function(
|
||||
'React',
|
||||
'ReactDOM',
|
||||
'HelloWorld',
|
||||
`
|
||||
return class MyElement extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
const shadowRoot = this.attachShadow({ mode:'open' });
|
||||
ReactDOM.render(React.createElement(HelloWorld), shadowRoot);
|
||||
}
|
||||
}`
|
||||
)(React, ReactDOM, HelloWorld);
|
||||
|
||||
customElements.define('my-element', MyElement);
|
||||
|
||||
export default class ButtonTestCases extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<FixtureSet
|
||||
title="Custom Elements"
|
||||
description="Support for Custom Element DOM standards.">
|
||||
<TestCase title="Rendering into shadow root">
|
||||
<TestCase.ExpectedResult>
|
||||
You should see "Hello, World" printed below.{' '}
|
||||
</TestCase.ExpectedResult>
|
||||
<my-element />
|
||||
</TestCase>
|
||||
</FixtureSet>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import ButtonFixtures from './buttons';
|
||||
import DateInputFixtures from './date-inputs';
|
||||
import ErrorHandling from './error-handling';
|
||||
import EventPooling from './event-pooling';
|
||||
import CustomElementFixtures from './custom-elements';
|
||||
|
||||
const React = window.React;
|
||||
|
||||
@@ -40,6 +41,8 @@ function FixturesPage() {
|
||||
return <ErrorHandling />;
|
||||
case '/event-pooling':
|
||||
return <EventPooling />;
|
||||
case '/custom-elements':
|
||||
return <CustomElementFixtures />;
|
||||
default:
|
||||
return <p>Please select a test fixture.</p>;
|
||||
}
|
||||
|
||||
-6379
File diff suppressed because it is too large
Load Diff
@@ -163,17 +163,24 @@ var DOMRenderer = ReactFiberReconciler({
|
||||
getRootHostContext(rootContainerInstance: Container): HostContext {
|
||||
let type;
|
||||
let namespace;
|
||||
if (rootContainerInstance.nodeType === DOCUMENT_NODE) {
|
||||
type = '#document';
|
||||
let root = (rootContainerInstance: any).documentElement;
|
||||
namespace = root ? root.namespaceURI : getChildNamespace(null, '');
|
||||
} else {
|
||||
const container: any = rootContainerInstance.nodeType === COMMENT_NODE
|
||||
? rootContainerInstance.parentNode
|
||||
: rootContainerInstance;
|
||||
const ownNamespace = container.namespaceURI || null;
|
||||
type = container.tagName;
|
||||
namespace = getChildNamespace(ownNamespace, type);
|
||||
const nodeType = rootContainerInstance.nodeType;
|
||||
switch (nodeType) {
|
||||
case DOCUMENT_NODE:
|
||||
case DOCUMENT_FRAGMENT_NODE: {
|
||||
type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';
|
||||
let root = (rootContainerInstance: any).documentElement;
|
||||
namespace = root ? root.namespaceURI : getChildNamespace(null, '');
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
const container: any = nodeType === COMMENT_NODE
|
||||
? rootContainerInstance.parentNode
|
||||
: rootContainerInstance;
|
||||
const ownNamespace = container.namespaceURI || null;
|
||||
type = container.tagName;
|
||||
namespace = getChildNamespace(ownNamespace, type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (__DEV__) {
|
||||
const validatedTag = type.toLowerCase();
|
||||
|
||||
@@ -17,7 +17,6 @@ var React;
|
||||
var ReactDOM;
|
||||
var ReactDOMServer;
|
||||
var ReactTestUtils;
|
||||
var WebComponents;
|
||||
|
||||
describe('ReactMount', () => {
|
||||
beforeEach(() => {
|
||||
@@ -27,16 +26,6 @@ describe('ReactMount', () => {
|
||||
ReactDOM = require('react-dom');
|
||||
ReactDOMServer = require('react-dom/server');
|
||||
ReactTestUtils = require('react-dom/test-utils');
|
||||
|
||||
try {
|
||||
if (WebComponents === undefined && typeof jest !== 'undefined') {
|
||||
WebComponents = require('WebComponents');
|
||||
}
|
||||
} catch (e) {
|
||||
// Parse error expected on engines that don't support setters
|
||||
// or otherwise aren't supportable by the polyfill.
|
||||
// Leave WebComponents undefined.
|
||||
}
|
||||
});
|
||||
|
||||
describe('unmountComponentAtNode', () => {
|
||||
@@ -201,29 +190,6 @@ describe('ReactMount', () => {
|
||||
);
|
||||
});
|
||||
|
||||
if (WebComponents !== undefined) {
|
||||
it('should allow mounting/unmounting to document fragment container', () => {
|
||||
var shadowRoot;
|
||||
var proto = Object.create(HTMLElement.prototype, {
|
||||
createdCallback: {
|
||||
value: function() {
|
||||
shadowRoot = this.createShadowRoot();
|
||||
ReactDOM.render(<div>Hi, from within a WC!</div>, shadowRoot);
|
||||
expect(shadowRoot.firstChild.tagName).toBe('DIV');
|
||||
ReactDOM.render(<span>Hi, from within a WC!</span>, shadowRoot);
|
||||
expect(shadowRoot.firstChild.tagName).toBe('SPAN');
|
||||
},
|
||||
},
|
||||
});
|
||||
proto.unmount = function() {
|
||||
ReactDOM.unmountComponentAtNode(shadowRoot);
|
||||
};
|
||||
document.registerElement('x-foo', {prototype: proto});
|
||||
var element = document.createElement('x-foo');
|
||||
element.unmount();
|
||||
});
|
||||
}
|
||||
|
||||
it('should warn if render removes React-rendered children', () => {
|
||||
var container = document.createElement('container');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user