Skip to content

Commit

Permalink
Move strings into locales.
Browse files Browse the repository at this point in the history
Use a pattern like gettext() where the original string stays in the source, so the source is still readable.
This means a lot of copy/paste into _locales/en/messages.json.

Include a few strings in German, because I can speak it _just_ enough to test in German.  Just to be sure it's working.

Fixes #2527
  • Loading branch information
arantius committed Jan 26, 2018
1 parent 4ca4055 commit 9ce5dab
Show file tree
Hide file tree
Showing 18 changed files with 107 additions and 52 deletions.
2 changes: 1 addition & 1 deletion Makefile
@@ -1,4 +1,4 @@
.PHONY: test testonce coverage xpi
.PHONY: test testwatch coverage xpi

test:
@npm run test
Expand Down
6 changes: 6 additions & 0 deletions _locales/de/messages.json
@@ -0,0 +1,6 @@
{
"Disabled": { "message": "Deaktiviert" },
"Enabled": { "message": "Activiert" },
"Greasemonkey is active": { "message": "Greasemonkey ist aktiv" },
"Greasemonkey is disabled": { "message": "Greasemonkey ist behindert" }
}
35 changes: 35 additions & 0 deletions _locales/en/messages.json
@@ -0,0 +1,35 @@
{
"$1 - Greasemonkey User Script Editor": { "message": "$1 - Greasemonkey User Script Editor" },
"$1 - Greasemonkey User Script": { "message": "$1 - Greasemonkey User Script" },
"$1 does not @grant method $2": { "message": "$1 does not @grant method $2" },
"Cancel": { "message": "Cancel" },
"Could not execute user script: $1\n$2": { "message": "Could not execute user script: $1\n$2" },
"Disabled": { "message": "Disabled" },
"Does not run on:": { "message": "Does not run on:" },
"Download and install successful!": { "message": "Download and install successful!" },
"Duplicate resource name: $1": { "message": "Duplicate resource name: $1" },
"Edit": { "message": "Edit" },
"Enabled": { "message": "Enabled" },
"GM.notification: \"text\" must be a string": { "message": "GM.notification: \"text\" must be a string" },
"GM.openInTab: Could not understand the URL: $1": { "message": "GM.openInTab: Could not understand the URL: $1" },
"GM.xmlHttpRequest: Could not understand the URL: $1\n$2": { "message": "GM.xmlHttpRequest: Could not understand the URL: $1\n$2" },
"GM.xmlHttpRequest: Passed URL has bad protocol: $1": { "message": "GM.xmlHttpRequest: Passed URL has bad protocol: $1" },
"GM.xmlHttpRequest: Received no URL.": { "message": "GM.xmlHttpRequest: Received no URL." },
"GM.xmlHttpRequest: Received no details.": { "message": "GM.xmlHttpRequest: Received no details." },
"Greasemonkey Wiki": { "message": "Greasemonkey Wiki" },
"Greasemonkey home page": { "message": "Greasemonkey home page" },
"Greasemonkey is active": { "message": "Greasemonkey is active" },
"Greasemonkey is disabled": { "message": "Greasemonkey is disabled" },
"Ignoring @match pattern $1 because:\n$2": { "message": "Ignoring @match pattern $1 because:\n$2" },
"Install": { "message": "Install" },
"Malicious user scripts can violate your privacy, steal your data, and act on your behalf without your knowledge.": { "message": "Malicious user scripts can violate your privacy, steal your data, and act on your behalf without your knowledge." },
"Matches:": { "message": "Matches:" },
"New user script ...": { "message": "New user script ..." },
"Requires special APIs:": { "message": "Requires special APIs:" },
"Runs on:": { "message": "Runs on:" },
"This is a Greasemonkey user script. Click install to start using it.": { "message": "This is a Greasemonkey user script. Click install to start using it." },
"Undo uninstall": { "message": "Undo uninstall" },
"Uninstall": { "message": "Uninstall" },
"User scripts for this tab": { "message": "User scripts for this tab" },
"You should only install scripts from sources that you trust.": { "message": "You should only install scripts from sources that you trust." }
}
3 changes: 3 additions & 0 deletions manifest.json
Expand Up @@ -9,6 +9,7 @@
"96": "skin/icon.svg",
"512": "skin/icon.svg"
},
"default_locale": "en",

