Closed
Bug 983347
Opened 11 years ago
Closed 10 years ago
Need different paths for displaying to the screen and sending over the wire
Categories
(Instantbird Graveyard :: Conversation, defect)
Tracking
(Not tracked)
RESOLVED
FIXED
1.6
People
(Reporter: arlolra, Assigned: arlolra)
References
(Blocks 1 open bug)
Details
Attachments
(2 files, 14 obsolete files)
24.60 KB,
patch
|
Details | Diff | Splinter Review | |
3.09 KB,
patch
|
Details | Diff | Splinter Review |
User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.149 Safari/537.36
Actual results:
Sending a message follows the same path for both.
Updated•11 years ago
|
pasting the current plan from irc
flo-retina:
what I have in mind right now: the API letting 'stuff' modify messages before they are sent will have in its return value an object that will contain the modified message, but also a flag indicating if the modified version or the original one should be shown in the conversation.
If the original message should be shown, then the conversation service prints the message itself. If the modified message should be shown, then it's up to the prpl to display the message.
btw, I find this stuff easier to think about if I have concrete examples of use cases in mind. So the examples I use are OTR and a pastebin add-on/feature.
in the case of a pastebin feature, we would want to show the modified message
it seems over complicated. But I can't come up with something nicer right now
Comment 2•11 years ago
|
||
Two other relevant messages before what's pasted in comment 1:
clokep: in http://mxr.mozilla.org/comm-central/source/chat/components/src/imConversations.js#273 you'll want to 1. display the text to the UI conversation, 2. encrypt the text, 3. pass the encrypted text to this.target.sendMsg
flo-retina: what clokep said is a very high level version of what needs to happen. The step 2 ("encrypt the text") is a bit more complicated.
You need to add there an API that will let other components (eg. your OTR code) modify messages.
As a first step, this splits displaying and sending a message in the conversation.
Updated•11 years ago
|
Assignee: nobody → arlolra
Status: NEW → ASSIGNED
Comment 4•11 years ago
|
||
Comment on attachment 8398176 [details] [diff] [review]
display.patch
Review of attachment 8398176 [details] [diff] [review]:
-----------------------------------------------------------------
I'm sure Florian will have some comments too. Many of mine are style type things which aren't a big deal but will eventually need to get fixed (and hopefully pointing them out now will keep you from having to redo work later on).
Also, can you turn on git style diffs with 8-lines of context for your next diff please? Thanks! (See https://developer.mozilla.org/en-US/docs/Installing_Mercurial#Basic_configuration for the configuration we normally use.)
::: chat/components/src/imConversations.js
@@ +271,5 @@
> get title() this.target.title,
> get startDate() this.target.startDate,
> + sendMsg: function (aMsg) {
> + this.target.sendMsg(aMsg);
> + this.target.displayMsg(aMsg);
Nit: Please use spaces, not tabs. We do 2-space indent.
::: chat/modules/jsProtoHelper.jsm
@@ +479,4 @@
> },
> sendTyping: function(aString) Ci.prplIConversation.NO_TYPING_LIMIT,
>
> + displayMsg: function (aMsg) {
Please move this between sendMsg and sendTyping. It logically belongs next to sendMsg.
::: chat/protocols/irc/irc.js
@@ +171,5 @@
> this._pendingMessage = true;
> }
> },
> +
> + displayMsg: function (aMessage) {
Nit: No space between function and (. (This is done in a few other places too, I didn't point them out.)
@@ +173,5 @@
> },
> +
> + displayMsg: function (aMessage) {
> + // Since the server doesn't send us a message back, just assume the
> + // message was received and immediately show it.
This comment makes me wonder if there should be a way for a prpl to tell the UI NOT display a message until a response is acknowledged. I'm unsure what (if any) protocols do that. (Maybe Twitter?)
::: chat/protocols/irc/test/test_splitLongMessages.js
@@ +23,5 @@
> prefix: "!user@host",
> maxMessageLength: 51, // For convenience.
> + sendMessage: function(aCommand, aParams) {
> + irc.GenericIRCConversation.messages.push(aParams[1]);
> + return true
Nit: End lines in a ;.
Attachment #8398176 -
Flags: feedback?(florian)
Re: the comment, XMPP MUC and Twitter seems to be fire and forget.
Attachment #8398176 -
Attachment is obsolete: true
Attachment #8398176 -
Flags: feedback?(florian)
twitter and xmpp muc needs a no-op displayMsg with a comment "We re-receive this messag efrom the server so it is displayed there."
Add the changes from comment 6.
Attachment #8398208 -
Attachment is obsolete: true
Attachment #8398228 -
Flags: feedback+
Attachment #8398228 -
Attachment is obsolete: true
Attachment #8398229 -
Flags: feedback+
Attachment #8398229 -
Flags: feedback?(florian)
Attachment #8398229 -
Flags: feedback?(clokep)
Attachment #8398229 -
Flags: feedback+
Comment 9•11 years ago
|
||
Comment on attachment 8398229 [details] [diff] [review]
display.patch
Review of attachment 8398229 [details] [diff] [review]:
-----------------------------------------------------------------
I don't really see how this patch relates to the discussion we have had before. Hopefully the comments I've left will help further define what needs to happen:
::: chat/components/src/imConversations.js
@@ +269,5 @@
> get name() this.target.name,
> get normalizedName() this.target.normalizedName,
> get title() this.target.title,
> get startDate() this.target.startDate,
> + sendMsg: function(aMsg) {
Where are you integrating the encryption? You need a hook before calling the prpl's sendMsg method.
@@ +270,5 @@
> get normalizedName() this.target.normalizedName,
> get title() this.target.title,
> get startDate() this.target.startDate,
> + sendMsg: function(aMsg) {
> + this.target.sendMsg(aMsg);
Maybe sendMsg could return a string with the message that should be displayed; or null if the message will be re-received from the server before it should be displayed (ie. the Twitter and XMPP MUC cases). Or maybe an object if we need to pass around more than just the displayable message text.
@@ +271,5 @@
> get title() this.target.title,
> get startDate() this.target.startDate,
> + sendMsg: function(aMsg) {
> + this.target.sendMsg(aMsg);
> + this.target.displayMsg(aMsg);
I'm wondering if displaying the message should be handled in imConversations.js instead of having some code doing it in each protocol plugin.
Attachment #8398229 -
Flags: feedback?(florian)
Assignee | ||
Comment 10•11 years ago
|
||
(In reply to Florian Quèze [:florian] [:flo] from comment #9)
> Comment on attachment 8398229 [details] [diff] [review]
> display.patch
>
> Review of attachment 8398229 [details] [diff] [review]:
> -----------------------------------------------------------------
>
> I don't really see how this patch relates to the discussion we have had
> before.
It accomplishes what's stated in the bug report. I was trying to take things one step at a time.
> Hopefully the comments I've left will help further define what needs
> to happen:
>
> ::: chat/components/src/imConversations.js
> @@ +269,5 @@
> > get name() this.target.name,
> > get normalizedName() this.target.normalizedName,
> > get title() this.target.title,
> > get startDate() this.target.startDate,
> > + sendMsg: function(aMsg) {
>
> Where are you integrating the encryption? You need a hook before calling the
> prpl's sendMsg method.
That will be in the next patch.
Sometimes OTR will need to send a message in response to a received message that is transparent to the user (particularly during the authenticated key exchange). The changes in this patch allow me to call sendMsg on the prpls without displaying anything to the user.
>
> @@ +270,5 @@
> > get normalizedName() this.target.normalizedName,
> > get title() this.target.title,
> > get startDate() this.target.startDate,
> > + sendMsg: function(aMsg) {
> > + this.target.sendMsg(aMsg);
>
> Maybe sendMsg could return a string with the message that should be
> displayed; or null if the message will be re-received from the server before
> it should be displayed (ie. the Twitter and XMPP MUC cases). Or maybe an
> object if we need to pass around more than just the displayable message text.
It would need to be an object with the to, msg, and alias fields, which differ between prpls.
If that's what you'd prefer, I'm happy to do that. But the reason I did it this way is that some prpls do some processing before displaying the message that's logically separate from sending it. An example is the txttohtml conversion in xmpp.
>
> @@ +271,5 @@
> > get title() this.target.title,
> > get startDate() this.target.startDate,
> > + sendMsg: function(aMsg) {
> > + this.target.sendMsg(aMsg);
> > + this.target.displayMsg(aMsg);
>
> I'm wondering if displaying the message should be handled in
> imConversations.js instead of having some code doing it in each protocol
> plugin.
All the displayMsg functions move the code related to displaying messages out of sendMsg and call writeMessage. If sendMsg returns an object as you'd defined above, then yes, that should be possible.
Comment 11•11 years ago
|
||
(In reply to arlolra from comment #10)
> (In reply to Florian Quèze [:florian] [:flo] from comment #9)
> > I don't really see how this patch relates to the discussion we have had
> > before.
>
> It accomplishes what's stated in the bug report. I was trying to take things
> one step at a time.
I appreciate the effort to break things down to small patches for easier review; but I want to be sure we are not doing changes that we will discover later don't actually fit our needs.
> Sometimes OTR will need to send a message in response to a received message
> that is transparent to the user (particularly during the authenticated key
> exchange). The changes in this patch allow me to call sendMsg on the prpls
> without displaying anything to the user.
Making sendMsg not display the message to the user seems the right thing to do (although I do wonder how we can get this behavior with libpurple). The part that I dislike is the displayMsg implemented by each prpl.
> > @@ +270,5 @@
> > > get normalizedName() this.target.normalizedName,
> > > get title() this.target.title,
> > > get startDate() this.target.startDate,
> > > + sendMsg: function(aMsg) {
> > > + this.target.sendMsg(aMsg);
> >
> > Maybe sendMsg could return a string with the message that should be
> > displayed; or null if the message will be re-received from the server before
> > it should be displayed (ie. the Twitter and XMPP MUC cases). Or maybe an
> > object if we need to pass around more than just the displayable message text.
>
> It would need to be an object with the to, msg, and alias fields, which
> differ between prpls.
The conversation and account objects would be accessible, so I don't think we need to pass around the alias. For 'to' (I assume you meant from), I'm not sure but I suspect we could also avoid it.
Assignee | ||
Comment 12•11 years ago
|
||
(In reply to Florian Quèze [:florian] [:flo] from comment #11)
> (In reply to arlolra from comment #10)
> > (In reply to Florian Quèze [:florian] [:flo] from comment #9)
>
> > > I don't really see how this patch relates to the discussion we have had
> > > before.
> >
> > It accomplishes what's stated in the bug report. I was trying to take things
> > one step at a time.
>
> I appreciate the effort to break things down to small patches for easier
> review; but I want to be sure we are not doing changes that we will discover
> later don't actually fit our needs.
Fair enough.
>
> > Sometimes OTR will need to send a message in response to a received message
> > that is transparent to the user (particularly during the authenticated key
> > exchange). The changes in this patch allow me to call sendMsg on the prpls
> > without displaying anything to the user.
>
> Making sendMsg not display the message to the user seems the right thing to
> do (although I do wonder how we can get this behavior with libpurple). The
> part that I dislike is the displayMsg implemented by each prpl.
Are you happy with having the prpl sendMsg return an object that imConversation
then optionally displays?
>
> > > @@ +270,5 @@
> > > > get normalizedName() this.target.normalizedName,
> > > > get title() this.target.title,
> > > > get startDate() this.target.startDate,
> > > > + sendMsg: function(aMsg) {
> > > > + this.target.sendMsg(aMsg);
> > >
> > > Maybe sendMsg could return a string with the message that should be
> > > displayed; or null if the message will be re-received from the server before
> > > it should be displayed (ie. the Twitter and XMPP MUC cases). Or maybe an
> > > object if we need to pass around more than just the displayable message text.
> >
> > It would need to be an object with the to, msg, and alias fields, which
> > differ between prpls.
>
> The conversation and account objects would be accessible, so I don't think
> we need to pass around the alias. For 'to' (I assume you meant from), I'm
> not sure but I suspect we could also avoid it.
My concern here is that prpls seem to want to use different attributes for the,
as you correctly pointed out, 'from' field. For example, xmpp uses prefers
`this._account._connection._jid.jid`, whereas yahoo defaults to
`this._account.cleanUsername`. The same is true for alias. Casing that in the
imConversations sendMsg seemslike the wrong things to do.
Comment 13•11 years ago
|
||
(In reply to arlolra from comment #12)
> (In reply to Florian Quèze [:florian] [:flo] from comment #11)
> > (In reply to arlolra from comment #10)
> > > (In reply to Florian Quèze [:florian] [:flo] from comment #9)
> > > Sometimes OTR will need to send a message in response to a received message
> > > that is transparent to the user (particularly during the authenticated key
> > > exchange). The changes in this patch allow me to call sendMsg on the prpls
> > > without displaying anything to the user.
> >
> > Making sendMsg not display the message to the user seems the right thing to
> > do (although I do wonder how we can get this behavior with libpurple). The
> > part that I dislike is the displayMsg implemented by each prpl.
>
> Are you happy with having the prpl sendMsg return an object that
> imConversation
> then optionally displays?
Yes. The message could implement the prplIMessage interface.
I'm still wondering if it's something we will manage to implement with libpurple though. Is there an easy way to obtain that behavior from the libpurple code base? Or is it going to just add a message to the conversation without our control...
Do you know how pidgin-otr solves this problem?
> prpls seem to want to use different attributes for the [...]
> 'from' field. For example, xmpp uses prefers
> `this._account._connection._jid.jid`, whereas yahoo defaults to
> `this._account.cleanUsername`.
This may be a bug (not fully sure).
> The same is true for alias.
The alias should be handled by the UI, not by the prpl. It's something that has made me frown a few times already when looking at JS prpls.
Comment 14•11 years ago
|
||
Comment on attachment 8398229 [details] [diff] [review]
display.patch
I think we need to take a step back and ensure that:
1. We agree on what we're trying to accomplish
2. We agree on the requirements
This should hopefully allow us to design an API that will not need to be changed many times in the ensuing patches.
The requirements as I see them are:
1. prpls can modify text before sending, including sending multiple sub-messages (e.g. for length reasons as on IRC)
2. An API to sit between the UI and the prpl that can modify the text send to a prpl, but display the unmodified text to the user (e.g. OTR or other encryption type stuff)
3. Some prpls get a ack that a message was received and should not be displayed until that point (e.g. on Twitter we get our own tweets sent back to us)
4. Messages must go through an API before being shown to the user (e.g. OTR gets messages that contain no plaintext, only encoded information)
5. Some text might need to be sent without the users knowledge (e.g. the OTR handshake)
Do all of these make sense? Am I missing any?
We have two use-cases in mind:
1. OTR where ciphertext is sent to the network and plaintext is displayed to the user.
2. Pastebin Add-on where the original text is discarded and replaced with a link.
An additional thing to think about, what if I have both the Pastebin Add-on and OTR installed? How do they interact? (Everything should be fine if the Pastebin one is "run" first, but the opposite is not true...)
Attachment #8398229 -
Flags: feedback?(clokep)
Comment 15•11 years ago
|
||
(In reply to Patrick Cloke [:clokep] from comment #14)
> The requirements as I see them are:
[...]
> Do all of these make sense?
Yes.
> Am I missing any?
6. The API we come up with needs to be reasonable to implement both for js-prpls and libpurple.
Assignee | ||
Comment 16•11 years ago
|
||
> Do you know how pidgin-otr solves this problem?
It adds a signal handler that listens for "sending-im-msg". When that fires, it intercepts the message and passes it to otr for processing. If otr fragments the encrypted response, it'll inject all but the last message itself. It then swaps in a pointer to the final encrypted message so that the normal course of continues.
> An additional thing to think about, what if I have both the Pastebin Add-on and OTR installed? How do they interact? (Everything should be fine if the Pastebin one is "run" first, but the opposite is not true...)
Until recently, I think you were just expected not to do this. If you're using otr, you probably don't want to be pasting plaintext. However, the latest pidgin api provides priorities to the signal handlers.
Assignee | ||
Comment 17•11 years ago
|
||
I have two ideas here, neither of which are entirely satisfying.
The api to libpurple is limited to accepting a string to send and then notifying when that's accomplished. If transforms are happening in imConversation, we'd need to buffer tuples of strings (sent, display) set by the transforms and retrieved by the message in the callback.
Either that, or forgo async transforms (like Pastebin) and mimic what pidgin-otr does in libpurple, making similar changes to the js prpls.
Comment 18•11 years ago
|
||
(In reply to arlolra from comment #17)
> I have two ideas here, neither of which are entirely satisfying.
>
> The api to libpurple is limited to accepting a string to send and then
> notifying when that's accomplished. If transforms are happening in
> imConversation, we'd need to buffer tuples of strings (sent, display) set by
> the transforms and retrieved by the message in the callback.
That's unfortunate but not unacceptable. I've also scratched my head while looking at the existing libpurple API and didn't find anything I fully liked to work around the fact that the libpurple prpls directly call write_conv without context.
> Either that, or forgo async transforms (like Pastebin) and mimic what
> pidgin-otr does in libpurple, making similar changes to the js prpls.
I'm not sure I fully understand this solution, but I suspect the changes to the js prpls would be even more unpleasant than the first proposed solution.
Assignee | ||
Comment 19•11 years ago
|
||
(In reply to Florian Quèze [:florian] [:flo] from comment #18)
> That's unfortunate but not unacceptable. I've also scratched my head while
> looking at the existing libpurple API and didn't find anything I fully liked
> to work around the fact that the libpurple prpls directly call write_conv
> without context.
In that case, I'll proceed down this road.
prpls will need to fire a new event (text-sent, or something) for the replacer to observe, which will fire the new-text event in turn.
> > Either that, or forgo async transforms (like Pastebin) and mimic what
> > pidgin-otr does in libpurple, making similar changes to the js prpls.
>
> I'm not sure I fully understand this solution, but I suspect the changes to
> the js prpls would be even more unpleasant than the first proposed solution.
The shape would be something like this: the js prpl would need to implement a toWire
that does the final step of sending a msg. the prpl's sendMsg would call a generic
transformMsg that performs the synchronous operations and calls toWire as necessary.
The sync restriction is to conform with running them in a signal handler in libpurple,
as in pidgin-otr.
Comment 20•11 years ago
|
||
(In reply to arlolra from comment #19)
> (In reply to Florian Quèze [:florian] [:flo] from comment #18)
> > That's unfortunate but not unacceptable. I've also scratched my head while
> > looking at the existing libpurple API and didn't find anything I fully liked
> > to work around the fact that the libpurple prpls directly call write_conv
> > without context.
>
> In that case, I'll proceed down this road.
>
> prpls will need to fire a new event (text-sent, or something) for the
> replacer to observe, which will fire the new-text event in turn.
I'm a bit uncomfortable with the idea of having the text replacer fire events instead of the prpls.
What about having prpls call a method of the conversation, and having the conversation object communicate with the replacer?
Assignee | ||
Comment 21•11 years ago
|
||
(In reply to Florian Quèze [:florian] [:flo] from comment #20)
> I'm a bit uncomfortable with the idea of having the text replacer fire
> events instead of the prpls.
>
> What about having prpls call a method of the conversation, and having the
> conversation object communicate with the replacer?
Yes, that will work. I'll do that.
Comment 22•11 years ago
|
||
I wonder if this means we no longer need to have so many different implementations of the prplIMessage interface. If we could have a single implementation of the message object in imConversations.js, I think we would get a nice code simplification.
Assignee | ||
Comment 23•11 years ago
|
||
Here's a rot13 transform using this api: https://gist.github.com/arlolra/11151564
Attachment #8398229 -
Attachment is obsolete: true
Attachment #8409753 -
Flags: feedback?(florian)
Attachment #8409753 -
Flags: feedback?(clokep)
Comment 24•11 years ago
|
||
Comment on attachment 8409753 [details] [diff] [review]
transform.patch
Florian will hopefully give more specific feedback at some point, but aleth, him and I had a conversation about this that boiled down to a few points:
- The current proposed API probably adds too many interfaces, some of this could be done with observers.
- The changes in jsProtoHelper should most likely be in imConversations.
- Changes to the message interface should actually change prplIMessage, there shouldn't be protocol specific versions of this.
Also, please include comments about what each of these APIs does, etc. I had to read the whole patch before understanding how everything fit together.
Attachment #8409753 -
Flags: feedback?(clokep) → feedback+
Comment 25•11 years ago
|
||
Comment on attachment 8409753 [details] [diff] [review]
transform.patch
Review of attachment 8409753 [details] [diff] [review]:
-----------------------------------------------------------------
::: chat/components/public/prplIConversation.idl
@@ +12,5 @@
> interface nsIURI;
> interface nsIDOMDocument;
> +interface prplIConversation;
> +
> +/* A tMsg interface */
Interfaces really need descriptive comments.
@@ +14,5 @@
> +interface prplIConversation;
> +
> +/* A tMsg interface */
> +[scriptable, uuid(b62563d6-c8ff-11e3-b0b0-42251e5d46b0)]
> +interface tMessage : nsISupports {
Is this something that should be part of prplIMessage? What's the purpose of this interface?
@@ +21,5 @@
> +};
> +
> +/* A generic callback */
> +[scriptable, function, uuid(fe7d8cdc-c8e4-11e3-bdf4-1c101e5d46b0)]
> +interface callback : nsISupports {
All the interfaces we define have a prefix:
"im" for things that are implemented by the chat/ core (shared by Instantbird and Thunderbird)
"prpl" for things implemented by each protocol plugin
"ib" for things specific to Instantbird (these shouldn't exist in chat/).
@@ +22,5 @@
> +
> +/* A generic callback */
> +[scriptable, function, uuid(fe7d8cdc-c8e4-11e3-bdf4-1c101e5d46b0)]
> +interface callback : nsISupports {
> + void invoke([optional] in AUTF8String aMsg);
The parameter being optional here makes me wonder if you could just have used nsIRunnable
@@ +25,5 @@
> +interface callback : nsISupports {
> + void invoke([optional] in AUTF8String aMsg);
> +};
> +
> +/* A transform */
It's not clear what a "transform" is. What should implement this interface? What's responsible for calling its methods?
@@ +71,5 @@
>
> + /* Transform a message */
> + void transformMsg(in AUTF8String aMsg, in boolean isSending, in callback aCb);
> + void addTransform(in transform aTransform);
> + void removeTransform(in transform aTransform);
Conversation objects already support observers (addObserver, removeObserver methods). Could you get what you want by just firing more observer notifications? Maybe fire a notification when a message is about to be sent, with the prplIMessage object as aSubject parameter.
::: chat/modules/jsProtoHelper.jsm
@@ +478,5 @@
> throw Cr.NS_ERROR_NOT_IMPLEMENTED;
> },
> sendTyping: function(aString) Ci.prplIConversation.NO_TYPING_LIMIT,
>
> + addTransform: function(aTransform) {
I really think you don't want to have each prpl implement add/removeTransform methods in addition to the existing observers.
@@ +485,5 @@
> + },
> + removeTransform: function(aTransform) {
> + this._transforms = this._transforms.filter(function (o) o !== aTransform);
> + },
> + transformMsg: function(aMsg, isSending, aCb) {
I used to think that you also don't want to implement this in the prpls, but I'm increasingly thinking that if we can just simplify this to firing a few observer notifications, it would be acceptable to have an implementation in jsProtoHelper and one in purplexpcom.
Attachment #8409753 -
Flags: feedback?(florian) → review-
Comment 26•11 years ago
|
||
Here's a proposal; let me know if it addresses your use case correctly:
I think you want the process of sending/receiving/displaying a message to fire 3 distinct observer notifications:
- sending-message
-- the aSubject parameter is a prplIMessage (or a new interface wrapping a prplIMessage) where the message can still be modified (or maybe even cancelled?) by observers
- receiving-message
-- aSubject would be a prplIMessage or an interface wrapping it. Observers can modify the message, or stop its processing.
- new-text (the current notification)
-- This is fired to tell the UI to display the message in the conversation.
Note: all names in this proposal can be modified/tweaked for better consistency.
Assignee | ||
Comment 27•11 years ago
|
||
> - sending-message
> -- the aSubject parameter is a prplIMessage (or a new interface wrapping a
> prplIMessage) where the message can still be modified (or maybe even
> cancelled?) by observers
To make this more concrete, you're saying in imConversation.js sendMsg() would first fire "sending-message" that the transformer (otr, etc.) would modify, and then continue doing target.sendMsg(). This doesn't work for the async case (pastebin) that was mentioned above.
Comment 28•11 years ago
|
||
(In reply to arlolra from comment #27)
> > - sending-message
> > -- the aSubject parameter is a prplIMessage (or a new interface wrapping a
> > prplIMessage) where the message can still be modified (or maybe even
> > cancelled?) by observers
>
> To make this more concrete, you're saying in imConversation.js sendMsg()
> would first fire "sending-message" that the transformer (otr, etc.) would
> modify, and then continue doing target.sendMsg(). This doesn't work for the
> async case (pastebin) that was mentioned above.
Observers performing an async processing could cancel the message (ie. stop it) and then reinsert a new message once they get the result from the async operation.
Assignee | ||
Comment 29•11 years ago
|
||
(In reply to Florian Quèze [:florian] [:flo] from comment #28)
> Observers performing an async processing could cancel the message (ie. stop
> it) and then reinsert a new message once they get the result from the async
> operation.
Can you elaborate on what you mean by reinsert. Let's say you wanted to run two transformations and the first one is async. When does the second one run and how do you avoid calling the first one twice.
Comment 30•11 years ago
|
||
(In reply to arlolra from comment #29)
> When does the second one run
> and how do you avoid calling the first one twice.
The second (or Nth) runs when no transformation before it cancels the message.
I don't see any generic way to avoid calling the same transformation twice, but I also can't see any real use case of a transformation that would be both async and unable to detect if it needs to be performed again (pastebin would detect that the pastebin url is short and not worth pastebining; other transformations that would fix typos or automatically add links would just do nothing if they have already transformed the message before (+ these are sync operations)).
Assignee | ||
Comment 31•11 years ago
|
||
This patch implements Florian's above proposal. Because of the libpurple limitations, there's an implicit contract that whatever message the UIConversation passes to a prpl, it'll get back as is when "new-text" is notified. This requires making a few changes to the js prpls to make use of the new API to apply their transforms (think irc message splitting). The one caveat is that observers need to be fired by priority for it to work.
Attachment #8409753 -
Attachment is obsolete: true
Attachment #8438931 -
Flags: feedback?(florian)
Attachment #8438931 -
Flags: feedback?(clokep)
Comment 32•11 years ago
|
||
Comment on attachment 8438931 [details] [diff] [review]
transform.patch
arlo and flo are pair programmed on this a bit today at the Tor conference (or whatever it's called) in Paris. Clearing feedback on this as I'm sure arlo got good feedback in person! (And we discussed the API a bit over IRC after flo and arlo had discussed.)
Attachment #8438931 -
Flags: feedback?(florian)
Attachment #8438931 -
Flags: feedback?(clokep)
Attachment #8438931 -
Flags: feedback+
Assignee | ||
Comment 33•11 years ago
|
||
I started implementing the newly proposed API but ran into a few issues. Here's the patch so you can follow along, https://gist.github.com/14d38c35c65b555677ec
1) JS arrays do *not* implement the nsIMutableArray interface (ie. queryElementAt is not an available method), so we'll need to introduce a bunch of helpers (not present in the above patch at the time of writing) for converting back-and-forth, which is tedious.
2) We will need the converse of prepareForSending (ie. prepareForDisplaying) because the irc prpl wants to apply ctcpFormatToHTML before displaying.
3) We concentrated a lot of outgoing messages, at the neglect of incoming (and displaying) them. The logic I had in the last patch waited for "new-text" to be emitted, but that only worked because I made the originalMessage mutable. Here I put a bunch of stuff in writeMessage, which seems wrong. Maybe the conversation service should expose a displayMsg method, that receive the text, conversation and properties so it can notifyObservers (with cancellableMessages) and then emit "new-text"? Hopefully the issue here is clear, if not the solution.
4) In practice, working with both an array of sending strings and a linked list of cancellableMessages is a little cumbersome. As an example, see prepareForSending in the irc prpl where it splits strings.
5) I've added a "displaying-message" event, for outgoing messages, which is distinct from "receiving-message" for incoming.
Comment 34•11 years ago
|
||
Patch reviews (even WIPs) are easier on bugzilla.
Attachment #8438931 -
Attachment is obsolete: true
Comment 35•11 years ago
|
||
(In reply to arlolra from comment #33)
> 1) JS arrays do *not* implement the nsIMutableArray interface
Do you remember I was unhappy about having to use an nsIMutableArray? I guess now you understand why.
An other solution if we really want JS Arrays could be to have a method returning an array, instead of having an attribute. But then we may need a second method to modify the array, as the arrays returned by methods are copies, not references :-/.
> 2) We will need the converse of prepareForSending (ie. prepareForDisplaying)
> because the irc prpl wants to apply ctcpFormatToHTML before displaying.
Do we actually need this? If the encryption happened on the HTML message, then decrypting the message should output HTML, and I don't think we need to apply ctcp formatting.
I don't know much about ctcp though, so clokep's opinion would be very welcome here.
> 3) We concentrated a lot of outgoing messages, at the neglect of incoming
> (and displaying) them. The logic I had in the last patch waited for
> "new-text" to be emitted, but that only worked because I made the
> originalMessage mutable. Here I put a bunch of stuff in writeMessage, which
> seems wrong. Maybe the conversation service should expose a displayMsg
> method, that receive the text, conversation and properties so it can
> notifyObservers (with cancellableMessages) and then emit "new-text"?
> Hopefully the issue here is clear, if not the solution.
I think the issue is clear, yes. We forgot to discuss the canceling of incoming messages yesterday.
The conversation service already seems to receive all messages in a single place (http://lxr.instantbird.org/instantbird/source/chat/components/src/imConversations.js#251) so I don't see how adding a method would help.
I'm wondering if we shouldn't create an imIMessage interface inheriting from prplIMessage, but with more attributes. This interface would be implemented by the conversation service, and an instance of imMessage would be created for each received prplMessage, and sent to conversation observers.
> 4) In practice, working with both an array of sending strings and a linked
> list of cancellableMessages is a little cumbersome. As an example, see
> prepareForSending in the irc prpl where it splits strings.
That method seems either not finished, or not doing what you want.
> 5) I've added a "displaying-message" event, for outgoing messages, which is
> distinct from "receiving-message" for incoming.
I'm under the impression that these 2 notifications want to be fired from the observeConv method of the conversation service, rather than from jsProtoHelper.
Comment 36•11 years ago
|
||
(In reply to Florian Quèze [:florian] [:flo] from comment #35)
> (In reply to arlolra from comment #33)
> > 2) We will need the converse of prepareForSending (ie. prepareForDisplaying)
> > because the irc prpl wants to apply ctcpFormatToHTML before displaying.
>
> Do we actually need this? If the encryption happened on the HTML message,
> then decrypting the message should output HTML, and I don't think we need to
> apply ctcp formatting.
>
> I don't know much about ctcp though, so clokep's opinion would be very
> welcome here.
I'd think the encryption should apply to the raw CTCP message, not to HTML. But I'm not positive how other clients would receive this.
Assignee | ||
Comment 37•11 years ago
|
||
Attachment #8450280 -
Flags: feedback?(clokep)
Attachment #8450280 -
Flags: feedback?(aleth)
Assignee | ||
Comment 38•11 years ago
|
||
Comment on attachment 8450280 [details] [diff] [review]
transform.patch
Review of attachment 8450280 [details] [diff] [review]:
-----------------------------------------------------------------
::: chat/components/src/imConversations.js
@@ +337,5 @@
> this.target = this._prplConv[aTargetId];
> +
> + if (aTopic == "new-text") {
> + aSubject = new imMessage(aSubject);
> + this.notifyObservers(aSubject, "received-message");
if (aSubject.cancelled)
return;
Comment 39•11 years ago
|
||
Comment on attachment 8450280 [details] [diff] [review]
transform.patch
Review of attachment 8450280 [details] [diff] [review]:
-----------------------------------------------------------------
This is a much nicer API than the last version I saw - thanks for improving this so much!
The interface file needs some documentatory comments (most of what's needed seems to already exist in comments in imConversations).
I'd like clokep to take a look at the way this will interact with ctcp in IRC.
Attachment #8450280 -
Flags: feedback?(aleth) → feedback+
Comment 40•11 years ago
|
||
Comment on attachment 8450280 [details] [diff] [review]
transform.patch
Review of attachment 8450280 [details] [diff] [review]:
-----------------------------------------------------------------
Please add a lot of comments to the interfaces! (As aleth said earlier.)
The question with CTCP messages is, what should get encrypted? (In all my examples below I'm using ` to be \001, cause it's easier.)
If the user types "/me foobar" to somenick, this becomes PRIVMSG somenick :`ACTION foobar`. Do we expect just "foobar" to be encrypted or `ACTION foobar` to be encrypted? (We should probably match whatever other clients do!)
Encrypting just "foobar" is nice because we can do all the CTCP processing first and just hand the encrypted string to the UI and it'll get decrypted before being shown...
But...
CTCP is also used for formatting (I use * below to be ^B):
The user types "Hello <b>bob</b>" to somenick, becomes "PRIVMSG somenick :Hello *bob*"
The question here is...do you care about the CTCP entities at all or do you just encrypt the entire HTML block: "Hello <b>bob</b>"
::: chat/components/src/imConversations.js
@@ +377,5 @@
> + // prpls have an opportunity here to preprocess messages before they are
> + // sent, eg. split long messages. If a message is split here, the split
> + // will be visible in the UI.
> + // prpls can return null if they don't need to make any change
> + let messages = this.target.prepareForSending(om) || [om.message];
Why the || here? In case this is not implemented by a prpl?
Updated•11 years ago
|
Attachment #8450280 -
Flags: feedback?(clokep) → feedback+
Comment 41•11 years ago
|
||
(In reply to Patrick Cloke [:clokep] from comment #40)
> If the user types "/me foobar" to somenick, this becomes PRIVMSG somenick
> :`ACTION foobar`. Do we expect just "foobar" to be encrypted or `ACTION
> foobar` to be encrypted? (We should probably match whatever other clients
> do!)
>
> Encrypting just "foobar" is nice because we can do all the CTCP processing
> first and just hand the encrypted string to the UI and it'll get decrypted
> before being shown...
I think I would encrypt only "foobar".
> The question here is...do you care about the CTCP entities at all or do you
> just encrypt the entire HTML block: "Hello <b>bob</b>"
The latter, I think it makes sense to just encrypt the HTML message. (We did have a long debate about this in Paris, and IIRC the conclusion was that it was very likely undefined behavior.)
> ::: chat/components/src/imConversations.js
> @@ +377,5 @@
> > + // prpls have an opportunity here to preprocess messages before they are
> > + // sent, eg. split long messages. If a message is split here, the split
> > + // will be visible in the UI.
> > + // prpls can return null if they don't need to make any change
> > + let messages = this.target.prepareForSending(om) || [om.message];
>
> Why the || here? In case this is not implemented by a prpl?
The || here is something I added to make no-op implementations trivial: they can just return null instead of bothering with returning an array. I expect this to be particularly handy for the C++ implementation in purplexpcom; but this isn't really required.
Assignee | ||
Comment 42•11 years ago
|
||
Thanks for taking a look. Comments are forthcoming.
I updated the OTR extension to make use of this new API. Here's what sending looks like,
https://github.com/arlolra/ctypes-otr/blob/master/chrome/content/otr.js#L410-L457
A few things came up:
* OTR does this thing where if you set a policy, REQUIRE_ENCRYPTION, it'll buffer messages internally until the authenticated key exchange is complete, and then send them off. In this case, no message is returned from libotr but you still want to call writeMessage to display them to the sender (and assume they'll be delivered eventually).
* We described in comment #14 that there're a few instances where OTR wants to send its own messages (call target.sendMsg) in response to having received a msg. In that case, any other listener for "sending-message" will never see them.
* We don't have priorities for observers so OTR kind of wants to be alone listening on "sending-message" anyways to ensure it's last in the chain. Anything else altering the msgs there (when OTR is enabled) is playing with undefined behaviour.
* With all that in mind, I think we should eliminate imISendableMessage and just keep imIOutgoingMessage, but change the conversation attribute to target. We can still provide the conversation there for "preparing-message" since imIOutgoingMessage inherits from prplIConversation (I hope that's right). Any fragmentation OTR does can inject messages (with target.sendMsg and OTRL_FRAGMENT_SEND_ALL_BUT_LAST as I had it before, since it already needs to do that above). This avoids having to loop over getSendableMessages(), which I find a little unpleasant in practice.
Comment 43•11 years ago
|
||
(In reply to arlolra from comment #42)
> * OTR does this thing where if you set a policy, REQUIRE_ENCRYPTION, it'll
> buffer messages internally until the authenticated key exchange is complete,
> and then send them off. In this case, no message is returned from libotr but
> you still want to call writeMessage to display them to the sender (and
> assume they'll be delivered eventually).
Wouldn't you want to display them once they are sent?
> * We described in comment #14 that there're a few instances where OTR wants
> to send its own messages (call target.sendMsg) in response to having
> received a msg. In that case, any other listener for "sending-message" will
> never see them.
>
> * We don't have priorities for observers so OTR kind of wants to be alone
> listening on "sending-message" anyways to ensure it's last in the chain.
> Anything else altering the msgs there (when OTR is enabled) is playing with
> undefined behaviour.
These 2 points don't worry me too much.
> * With all that in mind, I think we should eliminate imISendableMessage and
> just keep imIOutgoingMessage, but change the conversation attribute to
> target.
I don't see how that relates to the above.
> since imIOutgoingMessage inherits from prplIConversation (I hope that's
> right).
I hope you meant imIConversation inherits from prplIConversation, otherwise, no, that's not right.
Assignee | ||
Comment 44•11 years ago
|
||
(In reply to Florian Quèze [:florian] [:flo] from comment #43)
> (In reply to arlolra from comment #42)
>
> > * OTR does this thing where if you set a policy, REQUIRE_ENCRYPTION, it'll
> > buffer messages internally until the authenticated key exchange is complete,
> > and then send them off. In this case, no message is returned from libotr but
> > you still want to call writeMessage to display them to the sender (and
> > assume they'll be delivered eventually).
>
> Wouldn't you want to display them once they are sent?
Ideally, but I don't think there's any context provided with the ciphertext to say to which message it corresponds. I guess you can listen for when the AKE is complete and assume each subsequent messages pair up, but that's not always true. Depending on who initiates the AKE, you may be sending another response after going secure. Also, with fragmentation, you'd need to parse the head (?OTRv3,1,3) to determine where each message ends.
Pidgin-otr seems to just assumes delivery.
>
> > * We described in comment #14 that there're a few instances where OTR wants
> > to send its own messages (call target.sendMsg) in response to having
> > received a msg. In that case, any other listener for "sending-message" will
> > never see them.
> >
> > * We don't have priorities for observers so OTR kind of wants to be alone
> > listening on "sending-message" anyways to ensure it's last in the chain.
> > Anything else altering the msgs there (when OTR is enabled) is playing with
> > undefined behaviour.
>
> These 2 points don't worry me too much.
>
>
> > * With all that in mind, I think we should eliminate imISendableMessage and
> > just keep imIOutgoingMessage, but change the conversation attribute to
> > target.
>
> I don't see how that relates to the above.
Well, the above said,
"Any fragmentation OTR does can inject messages (with target.sendMsg and OTRL_FRAGMENT_SEND_ALL_BUT_LAST as I had it before, since it already needs to do that above)"
which means we don't really need the getSendableMessages() array, which is only significant difference between those two interfaces.
>
> > since imIOutgoingMessage inherits from prplIConversation (I hope that's
> > right).
>
> I hope you meant imIConversation inherits from prplIConversation, otherwise,
> no, that's not right.
Whoops, yes, that's what I meant. Sorry.
Assignee | ||
Comment 45•10 years ago
|
||
Sorry for the extended delay. I added some comments to the interfaces, as requested, and removed the imISendableMessage interface as described in comment 44.
Updated the OTR extension to use this API and it seems to be working reasonably well.
https://github.com/arlolra/ctypes-otr/commit/b7f2305b75576b6b44ae43bd9278d99ac1a649e8
As always, your feedback is appreciated.
Attachment #8450280 -
Attachment is obsolete: true
Attachment #8480381 -
Flags: review?(florian)
Attachment #8480381 -
Flags: review?(clokep)
Attachment #8480381 -
Flags: review?(aleth)
Comment 46•10 years ago
|
||
Comment on attachment 8480381 [details] [diff] [review]
transform.patch from comment 44
Review of attachment 8480381 [details] [diff] [review]:
-----------------------------------------------------------------
This looks good! I made a few comments...half of which are nits. The other half are pretty much asking for more comments. My only major concern is the ordering in the sendMsg function, see below.
::: chat/components/public/imIConversationsService.idl
@@ +85,5 @@
> +// opportunity to swap or cancel the message.
> +[scriptable, uuid(bd2f77d4-1fad-432d-a914-6bb5ed5c13d0)]
> +interface imIMessage: prplIMessage {
> + attribute boolean cancelled;
> + attribute AUTF8String decodedMessage;
Decoded message? That's pretty specific...what's that really mean anyway?
::: chat/components/public/prplIConversation.idl
@@ +45,5 @@
>
> /* Send a message in the conversation */
> void sendMsg(in AUTF8String aMsg);
>
> + void prepareForSending(in imIOutgoingMessage message,
This needs a comment above it.
::: chat/components/src/imConversations.js
@@ +14,5 @@
> XPCOMUtils.defineLazyGetter(this, "bundle", function()
> Services.strings.createBundle("chrome://chat/locale/conversations.properties")
> );
>
> +function OutgoingMessage(message, conversation) {
Nit: Start parameters with "a", so:
function OutgoingMessage(aMessage, aConversation)
This is true for all functions.
@@ +39,5 @@
> +
> + get message() this.prplMessage.message,
> + set message(msg) { this.prplMessage.message = msg; },
> +
> + // from prplIMessage
If we have the message...do we really need all these fields? (Does this just make the change less invasive in other places?)
@@ +325,5 @@
> (aTopic == "update-typing" &&
> this._prplConv[aTargetId].typingState == Ci.prplIConvIM.TYPING)))
> this.target = this._prplConv[aTargetId];
> +
> + if (aTopic == "new-text") {
I'm not entirely sure I understand this change.
@@ +359,5 @@
> + sendMsg: function(aMsg) {
> + // Add-ons (eg. pastebin) have an opportunity to cancel the message at this
> + // point, or change the text content of the message.
> + // If an add-on wants to split a message, it should truncate the first
> + // message, and insert new messages using the conversation's sendMsg method.
Are we concerned about ordering here? What if I'm using the pastebin add-on, send a huge message (A) immediately followed by a very short message (B). If the pastebin add-on cancels the first message (A) and adds a new short message (A*), I'd end up sending B, A*; but the user wanted to send A / A*, B.
@@ +365,5 @@
> + this.notifyObservers(om, "preparing-message");
> + if (om.cancelled)
> + return;
> +
> + // Prpls have an opportunity here to preprocess messages before they are
I think we normally write this out in comments "Protocols".
::: chat/modules/imThemes.jsm
@@ +370,1 @@
> msgClass.push("action");
I still wish this was a flag...but I'm certainly not going to ask you to change it. :)
::: chat/protocols/xmpp/xmpp.jsm
@@ +38,5 @@
> );
>
> +XPCOMUtils.defineLazyGetter(this, "TXTToHTML", function() {
> + let cs = Cc["@mozilla.org/txttohtmlconv;1"].getService(Ci.mozITXTToHTMLConv);
> + return function(aTXT) cs.scanTXT(aTXT, cs.kEntities);
Nit: aTxt.
@@ +251,5 @@
>
> + prepareForSending: function(aOm, aCount) {
> + if (aCount)
> + aCount.value = 1;
> + return [TXTToHTML(aOm.message)];
While we're touching this, can you add a comment about why this is necessary please.
Attachment #8480381 -
Flags: review?(clokep) → review-
Assignee | ||
Comment 47•10 years ago
|
||
Comment on attachment 8480381 [details] [diff] [review]
transform.patch from comment 44
Review of attachment 8480381 [details] [diff] [review]:
-----------------------------------------------------------------
Thanks for taking a look. I'll get this cleaned up shortly.
::: chat/components/public/imIConversationsService.idl
@@ +85,5 @@
> +// opportunity to swap or cancel the message.
> +[scriptable, uuid(bd2f77d4-1fad-432d-a914-6bb5ed5c13d0)]
> +interface imIMessage: prplIMessage {
> + attribute boolean cancelled;
> + attribute AUTF8String decodedMessage;
The content to display to the user.
::: chat/components/src/imConversations.js
@@ +39,5 @@
> +
> + get message() this.prplMessage.message,
> + set message(msg) { this.prplMessage.message = msg; },
> +
> + // from prplIMessage
The latter (less invasive elsewhere).
@@ +325,5 @@
> (aTopic == "update-typing" &&
> this._prplConv[aTargetId].typingState == Ci.prplIConvIM.TYPING)))
> this.target = this._prplConv[aTargetId];
> +
> + if (aTopic == "new-text") {
The comment where the imIMessage interface is defined sums it up.
When a new message is to be displayed, we notify listening observers so they can make changes. In the OTR case, that's decrypting the message. The imMessage wraps a prplMessage to provide a field for cancelling the message (if it's not intended to be displayed to the user) or a place to put the decoded content (without making originalMessage editable).
@@ +359,5 @@
> + sendMsg: function(aMsg) {
> + // Add-ons (eg. pastebin) have an opportunity to cancel the message at this
> + // point, or change the text content of the message.
> + // If an add-on wants to split a message, it should truncate the first
> + // message, and insert new messages using the conversation's sendMsg method.
There were past proposals (and patches) that did more to handle the async case.
We settled on pushing that business into the add-on. It has the responsibility of buffering message and assuring proper order.
Similarly, the OTR extension maintains a map of encrypted/decrypted messages so that it knows which plaintext message to display to the sender when the prpl waits for an async confirmation before emitting it as sent.
::: chat/protocols/xmpp/xmpp.jsm
@@ +251,5 @@
>
> + prepareForSending: function(aOm, aCount) {
> + if (aCount)
> + aCount.value = 1;
> + return [TXTToHTML(aOm.message)];
Hmmm, on the left hand side this is being applied for the senders benefit, but here it's affecting both.
It's been some time but I seem to recall this being superfluous and should probably be removed entirely. Please correct me if I'm wrong.
Assignee | ||
Comment 48•10 years ago
|
||
Updated based on clokep's review.
Attachment #8480381 -
Attachment is obsolete: true
Attachment #8480381 -
Flags: review?(florian)
Attachment #8480381 -
Flags: review?(aleth)
Attachment #8484485 -
Flags: review?(florian)
Attachment #8484485 -
Flags: review?(clokep)
Attachment #8484485 -
Flags: review?(aleth)
Comment 49•10 years ago
|
||
Comment on attachment 8484485 [details] [diff] [review]
transform.patch from comment 46
Review of attachment 8484485 [details] [diff] [review]:
-----------------------------------------------------------------
Just a minor nit, overall it looks good! Thanks for updating this so fast. :)
::: chat/components/public/imIConversationsService.idl
@@ +86,5 @@
> +// eventually gets shown to the user.
> +[scriptable, uuid(bd2f77d4-1fad-432d-a914-6bb5ed5c13d0)]
> +interface imIMessage: prplIMessage {
> + attribute boolean cancelled;
> + attribute AUTF8String displayMessage;
Nit: Put the comment about what this field is right above the field.
Attachment #8484485 -
Flags: review?(clokep) → review+
Comment 50•10 years ago
|
||
Comment on attachment 8484485 [details] [diff] [review]
transform.patch from comment 46
Review of attachment 8484485 [details] [diff] [review]:
-----------------------------------------------------------------
This looks good to me overall! Thanks for all your work on this.
::: chat/components/public/prplIConversation.idl
@@ +49,5 @@
> + /* Preprocess messages before they are sent (eg. split long messages).
> + Can return null if no changes are to be made. */
> + void prepareForSending(in imIOutgoingMessage message,
> + [optional] out unsigned long messageCount,
> + [retval, array, size_is(messageCount)] out string messages);
Unless I am missing something, you probably need wstring here so Unicode messages work. Please test this!
::: chat/modules/jsProtoHelper.jsm
@@ +471,5 @@
> }
> }
> },
>
> + prepareForSending: function(aOm, aCount) null,
Can we use something more descriptive than aOm? Is it short for aOriginalMessage?
::: chat/protocols/irc/irc.js
@@ +133,5 @@
> " :\r\n";
> return this._account.maxMessageLength -
> this._account.countBytes(baseMessage);
> },
> + prepareForSending: function(aOm, aCount) {
Same here, for legibility.
Attachment #8484485 -
Flags: review?(aleth) → review-
Comment 51•10 years ago
|
||
(In reply to aleth [:aleth] from comment #50)
> ::: chat/components/public/prplIConversation.idl
> @@ +49,5 @@
> > + /* Preprocess messages before they are sent (eg. split long messages).
> > + Can return null if no changes are to be made. */
> > + void prepareForSending(in imIOutgoingMessage message,
> > + [optional] out unsigned long messageCount,
> > + [retval, array, size_is(messageCount)] out string messages);
>
> Unless I am missing something, you probably need wstring here so Unicode
> messages work. Please test this!
AUTF8String for unicode strings.
string and wstring are deprecated, they cause the whole string to be memcpy'ed each time the xpconnect boundary is crossed.
Assignee | ||
Comment 52•10 years ago
|
||
Fixed the nits and switched to wstring.
There was also a problem that system messages weren't being displayed. I moved the imMessage definition to the jsProtoHelper, and now emit them directly when the conversation is attached to a Message, rather than swapping in observeConv, which isn't watching for system messages from the conversation service itself. Hopefully that makes sense.
Attachment #8484485 -
Attachment is obsolete: true
Attachment #8484485 -
Flags: review?(florian)
Attachment #8485224 -
Flags: review?(florian)
Attachment #8485224 -
Flags: review?(clokep)
Attachment #8485224 -
Flags: review?(aleth)
Comment 53•10 years ago
|
||
Comment on attachment 8485224 [details] [diff] [review]
transform.patch from 49-50
Review of attachment 8485224 [details] [diff] [review]:
-----------------------------------------------------------------
I haven't re-read all the previous discussion, only looked at the code, and overall this looks pretty good. I just found one issue.
(In reply to arlolra from comment #52)
> I moved the imMessage definition to the jsProtoHelper, and now emit them
> directly when the conversation is attached to a Message, rather than
> swapping in observeConv,
This change isn't correct, sorry.
> which isn't watching for system messages from the
> conversation service itself.
Is it possible to wrap the system messages from the conversation service itself?
::: chat/components/src/imConversations.js
@@ +295,3 @@
> this.notifyObservers(aSubject, aTopic, aData);
> if (aTopic == "new-text") {
> Services.obs.notifyObservers(aSubject, aTopic, aData);
Isn't this the place to do |new imMessage(aSubject)|?
::: chat/modules/jsProtoHelper.jsm
@@ +429,5 @@
> }
> Message.prototype = GenericMessagePrototype;
>
>
> +function imMessage(aPrplMessage) {
At first glance, this new object should be implemented in imConversations.js (otherwise the messages from libpurple protocol plugins won't benefit from this wrapping).
Attachment #8485224 -
Flags: review?(florian)
Attachment #8485224 -
Flags: review-
Attachment #8485224 -
Flags: feedback+
Assignee | ||
Comment 54•10 years ago
|
||
Comment on attachment 8485224 [details] [diff] [review]
transform.patch from 49-50
Review of attachment 8485224 [details] [diff] [review]:
-----------------------------------------------------------------
> Is it possible to wrap the system messages from the conversation service itself?
Yeah, but it's ugly,
systemMessage: function(aText, aIsError) {
let flags = {system: true, noLog: true, error: !!aIsError};
(new Message("system", aText, flags)).conversation = this;
},
gets changed to,
systemMessage: function(aText, aIsError) {
let flags = {system: true, noLog: true, error: !!aIsError};
let message = new Message("system", aText, flags)
message._conversation = this;
this.notifyObservers(new imMessage(message), "new-text", null);
},
The reason for that is because setting imMessage.conversation invokes the setter on the prplMessage, which ends up calling notifyObservers with the prplMessage itself.
Maybe you can think of something cleaner.
::: chat/components/src/imConversations.js
@@ +295,3 @@
> this.notifyObservers(aSubject, aTopic, aData);
> if (aTopic == "new-text") {
> Services.obs.notifyObservers(aSubject, aTopic, aData);
It has to be before notifying "received-message" above. But observeConv isn't observing the conversationService itself, so this doesn't get fired for system messages.
::: chat/modules/jsProtoHelper.jsm
@@ +429,5 @@
> }
> Message.prototype = GenericMessagePrototype;
>
>
> +function imMessage(aPrplMessage) {
Very true. I guess I should put it back.
Assignee | ||
Comment 55•10 years ago
|
||
Reverted the changes in the last patch to jsProtoHelper and solved it a different way, by moving a few things from observeConv to notifyObservers. Hopefully that's acceptable.
Attachment #8485224 -
Attachment is obsolete: true
Attachment #8485224 -
Flags: review?(clokep)
Attachment #8485224 -
Flags: review?(aleth)
Attachment #8485329 -
Flags: review?(florian)
Attachment #8485329 -
Flags: review?(clokep)
Attachment #8485329 -
Flags: review?(aleth)
Comment 56•10 years ago
|
||
Comment on attachment 8485329 [details] [diff] [review]
transform.patch from comments 53-54
Review of attachment 8485329 [details] [diff] [review]:
-----------------------------------------------------------------
::: chat/components/src/imConversations.js
@@ +359,5 @@
> + // Protocols can return null if they don't need to make any changes.
> + // (nb. passing null with retval array results in an empty array)
> + if (messages.length == 0) {
> + messages = [om.message];
> + }
Nit: No { } around single line statements.
Attachment #8485329 -
Flags: review?(clokep) → review+
Comment 57•10 years ago
|
||
I just went to try this...and realized that this requires changes to purplexpcom too, I don't want to redo work so: have you looked at these changes at all, arlolra?
Assignee | ||
Comment 58•10 years ago
|
||
The related purple patch. Not quite sure this is right but seems to work.
Attachment #8488122 -
Flags: review?(florian)
Attachment #8488122 -
Flags: review?(clokep)
Attachment #8488122 -
Flags: review?(aleth)
Comment 59•10 years ago
|
||
Comment on attachment 8488122 [details] [diff] [review]
purple part
Review of attachment 8488122 [details] [diff] [review]:
-----------------------------------------------------------------
::: purplexpcom/src/purpleConvChat.h
@@ +59,5 @@
> }
> NS_IMETHOD RemoveObserver(nsIObserver *aObserver) {
> return purpleConversation::RemoveObserver(aObserver);
> }
> + NS_IMETHOD PrepareForSending(imIOutgoingMessage *message, uint32_t *messageCount, char16_t * **messages) {
Codying style:
- keep the "a" prefix for arguments.
- insert line breaks after "," to avoid having more than 80 chars per line.
::: purplexpcom/src/purpleConversation.cpp
@@ +151,5 @@
> return NS_ERROR_NOT_IMPLEMENTED;
> }
>
> +/* void prepareForSending (in imIOutgoingMessage message, [optional] out unsigned long messageCount, [array, size_is (messageCount), retval] out wstring messages); */
> +NS_IMETHODIMP purpleConversation::PrepareForSending(imIOutgoingMessage *message, uint32_t *messageCount, char16_t * **messages)
Same coding style comments apply here.
@@ +153,5 @@
>
> +/* void prepareForSending (in imIOutgoingMessage message, [optional] out unsigned long messageCount, [array, size_is (messageCount), retval] out wstring messages); */
> +NS_IMETHODIMP purpleConversation::PrepareForSending(imIOutgoingMessage *message, uint32_t *messageCount, char16_t * **messages)
> +{
> + messages = NULL;
Real reason for the r-: this line has no effect.
You want:
*aMessageCount = 0;
*aMessages = nullptr;
Attachment #8488122 -
Flags: review?(florian)
Attachment #8488122 -
Flags: review?(clokep)
Attachment #8488122 -
Flags: review?(aleth)
Attachment #8488122 -
Flags: review-
Comment 60•10 years ago
|
||
Comment on attachment 8485329 [details] [diff] [review]
transform.patch from comments 53-54
Review of attachment 8485329 [details] [diff] [review]:
-----------------------------------------------------------------
Looks good, thanks!
Given that aleth already said "This looks good to me overall!" in comment 50, I don't think we should wait for his review here.
Note: I haven't tried this, but comment 57 looks like Patrick intends to do it.
::: chat/components/src/imConversations.js
@@ +359,5 @@
> + // Protocols can return null if they don't need to make any changes.
> + // (nb. passing null with retval array results in an empty array)
> + if (messages.length == 0) {
> + messages = [om.message];
> + }
I also saw this during my previous review but skipped it to not be annoying, as it doesn't matter all that much... but while we are here, I would probably write !messages.length rather than messages.length == 0.
Attachment #8485329 -
Flags: review?(florian)
Attachment #8485329 -
Flags: review?(aleth)
Attachment #8485329 -
Flags: review+
Assignee | ||
Comment 61•10 years ago
|
||
Thanks for the review.
Attachment #8488122 -
Attachment is obsolete: true
Assignee | ||
Comment 62•10 years ago
|
||
Fixed up all the nits, coding conventions and the return value in purplexpcom PrepareForSending.
Thanks again for the review.
Attachment #8485329 -
Attachment is obsolete: true
Attachment #8488366 -
Flags: review?(florian)
Attachment #8488366 -
Flags: review?(clokep)
Updated•10 years ago
|
Attachment #8449776 -
Attachment is obsolete: true
Comment 63•10 years ago
|
||
Comment on attachment 8488366 [details] [diff] [review]
transform-purple.patch
Review of attachment 8488366 [details] [diff] [review]:
-----------------------------------------------------------------
::: purplexpcom/src/purpleConversation.cpp
@@ +152,5 @@
> }
>
> +/* void prepareForSending (in imIOutgoingMessage aMsg,
> + [optional] out unsigned long aMsgCount,
> + [array, size_is (aMsgCount), retval] out wstring aMsgs); */
The indent seems wrong here.
Attachment #8488366 -
Flags: review?(florian) → review+
Assignee | ||
Comment 64•10 years ago
|
||
Comment on attachment 8488366 [details] [diff] [review]
transform-purple.patch
Review of attachment 8488366 [details] [diff] [review]:
-----------------------------------------------------------------
::: purplexpcom/src/purpleConversation.cpp
@@ +152,5 @@
> }
>
> +/* void prepareForSending (in imIOutgoingMessage aMsg,
> + [optional] out unsigned long aMsgCount,
> + [array, size_is (aMsgCount), retval] out wstring aMsgs); */
Yeah ... but this seemed the most legible. I'd need to split up the last line to fit 80 chars:
[array, size_is (aMsgCount), retval]
out wstring aMsgs); */
Comment 65•10 years ago
|
||
(In reply to arlolra from comment #64)
> Yeah ... but this seemed the most legible. I'd need to split up the last
> line to fit 80 chars:
>
> [array, size_is (aMsgCount), retval]
> out wstring aMsgs); */
The 80 chars thing is more a guideline than a strict rule. It's not a problem to have a few more chars if that significantly improves legibility. In that case, the last parameter shouldn't be split.
Assignee | ||
Comment 66•10 years ago
|
||
Attachment #8488366 -
Attachment is obsolete: true
Attachment #8488366 -
Flags: review?(clokep)
Assignee | ||
Comment 67•10 years ago
|
||
I see. Ok, cleaned that up.
Comment 68•10 years ago
|
||
I compiled and tested this and didn't see any issues. I'll commit this once I get approval.
Comment 69•10 years ago
|
||
Thanks!
https://hg.mozilla.org/comm-central/rev/d2a0c6d324fa
http://hg.mozilla.org/users/florian_queze.net/purple/rev/d971cac153ee
Florian and I did have a conversation about how hard it would be to test this, any thoughts?
Status: ASSIGNED → RESOLVED
Closed: 10 years ago
Resolution: --- → FIXED
Target Milestone: --- → 1.6
Assignee | ||
Comment 70•10 years ago
|
||
clokep: It looks like you committed the wrong patches :(
It should have been the ones from comment 62 and comment 66, which are the non-obsolete ones from the top.
Comment 71•10 years ago
|
||
Backouts:
https://hg.mozilla.org/comm-central/rev/a27468ae7846
http://hg.mozilla.org/users/florian_queze.net/purple/rev/ecb887e33c33
Updated versions:
https://hg.mozilla.org/comm-central/rev/e2c85d70fda2
http://hg.mozilla.org/users/florian_queze.net/purple/rev/6550fcf407f0
Thanks for catching that. I should have checked what I had locally before pushing.
Comment 72•10 years ago
|
||
This busted a couple of tests, I pushed a fix because I'd rather see this stick than get backed out:
https://hg.mozilla.org/comm-central/rev/0c3c6ce0353f
You need to log in
before you can comment on or make changes to this bug.
Description
•