<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/.
*/
'use strict';

import {
  configs,
  log,
  appendContents,
  sanitizeForHTMLText,
  shouldEnableCommand,
} from '/common/common.js';
import * as Dialog from '/extlib/dialog.js';
import * as Constants from '/common/constants.js';

const container = document.getElementById('commands');

browser.mailTabs.query({ active: true, windowId: browser.windows.WINDOW_ID_CURRENT }).then(async tabs => {
  const tab     = tabs[0];
  const message = await browser.messageDisplay.getDisplayedMessage(tab.id);
  const account = await browser.accounts.get(message.folder.accountId);
  log('original message: ', message);

  for (const definition of (configs.buttons || [])) {
    if (!definition.quoteType && !definition.forwardType) {
      createButton({
        ...definition,
        id:        `${definition.id}:no-quote`,
        quoteType: Constants.QUOTE_NEVER
      }, { message, account });
      createButton({
        ...definition,
        id:        `${definition.id}:with-quote`,
        quoteType: Constants.QUOTE_ALWAYS,
        label:     `${configs.labelQuotePrefix}${definition.label}${configs.labelQuoteSuffix}`
      }, { message, account });
    }
    else {
      createButton(definition, { message, account });
    }
  }
});


function createButton(definition, { message } = {}) {
  log(`build button: `, definition);
  let label = sanitizeForHTMLText(definition.label);
  if (definition.accesskey) {
    const accesskeyMatcher = definition.accesskey && new RegExp(`^(.*)(${definition.accesskey})(.*)$`, 'i');
    const matched = label.match(accesskeyMatcher);
    if (matched)
      label = `${sanitizeForHTMLText(matched[1])}<key>${sanitizeForHTMLText(matched[2])}</key>${sanitizeForHTMLText(matched[3])}`
    else
      label += `(<key>${sanitizeForHTMLText(definition.accesskey)}</key>)`
  }
  const accesskey = definition.accesskey ? ` accesskey=${JSON.stringify(sanitizeForHTMLText(definition.accesskey))}` : '';
  const source = `
    <li class="flex-box row"
       ><button id=${JSON.stringify('button:' + sanitizeForHTMLText(definition.id))}
                class="flex-box row"
                ${accesskey}
                data-accesskey=${accesskey ? JSON.stringify(sanitizeForHTMLText(definition.accesskey.toLowerCase())) : '""'}
                disabled="true"
               ><span class="icon flex-box column"
                      style='background-image:url(${JSON.stringify(sanitizeForHTMLText(definition.icon))})'
                     ></span><label class="flex-box column"
                                   ><span>${label}</span></label></button></li>
  `.trim();
  log(' => source: ', source);
  appendContents(container, source);
  const button = container.lastChild.querySelector('button');
  shouldEnableCommand(definition, { message }).then(enabled => {
    if (!enabled)
      return;
    button.removeAttribute('disabled');
    Dialog.initButton(container.lastChild, async _event => {
      browser.runtime.sendMessage({
        type: Constants.TYPE_DO_BUTTON_COMMAND,
        params: definition
      });
      window.close();
    });
  });
}

let mLastHoverItem;
let mLastFocusedItem;

container.addEventListener('mouseover', _event => {
  setHover(null);
  if (mLastFocusedItem) {
    mLastFocusedItem.blur();
    mLastFocusedItem = null;
  }
  mLastHoverItem = null;
});

window.addEventListener('keydown', event => {<commit_msg>Bind event listener only to the corresponding button<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/.
*/
'use strict';

import {
  configs,
  log,
  appendContents,
  sanitizeForHTMLText,
  shouldEnableCommand,
} from '/common/common.js';
import * as Dialog from '/extlib/dialog.js';
import * as Constants from '/common/constants.js';

const container = document.getElementById('commands');

browser.mailTabs.query({ active: true, windowId: browser.windows.WINDOW_ID_CURRENT }).then(async tabs => {
  const tab     = tabs[0];
  const message = await browser.messageDisplay.getDisplayedMessage(tab.id);
  const account = await browser.accounts.get(message.folder.accountId);
  log('original message: ', message);

  for (const definition of (configs.buttons || [])) {
    if (!definition.quoteType && !definition.forwardType) {
      createButton({
        ...definition,
        id:        `${definition.id}:no-quote`,
        quoteType: Constants.QUOTE_NEVER
      }, { message, account });
      createButton({
        ...definition,
        id:        `${definition.id}:with-quote`,
        quoteType: Constants.QUOTE_ALWAYS,
        label:     `${configs.labelQuotePrefix}${definition.label}${configs.labelQuoteSuffix}`
      }, { message, account });
    }
    else {
      createButton(definition, { message, account });
    }
  }
});


function createButton(definition, { message } = {}) {
  log(`build button: `, definition);
  let label = sanitizeForHTMLText(definition.label);
  if (definition.accesskey) {
    const accesskeyMatcher = definition.accesskey && new RegExp(`^(.*)(${definition.accesskey})(.*)$`, 'i');
    const matched = label.match(accesskeyMatcher);
    if (matched)
      label = `${sanitizeForHTMLText(matched[1])}<key>${sanitizeForHTMLText(matched[2])}</key>${sanitizeForHTMLText(matched[3])}`
    else
      label += `(<key>${sanitizeForHTMLText(definition.accesskey)}</key>)`
  }
  const accesskey = definition.accesskey ? ` accesskey=${JSON.stringify(sanitizeForHTMLText(definition.accesskey))}` : '';
  const source = `
    <li class="flex-box row"
       ><button id=${JSON.stringify('button:' + sanitizeForHTMLText(definition.id))}
                class="flex-box row"
                ${accesskey}
                data-accesskey=${accesskey ? JSON.stringify(sanitizeForHTMLText(definition.accesskey.toLowerCase())) : '""'}
                disabled="true"
               ><span class="icon flex-box column"
                      style='background-image:url(${JSON.stringify(sanitizeForHTMLText(definition.icon))})'
                     ></span><label class="flex-box column"
                                   ><span>${label}</span></label></button></li>
  `.trim();
  log(' => source: ', source);
  appendContents(container, source);
  const button = container.lastChild.querySelector('button');
  shouldEnableCommand(definition, { message }).then(enabled => {
    if (!enabled)
      return;
    button.removeAttribute('disabled');
    Dialog.initButton(button, async _event => {
      browser.runtime.sendMessage({
        type: Constants.TYPE_DO_BUTTON_COMMAND,
        params: definition
      });
      window.close();
    });
  });
}

let mLastHoverItem;
let mLastFocusedItem;

container.addEventListener('mouseover', _event => {
  setHover(null);
  if (mLastFocusedItem) {
    mLastFocusedItem.blur();
    mLastFocusedItem = null;
  }
  mLastHoverItem = null;
});

window.addEventListener('keydown', event => {
{'fraction_non_alphanumeric': 0.14988907376594565, 'fraction_numerical': 0.0022185246810870773, 'mean_word_length': 3.3425647200481636, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3522700', 'n_tokens_mistral': 2121, 'n_tokens_neox': 2106, 'n_words': 415}