Skip to content

Commit

Permalink
Re-enable post-mount event listener attachment
Browse files Browse the repository at this point in the history
Only access node if there is an actual listener
  • Loading branch information
nhunzaker committed Apr 6, 2017
1 parent e863df8 commit 9d99892
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 49 deletions.
93 changes: 44 additions & 49 deletions src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -756,31 +756,29 @@ describe('ReactDOMComponent', () => {
};
});

if (ReactDOMFeatureFlags.useCreateElement) {
// We do not attach DOM listeners when not using create element
it('should work error event on <source> element', () => {
var container = document.createElement('div');
var onError = jest.fn();
// We do not attach DOM listeners when not using create element
it('should work error event on <source> element', () => {
var container = document.createElement('div');
var onError = jest.fn();

ReactDOM.render(
<video>
<source
src="http://example.org/video"
type="video/mp4"
onError={() => onError('onError called')}
/>
</video>,
container,
);
ReactDOM.render(
<video>
<source
src="http://example.org/video"
type="video/mp4"
onError={() => onError('onError called')}
/>
</video>,
container,
);

var errorEvent = document.createEvent('Event');
errorEvent.initEvent('error', false, false);
container.querySelector('source').dispatchEvent(errorEvent);
var errorEvent = document.createEvent('Event');
errorEvent.initEvent('error', false, false);
container.querySelector('source').dispatchEvent(errorEvent);

expect(onError).toHaveBeenCalledTimes(1);
expect(onError).toHaveBeenCalledWith('onError called');
});
}
expect(onError).toHaveBeenCalledTimes(1);
expect(onError).toHaveBeenCalledWith('onError called');
});

it('should not duplicate uppercased selfclosing tags', () => {
spyOn(console, 'error');
Expand Down Expand Up @@ -1058,38 +1056,35 @@ describe('ReactDOMComponent', () => {
}
});

if (ReactDOMFeatureFlags.useCreateElement) {
// We do not attach DOM listeners when not using create element
it('should work load and error events on <image> element in SVG', () => {
var onError = jest.fn();
var onLoad = jest.fn();
it('should work load and error events on <image> element in SVG', () => {
var onError = jest.fn();
var onLoad = jest.fn();

var container = document.createElement('div');
ReactDOM.render(
<svg>
<image
xlinkHref="http://example.org/image"
onError={() => onError('onError called')}
onLoad={() => onLoad('onLoad called')}
/>
</svg>,
container,
);
var container = document.createElement('div');
ReactDOM.render(
<svg>
<image
xlinkHref="http://example.org/image"
onError={() => onError('onError called')}
onLoad={() => onLoad('onLoad called')}
/>
</svg>,
container,
);

var loadEvent = new Event('load');
var errorEvent = new Event('error');
var image = container.querySelector('image');
var loadEvent = new Event('load');
var errorEvent = new Event('error');
var image = container.querySelector('image');

image.dispatchEvent(errorEvent);
image.dispatchEvent(loadEvent);
image.dispatchEvent(errorEvent);
image.dispatchEvent(loadEvent);

expect(onError).toHaveBeenCalledTimes(1);
expect(onError).toHaveBeenCalledWith('onError called');
expect(onError).toHaveBeenCalledTimes(1);
expect(onError).toHaveBeenCalledWith('onError called');

expect(onLoad).toHaveBeenCalledTimes(1);
expect(onLoad).toHaveBeenCalledWith('onLoad called');
});
}
expect(onLoad).toHaveBeenCalledTimes(1);
expect(onLoad).toHaveBeenCalledWith('onLoad called');
});
});

describe('updateComponent', () => {
Expand Down
20 changes: 20 additions & 0 deletions src/renderers/dom/stack/client/ReactDOMComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,24 @@ function getDocument(inst) {
return doc;
}

function ensureListeners() {
var inst = this;
var props = inst._currentElement.props;
var doc = getDocument(inst);

for (var propKey in props) {
if (registrationNameModules.hasOwnProperty(propKey)) {
if (!!props[propKey]) {
// Note: we access getNode in the loop here for some
// additional bulletproofing for invalidly nested DOM
// elements. Invalidly nested elements with event listeners
// will still crash
listenTo(propKey, doc, getNode(inst));
}
}
}
}

function inputPostMount() {
var inst = this;
// For controlled components we always need to ensure we're listening
Expand Down Expand Up @@ -588,6 +606,8 @@ ReactDOMComponent.Mixin = {
return ret;
}

transaction.getReactMountReady().enqueue(ensureListeners, this);

if (!this._hostParent) {
ret += ' ' + DOMPropertyOperations.createMarkupForRoot();
}
Expand Down

0 comments on commit 9d99892

Please sign in to comment.