Repeatedly infusing the same node generates a new Widget every time. The documentation we have does not seem to actually specify that the same Widget will be returned on repeated OO.ui.infuse() calls, but I think that's what we'd been assuming, and that's what the code seems to be intending to do.
Try the following console commands on https://doc.wikimedia.org/oojs-ui/master/demos/widgets.php:
e = document.getElementById( 'ooui-0' ) w1 = OO.ui.infuse( e ) w2 = OO.ui.infuse( e ) w1 === w2 // Returns false!
Consider the following snippet from OO.ui.Element.static.unsafeInfuse:
data = $elem.data( 'ooui-infused' ); if ( data ) { // cached! if ( data === true ) { throw new Error( 'Circular dependency! ' + id ); } return data; } ... $elem.data( 'ooui-infused', true ); // prevent loops ... obj = new cls( data ); // rebuild widget // now replace old DOM with this new DOM. if ( top ) { $elem.replaceWith( obj.$element ); } obj.$element.data( 'ooui-infused', obj );
There are two problems here:
- We never update the data on $elem to point to the newly constructed widget.
- $elem.replaceWith(…) clears all data, including the true marker we set, that would otherwise cause a loud error.
This is not a problem when infusing by id, since we get the new element then (as the original has been removed from DOM), which has the right data set.