• Skip to main content
  • Select language
  • Skip to search
MDN Web Docs
  • Technologies
    • HTML
    • CSS
    • JavaScript
    • Graphics
    • HTTP
    • APIs / DOM
    • WebExtensions
    • MathML
  • References & Guides
    • Learn web development
    • Tutorials
    • References
    • Developer Guides
    • Accessibility
    • Game development
    • ...more docs
Add-ons
  1. MDN
  2. Mozilla
  3. Add-ons
  4. Thunderbird extensions
  5. Demo Addon

Demo Addon

In This Article
  1. Thunderbird Demo Add-on
      1. Overview
      2. How to use
    1. The basics
    2. Demo 1 - Iterate over all the accounts
    3. Demo 2 - Find the Inbox
    4. Demo 3- Search messages by subject
  2. Download
  3. See also

Thunderbird Demo Add-on

Overview

This demo add-on has been created by Jonathan Protzenko for his presentation at MozCamp 2011. It shows how to achieve various goals in a working live example, such as working with Gloda.

You can download it at the bottom of the page.

How to use

After installing the demo add-on in Thunderbird, right click on the toolbar and choose "Customize". Drag the "Demo" button into the toolbar. Afterwards, just click that button to show the demo overview.

All three demos are explained in the following sections. Only the interesting parts are shown, it's recommended that you download the add-on and have a look at its files.

The basics

The interesting parts covered in this article are in the content folder. The toolbar button and its functionality are defined in overlay.xul and overlay.js.

We make use of fixIterator(). It is a handy library that keeps your code cleaner and simpler. It lets you iterate over any collection and transforms your collection elements in the given objects, To use fixIterator, you have to import it with Cu.import("resource:///modules/iteratorUtils.jsm");.

Demo 1 - Iterate over all the accounts

This demo is implemented in demo1.html in the content folder. It lists all your email accounts with their account type - either pop3 or imap - and the associated email addresses.

let data = [];
for each (let account in fixIterator(MailServices.accounts.accounts, Ci.nsIMsgAccount)) {
    let info = {
        server: null,
        type: null,
        emails: [],
        name: null,
    };
    let server = account.incomingServer;
    if (server) {
        info.server = server.prettyName;
        info.type = server.type;
    }
    for each (let id in fixIterator(account.identities, Ci.nsIMsgIdentity)) {
        // We're only interested in identities that have a real email.
        if (id.email)
            info.emails.push(id.email);
    }
    data.push(info);
}

First, we use fixIterator() here to get all accounts in your profile. Each account is a nsIMsgAccount.

To get the the server name, we access the incomingServer property of our account, which is a nsIMsgIncomingServer object. From this, we get its name and type.

Because an account can have multiple identities of type nsIMsgIdentity and therefore multiple associated email addresses, with use fixIterator() again to go over all identities and get every email address.

Demo 2 - Find the Inbox

This demo shows various information: It lists all folders of an account (in this case the first one) and marks the inbox folder with a *. Furthermore, it shows some messages in the inbox and lists a random attachment.

We start with listing all folders and marking the inbox:

let server = accounts[0].incomingServer;
let folder = server.rootFolder;
// ...
let inbox;
let print = function (indent, folder) {
    let isInbox = folder.getFlag(Ci.nsMsgFolderFlags.Inbox);
    if (isInbox)
        inbox = folder;
    str += indent + folder.prettiestName + (isInbox ? " *" : "") + "\n";
    if (folder.hasSubFolders)
        for each (let folder in fixIterator(folder.subFolders, Ci.nsIMsgFolder))
            print(indent + "  ", folder);
};
print("  ", folder);

As in the previous example, we get the incomingServer of the account in question. Beginning with the rootFolder, with  folder.getFlag(Ci.nsMsgFolderFlags.Inbox) we check whether the folder is the inbox. Then we store the folder name in a string to display it later on the screen and mark it with an * if it is the inbox. Afterwards, we check every folder for subfolders. We then go into each subfolder and start over.

To list some messages of the folder we use:

for each (let msgHdr in fixIterator(inbox.msgDatabase.EnumerateMessages(), Ci.nsIMsgDBHdr)) {
    if (++i >= 10 && lastMsgHdr != null)
        break;
    messages.push({
        author: msgHdr.mime2DecodedAuthor,
        subject: msgHdr.mime2DecodedSubject,
        date: new Date(msgHdr.date/1000),
    });
//...
}

To get a collection of messages in the inbox, we use inbox.msgDatabase.EnumerateMessages(). Each message is a nsIMsgDBHdr. We iterate over the first ten of them and extract author, subject and date for each one.

Demo 3- Search messages by subject

This demo shows how to find messages by a subject accross all folders using Gloda.

let query = Gloda.newQuery(Gloda.NOUN_MESSAGE);
query.subjectMatches(searchTerm);
let myListener = {
    /* called when new items are returned by the database query or freshly indexed */
    onItemsAdded: function myListener_onItemsAdded(aItems, aCollection) {
    },
    /* called when items that are already in our collection get re-indexed */
    onItemsModified: function myListener_onItemsModified(aItems, aCollection) {
    },
    /* called when items that are in our collection are purged from the system */
    onItemsRemoved: function myListener_onItemsRemoved(aItems, aCollection) {
    },
    /* called when our database query completes */
    onQueryCompleted: function myListener_onQueryCompleted(aCollection) {
        let items = aCollection.items;
        let data = {
            messages: [],
        };
        for each (let [, glodaMsg] in Iterator(items)) {
            data.messages.push({
                subject: glodaMsg.subject,
                date: glodaMsg.date,
                author: glodaMsg.from.value,
            });
        // ...
        };
    }
    // ...
  }
};
let collection = query.getCollection(myListener);

