Bug 1870306 - Enable Select Translations context menu item for hyperlinked text r=translations-reviewers,fluent-reviewers,bolsson,gregtatum

Adds the functionality for the Select Translations
context menu item to appear when a hyperlink is clicked
even if no text is selected. Selected text takes precedence
if a link is clicked while there is also an active selection.

Depends on D197225

Differential Revision: https://phabricator.services.mozilla.com/D197226
This commit is contained in:
Erik Nordin 2024-01-05 18:50:14 +00:00
Родитель a9937472c5
Коммит 9bed554614
8 изменённых файлов: 220 добавлений и 5 удалений

Просмотреть файл

@ -2464,7 +2464,10 @@ class nsContextMenu {
"browser.translations.select.enable"
);
const translatableText = this.selectedText.trim();
// Selected text takes precedence over link text.
const translatableText = this.isTextSelected
? this.selectedText.trim()
: this.linkTextStr.trim();
translateSelectionItem.hidden =
// Only show the item if the feature is enabled.
@ -2491,7 +2494,9 @@ class nsContextMenu {
});
document.l10n.setAttributes(
translateSelectionItem,
"main-context-menu-translate-selection-to-language",
this.isTextSelected
? "main-context-menu-translate-selection-to-language"
: "main-context-menu-translate-link-text-to-language",
{ language: dn.of(topPreferredLanguage) }
);
return;
@ -2503,7 +2508,9 @@ class nsContextMenu {
document.l10n.setAttributes(
translateSelectionItem,
"main-context-menu-translate-selection"
this.isTextSelected
? "main-context-menu-translate-selection"
: "main-context-menu-translate-link-text"
);
}

Просмотреть файл

@ -79,6 +79,8 @@ skip-if = ["os == 'linux' && !debug"] # Bug 1863227
["browser_translations_select_context_menu_feature_disabled.js"]
["browser_translations_select_context_menu_with_hyperlink.js"]
["browser_translations_select_context_menu_with_no_text_selected.js"]
["browser_translations_select_context_menu_with_text_selected.js"]

Просмотреть файл

@ -79,3 +79,36 @@ add_task(
await cleanup();
}
);
/**
* This test checks the availability of the translate-selection menu item in the context menu,
* ensuring it is not visible when the "browser.translations.select.enable" preference is set to false
* and the context menu is invoked on a hyperlink. This would result in the menu item being available
* if the pref were set to true.
*/
add_task(
async function test_translate_selection_menuitem_is_unavailable_with_feature_disabled_and_clicking_a_hyperlink() {
const { cleanup, runInPage } = await loadTestPage({
page: SPANISH_PAGE_URL,
languagePairs: LANGUAGE_PAIRS,
prefs: [["browser.translations.select.enable", false]],
});
await assertTranslationsButton(
{ button: true, circleArrows: false, locale: false, icon: true },
"The button is available."
);
await assertContextMenuTranslateSelectionItem(
runInPage,
{
selectSpanishParagraph: false,
openAtSpanishHyperlink: true,
expectMenuItemVisible: false,
},
"The translate-selection context menu item should be unavailable when the feature is disabled."
);
await cleanup();
}
);

Просмотреть файл

