瀏覽代碼

Removes translateString and use translateElement.

Removing translateString forces using data-i18n attributes, to make sure we do not forget to set them. Missing data-i18n attributes is a problem with late loading where we can end up without translation, without text. Missing data-i18n attributes is also problem that strings will not be translated when changing language.
Fixes a bug in invite dialog, where remove password button was shown for non moderators.
master
damencho 8 年之前
父節點
當前提交
5217bf0bb8

+ 8
- 12
conference.js 查看文件

194
     }
194
     }
195
 
195
 
196
     if (showThankYou) {
196
     if (showThankYou) {
197
-        APP.UI.messageHandler.openMessageDialog(
198
-            null, "dialog.thankYou",
199
-            APP.translation.translateString(
200
-                "dialog.thankYou", {appName:interfaceConfig.APP_NAME}
201
-            )
202
-        );
197
+        APP.UI.messageHandler.openMessageDialog(null, null,
198
+            APP.translation.generateTranslationHTML(
199
+                "dialog.thankYou", {appName:interfaceConfig.APP_NAME}));
203
     }
200
     }
204
 
201
 
205
     if (!config.enableWelcomePage) {
202
     if (!config.enableWelcomePage) {
1050
                 // TrackErrors.GENERAL
1047
                 // TrackErrors.GENERAL
1051
                 // and any other
1048
                 // and any other
1052
                 let dialogTxt;
1049
                 let dialogTxt;
1053
-                let dialogTitle;
1050
+                let dialogTitleKey;
1054
 
1051
 
1055
                 if (err.name === TrackErrors.PERMISSION_DENIED) {
1052
                 if (err.name === TrackErrors.PERMISSION_DENIED) {
1056
                     dialogTxt = APP.translation.generateTranslationHTML(
1053
                     dialogTxt = APP.translation.generateTranslationHTML(
1057
                         "dialog.screenSharingPermissionDeniedError");
1054
                         "dialog.screenSharingPermissionDeniedError");
1058
-                    dialogTitle = APP.translation.generateTranslationHTML(
1059
-                        "dialog.error");
1055
+                    dialogTitleKey = "dialog.error";
1060
                 } else {
1056
                 } else {
1061
                     dialogTxt = APP.translation.generateTranslationHTML(
1057
                     dialogTxt = APP.translation.generateTranslationHTML(
1062
                         "dialog.failtoinstall");
1058
                         "dialog.failtoinstall");
1063
-                    dialogTitle = APP.translation.generateTranslationHTML(
1064
-                        "dialog.permissionDenied");
1059
+                    dialogTitleKey = "dialog.permissionDenied";
1065
                 }
1060
                 }
1066
 
1061
 
1067
-                APP.UI.messageHandler.openDialog(dialogTitle, dialogTxt, false);
1062
+                APP.UI.messageHandler.openDialog(
1063
+                    dialogTitleKey, dialogTxt, false);
1068
             });
1064
             });
