@@ -41,6 +41,7 @@ define([
41
41
this . username = "username" ;
42
42
this . session_id = utils . uuid ( ) ;
43
43
this . _msg_callbacks = { } ;
44
+ this . _msg_callbacks_overrides = { } ;
44
45
this . _display_id_to_parent_ids = { } ;
45
46
this . _msg_queue = Promise . resolve ( ) ;
46
47
this . info_reply = { } ; // kernel_info_reply stored here after starting
@@ -301,6 +302,7 @@ define([
301
302
this . events . trigger ( 'kernel_restarting.Kernel' , { kernel : this } ) ;
302
303
this . stop_channels ( ) ;
303
304
this . _msg_callbacks = { } ;
305
+ this . _msg_callbacks_overrides = { } ;
304
306
this . _display_id_to_parent_ids = { } ;
305
307
306
308
var that = this ;
@@ -850,6 +852,35 @@ define([
850
852
}
851
853
} ;
852
854
855
+ /**
856
+ * Get output callbacks for a specific message.
857
+ *
858
+ * @function get_output_callbacks_for_msg
859
+ *
860
+ * Since output callbacks can be overridden, we first check the override stack.
861
+ */
862
+ Kernel . prototype . get_output_callbacks_for_msg = function ( msg_id ) {
863
+ return this . get_callbacks_for_msg ( this . get_output_callback_id ( msg_id ) ) ;
864
+ } ;
865
+
866
+
867
+ /**
868
+ * Get the output callback id for a message
869
+ *
870
+ * Since output callbacks can be redirected, this may not be the same as
871
+ * the msg_id.
872
+ *
873
+ * @function get_output_callback_id
874
+ */
875
+ Kernel . prototype . get_output_callback_id = function ( msg_id ) {
876
+ var callback_id = msg_id ;
877
+ var overrides = this . _msg_callbacks_overrides [ msg_id ] ;
878
+ if ( overrides && overrides . length > 0 ) {
879
+ callback_id = overrides [ overrides . length - 1 ] ;
880
+ }
881
+ return callback_id
882
+ }
883
+
853
884
/**
854
885
* Clear callbacks for a specific message.
855
886
*
@@ -913,10 +944,16 @@ define([
913
944
*
914
945
* }
915
946
*
947
+ * If the third parameter is truthy, the callback is set as the last
948
+ * callback registered.
949
+ *
916
950
* @function set_callbacks_for_msg
917
951
*/
918
- Kernel . prototype . set_callbacks_for_msg = function ( msg_id , callbacks ) {
919
- this . last_msg_id = msg_id ;
952
+ Kernel . prototype . set_callbacks_for_msg = function ( msg_id , callbacks , save ) {
953
+ var remember = save || true ;
954
+ if ( remember ) {
955
+ this . last_msg_id = msg_id ;
956
+ }
920
957
if ( callbacks ) {
921
958
// shallow-copy mapping, because we will modify it at the top level
922
959
var cbcopy = this . _msg_callbacks [ msg_id ] = this . last_msg_callbacks = { } ;
@@ -931,11 +968,31 @@ define([
931
968
// default to clear-on-done
932
969
cbcopy . clear_on_done = true ;
933
970
}
934
- } else {
971
+ } else if ( remember ) {
935
972
this . last_msg_callbacks = { } ;
936
973
}
937
974
} ;
938
-
975
+
976
+ /**
977
+ * Override output callbacks for a particular msg_id
978
+ */
979
+ Kernel . prototype . output_callback_overrides_push = function ( msg_id , callback_id ) {
980
+ var output_callbacks = this . _msg_callbacks_overrides [ msg_id ] ;
981
+ if ( output_callbacks === void 0 ) {
982
+ this . _msg_callbacks_overrides [ msg_id ] = output_callbacks = [ ] ;
983
+ }
984
+ output_callbacks . push ( callback_id ) ;
985
+ }
986
+
987
+ Kernel . prototype . output_callback_overrides_pop = function ( msg_id ) {
988
+ var callback_ids = this . _msg_callbacks_overrides [ msg_id ] ;
989
+ if ( ! callback_ids ) {
990
+ console . error ( "Popping callback overrides, but none registered" , msg_id ) ;
991
+ return ;
992
+ }
993
+ return callback_ids . pop ( ) ;
994
+ }
995
+
939
996
Kernel . prototype . _handle_ws_message = function ( e ) {
940
997
var that = this ;
941
998
this . _msg_queue = this . _msg_queue . then ( function ( ) {
@@ -1060,7 +1117,7 @@ define([
1060
1117
* @function _handle_clear_output
1061
1118
*/
1062
1119
Kernel . prototype . _handle_clear_output = function ( msg ) {
1063
- var callbacks = this . get_callbacks_for_msg ( msg . parent_header . msg_id ) ;
1120
+ var callbacks = this . get_output_callbacks_for_msg ( msg . parent_header . msg_id ) ;
1064
1121
if ( ! callbacks || ! callbacks . iopub ) {
1065
1122
return ;
1066
1123
}
@@ -1078,7 +1135,7 @@ define([
1078
1135
Kernel . prototype . _handle_output_message = function ( msg ) {
1079
1136
var that = this ;
1080
1137
var msg_id = msg . parent_header . msg_id ;
1081
- var callbacks = this . get_callbacks_for_msg ( msg_id ) ;
1138
+ var callbacks = this . get_output_callbacks_for_msg ( msg_id ) ;
1082
1139
if ( [ 'display_data' , 'update_display_data' , 'execute_result' ] . indexOf ( msg . header . msg_type ) > - 1 ) {
1083
1140
// display_data messages may re-route based on their display_id
1084
1141
var display_id = ( msg . content . transient || { } ) . display_id ;
@@ -1110,8 +1167,9 @@ define([
1110
1167
if ( this . _display_id_to_parent_ids [ display_id ] === undefined ) {
1111
1168
this . _display_id_to_parent_ids [ display_id ] = [ ] ;
1112
1169
}
1113
- if ( this . _display_id_to_parent_ids [ display_id ] . indexOf ( msg_id ) === - 1 ) {
1114
- this . _display_id_to_parent_ids [ display_id ] . push ( msg_id ) ;
1170
+ var callback_id = this . get_output_callback_id ( msg_id ) ;
1171
+ if ( this . _display_id_to_parent_ids [ display_id ] . indexOf ( callback_id ) === - 1 ) {
1172
+ this . _display_id_to_parent_ids [ display_id ] . push ( callback_id ) ;
1115
1173
}
1116
1174
// and in callbacks for cleanup on clear_callbacks_for_msg
1117
1175
if ( callbacks && callbacks . display_ids . indexOf ( display_id ) === - 1 ) {
0 commit comments