diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index 68f08df..82825d2 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -118,6 +118,10 @@ } }, + "menuCaseCasing": { + "message": "Change casing", + "description": "An entry in the context menu. This is an entry for the case." + }, "menuCaseLowercase": { "message": "Lowercase", "description": "An entry in the context menu. This is an entry for the case." @@ -139,6 +143,14 @@ "message": "Superscript", "description": "An entry in the context menu. This is an entry for the Unicode font." }, + "menuFontSubscript": { + "message": "Subscript", + "description": "An entry in the context menu. This is an entry for the Unicode font." + }, + "menuFontSmallCapsSmallCaps": { + "message": "Small Caps", + "description": "An entry in the context menu. This is an entry for the Unicode font." + }, "menuFontSmallCaps": { "message": "Small Caps", "description": "An entry in the context menu. This is an entry for the Unicode font." @@ -151,6 +163,10 @@ "message": "Unicase", "description": "An entry in the context menu. This is an entry for the Unicode font." }, + "menuFontSerif": { + "message": "Serif", + "description": "An entry in the context menu. This is an entry for the Unicode font." + }, "menuFontSerifBold": { "message": "Serif bold", "description": "An entry in the context menu. This is an entry for the Unicode font." @@ -163,6 +179,10 @@ "message": "Serif bold italic", "description": "An entry in the context menu. This is an entry for the Unicode font." }, + "menuFontSansSerifSansSerif": { + "message": "Sans-serif", + "description": "An entry in the context menu. This is an entry for the Unicode font." + }, "menuFontSansSerif": { "message": "Sans-serif", "description": "An entry in the context menu. This is an entry for the Unicode font." @@ -179,6 +199,10 @@ "message": "Sans-serif bold italic", "description": "An entry in the context menu. This is an entry for the Unicode font." }, + "menuFontScriptScript": { + "message": "Script", + "description": "An entry in the context menu. This is an entry for the Unicode font." + }, "menuFontScript": { "message": "Script", "description": "An entry in the context menu. This is an entry for the Unicode font." @@ -187,7 +211,11 @@ "message": "Script bold", "description": "An entry in the context menu. This is an entry for the Unicode font." }, - "menuFontScriptFraktur": { + "menuFontFrakturFraktur": { + "message": "Fraktur", + "description": "An entry in the context menu. This is an entry for the Unicode font." + }, + "menuFontFraktur": { "message": "Fraktur", "description": "An entry in the context menu. This is an entry for the Unicode font." }, @@ -203,6 +231,10 @@ "message": "Double-struck", "description": "An entry in the context menu. This is an entry for the Unicode font." }, + "menuFontOther": { + "message": "Other/Emojis", + "description": "An entry in the context menu. This is an entry for the Unicode font." + }, "menuFontCircled": { "message": "Circled", "description": "An entry in the context menu. This is an entry for the Unicode font." diff --git a/src/background/modules/ContextMenu.js b/src/background/modules/ContextMenu.js index a3af1e4..8e962ab 100644 --- a/src/background/modules/ContextMenu.js +++ b/src/background/modules/ContextMenu.js @@ -5,7 +5,7 @@ import { isMobile } from "/common/modules/MobileHelper.js"; import * as Notifications from "/common/modules/Notifications.js"; import { COMMUNICATION_MESSAGE_TYPE } from "/common/modules/data/BrowserCommunicationTypes.js"; -import { menuStructure, SEPARATOR_ID, TRANSFORMATION_TYPE } from "/common/modules/data/Fonts.js"; +import { menuStructure, SEPARATOR_ID_PREFIX, TRANSFORMATION_TYPE } from "/common/modules/data/Fonts.js"; const menus = browser.menus || browser.contextMenus; // fallback for Thunderbird const PREVIEW_STRING_CUT_LENGTH = 100; // a setting that may improve performance by not calculating invisible parts of the context menu @@ -124,7 +124,8 @@ async function buildMenu(unicodeFontSettings, exampleText = null) { if (unicodeFontSettings.changeFont) { await addMenuItems(menuStructure[TRANSFORMATION_TYPE.FONT], unicodeFontSettings, exampleText); } - if (unicodeFontSettings.changeFont && + if (!unicodeFontSettings.nested && + unicodeFontSettings.changeFont && unicodeFontSettings.changeCase && !menuIsShown) { await menus.create({ @@ -140,18 +141,50 @@ async function buildMenu(unicodeFontSettings, exampleText = null) { menuIsShown = true; } +/** + * Create Unicode menu items. + * + * @param {string|null} transformationId + * @param {string[]} menuItems + * @param {Object} unicodeFontSettings + * @param {string?} exampleText + * @returns {Promise} + */ +async function createMenu(transformationId, menuItems, unicodeFontSettings, exampleText) { + for (const currentTransformationId of menuItems) { + const translatedMenuText = browser.i18n.getMessage(currentTransformationId); + const textToBeTransformed = unicodeFontSettings.livePreview && exampleText ? exampleText : translatedMenuText; + const transformedText = UnicodeTransformationHandler.transformText(textToBeTransformed, currentTransformationId); + + let menuText = unicodeFontSettings.showReadableText ? browser.i18n.getMessage("menuReadableTextWrapper", [translatedMenuText, transformedText]) : transformedText; + menuText = menuText.replaceAll("&", "&&"); + if (menuIsShown) { + menus.update(currentTransformationId, { + title: menuText + }); + } else { + await menus.create({ + id: currentTransformationId, + parentId: transformationId, + title: menuText, + contexts: ["editable"] + }); + } + } +} + /** * Add Unicode menu items. * - * @param {string[]|symbol[]} menuItems + * @param {Object.} menuItems * @param {Object} [unicodeFontSettings] * @param {string?} [exampleText=null] * @returns {Promise} */ async function addMenuItems(menuItems, unicodeFontSettings = lastCachedUnicodeFontSettings, exampleText = null) { - for (const transformationId of menuItems) { - if (transformationId === SEPARATOR_ID) { - if (menuIsShown) { + for (const [transformationId, currentMenuItems] of Object.entries(menuItems)) { + if (transformationId.startsWith(SEPARATOR_ID_PREFIX)) { + if (unicodeFontSettings.nested || menuIsShown) { continue; } @@ -163,29 +196,22 @@ async function addMenuItems(menuItems, unicodeFontSettings = lastCachedUnicodeFo continue; } - const translatedMenuText = browser.i18n.getMessage(transformationId); - let textToBeTransformed = translatedMenuText; - if (unicodeFontSettings.livePreview && exampleText) { - textToBeTransformed = exampleText; - } - const transformedText = UnicodeTransformationHandler.transformText(textToBeTransformed, transformationId); - - let menuText = transformedText; - if (unicodeFontSettings.showReadableText) { - menuText = browser.i18n.getMessage("menuReadableTextWrapper", [translatedMenuText, transformedText]); - } - menuText = menuText.replaceAll("&", "&&"); - - if (menuIsShown) { - menus.update(transformationId, { - title: menuText - }); + if (unicodeFontSettings.nested && currentMenuItems.length > 1) { + const translatedMenuText = browser.i18n.getMessage(transformationId); + if (menuIsShown) { + menus.update(transformationId, { + title: translatedMenuText + }); + } else { + await menus.create({ + id: transformationId, + title: translatedMenuText, + contexts: ["editable"] + }); + } + await createMenu(transformationId, currentMenuItems, unicodeFontSettings, exampleText); } else { - await menus.create({ - id: transformationId, - title: menuText, - contexts: ["editable"] - }); + await createMenu(null, currentMenuItems, unicodeFontSettings, exampleText); } } } diff --git a/src/common/modules/data/DefaultSettings.js b/src/common/modules/data/DefaultSettings.js index db8558c..079c336 100644 --- a/src/common/modules/data/DefaultSettings.js +++ b/src/common/modules/data/DefaultSettings.js @@ -24,8 +24,9 @@ const defaultSettings = { unicodeFont: { changeFont: true, changeCase: true, - showReadableText: false, - livePreview: false + showReadableText: true, + livePreview: true, + nested: true }, notifications: { send: true diff --git a/src/common/modules/data/Fonts.js b/src/common/modules/data/Fonts.js index d62a4fc..ead0b5d 100644 --- a/src/common/modules/data/Fonts.js +++ b/src/common/modules/data/Fonts.js @@ -17,13 +17,13 @@ export const TRANSFORMATION_TYPE = Object.freeze({ }); /** - * Separater symbol + * Separater string * * @public * @const - * @type {symbol} + * @type {string} */ -export const SEPARATOR_ID = Symbol("separator"); +export const SEPARATOR_ID_PREFIX = "separator"; /** * Unique prefix for all IDs related to casing. @@ -48,41 +48,66 @@ export const FONT_ID_PREFIX = "menuFont"; * * @public * @const - * @type {Object.} + * @type {Object.>>} */ export const menuStructure = Object.freeze({ - [TRANSFORMATION_TYPE.FONT]: [ - `${FONT_ID_PREFIX}Superscript`, - `${FONT_ID_PREFIX}SmallCaps`, - `${FONT_ID_PREFIX}AllSmallCaps`, - `${FONT_ID_PREFIX}Unicase`, - SEPARATOR_ID, - `${FONT_ID_PREFIX}SerifBold`, - `${FONT_ID_PREFIX}SerifItalic`, - `${FONT_ID_PREFIX}SerifBoldItalic`, - `${FONT_ID_PREFIX}SansSerif`, - `${FONT_ID_PREFIX}SansSerifBold`, - `${FONT_ID_PREFIX}SansSerifItalic`, - `${FONT_ID_PREFIX}SansSerifBoldItalic`, - `${FONT_ID_PREFIX}Script`, - `${FONT_ID_PREFIX}ScriptBold`, - `${FONT_ID_PREFIX}ScriptFraktur`, - `${FONT_ID_PREFIX}FrakturBold`, - `${FONT_ID_PREFIX}Monospace`, - `${FONT_ID_PREFIX}DoubleStruck`, - SEPARATOR_ID, - `${FONT_ID_PREFIX}Circled`, - `${FONT_ID_PREFIX}CircledBlack`, - `${FONT_ID_PREFIX}Squared`, - `${FONT_ID_PREFIX}SquaredBlack`, - `${FONT_ID_PREFIX}Fullwidth` - ], - [TRANSFORMATION_TYPE.CASING]: [ - `${CASE_ID_PREFIX}Lowercase`, - `${CASE_ID_PREFIX}Uppercase`, - `${CASE_ID_PREFIX}CapitalizeEachWord`, - `${CASE_ID_PREFIX}ToggleCase` - ] + [TRANSFORMATION_TYPE.FONT]: { + [`${FONT_ID_PREFIX}Superscript`]: [ + `${FONT_ID_PREFIX}Superscript` + ], + [`${FONT_ID_PREFIX}Subscript`]: [ + `${FONT_ID_PREFIX}Subscript` + ], + [`${FONT_ID_PREFIX}SmallCapsSmallCaps`]: [ + `${FONT_ID_PREFIX}SmallCaps`, + `${FONT_ID_PREFIX}AllSmallCaps`, + `${FONT_ID_PREFIX}Unicase` + ], + [`${SEPARATOR_ID_PREFIX}1`]: [], + [`${FONT_ID_PREFIX}Serif`]: [ + `${FONT_ID_PREFIX}SerifBold`, + `${FONT_ID_PREFIX}SerifItalic`, + `${FONT_ID_PREFIX}SerifBoldItalic` + ], + [`${FONT_ID_PREFIX}SansSerifSansSerif`]: [ + `${FONT_ID_PREFIX}SansSerif`, + `${FONT_ID_PREFIX}SansSerifBold`, + `${FONT_ID_PREFIX}SansSerifItalic`, + `${FONT_ID_PREFIX}SansSerifBoldItalic` + ], + [`${FONT_ID_PREFIX}ScriptScript`]: [ + `${FONT_ID_PREFIX}Script`, + `${FONT_ID_PREFIX}ScriptBold` + ], + [`${FONT_ID_PREFIX}FrakturFraktur`]: [ + `${FONT_ID_PREFIX}Fraktur`, + `${FONT_ID_PREFIX}FrakturBold` + ], + [`${FONT_ID_PREFIX}Monospace`]: [ + `${FONT_ID_PREFIX}Monospace` + ], + [`${FONT_ID_PREFIX}DoubleStruck`]: [ + `${FONT_ID_PREFIX}DoubleStruck` + ], + [`${SEPARATOR_ID_PREFIX}2`]: [], + [`${FONT_ID_PREFIX}Other`]: [ + `${FONT_ID_PREFIX}Circled`, + `${FONT_ID_PREFIX}CircledBlack`, + `${FONT_ID_PREFIX}Squared`, + `${FONT_ID_PREFIX}SquaredBlack` + ], + [`${FONT_ID_PREFIX}Fullwidth`]: [ + `${FONT_ID_PREFIX}Fullwidth` + ] + }, + [TRANSFORMATION_TYPE.CASING]: { + [`${CASE_ID_PREFIX}Casing`]: [ + `${CASE_ID_PREFIX}Lowercase`, + `${CASE_ID_PREFIX}Uppercase`, + `${CASE_ID_PREFIX}CapitalizeEachWord`, + `${CASE_ID_PREFIX}ToggleCase` + ] + } }); /** @@ -106,7 +131,7 @@ const fonts = Object.freeze({ [`${FONT_ID_PREFIX}SansSerifBoldItalic`]: "๐˜ผ๐˜ฝ๐˜พ๐˜ฟ๐™€๐™๐™‚๐™ƒ๐™„๐™…๐™†๐™‡๐™ˆ๐™‰๐™Š๐™‹๐™Œ๐™๐™Ž๐™๐™๐™‘๐™’๐™“๐™”๐™•๐™–๐™—๐™˜๐™™๐™š๐™›๐™œ๐™๐™ž๐™Ÿ๐™ ๐™ก๐™ข๐™ฃ๐™ค๐™ฅ๐™ฆ๐™ง๐™จ๐™ฉ๐™ช๐™ซ๐™ฌ๐™ญ๐™ฎ๐™ฏ", [`${FONT_ID_PREFIX}Script`]: "๐’œโ„ฌ๐’ž๐’Ÿโ„ฐโ„ฑ๐’ขโ„‹โ„๐’ฅ๐’ฆโ„’โ„ณ๐’ฉ๐’ช๐’ซ๐’ฌโ„›๐’ฎ๐’ฏ๐’ฐ๐’ฑ๐’ฒ๐’ณ๐’ด๐’ต๐’ถ๐’ท๐’ธ๐’นโ„ฏ๐’ปโ„Š๐’ฝ๐’พ๐’ฟ๐“€๐“๐“‚๐“ƒโ„ด๐“…๐“†๐“‡๐“ˆ๐“‰๐“Š๐“‹๐“Œ๐“๐“Ž๐“", [`${FONT_ID_PREFIX}ScriptBold`]: "๐“๐“‘๐“’๐““๐“”๐“•๐“–๐“—๐“˜๐“™๐“š๐“›๐“œ๐“๐“ž๐“Ÿ๐“ ๐“ก๐“ข๐“ฃ๐“ค๐“ฅ๐“ฆ๐“ง๐“จ๐“ฉ๐“ช๐“ซ๐“ฌ๐“ญ๐“ฎ๐“ฏ๐“ฐ๐“ฑ๐“ฒ๐“ณ๐“ด๐“ต๐“ถ๐“ท๐“ธ๐“น๐“บ๐“ป๐“ผ๐“ฝ๐“พ๐“ฟ๐”€๐”๐”‚๐”ƒ", - [`${FONT_ID_PREFIX}ScriptFraktur`]: "๐”„๐”…โ„ญ๐”‡๐”ˆ๐”‰๐”Šโ„Œโ„‘๐”๐”Ž๐”๐”๐”‘๐”’๐”“๐””โ„œ๐”–๐”—๐”˜๐”™๐”š๐”›๐”œโ„จ๐”ž๐”Ÿ๐” ๐”ก๐”ข๐”ฃ๐”ค๐”ฅ๐”ฆ๐”ง๐”จ๐”ฉ๐”ช๐”ซ๐”ฌ๐”ญ๐”ฎ๐”ฏ๐”ฐ๐”ฑ๐”ฒ๐”ณ๐”ด๐”ต๐”ถ๐”ท", + [`${FONT_ID_PREFIX}Fraktur`]: "๐”„๐”…โ„ญ๐”‡๐”ˆ๐”‰๐”Šโ„Œโ„‘๐”๐”Ž๐”๐”๐”‘๐”’๐”“๐””โ„œ๐”–๐”—๐”˜๐”™๐”š๐”›๐”œโ„จ๐”ž๐”Ÿ๐” ๐”ก๐”ข๐”ฃ๐”ค๐”ฅ๐”ฆ๐”ง๐”จ๐”ฉ๐”ช๐”ซ๐”ฌ๐”ญ๐”ฎ๐”ฏ๐”ฐ๐”ฑ๐”ฒ๐”ณ๐”ด๐”ต๐”ถ๐”ท", [`${FONT_ID_PREFIX}FrakturBold`]: "๐•ฌ๐•ญ๐•ฎ๐•ฏ๐•ฐ๐•ฑ๐•ฒ๐•ณ๐•ด๐•ต๐•ถ๐•ท๐•ธ๐•น๐•บ๐•ป๐•ผ๐•ฝ๐•พ๐•ฟ๐–€๐–๐–‚๐–ƒ๐–„๐–…๐–†๐–‡๐–ˆ๐–‰๐–Š๐–‹๐–Œ๐–๐–Ž๐–๐–๐–‘๐–’๐–“๐–”๐–•๐––๐–—๐–˜๐–™๐–š๐–›๐–œ๐–๐–ž๐–Ÿ", [`${FONT_ID_PREFIX}Monospace`]: "๐™ฐ๐™ฑ๐™ฒ๐™ณ๐™ด๐™ต๐™ถ๐™ท๐™ธ๐™น๐™บ๐™ป๐™ผ๐™ฝ๐™พ๐™ฟ๐š€๐š๐š‚๐šƒ๐š„๐š…๐š†๐š‡๐šˆ๐š‰๐šŠ๐š‹๐šŒ๐š๐šŽ๐š๐š๐š‘๐š’๐š“๐š”๐š•๐š–๐š—๐š˜๐š™๐šš๐š›๐šœ๐š๐šž๐šŸ๐š ๐šก๐šข๐šฃ๐Ÿถ๐Ÿท๐Ÿธ๐Ÿน๐Ÿบ๐Ÿป๐Ÿผ๐Ÿฝ๐Ÿพ๐Ÿฟ", [`${FONT_ID_PREFIX}DoubleStruck`]: "๐”ธ๐”นโ„‚๐”ป๐”ผ๐”ฝ๐”พโ„๐•€๐•๐•‚๐•ƒ๐•„โ„•๐•†โ„™โ„šโ„๐•Š๐•‹๐•Œ๐•๐•Ž๐•๐•โ„ค๐•’๐•“๐•”๐••๐•–๐•—๐•˜๐•™๐•š๐•›๐•œ๐•๐•ž๐•Ÿ๐• ๐•ก๐•ข๐•ฃ๐•ค๐•ฅ๐•ฆ๐•ง๐•จ๐•ฉ๐•ช๐•ซ๐Ÿ˜๐Ÿ™๐Ÿš๐Ÿ›๐Ÿœ๐Ÿ๐Ÿž๐ŸŸ๐Ÿ ๐Ÿก", diff --git a/src/options/options.html b/src/options/options.html index b1495d7..c643584 100644 --- a/src/options/options.html +++ b/src/options/options.html @@ -144,6 +144,13 @@

Entry design

In addition to the examples of the transformation, this also shows the name of transformation as text. +
  • +
    + + +
    +
  • +