### Thunderbird Extension Registration and Initialization (JavaScript) Source: https://context7.com/opto/nostalgy-xpi/llms.txt This JavaScript code outlines the setup for a Thunderbird WebExtension, utilizing the MailExtension architecture and WindowListener API for compatibility with Thunderbird 78+ and legacy code integration. It registers default preferences, chrome URLs, options pages, and window overlays. ```javascript // Background script (me-background.js) async function main() { messenger.WindowListener.registerDefaultPrefs( "chrome/content/scripts/me-Defaults.js" ); messenger.WindowListener.registerChromeUrl([ ["content", "nostalgy", "chrome/content/"], ["locale", "nostalgy", "en-US", "chrome/locale/en-US/"], ["locale", "nostalgy", "de", "chrome/locale/de/"] ]); messenger.WindowListener.registerOptionsPage( "chrome://nostalgy/content/edit_prefs.xhtml" ); messenger.WindowListener.registerWindow( "chrome://messenger/content/messenger.xhtml", "chrome/content/scripts/me-messenger.js" ); messenger.WindowListener.registerWindow( "chrome://messenger/content/messengercompose/messengercompose.xhtml", "chrome/content/scripts/me-composer.js" ); messenger.WindowListener.registerWindow( "chrome://messenger/content/messageWindow.xhtml", "chrome/content/scripts/me-messageWindow.js" ); messenger.WindowListener.startListening(); } main(); // Handle installation and updates messenger.runtime.onInstalled.addListener(async ({ reason, temporary }) => { switch (reason) { case "install": { const url = messenger.runtime.getURL("popup/installed.html"); await messenger.windows.create({ url, type: "popup", height: 780, width: 990 }); break; } case "update": { const url = messenger.runtime.getURL("popup/update.html"); await messenger.windows.create({ url, type: "popup", height: 780, width: 990 }); break; } } }); // Manifest.json experiment APIs { "experiment_apis": { "WindowListener": { "schema": "chrome/content/api/WindowListener/schema.json", "parent": { "scopes": ["addon_parent"], "paths": [["WindowListener"]], "script": "chrome/content/api/WindowListener/implementation.js" } }, "LegacyPrefs": { "schema": "chrome/content/api/LegacyPrefs/schema.json", "parent": { "scopes": ["addon_parent"], "paths": [["LegacyPrefs"]], "script": "chrome/content/api/LegacyPrefs/implementation.js" } } } } ``` -------------------------------- ### Define and Apply Rule-Based Folder Suggestions (JavaScript) Source: https://context7.com/opto/nostalgy-xpi/llms.txt This JavaScript code defines the structure for rules used to suggest destination folders for messages based on sender, recipient, or subject patterns. The `NostalgyRules.apply` function iterates through defined rules to find a match, while `NostalgyMatchContains` handles both literal string matching and regular expression matching for flexibility. ```javascript var exampleRule = { sender: true, recipients: false, subject: false, contains: "github.com", folder: "Dev/GitHub", under: "INBOX" }; function NostalgyRules.apply(sender, subject, recipients, cfolder) { var folder = null; var rules = this.rules; var current_folder = NostalgyFullFolderName(cfolder); for (var i = 0; (i < rules.length) && (!folder); i++) { var r = rules[i]; if (((r.subject && NostalgyMatchContains(subject, r.contains)) || (r.sender && NostalgyMatchContains(sender, r.contains)) || (r.recipients && NostalgyMatchContains(recipients, r.contains))) && (current_folder == r.under)) { folder = NostalgyFindFolderExact(r.folder); } } return folder; } function NostalgyMatchContains(field, contain) { var re = /^/(.*)/$/; if (contain.match(re)) { var m = re.exec(contain); var regex = RegExp(m[1], ""); return field.match(regex); } return (field.indexOf(contain) >= 0); } ``` -------------------------------- ### Activate Folder Navigation with Auto-Completion (JavaScript) Source: https://context7.com/opto/nostalgy-xpi/llms.txt This JavaScript code demonstrates how to activate keyboard-driven folder navigation in Nostalgy++. It allows users to type partial folder names, with auto-completion and tab completion for selecting the desired folder. The `NostalgyGoCommand` function is typically triggered by a hotkey. ```javascript function NostalgyGoCommand() { if (!nostalgy_in_message_window) { NostalgyCmd('Go to folder:', NostalgyShowFolder, false); return true; } else return false; } var folder = NostalgyFindFolderExact("Personal/Projects/2024"); if (folder) { NostalgyShowFolder(folder); } // Example: Type "pers/proj" to match "Personal/Projects" // Tab completion cycles through matching folders ``` -------------------------------- ### Move and Copy Messages to Folders with Keyboard Shortcuts (JavaScript) Source: https://context7.com/opto/nostalgy-xpi/llms.txt These JavaScript functions facilitate moving and copying selected messages to specified folders using keyboard shortcuts. `NostalgyMoveToFolder` handles moving, while `NostalgyCopyToFolder` handles copying. Both functions register the folder, update prediction models, and use Thunderbird's command interface for the operation. `NostalgySuggested` allows using a currently suggested folder. ```javascript function NostalgyMoveToFolder(folder) { manage_emails.lastFolder = folder; NostalgyRegisterFolder(folder); if (window.SetNextMessageAfterDelete) SetNextMessageAfterDelete(); else gFolderDisplay.hintAboutToDeleteMessages(); if (folder.tag) { NostalgyToggleMessageTag(folder); } else { NostalgyPredict.update_folder(folder); gDBView.doCommandWithFolder( Components.interfaces.nsMsgViewCommandType.moveMessages, folder ); } return true; } function NostalgyCopyToFolder(folder) { NostalgyRegisterFolder(folder); if (!folder.tag) { NostalgyPredict.update_folder(folder); gDBView.doCommandWithFolder( Components.interfaces.nsMsgViewCommandType.copyMessages, folder ); } return true; } function NostalgySuggested(cmd) { if (nostalgy_gsuggest_folder) cmd(nostalgy_gsuggest_folder); return true; } ``` -------------------------------- ### Statistical Folder Prediction in JavaScript Source: https://context7.com/opto/nostalgy-xpi/llms.txt Implements a machine learning system to predict email folder destinations based on historical sender-recipient-folder associations stored in an SQLite database. It provides functions to predict folders and update statistics. Dependencies include NostalgyPredict, NostalgyFolderName, and a database schema for addresses, folders, and probabilities. ```javascript // Predict most likely folder(s) for current message var predictedFolders = NostalgyPredict.predict_folder(5); // Returns array of up to 5 folder objects ranked by probability // Update statistics when message is filed NostalgyPredict.update_folder(destinationFolder); // Increments count for sender/recipient -> folder associations // Database schema: // addresses: id, address (email), count (total messages) // folders: id, folder (path) // probabilities: address_id, folder_id, probability, count // Prediction query calculates weighted average: // SELECT avg(probabilities.count*100/addresses.count) as prob, folder // FROM addresses, folders, probabilities // WHERE addresses.address IN ('sender@example.com', 'recipient@example.com') // GROUP BY folder ORDER BY prob DESC LIMIT 5 // Enable in preferences: nostalgy_completion_options.use_statistical_prediction = true; ``` -------------------------------- ### Composer Keyboard Shortcuts in JavaScript Source: https://context7.com/opto/nostalgy-xpi/llms.txt Enables keyboard navigation and actions within the email composer, including focusing To/Cc/Bcc fields, adding attachments, and quick field switching. It uses event handling and DOM manipulation. Dependencies include goDoCommand, NostalgyStopEvent, window.showAddressRow, ccShown, bccShown, NostalgyEBI, and NostalgyMakeRegexp. ```javascript // Composer key handler function NostalgyKeyPress(ev) { if (NostalgyEscapePressed >= 1) { if (ev.key == "a") { // Add attachment goDoCommand('cmd_attachFile'); NostalgyStopEvent(ev); } if (ev.key == "t") { // Focus To field let input = window.document.getElementById("toAddrInput"); NostalgyStopEvent(ev); input.focus(); } if (ev.key == "c") { // Show/focus Cc field if (ccShown) { let input = window.document.getElementById("ccAddrInput"); input.focus(); } else { var label_cc = window.document.getElementById("addr_cc"); window.showAddressRow(label_cc, 'addressRowCc'); ccShown = 1; } NostalgyStopEvent(ev); } if (ev.key == "b") { // Show/focus Bcc field if (bccShown) { let input = window.document.getElementById("bccAddrInput"); input.focus(); } else { var label_bcc = window.document.getElementById("addr_bcc"); window.showAddressRow(label_bcc, 'addressRowBcc'); bccShown = 1; } NostalgyStopEvent(ev); } } } // Quick field switching in address inputs // Type "to ", "cc ", or "bcc " followed by space function nostalgy_awRecipientKeyPress(event, element) { var v = element.value; var i = element.selectionStart; var f = v.substr(0, i); if (event.key == " " && (f == "to" || f == "cc" || f == "bcc")) { var select = NostalgyEBI(element.id.replace(/addressCol2#/, "addressCol1#")); select.value = "addr_" + f; element.value = ""; NostalgyStopEvent(event); } } ``` -------------------------------- ### Folder Auto-Completion System in JavaScript Source: https://context7.com/opto/nostalgy-xpi/llms.txt A custom autocomplete component for email folders offering instant suggestions with configurable matching and sorting. It can utilize statistical predictions and recent folder history for suggestions. Dependencies include NostalgyPredict, NostalgyFolderName, NostalgyMakeRegexp, NostalgyIterateMatches, box.shell_completion, Factory, Components.manager, CLASS_ID, CLASS_NAME, and CONTRACT_ID. ```javascript // Autocomplete configuration options var nostalgy_completion_options = { restrict_to_current_server: false, // Only show folders from current account match_only_folder_name: false, // Match folder name or full path match_only_prefix: false, // Require match at start sort_folders: false, // Sort results alphabetically match_case_sensitive: false, // Case-insensitive by default tab_shell_completion: false, // Tab = cycle vs shell-style complete always_include_tags: false, // Include tags (:tagname) in results use_statistical_prediction: false // Use ML predictions }; // Autocomplete implementation function NostalgyGetAutoCompleteValues(text) { var values = []; if (text == "") { // Empty input: show predicted or recent folders var predictedFolders = NostalgyPredict.predict_folder(5); if (predictedFolders && predictedFolders.length > 0) { predictedFolders.forEach(f => values.push(NostalgyFolderName(f))); } // Fill remaining slots with recent folders nostalgy_recent_folders.forEach(fname => values.push(fname)); } else { // Match input against all folders var regex = NostalgyMakeRegexp(text); // Converts ".." to ".*" NostalgyIterateMatches(text, box.shell_completion, function(folder) { values.push(NostalgyFolderName(folder)); }); } return values; } // Register autocomplete component var factory = new Factory(NostalgyAutoCompleteSearch); Components.manager.registerFactory( CLASS_ID, CLASS_NAME, CONTRACT_ID, factory ); ``` -------------------------------- ### Thunderbird Quick Search and Message Filtering (JavaScript) Source: https://context7.com/opto/nostalgy-xpi/llms.txt This JavaScript code enables rapid filtering of email messages by sender, recipient, or subject. It utilizes keyboard shortcuts to interact with Thunderbird's Quick Filter Bar, cycling through predefined search filters. ```javascript function NostalgySearchSenderQuickFilter() { var input = NostalgyEBI("qfb-qs-textbox"); if (!input) return false; var sender = NostalgyMailAuthorName(); var recipient = NostalgyMailRecipName(); var subject = NostalgyMailSubject(); var values = { sender: sender, subject: subject, recipients: recipient }; var fields; if (NostalgyCurrentFolder().displayRecipients) { fields = ["recipients", "sender", "subject"]; } else { fields = ["sender", "subject"]; } var state = QuickFilterBarMuxer.activeFilterer.filterValues.text; var found = 0; for (var i = 0; i < fields.length; i++) { if (JSON.stringify(make_state(fields[i])) == JSON.stringify(state)) { found = i + 1; } } var new_state; if (found < fields.length) { new_state = make_state(fields[found]); } else { new_state = make_state(null); } QuickFilterBarMuxer.activeFilterer.filterValues.text = new_state; QuickFilterBarMuxer._showFilterBar(new_state.text != null); QuickFilterBarMuxer.updateSearch(); return true; } function NostalgyMailAuthorName() { return NostalgyHeaderParser.get_address( gDBView.hdrForFirstSelectedMessage.author ); } function NostalgyMailSubject() { var s = gDBView.hdrForFirstSelectedMessage.mime2DecodedSubject.toLowerCase(); var old; do { old = s; s = s.replace(/^\\[fwd:|^fwd:|^fw:|^re:|^ |^e :|\\]$/g, ""); } while (s != old); return s; } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.