@ -0,0 +1,109 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* This test case verifies the functionality of the translate-selection context menu item
* when a hyperlink is right-clicked. The menu item should offer to translate the link text
* to a target language when the detected language of the link text does not match the preferred
* language.
*/
add_task(
async function test_translate_selection_menuitem_translate_link_text_to_target_language() {
const { cleanup, runInPage } = await loadTestPage({
page: SPANISH_PAGE_URL,
languagePairs: LANGUAGE_PAIRS,
prefs: [["browser.translations.select.enable", true]],
});
await assertTranslationsButton(
{ button: true, circleArrows: false, locale: false, icon: true },
"The button is available."
);
await assertContextMenuTranslateSelectionItem(
runInPage,
{
selectSpanishParagraph: false,
openAtSpanishHyperlink: true,
expectMenuItemVisible: true,
expectedTargetLanguage: "en",
},
"The translate-selection context menu item should be localized to translate the link text" +
"to the target language."
);
await cleanup();
}
);
/**
* This test case verifies the functionality of the translate-selection context menu item
* when a hyperlink is right-clicked, and the link text is in the top preferred language.
* The menu item should offer to translate the link text without specifying a target language,
* since it is already in the preferred language for the user.
*/
add_task(
async function test_translate_selection_menuitem_translate_link_text_in_preferred_language() {
const { cleanup, runInPage } = await loadTestPage({
page: SPANISH_PAGE_URL,
languagePairs: LANGUAGE_PAIRS,
prefs: [["browser.translations.select.enable", true]],
});
await assertTranslationsButton(
{ button: true, circleArrows: false, locale: false, icon: true },
"The button is available."
);
await assertContextMenuTranslateSelectionItem(
runInPage,
{
selectSpanishParagraph: false,
openAtEnglishHyperlink: true,
expectMenuItemVisible: true,
expectedTargetLanguage: null,
},
"The translate-selection context menu item should be localized to translate the link text" +
"without a target language."
);
await cleanup();
}
);
/**
* This test case ensures that the translate-selection context menu item functions correctly
* when text is actively selected but the context menu is invoked on an unselected hyperlink.
* The selected text content should take precedence over the link text, and the menu item should
* be localized to translate the selected text to the target language, rather than the hyperlink text.
*/
add_task(
async function test_translate_selection_menuitem_selected_text_takes_precedence_over_link_text() {
const { cleanup, runInPage } = await loadTestPage({
page: SPANISH_PAGE_URL,
languagePairs: LANGUAGE_PAIRS,
prefs: [["browser.translations.select.enable", true]],
});
await assertTranslationsButton(
{ button: true, circleArrows: false, locale: false, icon: true },
"The button is available."
);
await assertContextMenuTranslateSelectionItem(
runInPage,
{
selectSpanishParagraph: true,
openAtEnglishHyperlink: true,
expectMenuItemVisible: true,
expectedTargetLanguage: "en",
},
"The translate-selection context menu item should be localized to translate the selection" +
"even though the hyperlink is the element on which the context menu was invoked."
);
await cleanup();
}
);

Просмотреть файл

