Fix for 21846. Next Msg works for thread view. r=sspitzer, a=sdagley

This commit is contained in:
putterman%netscape.com 1999-12-21 23:38:31 +00:00
parent 60a39256fc
commit 53bb123d4e
5 changed files with 270 additions and 8 deletions

View File

@ -46,7 +46,7 @@
IsServer="rdf:http://home.netscape.com/NC-rdf#IsServer"
ServerType="rdf:http://home.netscape.com/NC-rdf#ServerType"
HasUnreadMessages="rdf:http://home.netscape.com/NC-rdf#HasUnreadMessages"
SubfoldersHaveUnreadMesages="rdf:http://home.netscape.com/NC-rdf#SubfoldersHaveUnreadMessages"
SubfoldersHaveUnreadMessages="rdf:http://home.netscape.com/NC-rdf#SubfoldersHaveUnreadMessages"
persist="threaded">
<treerow >
<treecell indent="true" value="rdf:http://home.netscape.com/NC-rdf#FolderTreeName"/>

View File

@ -322,6 +322,7 @@ function OnLoadFolderPane(folderTree)
dump('In onLoadfolderPane\n');
gFolderTree = folderTree;
SortFolderPane('FolderColumn', 'http://home.netscape.com/NC-rdf#FolderTreeName');
//Add folderDataSource and accountManagerDataSource to folderPane
accountManagerDataSource = accountManagerDataSource.QueryInterface(Components.interfaces.nsIRDFDataSource);
folderDataSource = folderDataSource.QueryInterface(Components.interfaces.nsIRDFDataSource);
@ -469,3 +470,67 @@ function GetSelectedFolder()
}
function ThreadPaneOnClick(event)
{
dump('In ThreadPaneOnClick\n');
var targetclass = event.target.getAttribute('class');
debug('targetclass = ' + targetclass + '\n');
if (targetclass == 'twisty') {
// The twisty is nested three below the treeitem:
// <treeitem>
// <treerow>
// <treecell>
// <box> <!-- anonymous -->
// <titledbutton class="twisty"> <!-- anonymous -->
var treeitem = event.target.parentNode.parentNode.parentNode.parentNode;
var open = treeitem.getAttribute('open');
if(open == "true")
{
//open all of the children of the treeitem
OpenThread(treeitem);
}
dump('clicked on a twisty\n');
}
}
function OpenThread(treeitem)
{
var open = treeitem.getAttribute('open');
if(open != "true")
{
treeitem.setAttribute('open', 'true');
}
var treeitemChildNodes = treeitem.childNodes;
var numTreeitemChildren = treeitemChildNodes.length;
//if there's only one child then there are no treechildren so close it.
if(numTreeitemChildren == 1)
treeitem.setAttribute('open', '');
else
{
for(var i = 0; i < numTreeitemChildren; i++)
{
var treeitemChild = treeitemChildNodes[i];
if(treeitemChild.nodeName == 'treechildren')
{
var treechildrenChildNodes = treeitemChildNodes[i].childNodes;
var numTreechildrenChildren = treechildrenChildNodes.length;
for(var j = 0; j < numTreechildrenChildren; j++)
{
var treechildrenChild = treechildrenChildNodes[j];
if(treechildrenChild.nodeName == 'treeitem')
{
treechildrenChild.setAttribute('open', 'true');
//Open up all of this items
OpenThread(treechildrenChild);
}
}
}
}
}
}

View File

