<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright 2017 <NAME>.

// https://developer.mozilla.org/en-US/docs/Extensions/bootstrap.js
// Also, lots of code here cribbed from
// https://developer.mozilla.org/en-US/Add-ons/How_to_convert_an_overlay_extension_to_restartless

const {Log4Moz} = ChromeUtils.import("resource:///modules/gloda/log4moz.js");
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
const {MailServices} = ChromeUtils.import(
    "resource:///modules/MailServices.jsm");

prefBranch = Services.prefs;
prefPrefix = "extensions.reply-to-multiple-messages";
bccPref = prefPrefix + ".use_bcc";
refsPref = prefPrefix + ".hide_references";
prefsLoaded = false;

function startup(data, reason) {
    setEverythingUp("startup");
    logger.trace("startup");
}

function setEverythingUp(which) {
    /// Bootstrap data structure @see https://developer.mozilla.org/en-US/docs/Extensions/Bootstrapped_extensions#Bootstrap_data
    ///   string id
    ///   string version
    ///   nsIFile installPath
    ///   nsIURI resourceURI
    /// 
    /// Reason types:
    ///   APP_STARTUP
    ///   ADDON_ENABLE
    ///   ADDON_INSTALL
    ///   ADDON_UPGRADE
    ///   ADDON_DOWNGRADE
    loadDefaultPreferences();
    initLogging();
    logger.trace("setEverythingUp");
    if (which == "startup") {
        Services.obs.addObserver(WindowObserver, "mail-startup-done", false);
        forEachOpenWindow(loadIntoWindow);
    }
}

function shutdown(data, reason) {
    try {
        logger.trace("shutdown");
    } catch {}
    /// Bootstrap data structure @see https://developer.mozilla.org/en-US/docs/Extensions/Bootstrapped_extensions#Bootstrap_data
    ///   string id
    ///   string version
    ///   nsIFile installPath
    ///   nsIURI resourceURI
    /// 
    /// Reason types:
    ///   APP_SHUTDOWN
    ///   ADDON_DISABLE
    ///   ADDON_UNINSTALL
    ///   ADDON_UPGRADE
    ///   ADDON_DOWNGRADE
    if (reason == APP_SHUTDOWN)
        return;

    forEachOpenWindow(unloadFromWindow);
    Services.obs.removeObserver(WindowObserver, "mail-startup-done");

    // HACK WARNING: The Addon Manager does not properly clear all addon
    //               related caches on update; in order to fully update images
    //               and locales, their caches need clearing here
    Services.obs.notifyObservers(null, "chrome-flush-caches", null);
}

function install(data, reason) {
    setEverythingUp("install");
    logger.trace("install");
    /// Bootstrap data structure @see https://developer.mozilla.org/en-US/docs/Extensions/Bootstrapped_extensions#Bootstrap_data
    ///   string id
    ///   string version
    ///   nsIFile installPath
    ///   nsIURI resourceURI
    /// 
    /// Reason types:
    ///   ADDON_INSTALL
    ///   ADDON_UPGRADE
    ///   ADDON_DOWNGRADE
}

function uninstall(data, reason) {
    logger.trace("uninstall");
    /// Bootstrap data structure @see https://developer.mozilla.org/en-US/docs/Extensions/Bootstrapped_extensions#Bootstrap_data
    ///   string id
    ///   string version
    ///   nsIFile installPath
    ///   nsIURI resourceURI
    /// 
    /// Reason types:
    ///   ADDON_UNINSTALL
    ///   ADDON_UPGRADE
    ///   ADDON_DOWNGRADE
}

