Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 6b1b643

Browse files
author
Luke Barnard
committed
Merge branch 'develop' into luke/store-history-as-raw-content
2 parents fc00eaf + 7d10a75 commit 6b1b643

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+1226
-495
lines changed

jenkins.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ set -e
44

55
export NVM_DIR="$HOME/.nvm"
66
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
7-
nvm use 4
7+
nvm use 6
88

99
set -x
1010

karma.conf.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,18 @@ module.exports = function (config) {
9393
// test results reporter to use
9494
// possible values: 'dots', 'progress'
9595
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
96-
reporters: ['progress', 'junit'],
96+
reporters: ['logcapture', 'spec', 'junit', 'summary'],
97+
98+
specReporter: {
99+
suppressErrorSummary: false, // do print error summary
100+
suppressFailed: false, // do print information about failed tests
101+
suppressPassed: false, // do print information about passed tests
102+
showSpecTiming: true, // print the time elapsed for each spec
103+
},
104+
105+
client: {
106+
captureLogs: true,
107+
},
97108

98109
// web server port
99110
port: 9876,
@@ -104,7 +115,10 @@ module.exports = function (config) {
104115
// level of logging
105116
// possible values: config.LOG_DISABLE || config.LOG_ERROR ||
106117
// config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
107-
logLevel: config.LOG_INFO,
118+
//
119+
// This is strictly for logs that would be generated by the browser itself and we
120+
// don't want to log about missing images, which are emitted on LOG_WARN.
121+
logLevel: config.LOG_ERROR,
108122

109123
// enable / disable watching file and executing tests whenever any file
110124
// changes

package.json

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@
5353
"classnames": "^2.1.2",
5454
"commonmark": "^0.27.0",
5555
"counterpart": "^0.18.0",
56-
"draft-js": "^0.9.1",
57-
"draft-js-export-html": "^0.5.0",
58-
"draft-js-export-markdown": "^0.2.0",
56+
"draft-js": "^0.11.0-alpha",
57+
"draft-js-export-html": "^0.6.0",
58+
"draft-js-export-markdown": "^0.3.0",
5959
"emojione": "2.2.7",
6060
"file-saver": "^1.3.3",
6161
"filesize": "3.5.6",
@@ -102,12 +102,15 @@
102102
"eslint-plugin-react": "^6.9.0",
103103
"expect": "^1.16.0",
104104
"json-loader": "^0.5.3",
105-
"karma": "^0.13.22",
105+
"karma": "^1.7.0",
106106
"karma-chrome-launcher": "^0.2.3",
107107
"karma-cli": "^0.1.2",
108108
"karma-junit-reporter": "^0.4.1",
109+
"karma-logcapture-reporter": "0.0.1",
109110
"karma-mocha": "^0.2.2",
110111
"karma-sourcemap-loader": "^0.3.7",
112+
"karma-spec-reporter": "^0.0.31",
113+
"karma-summary-reporter": "^1.3.3",
111114
"karma-webpack": "^1.7.0",
112115
"matrix-react-test-utils": "^0.1.1",
113116
"mocha": "^2.4.5",

src/Analytics.js

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*/
1616

1717
import { getCurrentLanguage } from './languageHandler';
18-
import MatrixClientPeg from './MatrixClientPeg';
1918
import PlatformPeg from './PlatformPeg';
2019
import SdkConfig from './SdkConfig';
2120

@@ -31,8 +30,18 @@ const customVariables = {
3130
'User Type': 3,
3231
'Chosen Language': 4,
3332
'Instance': 5,
33+
'RTE: Uses Richtext Mode': 6,
34+
'Homeserver URL': 7,
35+
'Identity Server URL': 8,
3436
};
3537

38+
function whitelistRedact(whitelist, str) {
39+
if (whitelist.includes(str)) return str;
40+
return '<redacted>';
41+
}
42+
43+
const whitelistedHSUrls = ["https://matrix.org"];
44+
const whitelistedISUrls = ["https://vector.im"];
3645

3746
class Analytics {
3847
constructor() {
@@ -76,7 +85,7 @@ class Analytics {
7685
this._paq.push(['trackAllContentImpressions']);
7786
this._paq.push(['discardHashTag', false]);
7887
this._paq.push(['enableHeartBeatTimer']);
79-
this._paq.push(['enableLinkTracking', true]);
88+
// this._paq.push(['enableLinkTracking', true]);
8089

8190
const platform = PlatformPeg.get();
8291
this._setVisitVariable('App Platform', platform.getHumanReadableName());
@@ -130,20 +139,20 @@ class Analytics {
130139
this._paq.push(['deleteCookies']);
131140
}
132141

133-
login() { // not used currently
134-
const cli = MatrixClientPeg.get();
135-
if (this.disabled || !cli) return;
136-
137-
this._paq.push(['setUserId', `@${cli.getUserIdLocalpart()}:${cli.getDomain()}`]);
138-
}
139-
140142
_setVisitVariable(key, value) {
141143
this._paq.push(['setCustomVariable', customVariables[key], key, value, 'visit']);
142144
}
143145

144-
setGuest(guest) {
146+
setLoggedIn(isGuest, homeserverUrl, identityServerUrl) {
147+
if (this.disabled) return;
148+
this._setVisitVariable('User Type', isGuest ? 'Guest' : 'Logged In');
149+
this._setVisitVariable('Homeserver URL', whitelistRedact(whitelistedHSUrls, homeserverUrl));
150+
this._setVisitVariable('Identity Server URL', whitelistRedact(whitelistedISUrls, identityServerUrl));
151+
}
152+
153+
setRichtextMode(state) {
145154
if (this.disabled) return;
146-
this._setVisitVariable('User Type', guest ? 'Guest' : 'Logged In');
155+
this._setVisitVariable('RTE: Uses Richtext Mode', state ? 'on' : 'off');
147156
}
148157
}
149158

src/CallHandler.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ function _setCallListeners(call) {
143143
pause("ringbackAudio");
144144
play("busyAudio");
145145
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
146-
Modal.createDialog(ErrorDialog, {
146+
Modal.createTrackedDialog('Call Handler', 'Call Timeout', ErrorDialog, {
147147
title: _t('Call Timeout'),
148148
description: _t('The remote side failed to pick up') + '.',
149149
});
@@ -205,7 +205,7 @@ function _onAction(payload) {
205205
_setCallState(undefined, newCall.roomId, "ended");
206206
console.log("Can't capture screen: " + screenCapErrorString);
207207
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
208-
Modal.createDialog(ErrorDialog, {
208+
Modal.createTrackedDialog('Call Handler', 'Unable to capture screen', ErrorDialog, {
209209
title: _t('Unable to capture screen'),
210210
description: screenCapErrorString,
211211
});
@@ -225,7 +225,7 @@ function _onAction(payload) {
225225
case 'place_call':
226226
if (module.exports.getAnyActiveCall()) {
227227
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
228-
Modal.createDialog(ErrorDialog, {
228+
Modal.createTrackedDialog('Call Handler', 'Existing Call', ErrorDialog, {
229229
title: _t('Existing Call'),
230230
description: _t('You are already in a call.'),
231231
});
@@ -235,7 +235,7 @@ function _onAction(payload) {
235235
// if the runtime env doesn't do VoIP, whine.
236236
if (!MatrixClientPeg.get().supportsVoip()) {
237237
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
238-
Modal.createDialog(ErrorDialog, {
238+
Modal.createTrackedDialog('Call Handler', 'VoIP is unsupported', ErrorDialog, {
239239
title: _t('VoIP is unsupported'),
240240
description: _t('You cannot place VoIP calls in this browser.'),
241241
});
@@ -251,7 +251,7 @@ function _onAction(payload) {
251251
var members = room.getJoinedMembers();
252252
if (members.length <= 1) {
253253
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
254-
Modal.createDialog(ErrorDialog, {
254+
Modal.createTrackedDialog('Call Handler', 'Cannot place call with self', ErrorDialog, {
255255
description: _t('You cannot place a call with yourself.'),
256256
});
257257
return;
@@ -277,13 +277,13 @@ function _onAction(payload) {
277277
console.log("Place conference call in %s", payload.room_id);
278278
if (!ConferenceHandler) {
279279
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
280-
Modal.createDialog(ErrorDialog, {
280+
Modal.createTrackedDialog('Call Handler', 'Conference call unsupported client', ErrorDialog, {
281281
description: _t('Conference calls are not supported in this client'),
282282
});
283283
}
284284
else if (!MatrixClientPeg.get().supportsVoip()) {
285285
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
286-
Modal.createDialog(ErrorDialog, {
286+
Modal.createTrackedDialog('Call Handler', 'VoIP is unsupported', ErrorDialog, {
287287
title: _t('VoIP is unsupported'),
288288
description: _t('You cannot place VoIP calls in this browser.'),
289289
});
@@ -296,13 +296,13 @@ function _onAction(payload) {
296296
// participant.
297297
// Therefore we disable conference calling in E2E rooms.
298298
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
299-
Modal.createDialog(ErrorDialog, {
299+
Modal.createTrackedDialog('Call Handler', 'Conference calls unsupported e2e', ErrorDialog, {
300300
description: _t('Conference calls are not supported in encrypted rooms'),
301301
});
302302
}
303303
else {
304304
var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
305-
Modal.createDialog(QuestionDialog, {
305+
Modal.createTrackedDialog('Call Handler', 'Conference calling in development', QuestionDialog, {
306306
title: _t('Warning!'),
307307
description: _t('Conference calling is in development and may not be reliable.'),
308308
onFinished: confirm=>{
@@ -314,7 +314,7 @@ function _onAction(payload) {
314314
}, function(err) {
315315
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
316316
console.error("Conference call failed: " + err);
317-
Modal.createDialog(ErrorDialog, {
317+
Modal.createTrackedDialog('Call Handler', 'Failed to set up conference call', ErrorDialog, {
318318
title: _t('Failed to set up conference call'),
319319
description: _t('Conference call failed.') + ' ' + ((err && err.message) ? err.message : ''),
320320
});

src/ContentMessages.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ class ContentMessages {
360360
desc = _t('The file \'%(fileName)s\' exceeds this home server\'s size limit for uploads', {fileName: upload.fileName});
361361
}
362362
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
363-
Modal.createDialog(ErrorDialog, {
363+
Modal.createTrackedDialog('Upload failed', '', ErrorDialog, {
364364
title: _t('Upload Failed'),
365365
description: desc,
366366
});

src/HtmlUtils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ const sanitizeHtmlParams = {
145145
font: ['color', 'data-mx-bg-color', 'data-mx-color', 'style'], // custom to matrix
146146
span: ['data-mx-bg-color', 'data-mx-color', 'style'], // custom to matrix
147147
a: ['href', 'name', 'target', 'rel'], // remote target: custom to matrix
148-
img: ['src'],
148+
img: ['src', 'width', 'height', 'alt', 'title'],
149149
ol: ['start'],
150150
code: ['class'], // We don't actually allow all classes, we filter them in transformTags
151151
},

src/KeyRequestHandler.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ export default class KeyRequestHandler {
125125
};
126126

127127
const KeyShareDialog = sdk.getComponent("dialogs.KeyShareDialog");
128-
Modal.createDialog(KeyShareDialog, {
128+
Modal.createTrackedDialog('Key Share', 'Process Next Request', KeyShareDialog, {
129129
matrixClient: this._matrixClient,
130130
userId: userId,
131131
deviceId: deviceId,

src/Lifecycle.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ function _handleRestoreFailure(e) {
240240
const SessionRestoreErrorDialog =
241241
sdk.getComponent('views.dialogs.SessionRestoreErrorDialog');
242242

243-
Modal.createDialog(SessionRestoreErrorDialog, {
243+
Modal.createTrackedDialog('Session Restore Error', '', SessionRestoreErrorDialog, {
244244
error: e.message,
245245
onFinished: (success) => {
246246
def.resolve(success);
@@ -318,7 +318,7 @@ async function _doSetLoggedIn(credentials, clearStorage) {
318318
await _clearStorage();
319319
}
320320

321-
Analytics.setGuest(credentials.guest);
321+
Analytics.setLoggedIn(credentials.guest, credentials.homeserverUrl, credentials.identityServerUrl);
322322

323323
// Resolves by default
324324
let teamPromise = Promise.resolve(null);

src/Markdown.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,33 @@ function is_multi_line(node) {
5555
return par.firstChild != par.lastChild;
5656
}
5757

58+
import linkifyMatrix from './linkify-matrix';
59+
import * as linkify from 'linkifyjs';
60+
linkifyMatrix(linkify);
61+
62+
// Thieved from draft-js-export-markdown
63+
function escapeMarkdown(s) {
64+
return s.replace(/[*_`]/g, '\\$&');
65+
}
66+
67+
// Replace URLs, room aliases and user IDs with md-escaped URLs
68+
function linkifyMarkdown(s) {
69+
const links = linkify.find(s);
70+
links.forEach((l) => {
71+
// This may replace several instances of `l.value` at once, but that's OK
72+
s = s.replace(l.value, escapeMarkdown(l.value));
73+
});
74+
return s;
75+
}
76+
5877
/**
5978
* Class that wraps commonmark, adding the ability to see whether
6079
* a given message actually uses any markdown syntax or whether
6180
* it's plain text.
6281
*/
6382
export default class Markdown {
6483
constructor(input) {
65-
this.input = input;
84+
this.input = linkifyMarkdown(input);
6685

6786
const parser = new commonmark.Parser();
6887
this.parsed = parser.parse(this.input);

0 commit comments

Comments
 (0)