nsIEditor is now builtinclass

Jonathan Protzenko jonathan.protzenko at gmail.com
Tue Aug 26 21:11:42 UTC 2014

Here's the full explanation for the earlier initEditor breakage I 
mentioned in my original mail below.

tl;dr: nsIEditor is, as Ehsan kindly pointed out to me, now builtinclass 
(can't be implemented in JS); a consequence is that clients who wish to 
send HTML emails now really need to abide by one very specific state 
protocol. A way to workaround this would be to make the editor field of 
nsIMsgCompose read-write. Thoughts?

Here's the long story.

My use-case is as follows. Thunderbird-stdlib currently offers a 
sendMessage function with a nice Javascript-oriented API that hides the 
atrocities of the underlying nsMsgCompose / nsMsgComposeSession / 
nsIMsgComposeParams / nsIMsgCompFields / nsIEditor / nsIMsgProgress / 
nsIStateListener classes and instead provides (what I believe is) a 
moderately simple function with intuitive parameters [1].

This function can either send a blob of plain text, or take something 
that looks more or less like an iframe and send its inner contents as an 
HTML mail. It places no further requirements on the state of the iframe 
before sending, meaning that the client code really can send whatever 
they want. It is entirely decoupled from the act of setting up a 
composition window.

Internally, the mail sending code is in nsMsgCompose; the code relies on 
its m_editor field [2], and uses, for instance, the outputToString 
method of nsIEditor [4] to figure out the HTML that ought to be put in 
the message (also, it uses the getEmbeddedObjects method of nsIEditor to 
figure out the inline images it should attach [3]). When sending a 
message, I create an nsMsgCompose object. I hence wish to set its 
m_editor field for my HTML message to be sent properly. The only 
possible way to set m_editor to something other than nullptr [5] is to 
call InitEditor. Quite unfortunately, initEditor also does something 
else, namely quoting the original message's body and adding the user's 
signature, if any, into the iframe [6].

This contradicts my earlier claim of having a stateless, composable 
"send" function that makes no further assumptions on the state of the 
original editor/iframe and is able to just send anything without 
requiring the client code to go through a certain protocol.

The way I work around this currently is to create a fake nsIEditor 
instance, that forwards calls to outputToString and getEmbeddedObjects 
to the real nsIEditor, and ignores everything else, hence rendering the 
code that quotes the original message into the iframe effectless. The 
code for my sendMessage function hence creates a fake editor, calls 
InitEditor only to have m_editor set, and proceeds with calling the 
actual sendMsg function.

A few days ago, nsIEditor was made builtinclass [7], meaning that one 
can no longer implement nsIEditor in JS. This means that I must ask 
clients of my code to:
- set up a composition session (nsIMsgCompose) parameterized over a 
nsIMsgComposeParams object (required at initialization-time of 
- modify in place this nsIMsgComposeParams object to reflect the choice 
of recipients, identity, etc. for sending the email;
- call my sendMessage function and pass it the original nsIMsgCompose 

Also, if clients of my code do not wish to have a message quoted into 
the iframe (say, because the iframe contains something already), they no 
longer have this option.

This is not very satisfactory, as it requires clients of my code to:
- be familiar with complex interfaces;
- go through a state protocol;
- manipulate the same object in an imperative manner.

A way to restore the previous behavior would be to make the m_editor 
field of nsIMsgCompose read-write, hence no longer requiring me to call 
InitEditor with all its nasty side-effects. I will file a bug with the 
corresponding patch soon.

Thanks for reading so far!

~ jonathan

[1] https://github.com/protz/thunderbird-stdlib/blob/master/send.js#L210
[5] http://mxr.mozilla.org/comm-central/ident?i=m_editor

On 08/22/2014 07:13 AM, Jonathan Protzenko wrote:
> Hi,
> I noticed several things breaking all at once over the past few days.
> - In 08-19, everything is fine as far as I can tell.
> - In 08-20, the call I am making (in Conversations) to 
> nsIMsgCompose::initEditor fails with an error "Failure: arg 0" in the 
> error console. Do you if something changed in this area? 
> http://hg.mozilla.org/comm-central/pushloghtml gives little clues, so 
> I suspect it must be in mozilla-central.
> - In 08-21, several things are broken at once: the thread summary no 
> longer works, tabs are not saved, the state of the folder pane 
> (unified vs. all vs. ...) is not saved either. Do you have any hints 
> as to what bugs could be causing this?
> In the meantime, I would advise _not_ to use 08-21 because it seems 
> badly impacted. I can file bugs if that helps.
> Cheers,
> ~ jonathan

More information about the tb-planning mailing list