-
Notifications
You must be signed in to change notification settings - Fork 408
Zone.js 0.8.13+ breaks addEventListener in Safari 11.0, 11.1 #883
Comments
Something must've changed here: v0.8.12...v0.8.13 — perhaps b3a76d3? |
Interestingly, if I use the Example without Zone.js (async () => {
console.log('Create RTCPeerConnection')
const pc = new RTCPeerConnection()
console.log('Add "track" event listener')
let event
pc.ontrack = _event => event = _event
console.log('Dispatch "track" event')
pc.dispatchEvent(new Event('track'))
if (event) {
console.log('Success!')
} else {
console.error('Failure!')
}
})().catch(console.error) Example with Zone.js (async () => {
const script = document.createElement('script')
script.src = 'https://cdnjs.cloudflare.com/ajax/libs/zone.js/0.8.16/zone.js'
document.body.appendChild(script)
await new Promise(resolve => script.onload = resolve)
console.log('Create RTCPeerConnection')
const pc = new RTCPeerConnection()
console.log('Add "track" event listener')
let event
pc.ontrack = _event => event = _event
console.log('Dispatch "track" event')
pc.dispatchEvent(new Event('track'))
if (event) {
console.log('Success!')
} else {
console.error('Failure!')
}
})().catch(console.error) Actual Results (Safari 11.0, Safari 11.1)
|
@markandrus , thank you for posting the issue, I will check it. |
@markandrus , I think it is a weird safari behavior. I create a html for easier test. <html>
<head>
<!--<script src="https://cdnjs.cloudflare.com/ajax/libs/zone.js/0.8.16/zone.js"></script>-->
<script>
window.onload = function () {
console.log('Create RTCPeerConnection')
const pc = new RTCPeerConnection()
console.log('Add "track" event listener')
let event
pc.addEventListener('track', function(_event) {
console.log('this === pc', this === pc);
console.log('track event', _event);
event = _event
});
/*pc.ontrack = function(_event) {
console.log('this === pc', this === pc);
console.log('track event', _event);
event = _event
};*/
console.log('Dispatch "track" event')
pc.dispatchEvent(new Event('track'))
if (event) {
console.log('Success!')
} else {
console.error('Failure!')
}
}
</script>
</head>
</html> without And I have created an issue in webkit bug tracker, https://bugs.webkit.org/show_bug.cgi?id=175802 |
@JiaLiPassion thank you for your analysis and for opening the WebKit bug. I spoke too soon and this is indeed an RTCPeerConnection-specific issue in WebKit.
What path forward do you recommend? Although I could workaround this using |
@markandrus , if this is a webkit bug, I think we can wait for the fix, and at that time, you can use |
@JiaLiPassion OK, that seems reasonable. I've reviewed my code, though, and I see I'd have to change a non-trivial amount of code to use the |
@markandrus , about
|
@JiaLiPassion with Safari 11's release now looming, and there no one assigned to the webkit bug that you filed, are there any plans to implement a patch at the zone.js level? This is essentially forcing us to select between using zone.js in our project or WebRTC in Safari, since the two cannot be used together. |
Here is one potential workaround, but it precludes using a mixture of (async () => {
console.log('Load Zone.js')
const script = document.createElement('script')
script.src = 'https://cdnjs.cloudflare.com/ajax/libs/zone.js/0.8.16/zone.js'
document.body.appendChild(script)
await new Promise(resolve => script.onload = resolve)
// NOTE(mroberts): Workaround for https://github.com/angular/zone.js/issues/883
const originalAddEventListener = RTCPeerConnection.prototype.addEventListener
RTCPeerConnection.prototype.addEventListener = function addEventListener(event, listener) {
if ('on' + event in this) {
this._eventListeners = this._eventListeners || new Map()
const listeners = this._eventListeners.get(event) || []
listeners.push(listener)
this._eventListeners.set(event, listeners)
if (typeof this['on' + event] !== 'function') {
var self = this
this['on' + event] = function applyListeners() {
const listeners = self._eventListeners.get(event) || []
listeners.forEach(listener => {
try {
listener.apply(self, arguments)
} catch (error) {
console.error(error)
}
})
}
}
return
}
originalAddEventListener.call(this, event, listener)
}
const originalRemoveEventListener = RTCPeerConnection.prototype.removeEventListener
RTCPeerConnection.prototype.removeEventListener = function removeEventListener(event, listener) {
if ('on' + event in this) {
this._eventListeners = this._eventListeners || new Map()
const listeners = this._eventListeners.get(event) || []
this._eventListeners.set(event, listeners.filter(_listener => _listener !== listener))
return
}
originalRemoveEventListener.call(this, event, listener)
}
console.log('Create RTCPeerConnection')
const pc = new RTCPeerConnection()
console.log('Add "track" event listener')
let event
pc.addEventListener('track', _event => event = _event)
console.log('Dispatch "track" event')
pc.dispatchEvent(new Event('track'))
if (event) {
console.log('Success!')
} else {
console.error('Failure!')
}
})().catch(console.error) |
@JiaLiPassion I may land this code in my library, but would you consider landing this workaround in Zone.js? I would prefer not to have to workaround this in my own library. Can you think of any other ways to implement this workaround? |
…riggered issue
@markandrus , sure , I will post a PR to fix this one. <script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/zone.js/dist/webapis-rtc-peer-connection.js"></script> |
Includes the fix for RTCPeerConnection in zone.js angular/zone.js#883
Hi,
I'm a WebRTC developer, and I noticed an issue with
addEventListener
in Safari using Zone.js. I doubt this issue is specific to WebRTC—I just happened to notice it when using the RTCPeerConnection APIs. Try for example, the following in the console for Chrome, Firefox, and Safari (11.0 or greater). They should all yield the same result.Example without Zone.js
Results
Now, try loading Zone.js first and re-running the code sample.
Example with Zone.js
Expected Results
Actual Results (Chrome, Firefox)
Chrome and Firefox work fine.
Actual Results (Safari 11.0, Safari 11.1)
Safari 11.0 and Safari 11.1 do not.
If you re-run the tests, changing out the version of Zone.js used, 0.8.12 is the last version of Zone.js that worked without error in Safari. Zone.js 0.8.13 introduced the error.
The text was updated successfully, but these errors were encountered: