Don't abuse state change function for messages

This doesn't even work anymore since we fixed it to ignore changes
to the current state. Add a separate callback for notifications
instead.
This commit is contained in:
Samuel Mannehed 2016-08-29 14:59:28 +02:00
parent 4cfd49c8c3
commit a7127fee73
4 changed files with 69 additions and 6 deletions

View File

@ -338,6 +338,7 @@ var UI;
initRFB: function() {
try {
UI.rfb = new RFB({'target': document.getElementById('noVNC_canvas'),
'onNotification': UI.notification,
'onUpdateState': UI.updateState,
'onPasswordRequired': UI.passwordRequired,
'onXvpInit': UI.updateXvpButton,
@ -486,6 +487,10 @@ var UI;
document.getElementById('noVNC_status').classList.remove("noVNC_open");
},
notification: function (rfb, msg, level, options) {
UI.showStatus(msg, level);
},
activateControlbar: function(event) {
clearTimeout(UI.idleControlbarTimeout);
// We manipulate the anchor instead of the actual control

View File

@ -158,6 +158,7 @@
// Callback functions
'onUpdateState': function () { }, // onUpdateState(rfb, state, oldstate, statusMsg): state update/change
'onNotification': function () { }, // onNotification(rfb, msg, level, options): notification for UI
'onPasswordRequired': function () { }, // onPasswordRequired(rfb, msg): VNC password is required
'onClipboard': function () { }, // onClipboard(rfb, text): RFB clipboard contents received
'onBell': function () { }, // onBell(rfb): RFB Bell message received
@ -535,6 +536,33 @@
return false;
},
/*
* Send a notification to the UI. Valid levels are:
* 'normal'|'warn'|'error'
*
* NOTE: Options could be added in the future.
* NOTE: If this function is called multiple times, remember that the
* interface could be only showing the latest notification.
*/
_notification: function(msg, level, options) {
switch (level) {
case 'normal':
case 'warn':
case 'error':
Util.Debug("Notification[" + level + "]:" + msg);
break;
default:
Util.Error("Invalid notification level: " + level);
return;
}
if (options) {
this._onNotification(this, msg, level, options);
} else {
this._onNotification(this, msg, level);
}
},
_handle_message: function () {
if (this._sock.rQlen() === 0) {
Util.Warn("handle_message called on an empty receive queue");
@ -1130,7 +1158,8 @@
switch (xvp_msg) {
case 0: // XVP_FAIL
this._updateState(this._rfb_state, "Operation Failed");
Util.Error("Operation Failed");
this._notification("XVP Operation Failed", 'error');
break;
case 1: // XVP_INIT
this._rfb_xvp_ver = xvp_ver;
@ -1322,6 +1351,7 @@
// Callback functions
['onUpdateState', 'rw', 'func'], // onUpdateState(rfb, state, oldstate, statusMsg): RFB state update/change
['onNotification', 'rw', 'func'], // onNotification(rfb, msg, level, options): notification for the UI
['onPasswordRequired', 'rw', 'func'], // onPasswordRequired(rfb, msg): VNC password is required
['onClipboard', 'rw', 'func'], // onClipboard(rfb, text): RFB clipboard contents received
['onBell', 'rw', 'func'], // onBell(rfb): RFB Bell message received
@ -2275,7 +2305,8 @@
msg = "Unknown reason";
break;
}
Util.Info("Server did not accept the resize request: " + msg);
this._notification("Server did not accept the resize request: "
+ msg, 'normal');
return true;
}

View File

@ -338,6 +338,28 @@ describe('Remote Frame Buffer Protocol Client', function() {
expect(client._disconnTimer).to.be.null;
});
});
describe('#_notification', function () {
var client;
beforeEach(function () { client = make_rfb(); });
it('should call the notification callback', function () {
client.set_onNotification(sinon.spy());
client._notification('notify!', 'warn');
var spy = client.get_onNotification();
expect(spy).to.have.been.calledOnce;
expect(spy.args[0][1]).to.equal('notify!');
expect(spy.args[0][2]).to.equal('warn');
});
it('should not call the notification callback when level is invalid', function () {
client.set_onNotification(sinon.spy());
client._notification('notify!', 'invalid');
var spy = client.get_onNotification();
expect(spy).to.not.have.been.called;
});
});
});
describe('Page States', function () {
@ -1730,11 +1752,12 @@ describe('Remote Frame Buffer Protocol Client', function() {
client._fb_height = 32;
});
it('should call updateState with a message on XVP_FAIL, but keep the same state', function () {
client._updateState = sinon.spy();
it('should send a notification on XVP_FAIL', function () {
client.set_onNotification(sinon.spy());
client._sock._websocket._receive_data(new Uint8Array([250, 0, 10, 0]));
expect(client._updateState).to.have.been.calledOnce;
expect(client._updateState).to.have.been.calledWith('normal', 'Operation Failed');
var spy = client.get_onNotification();
expect(spy).to.have.been.calledOnce;
expect(spy.args[0][1]).to.equal('XVP Operation Failed');
});
it('should set the XVP version and fire the callback with the version on XVP_INIT', function () {

View File

@ -161,6 +161,9 @@
s.innerHTML = msg;
}
}
function notification(rfb, msg, level, options) {
$D('noVNC_status').innerHTML = msg;
}
window.onresize = function () {
// When the window has been resized, wait until the size remains
@ -236,6 +239,7 @@
'local_cursor': WebUtil.getConfigVar('cursor', true),
'shared': WebUtil.getConfigVar('shared', true),
'view_only': WebUtil.getConfigVar('view_only', false),
'onNotification: notification,
'onUpdateState': updateState,
'onXvpInit': xvpInit,
'onPasswordRequired': passwordRequired,