89 lines
2.5 KiB
JavaScript
89 lines
2.5 KiB
JavaScript
|
'use strict'
|
||
|
|
||
|
// 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/internal/renderer/ipc-renderer-internal')
|
||
|
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 localesDirectory = path.join(metadata.srcDirectory, '_locales')
|
||
|
try {
|
||
|
const filename = path.join(localesDirectory, language, 'messages.json')
|
||
|
fs.accessSync(filename, fs.constants.R_OK)
|
||
|
return filename
|
||
|
} catch (err) {
|
||
|
const defaultLocale = metadata.default_locale || 'en'
|
||
|
return path.join(localesDirectory, defaultLocale, 'messages.json')
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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)
|
||
|
}
|
||
|
}
|
||
|
}
|