Merge pull request #5924 from electron/chrome-i18n-get-message

Implement chrome.i18n.getMessage
This commit is contained in:
Kevin Sawicki 2016-06-09 14:47:37 -07:00 committed by GitHub
commit 50f5025447
8 changed files with 106 additions and 2 deletions

View file

@ -63,6 +63,7 @@
'lib/renderer/api/remote.js',
'lib/renderer/api/screen.js',
'lib/renderer/api/web-frame.js',
'lib/renderer/extensions/i18n.js',
],
'js2c_sources': [
'lib/common/asar.js',

View file

@ -115,6 +115,10 @@ ipcMain.on('CHROME_RUNTIME_CONNECT', function (event, extensionId, connectInfo)
page.webContents.sendToAll(`CHROME_RUNTIME_ONCONNECT_${extensionId}`, event.sender.id, portId, connectInfo)
})
ipcMain.on('CHROME_I18N_MANIFEST', function (event, extensionId) {
event.returnValue = manifestMap[extensionId]
})
ipcMain.on('CHROME_RUNTIME_SENDMESSAGE', function (event, extensionId, message) {
const page = backgroundPages[extensionId]
if (!page) {

View file

@ -199,4 +199,6 @@ exports.injectTo = function (extensionId, isBackgroundPage, context) {
setPopup () {},
getPopup () {}
}
chrome.i18n = require('./extensions/i18n.js').setup(extensionId)
}

View file

@ -0,0 +1,84 @@
// Implementation of chrome.i18n.getMessage
// https://developer.chrome.com/extensions/i18n#method-getMessage
//
// Does not implement predefined messages:
// https://developer.chrome.com/extensions/i18n#overview-predefined
const {ipcRenderer} = require('electron')
const fs = require('fs')
const path = require('path')
let metadata
const getExtensionMetadata = (extensionId) => {
if (!metadata) {
metadata = ipcRenderer.sendSync('CHROME_I18N_MANIFEST', extensionId)
}
return metadata
}
const getMessagesPath = (extensionId, language) => {
const metadata = getExtensionMetadata(extensionId)
const defaultLocale = metadata.default_locale || 'en'
const localesDirectory = path.join(metadata.srcDirectory, '_locales')
let messagesPath = path.join(localesDirectory, language, 'messages.json')
if (!fs.statSyncNoException(messagesPath)) {
messagesPath = path.join(localesDirectory, defaultLocale, 'messages.json')
}
return messagesPath
}
const getMessages = (extensionId, language) => {
try {
const messagesPath = getMessagesPath(extensionId, language)
return JSON.parse(fs.readFileSync(messagesPath)) || {}
} catch (error) {
return {}
}
}
const getLanguage = () => {
return navigator.language.replace(/-.*$/, '').toLowerCase()
}
const replaceNumberedSubstitutions = (message, substitutions) => {
return message.replace(/\$(\d+)/, (_, number) => {
const index = parseInt(number, 10) - 1
return substitutions[index] || ''
})
}
const replacePlaceholders = (message, placeholders, substitutions) => {
if (typeof substitutions === 'string') {
substitutions = [substitutions]
}
if (!Array.isArray(substitutions)) {
substitutions = []
}
if (placeholders) {
Object.keys(placeholders).forEach((name) => {
let {content} = placeholders[name]
content = replaceNumberedSubstitutions(content, substitutions)
message = message.replace(new RegExp(`\\$${name}\\$`, 'gi'), content)
})
}
return replaceNumberedSubstitutions(message, substitutions)
}
const getMessage = (extensionId, messageName, substitutions) => {
const messages = getMessages(extensionId, getLanguage())
if (messages.hasOwnProperty(messageName)) {
const {message, placeholders} = messages[messageName]
return replacePlaceholders(message, placeholders, substitutions)
}
}
exports.setup = (extensionId) => {
return {
getMessage (messageName, substitutions) {
return getMessage(extensionId, messageName, substitutions)
}
}
}

View file

@ -865,6 +865,7 @@ describe('browser-window module', function () {
ipcMain.once('answer', function (event, message) {
assert.equal(message.runtimeId, 'foo')
assert.equal(message.tabId, w.webContents.id)
assert.equal(message.i18nString, 'foo - bar (baz)')
done()
})
})

View file

@ -0,0 +1,10 @@
{
"foo": {
"message": "foo - $BAZ$ ($2)",
"placeholders": {
"baz": {
"content": "$1"
}
}
}
}

View file

@ -6,7 +6,8 @@
<script>
var message = JSON.stringify({
runtimeId: chrome.runtime.id,
tabId: chrome.devtools.inspectedWindow.tabId
tabId: chrome.devtools.inspectedWindow.tabId,
i18nString: chrome.i18n.getMessage('foo', ['bar', 'baz'])
})
var sendMessage = `require('electron').ipcRenderer.send('answer', ${message})`
window.chrome.devtools.inspectedWindow.eval(sendMessage, function () {})

View file

@ -1,5 +1,6 @@
{
"name": "foo",
"version": "1.0",
"devtools_page": "foo.html"
"devtools_page": "foo.html",
"default_locale": "en"
}