1069
         } else {
1065
         } else {
1070
             createLocalTracks({ devices: ['video'] }).then(
1066
             createLocalTracks({ devices: ['video'] }).then(

+ 1
- 1
index.html 查看文件

174
                     </div>
174
                     </div>
175
                 </div>
175
                 </div>
176
                 <div id="contacts_container" class="sideToolbarContainer__inner">
176
                 <div id="contacts_container" class="sideToolbarContainer__inner">
177
-                    <div class="title" data-i18n="contactlist"></div>
177
+                    <div class="title" data-i18n="contactlist" data-i18n-options='{"pcount":"1"}'></div>
178
                     <ul id="contacts"></ul>
178
                     <ul id="contacts"></ul>
179
                 </div>
179
                 </div>
180
                 <div id="settings_container" class="sideToolbarContainer__inner">
180
                 <div id="settings_container" class="sideToolbarContainer__inner">

+ 2
- 2
lang/main.json 查看文件

1
 {
1
 {
2
-    "contactlist": "Participants",
2
+    "contactlist": "Participants (__pcount__)",
3
     "addParticipants": "Add Participants",
3
     "addParticipants": "Add Participants",
4
     "roomLocked": "Callers must enter a password",
4
     "roomLocked": "Callers must enter a password",
5
     "roomUnlocked": "Anyone with the link can join",
5
     "roomUnlocked": "Anyone with the link can join",
340
         "ATTACHED": "Attached",
340
         "ATTACHED": "Attached",
341
         "FETCH_SESSION_ID": "Obtaining session-id...",
341
         "FETCH_SESSION_ID": "Obtaining session-id...",
342
         "GOT_SESSION_ID": "Obtaining session-id... Done",
342
         "GOT_SESSION_ID": "Obtaining session-id... Done",
343
-        "GET_SESSION_ID_ERROR": "Get session-id error: ",
343
+        "GET_SESSION_ID_ERROR": "Get session-id error: __code__",
344
         "USER_CONNECTION_INTERRUPTED": "__displayName__ is having connectivity issues..."
344
         "USER_CONNECTION_INTERRUPTED": "__displayName__ is having connectivity issues..."
345
     },
345
     },
346
     "recording":
346
     "recording":

+ 10
- 28
modules/UI/UI.js 查看文件

75
  */
75
  */
76
 function promptDisplayName() {
76
 function promptDisplayName() {
77
     let labelKey = 'dialog.enterDisplayName';
77
     let labelKey = 'dialog.enterDisplayName';
78
-    let labelStr = APP.translation.translateString(labelKey);
79
-    let defaultNickMsg = APP.translation.translateString("defaultNickname");
80
     let message = (
78
     let message = (
81
         `<div class="input-control">
79
         `<div class="input-control">
82
-            <label data-i18n="${labelKey}" 
83
-                class="input-control__label">${labelStr}</label>
80
+            <label data-i18n="${labelKey}" class="input-control__label"></label>
84
             <input name="displayName" type="text"
81
             <input name="displayName" type="text"
85
                data-i18n="[placeholder]defaultNickname"
82
                data-i18n="[placeholder]defaultNickname"
86
                class="input-control__input"
83
                class="input-control__input"
87
-               placeholder="${defaultNickMsg}" autofocus>
84
+               autofocus>
88
          </div>`
85
          </div>`
89
     );
86
     );
90
 
87
 
166
  * Notify user that reservation error happened.
163
  * Notify user that reservation error happened.
167
  */
164
  */
168
 UI.notifyReservationError = function (code, msg) {
165
 UI.notifyReservationError = function (code, msg) {
169
-    var title = APP.translation.generateTranslationHTML(
170
-        "dialog.reservationError");
171
     var message = APP.translation.generateTranslationHTML(
166
     var message = APP.translation.generateTranslationHTML(
172
         "dialog.reservationErrorMsg", {code: code, msg: msg});
167
         "dialog.reservationErrorMsg", {code: code, msg: msg});
173
-    messageHandler.openDialog(title, message, true, {}, () => false);
168
+    messageHandler.openDialog(
169
+        "dialog.reservationError", message, true, {}, () => false);
174
 };
170
 };
175
 
171
 
176
 /**
172
 /**
189
 UI.notifyConferenceDestroyed = function (reason) {
185
 UI.notifyConferenceDestroyed = function (reason) {
190
     //FIXME: use Session Terminated from translation, but
186
     //FIXME: use Session Terminated from translation, but
191
     // 'reason' text comes from XMPP packet and is not translated
187
     // 'reason' text comes from XMPP packet and is not translated
192
-    const title
193
-        = APP.translation.generateTranslationHTML("dialog.sessTerminated");
194
-    messageHandler.openDialog(title, reason, true, {}, () => false);
188
+    messageHandler.openDialog(
189
+        "dialog.sessTerminated", reason, true, {}, () => false);
195
 };
190
 };
196
 
191
 
197
 /**
192
 /**
919
  * @param {string} stropheErrorMsg raw Strophe error message
914
  * @param {string} stropheErrorMsg raw Strophe error message
920
  */
915
  */
921
 UI.notifyConnectionFailed = function (stropheErrorMsg) {
916
 UI.notifyConnectionFailed = function (stropheErrorMsg) {
922
-    var title = APP.translation.generateTranslationHTML(
923
-        "dialog.error");
924
-
925
     var message;
917
     var message;
926
     if (stropheErrorMsg) {
918
     if (stropheErrorMsg) {
927
         message = APP.translation.generateTranslationHTML(
919
         message = APP.translation.generateTranslationHTML(
931
             "dialog.connectError");
923
             "dialog.connectError");
932
     }
924
     }
933
 
925
 
934
-    messageHandler.openDialog(title, message, true, {}, () => false);
926
+    messageHandler.openDialog("dialog.error", message, true, {}, () => false);
935
 };
927
 };
936
 
928
 
937
 
929
 
939
  * Notify user that maximum users limit has been reached.
931
  * Notify user that maximum users limit has been reached.
940
  */
932
  */
941
 UI.notifyMaxUsersLimitReached = function () {
933
 UI.notifyMaxUsersLimitReached = function () {
942
-    var title = APP.translation.generateTranslationHTML(
943
-        "dialog.error");
944
-
945
     var message = APP.translation.generateTranslationHTML(
934
     var message = APP.translation.generateTranslationHTML(
946
             "dialog.maxUsersLimitReached");
935
             "dialog.maxUsersLimitReached");
947
 
936
 
948
-    messageHandler.openDialog(title, message, true, {}, () => false);
937
+    messageHandler.openDialog("dialog.error", message, true, {}, () => false);
949
 };
938
 };
950
 
939
 
951
 /**
940
 /**
1112
  * Notify user that focus left the conference so page should be reloaded.
1101
  * Notify user that focus left the conference so page should be reloaded.
1113
  */
1102
  */
1114
 UI.notifyFocusLeft = function () {
1103
 UI.notifyFocusLeft = function () {
1115
-    let title = APP.translation.generateTranslationHTML(
1116
-        'dialog.serviceUnavailable'
1117
-    );
1118
     let msg = APP.translation.generateTranslationHTML(
1104
     let msg = APP.translation.generateTranslationHTML(
1119
         'dialog.jicofoUnavailable'
1105
         'dialog.jicofoUnavailable'
1120
     );
1106
     );
1121
     messageHandler.openDialog(
1107
     messageHandler.openDialog(
1122
-        title,
1108
+        'dialog.serviceUnavailable',
1123
         msg,
1109
         msg,
1124
         true, // persistent
1110
         true, // persistent
1125
         [{title: 'retry'}],
1111
         [{title: 'retry'}],
1284
         }
1270
         }
1285
     }
1271
     }
1286
 
1272
 
1287
-    let title = getTitleKey();
1288
-    let titleMsg = `<span data-i18n="${title}"></span>`;
1289
     let cameraJitsiTrackErrorMsg = cameraError
1273
     let cameraJitsiTrackErrorMsg = cameraError
1290
         ? JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP.camera[cameraError.name]
1274
         ? JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP.camera[cameraError.name]
1291
         : undefined;
1275
         : undefined;
1339
     deviceErrorDialog && deviceErrorDialog.close();
1323
     deviceErrorDialog && deviceErrorDialog.close();
1340
 
1324
 
1341
     deviceErrorDialog = messageHandler.openDialog(
1325
     deviceErrorDialog = messageHandler.openDialog(
1342
-        titleMsg,
1326
+        getTitleKey(),
1343
         message,
1327
         message,
1344
         false,
1328
         false,
1345
         {Ok: true},
1329
         {Ok: true},
1363
         }
1347
         }
1364
     );
1348
     );
1365
 
1349
 
1366
-    APP.translation.translateElement($(".jqibox"));
1367
-
1368
     function getTitleKey() {
1350
     function getTitleKey() {
1369
         let title = "dialog.error";
1351
         let title = "dialog.error";
1370
 
1352
 

+ 1
- 1
modules/UI/authentication/AuthHandler.js 查看文件

164
                 console.error('Auth on the fly failed', error);
164
                 console.error('Auth on the fly failed', error);
165
 
165
 
166
                 loginDialog.displayError(
166
                 loginDialog.displayError(
167
-                    'connection.GET_SESSION_ID_ERROR', code);
167
+                    'connection.GET_SESSION_ID_ERROR', {code: code});
168
             });
168
             });
169
         }, function (err) {
169
         }, function (err) {
170
             loginDialog.displayError(err);
170
             loginDialog.displayError(err);

+ 9
- 15
modules/UI/authentication/LoginDialog.js 查看文件

1
-/* global APP, config */
1
+/* global $, APP, config */
2
 
2
 
3
 /**
3
 /**
4
  * Build html for "password required" dialog.
4
  * Build html for "password required" dialog.
8
     let placeholder = config.hosts.authdomain
8
     let placeholder = config.hosts.authdomain
9
         ? "user identity"
9
         ? "user identity"
10
         : "user@domain.net";
10
         : "user@domain.net";
11
-    let passRequiredMsg = APP.translation.translateString(
12
-        "dialog.passwordRequired"
13
-    );
14
     return `
11
     return `
15
-        <h2 data-i18n="dialog.passwordRequired">${passRequiredMsg}</h2>
12
+        <h2 data-i18n="dialog.passwordRequired"></h2>
16
         <input name="username" type="text" placeholder=${placeholder} autofocus>
13
         <input name="username" type="text" placeholder=${placeholder} autofocus>
17
         <input name="password" type="password"
14
         <input name="password" type="password"
18
                data-i18n="[placeholder]dialog.userPassword"
15
                data-i18n="[placeholder]dialog.userPassword"
68
         value: true
65
         value: true
69
     }];
66
     }];
70
     let finishedButtons = [{
67
     let finishedButtons = [{
71
-        title: APP.translation.translateString('dialog.retry'),
68
+        title: APP.translation.generateTranslationHTML('dialog.retry'),
72
         value: 'retry'
69
         value: 'retry'
73
     }];
70
     }];
74
 
71
 
129
      * Displays error message in 'finished' state which allows either to cancel
126
      * Displays error message in 'finished' state which allows either to cancel
130
      * or retry.
127
      * or retry.
131
      * @param messageKey the key to the message to be displayed.
128
      * @param messageKey the key to the message to be displayed.
132
-     * @param code the code error (optional)
129
+     * @param options the options to the error message (optional)
133
      */
130
      */
134
-    this.displayError = function (messageKey, code) {
131
+    this.displayError = function (messageKey, options) {
135
 
132
 
136
         let finishedState = connDialog.getState('finished');
133
         let finishedState = connDialog.getState('finished');
137
 
134
 
138
         let errorMessageElem = finishedState.find('#errorMessage');
135
         let errorMessageElem = finishedState.find('#errorMessage');
139
         errorMessageElem.attr("data-i18n", messageKey);
136
         errorMessageElem.attr("data-i18n", messageKey);
140
-        errorMessageElem.text(
141
-            APP.translation.translateString(messageKey) + (code ? code : ''));
137
+
138
+        APP.translation.translateElement($(errorMessageElem), options);
142
 
139
 
143
         connDialog.goToState('finished');
140
         connDialog.goToState('finished');
144
     };
141
     };
152
 
149
 
153
         let connectionStatus = connectingState.find('#connectionStatus');
150
         let connectionStatus = connectingState.find('#connectionStatus');
154
         connectionStatus.attr("data-i18n", messageKey);
151
         connectionStatus.attr("data-i18n", messageKey);
155
-        connectionStatus.text(APP.translation.translateString(messageKey));
152
+        APP.translation.translateElement($(connectionStatus));
156
     };
153
     };
157
 
154
 
158
     /**
155
     /**
206
      * @returns dialog
203
      * @returns dialog
207
      */
204
      */