@ -1046,6 +1046,10 @@ function assertIsVisible(expected, { element, id }) {
* @param {boolean} options.openAtFirstParagraph - Opens the context menu at the first paragraph in the test page.
* @param {boolean} options.openAtSpanishParagraph - Opens the context menu at the Spanish paragraph in the test page.
* This is only available in SPANISH_TEST_PAGE.
* @param {boolean} options.openAtEnglishHyperlink - Opens the context menu at the English hyperlink in the test page.
* This is only available in SPANISH_TEST_PAGE.
* @param {boolean} options.openAtSpanishHyperlink - Opens the context menu at the Spanish hyperlink in the test page.
* This is only available in SPANISH_TEST_PAGE.
* @throws Throws an error if no valid option was provided for opening the menu.
*/
async function openContextMenu(
@ -1055,6 +1059,8 @@ async function openContextMenu(
selectSpanishParagraph,
openAtFirstParagraph,
openAtSpanishParagraph,
openAtEnglishHyperlink,
openAtSpanishHyperlink,
}
) {
logAction();
@ -1093,6 +1099,24 @@ async function openContextMenu(
return;
}
if (openAtEnglishHyperlink === true) {
await runInPage(async TranslationsTest => {
const { getEnglishHyperlink } = TranslationsTest.getSelectors();
const hyperlink = getEnglishHyperlink();
await TranslationsTest.rightClickContentElement(hyperlink);
});
return;
}
if (openAtSpanishHyperlink === true) {
await runInPage(async TranslationsTest => {
const { getSpanishHyperlink } = TranslationsTest.getSelectors();
const hyperlink = getSpanishHyperlink();
await TranslationsTest.rightClickContentElement(hyperlink);
});
return;
}
throw new Error(
"openContextMenu() was not provided a declaration for which element to open the menu at."
);
@ -1112,6 +1136,10 @@ async function openContextMenu(
* @param {boolean} options.openAtFirstParagraph - Opens the context menu at the first paragraph in the test page.
* @param {boolean} options.openAtSpanishParagraph - Opens the context menu at the Spanish paragraph in the test page.
* This is only available in SPANISH_TEST_PAGE.
* @param {boolean} options.openAtEnglishHyperlink - Opens the context menu at the English hyperlink in the test page.
* This is only available in SPANISH_TEST_PAGE.
* @param {boolean} options.openAtSpanishHyperlink - Opens the context menu at the Spanish hyperlink in the test page.
* This is only available in SPANISH_TEST_PAGE.
* @param {string} [message] - A message to log to info.
* @throws Throws an error if the properties of the translate-selection item do not match the expected options.
*/
@ -1124,6 +1152,8 @@ async function assertContextMenuTranslateSelectionItem(
expectedTargetLanguage,
openAtFirstParagraph,
openAtSpanishParagraph,
openAtEnglishHyperlink,
openAtSpanishHyperlink,
},
message
) {
@ -1141,6 +1171,8 @@ async function assertContextMenuTranslateSelectionItem(
selectSpanishParagraph,
openAtFirstParagraph,
openAtSpanishParagraph,
openAtEnglishHyperlink,
openAtSpanishHyperlink,
});
const menuItem = maybeGetById(
@ -1156,7 +1188,9 @@ async function assertContextMenuTranslateSelectionItem(
if (expectedTargetLanguage) {
// Target language expected, check for the data-l10n-id with a `{$language}` argument.
const expectedL10nId =
"main-context-menu-translate-selection-to-language";
selectFirstParagraph === true || selectSpanishParagraph === true
? "main-context-menu-translate-selection-to-language"
: "main-context-menu-translate-link-text-to-language";
await waitForCondition(
() => menuItem.getAttribute("data-l10n-id") === expectedL10nId,
`Waiting for translate-selection context menu item to localize with target language ${expectedTargetLanguage}`
@ -1176,7 +1210,10 @@ async function assertContextMenuTranslateSelectionItem(
);
} else {
// No target language expected, check for the data-l10n-id that has no `{$language}` argument.
const expectedL10nId = "main-context-menu-translate-selection";
const expectedL10nId =
selectFirstParagraph === true || selectSpanishParagraph === true
? "main-context-menu-translate-selection"
: "main-context-menu-translate-link-text";
await waitForCondition(
() => menuItem.getAttribute("data-l10n-id") === expectedL10nId,
"Waiting for translate-selection context menu item to localize without target language."

Просмотреть файл

@ -15,3 +15,16 @@ main-context-menu-translate-selection =
# $language (string) - The localized display name of the target language
main-context-menu-translate-selection-to-language =
.label = Translate Selection to { $language }
# Text displayed in the right-click context menu for translating
# the text of a hyperlink to a yet-to-be-determined language.
main-context-menu-translate-link-text =
.label = Translate Link Text…
# Text displayed in the right-click context menu for translating
# the text of a hyperlink to a target language.
#
# Variables:
# $language (string) - The localized display name of the target language
main-context-menu-translate-link-text-to-language =
.label = Translate Link Text to { $language }

Просмотреть файл

@ -47,6 +47,12 @@ export function getSelectors() {
getSpanishParagraph() {
return content.document.getElementById("spanish-paragraph");
},
getSpanishHyperlink() {
return content.document.getElementById("spanish-hyperlink");
},
getEnglishHyperlink() {
return content.document.getElementById("english-hyperlink");
},
};
}

Просмотреть файл

@ -32,5 +32,13 @@
<p>Levantóse en esto un poco de viento y las grandes aspas comenzaron a moverse, lo cual visto por don Quijote, dijo:</p>
<p>— Pues, aunque mováis más brazos que los del gigante Briareo, me lo habéis de pagar.</p>
</div>
<div>
<header lang="en">The following is a link to another test page in Spanish.</header>
<p><a id="spanish-hyperlink" href="https://example.org/browser/translations-tester-es.html">Otra pagina en español.</a></p>
</div>
<div>
<header lang="en">The following is a link to another test page in English.</header>
<p lang="en"><a id="english-hyperlink" href="https://example.org/browser/translations-tester-en.html">Another page in English.</a></p>
</div>
</body>
</html>