diff --git a/css/activities.css b/css/activities.css index 1c09e1fec1..de0521c577 100644 --- a/css/activities.css +++ b/css/activities.css @@ -51,21 +51,21 @@ } #search[type="text"] { - width: 400px; + width: 86.5px; box-sizing: border-box; position: absolute; background-color: white; background-repeat: no-repeat; - padding: 4.5px 10px 4.5px 20px; + padding: 9.2px 1.3px 8.8px 0.7px; -webkit-transition: width 0.4s ease-in-out; transition: width 0.4s ease-in-out; - font-size: 24px; + font-size: 16px; color: black; max-width: 100%; } #search:focus { - border: 2px solid #87cefa; + border: 0px solid #87cefa; } #search.open { diff --git a/index.html b/index.html index aea8f6d80a..43b29fbac1 100644 --- a/index.html +++ b/index.html @@ -933,7 +933,7 @@ name="search" id="search" class="ui-autocomplete" - placeholder="Search for Blocks" + placeholder="Search" tabindex="-1" /> diff --git a/js/activity.js b/js/activity.js index 37ca13d0f3..909d081563 100644 --- a/js/activity.js +++ b/js/activity.js @@ -319,6 +319,7 @@ class Activity { console.error(e); } + /** * Initialises major variables and renders default stack. * Sets up the initial state and dependencies of the activity. @@ -393,12 +394,12 @@ class Activity { this.searchWidget = docById("search"); this.searchWidget.style.visibility = "hidden"; - this.searchWidget.placeholder = _("Search for blocks"); + this.searchWidget.placeholder = _("Search"); this.helpfulSearchWidget = document.createElement("input"); this.helpfulSearchWidget.setAttribute("id", "helpfulSearch"); this.helpfulSearchWidget.style.visibility = "hidden"; - this.helpfulSearchWidget.placeholder = _("Search for blocks"); + this.helpfulSearchWidget.placeholder = _("Search"); this.helpfulSearchWidget.classList.add("ui-autocomplete"); this.progressBar = docById("myProgress"); this.progressBar.style.visibility = "hidden"; @@ -2400,7 +2401,10 @@ class Activity { this.showSearchWidget = () => { // Bring widget to top. this.searchWidget.style.zIndex = 1001; - this.searchWidget.style.border = "2px solid blue"; + this.searchWidget.style.borderBottom = "1px solid #0cafff"; + this.searchWidget.style.borderTop = "0px"; + this.searchWidget.style.borderRight = "0px"; + this.searchWidget.style.borderLeft = "0px"; if (this.helpfulSearchDiv) { this._hideHelpfulSearchWidget(); } @@ -2415,9 +2419,9 @@ class Activity { this.searchWidget.value = null; this.searchWidget.style.visibility = "visible"; this.searchWidget.style.left = - this.palettes.getSearchPos()[0] * this.turtleBlocksScale * 1.5 + "px"; + this.palettes.getSearchPos()[0] * this.turtleBlocksScale * 1.428571 + "px"; this.searchWidget.style.top = - this.palettes.getSearchPos()[1] * this.turtleBlocksScale * 0.95 + "px"; + this.palettes.getSearchPos()[1] * this.turtleBlocksScale * 0.9774193548 + "px"; this.searchBlockPosition = [100, 100]; this.prepSearchWidget(); @@ -2443,6 +2447,18 @@ class Activity { }; document.addEventListener("mousedown", closeListener); + + // Add hover behavior for the search widget + this.searchWidget.addEventListener("mouseover", () => { + this.searchWidget.style.backgroundColor = "#ddd"; // Change color on hover + + }); + + this.searchWidget.addEventListener("mouseout", () => { + this.searchWidget.style.backgroundColor = "white"; // Revert color when not hovered + + }); + // Give the browser time to update before selecting // focus. setTimeout(() => { diff --git a/js/utils/utils.js b/js/utils/utils.js index 0c11303ccc..6367b1d885 100644 --- a/js/utils/utils.js +++ b/js/utils/utils.js @@ -58,7 +58,8 @@ const changeImage = (imgElement, from, to) => { }; /** - * A simple localization function for translating strings. + * Enhanced _() method to handle case variations for translations + * and preserve the case of the input text. * @function * @param {string} text - The input text to be translated. * @returns {string} The translated text. @@ -69,47 +70,73 @@ function _(text) { return ""; } - let replaced = text; - const replace = [ - ",", - "(", - ")", - "?", - "¿", - "<", - ">", - ".", - "\n", - '"', - ":", - "%s", - "%d", - "/", - "'", - ";", - "×", - "!", - "¡" - ]; - for (let p = 0; p < replace.length; p++) { - replaced = replaced.replace(replace[p], ""); - } - - replaced = replaced.replace(/ /g, "-"); - - if (localStorage.kanaPreference === "kana") { - const lang = document.webL10n.getLanguage(); - if (lang === "ja") { - replaced = "kana-" + replaced; + try { + let replaced = text; + // Replace certain characters from the input text + const replace = [ + ",", + "(", + ")", + "?", + "¿", + "<", + ">", + ".", + "\n", + '"', + ":", + "%s", + "%d", + "/", + "'", + ";", + "×", + "!", + "¡" + ]; + for (let p = 0; p < replace.length; p++) { + replaced = replaced.replace(replace[p], ""); } - } - try { - let translation = document.webL10n.get(replaced); - if (translation === "") { - translation = text; + replaced = replaced.replace(/ /g, "-"); + + if (localStorage.kanaPreference === "kana") { + const lang = document.webL10n.getLanguage(); + if (lang === "ja") { + replaced = "kana-" + replaced; + } + } + // first, we actually tried to find out if there was an existing translation with SAME case + let translated = document.webL10n.get(text); + + // If no translation is found, try the lowercase translation + if (!translated || translated === text) { + translated = document.webL10n.get(text.toLowerCase()); } - return translation; + + //if still no translation is found, try the initial caps translation too + if (!translated || translated === text) { + const initialCaps = text.charAt(0).toUpperCase() + text.slice(1).toLowerCase(); + translated = document.webL10n.get(initialCaps); + } + + //function returns the ORIGINAL case without any translation if no translation exists + translated = translated || text; + + // this if ensures Correct LETTER CASING, for example, "Search" -> "Buscar" and "SEARCH" -> "BUSCAR" and "search" -> "buscar" + if (text === text.toUpperCase()) { + //if the input is all uppercase, then we will return the translation in uppercase + return translated.toUpperCase(); + } else if (text === text.toLowerCase()) { + //if the input is all lowercase,then return the translation in lowercase + return translated.toLowerCase(); + } else if (text.charAt(0).toUpperCase() + text.slice(1).toLowerCase() === text) { + //if the input is in title case, then return the translation in title case + return translated.charAt(0).toUpperCase() + translated.slice(1).toLowerCase(); + } + + // return the translation as is if any of the case does not match + return translated; } catch (e) { // console.debug("i18n error: " + text); return text; @@ -130,7 +157,7 @@ let format = (str, data) => { if (x === undefined) { // eslint-disable-next-line no-console console.debug("Undefined value in template string", str, name, x, v); - } + } x = x[v]; });