The state of WindowInstance private deferreds (e.g. lifecycle.deferreds.closing) and public promises (e.g. lifecycle.closing) can be inconsistent due to jQuery 3 asynchronous promise resolution. The public promise will lag behind the private deferred by one "tick".
Our code does not correctly account for this. It should not cause any problems when simply waiting for promises to resolve, but we check their .state() in a few places and that causes issues.
In particular, some examples:
- (T169844) Trying to close a window that is already closing while the states of closing promise are inconsistent causes exceptions. Minimal test case: open "Quick alert" on https://doc.wikimedia.org/oojs-ui/master/demos/?page=dialogs, then run this in the console:
[Note, this isn't actually visible in the demo right now since we just merged a workaround for that bug. Use a local build without that patch.]
manager = OO.ui.getWindowManager(); win = manager.getCurrentWindow(); setTimeout( function () { OO.ui.getWindowManager().closeWindow( win ); } ); // "Uncaught TypeError: Cannot read property 'resolve' of null" OO.ui.getWindowManager().closeWindow( win );
- WindowManager#isClosing returns wrong result for windows that began closing on the same tick. Minimal test case: open "Quick alert" on https://doc.wikimedia.org/oojs-ui/master/demos/?page=dialogs, then run this in the console:
manager = OO.ui.getWindowManager(); win = manager.getCurrentWindow(); manager.closeWindow( win ); console.log( manager.isClosing( win ) ); // should log true, actually logs false