208
     showAuthRequiredDialog: function (roomName, onAuthNow) {
205
     showAuthRequiredDialog: function (roomName, onAuthNow) {
209
-        var title = APP.translation.generateTranslationHTML(
210
-            "dialog.WaitingForHost"
211
-        );
212
         var msg = APP.translation.generateTranslationHTML(
206
         var msg = APP.translation.generateTranslationHTML(
213
             "dialog.WaitForHostMsg", {room: roomName}
207
             "dialog.WaitForHostMsg", {room: roomName}
214
         );
208
         );
219
         var buttons = [{title: buttonTxt, value: "authNow"}];
213
         var buttons = [{title: buttonTxt, value: "authNow"}];
220
 
214
 
221
         return APP.UI.messageHandler.openDialog(
215
         return APP.UI.messageHandler.openDialog(
222
-            title,
216
+            "dialog.WaitingForHost",
223
             msg,
217
             msg,
224
             true,
218
             true,
225
             buttons,
219
             buttons,

+ 3
- 5
modules/UI/feedback/FeedbackWindow.js 查看文件

35
  * @returns {string} the contructed html string
35
  * @returns {string} the contructed html string
36
  */
36
  */
37
 function createRateFeedbackHTML() {
37
 function createRateFeedbackHTML() {
38
-    let feedbackHelp = APP.translation.translateString('dialog.feedbackHelp');
39
 
38
 
40
     let starClassName = (interfaceConfig.ENABLE_FEEDBACK_ANIMATION)
39
     let starClassName = (interfaceConfig.ENABLE_FEEDBACK_ANIMATION)
41
         ? "icon-star-full shake-rotate"
40
         ? "icon-star-full shake-rotate"
67
                 </div>
66
                 </div>
68
             </div>
67
             </div>
69
             <div class="details">
68
             <div class="details">
70
-                <textarea id="feedbackTextArea" class="input-control__input"
71
-                    placeholder="${ feedbackHelp }" 
69
+                <textarea id="feedbackTextArea" class="input-control__input" 
72
                     data-i18n="[placeholder]dialog.feedbackHelp"></textarea>
70
                     data-i18n="[placeholder]dialog.feedbackHelp"></textarea>
73
             </div>
71
             </div>
74
         </form>`;
72
         </form>`;
148
         this.submitted = false;
146
         this.submitted = false;
149
         this.onCloseCallback = function() {};
147
         this.onCloseCallback = function() {};
150
 
148
 
151
-        this.setDefoulOptions();
149
+        this.setDefaulOptions();
152
     }
150
     }
153
 
151
 
154
-    setDefoulOptions() {
152
+    setDefaulOptions() {
155
         var self = this;
153
         var self = this;
156
 
154
 
157
         this.options = {
155
         this.options = {

+ 1
- 3
modules/UI/invite/AskForPassword.js 查看文件

8
  */
8
  */
9
 export default function askForPassword () {
9
 export default function askForPassword () {
10
     let titleKey = "dialog.passwordRequired";
10
     let titleKey = "dialog.passwordRequired";
11
-    let passMsg = APP.translation.translateString("dialog.password");
12
     let msgString = `
11
     let msgString = `
13
         <input name="lockKey" type="text"
12
         <input name="lockKey" type="text"
14
                data-i18n="[placeholder]dialog.password"
13
                data-i18n="[placeholder]dialog.password"
15
-               placeholder="${passMsg}" autofocus>
16
-    `;
14
+               autofocus>`;
17
     return new Promise(function (resolve, reject) {
15
     return new Promise(function (resolve, reject) {
18
         APP.UI.messageHandler.openTwoButtonDialog({
16
         APP.UI.messageHandler.openTwoButtonDialog({
19
             titleKey,
17
             titleKey,

+ 4
- 2
modules/UI/invite/Invite.js 查看文件

203
      * @param isLocked
203
      * @param isLocked
204
      */
204
      */
205
     setLockedFromElsewhere(isLocked) {
205
     setLockedFromElsewhere(isLocked) {
206
-        let oldLockState = this.roomLocker.lockedElsewhere;
207
-        if (oldLockState !== isLocked) {
206
+        // isLocked can be 1, true or false
207
+        let newLockState = (isLocked === 1) || isLocked;
208
+        let oldLockState = this.roomLocker.isLocked;
209
+        if (oldLockState !== newLockState) {
208
             this.roomLocker.lockedElsewhere = isLocked;
210
             this.roomLocker.lockedElsewhere = isLocked;
209
             APP.UI.emitEvent(UIEvents.TOGGLE_ROOM_LOCK);
211
             APP.UI.emitEvent(UIEvents.TOGGLE_ROOM_LOCK);
210
             this.updateView();
212
             this.updateView();

+ 28
- 55
modules/UI/invite/InviteDialogView.js 查看文件

15
  */
15
  */
16
 export default class InviteDialogView {
16
 export default class InviteDialogView {
17
     constructor(model) {
17
     constructor(model) {
18
-        let inviteAttributesKey = 'inviteUrlDefaultMsg';
19
-        let title = APP.translation.translateString(inviteAttributesKey);
20
-
21
         this.unlockHint = "unlockHint";
18
         this.unlockHint = "unlockHint";
22
         this.lockHint = "lockHint";
19
         this.lockHint = "lockHint";
23
         this.model = model;
20
         this.model = model;
24
 
21
 
25
         if (this.model.inviteUrl === null) {
22
         if (this.model.inviteUrl === null) {
26
-            this.inviteAttributes = (
27
-                `data-i18n="[value]${inviteAttributesKey}" value="${title}"`
28
-            );
23
+            this.inviteAttributes = `data-i18n="[value]inviteUrlDefaultMsg"`;
29
         } else {
24
         } else {
30
-            let encodedInviteUrl = this.model.getEncodedInviteUrl();
31
-            this.inviteAttributes = `value="${encodedInviteUrl}"`;
25
+            this.inviteAttributes
26
+                = `value="${this.model.getEncodedInviteUrl()}"`;
32
         }
27
         }
33
 
28
 
34
         this.initDialog();
29
         this.initDialog();
99
         let {
94
         let {
100
             titleKey
95
             titleKey
101
         } = this.dialog;
96
         } = this.dialog;
102
-        let doneKey = 'dialog.done';
103
-        let doneMsg = APP.translation.translateString(doneKey);
97
+        let doneMsg = APP.translation.generateTranslationHTML('dialog.done');
104
         let states = {};
98
         let states = {};
105
         let buttons = {};
99
         let buttons = {};
106
         buttons[`${doneMsg}`] = true;
100
         buttons[`${doneMsg}`] = true;
124
      * @returns {string}
118
      * @returns {string}
125
      */
119
      */
126
     getShareLinkBlock() {
120
     getShareLinkBlock() {
127
-        let copyKey = 'dialog.copy';
128
-        let copyText = APP.translation.translateString(copyKey);
129
-        let roomLockDescKey = 'dialog.roomLocked';
130
-        let roomLockDesc = APP.translation.translateString(roomLockDescKey);
131
-        let roomUnlockKey = 'roomUnlocked';
132
-        let roomUnlock = APP.translation.translateString(roomUnlockKey);
133
         let classes = 'button-control button-control_light copyInviteLink';
121
         let classes = 'button-control button-control_light copyInviteLink';
134
-        let title = APP.translation.translateString(this.dialog.titleKey);
135
         return (
122
         return (
136
             `<div class="input-control">
123
             `<div class="input-control">
137
                 <label class="input-control__label" for="inviteLinkRef"
124
                 <label class="input-control__label" for="inviteLinkRef"
138
-                    data-i18n="${this.dialog.titleKey}">
139
-                        ${title}
140
-                </label>
125
+                    data-i18n="${this.dialog.titleKey}"></label>
141
                 <div class="input-control__container">
126
                 <div class="input-control__container">
142
                     <input class="input-control__input inviteLink"
127
                     <input class="input-control__input inviteLink"
143
                            id="inviteLinkRef" type="text"
128
                            id="inviteLinkRef" type="text"
144
                            ${this.inviteAttributes} readonly>
129
                            ${this.inviteAttributes} readonly>
145
-                    <button data-i18n="${copyKey}"
146
-                            class="${classes}">
147
-                        ${copyText}
148
-                    </button>
130
+                    <button data-i18n="dialog.copy" class="${classes}"></button>
149
                 </div>
131
                 </div>
150
                 <p class="input-control__hint ${this.lockHint}">
132
                 <p class="input-control__hint ${this.lockHint}">
151
                    <span class="icon-security-locked"></span>
133
                    <span class="icon-security-locked"></span>
152
-                   <span data-i18n="${roomLockDescKey}">${roomLockDesc}</span>
134
+                   <span data-i18n="dialog.roomLocked"></span>
153
                 </p>
135
                 </p>
154
                 <p class="input-control__hint ${this.unlockHint}">
136
                 <p class="input-control__hint ${this.unlockHint}">
155
                    <span class="icon-security"></span>
137
                    <span class="icon-security"></span>
156
-                   <span data-i18n="${roomUnlockKey}">${roomUnlock}</span>
138
+                   <span data-i18n="roomUnlocked"></span>
157
                 </p>
139
                 </p>
158
             </div>`
140
             </div>`
159
         );
141
         );
164
      * @returns {string}
146
      * @returns {string}
165
      */
147
      */
166
     getAddPasswordBlock() {
148
     getAddPasswordBlock() {
167
-        let addPassKey = 'dialog.addPassword';
168
-        let addPassText = APP.translation.translateString(addPassKey);
169
-        let addKey = 'dialog.add';
170
-        let addText = APP.translation.translateString(addKey);
171
-        let hintKey = 'dialog.createPassword';
172
-        let hintMsg = APP.translation.translateString(hintKey);
173
         let html;
149
         let html;
174
 
150
 
175
         if (this.model.isModerator) {
151
         if (this.model.isModerator) {
176
             html = (`
152
             html = (`
177
             <div class="input-control">
153
             <div class="input-control">
178
-                <label class="input-control__label
179
-                       for="newPasswordInput"
180
-                       data-i18n="${addPassKey}">${addPassText}</label>
154
+                <label class="input-control__label"
155
+                       for="newPasswordInput" data-i18n="dialog.addPassword">
156
+               </label>
181
                 <div class="input-control__container">
157
                 <div class="input-control__container">
182
                     <input class="input-control__input" id="newPasswordInput"
158
                     <input class="input-control__input" id="newPasswordInput"
183
-                           type="text" placeholder="${hintMsg}">
159
+                           type="text" data-i18n="dialog.createPassword">
184
                     <button id="addPasswordBtn" id="inviteDialogAddPassword"
160
                     <button id="addPasswordBtn" id="inviteDialogAddPassword"
185
-                            disabled data-i18n="${addKey}"
161
+                            disabled data-i18n="dialog.add"
186
                             class="button-control button-control_light">
162
                             class="button-control button-control_light">
187
-                        ${addText}
188
                     </button>
163
                     </button>
189
                 </div>
164
                 </div>
190
             </div>
165
             </div>
202
      */
177
      */
203
     getPasswordBlock() {
178
     getPasswordBlock() {
204
         let { password, isModerator } = this.model;
179
         let { password, isModerator } = this.model;
205
-        let removePassKey = 'dialog.removePassword';
206
-        let removePassText = APP.translation.translateString(removePassKey);
207
-        let currentPassKey = 'dialog.currentPassword';
208
-        let currentPassText = APP.translation.translateString(currentPassKey);
209
-        let passwordKey = "dialog.passwordLabel";
210
-        let passwordText = APP.translation.translateString(passwordKey);
211
 
180
 
212
         if (isModerator) {
181
         if (isModerator) {
213
             return (`
182
             return (`
214
                 <div class="input-control">
183
                 <div class="input-control">
215
                     <label class="input-control__label"
184
                     <label class="input-control__label"
216
-                           data-i18n="${passwordKey}">${passwordText}</label>
185
+                           data-i18n="dialog.passwordLabel"></label>
217
                     <div class="input-control__container">
186
                     <div class="input-control__container">
218
-                        <p class="input-control__text"
219
-                           data-i18n="${currentPassKey}">
220
-                            ${currentPassText}
187
+                        <p>
188
+                            <span class="input-control__text"
189
+                                  data-i18n="dialog.currentPassword"></span>
221
                             <span id="inviteDialogPassword"
190
                             <span id="inviteDialogPassword"
222
                                   class="input-control__em">
191
                                   class="input-control__em">
223
                                 ${password}
192
                                 ${password}
225
                         </p>
194
                         </p>
226
                         <a class="link input-control__right"
195
                         <a class="link input-control__right"
227
                            id="inviteDialogRemovePassword"
196
                            id="inviteDialogRemovePassword"
228
-                           data-i18n="${removePassKey}">
229
-                           ${removePassText}
230
-                       </a>
197
+                           data-i18n="dialog.removePassword"></a>
231
                     </div>
198
                     </div>
232
                 </div>
199
                 </div>
233
             `);
200
             `);
349
      */
316
      */
350
     updateView() {
317
     updateView() {
351
         let pass = this.model.getPassword();
318
         let pass = this.model.getPassword();
352
-        if (!pass)
353
-            pass = APP.translation.translateString("passwordSetRemotely");
319
+        if (this.model.getRoomLocker().lockedElsewhere || !pass)
320
+            $('#inviteDialogPassword').attr("data-i18n", "passwordSetRemotely");
321
+        else
322
+            $('#inviteDialogPassword').text(pass);
323
+
324
+        // if we are not moderator we cannot remove password
325
+        if (APP.conference.isModerator)
326
+            $('#inviteDialogRemovePassword').show();
327
+        else
328
+            $('#inviteDialogRemovePassword').hide();
354
 
329
 
355
-        $('#inviteDialogPassword').attr("data-i18n", "passwordSetRemotely");
356
-        $('#inviteDialogPassword').text(pass);
357
         $('#newPasswordInput').val('');
330
         $('#newPasswordInput').val('');
358
         this.disableAddPassIfInputEmpty();
331
         this.disableAddPassIfInputEmpty();
359
 
332
 

+ 6
- 10
modules/UI/recording/Recording.js 查看文件

41
  * @returns {Promise}
41
  * @returns {Promise}
42
  */
42
  */
43
 function _requestLiveStreamId() {
43
 function _requestLiveStreamId() {
44
-    const msg = APP.translation.generateTranslationHTML("dialog.liveStreaming");
45
-    const token = APP.translation.translateString("dialog.streamKey");
46
     const cancelButton
44
     const cancelButton
47
         = APP.translation.generateTranslationHTML("dialog.Cancel");
45
         = APP.translation.generateTranslationHTML("dialog.Cancel");
48
     const backButton = APP.translation.generateTranslationHTML("dialog.Back");
46
     const backButton = APP.translation.generateTranslationHTML("dialog.Back");
55
     return new Promise(function (resolve, reject) {
53
     return new Promise(function (resolve, reject) {
56
         dialog = APP.UI.messageHandler.openDialogWithStates({
54
         dialog = APP.UI.messageHandler.openDialogWithStates({
57
             state0: {
55
             state0: {
58
-                title: msg,
56
+                titleKey: "dialog.liveStreaming",
59
                 html:
57
                 html:
60
                     `<input name="streamId" type="text"
58
                     `<input name="streamId" type="text"
61
                     data-i18n="[placeholder]dialog.streamKey"
59
                     data-i18n="[placeholder]dialog.streamKey"
62
-                    placeholder="${token}" autofocus>`,
60
+                    autofocus>`,
63
                 persistent: false,
61
                 persistent: false,
64
                 buttons: [
62
                 buttons: [
65
                     {title: cancelButton, value: false},
63
                     {title: cancelButton, value: false},
89
             },
87
             },
90
 
88
 
91
             state1: {
89
             state1: {
92
-                title: msg,
90
+                titleKey: "dialog.liveStreaming",
93
                 html: streamIdRequired,
91
                 html: streamIdRequired,
94
                 persistent: false,
92
                 persistent: false,
95
                 buttons: [
93
                 buttons: [
122
  */
120
  */
123
 function _requestRecordingToken () {
121
 function _requestRecordingToken () {
124
     let titleKey = "dialog.recordingToken";
122
     let titleKey = "dialog.recordingToken";
125
-    let token = APP.translation.translateString("dialog.token");
126
     let messageString = (
123
     let messageString = (
127
         `<input name="recordingToken" type="text"
124
         `<input name="recordingToken" type="text"
128
                 data-i18n="[placeholder]dialog.token"
125
                 data-i18n="[placeholder]dialog.token"
129
-                placeholder="${token}" autofocus>`
126
+                autofocus>`
130
     );
127
     );
131
     return new Promise(function (resolve, reject) {
128
     return new Promise(function (resolve, reject) {
132
         dialog = APP.UI.messageHandler.openTwoButtonDialog({
129
         dialog = APP.UI.messageHandler.openTwoButtonDialog({
297
 
294
 
298
         selector.addClass(this.baseClass);
295
         selector.addClass(this.baseClass);
299
         selector.attr("data-i18n", "[content]" + this.recordingButtonTooltip);
296
         selector.attr("data-i18n", "[content]" + this.recordingButtonTooltip);
300
-        selector.attr("content",
301
-            APP.translation.translateString(this.recordingButtonTooltip));
297
+        APP.translation.translateElement(selector);
302
 
298
 
303
         var self = this;
299
         var self = this;
304
         selector.click(function () {
300
         selector.click(function () {
505
         moveToCorner(labelSelector, !isCentered);
501
         moveToCorner(labelSelector, !isCentered);
506
 
502
 
507
         labelTextSelector.attr("data-i18n", textKey);
503
         labelTextSelector.attr("data-i18n", textKey);
508
-        labelTextSelector.text(APP.translation.translateString(textKey));
504
+        APP.translation.translateElement(labelSelector);
509
     },
505
     },
510
 
506
 
511
     /**
507
     /**

+ 4
- 8
modules/UI/shared_video/SharedVideo.js 查看文件

750
  */
750
  */
751
 function requestVideoLink() {
751
 function requestVideoLink() {
752
     let i18n = APP.translation;
752
     let i18n = APP.translation;
753
-    const title = i18n.generateTranslationHTML("dialog.shareVideoTitle");
754
     const cancelButton = i18n.generateTranslationHTML("dialog.Cancel");
753
     const cancelButton = i18n.generateTranslationHTML("dialog.Cancel");
755
     const shareButton = i18n.generateTranslationHTML("dialog.Share");
754
     const shareButton = i18n.generateTranslationHTML("dialog.Share");
756
     const backButton = i18n.generateTranslationHTML("dialog.Back");
755
     const backButton = i18n.generateTranslationHTML("dialog.Back");
757
     const linkError
756
     const linkError
758
         = i18n.generateTranslationHTML("dialog.shareVideoLinkError");
757
         = i18n.generateTranslationHTML("dialog.shareVideoLinkError");
759
-    const i18nOptions = {url: defaultSharedVideoLink};
760
-    const defaultUrl = i18n.translateString("defaultLink", i18nOptions);
761
 
758
 
762
     return new Promise(function (resolve, reject) {
759
     return new Promise(function (resolve, reject) {
763
         dialog = APP.UI.messageHandler.openDialogWithStates({
760
         dialog = APP.UI.messageHandler.openDialogWithStates({
764
             state0: {
761
             state0: {
765
-                title: title,
762
+                titleKey: "dialog.shareVideoTitle",
766
                 html:  `
763
                 html:  `
767
                     <input name="sharedVideoUrl" type="text"
764
                     <input name="sharedVideoUrl" type="text"
768
                            data-i18n="[placeholder]defaultLink"
765
                            data-i18n="[placeholder]defaultLink"
769
-                           data-i18n-options="${JSON.stringify(i18nOptions)}"
770
-                           placeholder="${defaultUrl}"
771
                            autofocus>`,
766
                            autofocus>`,
772
                 persistent: false,
767
                 persistent: false,
773
                 buttons: [
768
                 buttons: [
802
             },
797
             },
803
 
798
 
804
             state1: {
799
             state1: {
805
-                title: title,
800
+                titleKey: "dialog.shareVideoTitle",
806
                 html: linkError,
801
                 html: linkError,
807
                 persistent: false,
802
                 persistent: false,
808
                 buttons: [
803
                 buttons: [
825
             close: function () {
820
             close: function () {
826
                 dialog = null;
821
                 dialog = null;
827
             }
822
             }
823
+        }, {
824
+            url: defaultSharedVideoLink
828
         });
825
         });
829
-
830
     });
826
     });
831
 }
827
 }

+ 10
- 16
modules/UI/side_pannels/contactlist/ContactListView.js 查看文件

21
 
21
 
22
     $("#numberOfParticipants").text(numberOfContacts);
22
     $("#numberOfParticipants").text(numberOfContacts);
23
 
23
 
24
-    $("#contacts_container>div.title").text(
25
-        APP.translation.translateString("contactlist")
26
-            + ' (' + numberOfContacts + ')');
24
+    APP.translation.translateElement(
25
+        $("#contacts_container>div.title"), {pcount: numberOfContacts});
27
 }
26
 }
28
 
27
 
29
 /**
28
 /**
50
         p.innerHTML = displayName;
49
         p.innerHTML = displayName;
51
     } else if(key) {
50
     } else if(key) {
52
         p.setAttribute("data-i18n",key);
51
         p.setAttribute("data-i18n",key);
53
-        p.innerHTML = APP.translation.translateString(key);
54
     }
52
     }
55
 
53
 
56
     return p;
54
     return p;
82
      */
80
      */
83
     addInviteButton() {
81
     addInviteButton() {
84
         let container = document.getElementById('contacts_container');
82
         let container = document.getElementById('contacts_container');
85
-        let title = container.firstElementChild;
86
 
83
 
87
-        let htmlLayout =  this.getInviteButtonLayout();
88
-        title.insertAdjacentHTML('afterend', htmlLayout);
84
+        container.firstElementChild // this is the title
85
+            .insertAdjacentHTML('afterend', this.getInviteButtonLayout());
86
+
87
+        APP.translation.translateElement($(container));
89
         $(document).on('click', '#addParticipantsBtn', () => {
88
         $(document).on('click', '#addParticipantsBtn', () => {
90
             APP.UI.emitEvent(UIEvents.INVITE_CLICKED);
89
             APP.UI.emitEvent(UIEvents.INVITE_CLICKED);
91
         });
90
         });
97
         let classes = 'button-control button-control_primary';
96
         let classes = 'button-control button-control_primary';
98
         classes += ' button-control_full-width';
97
         classes += ' button-control_full-width';
99
         let key = 'addParticipants';
98
         let key = 'addParticipants';
100
-        let text = APP.translation.translateString(key);
101
 
99
 
102
         let lockedHtml = this.getLockDescriptionLayout(this.lockKey);
100
         let lockedHtml = this.getLockDescriptionLayout(this.lockKey);
103
         let unlockedHtml = this.getLockDescriptionLayout(this.unlockKey);
101
         let unlockedHtml = this.getLockDescriptionLayout(this.unlockKey);
104
 
102
 
105
-        let html = (
103
+        return (
106
             `<div class="sideToolbarBlock first">
104
             `<div class="sideToolbarBlock first">
107
                 <button id="addParticipantsBtn" 
105
                 <button id="addParticipantsBtn" 
108
                          data-i18n="${key}" 
106
                          data-i18n="${key}" 
109
-                         class="${classes}">
110
-                    ${text}
111
-                </button>
107
+                         class="${classes}"></button>
112
                 <div>
108
                 <div>
113
                     ${lockedHtml}
109
                     ${lockedHtml}
114
                     ${unlockedHtml}
110
                     ${unlockedHtml}
115
                 </div>
111
                 </div>
116
             </div>`);
112
             </div>`);
117
-
118
-        return html;
119
     },
113
     },
120
     /**
114
     /**
121
      * Adds layout for lock description
115
      * Adds layout for lock description
122
      */
116
      */
123
     getLockDescriptionLayout(key) {
117
     getLockDescriptionLayout(key) {
124
         let classes = "input-control__hint input-control_full-width";
118
         let classes = "input-control__hint input-control_full-width";
125
-        let description = APP.translation.translateString(key);
126
         let padlockSuffix = '';
119
         let padlockSuffix = '';
127
         if (key === this.lockKey) {
120
         if (key === this.lockKey) {
128
             padlockSuffix = '-locked';
121
             padlockSuffix = '-locked';
130
 
123
 
131
         return `<p id="contactList${key}" class="${classes}">
124
         return `<p id="contactList${key}" class="${classes}">
132
                     <span class="icon-security${padlockSuffix}"></span>
125
                     <span class="icon-security${padlockSuffix}"></span>
133
-                    <span data-i18n="${key}">${description}</span>
126
+                    <span data-i18n="${key}"></span>
134
                 </p>`;
127
                 </p>`;
135
     },
128
     },
136
     /**
129
     /**
198
             createDisplayNameParagraph(
191
             createDisplayNameParagraph(
199
                 isLocal ? interfaceConfig.DEFAULT_LOCAL_DISPLAY_NAME : null,
192
                 isLocal ? interfaceConfig.DEFAULT_LOCAL_DISPLAY_NAME : null,
200
                 isLocal ? null : interfaceConfig.DEFAULT_REMOTE_DISPLAY_NAME));
193
                 isLocal ? null : interfaceConfig.DEFAULT_REMOTE_DISPLAY_NAME));
194
+        APP.translation.translateElement($(newContact));
201
 
195
 
202
         if (APP.conference.isLocalId(id)) {
196
         if (APP.conference.isLocalId(id)) {
203
             contactlist.prepend(newContact);
197
             contactlist.prepend(newContact);

+ 4
- 2
modules/UI/util/JitsiPopover.js 查看文件

1
-/* global $ */
1
+/* global $, APP */
2
 var JitsiPopover = (function () {
2
 var JitsiPopover = (function () {
3
     /**
3
     /**
4
      * Constructs new JitsiPopover and attaches it to the element
4
      * Constructs new JitsiPopover and attaches it to the element
76
      */
76
      */
77
     JitsiPopover.prototype.createPopover = function () {
77
     JitsiPopover.prototype.createPopover = function () {
78
         $("body").append(this.template);
78
         $("body").append(this.template);
79
-        $(".jitsipopover > .jitsipopover-content").html(this.options.content);
79
+        let popoverElem = $(".jitsipopover > .jitsipopover-content");
80
+        popoverElem.html(this.options.content);
81
+        APP.translation.translateElement(popoverElem);
80
         var self = this;
82
         var self = this;
81
         $(".jitsipopover").on("mouseenter", function () {
83
         $(".jitsipopover").on("mouseenter", function () {
82
             self.popoverIsHovered = true;
84
             self.popoverIsHovered = true;

+ 20
- 14
modules/UI/util/MessageHandler.js 查看文件

45
             message = APP.translation.generateTranslationHTML(messageKey);
45
             message = APP.translation.generateTranslationHTML(messageKey);
46
         }
46
         }
47
 
47
 
48
-        return $.prompt(message, {
48
+        let dialog = $.prompt(message, {
49
             title: this._getFormattedTitleString(titleKey),
49
             title: this._getFormattedTitleString(titleKey),
50
             persistent: false,
50
             persistent: false,
51
             promptspeed: 0,
51
             promptspeed: 0,
55
                     closeFunction(e, v, m, f);
55
                     closeFunction(e, v, m, f);
56
             }
56
             }
57
         });
57
         });
58
+        APP.translation.translateElement(dialog);
59
+        return dialog;
58
     },
60
     },
59
     /**
61
     /**
60
      * Shows a message to the user with two buttons: first is given as a
62
      * Shows a message to the user with two buttons: first is given as a
137
                 }
139
                 }
138
             }
140
             }
139
         });
141
         });
142
+        APP.translation.translateElement(twoButtonDialog);
140
         return twoButtonDialog;
143
         return twoButtonDialog;
141
     },
144
     },
142
 
145
 
177
             args.closeText = '';
180
             args.closeText = '';
178
         }
181
         }
179
 
182
 
180
-        return new Impromptu(msgString, args);
183
+        let dialog = new Impromptu(msgString, args);
184
+        APP.translation.translateElement(dialog.getPrompt());
185
+        return dialog;
181
     },
186
     },
182
 
187
 
183
     /**
188
     /**
189
         let $titleString = $('<h2>');
194
         let $titleString = $('<h2>');
190
         $titleString.addClass('aui-dialog2-header-main');
195
         $titleString.addClass('aui-dialog2-header-main');
191
         $titleString.attr('data-i18n',titleKey);
196
         $titleString.attr('data-i18n',titleKey);
192
-        $titleString.append(APP.translation.translateString(titleKey));
193
         return $('<div>').append($titleString).html();
197
         return $('<div>').append($titleString).html();
194
     },
198
     },
195
 
199
 
224
      * Shows a dialog with different states to the user.
228
      * Shows a dialog with different states to the user.
225
      *
229
      *
226
      * @param statesObject object containing all the states of the dialog.
230
      * @param statesObject object containing all the states of the dialog.
231
+     * @param options impromptu options
232
+     * @param translateOptions options passed to translation
227
      */
233
      */
228
-    openDialogWithStates: function (statesObject, options) {
234
+    openDialogWithStates: function (statesObject, options, translateOptions) {
229
         if (!popupEnabled)
235
         if (!popupEnabled)
230
             return;
236
             return;
231
         let { classes, size } = options;
237
         let { classes, size } = options;
240
                     = this._getFormattedTitleString(currentState.titleKey);
246
                     = this._getFormattedTitleString(currentState.titleKey);
241
             }
247
             }
242
         }
248
         }
243
-        return new Impromptu(statesObject, options);
249
+        let dialog = new Impromptu(statesObject, options);
250
+        APP.translation.translateElement(dialog.getPrompt(), translateOptions);
251
+        return dialog;
244
     },
252
     },
245
 
253
 
246
     /**
254
     /**
329
         if (displayName) {
337
         if (displayName) {
330
             displayNameSpan += ">" + UIUtil.escapeHtml(displayName);
338
             displayNameSpan += ">" + UIUtil.escapeHtml(displayName);
331
         } else {
339
         } else {
332
-            displayNameSpan += "data-i18n='" + displayNameKey +
333
-                "'>" + APP.translation.translateString(displayNameKey);
340
+            displayNameSpan += "data-i18n='" + displayNameKey + "'>";
334
         }
341
         }
335
         displayNameSpan += "</span>";
342
         displayNameSpan += "</span>";
336
-        return toastr.info(
343
+        let element = toastr.info(
337
             displayNameSpan + '<br>' +
344
             displayNameSpan + '<br>' +
338
             '<span class=' + cls + ' data-i18n="' + messageKey + '"' +
345
             '<span class=' + cls + ' data-i18n="' + messageKey + '"' +
339
                 (messageArguments?
346
                 (messageArguments?
340
-                    " data-i18n-options='" + JSON.stringify(messageArguments)
341
-                        + "'"
342
-                    : "") + ">" +
343
-            APP.translation.translateString(messageKey,
344
-                messageArguments) +
345
-            '</span>', null, options);
347
+                    " data-i18n-options='"
348
+                        + JSON.stringify(messageArguments) + "'"
349
+                    : "") + "></span>", null, options);
350
+        APP.translation.translateElement(element);
351
+        return element;
346
     },
352
     },
347
 
353
 
348
     /**
354
     /**

+ 13
- 34
modules/UI/videolayout/ConnectionIndicator.js 查看文件

1
-/* global APP, $, config */
1
+/* global $, config */
2
 /* jshint -W101 */
2
 /* jshint -W101 */
3
 import JitsiPopover from "../util/JitsiPopover";
3
 import JitsiPopover from "../util/JitsiPopover";
4
 import VideoLayout from "./VideoLayout";
4
 import VideoLayout from "./VideoLayout";
63
 ConnectionIndicator.prototype.generateText = function () {
63
 ConnectionIndicator.prototype.generateText = function () {
64
     var downloadBitrate, uploadBitrate, packetLoss, i;
64
     var downloadBitrate, uploadBitrate, packetLoss, i;
65
 
65
 
66
-    var translate = APP.translation.translateString;
67
-
68
     if(this.bitrate === null) {
66
     if(this.bitrate === null) {
69
         downloadBitrate = "N/A";
67
         downloadBitrate = "N/A";
70
         uploadBitrate = "N/A";
68
         uploadBitrate = "N/A";
97
 
95
 
98
     var result = "<table style='width:100%'>" +
96
     var result = "<table style='width:100%'>" +
99
         "<tr>" +
97
         "<tr>" +
100
-        "<td><span class='jitsipopover_blue' data-i18n='connectionindicator.bitrate'>" +
101
-        translate("connectionindicator.bitrate") + "</span></td>" +
98
+        "<td><span class='jitsipopover_blue' data-i18n='connectionindicator.bitrate'></span></td>" +
102
         "<td><span class='jitsipopover_green'>&darr;</span>" +
99
         "<td><span class='jitsipopover_green'>&darr;</span>" +
103
         downloadBitrate + " <span class='jitsipopover_orange'>&uarr;</span>" +
100
         downloadBitrate + " <span class='jitsipopover_orange'>&uarr;</span>" +
104
         uploadBitrate + "</td>" +
101
         uploadBitrate + "</td>" +
105
         "</tr><tr>" +
102
         "</tr><tr>" +
106
-        "<td><span class='jitsipopover_blue' data-i18n='connectionindicator.packetloss'>" +
107
-        translate("connectionindicator.packetloss") + "</span></td>" +
103
+        "<td><span class='jitsipopover_blue' data-i18n='connectionindicator.packetloss'></span></td>" +
108
         "<td>" + packetLoss  + "</td>" +
104
         "<td>" + packetLoss  + "</td>" +
109
         "</tr><tr>" +
105
         "</tr><tr>" +
110
-        "<td><span class='jitsipopover_blue' data-i18n='connectionindicator.resolution'>" +
111
-        translate("connectionindicator.resolution") + "</span></td>" +
106
+        "<td><span class='jitsipopover_blue' data-i18n='connectionindicator.resolution'></span></td>" +
112
         "<td>" + resolutionStr + "</td></tr></table>";
107
         "<td>" + resolutionStr + "</td></tr></table>";
113
 
108
 
114
     if(this.videoContainer.videoSpanId == "localVideoContainer") {
109
     if(this.videoContainer.videoSpanId == "localVideoContainer") {
117
             // FIXME: we do not know local id when this text is generated
112
             // FIXME: we do not know local id when this text is generated
118
             //this.id + "')\"  data-i18n='connectionindicator." +
113
             //this.id + "')\"  data-i18n='connectionindicator." +
119
             "local')\"  data-i18n='connectionindicator." +
114
             "local')\"  data-i18n='connectionindicator." +
120
-                (this.showMoreValue ? "less" : "more") + "'>" +
121
-            translate("connectionindicator." + (this.showMoreValue ? "less" : "more")) +
122
-            "</div><br />";
115
+                (this.showMoreValue ? "less" : "more") + "'></div><br />";
123
     }
116
     }
124
 
117
 
125
     if (this.showMoreValue) {
118
     if (this.showMoreValue) {
139
         if (!this.transport || this.transport.length === 0) {
132
         if (!this.transport || this.transport.length === 0) {
140
             transport = "<tr>" +
133
             transport = "<tr>" +
141
                 "<td><span class='jitsipopover_blue' " +
134
                 "<td><span class='jitsipopover_blue' " +
142
-                "data-i18n='connectionindicator.address'>" +
143
-                translate("connectionindicator.address") + "</span></td>" +
135
+                "data-i18n='connectionindicator.address'></span></td>" +
144
                 "<td> N/A</td></tr>";
136
                 "<td> N/A</td></tr>";
145
         } else {
137
         } else {
146
             var data = {remoteIP: [], localIP:[], remotePort:[], localPort:[]};
138
             var data = {remoteIP: [], localIP:[], remotePort:[], localPort:[]};
173
             var localTransport =
165
             var localTransport =
174
                 "<tr><td><span class='jitsipopover_blue' data-i18n='" +
166
                 "<tr><td><span class='jitsipopover_blue' data-i18n='" +
175
                 local_address_key +"' data-i18n-options='" +
167
                 local_address_key +"' data-i18n-options='" +
176
-                    JSON.stringify({count: data.localIP.length}) + "'>" +
177
-                    translate(local_address_key, {count: data.localIP.length}) +
178
-                    "</span></td><td> " +
168
+                    JSON.stringify({count: data.localIP.length}) + "'></span></td><td> " +
179
                 ConnectionIndicator.getStringFromArray(data.localIP) +
169
                 ConnectionIndicator.getStringFromArray(data.localIP) +
180
                 "</td></tr>";
170
                 "</td></tr>";
181
             transport =
171
             transport =
182
                 "<tr><td><span class='jitsipopover_blue' data-i18n='" +
172
                 "<tr><td><span class='jitsipopover_blue' data-i18n='" +
183
                 remote_address_key + "' data-i18n-options='" +
173
                 remote_address_key + "' data-i18n-options='" +
184
-                    JSON.stringify({count: data.remoteIP.length}) + "'>" +
185
-                    translate(remote_address_key,
186
-                        {count: data.remoteIP.length}) +
187
-                    "</span></td><td> " +
174
+                    JSON.stringify({count: data.remoteIP.length}) + "'></span></td><td> " +
188
                 ConnectionIndicator.getStringFromArray(data.remoteIP) +
175
                 ConnectionIndicator.getStringFromArray(data.remoteIP) +
189
                 "</td></tr>";
176
                 "</td></tr>";
190
 
177
 
195
                 "<td>" +
182
                 "<td>" +
196
                 "<span class='jitsipopover_blue' data-i18n='" + key_remote +
183
                 "<span class='jitsipopover_blue' data-i18n='" + key_remote +
197
                 "' data-i18n-options='" +
184
                 "' data-i18n-options='" +
198
-                JSON.stringify({count: this.transport.length}) + "'>" +
199
-                translate(key_remote, {count: this.transport.length}) +
200
-                "</span></td><td>";
185
+                JSON.stringify({count: this.transport.length}) + "'></span></td><td>";
201
             localTransport += "<tr>" +
186
             localTransport += "<tr>" +
202
                 "<td>" +
187
                 "<td>" +
203
                 "<span class='jitsipopover_blue' data-i18n='" + key_local +
188
                 "<span class='jitsipopover_blue' data-i18n='" + key_local +
204
                 "' data-i18n-options='" +
189
                 "' data-i18n-options='" +
205
-                JSON.stringify({count: this.transport.length}) + "'>" +
206
-                translate(key_local, {count: this.transport.length}) +
207
-                "</span></td><td>";
190
+                JSON.stringify({count: this.transport.length}) + "'></span></td><td>";
208
 
191
 
209
             transport +=
192
             transport +=
210
                 ConnectionIndicator.getStringFromArray(data.remotePort);
193
                 ConnectionIndicator.getStringFromArray(data.remotePort);
213
             transport += "</td></tr>";
196
             transport += "</td></tr>";
214
             transport += localTransport + "</td></tr>";
197
             transport += localTransport + "</td></tr>";
215
             transport +="<tr>" +
198
             transport +="<tr>" +
216
-                "<td><span class='jitsipopover_blue' data-i18n='connectionindicator.transport'>" +
217
-                translate("connectionindicator.transport") + "</span></td>" +
199
+                "<td><span class='jitsipopover_blue' data-i18n='connectionindicator.transport'></span></td>" +
218
                 "<td>" + this.transport[0].type + "</td></tr>";
200
                 "<td>" + this.transport[0].type + "</td></tr>";
219
 
201
 
220
         }
202
         }
222
         result += "<table  style='width:100%'>" +
204
         result += "<table  style='width:100%'>" +
223
             "<tr>" +
205
             "<tr>" +
224
             "<td>" +
206
             "<td>" +
225
-            "<span class='jitsipopover_blue' data-i18n='connectionindicator.bandwidth'>" +
226
-            translate("connectionindicator.bandwidth") + "</span>" +
207
+            "<span class='jitsipopover_blue' data-i18n='connectionindicator.bandwidth'></span>" +
227
             "</td><td>" +
208
             "</td><td>" +
228
             "<span class='jitsipopover_green'>&darr;</span>" +
209
             "<span class='jitsipopover_green'>&darr;</span>" +
229
             downloadBandwidth +
210
             downloadBandwidth +
266
         this.connectionIndicatorContainer);
247
         this.connectionIndicatorContainer);
267
     this.popover = new JitsiPopover(
248
     this.popover = new JitsiPopover(
268
         $("#" + this.videoContainer.videoSpanId + " > .connectionindicator"),
249
         $("#" + this.videoContainer.videoSpanId + " > .connectionindicator"),
269
-        {content: "<div class=\"connection_info\" data-i18n='connectionindicator.na'>" +
270
-            APP.translation.translateString("connectionindicator.na") + "</div>",
250
+        {content: "<div class=\"connection_info\" data-i18n='connectionindicator.na'></div>",
271
             skin: "black"});
251
             skin: "black"});
272
 
252
 
273
     // override popover show method to make sure we will update the content
253
     // override popover show method to make sure we will update the content
381
         this.popover.updateContent(
361
         this.popover.updateContent(
382
             `<div class="connection_info">${this.generateText()}</div>`
362
             `<div class="connection_info">${this.generateText()}</div>`
383
         );
363
         );
384
-        APP.translation.translateElement($(".connection_info"));
385
     }
364
     }
386
 };
365
 };
387
 
366
 

+ 5
- 3
modules/UI/videolayout/LargeVideoManager.js 查看文件

379
      */
379
      */
380
     _setRemoteConnectionMessage (msgKey, msgOptions) {
380
     _setRemoteConnectionMessage (msgKey, msgOptions) {
381
         if (msgKey) {
381
         if (msgKey) {
382
-            let text = APP.translation.translateString(msgKey, msgOptions);
383
             $('#remoteConnectionMessage')
382
             $('#remoteConnectionMessage')
384
-                .attr("data-i18n", msgKey).text(text);
383
+                .attr("data-i18n", msgKey)
384
+                .attr("data-i18n-options", JSON.stringify(msgOptions));
385
+            APP.translation.translateElement($('#remoteConnectionMessage'));
385
         }
386
         }
386
 
387
 
387
         this.videoContainer.positionRemoteConnectionMessage();
388
         this.videoContainer.positionRemoteConnectionMessage();
400
     _setLocalConnectionMessage (msgKey, msgOptions) {
401
     _setLocalConnectionMessage (msgKey, msgOptions) {
401
         $('#localConnectionMessage')
402
         $('#localConnectionMessage')
402
             .attr("data-i18n", msgKey)
403
             .attr("data-i18n", msgKey)
403
-            .text(APP.translation.translateString(msgKey, msgOptions));
404
+            .attr("data-i18n-options", JSON.stringify(msgOptions));
405
+        APP.translation.translateElement($('#localConnectionMessage'));
404
     }
406
     }
405
 
407
 
406
     /**
408
     /**

+ 4
- 5
modules/UI/videolayout/LocalVideo.js 查看文件

96
             editableText.value = displayName;
96
             editableText.value = displayName;
97
         }
97
         }
98
 
98
 
99
-        var defaultNickname = APP.translation.translateString(
100
-            "defaultNickname", {name: "Jane Pink"});
101
         editableText.setAttribute('style', 'display:none;');
99
         editableText.setAttribute('style', 'display:none;');
102
-        editableText.setAttribute('data-18n',
100
+        editableText.setAttribute('data-i18n',
103
             '[placeholder]defaultNickname');
101
             '[placeholder]defaultNickname');
104
         editableText.setAttribute("data-i18n-options",
102
         editableText.setAttribute("data-i18n-options",
105
             JSON.stringify({name: "Jane Pink"}));
103
             JSON.stringify({name: "Jane Pink"}));
106
-        editableText.setAttribute("placeholder", defaultNickname);
104
+        APP.translation.translateElement($(editableText));
107
 
105
 
108
         this.container
106
         this.container
109
             .querySelector('.videocontainer__toolbar')
107
             .querySelector('.videocontainer__toolbar')
253
         events: {
251
         events: {
254
             show : function(options){
252
             show : function(options){
255
                 options.items.flip.name =
253
                 options.items.flip.name =
256
-                    APP.translation.translateString("videothumbnail.flip");
254
+                    APP.translation.generateTranslationHTML(
255
+                        "videothumbnail.flip");
257
             }
256
             }
258
         }
257
         }
259
     });
258
     });

+ 5
- 12
modules/UI/videolayout/RemoteVideo.js 查看文件

109
     var mutedIndicator = "<i class='icon-mic-disabled'></i>";
109
     var mutedIndicator = "<i class='icon-mic-disabled'></i>";
110
 
110
 
111
     var doMuteHTML = mutedIndicator +
111
     var doMuteHTML = mutedIndicator +
112
-        " <div " +
113
-        "data-i18n='videothumbnail.domute'>" +
114
-        APP.translation.translateString("videothumbnail.domute") +
115
-        "</div>";
112
+        " <div data-i18n='videothumbnail.domute'></div>";
116
 
113
 
117
     var mutedHTML = mutedIndicator +
114
     var mutedHTML = mutedIndicator +
118
-        " <div " +
119
-        "data-i18n='videothumbnail.muted'>" +
120
-        APP.translation.translateString("videothumbnail.muted") +
121
-        "</div>";
115
+        " <div data-i18n='videothumbnail.muted'></div>";
122
 
116
 
123
     muteLinkItem.id = "mutelink_" + this.id;
117
     muteLinkItem.id = "mutelink_" + this.id;
124
 
118
 
150
     var ejectMenuItem = document.createElement('li');
144
     var ejectMenuItem = document.createElement('li');
151
     var ejectLinkItem = document.createElement('a');
145
     var ejectLinkItem = document.createElement('a');
152
 
146
 
153
-    var ejectText = "<div " +
154
-        "data-i18n='videothumbnail.kick'>" +
155
-        APP.translation.translateString("videothumbnail.kick") +
156
-        "</div>";
147
+    var ejectText = "<div data-i18n='videothumbnail.kick'></div>";
157
 
148
 
158
     ejectLinkItem.className = 'ejectlink';
149
     ejectLinkItem.className = 'ejectlink';
159
     ejectLinkItem.innerHTML = ejectIndicator + ' ' + ejectText;
150
     ejectLinkItem.innerHTML = ejectIndicator + ' ' + ejectText;
167
     ejectMenuItem.appendChild(ejectLinkItem);
158
     ejectMenuItem.appendChild(ejectLinkItem);
168
     popupmenuElement.appendChild(ejectMenuItem);
159
     popupmenuElement.appendChild(ejectMenuItem);
169
 
160
 
161
+    APP.translation.translateElement($(popupmenuElement));
162
+
170
     return popupmenuElement;
163
     return popupmenuElement;
171
 };
164
 };
172
 
165
 

+ 1
- 2
modules/keyboardshortcut/keyboardshortcut.js 查看文件

190
         let descriptionClass = "shortcuts-list__description";
190
         let descriptionClass = "shortcuts-list__description";
191
         descriptionElement.className = descriptionClass;
191
         descriptionElement.className = descriptionClass;
192
         descriptionElement.setAttribute("data-i18n", shortcutDescriptionKey);
192
         descriptionElement.setAttribute("data-i18n", shortcutDescriptionKey);
193
-        descriptionElement.innerHTML
194
-            = APP.translation.translateString(shortcutDescriptionKey);
193
+        APP.translation.translateElement($(descriptionElement));
195
 
194
 
196
         listElement.appendChild(spanElement);
195
         listElement.appendChild(spanElement);
197
         listElement.appendChild(descriptionElement);
196
         listElement.appendChild(descriptionElement);

+ 4
- 7
modules/translation/translation.js 查看文件

89
 
89
 
90
         i18n.init(options, initCompleted);
90
         i18n.init(options, initCompleted);
91
     },
91
     },
92
-    translateString: function (key, options) {
93
-        return i18n.t(key, options);
94
-    },
95
     setLanguage: function (lang) {
92
     setLanguage: function (lang) {
96
         if(!lang)
93
         if(!lang)
97
             lang = DEFAULT_LANG;
94
             lang = DEFAULT_LANG;
100
     getCurrentLanguage: function () {
97
     getCurrentLanguage: function () {
101
         return i18n.lng();
98
         return i18n.lng();
102
     },
99
     },
103
-    translateElement: function (selector) {
104
-        selector.i18n();
100
+    translateElement: function (selector, options) {
101
+        selector.i18n(options);
105
     },
102
     },
106
     generateTranslationHTML: function (key, options) {
103
     generateTranslationHTML: function (key, options) {
107
         var str = "<span data-i18n=\"" + key + "\"";
104
         var str = "<span data-i18n=\"" + key + "\"";
108
         if (options) {
105
         if (options) {
109
-            str += " data-i18n-options=\"" + JSON.stringify(options) + "\"";
106
+            str += " data-i18n-options='" + JSON.stringify(options) + "'";
110
         }
107
         }
111
         str += ">";
108
         str += ">";
112
-        str += this.translateString(key, options);
109
+        str += i18n.t(key, options);
113
         str += "</span>";
110
         str += "</span>";
114
         return str;
111
         return str;
115
 
112
 

Loading…
取消
儲存