At first, a new Gloda query for finding messages is created. The subject is assigned as search criterion. In the Gloda query result listener the variable aCollection is a GlodaCollections. It contains a collection of GlodaConversation objects which itself is a thread that contains one or more GlodaMessages. For every Gloda message subject, date and author is extracted.

The last line of this example executes the Gloda query.

 

Download

Demo Addon Download


See also

  • Creating a gloda message query
  • Gloda examples
  • Gloda
  • Thunderbird HowTos
     

Document Tags and Contributors

 Contributors to this page: steely.wing, wbamberg, kylewm, pbenysek, pablocubico, One, jswisher
 Last updated by: steely.wing, Oct 5, 2016, 12:54:36 AM
See also
  1. WebExtensions
  2. Getting started
    1. Prerequisites
    2. Anatomy of a WebExtension
    3. Packaging and Installation
    4. Walkthrough
    5. Examples
  3. Guides
    1. Content scripts
    2. Porting from Google Chrome
    3. Match patterns
    4. Debugging
    5. Chrome incompatibilities
  4. JavaScript APIs
    1. alarms
    2. bookmarks
    3. browserAction
    4. commands
    5. contextMenus
    6. cookies
    7. downloads
    8. events
    9. extension
    10. extensionTypes
    11. history
    12. i18n
    13. idle
    14. management
    15. notifications
    16. pageAction
    17. runtime
    18. storage
    19. tabs
    20. webNavigation
    21. webRequest
    22. windows
  5. Manifest keys
    1. applications
    2. background
    3. browser_action
    4. commands
    5. content_scripts
    6. content_security_policy
    7. default_locale
    8. description
    9. homepage_url
    10. icons
    11. manifest_version
    12. name
    13. options_ui
    14. page_action
    15. permissions
    16. version
    17. web_accessible_resources
  6. Add-on SDK
  7. Getting started
    1. Installation
    2. Getting started
    3. Troubleshooting
  8. High-Level APIs
    1. addon-page
    2. base64
    3. clipboard
    4. context-menu
    5. hotkeys
    6. indexed-db
    7. l10n
    8. notifications
    9. page-mod
    10. page-worker
    11. panel
    12. passwords
    13. private-browsing
    14. querystring
    15. request
    16. selection
    17. self
    18. simple-prefs
    19. simple-storage
    20. system
    21. tabs
    22. timers
    23. ui
    24. url
    25. widget
    26. windows
  9. Low-Level APIs
    1. /loader
    2. chrome
    3. console/plain-text
    4. console/traceback
    5. content/content
    6. content/loader
    7. content/mod
    8. content/symbiont
    9. content/worker
    10. core/heritage
    11. core/namespace
    12. core/promise
    13. dev/panel
    14. event/core
    15. event/target
    16. frame/hidden-frame
    17. frame/utils
    18. fs/path
    19. io/byte-streams
    20. io/file
    21. io/text-streams
    22. lang/functional
    23. lang/type
    24. loader/cuddlefish
    25. loader/sandbox
    26. net/url
    27. net/xhr
    28. places/bookmarks
    29. places/favicon
    30. places/history
    31. platform/xpcom
    32. preferences/event-target
    33. preferences/service
    34. remote/child
    35. remote/parent
    36. stylesheet/style
    37. stylesheet/utils
    38. system/child_process
    39. system/environment
    40. system/events
    41. system/runtime
    42. system/unload
    43. system/xul-app
    44. tabs/utils
    45. test/assert
    46. test/harness
    47. test/httpd
    48. test/runner
    49. test/utils
    50. ui/button/action
    51. ui/button/toggle
    52. ui/frame
    53. ui/id
    54. ui/sidebar
    55. ui/toolbar
    56. util/array
    57. util/collection
    58. util/deprecate
    59. util/list
    60. util/match-pattern
    61. util/object
    62. util/uuid
    63. window/utils
  10. Firefox for Android
  11. Getting started
    1. Walkthrough
    2. Debugging
    3. Code snippets
  12. APIs
    1. Accounts.jsm
    2. BrowserApp
    3. HelperApps.jsm
    4. Home.jsm
    5. HomeProvider.jsm
    6. JavaAddonManager.jsm
    7. NativeWindow
    8. Notifications.jsm
    9. PageActions.jsm
    10. Prompt.jsm
    11. RuntimePermissions.jsm
    12. Snackbars.jsm
    13. Sound.jsm
    14. Tab
  13. Legacy
  14. Restartless extensions
    1. Overview
  15. Overlay extensions
    1. Overview
  16. Themes
  17. Lightweight themes
    1. Overview
  18. Complete themes
    1. Overview
  19. Publishing add-ons
  20. Guides
    1. Signing and distribution overview
    2. Submit an add-on
    3. Review policies
    4. Developer agreement
    5. Featured add-ons
    6. Contact addons.mozilla.org
  21. Community and support
  22. Channels
    1. Add-ons blog
    2. Add-on forums
    3. Stack Overflow
    4. Development newsgroup
    5. IRC Channel