Using CSS references to DOS your desktop
2005-03-06 15:35:31
Have you ever wanted to pop up an apparently invisible Mozilla
window that completely disables your keyboard and mouse so that
the only way to get control again is to SSH remotely and kill
the shell from which you started Mozilla?
Me neither. But if
you want to, here's a simple way : create a XUL file with this at the beginning :
(note that the CSS file should attempt to refer to a CSS file,
but should do so in a way that shows that you don't know how
to refer to CSS files in XUL).
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://findfile/skin/asdfasdf.css" type="text/css"?>
<window
id="findfile-window"
title="Find Files"
orient="horizontal"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<vbox flex="1">
<description>
Enter your search criteria below and select the Find button to begin
the search.
</description>
<hbox>
<label value="Search for:" control="find-text"/>
<textbox id="find-text"/>
</hbox>
<hbox>
<spacer flex="1"/>
<button id="find-button" label="Find" default="true"/>
<button id="cancel-button" label="Cancel"/>
</hbox>
</vbox>
</window>
Semantic difference between resource:/ and chrome://
2005-03-06 14:30:39
hiros-item(ekoontz)[/usr/local/lib/mozilla-1.8b2/chrome/findfile] $ find . -not -type d
./content/findfile.xul
hiros-item(ekoontz)[/usr/local/lib/mozilla-1.8b2/chrome/findfile] $
mozilla -chrome resource:/chrome/findfile/content
This will simply popup a directory view of the directory
/usr/local/lib/mozilla-1.8b2/chrome/findfile/content.
mozilla -chrome chrome://findfile/content
By contrast, this starts the findfile.xul application. The amazing thing is that
this can happen even with no contents.rdf or relevant entries in
installed-chrome.txt. Apparently
chrome://findfile/content is
"hardwired" to look for
resource:/chrome/findfile/content/findfile.xul, and as far as
I can tell, there is no way to cause
chrome://findfile/content to open another file - you cannot
move findfile.xul (for example, to findfile2.xul) and modify
installed-chrome.txt and/or content.rdf to cause
mozilla -chrome
chrome://findfile/content to open findfile2.xul.
That doesn't bother me in itself - what I don't like is all of these
complex files and syntax that doesn't seem to actually affect
anything. (yes, of course, that's because I don't understand the
meaning of these files and syntax...)
Two ways to start a XUL application
2005-03-05 12:06:32
Learning-by-doing with the findfile example from
XULPlanet tutorial.
hiros-item(ekoontz)[/usr/local/lib/mozilla-1.8b2/chrome] $ find findfile -not -type d
/usr/local/lib/mozilla-1.8b2/chrome/findfile/content/findfile/findfile.xul
/usr/local/lib/mozilla-1.8b2/chrome/findfile/content/contents.rdf
mozilla -chrome chrome://findfile/content/findfile/findfile.xul
mozilla -chrome resource:/chrome/findfile/content/findfile/findfile.xul
The two ways seem to differ only in the syntax (slightly different
ways to refer to the same file
findfile.xul), but there are
probably deeper semantic differences that I'm not aware of yet.
It appears that the following minimal contents.rdf doesn't have any
significance (that is, you can remove it and the above
commands still pop up the findfind.xul application) :
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window
id="findfile-window"
title="Find Files"
orient="horizontal"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<vbox flex="1">
<description>
Enter your search criteria below and select the Find button to begin
the search.
</description>
<hbox>
<label value="Search for:" control="find-text"/>
<textbox id="find-text"/>
</hbox>
<hbox>
<spacer flex="1"/>
<button id="find-button" label="Find" default="true"/>
<button id="cancel-button" label="Cancel"/>
</hbox>
</vbox>
</window>
Looks like I'll need to understand the way the existing mailnews
component interfaces with the relevant UI stuff (written XUL),
before I can try to understand the former on their own...
This tutorial seems pretty good. The examples work pretty much
as-is, and it looks like there is some detail on interfacing XUL and XPCOM. Creating/testing a little sample app :
mozilla -chrome resource:/chrome/findfile/content/findfile.xul
Learning XPCOM from the sample component.
2005-02-25 23:57:55
Slowly learning about XPCOM by creating a component. Started by
copying the
sample component and then removing
everything and gradually adding things and trying it out with xpcshell.
Put this
"foo" component in my own CVS.
Learned how to setup xpcshell and nsISample
2005-02-14 08:42:52
I'm just going to ignore that transformiix stuff. IIRC
transformix is the XSLT processor.
hiros-item(ekoontz)[/tmp/mozilla/xpcom/sample] $ export MOZILLA_FIVE_HOME=/usr/local/lib/thunderbird-0.6+/
hiros-item(ekoontz)[/tmp/mozilla/xpcom/sample] $ xpcshell
Type Manifest File: /usr/local/lib/thunderbird-0.6+/components/xpti.dat
+++ JavaScript debugging hooks installed.
nsNativeComponentLoader: autoregistering begins.
nsNativeComponentLoader: SelfRegisterDll(libp3p.so) Load FAILED with error: /usr/local/lib/thunderbird-0.6+/components/libp3p.so: undefined symbol: _ZTV18nsGetWeakReference
nsNativeComponentLoader: SelfRegisterDll(libtypeaheadfind.so) Load FAILED with error: /usr/local/lib/thunderbird-0.6+/components/libtypeaheadfind.so: undefined symbol: _ZTV18nsGetWeakReference
nsNativeComponentLoader: SelfRegisterDll(libtransformiix.so) Load FAILED with error: /usr/local/lib/thunderbird-0.6+/components/libtransformiix.so: undefined symbol: _ZTV18nsGetWeakReference
nsNativeComponentLoader: autoregistering succeeded
nsNativeComponentLoader: registering deferred (0)
js> var sample = Components.classes["@mozilla.org/sample;1"].createInstance();
js> sample = sample.QueryInterface(Components.interfaces.nsISample);
[xpconnect wrapped nsISample @ 0x8114428]
js> sample
[xpconnect wrapped nsISample @ 0x8114428]
js> dump("sample = " + sample + "\n");
sample = [xpconnect wrapped nsISample @ 0x8114428]
js> sample.value
initial value
js> sample.poke("foo");
js> sample.value
foo
js> sample.writeValue("hello");
hello foo
foopy 5
GetValue 8
js>
Moving to xpcshell 2005-02-07 00:35:38
Decided to just write standalone .js scripts and figure out the
mail API that way. It's just too slow and error prone to do it
with Mozilla running inside gdb. I was trying to get a bit
faster by just building thunderbird (below) but that's not going
far enough.
Going to be using my simple "bug11013.js" scripts from my
bug11013.jar (below).
Switched to thunderbird
2005-02-05 15:40:27
In an attempt to reduce the amount of detail needed to comprehend the code, I decided to rebuild as thunderbird :
./configure --enable-chrome-format=flat --prefix=/usr/local --enable-optimize=-g --enable-debug --enable-application=mail
Applied
this patch to fix a
freetype bug.
Deeper into the docShell stack
2005-02-05 02:18:13
nsDocShell.cpp:731
rv = InternalLoad(aURI,
referrer,
owner,
inheritOwner,
target.get(),
nsnull, // No type hint
postStream,
headersStream,
loadType,
nsnull, // No SHEntry
firstParty,
nsnull, // No nsIDocShell
nsnull); // No nsIRequest
nsDocShell.cpp:5414
rv = DoURILoad(aURI, aReferrer, owner, aTypeHint, aPostData, aHeadersData,
firstParty, aDocShell, aRequest);
nsDocShell.cpp:5413
rv = DoURILoad(aURI, aReferrer, owner, aTypeHint, aPostData, aHeadersData,
firstParty, aDocShell, aRequest);
nsDocShell.cpp:5624
rv = DoChannelLoad(channel, uriLoader);
nsDocShell.cpp:5773
rv = aURILoader->OpenURI(aChannel,
(mLoadType == LOAD_LINK),
this);
nsURILoader.cpp:224
rv = aChannel->AsyncOpen(this, nsnull);
But,
where is the AsyncOpen() method? What is the real type of
aChannel?
Just what is a docshell?
2005-01-12 23:32:57
To recap from has come before, we are tracing the call stack
that implements fetching messages and parts of messages
(i.e. attachments) from a folder. Such fetched objects are
represented as URIs, and a docshell seems to be the preferred
method of fetching objects referred to by URIs.
Did a google search on docshell and came up with something
very informative :
"What
the hell is the docshell?".
Fast way to get into docshell debugging:
export NSPR_LOG_MODULES="nsDocShell:5"
export XPCOM_BREAK_ON_LOAD=msgdb
/usr/local/bin/mozilla -g
r
shar docshell
b nsDocShell.cpp:606
possible clue on getting LOG() to work
2005-01-09 01:08:02
I found this useful comment in the
source code :
To put log messages in your programs, use the PR_LOG macro:
104 **
105 ** PR_LOG(<module>, <level>, (<printfString>, <args>*));
106 **
107 ** Where <module> is the address of a PRLogModuleInfo structure, and
108 ** <level> is one of the levels defined by the enumeration:
109 ** PRLogModuleLevel. <args> is a printf() style of argument list. That
110 ** is: (fmtstring, ...).
So, hopefully, to get the maximum amount of debugging output, we can do :
export NSPR_LOG_MODULES="all:5"
URLs : how to obfuscate them from debugging attempts.
2005-01-05 02:08:18
What a URL variable looks like in Mozilla code.
For example, suppose you have an object called "channel" that contains
a uri. This is how you can actually discover what the text of the uri
is.
816 #ifdef PR_LOGGING
817 if (LOG_ENABLED()) {
818 nsCOMPtr<nsIURI> uri;
819 channel->GetURI(getter_AddRefs(uri));
820 nsCAutoString spec;
821 uri->GetAsciiSpec(spec);
822 LOG(("nsURILoader::OpenURI for %s", spec.get()));
823 }
824 #endif
Easy.
non-mailbox protocol handling - what does
it mean?
2005-01-05 02:08:05
Trying to figure out what this code is for :
nsLocalMailFolder.cpp:1723
if (!protocolType.LowerCaseEqualsLiteral("mailbox"))
{
mCopyState->m_dummyEnvelopeNeeded = PR_TRUE;
nsParseMailMessageState* parseMsgState = new nsParseMailMessageState();
if (parseMsgState)
{
nsCOMPtr<nsIMsgDatabase> msgDb;
mCopyState->m_parseMsgState = do_QueryInterface(parseMsgState, &rv);
GetDatabaseWOReparse(getter_AddRefs(msgDb));
if (msgDb)
parseMsgState->SetMailDB(msgDb);
}
}
nsMailboxService.cpp:117 : nsMailboxService::CopyMessage()
nsMailboxService.cpp:178 : nsMailboxService::FetchMessage()
getting very,very close to loading a message..could it be?
810 NS_IMETHODIMP nsURILoader::OpenURI(nsIChannel *channel,
811 PRBool aIsContentPreferred,
812 nsIInterfaceRequestor *aWindowContext)
813 {
814 NS_ENSURE_ARG_POINTER(channel);
.
.
.
875
876 // now instruct the loader to go ahead and open the url
877 return loader->Open(channel);
878 }
Ah, but what
is this mysterious "loader"? What's behind it's
enigmatic "RawPtr*" disguise? Tune in next time to find out.
Deeper and deeper into copying messages..
2005-01-03 00:47:48
Continuing the discussion of the copyMessage call stack, there
are two final frame before calling the store-dependent
copyMessage functionality; here is the first :
NS_IMETHODIMP
nsMsgCopyService::CopyMessages(nsIMsgFolder* srcFolder, /* UI src folder */
nsISupportsArray* messages,
nsIMsgFolder* dstFolder,
PRBool isMove,
nsIMsgCopyServiceListener* listener,
nsIMsgWindow* window,
PRBool allowUndo)
{
.
.
.
rv = DoCopy(copyRequest);
.
.
.
All the stuff that I've elided has to do with populating the
copyRequest. So copyRequest seems to be a sequence of
folder-messages pairs, where each pair is a folder and a list of
messages for that folder that will be copied. (The destination
was given to the copyRequest when its Init() was called :
rv = copyRequest->Init(nsCopyMessagesType, aSupport, dstFolder,
isMove, listener, window, allowUndo);
)
Then, we get to the last frame before calling the actual
storage-dependent implementation:
nsMsgCopyService.cpp:286
rv = copyRequest->m_dstFolder->CopyMessages
(copySource->m_msgFolder, copySource->m_messageArray,
copyRequest->m_isMoveOrDraftOrTemplate,
copyRequest->m_msgWindow, copyRequest->m_listener, PR_FALSE, copyRequest->m_allowUndo); //isFolder operation PR_FALSE
At last, here we are in the local folder-implementation of
CopyMessages() :
nsLocalMailFolder.cpp:1655
NS_IMETHODIMP
nsMsgLocalMailFolder::CopyMessages(nsIMsgFolder* srcFolder, nsISupportsArray*
messages, PRBool isMove,
nsIMsgWindow *msgWindow,
nsIMsgCopyServiceListener* listener,
PRBool isFolder, PRBool allowUndo)
Deep inside the "copy message" stack.
2005-01-02 23:43:35
First, how I set ddd to break in here :
(gdb) set env XPCOM_BREAK_ON_LOAD msgdb
(gdb) r
Starting program: /usr/local/lib/mozilla-1.8a6/mozilla-bin -venkman -chrome chrome://messenger/content/messenger.xul
warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
[Thread debugging using libthread_db enabled]
[New Thread 16384 (LWP 16071)]
Type Manifest File: /usr/local/lib/mozilla-1.8a6/components/xpti.dat
+++ JavaScript debugging hooks installed.
.
lots of output deleted...
.
[New Thread 98310 (LWP 16083)]
++WEBSHELL == 6
++DOMWINDOW == 6
vnk: } 9.377 sec
window moved to offscreen position
window moved to offscreen position
window moved to offscreen position
...Loading module libmsgdb.so
Program received signal SIGTRAP, Trace/breakpoint trap.
[Switching to Thread 16384 (LWP 16071)]
nsDll::BreakAfterLoad (this=0x816e328, nsprPath=0x90f71a8 "libmsgdb.so") at xcDll.cpp:429
(gdb) shar mail
Reading symbols from /usr/local/lib/mozilla-1.8a6/components/libmailnews.so...done.
Loaded symbols for /usr/local/lib/mozilla-1.8a6/components/libmailnews.so
(gdb) b nsMsgDBView.cpp:2271
Breakpoint 1 at 0x419243b2: file nsMsgDBView.cpp, line 2271.
Starting here in the javascript :
mailWindowOverlay.js:854:
var destUri = destFolder.getAttribute('id');
var destResource = RDF.GetResource(destUri);
var destMsgFolder = destResource.QueryInterface(Components.interfaces.nsIMsgFolder);
gDBView.doCommandWithFolder(nsMsgViewCommandType.copyMessages, destMsgFolder);
-
nsMsgDBView.cpp:2007
NS_IMETHODIMP nsMsgDBView::DoCommandWithFolder(nsMsgViewCommandTypeValue command, nsIMsgFolder *destFolder)
{
nsUInt32Array selection;
NS_ENSURE_ARG_POINTER(destFolder);
GetSelectedIndices(&selection);
nsMsgViewIndex *indices = selection.GetData();
PRInt32 numIndices = selection.GetSize();
nsresult rv = NS_OK;
switch (command) {
case nsMsgViewCommandType::copyMessages:
case nsMsgViewCommandType::moveMessages:
// since the FE could have constructed the list of indices in
// any order (e.g. order of discontiguous selection), we have to
// sort the indices in order to find out which nsMsgViewIndex will
// be deleted first.
if (numIndices > 1)
NS_QuickSort(indices, numIndices, sizeof(nsMsgViewIndex), CompareViewIndices, nsnull);
NoteStartChange(nsMsgViewNotificationCode::none, 0, 0);
rv = ApplyCommandToIndicesWithFolder(command, indices, numIndices, destFolder);
- And ApplyCommandToIndicesWithFolder() looks like :
nsMsgDBView.cpp:2273
nsresult
nsMsgDBView::ApplyCommandToIndicesWithFolder(nsMsgViewCommandTypeValue command, nsMsgViewIndex* indices,
PRInt32 numIndices, nsIMsgFolder *destFolder)
{
nsresult rv = NS_OK;
NS_ENSURE_ARG_POINTER(destFolder);
switch (command) {
case nsMsgViewCommandType::copyMessages:
NS_ASSERTION(!(m_folder == destFolder), "The source folder and the destination folder are the same");
if (m_folder != destFolder)
rv = CopyMessages(mMsgWindow, indices, numIndices, PR_FALSE /* isMove */, destFolder);
break;
-
This (note the nsMsgViewCommandType.copyMessages way up there in the javascript) gets us into :
nsMsgDBView.cpp:2271
nsresult
nsMsgDBView::CopyMessages(nsIMsgWindow *window, nsMsgViewIndex *indices, PRInt32 numIndices, PRBool isMove, nsIMsgFolder *destFolder)
{
if (m_deletingRows)
{
NS_ASSERTION(PR_FALSE, "Last move did not complete");
return NS_OK;
}
m_deletingRows = isMove && mDeleteModel != nsMsgImapDeleteModels::IMAPDelete;
nsresult rv;
NS_ENSURE_ARG_POINTER(destFolder);
nsCOMPtr<nsISupportsArray> messageArray;
NS_NewISupportsArray(getter_AddRefs(messageArray));
for (nsMsgViewIndex index = 0; index < (nsMsgViewIndex) numIndices; index++)
{
nsMsgKey key;
nsMsgViewIndex viewIndex = indices[index];
if (viewIndex == nsMsgViewIndex_None)
continue;
key = m_keys.GetAt(viewIndex);
nsCOMPtr <nsIMsgDBHdr> msgHdr;
rv = m_db->GetMsgHdrForKey(key, getter_AddRefs(msgHdr));
if (NS_SUCCEEDED(rv) && msgHdr)
{
messageArray->AppendElement(msgHdr);
// if we are deleting rows, save off the keys
if (m_deletingRows)
mIndicesToNoteChange.Add(indices[index]);
}
}
This part above is basically updating the database, it
seems. Apparently we have not yet actually copied the mail to the
folder's actual permanent store, however.
Continuing on, though, is where we do it:
nsCOMPtr<nsIMsgCopyService> copyService = do_GetService(NS_MSGCOPYSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
return copyService->CopyMessages(m_folder /* source folder */, messageArray, destFolder, isMove, nsnull /* listener */, window, PR_TRUE /*allowUndo*/);
}
Notice that the copyService->CopyMessages is a virtual method of
some kind that can be specialized to be any of :
We will be going into detail next about how this last's CopyMessages
function is implemented.
On the creation of objects with mimetype : text/x-moz-message.
2005-01-01 16:24:09
If we can figure out how to synthesize a text/x-moz-message
object from a raw-text form of a message, we can simply allow
attachments of type message/rfc822 to be converted to raw text,
converted to a text/x-moz-message, and then to be dragged into
the folder, just as folder messages can be dragged now.
The problem is that a "text/x-moz-message" object seems
basically merely a reference to a certain message in a
folder. (more precisely, it seems that it's a key in a flat-file
database that is itself an index of the folder. So, we must
first convert the message to a database entry (and thus into a
folder) and THEN we can create a text/x-moz-message object that
references this new database entry.
Turning message text into a message window : two implementations.
2004-12-31 01:53:29
There's two cases where a message can be displayed in a message window :
- A message stored in a folder.
- A message stored as an attachment to a message.
These two cases are implemented separately, with the second
seeming to have been done more recently, in 2003, as a fix for
bug
143565. Prior to this fix, an attached email (a
message/rfc822 mime part) was simply shown as raw text, rather than being in a message window.
As an example of how these two cases' separate
implementations differ, many of the buttons (Forward, Reply,
etc) are disabled in the case of attachments. This has caused
a lot of
controversy in the related bugzilla
entries.
We need to look at the code involved in this bug fix and
note how its implementation of case 2 differs from the implementation of case 1.
One way we'll distinguish these two cases is to call case
1's implementation "
loadMessageByMsgKey()" and call
case 2's implementation : "
loadMessageByUrl()". These
names refer to the javascript functions that constitute the
essential difference between the two cases.
No updates till end of this month.
2004-12-23 11:14:00
On vacation for five days.
Enabling dragging over-generally.. 2004-12-22 01:17:31
These changes to messengerdnd.js allow us to drag an attachment
over a folder and dropped. It's overgeneral because it allows any
attachment to be dragged over and dropped without checking the
mimetype. As I said earlier, I have to parse these
mailbox://.. URLs to get the mimetype to allow only
attachments of type
message/rfc822 to be dragged and dropped
over folders.
hiros-item(ekoontz)[/usr/local/lib/mozilla-1.8a6/chrome/messenger/content/messenger] $ diff -u /tmp/mozilla/mailnews/base/resources/content/messengerdnd.js .
--- /tmp/mozilla/mailnews/base/resources/content/messengerdnd.js 2004-11-18 19:50:25.000000000 -0800
+++ ./messengerdnd.js 2004-12-22 01:07:29.801212208 -0800
@@ -46,7 +46,7 @@
function debugDump(msg)
{
// uncomment for noise
- // dump(msg+"\n");
+ dump(msg+"\n");
}
function CanDropOnFolderTree(index, orientation)
@@ -61,7 +61,9 @@
if (! dragSession)
return false;
- var flavorSupported = dragSession.isDataFlavorSupported("text/x-moz-message") || dragSession.isDataFlavorSupported("text/x-moz-folder");
+ var flavorSupported =
+ dragSession.isDataFlavorSupported("text/x-moz-message") ||
+ dragSession.isDataFlavorSupported("text/x-moz-folder");
var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
if (! trans)
@@ -102,7 +104,12 @@
var sourceUri = dataObj.data.substring(0, len.value);
if (! sourceUri)
continue;
- if (dataFlavor.value == "text/x-moz-message")
+
+ dump("trying to drop obj with uri : " + sourceUri + " with mimetype : " + dataFlavor.value + "\n");
+
+ if ((dataFlavor.value == "text/x-moz-message")
+ ||
+ (dataFlavor.value == "text/x-moz-url"))
{
sourceResource = null;
var isServer = GetFolderAttribute(folderTree, targetResource, "IsServer");
@@ -114,13 +121,21 @@
// canFileMessages checks no select, and acl, for imap.
var canFileMessages = GetFolderAttribute(folderTree, targetResource, "CanFileMessages");
if (canFileMessages != "true")
- {
+ {
debugDump("***canFileMessages == false\n");
return false;
}
- var hdr = messenger.messageServiceFromURI(sourceUri).messageURIToMsgHdr(sourceUri);
- if (hdr.folder == targetFolder)
- return false;
+ if (dataFlavor.value == "text/x-moz-message") {
+ var hdr = messenger.messageServiceFromURI(sourceUri).messageURIToMsgHdr(sourceUri);
+ if (hdr.folder == targetFolder)
+ return false;
+ }
+ else { // text/x-moz-url
+ // check if sourceUri points to an attached message/rfc822
+ // if so, then..
+ dump("GOT A TEXT/X-MOZ-URL..");
+ flavorSupported = true;
+ }
break;
} else if (dataFlavor.value == "text/x-moz-folder") {
@@ -282,8 +297,19 @@
rssService.subscribeToFeed(url, targetFolder, msgWindow);
return true;
}
- else
- return false;
+ else {
+ if (uri.schemeIs("mailbox")) {
+ dump("GOT HERE : A MAILBOX URL : " + uri + "\n");
+
+ // if it's a message/rfc822, then get the message text and
+ // turn it into some kind of message object...
+
+ dropMessage = true;
+ }
+ else {
+ return false;
+ }
+ }
}
}
else {
Here's some sample output from this:
trying to drop obj with uri : mailbox:///home/ekoontz/.mozilla/test/rcmagau1.slt/Mail/Local%20Folders/test?number=0&part=1.2&type=message/rfc822&filename=no more SPAM from this one..
no more SPAM from this one.. with mimetype : text/x-moz-url
GOT A TEXT/X-MOZ-URL..trying to drop obj with uri : mailbox:///home/ekoontz/.mozilla/test/rcmagau1.slt/Mail/Local%20Folders/test?number=0&part=1.2&type=message/rfc822&filename=no more SPAM from this one..
no more SPAM from this one.. with mimetype : text/x-moz-url
GOT A TEXT/X-MOZ-URL..BeginDragThreadPane
Compare the above (dragging attached message/rfc822 versus the following (dragging a folder message) :
selArray.length = 1
ID #0 = mailbox-message://nobody@Local%20Folders/test#0
trying to drop obj with uri : mailbox-message://nobody@Local%20Folders/test#0 with mimetype : text/x-moz-message
trying to drop obj with uri : mailbox-message://nobody@Local%20Folders/test#0 with mimetype : text/x-moz-message
Of course, this is not enough to fix the bug : we need to
actually convert the attachment's internal representation into a
representation that can be appended to the folder. Currently we
the following error output is seen when we drop the attachment
on the folder; hopefully this will give us some clues about
where to start looking next.
WARNING: NS_ENSURE_TRUE(NS_SUCCEEDED(rv)) failed, file nsMailboxService.cpp,line 541
WARNING: NS_ENSURE_TRUE(NS_SUCCEEDED(rv)) failed, file nsMailboxService.cpp,line 568
************************************************************
* Call to xpconnect wrapped JSObject produced this error: *
[Exception... "Component returned failure code: 0x80004005
(NS_ERROR_FAILURE) [nsIMsgMessageService.messageURIToMsgHdr]"
nsresult: "0x80004005 (NS_ERROR_FAILURE)" location:
"JS frame :: chrome://messenger/content/messengerdnd.js:: DropOnFolderTree :: line 323" data: no]
************************************************************
Attached message dragging debug output
2004-12-20 09:12:54
Added the following line to
CanDropOnFolderTree() :
dump("trying to drop obj with uri : " + sourceUri + " with mimetype : " + dataFlavor.value + "\n");
When I drag an attached message over a folder in the folder tree, I get the resulting output :
trying to drop obj with uri : imap://test@hiro-tan.org:143/fetch%3EUID%3E.INBOX.test2%3E4?part=1.2&type=message/rfc822&filename=no more SPAM from this one..
with mimetype : text/x-moz-url
Apparently we'll need to parse these URIs in order to extract
that
type=message/rfc822 so that we can return true in
this case from
CanDropOnFolderTree(). I assume there's
some functionality for parsing URIs and extracting argument
name/value pairs like this..
How drag and drop of attachments works
2004-12-19 15:11:13
messengerdnd.js:CanDropOnFolderTree() returns a
boolean based on the dataFlavor.value. A normal (not attached)
will have dataFlavor.value = text/x-moz-message :
if (dataFlavor.value == "text/x-moz-message")
{
sourceResource = null;
var isServer = GetFolderAttribute(folderTree, targetResource, "IsServer");
if (isServer == "true")
{
debugDump("***isServer == true\n");
return false;
}
// canFileMessages checks no select, and acl, for imap.
var canFileMessages = GetFolderAttribute(folderTree, targetResource, "CanFileMessages");
if (canFileMessages != "true")
{
debugDump("***canFileMessages == false\n");
return false;
}
var hdr = messenger.messageServiceFromURI(sourceUri).messageURIToMsgHdr(sourceUri);
if (hdr.folder == targetFolder)
return false;
break;
More thoughts about last post
2004-12-19 13:57:28
When a new GUI element is added for each attachment, why is
there no javascript callback added to the new element's
attributes in
displayAttachmentsForExpandedView()?
Where is the callback to be found? (It's probably something like
OpenAttachment()).
Attachments in messenger
Posted 2004-12-19 12:29:36
By using the DOM Inspector tool, we can see gross message window
structure simplified below; with attachments highlighted.
The attachmentList is populated by the function
msgHdrViewOverlay.js:displayAttachmentsForExpandedView(), shown below :
// For the currently displayed message, we store all the attachment data. When displaying a particular
// view, it's up to the view layer to extract this attachment data and turn it into something useful.
// For a given entry in the attachments list, you can ask for the following properties:
// .contentType --> the content type of the attachment
// url --> an imap, or mailbox url which can be used to fetch the message
// uri --> an RDF URI which refers to the message containig the attachment
// notDownloaded --> boolean flag stating whether the attachment is downloaded or not.
.
.
.
function displayAttachmentsForExpandedView()
{
var numAttachments = currentAttachments.length;
if (numAttachments > 0 && !gBuildAttachmentsForCurrentMsg)
{
var attachmentList = document.getElementById('attachmentList');
for (index in currentAttachments)
{
var attachment = currentAttachments[index];
// we need to create a listitem to insert the attachment
// into the attachment list..
var item = attachmentList.appendItem(attachment.displayName,"");
item.setAttribute("class", "listitem-iconic");
item.setAttribute("tooltip", "attachmentListTooltip");
item.attachment = attachment;
item.setAttribute("attachmentUrl", attachment.url);
item.setAttribute("attachmentContentType", attachment.contentType);
item.setAttribute("attachmentUri", attachment.uri);
setApplicationIconForAttachment(attachment, item);
} // for each attachment
gBuildAttachmentsForCurrentMsg = true;
}
var expandedAttachmentBox = document.getElementById('expandedAttachmentBox');
expandedAttachmentBox.collapsed = numAttachments <= 0;
}
currentAttachments is an array of attachment structures. This array is populated by the handleAttachment() function :
handleAttachment: function(contentType, url, displayName, uri, notDownloaded)
{
...
currentAttachments.push (new createNewAttachmentInfo(contentType, url, displayName, uri, notDownloaded));
...
}
There doesn't seem to be any calls to handleAttachment() in
the chrome, but there seems to be a call in the
components/mime.xpt component.
Sketch of solution
Posted 2004-12-18 17:42:44
This is my summary of my proposal to implement the fix of this bug.
Suppose someone wants to drag attached message/rfc822 part 'm' from a given message M.
- get URI(m) := the URI to the mime part that refers to m.
- read m into memory
- copy m to a temporary LocalMail folder T, call this new message m', which is the only message in T.
- URI(m') := (new path to m in folder T, as opposed to a path to an attachment in M)
- pass URI(m') as the source of the dragging action.
- When the user drops m on a folder F :
- Copy URI(m') using nsIMsgMessageService::CopyMessage() from T to F.
- Delete temporary folder T (which will also delete m').
Getting message information Posted 2004-12-18 17:42:52
Now I can retrieve a local message and get individual headers from it :
var gCurrentMessageUri = "mailbox-message://nobody@Local%20Folders/test#0";
.
.
var msgHdr = msgService.messageURIToMsgHdr(gCurrentMessageUri);
dump("THE HEADER IS : " + msgHdr + "\n");
dump(" subject : " + msgHdr.subject + "\n");
dump(" author : " + msgHdr.author + "\n");
Now, I need to figure how to get the MIME structure for a
message. I know that I can get an individual mime part with
nsImsgMessageService::fetchMimePart, but how do I get
the overall MIME structure (i.e., the MIME tree form) of the
message?
Getting Started Posted 2004-12-18 17:43:02
- Using a functional version of mozilla, use Communicator to
create a local folder called "test". Find a message M with an
attached message/rfc822 part. Drag this message M into your
"test" local folder.
- Check out mozilla source if you
haven't already:
export CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
cvs -z3 co mozilla
- Configure and make:
./configure --enable-chrome-format=flat --prefix=/usr/local --enable-optimize=-g --enable-debug --enable-application=suite
make
make install
- Unzip my little XUL bug diagnostics : bug11013.jar in /usr/local/lib/mozilla-1.8aX (where X is 6 currently, but will increase as the CVS tree changes).
- Add the following to your /usr/local/lib/mozilla-1.8aX/chrome/installed-chrome.txt :
content,install,url,resource:/chrome/bug11013/content/bug11013/
- Run the following from a shell :
mozilla -chrome "chrome://bug11013/content/bug11013.xul"
Some output will be sent to the shell from the diagnostic's dump() calls.
Hopefully you'll see things like :
THE HEADER IS : [xpconnect wrapped nsIMsgDBHdr @ 0x82fc0d8]
subject : [Fwd: no more SPAM from this one..]
author : Eugene Koontz <ekoontz@hiro-tan.org>
All code written by me here is licenced under the GNU Public Licence.
All documents here are licenced under the GNU Free Document Licence.
Last modified: Tue Apr 5 23:04:51 PDT 2005