Currently there are two layers, at which plugins can process incoming/outgoing messages. The first, lower layer is in Chat Core, where plugins can implement processIncomingMessageAsData:from:to: and processOutgoingMessageAsData:to:. The second, higher layer is in Colloquy the app, where plugins can implement processIncomingMessage:inView: and processOutgoingMessage:inView:.
Currently there is no way for plugins at the lower layer to add attributes to incoming messages, on which plugins in higher layers could work. The only changeable data is the message itself. Vice versa, plugins at the higher layer cannot add attributes to outgoing messages on which plugins in the lower layer could work. An example of a plugin needing this kind of solution is an encryption plugin, which encrypts/decrypts at the lower layer, working on raw bytes, but needs interaction at a higher layer, to mark incoming messages as decrypted, or allowing the user to override encryption for certain messages. This patch implements transient attributes for messages both in Chat Core and higher up for JVChatMessage.
At the Chat Core layer, plugin methods have been extended to processIncomingMessageAsData:from:to:attributes: and processOutgoingMessageAsData:to:attributes:, giving plugins access to attributes, too. The call for outgoing messages for now only provides a immutable attribute dictionary, as this is the last layer for sending a message, and adding/changing attributes is not that important. This might be changed in the future, so plugins could even change a message's action-flag.
Chat Core already knows about some attributes, namely @"notice" and @"action", which it sets/interprets accordingly in _handlePrivmsg:, _handleNotice: and _sendMessage:withEncoding:withAttributes:. MVChatRoom, MVChatUser and MVDirectChatConnection and all their subclasses for the different protocols got additional methods sendMessage:withEncoding:withAttributes:. Existing methods of the form sendMessage:withEncoding:withAttributes: have been kept for backwards compatibility, but just call the new methods, building a correct dictionary containing just one entry for the action-attribute.
At the higher layer, JVChatMessage now contains a mutable dictionary _attributes, which is accessed like a non-mutable dictionary for JVChatMessage, and a mutable one for JVMutableChatMessage.
JVDirectChatPanel now has a new method addMessageToDisplay:fromUser:withAttributes:withIdentifier:andType:, and as above, the existing method using isAction is still around, and just calls this new method. Calls in JVDirectChatPanel, JVChatRoomPanel and JVChatController have been modified to use the new method, but for example the Standard Commands plugin still uses the old message, as it doesn't use more than the action-attribute.