milo.classes.MessengerAPI
Base class, subclasses of which can supplement the functionality of MessageSource by implementing three methods:
translateToSourceMessage
to translate source messages (recieved from external source via MessageSOurce
) to internal messages (that are dispatched on Messenger), allowing to make internal messages more detailed than source messages. For example, Data facet uses DataMsgAPI to define several internal messages related to the change of state in contenteditable DOM element.createInternalData
to modify message data received from source to some more meaningful or more detailed message data that will be dispatched on Messenger. For example, Data facet uses DataMsgAPI (subclass of MessengerAPI) to translate DOM messages to data change messages.filterSourceMessage
to enable/disable message dispatch based on some conditions in data.If MessageSource
constructor is not passed an instance of some subclass of MessengerAPI
, it automatically creates an instance of MessengerAPI that defines all 3 of those methods in a trivial way. See these methods below for their signatures.
function MessengerAPI() {
if (this.init)
this.init.apply(this, arguments);
}
These methods should be redefined by subclass:
_.extendProto(MessengerAPI, {
init: init,
destroy: MessengerAPI$destroy,
addInternalMessage: addInternalMessage,
removeInternalMessage: removeInternalMessage,
getInternalMessages: getInternalMessages,
// should be redefined by subclass
translateToSourceMessage: translateToSourceMessage,
createInternalData: createInternalData,
filterSourceMessage: filterSourceMessage
});
MessengerAPI instance method
Called by MessengerAPI constructor. Subclasses that re-implement init
method should call this method using: MessengerAPI.prototype.init.apply(this, arguments)
function init() {
_.defineProperty(this, '_internalMessages', {});
}
Destroys messenger API
function MessengerAPI$destroy() {
}
Option name | Type | Description |
---|---|---|
message | String | internal message to be translated and added |
return | String |
MessengerAPI instance method
Translates internal message
to source message, adds internal message
to the list, making sure the same message
wasn't passed before (it would indicate Messenger error).
Returns source message if it is used first time (so that MessageSource
subcribes to this source message) or undefined
.
function addInternalMessage(message) {
var internalMsgs
, sourceMessage = this.translateToSourceMessage(message);
if (typeof sourceMessage == 'undefined') return;
if (this._internalMessages.hasOwnProperty(sourceMessage)) {
internalMsgs = this._internalMessages[sourceMessage];
if (internalMsgs.indexOf(message) == -1)
internalMsgs.push(message);
else
logger.warn('Duplicate addInternalMessage call for internal message ' + message);
} else {
internalMsgs = this._internalMessages[sourceMessage] = [];
internalMsgs.push(message);
return sourceMessage;
}
}
Option name | Type | Description |
---|---|---|
message | String | internal message to be translated and removed |
return | String |
MessengerAPI instance method
Removes internal message
from the list connected to corresponding source message (translateToSourceMessage
is used for translation).
Returns source message, if the last internal message was removed (so that MessageSource
can unsubscribe from this source message), or undefined
.
function removeInternalMessage(message) {
var sourceMessage = this.translateToSourceMessage(message);
if (typeof sourceMessage == 'undefined') return;
var internalMsgs = this._internalMessages[sourceMessage];
if (internalMsgs && internalMsgs.length) {
var messageIndex = internalMsgs.indexOf(message);
if (messageIndex >= 0) {
internalMsgs.splice(messageIndex, 1);
if (internalMsgs.length == 0) {
delete this._internalMessages[sourceMessage];
return sourceMessage;
}
} else
unexpectedNotificationWarning();
} else
unexpectedNotificationWarning();
function unexpectedNotificationWarning() {
logger.warn('notification received: un-subscribe from internal message ' + message
+ ' without previous subscription notification');
}
}
Option name | Type | Description |
---|---|---|
sourceMessage | String | source message |
return |
MessengerAPI instance method
Returns the array of internal messages that were translated to given sourceMessage
.
This method is used by MessageSource
to dispatch source message on the Mesenger
.
function getInternalMessages(sourceMessage) {
return this._internalMessages[sourceMessage];
}
Option name | Type | Description |
---|---|---|
message | String | internal message to be translated |
return | String |
MessengerAPI instance method
Subclasses should re-implement this method to define the rule for translation of internal message
to source message. This class simply returns the same message
.
function translateToSourceMessage(message) {
return message
}
Option name | Type | Description |
---|---|---|
sourceMessage | String | source message, can be used in translation rule |
message | String | internal message, can be used in translation rule |
sourceData | Object | data received from source that has to be translated to data that will be sent to internal Messenger subscriber |
return | Object |
MessengerAPI instance method
Subclasses should re-implement this method to define the rule for translation of source message data to internal message data. This class simply returns the same sourceData
.
This method is used in dispatchMessage method of MessageSource
.
function createInternalData(sourceMessage, message, sourceData) {
return sourceData;
}
Option name | Type | Description |
---|---|---|
sourceMessage | String | source message, can be used in filter rule |
message | String | internal message, can be used in filter rule |
internalData | Object | data translated by |
return | Boolean |
MessengerAPI instance method
Subclasses should re-implement this method to define the dispatch filter for internal messages. This method should return true
to allow and false
to prevent internal message dispatch. This class always returns true
.
This method is used in dispatchMessage method of MessageSource
.
function filterSourceMessage(sourceMessage, message, internalData) {
return true;
}