@ -25,26 +25,55 @@ function GoMessage(message)
return true;
}
function ResourceGoMessage(message)
{
return true;
}
function GoUnreadMessage(message)
{
var status = message.getAttribute('Status');
return(status == ' ' || status == 'New');
}
function ResourceGoUnreadMessage(message)
{
var statusValue = GetMessageValue(message, "http://home.netscape.com/NC-rdf#Status");
return(statusValue == ' ' || statusValue == 'New');
}
function GoFlaggedMessage(message)
{
var flagged = message.getAttribute('Flagged');
return(flagged == 'flagged');
}
function ResourceGoFlaggedMessage(message)
{
var flaggedValue = GetMessageValue(message, "http://home.netscape.com/NC-rdf#Flagged");
return(flaggedValue == 'flagged');
}
function GetMessageValue(message, propertyURI)
{
var db = GetThreadTree().database;
var propertyResource = RDF.GetResource(propertyURI);
var node = db.GetTarget(message, propertyResource, true);
var literal = node.QueryInterface(Components.interfaces.nsIRDFLiteral);
if(literal)
{
return literal.Value;
}
return null;
}
/*GoNextMessage finds the message that matches criteria and selects it.
nextFunction is the function that will be used to detertime if a message matches criteria.
It must take a node and return a boolean.
startFromBeginning is a boolean that states whether or not we should start looking at the beginning
if we reach then end
if we reach the end
*/
function GoNextMessage(nextFunction, startFromBeginning)
function GoNextMessage(nextFunction, nextResourceFunction, startFromBeginning)
{
var tree = GetThreadTree();
@ -60,7 +89,16 @@ function GoNextMessage(nextFunction, startFromBeginning)
else
currentMessage = selArray[0];
var nextMessage = GetNextMessage(tree, currentMessage, nextFunction, startFromBeginning);
var nextMessage;
if(messageView.showThreads)
{
nextMessage = GetNextMessageInThreads(tree, currentMessage, nextFunction, nextResourceFunction, startFromBeginning);
}
else
{
nextMessage = GetNextMessage(tree, currentMessage, nextFunction, startFromBeginning);
}
//Only change the selection if there's a valid nextMessage
if(nextMessage && (nextMessage != currentMessage))
@ -119,6 +157,162 @@ function GetNextMessage(tree, currentMessage, nextFunction, startFromBeginning)
return nextMessage;
}
function GetNextMessageInThreads(tree, currentMessage, nextFunction, nextResourceFunction, startFromBeginning)
{
var checkStartMessage = false;
//In the case where nothing is selected
if(currentMessage == null)
{
currentMessage = FindFirstMessage(tree);
checkStartMessage = true;
}
return FindNextMessageInThreads(currentMessage, currentMessage, nextFunction, nextResourceFunction, startFromBeginning, checkStartMessage);
}
function FindNextMessageInThreads(startMessage, originalStartMessage, nextFunction, nextResourceFunction, startFromBeginning, checkStartMessage)
{
//First check startMessage if we are supposed to
if(checkStartMessage)
{
if(nextFunction(startMessage))
return startMessage;
}
//Next, search the current messages children.
nextChildMessage = FindNextInChildren(startMessage, originalStartMessage, nextFunction, nextResourceFunction);
if(nextChildMessage)
return nextChildMessage;
//Next we need to search the current messages siblings
nextMessage = startMessage.nextSibling;
while(nextMessage)
{
//In case we've already been here before
if(nextMessage == originalStartMessage)
return nextMessage;
if(nextFunction(nextMessage))
return nextMessage;
var nextChildMessage = FindNextInChildren(nextMessage, originalStartMessage, nextFunction, nextResourceFunction);
if(nextChildMessage)
return nextChildMessage;
nextMessage = nextMessage.nextSibling;
}
//Finally, we need to find the next of the start message's ancestors that has a sibling
var parentMessage = startMessage.parentNode.parentNode;
while(parentMessage.nodeName == 'treeitem')
{
if(parentMessage.nextSibling != null)
{
nextMessage = FindNextMessageInThreads(parentMessage.nextSibling, originalStartMessage, nextFunction, nextResourceFunction, startFromBeginning, true);
return nextMessage;
}
parentMessage = parentMessage.parentNode.parentNode;
}
//otherwise it's the tree so we need to stop and potentially start from the beginning
if(startFromBeginning)
{
nextMessage = FindNextMessageInThreads(FindFirstMessage(parentMessage), originalStartMessage, nextFunction, nextResourceFunction, false, true);
return nextMessage;
}
return null;
}
//Searches children messages in thread navigation.
function FindNextInChildren(parentMessage, originalStartMessage, nextFunction, nextResourceFunction)
{
var isParentOpen = parentMessage.getAttribute('open') == 'true';
//First we'll deal with the case where the parent is open. In this case we can use DOM calls.
if(isParentOpen)
{
//In this case we have treechildren
if(parentMessage.childNodes.length == 2)
{
var treechildren = parentMessage.childNodes[1];
var childMessages = treechildren.childNodes;
var numChildMessages = childMessages.length;
for(var i = 0; i < numChildMessages; i++)
{
var childMessage = childMessages[i];
//If we're at the original message again then stop.
if(childMessage == originalStartMessage)
return childMessage;
if(nextFunction(childMessage))
return childMessage;
else
{
//if this child isn't the message, perhaps one of its children is.
var nextChildMessage = FindNextInChildren(childMessage, originalStartMessage, nextFunction);
if(nextChildMessage)
return nextChildMessage;
}
}
}
}
else
{
//We need to traverse the graph in rdf looking for the next resource that fits what we're searching for.
var parentUri = parentMessage.getAttribute('id');
var parentResource = RDF.GetResource(parentUri);
//If we find one, then we get the id and open up the parent and all of it's children. Then we find the element
//with the id in the document and return that.
if(parentResource)
{
var nextResource = FindNextInChildrenResources(parentResource, nextResourceFunction);
if(nextResource)
{
OpenThread(parentMessage);
var nextUri = nextResource.Value;
var nextChildMessage = document.getElementById(nextUri);
return nextChildMessage;
}
}
}
return null;
}
function FindNextInChildrenResources(parentResource, nextResourceFunction)
{
var db = GetThreadTree().database;
var childrenResource = RDF.GetResource("http://home.netscape.com/NC-rdf#MessageChild");
var childrenEnumerator = db.GetTargets(parentResource, childrenResource, true);
if(childrenEnumerator)
{
while(childrenEnumerator.HasMoreElements())
{
var childResource = childrenEnumerator.GetNext().QueryInterface(Components.interfaces.nsIRDFResource);
if(childResource)
{
if(nextResourceFunction(childResource))
return childResource;
var nextMessageResource = FindNextInChildrenResources(childResource, nextResourceFunction);
if(nextMessageResource)
return nextMessageResource;
}
}
}
return null;
}
/*GoPreviousMessage finds the message that matches criteria and selects it.
previousFunction is the function that will be used to detertime if a message matches criteria.

View File

@ -42,7 +42,7 @@ Rights Reserved.
<template>
<rule>
<treechildren>
<treechildren onclick="ThreadPaneOnClick(event);">
<treeitem uri="..."
Status="rdf:http://home.netscape.com/NC-rdf#Status"
Flagged="rdf:http://home.netscape.com/NC-rdf#Flagged"
@ -105,5 +105,6 @@ Rights Reserved.
</treecell>
</treerow>
</treehead>
</tree>
</overlay>

View File

@ -258,9 +258,11 @@ function MsgDeleteMessage(fromToolbar)
}
dump("tree is valid\n");
//get the selected elements
var messageList = ConvertDOMListToResourceArray(tree.selectedItems);
var nextMessage = GetNextMessageAfterDelete(tree.selectedItems);
//get the current folder
messenger.DeleteMessages(tree.database, srcFolder.resource, messageList);
SelectNextMessage(nextMessage);
}
@ -788,16 +790,16 @@ function MsgStop() {
function MsgNextMessage()
{
GoNextMessage(GoMessage, false);
GoNextMessage(GoMessage, ResourceGoMessage, false);
}
function MsgNextUnreadMessage()
{
GoNextMessage(GoUnreadMessage, true);
GoNextMessage(GoUnreadMessage, ResourceGoUnreadMessage, true);
}
function MsgNextFlaggedMessage()
{
GoNextMessage(GoFlaggedMessage, true);
GoNextMessage(GoFlaggedMessage, ResourceGoFlaggedMessage, true);
}
function MsgPreviousMessage()