gecko-dev/mailnews/base/resources/content/msgViewNavigation.js
2000-04-23 17:36:03 +00:00

222 lines
7.0 KiB
JavaScript

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
* Rights Reserved.
*/
/* This file contains the js functions necessary to implement view navigation within the 3 pane. */
// These are the types of navigation you can do
var navigateAny=0;
var navigateUnread = 1;
var navigateFlagged = 2;
var navigateNew = 3;
/*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.
nextResourceFunction is the function that will be used to determine if a message in the form of a resource
matches criteria. Takes a resource and returns a boolean
nextThreadFunction is an optional function that can be used to optimize whether or not a thread will have a
message that matches the criteria. Takes the top level message in the form of a node and returns a boolean.
startFromBeginning is a boolean that states whether or not we should start looking at the beginning
if we reach the end
*/
function GoNextMessage(type, startFromBeginning )
{
var beforeGoNextMessage = new Date();
var tree = GetThreadTree();
var selArray = tree.selectedItems;
var length = selArray.length;
if ( selArray && ((length == 0) || (length == 1)) )
{
var currentMessage;
if(length == 0)
currentMessage = null;
else
currentMessage = selArray[0];
var nextMessage = msgNavigationService.FindNextMessage(type, tree, currentMessage, RDF, document, startFromBeginning, messageView.showThreads);
//Only change the selection if there's a valid nextMessage
if(nextMessage && (nextMessage != currentMessage))
ChangeSelection(tree, nextMessage);
}
var afterGoNextMessage = new Date();
var timeToGetNext = (afterGoNextMessage.getTime() - beforeGoNextMessage.getTime())/1000;
dump("time to GoNextMessage is " + timeToGetNext + "seconds\n");
}
/*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.
It must take a node and return a boolean.
startFromEnd is a boolean that states whether or not we should start looking at the end
if we reach the beginning
*/
function GoPreviousMessage(type, startFromEnd)
{
var tree = GetThreadTree();
var selArray = tree.selectedItems;
if ( selArray && (selArray.length == 1) )
{
var currentMessage = selArray[0];
var previousMessage = msgNavigationService.FindPreviousMessage(type, tree, currentMessage, RDF, document, startFromEnd, messageView.showThreads);
//Only change selection if there's a valid previous message.
if(previousMessage && (previousMessage != currentMessage))
ChangeSelection(tree, previousMessage);
}
}
// type is the the type of the next thread we are looking for.
// startFromBeginning is true if we should start looking from the beginning after we get to the end of the thread pane.
// gotoNextInThread is true if once we find an unrad thread we should select the first message in that thread that fits criteria
function GoNextThread(type, startFromBeginning, gotoNextInThread)
{
if(messageView.showThreads)
{
var tree = GetThreadTree();
var selArray = tree.selectedItems;
var length = selArray.length;
if ( selArray && ((length == 0) || (length == 1)) )
{
var currentMessage;
if(length == 0)
currentMessage = null;
else
currentMessage = selArray[0];
var nextMessage;
var currentTopMessage;
var checkCurrentTopMessage;
//Need to get the parent message for the current selection to begin to find thread
if(currentMessage)
{
//need to find its top level message and we don't want it to be checked for criteria
currentTopMessage = FindTopLevelMessage(currentMessage);
checkCurrentTopMessage = false;
}
else
{
//currentTopmessage is the first one in the tree and we want it to be checked for criteria.
currentTopMessage = msgNavigationService.FindFirstMessage(tree);
checkCurrentTopMessage = true;
}
var nextTopMessage = msgNavigationService.FindNextThread(type, tree, currentTopMessage, RDF, document, startFromBeginning, checkCurrentTopMessage);
var changeSelection = (nextTopMessage != null && ((currentTopMessage != nextTopMessage) || checkCurrentTopMessage));
if(changeSelection)
{
if(gotoNextInThread)
{
nextMessage = msgNavigationService.FindNextInThread(type, tree, nextTopMessage, RDF, document);
ChangeSelection(tree, nextMessage);
}
else
ChangeSelection(tree, nextTopMessage);
}
}
}
}
function FindTopLevelMessage(startMessage)
{
var currentTop = startMessage;
var parent = startMessage.parentNode.parentNode;
while(parent.nodeName == 'treeitem')
{
currentTop = parent;
parent = parent.parentNode.parentNode;
}
return currentTop;
}
function ScrollToFirstNewMessage()
{
var tree = GetThreadTree();
var treeFolder = GetThreadTreeFolder();
var folderURI = treeFolder.getAttribute('ref');
var folderResource = RDF.GetResource(folderURI);
var folder = folderResource.QueryInterface(Components.interfaces.nsIMsgFolder);
var hasNew = folder.hasNewMessages();
if(hasNew)
{
var newMessage = folder.firstNewMessage;
if(messageView.showThreads)
{
//if we're in thread mode, then we need to actually make sure the message is showing.
var topLevelMessage = GetTopLevelMessageForMessage(newMessage, folder);
var topLevelResource = topLevelMessage.QueryInterface(Components.interfaces.nsIRDFResource);
var topLevelURI = topLevelResource.Value;
var topElement = document.getElementById(topLevelURI);
if(topElement)
{
msgNavigationService.OpenTreeitemAndDescendants(topElement);
}
}
var messageResource = newMessage.QueryInterface(Components.interfaces.nsIRDFResource);
var messageURI = messageResource.Value;
var messageElement = document.getElementById(messageURI);
if(messageElement)
{
tree.ensureElementIsVisible(messageElement);
}
}
}
function GetTopLevelMessageForMessage(message, folder)
{
if(!folder)
folder = message.msgFolder;
var thread = folder.getThreadForMessage(message);
var outIndex = new Object();
var rootHdr = thread.GetRootHdr(outIndex);
var topMessage = folder.createMessageFromMsgDBHdr(rootHdr);
return topMessage;
}