"applications": {
"gecko": {
Expand All @@ -26,6 +27,8 @@

"background": {
"scripts": [
"src/i18n.js",

"src/bg/api-provider-source.js",
"src/bg/execute.js",
"src/bg/is-enabled.js",
Expand Down
14 changes: 7 additions & 7 deletions src/bg/api-provider-source.js
Expand Up @@ -157,7 +157,7 @@ function GM_notification(text, title, image, onclick) {
}

if (typeof opt.text != 'string') {
throw new Error('GM.notification: "text" must be a string');
throw new Error(_('GM.notification: "text" must be a string'));
}

if (typeof opt.title != 'string') opt.title = 'Greasemonkey';
Expand Down Expand Up @@ -186,7 +186,7 @@ function GM_openInTab(url, openInBackground) {
try {
objURL = new URL(url, location.href);
} catch(e) {
throw new Error('GM.openInTab: Could not understand the URL: ' + url);
throw new Error(_('GM.openInTab: Could not understand the URL: $1', url));
}

chrome.runtime.sendMessage({
Expand Down Expand Up @@ -219,23 +219,23 @@ function GM_setClipboard(text) {


function GM_xmlHttpRequest(d) {
if (!d) throw new Error('GM.xmlHttpRequest: Received no details.');
if (!d.url) throw new Error('GM.xmlHttpRequest: Received no URL.');
if (!d) throw new Error(_('GM.xmlHttpRequest: Received no details.'));
if (!d.url) throw new Error(_('GM.xmlHttpRequest: Received no URL.'));

let url;
try {
url = new URL(d.url, location.href);
} catch (e) {
throw new Error(
'GM.xmlHttpRequest: Could not understand the URL: ' + d.url
+ '\n' + e);
_('GM.xmlHttpRequest: Could not understand the URL: $1\n$2', d.url, e));
}

if (url.protocol != 'http:'
&& url.protocol != 'https:'
&& url.protocol != 'ftp:'
) {
throw new Error('GM.xmlHttpRequest: Passed URL has bad protocol: ' + d.url);
throw new Error(
_('GM.xmlHttpRequest: Passed URL has bad protocol: $1', d.url));
}

let port = chrome.runtime.connect({name: 'UserScriptXhr'});
Expand Down
7 changes: 5 additions & 2 deletions src/bg/execute.js
Expand Up @@ -19,12 +19,15 @@ function executeUserscriptOnNavigation(detail) {
chrome.tabs.executeScript(detail.tabId, options, result => {
let err = chrome.runtime.lastError;
if (!err) return;

// TODO: i18n?
if (err.message.startsWith('Message manager disconnected')) return;
if (err.message.startsWith('No matching message handler')) return;

// TODO: Better indication of the root cause.
console.error(
'Could not execute user script: ' + userScript.toString(),
'\n', err);
_('Could not execute user script: $1\n$2', userScript.toString(), err)
);
});
}
}
3 changes: 2 additions & 1 deletion src/bg/on-user-script-notification.js
Expand Up @@ -30,7 +30,8 @@ function onUserScriptNotification(port) {
createNotification(msg.details, port);
break;
default:
console.warn('UserScriptNotification port un-handled message name:', msg.name);
console.warn(
'UserScriptNotification port un-handled message name:', msg.name);
}
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/bg/user-script-detect.js
Expand Up @@ -83,7 +83,7 @@ function openInstallDialog(scriptDetails, url) {
} else {
let options = {
'height': 640,
'titlePreface': scriptDetails.name + ' - Greasemonkey User Script',
'titlePreface': _('$1 - Greasemonkey User Script', scriptDetails.name),
'type': 'popup',
'url': installUrl,
'width': 480,
Expand Down
25 changes: 14 additions & 11 deletions src/browser/monkey-menu.html
Expand Up @@ -14,7 +14,9 @@
<a href="#toggle-global" class="subview-item">
<div rv-show="enabled" class="icon fa fa-check-circle-o"></div>
<div rv-hide="enabled" class="icon fa fa-circle-o"></div>
<div class="text">Greasemonkey is {enabled | active}</div>
<div class="text i18n">
{enabled|i18nBool 'Greasemonkey is active' 'Greasemonkey is disabled'}
</div>
</a>
<!-- TODO: This feature.
<div class="subview-item" id="open-options">
Expand All @@ -26,7 +28,7 @@
<div rv-hide="userScripts.active | empty">
<hr>
<div class="subview-item heading">
<div class="text">User scripts for this tab</div>
<div class="text">{'User scripts for this tab'|i18n}</div>
</div>

<a class="subview-item next-menu user-script"
Expand All @@ -42,7 +44,7 @@
<div rv-hide="userScripts.inactive | empty">
<hr>
<div class="subview-item" rv-hide="userScripts.active | empty">
<div class="text heading">Other user scripts</div>
<div class="text heading">{'Other user scripts'|i18n}</div>
</div>

<a class="subview-item next-menu user-script"
Expand All @@ -59,27 +61,27 @@

<a href="#new-user-script" class="subview-item">
<div class="icon fa fa-file-text-o"></div>
<div class="text">New user script ...</div>
<div class="text">{'New user script ...'|i18n}</div>
</a>

<hr>

<a href="#https://www.greasespot.net/"
class="subview-item">
<div class="icon fa fa-link"></div>
<div class="text">Greasemonkey home page</div>
<div class="text">{'Greasemonkey home page'|i18n}</div>
</a>

<a href="#https://wiki.greasespot.net/"
class="subview-item">
<div class="icon fa fa-link"></div>
<div class="text">Greasemonkey Wiki</div>
<div class="text">{'Greasemonkey Wiki'|i18n}</div>
</a>

<a href="#https://wiki.greasespot.net/User_Script_Hosting"
class="subview-item">
<div class="icon fa fa-link"></div>
<div class="text">Get User Scripts</div>
<div class="text">{'Get User Scripts'|i18n}</div>
</a>
</div>
</section>
Expand All @@ -97,28 +99,29 @@
rv-class-fa-check-circle-o="activeScript.enabled"
rv-class-fa-circle-o="activeScript.enabled | not">
</div>
<div class="text">{activeScript.enabled | enabled}</div>
<div class="text">{activeScript.enabled|i18nBool 'Enabled' 'Disabled'}</div>
</a>

<a href="#edit-user-script" class="subview-item">
<div class="icon fa fa-pencil-square-o"></div>
<div class="text">Edit</div>
<div class="text">{'Edit'|i18n}</div>
</a>

<a href="#uninstall-user-script" class="subview-item"
rv-hide="pendingUninstall">
<div class="icon fa fa-trash-o"></div>
<div class="text">Uninstall</div>
<div class="text">{'Uninstall'|i18n}</div>
</a>
<a href="#undo-uninstall-user-script" class="subview-item"
rv-show="pendingUninstall">
<div class="icon fa fa-trash-o"></div>
<div class="text">Undo uninstall ({ pendingUninstall })</div>
<div class="text">{'Undo uninstall'|i18n} ({ pendingUninstall })</div>
</a>
</div>
</section>


<script src="/src/i18n.js"></script>
<script src="/third-party/rivets/rivets.bundled.min.js"></script>
<script src="/third-party/convert2RegExp.js"></script>
<script src="/third-party/MatchPattern.js"></script>
Expand Down
10 changes: 5 additions & 5 deletions src/browser/monkey-menu.js
Expand Up @@ -139,11 +139,11 @@ function onHashChange(event) {
} catch (err) {
if ('TypeError' === err.name) {
// Indicates a bad URL
console.log('Unknown Monkey Menu item, not a valid Uuid nor a url',
hash);
console.log(
'Unknown Monkey Menu item, not a valid Uuid nor a url', hash);
} else {
console.log('Unknown error parsing Monkey Menu item as url',
hash, err);
console.log(
'Unknown error parsing Monkey Menu item as url', hash, err);
}
}
break;
Expand Down Expand Up @@ -196,7 +196,7 @@ function onLoad(event) {
});

// Set up listeners for the transition effect. Set display: none when the
// vibility property is changed.
// visibility property is changed.
for (el of document.getElementsByTagName('section')) {
if (el.id !== 'menu') {
el.style.display = 'none';
Expand Down
2 changes: 2 additions & 0 deletions src/content/edit-user-script.html
Expand Up @@ -6,6 +6,8 @@
<link rel="stylesheet" href="/third-party/font_awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="edit-user-script.css">

<script src="/src/i18n.js"></script>

<script src="/third-party/codemirror/codemirror.js"></script>
<link rel="stylesheet" href="/third-party/codemirror/codemirror.css">

Expand Down
5 changes: 2 additions & 3 deletions src/content/edit-user-script.js
Expand Up @@ -11,7 +11,6 @@ var editor = CodeMirror(

CodeMirror.commands.save = onSave;

const titlePattern = '%s - Greasemonkey User Script Editor';
const userScriptUuid = location.hash.substr(1);
const editorDocs = [];
const editorTabs = [];
Expand Down Expand Up @@ -57,7 +56,7 @@ chrome.runtime.sendMessage({
editor.swapDoc(editorDocs[0]);
editor.focus();

document.title = titlePattern.replace('%s', userScript.name);
document.title = _('$1 - Greasemonkey User Script Editor', userScript.name);
});


Expand All @@ -67,7 +66,7 @@ function onUserScriptChanged(message, sender, sendResponse) {
let details = message.details;
let parsedDetails = message.parsedDetails;

document.title = titlePattern.replace('%s', details.name);
document.title = _('$1 - Greasemonkey User Script Editor', details.name);

for (let i = editorDocs.length - 1; i > 0; i--) {
let u = editorUrls[i];
Expand Down
20 changes: 10 additions & 10 deletions src/content/install-dialog.html
Expand Up @@ -18,32 +18,32 @@ <h1>
</header>

<div id="install">
<p>This is a Greasemonkey user script. Click install to start using it.</p>
<p>{'This is a Greasemonkey user script. Click install to start using it.'|i18n}</p>

<div id="details">
<div rv-hide="grants | empty" id="apis">
<p>Requires special APIs:</p>
<p>{'Requires special APIs:'|i18n}</p>
<ul>
<li rv-each-grant="grants">{ grant }</li>
</ul>
</div>

<div rv-hide="includes | empty" id="includes">
<p>Runs on:</p>
<p>{'Runs on:'|i18n}</p>
<ul>
<li rv-each-include="includes">{ include }</li>
</ul>
</div>

<div rv-hide="matches | empty" id="matches">
<p>Matches:</p>
<p>{'Matches:'|i18n}</p>
<ul>
<li rv-each-match="matches">{ match }</li>
</ul>
</div>

<div rv-hide="excludes | empty" id="excludes">
<p>Does not run on:</p>
<p>{'Does not run on:'|i18n}</p>
<ul>
<li rv-each-exclude="excludes">{ exclude }</li>
</ul>
Expand All @@ -54,9 +54,8 @@ <h1>

<div class="text">
<p>
Malicious user scripts can violate your privacy, steal your data, and
act on your behalf without your knowledge. <strong>You should only
install scripts from sources that you trust.</strong>
{'Malicious user scripts can violate your privacy, steal your data, and act on your behalf without your knowledge.'|i18n}
<strong>{'You should only install scripts from sources that you trust.'|i18n}</strong>
</p>
</div>

Expand All @@ -71,12 +70,13 @@ <h1>

<div id="footer">
<button id="btn-cancel" class="button-big button-secondary"
>Cancel</button>
>{'Cancel'|i18n}</button>
<div class="spacer"></div>
<button id="btn-install" class="button-big button-success" disabled="disabled"
>Install</button>
>{'Install'|i18n}</button>
</div>

<script src="/src/i18n.js"></script>
<script src="/third-party/rivets/rivets.bundled.min.js"></script>
<script src="/src/util/rivets-formatters.js"></script>
<script src="install-dialog.js"></script>
Expand Down
6 changes: 3 additions & 3 deletions src/content/install-dialog.js
@@ -1,5 +1,5 @@
const details = JSON.parse(unescape(document.location.search.substr(1)));
document.title = details.name + ' - Greasemonkey User Script';
document.title = _('$1 - Greasemonkey User Script', details.name);


function finish() {
Expand Down Expand Up @@ -65,7 +65,7 @@ chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
while (resultEl.firstChild) resultEl.removeChild(resultEl.firstChild);
resultEl.appendChild(errorList);
} else {
resultEl.textContent = 'Download and install successful!';
resultEl.textContent = _('Download and install successful!');
progressBar.parentNode && progressBar.parentNode.removeChild(progressBar);
finish();
}
Expand All @@ -82,7 +82,7 @@ window.addEventListener('DOMContentLoaded', event => {

// The fallback to default icon won't work unless iconUrl has at least an
// empty string.
rvDetails.iconUrl = rvDetails.iconUrl || "";
rvDetails.iconUrl = rvDetails.iconUrl || '';

rivets.bind(document.body, rvDetails);
});

0 comments on commit 9ce5dab

Please sign in to comment.