From 2c042cc3faedb9de8bb32683aaf8a5084cd1f59c Mon Sep 17 00:00:00 2001 From: JC Brand Date: Thu, 10 Sep 2020 07:33:00 +0200 Subject: [PATCH] Fixes #2184: Headless build relies on locale directory Removed Jed from the headless build and instead let `__` call sprintf. It's now up to downstream users for `@converse/headless` to decide whether they want i18n support for the few translatable strings in that package and to implement it themselves. --- package-lock.json | 46 ++++++++++-------- package.json | 1 + spec/disco.js | 2 +- src/components/adhoc-commands.js | 2 +- src/components/emoji-picker.js | 2 +- src/components/image_picker.js | 2 +- src/components/message-actions.js | 2 +- src/components/message-history.js | 2 +- src/components/message.js | 2 +- src/components/toolbar.js | 2 +- src/converse-bookmark-views.js | 2 +- src/converse-chatview.js | 2 +- src/converse-controlbox.js | 2 +- src/converse-headlines-view.js | 2 +- src/converse-minimize.js | 2 +- src/converse-modal.js | 2 +- src/converse-muc-views.js | 2 +- src/converse-notification.js | 9 ++-- src/converse-omemo.js | 2 +- src/converse-profile.js | 2 +- src/converse-register.js | 2 +- src/converse-roomslist.js | 2 +- src/converse-rosterview.js | 2 +- src/converse.js | 1 + src/headless/connection.js | 3 +- src/headless/converse-core.js | 56 +++++++++++++--------- src/headless/package-lock.json | 12 ++--- src/headless/package.json | 2 +- src/{headless/i18n.js => i18n/index.js} | 62 ++++++++++++++++--------- src/modals/add-muc.js | 2 +- src/modals/moderator-tools.js | 2 +- src/modals/muc-commands.js | 2 +- src/modals/muc-details.js | 2 +- src/modals/muc-list.js | 2 +- src/templates/add_chatroom_modal.js | 2 +- src/templates/add_contact_modal.js | 2 +- src/templates/bookmarks_list.js | 2 +- src/templates/buttons.js | 2 +- src/templates/chat_message.js | 2 +- src/templates/chatbox_head.js | 2 +- src/templates/chatroom_details_modal.js | 2 +- src/templates/chatroom_head.js | 2 +- src/templates/chats_panel.js | 2 +- src/templates/directives/retraction.js | 2 +- src/templates/emoji_picker.js | 2 +- src/templates/file_progress.js | 2 +- src/templates/image_modal.js | 2 +- src/templates/list_chatrooms_modal.js | 2 +- src/templates/login_panel.js | 2 +- src/templates/message_versions_modal.js | 2 +- src/templates/moderator_tools_modal.js | 2 +- src/templates/muc_bookmark_form.js | 2 +- src/templates/muc_config_form.js | 2 +- src/templates/muc_invite_modal.js | 2 +- src/templates/muc_password_form.js | 2 +- src/templates/muc_sidebar.js | 2 +- src/templates/occupant.js | 2 +- src/templates/profile.js | 2 +- src/templates/profile_modal.js | 2 +- src/templates/prompt.js | 2 +- src/templates/rooms_list.js | 2 +- src/templates/trimmed_chat.js | 2 +- src/templates/user_details_modal.js | 2 +- src/templates/user_settings_modal.js | 2 +- 64 files changed, 172 insertions(+), 130 deletions(-) rename src/{headless/i18n.js => i18n/index.js} (66%) diff --git a/package-lock.json b/package-lock.json index 288de0b74..61c7b1ba9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4904,20 +4904,20 @@ } }, "@octokit/endpoint": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.5.tgz", - "integrity": "sha512-70K5u6zd45ItOny6aHQAsea8HHQjlQq85yqOMe+Aj8dkhN2qSJ9T+Q3YjUjEYfPRBcuUWNgMn62DQnP/4LAIiQ==", + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.6.tgz", + "integrity": "sha512-7Cc8olaCoL/mtquB7j/HTbPM+sY6Ebr4k2X2y4JoXpVKQ7r5xB4iGQE0IoO58wIPsUk4AzoT65AMEpymSbWTgQ==", "dev": true, "requires": { "@octokit/types": "^5.0.0", - "is-plain-object": "^4.0.0", + "is-plain-object": "^5.0.0", "universal-user-agent": "^6.0.0" }, "dependencies": { "is-plain-object": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-4.1.1.tgz", - "integrity": "sha512-5Aw8LLVsDlZsETVMhoMXzqsXwQqr/0vlnBYzIXJbYo2F4yYlhLHs+Ez7Bod7IIQKWkJbJfxrWD7pA1Dw1TKrwA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true }, "universal-user-agent": { @@ -4982,16 +4982,16 @@ } }, "@octokit/request": { - "version": "5.4.7", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.7.tgz", - "integrity": "sha512-FN22xUDP0i0uF38YMbOfx6TotpcENP5W8yJM1e/LieGXn6IoRxDMnBf7tx5RKSW4xuUZ/1P04NFZy5iY3Rax1A==", + "version": "5.4.8", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.8.tgz", + "integrity": "sha512-mWbxjsARJzAq5xp+ZrQfotc+MHFz3/Am2qATJwflv4PZ1TjhgIJnr60PCVdZT9Z/tl+uPXooaVgeviy1KkDlLQ==", "dev": true, "requires": { "@octokit/endpoint": "^6.0.1", "@octokit/request-error": "^2.0.0", "@octokit/types": "^5.0.0", "deprecation": "^2.0.0", - "is-plain-object": "^4.0.0", + "is-plain-object": "^5.0.0", "node-fetch": "^2.3.0", "once": "^1.4.0", "universal-user-agent": "^6.0.0" @@ -5009,9 +5009,9 @@ } }, "is-plain-object": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-4.1.1.tgz", - "integrity": "sha512-5Aw8LLVsDlZsETVMhoMXzqsXwQqr/0vlnBYzIXJbYo2F4yYlhLHs+Ez7Bod7IIQKWkJbJfxrWD7pA1Dw1TKrwA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true }, "universal-user-agent": { @@ -5730,6 +5730,14 @@ "dev": true, "requires": { "sprintf-js": "~1.0.2" + }, + "dependencies": { + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + } } }, "arr-diff": { @@ -13012,7 +13020,8 @@ "jed": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/jed/-/jed-1.1.1.tgz", - "integrity": "sha1-elSbvZ/+FYWwzQoZHiAwVb7ldLQ=" + "integrity": "sha1-elSbvZ/+FYWwzQoZHiAwVb7ldLQ=", + "dev": true }, "jest-docblock": { "version": "25.3.0", @@ -22333,10 +22342,9 @@ } }, "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" }, "sshpk": { "version": "1.16.1", diff --git a/package.json b/package.json index f4f048d06..93e77b48f 100644 --- a/package.json +++ b/package.json @@ -85,6 +85,7 @@ "imports-loader": "^0.8.0", "install": "^0.13.0", "jasmine": "^3.5.0", + "jed": "1.1.1", "jsdoc": "^3.6.4", "karma": "^5.1.0", "karma-chrome-launcher": "^3.1.0", diff --git a/spec/disco.js b/spec/disco.js index 573d87f7d..aa20b5630 100644 --- a/spec/disco.js +++ b/spec/disco.js @@ -1,4 +1,4 @@ -/*global mock */ +/*global mock, converse */ describe("Service Discovery", function () { diff --git a/src/components/adhoc-commands.js b/src/components/adhoc-commands.js index a416b0314..1ca0e0064 100644 --- a/src/components/adhoc-commands.js +++ b/src/components/adhoc-commands.js @@ -2,7 +2,7 @@ import "./autocomplete.js" import log from "@converse/headless/log"; import sizzle from "sizzle"; import { CustomElement } from './element.js'; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { api, converse } from "@converse/headless/converse-core"; import { html } from "lit-html"; import { unsafeHTML } from 'lit-html/directives/unsafe-html.js'; diff --git a/src/components/emoji-picker.js b/src/components/emoji-picker.js index 3636d9a7b..b252dcd4b 100644 --- a/src/components/emoji-picker.js +++ b/src/components/emoji-picker.js @@ -2,7 +2,7 @@ import "./emoji-picker-content.js"; import DOMNavigator from "../dom-navigator"; import { BaseDropdown } from "./dropdown.js"; import { CustomElement } from './element.js'; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { _converse, api, converse } from "@converse/headless/converse-core"; import { debounce, find } from "lodash-es"; import { html } from "lit-element"; diff --git a/src/components/image_picker.js b/src/components/image_picker.js index b1213a471..59e2c2f71 100644 --- a/src/components/image_picker.js +++ b/src/components/image_picker.js @@ -1,5 +1,5 @@ import { CustomElement } from './element.js'; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { html } from 'lit-element'; import { renderAvatar } from "../templates/directives/avatar.js"; import { api } from "@converse/headless/converse-core"; diff --git a/src/components/message-actions.js b/src/components/message-actions.js index 356fac3f7..9a4a33bab 100644 --- a/src/components/message-actions.js +++ b/src/components/message-actions.js @@ -1,5 +1,5 @@ import { CustomElement } from './element.js'; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { api } from "@converse/headless/converse-core"; import { html } from 'lit-element'; import { until } from 'lit-html/directives/until.js'; diff --git a/src/components/message-history.js b/src/components/message-history.js index 5373d7538..0a8c6c3a2 100644 --- a/src/components/message-history.js +++ b/src/components/message-history.js @@ -2,7 +2,7 @@ import "./message"; import dayjs from 'dayjs'; import tpl_new_day from "../templates//new_day.js"; import { CustomElement } from './element.js'; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { api } from "@converse/headless/converse-core"; import { html } from 'lit-element'; import { repeat } from 'lit-html/directives/repeat.js'; diff --git a/src/components/message.js b/src/components/message.js index 2b45abd1a..198a8024f 100644 --- a/src/components/message.js +++ b/src/components/message.js @@ -8,7 +8,7 @@ import filesize from 'filesize'; import tpl_chat_message from '../templates/chat_message.js'; import tpl_spinner from '../templates/spinner.js'; import { CustomElement } from './element.js'; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { _converse, api, converse } from '@converse/headless/converse-core'; import { html } from 'lit-element'; import { renderAvatar } from './../templates/directives/avatar'; diff --git a/src/components/toolbar.js b/src/components/toolbar.js index e9254be34..21bbe283a 100644 --- a/src/components/toolbar.js +++ b/src/components/toolbar.js @@ -1,6 +1,6 @@ import "./emoji-picker.js"; import { CustomElement } from './element.js'; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { _converse, api, converse } from "@converse/headless/converse-core"; import { html } from 'lit-element'; import { until } from 'lit-html/directives/until.js'; diff --git a/src/converse-bookmark-views.js b/src/converse-bookmark-views.js index 8cf94e7cc..186f89f03 100644 --- a/src/converse-bookmark-views.js +++ b/src/converse-bookmark-views.js @@ -10,7 +10,7 @@ import tpl_bookmarks_list from "templates/bookmarks_list.js" import tpl_muc_bookmark_form from "templates/muc_bookmark_form.js"; import { Model } from '@converse/skeletor/src/model.js'; import { View } from '@converse/skeletor/src/view.js'; -import { __ } from '@converse/headless/i18n'; +import { __ } from './i18n'; import { invokeMap } from 'lodash-es'; const { Strophe } = converse.env; diff --git a/src/converse-chatview.js b/src/converse-chatview.js index aa45206c8..42ff904f6 100644 --- a/src/converse-chatview.js +++ b/src/converse-chatview.js @@ -17,7 +17,7 @@ import tpl_toolbar from "templates/toolbar.js"; import tpl_user_details_modal from "templates/user_details_modal.js"; import { BootstrapModal } from "./converse-modal.js"; import { View } from '@converse/skeletor/src/view.js'; -import { __ } from '@converse/headless/i18n'; +import { __ } from './i18n'; import { _converse, api, converse } from "@converse/headless/converse-core"; import { debounce, isString } from "lodash-es"; import { html, render } from "lit-html"; diff --git a/src/converse-controlbox.js b/src/converse-controlbox.js index 93a298054..2445a2110 100644 --- a/src/converse-controlbox.js +++ b/src/converse-controlbox.js @@ -12,7 +12,7 @@ import tpl_controlbox_toggle from "templates/controlbox_toggle.html"; import tpl_login_panel from "templates/login_panel.js"; import { Model } from '@converse/skeletor/src/model.js'; import { View } from "@converse/skeletor/src/view"; -import { __ } from '@converse/headless/i18n'; +import { __ } from './i18n'; import { _converse, api, converse } from "@converse/headless/converse-core"; const { Strophe, dayjs } = converse.env; diff --git a/src/converse-headlines-view.js b/src/converse-headlines-view.js index 81e935b2e..4e3fe0743 100644 --- a/src/converse-headlines-view.js +++ b/src/converse-headlines-view.js @@ -8,7 +8,7 @@ import tpl_chatbox from "templates/chatbox.js"; import tpl_headline_panel from "templates/headline_panel.js"; import { ChatBoxView } from "./converse-chatview"; import { View } from '@converse/skeletor/src/view.js'; -import { __ } from '@converse/headless/i18n'; +import { __ } from './i18n'; import { _converse, api, converse } from "@converse/headless/converse-core"; import { render } from "lit-html"; diff --git a/src/converse-minimize.js b/src/converse-minimize.js index be5ab9f2c..1ad34345f 100644 --- a/src/converse-minimize.js +++ b/src/converse-minimize.js @@ -8,7 +8,7 @@ import 'converse-chatview'; import tpl_chats_panel from 'templates/chats_panel.js'; import { Model } from '@converse/skeletor/src/model.js'; import { View } from '@converse/skeletor/src/view'; -import { __ } from '@converse/headless/i18n'; +import { __ } from './i18n'; import { _converse, api, converse } from '@converse/headless/converse-core'; import { debounce } from 'lodash-es'; import { render } from 'lit-html'; diff --git a/src/converse-modal.js b/src/converse-modal.js index fb8809858..202d2bc3c 100644 --- a/src/converse-modal.js +++ b/src/converse-modal.js @@ -7,7 +7,7 @@ import { View } from '@converse/skeletor/src/view.js'; import { Model } from '@converse/skeletor/src/model.js'; import { isString } from "lodash-es"; import { render } from 'lit-html'; -import { __ } from '@converse/headless/i18n'; +import { __ } from './i18n'; import bootstrap from "bootstrap.native"; import { converse } from "@converse/headless/converse-core"; import log from "@converse/headless/log"; diff --git a/src/converse-muc-views.js b/src/converse-muc-views.js index 06d9143a9..5460aa154 100644 --- a/src/converse-muc-views.js +++ b/src/converse-muc-views.js @@ -26,7 +26,7 @@ import tpl_spinner from "templates/spinner.html"; import { ChatBoxView } from "./converse-chatview"; import { Model } from '@converse/skeletor/src/model.js'; import { View } from '@converse/skeletor/src/view.js'; -import { __ } from '@converse/headless/i18n'; +import { __ } from './i18n'; import { _converse, api, converse } from "@converse/headless/converse-core"; import { debounce, isString, isUndefined } from "lodash-es"; import { render } from "lit-html"; diff --git a/src/converse-notification.js b/src/converse-notification.js index a190b4051..7b60e511b 100644 --- a/src/converse-notification.js +++ b/src/converse-notification.js @@ -5,7 +5,7 @@ */ import log from "@converse/headless/log"; import st from "@converse/headless/utils/stanza"; -import { __ } from '@converse/headless/i18n'; +import { __ } from './i18n'; import { _converse, api, converse } from "@converse/headless/converse-core"; const { Strophe, sizzle } = converse.env; @@ -36,9 +36,12 @@ converse.plugins.add('converse-notification', { notify_nicknames_without_references: false }); + /** + * Is this a group message for which we should notify the user? + * @private + * @method _converse#shouldNotifyOfGroupMessage + */ _converse.shouldNotifyOfGroupMessage = function (message, data) { - /* Is this a group message worthy of notification? - */ const jid = message.getAttribute('from'); const room_jid = Strophe.getBareJidFromJid(jid); const notify_all = api.settings.get('notify_all_room_messages'); diff --git a/src/converse-omemo.js b/src/converse-omemo.js index 47800c93c..e8789478e 100644 --- a/src/converse-omemo.js +++ b/src/converse-omemo.js @@ -9,7 +9,7 @@ import "converse-profile"; import log from "@converse/headless/log"; import { Collection } from "@converse/skeletor/src/collection"; import { Model } from '@converse/skeletor/src/model.js'; -import { __ } from '@converse/headless/i18n'; +import { __ } from './i18n'; import { _converse, api, converse } from "@converse/headless/converse-core"; import { concat, debounce, difference, invokeMap, range, omit } from "lodash-es"; import { html } from 'lit-html'; diff --git a/src/converse-profile.js b/src/converse-profile.js index 9fc244a6e..b4fd107e6 100644 --- a/src/converse-profile.js +++ b/src/converse-profile.js @@ -14,7 +14,7 @@ import tpl_chat_status_modal from "templates/chat_status_modal"; import tpl_profile from "templates/profile.js"; import tpl_profile_modal from "templates/profile_modal"; import { BootstrapModal } from "./converse-modal.js"; -import { __ } from '@converse/headless/i18n'; +import { __ } from './i18n'; import { _converse, api, converse } from "@converse/headless/converse-core"; const u = converse.env.utils; diff --git a/src/converse-register.js b/src/converse-register.js index c4d71e3b9..ad2a3cb4c 100644 --- a/src/converse-register.js +++ b/src/converse-register.js @@ -7,7 +7,7 @@ * @license Mozilla Public License (MPLv2) */ import "converse-controlbox"; -import { __ } from '@converse/headless/i18n'; +import { __ } from './i18n'; import { View } from "@converse/skeletor/src/view"; import { pick } from "lodash-es"; import { _converse, api, converse } from "@converse/headless/converse-core"; diff --git a/src/converse-roomslist.js b/src/converse-roomslist.js index 7db2984cb..6324b0ace 100644 --- a/src/converse-roomslist.js +++ b/src/converse-roomslist.js @@ -12,7 +12,7 @@ import { _converse, api, converse } from "@converse/headless/converse-core"; import tpl_rooms_list from "templates/rooms_list.js"; import { Model } from '@converse/skeletor/src/model.js'; import { View } from '@converse/skeletor/src/view.js'; -import { __ } from '@converse/headless/i18n'; +import { __ } from './i18n'; const { Strophe } = converse.env; diff --git a/src/converse-rosterview.js b/src/converse-rosterview.js index f49d7905f..ca7aeea42 100644 --- a/src/converse-rosterview.js +++ b/src/converse-rosterview.js @@ -18,7 +18,7 @@ import { BootstrapModal } from "./converse-modal.js"; import { Model } from '@converse/skeletor/src/model.js'; import { OrderedListView } from "@converse/skeletor/src/overview"; import { View } from '@converse/skeletor/src/view.js'; -import { __ } from '@converse/headless/i18n'; +import { __ } from './i18n'; import { _converse, api, converse } from "@converse/headless/converse-core"; import { compact, debounce, has, isString, uniq, without } from "lodash-es"; diff --git a/src/converse.js b/src/converse.js index ce28d65bc..04d4b919d 100644 --- a/src/converse.js +++ b/src/converse.js @@ -9,6 +9,7 @@ * Any of the following components may be removed if they're not needed. */ import "@converse/headless/headless"; +import "i18n"; import "converse-registry"; import "converse-autocomplete"; import "converse-bookmark-views"; // Views for XEP-0048 Bookmarks diff --git a/src/headless/connection.js b/src/headless/connection.js index 14ef37b3e..49708abec 100644 --- a/src/headless/connection.js +++ b/src/headless/connection.js @@ -2,7 +2,6 @@ import log from "./log"; import sizzle from 'sizzle'; import u from '@converse/headless/utils/core'; import { Strophe } from 'strophe.js/src/core'; -import { __ } from './i18n'; import { _converse, api, clearSession, tearDown } from "./converse-core"; import { debounce, isElement, noop } from 'lodash'; @@ -105,6 +104,7 @@ export class Connection extends Strophe.Connection { } async reconnect () { + const { __ } = _converse; log.debug('RECONNECTING: the connection has dropped, attempting to reconnect.'); this.setConnectionStatus( Strophe.Status.RECONNECTING, @@ -245,6 +245,7 @@ export class Connection extends Strophe.Connection { * @param { String } message */ onConnectStatusChanged (status, message) { + const { __ } = _converse; log.debug(`Status changed to: ${_converse.CONNECTION_STATUS[status]}`); if (status === Strophe.Status.ATTACHFAIL) { this.setConnectionStatus(status); diff --git a/src/headless/converse-core.js b/src/headless/converse-core.js index b6813a063..6060bef0c 100644 --- a/src/headless/converse-core.js +++ b/src/headless/converse-core.js @@ -5,8 +5,6 @@ */ import './polyfill'; import 'strophe.js/src/websocket'; -import { Strophe, $build, $iq, $msg, $pres } from 'strophe.js/src/strophe'; -import { Connection, MockConnection } from '@converse/headless/connection.js'; import Storage from '@converse/skeletor/src/storage.js'; import _ from './lodash.noconflict'; import advancedFormat from 'dayjs/plugin/advancedFormat'; @@ -17,13 +15,15 @@ import sizzle from 'sizzle'; import stanza_utils from "@converse/headless/utils/stanza"; import u from '@converse/headless/utils/core'; import { Collection } from "@converse/skeletor/src/collection"; +import { Connection, MockConnection } from '@converse/headless/connection.js'; +import { CustomElement } from '../components/element'; import { Events } from '@converse/skeletor/src/events.js'; import { Model } from '@converse/skeletor/src/model.js'; import { Router } from '@converse/skeletor/src/router.js'; -import { CustomElement } from '../components/element'; -import { __, i18n } from './i18n'; +import { Strophe, $build, $iq, $msg, $pres } from 'strophe.js/src/strophe'; import { assignIn, debounce, invoke, isFunction, isObject, isString, pick } from 'lodash-es'; import { html } from 'lit-element'; +import { sprintf } from 'sprintf-js'; dayjs.extend(advancedFormat); @@ -152,6 +152,32 @@ CONNECTION_STATUS[Strophe.Status.ERROR] = 'ERROR'; CONNECTION_STATUS[Strophe.Status.RECONNECTING] = 'RECONNECTING'; CONNECTION_STATUS[Strophe.Status.REDIRECT] = 'REDIRECT'; + +/** + * @namespace i18n + */ +export const i18n = { + initialize () {}, + + /** + * Overridable string wrapper method which can be used to provide i18n + * support. + * + * The default implementation in @converse/headless simply calls sprintf + * with the passed in arguments. + * + * If you install the full version of Converse, then this method gets + * overwritten in src/i18n/index.js to return a translated string. + * @method __ + * @private + * @memberOf i18n + * @param { String } str + */ + __ (...args) { + return sprintf(...args); + } +}; + /** * A private, closured object containing the private api (via {@link _converse.api}) * as well as private methods and internal data-structures. @@ -223,13 +249,12 @@ export const _converse = { /** * Translate the given string based on the current locale. - * Handles all MUC presence stanzas. * @method __ * @private * @memberOf _converse - * @param { String } str - The string to translate + * @param { String } str */ - '__': __, + '__': (...args) => i18n.__(...args), /** * A no-op method which is used to signal to gettext that the passed in string @@ -1431,21 +1456,6 @@ _converse.ConnectionFeedback = Model.extend({ }); -async function initLocale () { - if (_converse.isTestEnv()) { - _converse.locale = 'en'; - } else { - try { - _converse.locale = i18n.getLocale(api.settings.get('i18n'), api.settings.get("locales")); - await i18n.fetchTranslations(_converse); - } catch (e) { - log.fatal(e.message); - _converse.locale = 'en'; - } - } -} - - function setUnloadEvent () { if ('onpagehide' in window) { // Pagehide gets thrown in more cases than unload. Specifically it @@ -1536,7 +1546,6 @@ Object.assign(converse, { /^converse\?loglevel=(debug|info|warn|error|fatal)$/, 'loglevel', l => log.setLogLevel(l) ); - await initLocale(); _converse.connfeedback = new _converse.ConnectionFeedback(); /* When reloading the page: @@ -1550,6 +1559,7 @@ Object.assign(converse, { await initSessionStorage(); initClientConfig(); + i18n.initialize(); initPlugins(); registerGlobalEventHandlers(); diff --git a/src/headless/package-lock.json b/src/headless/package-lock.json index e2ba3c3b8..4fa5c45d4 100644 --- a/src/headless/package-lock.json +++ b/src/headless/package-lock.json @@ -31,12 +31,6 @@ "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", "dev": true }, - "jed": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/jed/-/jed-1.1.1.tgz", - "integrity": "sha1-elSbvZ/+FYWwzQoZHiAwVb7ldLQ=", - "dev": true - }, "lie": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", @@ -82,6 +76,12 @@ "lodash": "^4.17.11" } }, + "sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "dev": true + }, "strophe.js": { "version": "github:strophe/strophejs#ceb5640786dc60de4a13b18c9a263f2ef112874c", "from": "github:strophe/strophejs#ceb5640786dc60de4a13b18c9a263f2ef112874c", diff --git a/src/headless/package.json b/src/headless/package.json index 250c40e5f..3e501c681 100644 --- a/src/headless/package.json +++ b/src/headless/package.json @@ -38,10 +38,10 @@ "devDependencies": { "@converse/skeletor": "conversejs/skeletor#b260c554f4ce961c29deea4740083e58a489aa9b", "filesize": "^6.1.0", - "jed": "1.1.1", "localforage": "^1.7.3", "lodash-es": "^4.17.15", "pluggable.js": "2.0.1", + "sprintf-js": "^1.1.2", "strophe.js": "strophe/strophejs#ceb5640786dc60de4a13b18c9a263f2ef112874c" } } diff --git a/src/headless/i18n.js b/src/i18n/index.js similarity index 66% rename from src/headless/i18n.js rename to src/i18n/index.js index 969adfccc..e9249620e 100644 --- a/src/headless/i18n.js +++ b/src/i18n/index.js @@ -4,8 +4,10 @@ * @license Mozilla Public License (MPLv2) * @description This is the internationalization module */ -import Jed from "jed"; -import dayjs from "dayjs"; +import Jed from 'jed'; +import dayjs from 'dayjs'; +import log from "@converse/headless/log"; +import { _converse, api, i18n } from '@converse/headless/converse-core'; function detectLocale (library_check) { @@ -63,12 +65,30 @@ function isLocaleAvailable (locale, available) { } } + +/* Fetch the translations for the given local at the given URL. + * @private + * @method i18n#fetchTranslations + * @param { _converse } + */ +async function fetchTranslations (_converse) { + const { api, locale } = _converse; + if (!isConverseLocale(locale, api.settings.get("locales")) || locale === 'en') { + return; + } + const { default: data } = await import(/*webpackChunkName: "locales/[request]" */ `../i18n/${locale}/LC_MESSAGES/converse.po`); + await import(/*webpackChunkName: "locales/dayjs/[request]" */ `dayjs/locale/${locale.toLowerCase().replace('_', '-')}`); + dayjs.locale(getLocale(locale, l => dayjs.locale(l))); + jed_instance = new Jed(data); +} + + let jed_instance; /** * @namespace i18n */ -export const i18n = { +Object.assign(i18n, { getLocale (preferred_locale, available_locales) { return getLocale(preferred_locale, preferred => isConverseLocale(preferred, available_locales)); @@ -86,25 +106,23 @@ export const i18n = { } }, - /** - * Fetch the translations for the given local at the given URL. - * @private - * @method i18n#fetchTranslations - * @param { _converse } - */ - async fetchTranslations (_converse) { - const locale = _converse.locale; - if (!isConverseLocale(locale, _converse.api.settings.get("locales")) || locale === 'en') { - return; + async initialize () { + if (_converse.isTestEnv()) { + _converse.locale = 'en'; + } else { + try { + _converse.locale = i18n.getLocale(api.settings.get('i18n'), api.settings.get("locales")); + await fetchTranslations(_converse); + } catch (e) { + log.fatal(e.message); + _converse.locale = 'en'; + } } - const { default: data } = await import(/*webpackChunkName: "locales/[request]" */ `../i18n/${locale}/LC_MESSAGES/converse.po`); - await import(/*webpackChunkName: "locales/dayjs/[request]" */ `dayjs/locale/${locale.toLowerCase().replace('_', '-')}`); - dayjs.locale(getLocale(_converse.locale, l => dayjs.locale(l))); - jed_instance = new Jed(data); + }, + + __ (...args) { + return i18n.translate(...args); } -}; +}); - -export const __ = function () { - return i18n.translate.apply(i18n, arguments); -} +export const __ = i18n.__; diff --git a/src/modals/add-muc.js b/src/modals/add-muc.js index 16bc28121..879889524 100644 --- a/src/modals/add-muc.js +++ b/src/modals/add-muc.js @@ -1,7 +1,7 @@ import tpl_add_chatroom_modal from "templates/add_chatroom_modal.js"; import { BootstrapModal } from "../converse-modal.js"; import { Strophe } from 'strophe.js/src/strophe'; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { _converse, api, converse } from "@converse/headless/converse-core"; const u = converse.env.utils; diff --git a/src/modals/moderator-tools.js b/src/modals/moderator-tools.js index 06d462eff..89e82039a 100644 --- a/src/modals/moderator-tools.js +++ b/src/modals/moderator-tools.js @@ -3,7 +3,7 @@ import sizzle from "sizzle"; import tpl_moderator_tools_modal from "../templates/moderator_tools_modal.js"; import { AFFILIATIONS, ROLES } from "@converse/headless/converse-muc.js"; import { BootstrapModal } from "../converse-modal.js"; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { api, converse } from "@converse/headless/converse-core"; const { Strophe } = converse.env; diff --git a/src/modals/muc-commands.js b/src/modals/muc-commands.js index de175f26c..26b2cf33f 100644 --- a/src/modals/muc-commands.js +++ b/src/modals/muc-commands.js @@ -1,5 +1,5 @@ import { BootstrapModal } from "../converse-modal.js"; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { api, converse } from "@converse/headless/converse-core"; import log from "@converse/headless/log"; import sizzle from "sizzle"; diff --git a/src/modals/muc-details.js b/src/modals/muc-details.js index dd73953aa..22ff4f9ff 100644 --- a/src/modals/muc-details.js +++ b/src/modals/muc-details.js @@ -1,5 +1,5 @@ import { BootstrapModal } from "../converse-modal.js"; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import tpl_chatroom_details_modal from "../templates/chatroom_details_modal.js"; diff --git a/src/modals/muc-list.js b/src/modals/muc-list.js index b04e10636..dcceeff1c 100644 --- a/src/modals/muc-list.js +++ b/src/modals/muc-list.js @@ -6,7 +6,7 @@ import tpl_room_description from "templates/room_description.html"; import tpl_spinner from "templates/spinner.html"; import { BootstrapModal } from "../converse-modal.js"; import { Strophe, $iq } from 'strophe.js/src/strophe'; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { _converse, api, converse } from "@converse/headless/converse-core"; import { head } from "lodash-es"; diff --git a/src/templates/add_chatroom_modal.js b/src/templates/add_chatroom_modal.js index 6f372dd4f..15c7413c9 100644 --- a/src/templates/add_chatroom_modal.js +++ b/src/templates/add_chatroom_modal.js @@ -1,6 +1,6 @@ import { html } from "lit-html"; import { unsafeHTML } from "lit-html/directives/unsafe-html.js"; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { modal_header_close_button } from "./buttons" import xss from "xss/dist/xss"; diff --git a/src/templates/add_contact_modal.js b/src/templates/add_contact_modal.js index 2914b3fb9..d0fad63ae 100644 --- a/src/templates/add_contact_modal.js +++ b/src/templates/add_contact_modal.js @@ -1,5 +1,5 @@ import { html } from "lit-html"; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { modal_header_close_button } from "./buttons" diff --git a/src/templates/bookmarks_list.js b/src/templates/bookmarks_list.js index 276309a94..028120ce5 100644 --- a/src/templates/bookmarks_list.js +++ b/src/templates/bookmarks_list.js @@ -1,5 +1,5 @@ import { html } from "lit-html"; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; const bookmark_item = (o) => { diff --git a/src/templates/buttons.js b/src/templates/buttons.js index 72a48afab..a370a85a9 100644 --- a/src/templates/buttons.js +++ b/src/templates/buttons.js @@ -1,4 +1,4 @@ -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { html } from "lit-html"; diff --git a/src/templates/chat_message.js b/src/templates/chat_message.js index a2ea2e59c..f4e5aa9e3 100644 --- a/src/templates/chat_message.js +++ b/src/templates/chat_message.js @@ -1,5 +1,5 @@ import { html } from "lit-html"; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { renderAvatar } from './../templates/directives/avatar'; diff --git a/src/templates/chatbox_head.js b/src/templates/chatbox_head.js index ebf6c74d8..06c83ea3b 100644 --- a/src/templates/chatbox_head.js +++ b/src/templates/chatbox_head.js @@ -1,5 +1,5 @@ import { html } from "lit-html"; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { until } from 'lit-html/directives/until.js'; import avatar from "./avatar.js"; diff --git a/src/templates/chatroom_details_modal.js b/src/templates/chatroom_details_modal.js index 63f1a772e..c3ec44014 100644 --- a/src/templates/chatroom_details_modal.js +++ b/src/templates/chatroom_details_modal.js @@ -1,4 +1,4 @@ -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { html } from "lit-html"; import { modal_close_button, modal_header_close_button } from "./buttons" import { unsafeHTML } from 'lit-html/directives/unsafe-html.js'; diff --git a/src/templates/chatroom_head.js b/src/templates/chatroom_head.js index b0346f122..29ffc3e9e 100644 --- a/src/templates/chatroom_head.js +++ b/src/templates/chatroom_head.js @@ -1,5 +1,5 @@ import '../components/dropdown.js'; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { html } from "lit-html"; import { until } from 'lit-html/directives/until.js'; import { converse } from "@converse/headless/converse-core"; diff --git a/src/templates/chats_panel.js b/src/templates/chats_panel.js index ce3015aee..907587b5b 100644 --- a/src/templates/chats_panel.js +++ b/src/templates/chats_panel.js @@ -1,5 +1,5 @@ import { html } from "lit-html"; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; export default (o) => html`
diff --git a/src/templates/directives/retraction.js b/src/templates/directives/retraction.js index 4bf3e2401..f51128b0e 100644 --- a/src/templates/directives/retraction.js +++ b/src/templates/directives/retraction.js @@ -1,4 +1,4 @@ -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { api } from "@converse/headless/converse-core"; import { directive, html } from "lit-html"; diff --git a/src/templates/emoji_picker.js b/src/templates/emoji_picker.js index 4b19317cd..23446fda6 100644 --- a/src/templates/emoji_picker.js +++ b/src/templates/emoji_picker.js @@ -1,4 +1,4 @@ -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { _converse, converse, api } from "@converse/headless/converse-core"; import { html } from "lit-html"; diff --git a/src/templates/file_progress.js b/src/templates/file_progress.js index 39781b6ae..cb0c76af2 100644 --- a/src/templates/file_progress.js +++ b/src/templates/file_progress.js @@ -1,4 +1,4 @@ -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { html } from "lit-html"; import { renderAvatar } from './../templates/directives/avatar'; diff --git a/src/templates/image_modal.js b/src/templates/image_modal.js index f91f36109..7387325f8 100644 --- a/src/templates/image_modal.js +++ b/src/templates/image_modal.js @@ -1,5 +1,5 @@ import { html } from "lit-html"; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { modal_close_button, modal_header_close_button } from "./buttons" diff --git a/src/templates/list_chatrooms_modal.js b/src/templates/list_chatrooms_modal.js index a7fc804fb..58fed850c 100644 --- a/src/templates/list_chatrooms_modal.js +++ b/src/templates/list_chatrooms_modal.js @@ -1,4 +1,4 @@ -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { html } from "lit-html"; import { repeat } from 'lit-html/directives/repeat.js'; import { modal_close_button, modal_header_close_button } from "./buttons" diff --git a/src/templates/login_panel.js b/src/templates/login_panel.js index fca5d74ee..52cb39c44 100644 --- a/src/templates/login_panel.js +++ b/src/templates/login_panel.js @@ -1,5 +1,5 @@ import { html } from "lit-html"; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import tpl_spinner from './spinner.js'; diff --git a/src/templates/message_versions_modal.js b/src/templates/message_versions_modal.js index ada3714f3..fb7e54cfb 100644 --- a/src/templates/message_versions_modal.js +++ b/src/templates/message_versions_modal.js @@ -1,5 +1,5 @@ import { html } from "lit-html"; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import dayjs from 'dayjs'; import { modal_close_button, modal_header_close_button } from "./buttons" diff --git a/src/templates/moderator_tools_modal.js b/src/templates/moderator_tools_modal.js index 8113a6eb1..f88d31af7 100644 --- a/src/templates/moderator_tools_modal.js +++ b/src/templates/moderator_tools_modal.js @@ -1,5 +1,5 @@ import { html } from "lit-html"; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import spinner from "./spinner.js"; import { modal_header_close_button } from "./buttons" diff --git a/src/templates/muc_bookmark_form.js b/src/templates/muc_bookmark_form.js index 4ebda0822..a7afefc62 100644 --- a/src/templates/muc_bookmark_form.js +++ b/src/templates/muc_bookmark_form.js @@ -1,5 +1,5 @@ import { html } from "lit-html"; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; export default (o) => { diff --git a/src/templates/muc_config_form.js b/src/templates/muc_config_form.js index aed0e6502..f0a57d6f9 100644 --- a/src/templates/muc_config_form.js +++ b/src/templates/muc_config_form.js @@ -1,5 +1,5 @@ import { html } from "lit-html"; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { unsafeHTML } from 'lit-html/directives/unsafe-html.js'; export default (o) => { diff --git a/src/templates/muc_invite_modal.js b/src/templates/muc_invite_modal.js index 5675222b4..f43e806a6 100644 --- a/src/templates/muc_invite_modal.js +++ b/src/templates/muc_invite_modal.js @@ -1,5 +1,5 @@ import { html } from "lit-html"; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { modal_header_close_button } from "./buttons" diff --git a/src/templates/muc_password_form.js b/src/templates/muc_password_form.js index ee6188b6e..6b5e20e3c 100644 --- a/src/templates/muc_password_form.js +++ b/src/templates/muc_password_form.js @@ -1,5 +1,5 @@ import { html } from "lit-html"; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; export default (o) => { diff --git a/src/templates/muc_sidebar.js b/src/templates/muc_sidebar.js index b17cb0091..808d3a2ce 100644 --- a/src/templates/muc_sidebar.js +++ b/src/templates/muc_sidebar.js @@ -1,5 +1,5 @@ import { html } from "lit-html"; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import tpl_occupant from "./occupant.js"; diff --git a/src/templates/occupant.js b/src/templates/occupant.js index d00accebe..a8d6f0352 100644 --- a/src/templates/occupant.js +++ b/src/templates/occupant.js @@ -1,5 +1,5 @@ import { html } from "lit-html"; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; const occupant_title = (o) => { diff --git a/src/templates/profile.js b/src/templates/profile.js index 3b49e992f..79bd501f6 100644 --- a/src/templates/profile.js +++ b/src/templates/profile.js @@ -1,4 +1,4 @@ -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { api } from "@converse/headless/converse-core"; import { html } from "lit-html"; diff --git a/src/templates/profile_modal.js b/src/templates/profile_modal.js index a6b9d54b3..8a1a95b27 100644 --- a/src/templates/profile_modal.js +++ b/src/templates/profile_modal.js @@ -1,6 +1,6 @@ import "../components/image_picker.js"; import spinner from "./spinner.js"; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { _converse, converse } from "@converse/headless/converse-core"; import { html } from "lit-html"; import { modal_header_close_button } from "./buttons"; diff --git a/src/templates/prompt.js b/src/templates/prompt.js index f44c2451e..ca2ec6012 100644 --- a/src/templates/prompt.js +++ b/src/templates/prompt.js @@ -1,5 +1,5 @@ import { html } from "lit-html"; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; const tpl_field = (f) => html` diff --git a/src/templates/rooms_list.js b/src/templates/rooms_list.js index e86f51997..7490f3aeb 100644 --- a/src/templates/rooms_list.js +++ b/src/templates/rooms_list.js @@ -1,5 +1,5 @@ import { html } from "lit-html"; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; const bookmark = (o) => { diff --git a/src/templates/trimmed_chat.js b/src/templates/trimmed_chat.js index eec469183..cf8a18d83 100644 --- a/src/templates/trimmed_chat.js +++ b/src/templates/trimmed_chat.js @@ -1,5 +1,5 @@ import { html } from "lit-html"; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; export default (o) => { diff --git a/src/templates/user_details_modal.js b/src/templates/user_details_modal.js index 8ac82c920..2b814b260 100644 --- a/src/templates/user_details_modal.js +++ b/src/templates/user_details_modal.js @@ -1,4 +1,4 @@ -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { html } from "lit-html"; import avatar from "./avatar.js"; import { modal_close_button, modal_header_close_button } from "./buttons" diff --git a/src/templates/user_settings_modal.js b/src/templates/user_settings_modal.js index d023b9af2..f10ff36b0 100644 --- a/src/templates/user_settings_modal.js +++ b/src/templates/user_settings_modal.js @@ -1,6 +1,6 @@ import '../components/adhoc-commands.js'; import xss from "xss/dist/xss"; -import { __ } from '@converse/headless/i18n'; +import { __ } from '../i18n'; import { api } from "@converse/headless/converse-core"; import { html } from "lit-html"; import { modal_header_close_button } from "./buttons"