msghdrviewoverlay.js

来自「现在很火的邮件客户端软件thunderbird的源码」· JavaScript 代码 · 共 1,653 行 · 第 1/5 页

JS
1,653
字号
# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-# ***** BEGIN LICENSE BLOCK *****# Version: MPL 1.1/GPL 2.0/LGPL 2.1## The contents of this file are subject to the Mozilla 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/MPL/## 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 the Initial Developer are Copyright (C) 1998-1999# the Initial Developer. All Rights Reserved.## Contributor(s):## Alternatively, the contents of this file may be used under the terms of# either the GNU General Public License Version 2 or later (the "GPL"), or# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),# in which case the provisions of the GPL or the LGPL are applicable instead# of those above. If you wish to allow use of your version of this file only# under the terms of either the GPL or the LGPL, and not to allow others to# use your version of this file under the terms of the MPL, indicate your# decision by deleting the provisions above and replace them with the notice# and other provisions required by the GPL or the LGPL. If you do not delete# the provisions above, a recipient may use your version of this file under# the terms of any one of the MPL, the GPL or the LGPL.## ***** END LICENSE BLOCK *****/* This is where functions related to displaying the headers for a selected message in the   message pane live. */////////////////////////////////////////////////////////////////////////////////////// Warning: if you go to modify any of these JS routines please get a code review from// scott@scott-macgregor.org. It's critical that the code in here for displaying// the message headers for a selected message remain as fast as possible. In particular, // right now, we only introduce one reflow per message. i.e. if you click on a message in the thread// pane, we batch up all the changes for displaying the header pane (to, cc, attachements button, etc.) // and we make a single pass to display them. It's critical that we maintain this one reflow per message// view in the message header pane. ////////////////////////////////////////////////////////////////////////////////////const msgHeaderParserContractID		   = "@mozilla.org/messenger/headerparser;1";const abAddressCollectorContractID	 = "@mozilla.org/addressbook/services/addressCollecter;1";const kPersonalAddressbookUri        = "moz-abmdbdirectory://abook.mab";const kRDFServiceContractID          = "@mozilla.org/rdf/rdf-service;1";const kLargeIcon = 32;const kSmallIcon = 16;var gViewAllHeaders = false;var gShowOrganization = false;var gShowLargeAttachmentView = false;var gShowUserAgent = false;var gExtraExpandedHeaders;var gMinNumberOfHeaders = 0;var gDummyHeaderIdIndex = 0;var gCollapsedHeaderViewMode = false;var gBuildAttachmentsForCurrentMsg = false;var gBuildAttachmentPopupForCurrentMsg = true;var gBuiltExpandedView = false;var gBuiltCollapsedView = false;var gOpenLabel;var gOpenLabelAccesskey;var gSaveLabel;var gSaveLabelAccesskey;var gDetachLabel;var gDeleteLabel;var gDetachLabelAccesskey;var gDeleteLabelAccesskey;var gMessengerBundle;var gProfileDirURL;var gIOService;var gShowCondensedEmailAddresses = true; // show the friendly display names for people I know instead of the name + email addressvar gPersonalAddressBookDirectory; // used for determining if we want to show just the display name in email address nodesvar msgHeaderParser = Components.classes[msgHeaderParserContractID].getService(Components.interfaces.nsIMsgHeaderParser);var abAddressCollector = null;// other components may listen to on start header & on end header notifications for each message we display// to do that you need to add yourself to our gMessageListeners array with object that has two properties:// onStartHeaders and onEndHeaders.var gMessageListeners = new Array;// For every possible "view" in the message pane, you need to define the header names you want to// see in that view. In addition, include information describing how you want that header field to be// presented. i.e. if it's an email address field, if you want a toggle inserted on the node in case// of multiple email addresses, etc. We'll then use this static table to dynamically generate header view entries// which manipulate the UI. // When you add a header to one of these view lists you can specify the following properties:// name: the name of the header. i.e. "to", "subject". This must be in lower case and the name of the//       header is used to help dynamically generate ids for objects in the document. (REQUIRED)// useToggle:      true if the values for this header are multiple email addresses and you want a //                 a toggle icon to show a short vs. long list (DEFAULT: false)// useShortView:   (only works on some fields like From). If the field has a long presentation and a//                 short presentation we'll use the short one. i.e. if you are showing the From field and you//                 set this to true, we can show just "John Doe" instead of "John Doe <jdoe@netscape.net>".//                 (DEFAULT: false)// // outputFunction: this is a method which takes a headerEntry (see the definition below) and a header value//                 This allows you to provide your own methods for actually determining how the header value//                 is displayed. (DEFAULT: updateHeaderValue which just sets the header value on the text node)// Our first view is the collapsed view. This is very light weight view of the data. We only show a couple// fields.var gCollapsedHeaderList = [ {name:"subject", outputFunction:updateHeaderValueInTextNode},                             {name:"from", useToggle:true, useShortView:true, outputFunction:OutputEmailAddresses},                             {name:"date", outputFunction:updateHeaderValueInTextNode}];// We also have an expanded header view. This shows many of your more common (and useful) headers.var gExpandedHeaderList = [ {name:"subject"},                             {name:"from", useToggle:true, outputFunction:OutputEmailAddresses},                            {name:"sender", outputFunction:OutputEmailAddresses},                            {name:"reply-to", useToggle:true, outputFunction:OutputEmailAddresses},                            {name:"date"},                            {name:"to", useToggle:true, outputFunction:OutputEmailAddresses},                            {name:"cc", useToggle:true, outputFunction:OutputEmailAddresses},                            {name:"bcc", useToggle:true, outputFunction:OutputEmailAddresses},                            {name:"newsgroups", outputFunction:OutputNewsgroups},                            {name:"followup-to", outputFunction:OutputNewsgroups},                            {name:"content-base"},                            {name:"tags"} ];// Now, for each view the message pane can generate, we need a global table of headerEntries. These// header entry objects are generated dynamically based on the static date in the header lists (see above)// and elements we find in the DOM based on properties in the header lists. var gCollapsedHeaderView = {};var gExpandedHeaderView  = {};// currentHeaderData --> this is an array of header name and value pairs for the currently displayed message.//                       it's purely a data object and has no view information. View information is contained in the view objects.//                       for a given entry in this array you can ask for:// .headerName ---> name of the header (i.e. 'to'). Always stored in lower case// .headerValue --> value of the header "johndoe@netscape.net"var currentHeaderData = {};// 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// isExternalAttachment --> boolean flag stating whether the attachment is an attachment which is a URL that refers to the attachment locationvar currentAttachments = new Array();// createHeaderEntry --> our constructor method which creates a header Entry // based on an entry in one of the header lists. A header entry is different from a header list.// a header list just describes how you want a particular header to be presented. The header entry// actually has knowledge about the DOM and the actual DOM elements associated with the header.// prefix --> the name of the view (i.e. "collapsed", "expanded")// headerListInfo --> entry from a header list.function createHeaderEntry(prefix, headerListInfo){  var useShortView = false;  var partialIDName = prefix + headerListInfo.name;  this.enclosingBox = document.getElementById(partialIDName + 'Box');  this.textNode = document.getElementById(partialIDName + 'Value');  this.isValid = false;  if ("useShortView" in headerListInfo)  {    useShortView = headerListInfo.useShortView;    if (useShortView)      this.enclosingBox = this.textNode;    else      this.enclosingBox.emailAddressNode = this.textNode;  }  if ("useToggle" in headerListInfo)  {    this.useToggle = headerListInfo.useToggle;    if (this.useToggle) // find the toggle icon in the document    {      this.toggleIcon = this.enclosingBox.toggleIcon;      this.longTextNode = this.enclosingBox.longEmailAddresses;      this.textNode = this.enclosingBox.emailAddresses;    }  }  else   this.useToggle = false;  if (this.textNode)    this.textNode.useShortView = useShortView;  if ("outputFunction" in headerListInfo)    this.outputFunction = headerListInfo.outputFunction;  else    this.outputFunction = updateHeaderValue;}function initializeHeaderViewTables(){  // iterate over each header in our header list arrays and create header entries   // for each one. These header entries are then stored in the appropriate header table  var index;  for (index = 0; index < gCollapsedHeaderList.length; index++)    {      gCollapsedHeaderView[gCollapsedHeaderList[index].name] =         new createHeaderEntry('collapsed', gCollapsedHeaderList[index]);    }    for (index = 0; index < gExpandedHeaderList.length; index++)    {      var headerName = gExpandedHeaderList[index].name;      gExpandedHeaderView[headerName] = new createHeaderEntry('expanded', gExpandedHeaderList[index]);    }        var extraHeaders = gExtraExpandedHeaders.split(' ');    for (index = 0; index < extraHeaders.length; index++)    {      var extraHeader = extraHeaders[index];      gExpandedHeaderView[extraHeader.toLowerCase()] = new createNewHeaderView(extraHeader, extraHeader + ':');    }    if (gShowOrganization)    {      var organizationEntry = {name:"organization", outputFunction:updateHeaderValue};      gExpandedHeaderView[organizationEntry.name] = new createHeaderEntry('expanded', organizationEntry);    }        if (gShowUserAgent)    {      var userAgentEntry = {name:"user-agent", outputFunction:updateHeaderValue};      gExpandedHeaderView[userAgentEntry.name] = new createHeaderEntry('expanded', userAgentEntry);    }}function OnLoadMsgHeaderPane(){  // HACK...force our XBL bindings file to be load before we try to create our first xbl widget....  // otherwise we have problems.  document.loadBindingDocument('chrome://messenger/content/mailWidgets.xml');    // load any preferences that at are global with regards to   // displaying a message...  gShowUserAgent = pref.getBoolPref("mailnews.headers.showUserAgent");  gMinNumberOfHeaders = pref.getIntPref("mailnews.headers.minNumHeaders");  gShowOrganization = pref.getBoolPref("mailnews.headers.showOrganization");  gShowLargeAttachmentView = pref.getBoolPref("mailnews.attachments.display.largeView");  gShowCondensedEmailAddresses = pref.getBoolPref("mail.showCondensedAddresses");  gExtraExpandedHeaders = pref.getCharPref("mailnews.headers.extraExpandedHeaders");  // listen to the   pref.addObserver("mail.showCondensedAddresses", MsgHdrViewObserver, false);  initializeHeaderViewTables();  var deckHeaderView = document.getElementById("msgHeaderViewDeck");  gCollapsedHeaderViewMode = deckHeaderView.selectedIndex == 0;     // dispatch an event letting any listeners know that we have loaded the message pane  var event = document.createEvent('Events');  event.initEvent('messagepane-loaded', false, true);  var headerViewElement = document.getElementById("msgHeaderView");  headerViewElement.dispatchEvent(event);}function OnUnloadMsgHeaderPane(){  pref.removeObserver("mail.showCondensedAddresses", MsgHdrViewObserver);  // dispatch an event letting any listeners know that we have unloaded the message pane  var event = document.createEvent('Events');  event.initEvent('messagepane-unloaded', false, true);  var headerViewElement = document.getElementById("msgHeaderView");  headerViewElement.dispatchEvent(event);}const MsgHdrViewObserver = {  observe: function(subject, topic, prefName)  {    // verify that we're changing the mail pane config pref    if (topic == "nsPref:changed")    {      if (prefName == "mail.showCondensedAddresses")      {        gShowCondensedEmailAddresses = pref.getBoolPref("mail.showCondensedAddresses");        MsgReload();      }    }  }};// The messageHeaderSink is the class that gets notified of a message's headers as we display the message// through our mime converter. var messageHeaderSink = {    onStartHeaders: function()    {      this.mSaveHdr = null;      // every time we start to redisplay a message, check the view all headers pref....      var showAllHeadersPref = pref.getIntPref("mail.show_headers");      if (showAllHeadersPref == 2)      {        gViewAllHeaders = true;      }      else      {        if (gViewAllHeaders) // if we currently are in view all header mode, rebuild our header view so we remove most of the header data        {           hideHeaderView(gExpandedHeaderView);          gExpandedHeaderView = {};          initializeHeaderViewTables();         }                        gViewAllHeaders = false;      }      ClearCurrentHeaders();      gBuiltExpandedView = false;      gBuiltCollapsedView = false;      gBuildAttachmentsForCurrentMsg = false;      gBuildAttachmentPopupForCurrentMsg = true;      ClearAttachmentList();      ClearEditMessageButton();      gMessageNotificationBar.clearMsgNotifications();      for (index in gMessageListeners)        gMessageListeners[index].onStartHeaders();    },

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?