-
Bug
-
Resolution: Fixed
-
Major
-
8.0.3
-
None
-
Security Level: Jimmy
-
None
-
ZK 8.0.4 S1, ZK 8.0.4 S2
-
None
Steps to Reproduce
http://zkfiddle.org/sample/3hvgpkt/1-IE-popup-crash
Run fiddle
Click on the combobox input element to give it focus
Hover the button to trigger popup.
Move mouse out of the button to close the popup.
(sometime, this just cause a layout issue. In this case, repeat the same pattern)
Actual Result
IE 11 crash
Expected Result
IE 11 doesn't crash OR if not crashing error logging in the console
Debug Info
Crash details show a stack overflow in MSHTML.dll
IE Shouldn't crash on javascript overflow, which indicates that there might be an underlying IE bug / mshtml.dll bug causing the caught exception to crash the IE process.
Root Cause
It seem that the stack overflow in mshtml is caused by a function loop in popup / inputWidget from:
popup.close()
https://github.com/zkoss/zk/blob/v8.0.3.1/zul/src/archive/web/js/zul/wgt/Popup.js#L248
then trigger focus on the currently focused input
https://github.com/zkoss/zk/blob/v8.0.3.1/zul/src/archive/web/js/zul/wgt/Popup.js#L264
Focus triggers _domEvtProxy0
https://github.com/zkoss/zk/blob/v8.0.3.1/zk/src/archive/web/js/zk/widget.js#L63
Since the case if focus, the zWatch event onFloatUp is triggered
https://github.com/zkoss/zk/blob/v8.0.3.1/zk/src/archive/web/js/zk/widget.js#L73
This triggered the popup onFloatUp up listener, which calls popup._doFloatUp();
https://github.com/zkoss/zk/blob/v8.0.3.1/zul/src/archive/web/js/zul/wgt/Popup.js#L318
_doFloatUp in turn call popup.close, which goes back to the start of the loop.
https://github.com/zkoss/zk/blob/v8.0.3.1/zul/src/archive/web/js/zul/wgt/Popup.js#L332
This runs in a try / catch, which suppresses error messages:
https://github.com/zkoss/zk/blob/v8.0.3.1/zul/src/archive/web/js/zul/wgt/Popup.js#L269
Workaround
<script><![CDATA[ zk.afterLoad('zul.wgt', function() { var xPopup = {}; zk.override(zul.wgt.Popup.prototype, xPopup ,{ close : function() { setTimeout(xPopup.close.bind(this, arguments),0); } });//zk.override });//zk/afterLoad ]]></script>