function loadIntoWindow(window) {
    logger.trace("loadInToWindow");
    var document = window.document;
    var menu = document.getElementById("messageMenuPopup");
    if (! menu) {
        return;
    }

    if (document.getElementById("rtmm_menu_reply")) {
        // Already done during startup!
        return;
    }

    var old_menuitem = document.getElementById("menu_forwardMsg");

    var new_menuitem = document.createXULElement("menuitem");
    new_menuitem.setAttribute("id", "rtmm_menu_reply");
    new_menuitem.setAttribute("label", "Reply to Selected");
    // Closure so we have access to window.
    var replyToSelectedClosure = function(event) { replyToSelected(window); };
    new_menuitem.addEventListener("command", replyToSelectedClosure);
    menu.insertBefore(new_menuitem, old_menuitem);

    new_menuitem = document.createXULElement("menuitem");
    new_menuitem.setAttribute("id", "rtmm_menu_replyAll");
    new_menuitem.setAttribute("label", "Reply All to Selected");
    // Closure so we have access to window.
    var replyAllToSelectedClosure = function(event) {
        replyAllToSelected(window); };
    new_menuitem.addEventListener("command", replyAllToSelectedClosure);
    menu.insertBefore(new_menuitem, old_menuitem);

    var contextMenu = document.getElementById("mailContext");
    old_menuitem = document.getElementById("mailContext-forward");
    new_menuitem = document.createXULElement("menuitem");
    new_menuitem.setAttribute("id", "rtmm_menuContext_reply");
    new_menuitem.setAttribute("label", "Reply to Selected");
    new_menuitem.addEventListener("command", replyToSelectedClosure);
    contextMenu.insertBefore(new_menuitem, old_menuitem);

    new_menuitem = document.createXULElement("menuitem");
    new_menuitem.setAttribute("id", "rtmm_menuContext_replyAll");
    new_menuitem.setAttribute("label", "Reply All to Selected");
    new_menuitem.addEventListener("command", replyAllToSelectedClosure);
    contextMenu.insertBefore(new_menuitem, old_menuitem);

    // Isn't it just AWESOME what I have to add these menu commands in THREE
    // DIFFERENT PLACES?! Way, to go, Thunderbird developers, great job making
    // it easy for add-on developers to add new commands!
    if (! isSeaMonkey()) {
        var appMenu = document.getElementById("appmenu_messageMenuPopup");
        old_menuitem = document.getElementById("appmenu_forwardMsg");
        new_menuitem = document.createXULElement("menuitem");
        new_menuitem.setAttribute("id", "rtmm_appmenu_reply");
        new_menuitem.setAttribute("label", "Reply to Selected");
        new_menuitem.addEventListener("command", replyToSelectedClosure);
        appMenu.insertBefore(new_menuitem, old_menuitem);

        new_menuitem = document.createXULElement("menuitem");
        new_menuitem.setAttribute("id", "rtmm_appmenu_replyAll");
        new_menuitem.setAttribute("label", "Reply All to Selected");
        new_menuitem.addEventListener("command", replyAllToSelectedClosure);
        appMenu.insertBefore(new_menuitem, old_menuitem);
    }

    // So, the object here is for the menu command to be greyed out when no
    // messages are selected. For other command in this menu, that's
    // implemented by the mailMessageMenuItems commandset, which has
    // commandupdater set to true and oncommandupdate set to
    // goUpdateMailMenuItems(this). I can't horn in on that action since my<commit_msg>Fix menu commands in the the "hamburger menu"<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright 2017 <NAME>.

// https://developer.mozilla.org/en-US/docs/Extensions/bootstrap.js
// Also, lots of code here cribbed from
// https://developer.mozilla.org/en-US/Add-ons/How_to_convert_an_overlay_extension_to_restartless

const {Log4Moz} = ChromeUtils.import("resource:///modules/gloda/log4moz.js");
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
const {MailServices} = ChromeUtils.import(
    "resource:///modules/MailServices.jsm");

prefBranch = Services.prefs;
prefPrefix = "extensions.reply-to-multiple-messages";
bccPref = prefPrefix + ".use_bcc";
refsPref = prefPrefix + ".hide_references";
prefsLoaded = false;

function startup(data, reason) {
    setEverythingUp("startup");
    logger.trace("startup");
}

function setEverythingUp(which) {
    /// Bootstrap data structure @see https://developer.mozilla.org/en-US/docs/Extensions/Bootstrapped_extensions#Bootstrap_data
    ///   string id
    ///   string version
    ///   nsIFile installPath
    ///   nsIURI resourceURI
    /// 
    /// Reason types:
    ///   APP_STARTUP
    ///   ADDON_ENABLE
    ///   ADDON_INSTALL
    ///   ADDON_UPGRADE
    ///   ADDON_DOWNGRADE
    loadDefaultPreferences();
    initLogging();
    logger.trace("setEverythingUp");
    if (which == "startup") {
        Services.obs.addObserver(WindowObserver, "mail-startup-done", false);
        forEachOpenWindow(loadIntoWindow);
    }
}

function shutdown(data, reason) {
    try {
        logger.trace("shutdown");
    } catch {}
    /// Bootstrap data structure @see https://developer.mozilla.org/en-US/docs/Extensions/Bootstrapped_extensions#Bootstrap_data
    ///   string id
    ///   string version
    ///   nsIFile installPath
    ///   nsIURI resourceURI
    /// 
    /// Reason types:
    ///   APP_SHUTDOWN
    ///   ADDON_DISABLE
    ///   ADDON_UNINSTALL
    ///   ADDON_UPGRADE
    ///   ADDON_DOWNGRADE
    if (reason == APP_SHUTDOWN)
        return;

    forEachOpenWindow(unloadFromWindow);
    Services.obs.removeObserver(WindowObserver, "mail-startup-done");

    // HACK WARNING: The Addon Manager does not properly clear all addon
    //               related caches on update; in order to fully update images
    //               and locales, their caches need clearing here
    Services.obs.notifyObservers(null, "chrome-flush-caches", null);
}

function install(data, reason) {
    setEverythingUp("install");
    logger.trace("install");
    /// Bootstrap data structure @see https://developer.mozilla.org/en-US/docs/Extensions/Bootstrapped_extensions#Bootstrap_data
    ///   string id
    ///   string version
    ///   nsIFile installPath
    ///   nsIURI resourceURI
    /// 
    /// Reason types:
    ///   ADDON_INSTALL
    ///   ADDON_UPGRADE
    ///   ADDON_DOWNGRADE
}

function uninstall(data, reason) {
    logger.trace("uninstall");
    /// Bootstrap data structure @see https://developer.mozilla.org/en-US/docs/Extensions/Bootstrapped_extensions#Bootstrap_data
    ///   string id
    ///   string version
    ///   nsIFile installPath
    ///   nsIURI resourceURI
    /// 
    /// Reason types:
    ///   ADDON_UNINSTALL
    ///   ADDON_UPGRADE
    ///   ADDON_DOWNGRADE
}

function loadIntoWindow(window) {
    logger.trace("loadInToWindow");
    var document = window.document;
    var menu = document.getElementById("messageMenuPopup");
    if (! menu) {
        return;
    }

    if (document.getElementById("rtmm_menu_reply")) {
        // Already done during startup!
        return;
    }

    var old_menuitem = document.getElementById("menu_forwardMsg");

    var new_menuitem = document.createXULElement("menuitem");
    new_menuitem.setAttribute("id", "rtmm_menu_reply");
    new_menuitem.setAttribute("label", "Reply to Selected");
    // Closure so we have access to window.
    var replyToSelectedClosure = function(event) { replyToSelected(window); };
    new_menuitem.addEventListener("command", replyToSelectedClosure);
    menu.insertBefore(new_menuitem, old_menuitem);

    new_menuitem = document.createXULElement("menuitem");
    new_menuitem.setAttribute("id", "rtmm_menu_replyAll");
    new_menuitem.setAttribute("label", "Reply All to Selected");
    // Closure so we have access to window.
    var replyAllToSelectedClosure = function(event) {
        replyAllToSelected(window); };
    new_menuitem.addEventListener("command", replyAllToSelectedClosure);
    menu.insertBefore(new_menuitem, old_menuitem);

    var contextMenu = document.getElementById("mailContext");
    old_menuitem = document.getElementById("mailContext-forward");
    new_menuitem = document.createXULElement("menuitem");
    new_menuitem.setAttribute("id", "rtmm_menuContext_reply");
    new_menuitem.setAttribute("label", "Reply to Selected");
    new_menuitem.addEventListener("command", replyToSelectedClosure);
    contextMenu.insertBefore(new_menuitem, old_menuitem);

    new_menuitem = document.createXULElement("menuitem");
    new_menuitem.setAttribute("id", "rtmm_menuContext_replyAll");
    new_menuitem.setAttribute("label", "Reply All to Selected");
    new_menuitem.addEventListener("command", replyAllToSelectedClosure);
    contextMenu.insertBefore(new_menuitem, old_menuitem);

    // Isn't it just AWESOME what I have to add these menu commands in THREE
    // DIFFERENT PLACES?! Way, to go, Thunderbird developers, great job making
    // it easy for add-on developers to add new commands!
    if (! isSeaMonkey()) {
        old_menuitem = document.getElementById("appmenu_forwardMsg");
        new_menuitem = document.createXULElement("toolbarbutton");
        new_menuitem.setAttribute("id", "rtmm_appmenu_reply");
        new_menuitem.setAttribute("label", "Reply to Selected");
        new_menuitem.setAttribute("class", old_menuitem.getAttribute("class"));
        new_menuitem.addEventListener("command", replyToSelectedClosure);
        old_menuitem.parentElement.insertBefore(new_menuitem, old_menuitem);

        new_menuitem = document.createXULElement("toolbarbutton");
        new_menuitem.setAttribute("id", "rtmm_appmenu_replyAll");
        new_menuitem.setAttribute("label", "Reply All to Selected");
        new_menuitem.setAttribute("class", old_menuitem.getAttribute("class"));
        new_menuitem.addEventListener("command", replyAllToSelectedClosure);
        old_menuitem.parentElement.insertBefore(new_menuitem, old_menuitem);
    }

    // So, the object here is for the menu command to be greyed out when no
    // messages are selected. For other command in this menu, that's
    // implemented by the mailMessageMenuItems commandset, which has
    // commandupdater set to true and oncommandupdate set to
    // goUpdateMailMenuItems(this). I can't horn in on that action since my
{'fraction_non_alphanumeric': 0.11793983986150183, 'fraction_numerical': 0.0014426891726177595, 'mean_word_length': 3.336565530184548, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 12, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4839186', 'n_tokens_mistral': 4138, 'n_tokens_neox': 4103, 'n_words': 867}