8000 feat: Make translation system key based and add annotation type to gutter icon aria labels by akoreman · Pull Request #5524 · ajaxorg/ace · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat: Make translation system key based and add annotation type to gutter icon aria labels #5524

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Apr 3, 2024
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ lib/ace/mode/xml/*
lib/ace/mode/xquery/*
lib/ace/mode/xquery.js
lib/ace/mode/yaml/*
src/lib/default_english_messages.js
**/test/asyncjs/*
**/es5-shim.js
**/vim*.js
Expand Down
22 changes: 14 additions & 8 deletions Makefile.dryice.js
Original file line number Diff line number Diff line change
Expand Up @@ -654,28 +654,34 @@ function extractCss(callback) {
}

function extractNls() {
var allMessages = {};
var defaultData = require(__dirname + "/src/lib/default_english_messages").defaultEnglishMessages;

searchFiles(__dirname + "/src", function(path) {
if (/_test/.test(path)) return;
var text = fs.readFileSync(path, "utf8");
var matches = text.match(/nls\s*\(\s*("([^"\\]|\\.)+"|'([^'\\]|\\.)+')/g);
var matches = text.match(/nls\s*\(\s*("([^"\\]|\\.)+"|'([^'\\]|\\.)+'),\s*("([^"\\]|\\.)+"|'([^'\\]|\\.)+')/g);
matches && matches.forEach(function(m) {
var eng = m.replace(/^nls\s*\(\s*["']|["']$/g, "");
allMessages[eng] = "";
var match = m.match(/("([^"\\]|\\.)+"|'([^'\\]|\\.)+)/g);
var key = match[0].replace(/["']|["']$/g, "");
var defaultString = match[1].replace(/["']|["']$/g, "");

// If the key not yet in the default file, add it:
if (defaultData[key] !== undefined) return;
defaultData[key] = defaultString;
});
});
fs.writeFileSync(__dirname + "/src/lib/default_english_messages.js", "var defaultEnglishMessages = " + JSON.stringify(defaultData, null, 4) + "\n\nexports.defaultEnglishMessages = defaultEnglishMessages;", "utf8");

fs.readdirSync(__dirname + "/translations").forEach(function(x) {
if (!/\.json$/.test(x)) return;
var path = __dirname + "/translations/" + x;
var existingStr = fs.readFileSync(path, "utf8");
var existing = JSON.parse(existingStr);

var newData = {$id: existing.$id};
for (var i in allMessages) {
newData[i] = existing[i] || "";
for (var i in defaultData) {
existing[i] = existing[i] || "";
}
fs.writeFileSync(path, JSON.stringify(newData, null, 4), "utf8");
fs.writeFileSync(path, JSON.stringify(existing, null, 4), "utf8");
console.log("Saved " + x);
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ class Autocomplete {
}

static get completionsForLoading() { return [{
caption: config.nls("Loading..."),
caption: config.nls("autocomplete.loading", "Loading..."),
value: ""
}];
}
Expand Down
6 changes: 3 additions & 3 deletions src/autocomplete/popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ class AcePopup {

// Set aria attributes for the popup
popup.renderer.$textLayer.element.setAttribute("role", popupAriaRole);
popup.renderer.$textLayer.element.setAttribute("aria-roledescription", nls("Autocomplete suggestions"));
popup.renderer.$textLayer.element.setAttribute("aria-label", nls("Autocomplete suggestions"));
popup.renderer.$textLayer.element.setAttribute("aria-roledescription", nls("autocomplete.popup.aria-roledescription", "Autocomplete suggestions"));
popup.renderer.$textLayer.element.setAttribute("aria-label", nls("autocomplete.popup.aria-label", "Autocomplete suggestions"));
popup.renderer.textarea.setAttribute("aria-hidden", "true");

popup.setOption("displayIndentGuides", false);
Expand Down Expand Up @@ -152,7 +152,7 @@ class AcePopup {
t.element.setAttribute("aria-activedescendant", ariaId);
el.setAttribute("aria-activedescendant", ariaId);
selected.setAttribute("role", optionAriaRole);
selected.setAttribute("aria-roledescription", nls("item"));
selected.setAttribute("aria-roledescription", nls("autocomplete.popup.item.aria-roledescription", "item"));
selected.setAttribute("aria-label", popup.getData(row).caption || popup.getData(row).value);
selected.setAttribute("aria-setsize", popup.data.length);
selected.setAttribute("aria-posinset", row + 1);
Expand Down
15 changes: 9 additions & 6 deletions src/config_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,16 @@ module.exports = {
"test: nls": function() {
var nls = config.nls;
config.setMessages({
foo: "hello world of $1"
foo: "hello world of $1",
test_key: "hello world for test key"
});
assert.equal(nls("bar $1"), "bar $1");
assert.equal(nls("bar"), "bar");
assert.equal(nls("foo"), "hello world of $1");
assert.equal(nls("foo", {1: "goo"}), "hello world of goo");
assert.equal(nls("$0B is $1$$", [0.11, 22]), "0.11B is 22$");
assert.equal(nls("untranslated_key","bar $1"), "bar $1");
assert.equal(nls("untranslated_key", "bar"), "bar");
assert.equal(nls("untranslated_key_but_translated_default_string", "foo"), "hello world of $1");
assert.equal(nls("untranslated_key_but_translated_default_string", "foo", {1: "goo"}), "hello world of goo");
assert.equal(nls("untranslated_key", "$0B is $1$$", [0.11, 22]), "0.11B is 22$");
assert.equal(nls("untranslated_key_but_translated_default_string", "foo", {1: "goo"}), "hello world of goo");
assert.equal(nls("test_key", "this text should not appear"), "hello world for test key");
},
"test: define options" : function() {
var o = {};
Expand Down
8 changes: 4 additions & 4 deletions src/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -2944,10 +2944,10 @@ config.defineOptions(Editor.prototype, "editor", {
this.textInput.setNumberOfExtraLines(useragent.isWin ? 3 : 0);
this.renderer.scroller.setAttribute("tabindex", 0);
this.renderer.scroller.setAttribute("role", "group");
this.renderer.scroller.setAttribute("aria-roledescription", nls("editor"));
this.renderer.scroller.setAttribute("aria-roledescription", nls("editor.scroller.aria-roledescription", "editor"));
this.renderer.scroller.classList.add(this.renderer.keyboardFocusClassName);
this.renderer.scroller.setAttribute("aria-label",
nls("Editor content, press Enter to start editing, press Escape to exit")
nls("editor.scroller.aria-label", "Editor content, press Enter to start editing, press Escape to exit")
);

this.renderer.scroller.addEventListener("keyup", focusOnEnterKeyup.bind(this));
Expand All @@ -2956,9 +2956,9 @@ config.defineOptions(Editor.prototype, "editor", {
this.renderer.$gutter.setAttribute("tabindex", 0);
this.renderer.$gutter.setAttribute("aria-hidden", false);
this.renderer.$gutter.setAttribute("role", "group");
this.renderer.$gutter.setAttribute("aria-roledescription", nls("editor"));
this.renderer.$gutter.setAttribute("aria-roledescription", nls("editor.gutter.aria-roledescription", "editor"));
this.renderer.$gutter.setAttribute("aria-label",
nls("Editor gutter, press Enter to interact with controls using arrow keys, press Escape to exit")
nls("editor.gutter.aria-label", "Editor gutter, press Enter to interact with controls using arrow keys, press Escape to exit")
);
this.renderer.$gutter.classList.add(this.renderer.keyboardFocusClassName);

Expand Down
2 changes: 1 addition & 1 deletion src/ext/error_marker.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ exports.showErrorMarker = function(editor, dir) {
return;
} else {
gutterAnno = {
text: [nls("Looks good!")],
text: [nls("error-marker.good-state", "Looks good!")],
className: "ace_ok"
};
}
Expand Down
6 changes: 3 additions & 3 deletions src/ext/prompt.js
Original file line number Diff line number Diff line change
Expand Up @@ -441,13 +441,13 @@ prompt.commands = function(editor, callback) {
otherCommands = getFilteredCompletions(otherCommands, prefix);

if (recentlyUsedCommands.length && otherCommands.length) {
recentlyUsedCommands[0].message = nls("Recently used");
otherCommands[0].message = nls("Other commands");
recentlyUsedCommands[0].message = nls("prompt.recently-used", "Recently used");
otherCommands[0].message = nls("prompt.other-commands", "Other commands");
}

var completions = recentlyUsedCommands.concat(otherCommands);
return completions.length > 0 ? completions : [{
value: nls("No matching commands"),
value: nls("prompt.no-matching-commands", "No matching commands"),
error: 1
}];
}
Expand Down
22 changes: 11 additions & 11 deletions src/ext/searchbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,24 @@ class SearchBox {
dom.buildDom(["div", {class:"ace_search right"},
["span", {action: "hide", class: "ace_searchbtn_close"}],
["div", {class: "ace_search_form"},
["input", {class: "ace_search_field", placeholder: nls("Search for"), spellcheck: "false"}],
["input", {class: "ace_search_field", placeholder: nls("search-box.find.placeholder", "Search for"), spellcheck: "false"}],
["span", {action: "findPrev", class: "ace_searchbtn prev"}, "\u200b"],
["span", {action: "findNext", class: "ace_searchbtn next"}, "\u200b"],
["span", {action: "findAll", class: "ace_searchbtn", title: "Alt-Enter"}, nls("All")]
["span", {action: "findAll", class: "ace_searchbtn", title: "Alt-Enter"}, nls("search-box.find-all.text", "All")]
],
["div", {class: "ace_replace_form"},
["input", {class: "ace_search_field", placeholder: nls("Replace with"), spellcheck: "false"}],
["span", {action: "replaceAndFindNext", class: "ace_searchbtn"}, nls("Replace")],
["span", {action: "replaceAll", class: "ace_searchbtn"}, nls("All")]
["input", {class: "ace_search_field", placeholder: nls("search-box.replace.placeholder", "Replace with"), spellcheck: "false"}],
["span", {action: "replaceAndFindNext", class: "ace_searchbtn"}, nls("search-box.replace-next.text", "Replace")],
["span", {action: "replaceAll", class: "ace_searchbtn"}, nls("search-box.replace-all.text", "All")]
],
["div", {class: "ace_search_options"},
["span", {action: "toggleReplace", class: "ace_button", title: nls("Toggle Replace mode"),
["span", {action: "toggleReplace", class: "ace_button", title: nls("search-box.toggle-replace.title", "Toggle Replace mode"),
style: "float:left;margin-top:-2px;padding:0 5px;"}, "+"],
["span", {class: "ace_search_counter"}],
["span", {action: "toggleRegexpMode", class: "ace_button", title: nls("RegExp Search")}, ".*"],
["span", {action: "toggleCaseSensitive", class: "ace_button", title: nls("CaseSensitive Search")}, "Aa"],
["span", {action: "toggleWholeWords", class: "ace_button", title: nls("Whole Word Search")}, "\\b"],
["span", {action: "searchInSelection", class: "ace_button", title: nls("Search In Selection")}, "S"]
["span", {action: "toggleRegexpMode", class: "ace_button", title: nls("search-box.toggle-regexp.title", "RegExp Search")}, ".*"],
["span", {action: "toggleCaseSensitive", class: "ace_button", title: nls("search-box.toggle-case.title", "CaseSensitive Search")}, "Aa"],
["span", {action: "toggleWholeWords", class: "ace_button", title: nls("search-box.toggle-whole-word.title", "Whole Word Search")}, "\\b"],
["span", {action: "searchInSelection", class: "ace_button", title: nls("search-box.toggle-in-selection.title", "Search In Selection")}, "S"]
]
], div);
/**@type {any}*/
Expand Down Expand Up @@ -234,7 +234,7 @@ class SearchBox {
}
}
}
this.searchCounter.textContent = nls("$0 of $1", [before , (all > MAX_COUNT ? MAX_COUNT + "+" : all)]);
this.searchCounter.textContent = nls("search-box.search-counter", "$0 of $1", [before , (all > MAX_COUNT ? MAX_COUNT + "+" : all)]);
}
findNext() {
this.find(true, false);
Expand Down
4 changes: 2 additions & 2 deletions src/keyboard/textinput.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,10 @@ TextInput= function(parentNode, host) {
text.setAttribute("role", options.role);
}
if (options.setLabel) {
text.setAttribute("aria-roledescription", nls("editor"));
text.setAttribute("aria-roledescription", nls("text-input.aria-roledescription", "editor"));
if(host.session) {
var row = host.session.selection.cursor.row;
text.setAttribute("aria-label", nls("Cursor at row $0", [row + 1]));
text.setAttribute("aria-label", nls("text-input.aria-label", "Cursor at row $0", [row + 1]));
}
}
};
Expand Down
38 changes: 31 additions & 7 deletions src/layer/gutter.js
Original file line number Diff line number Diff line change
Expand Up @@ -409,21 +409,21 @@ class Gutter{

// getFoldWidgetRange is optional to be implemented by fold modes, if not available we fall-back.
if (foldRange)
foldWidget.setAttribute("aria-label", nls("Toggle code folding, rows $0 through $1", [foldRange.start.row + 1, foldRange.end.row + 1]));
foldWidget.setAttribute("aria-label", nls("gutter.code-folding.range.aria-label", "Toggle code folding, rows $0 through $1", [foldRange.start.row + 1, foldRange.end.row + 1]));
else {
if (fold)
foldWidget.setAttribute("aria-label", nls("Toggle code folding, rows $0 through $1", [fold.start.row + 1, fold.end.row + 1]));
foldWidget.setAttribute("aria-label", nls("gutter.code-folding.closed.aria-label", "Toggle code folding, rows $0 through $1", [fold.start.row + 1, fold.end.row + 1]));
else
foldWidget.setAttribute("aria-label", nls("Toggle code folding, row $0", [row + 1]));
foldWidget.setAttribute("aria-label", nls("gutter.code-folding.open.aria-label", "Toggle code folding, row $0", [row + 1]));
}

if (isClosedFold) {
foldWidget.setAttribute("aria-expanded", "false");
foldWidget.setAttribute("title", nls("Unfold code"));
foldWidget.setAttribute("title", nls("gutter.code-folding.closed.title", "Unfold code"));
}
else {
foldWidget.setAttribute("aria-expanded", "true");
foldWidget.setAttribute("title", nls("Fold code"));
foldWidget.setAttribute("title", nls("gutter.code-folding.open.title", "Fold code"));
}
} else {
if (foldWidget) {
Expand All @@ -442,7 +442,17 @@ class Gutter{
dom.setStyle(annotationIconNode.style, "height", lineHeight);
dom.setStyle(annotationNode.style, "display", "block");
dom.setStyle(annotationNode.style, "height", lineHeight);
annotationNode.setAttribute("aria-label", nls("Read annotations row $0", [rowText]));
var ariaLabel;
switch(foldAnnotationClass) {
case " ace_error_fold":
ariaLabel = nls("gutter.annotation.aria-label.error", "Read annotations row $0", [rowText]);
break;

case " ace_warning_fold":
ariaLabel = nls("gutter.annotation.aria-label.warning", "Read annotations row $0", [rowText]);
break;
}
annotationNode.setAttribute("aria-label", ariaLabel);
annotationNode.setAttribute("tabindex", "-1");
annotationNode.setAttribute("role", "button");
}
Expand All @@ -458,7 +468,21 @@ class Gutter{
dom.setStyle(annotationIconNode.style, "height", lineHeight);
dom.setStyle(annotationNode.style, "display", "block");
dom.setStyle(annotationNode.style, "height", lineHeight);
annotationNode.setAttribute("aria-label", nls("Read annotations row $0", [rowText]));
var ariaLabel;
switch(this.$annotations[row].className) {
case " ace_error":
ariaLabel = nls("gutter.annotation.aria-label.error", "Read annotations row $0", [rowText]);
break;

case " ace_warning":
ariaLabel = nls("gutter.annotation.aria-label.warning", "Read annotations row $0", [rowText]);
break;

case " ace_info":
ariaLabel = nls("gutter.annotation.aria-label.info", "Read annotations row $0", [rowText]);
break;
}
annotationNode.setAttribute("aria-label", ariaLabel);
annotationNode.setAttribute("tabindex", "-1");
annotationNode.setAttribute("role", "button");
}
Expand Down
2 changes: 1 addition & 1 deletion src/layer/text.js
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ class Text {
var span = this.dom.createElement("span");
if (token.type == "fold"){
span.style.width = (token.value.length * this.config.characterWidth) + "px";
span.setAttribute("title", nls("Unfold code"));
span.setAttribute("title", nls("inline-fold.closed.title", "Unfold code"));
}

span.className = classes;
Expand Down
23 changes: 15 additions & 8 deletions src/lib/app_config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
var oop = require("./oop");
var EventEmitter = require("./event_emitter").EventEmitter;
const reportError = require("./report_error").reportError;
const defaultEnglishMessages = require("./default_english_messages").defaultEnglishMessages;

var optionsProvider = {
setOptions: function(optList) {
Expand Down Expand Up @@ -61,8 +62,9 @@ var messages;

class AppConfig {
constructor() {
this.$defaultOptions = {};
}
this.$defaultOptions = {};
messages = defaultEnglishMessages;
}

/**
* @param {Object} obj
Expand Down Expand Up @@ -142,14 +144,19 @@ class AppConfig {
}

/**
* @param {string} string
* @param {string} key
* @param {string} defaultString
* @param {{ [x: string]: any; }} [params]
*/
nls(string, params) {
if (messages && !messages[string]) {
warn("No message found for '" + string + "' in the provided messages, falling back to default English message.");
}
var translated = messages && messages[string] || string;
nls(key, defaultString, params) {
if (!messages[key]) {
warn("No message found for the key '" + key + "' in the provided messages, trying to find a translation for the default string '" + defaultString + "'.");
if (!messages[defaultString]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we keeping this default string logic for backwards compatibility reasons?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I kept this so that Ace users who currently have translations set-up don't get those broken by this change (well that's the goal at least 😄)

warn("No message found for the default string '" + defaultString + "' in the provided messages. Falling back to the default English message.");
}
}

var translated = messages[key] || messages[defaultString] || defaultString;
if (params) {
translated = translated.replace(/\$(\$|[\d]+)/g, function(_, name) {
if (name == "$") return "$";
Expand Down
Loading
0