Merge branch 'develop' into travis/upgrade-warning

This commit is contained in:
Travis Ralston 2019-03-15 15:32:49 -06:00
commit da61e5e9d9
19 changed files with 172 additions and 118 deletions

60
.buildkite/pipeline.yaml Normal file
View file

@ -0,0 +1,60 @@
steps:
- label: ":eslint: Lint"
command:
- "yarn install"
- "yarn lintwithexclusions"
plugins:
- docker#v3.0.1:
image: "node:10"
# - label: ":chains: End-to-End Tests"
# command:
# # TODO: Remove hacky chmod for BuildKite
# - "chmod +x ./scripts/ci/*.sh"
# - "chmod +x ./scripts/*"
# - "sudo apt-get install build-essential python2.7-dev libffi-dev python-pip python-setuptools sqlite3 libssl-dev python-virtualenv libjpeg-dev libxslt1-dev"
# - "./scripts/ci/install-deps.sh"
# - "./scripts/ci/end-to-end-tests.sh"
# plugins:
# - docker#v3.0.1:
# image: "node:10"
- label: ":karma: Tests"
command:
# Install chrome
- "wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -"
- "sh -c 'echo \"deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main\" >> /etc/apt/sources.list.d/google.list'"
- "apt-get update"
- "apt-get install -y google-chrome-stable"
# Run tests
# TODO: Remove hacky chmod for BuildKite
- "chmod +x ./scripts/ci/*.sh"
- "chmod +x ./scripts/*"
- "./scripts/ci/install-deps.sh"
- "./scripts/ci/unit-tests.sh"
env:
CHROME_BIN: "/usr/bin/google-chrome-stable"
plugins:
- docker#v3.0.1:
image: "node:10"
propagate-environment: true
- label: "🔧 Riot Tests"
command:
# Install chrome
- "wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -"
- "sh -c 'echo \"deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main\" >> /etc/apt/sources.list.d/google.list'"
- "apt-get update"
- "apt-get install -y google-chrome-stable"
# Run tests
# TODO: Remove hacky chmod for BuildKite
- "chmod +x ./scripts/ci/*.sh"
- "chmod +x ./scripts/*"
- "./scripts/ci/install-deps.sh"
- "./scripts/ci/riot-unit-tests.sh"
env:
CHROME_BIN: "/usr/bin/google-chrome-stable"
plugins:
- docker#v3.0.1:
image: "node:10"
propagate-environment: true

View file

@ -1,38 +0,0 @@
# we need trusty for the chrome addon
dist: trusty
# we don't need sudo, so can run in a container, which makes startup much
# quicker.
#
# unfortunately we do temporarily require sudo as a workaround for
# https://github.com/travis-ci/travis-ci/issues/8836
sudo: required
language: node_js
node_js:
- node # Latest stable version of nodejs.
addons:
chrome: stable
before_install:
- curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.13.0
- export PATH=$HOME/.yarn/bin:$PATH
install:
- ./scripts/travis/install-deps.sh
matrix:
include:
- name: Linting Checks
script:
# run the linter, but exclude any files known to have errors or warnings.
- yarn lintwithexclusions
# - name: End-to-End Tests
# if: branch = develop
# install:
# - sudo apt-get install build-essential python2.7-dev libffi-dev python-pip python-setuptools sqlite3 libssl-dev python-virtualenv libjpeg-dev libxslt1-dev
# script:
# - ./scripts/travis/end-to-end-tests.sh
- name: Unit Tests
script:
- ./scripts/travis/unit-tests.sh
- name: Riot-web Unit Tests
script:
- ./scripts/travis/riot-unit-tests.sh

View file

@ -135,9 +135,10 @@ module.exports = function (config) {
], ],
customLaunchers: { customLaunchers: {
'ChromeHeadless': { 'VectorChromeHeadless': {
base: 'Chrome', base: 'Chrome',
flags: [ flags: [
'--no-sandbox',
// See https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md // See https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md
'--headless', '--headless',
'--disable-gpu', '--disable-gpu',

View file

@ -51,7 +51,7 @@
"lintwithexclusions": "eslint --max-warnings 0 --ignore-path .eslintignore.errorfiles src test", "lintwithexclusions": "eslint --max-warnings 0 --ignore-path .eslintignore.errorfiles src test",
"clean": "rimraf lib", "clean": "rimraf lib",
"prepare": "yarn clean && yarn build && git rev-parse HEAD > git-revision.txt", "prepare": "yarn clean && yarn build && git rev-parse HEAD > git-revision.txt",
"test": "karma start --single-run=true --browsers ChromeHeadless", "test": "karma start --single-run=true --browsers VectorChromeHeadless",
"test-multi": "karma start" "test-multi": "karma start"
}, },
"dependencies": { "dependencies": {
@ -131,7 +131,7 @@
"flow-parser": "^0.57.3", "flow-parser": "^0.57.3",
"jest-mock": "^23.2.0", "jest-mock": "^23.2.0",
"karma": "^4.0.1", "karma": "^4.0.1",
"karma-chrome-launcher": "^0.2.3", "karma-chrome-launcher": "^2.2.0",
"karma-cli": "^1.0.1", "karma-cli": "^1.0.1",
"karma-junit-reporter": "^2.0.0", "karma-junit-reporter": "^2.0.0",
"karma-logcapture-reporter": "0.0.1", "karma-logcapture-reporter": "0.0.1",

View file

@ -16,6 +16,16 @@ limitations under the License.
.mx_BaseAvatar { .mx_BaseAvatar {
position: relative; position: relative;
// In at least Firefox, the case of relative positioned inline elements
// (such as mx_BaseAvatar) with absolute positioned children (such as
// mx_BaseAvatar_initial) is a dark corner full of spider webs. It will give
// different results during full reflow of the page vs. incremental reflow
// of small portions. While that's surely a browser bug, we can avoid it by
// using `inline-block` instead of the default `inline`.
// https://github.com/vector-im/riot-web/issues/5594
// https://bugzilla.mozilla.org/show_bug.cgi?id=1535053
// https://bugzilla.mozilla.org/show_bug.cgi?id=255139
display: inline-block;
} }
.mx_BaseAvatar_initial { .mx_BaseAvatar_initial {

View file

@ -22,10 +22,20 @@ limitations under the License.
} }
.mx_EntityTile:hover { .mx_EntityTile:hover {
background-image: url('$(res)/img/member_chevron.png');
background-position: center right 10px;
background-repeat: no-repeat;
padding-right: 30px; padding-right: 30px;
position: relative; // to keep the chevron aligned
}
.mx_EntityTile:hover::before {
content: "";
position: absolute;
top: calc(50% - 8px); // center
right: 10px;
mask: url('$(res)/img/member_chevron.png');
mask-repeat: no-repeat;
width: 16px;
height: 16px;
background-color: $rightpanel-button-color;
} }
.mx_EntityTile .mx_PresenceLabel { .mx_EntityTile .mx_PresenceLabel {
@ -92,19 +102,19 @@ limitations under the License.
.mx_EntityTile_unavailable .mx_EntityTile_avatar, .mx_EntityTile_unavailable .mx_EntityTile_avatar,
.mx_EntityTile_unavailable .mx_EntityTile_name, .mx_EntityTile_unavailable .mx_EntityTile_name,
.mx_EntityTile_offline_beenactive .mx_EntityTile_avatar, .mx_EntityTile_offline_beenactive .mx_EntityTile_avatar,
.mx_EntityTile_offline_beenactive .mx_EntityTile_name, .mx_EntityTile_offline_beenactive .mx_EntityTile_name
{ {
opacity: 0.5; opacity: 0.5;
} }
.mx_EntityTile_offline_neveractive .mx_EntityTile_avatar, .mx_EntityTile_offline_neveractive .mx_EntityTile_avatar,
.mx_EntityTile_offline_neveractive .mx_EntityTile_name, .mx_EntityTile_offline_neveractive .mx_EntityTile_name
{ {
opacity: 0.25; opacity: 0.25;
} }
.mx_EntityTile_unknown .mx_EntityTile_avatar, .mx_EntityTile_unknown .mx_EntityTile_avatar,
.mx_EntityTile_unknown .mx_EntityTile_name, .mx_EntityTile_unknown .mx_EntityTile_name
{ {
opacity: 0.25; opacity: 0.25;
} }

2
scripts/travis/build.sh → scripts/ci/build.sh Executable file → Normal file
View file

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# #
# script which is run by the travis build (after `yarn test`). # script which is run by the CI build (after `yarn test`).
# #
# clones riot-web develop and runs the tests against our version of react-sdk. # clones riot-web develop and runs the tests against our version of react-sdk.

View file

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# #
# script which is run by the travis build (after `yarn test`). # script which is run by the CI build (after `yarn test`).
# #
# clones riot-web develop and runs the tests against our version of react-sdk. # clones riot-web develop and runs the tests against our version of react-sdk.
@ -9,7 +9,7 @@ set -ev
RIOT_WEB_DIR=riot-web RIOT_WEB_DIR=riot-web
REACT_SDK_DIR=`pwd` REACT_SDK_DIR=`pwd`
scripts/travis/build.sh scripts/ci/build.sh
# run end to end tests # run end to end tests
scripts/fetchdep.sh matrix-org matrix-react-end-to-end-tests master scripts/fetchdep.sh matrix-org matrix-react-end-to-end-tests master
pushd matrix-react-end-to-end-tests pushd matrix-react-end-to-end-tests

View file

View file

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# #
# script which is run by the travis build (after `yarn test`). # script which is run by the CI build (after `yarn test`).
# #
# clones riot-web develop and runs the tests against our version of react-sdk. # clones riot-web develop and runs the tests against our version of react-sdk.
@ -8,7 +8,7 @@ set -ev
RIOT_WEB_DIR=riot-web RIOT_WEB_DIR=riot-web
scripts/travis/build.sh scripts/ci/build.sh
pushd "$RIOT_WEB_DIR" pushd "$RIOT_WEB_DIR"
yarn test yarn test
popd popd

10
scripts/ci/unit-tests.sh Normal file
View file

@ -0,0 +1,10 @@
#!/bin/bash
#
# script which is run by the CI build (after `yarn test`).
#
# clones riot-web develop and runs the tests against our version of react-sdk.
set -ev
scripts/ci/build.sh
yarn test

View file

@ -17,10 +17,11 @@ clone() {
fi fi
} }
# Try the PR author's branch in case it exists on the deps as well. # Try the PR author's branch in case it exists on the deps as well.
clone $TRAVIS_PULL_REQUEST_BRANCH clone $BUILDKITE_BRANCH
# Try the target branch of the push or PR. # Try the target branch of the push or PR.
clone $TRAVIS_BRANCH clone $BUILDKITE_PULL_REQUEST_BASE_BRANCH
# Try the current branch from Jenkins. # Try the current branch from Jenkins.
clone `"echo $GIT_BRANCH" | sed -e 's/^origin\///'` clone `"echo $GIT_BRANCH" | sed -e 's/^origin\///'`
# Use the default branch as the last resort. # Use the default branch as the last resort.

View file

@ -1,10 +0,0 @@
#!/bin/bash
#
# script which is run by the travis build (after `yarn test`).
#
# clones riot-web develop and runs the tests against our version of react-sdk.
set -ev
scripts/travis/build.sh
CHROME_BIN='/usr/bin/google-chrome-stable' yarn test

View file

@ -48,19 +48,13 @@ module.exports = React.createClass({
</p> </p>
<p> <p>
{ _t( { _t(
'Please install <chromeLink>Chrome</chromeLink> or <firefoxLink>Firefox</firefoxLink> ' + 'Please install <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, ' +
'for the best experience.', 'or <safariLink>Safari</safariLink> for the best experience.',
{}, {},
{ {
'chromeLink': (sub) => <a href="https://www.google.com/chrome">{sub}</a>, 'chromeLink': (sub) => <a href="https://www.google.com/chrome">{sub}</a>,
'firefoxLink': (sub) => <a href="https://getfirefox.com">{sub}</a>, 'firefoxLink': (sub) => <a href="https://firefox.com">{sub}</a>,
}, 'safariLink': (sub) => <a href="https://apple.com/safari">{sub}</a>,
)}
{ _t('<safariLink>Safari</safariLink> and <operaLink>Opera</operaLink> work too.',
{},
{
'safariLink': (sub) => <a href="http://apple.com/safari">{sub}</a>,
'operaLink': (sub) => <a href="http://opera.com">{sub}</a>,
}, },
)} )}
</p> </p>

View file

@ -84,7 +84,7 @@ class CustomRoomTagTile extends React.Component {
render() { render() {
const BaseAvatar = sdk.getComponent('avatars.BaseAvatar'); const BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
const RoomTooltip = sdk.getComponent('rooms.RoomTooltip'); const Tooltip = sdk.getComponent('rooms.Tooltip');
const tag = this.props.tag; const tag = this.props.tag;
const avatarHeight = 40; const avatarHeight = 40;
@ -103,7 +103,7 @@ class CustomRoomTagTile extends React.Component {
} }
const tip = (this.state.hover ? const tip = (this.state.hover ?
<RoomTooltip className="mx_TagTile_tooltip" label={name} /> : <Tooltip className="mx_TagTile_tooltip" label={name} /> :
<div />); <div />);
return ( return (
<AccessibleButton className={className} onClick={this.onClick}> <AccessibleButton className={className} onClick={this.onClick}>

View file

@ -70,6 +70,11 @@ module.exports = React.createClass({
fieldErrors: {}, fieldErrors: {},
// The ISO2 country code selected in the phone number entry // The ISO2 country code selected in the phone number entry
phoneCountry: this.props.defaultPhoneCountry, phoneCountry: this.props.defaultPhoneCountry,
username: "",
email: "",
phoneNumber: "",
password: "",
passwordConfirm: "",
}; };
}, },
@ -89,7 +94,7 @@ module.exports = React.createClass({
const self = this; const self = this;
if (this.allFieldsValid()) { if (this.allFieldsValid()) {
if (this.refs.email.value == '') { if (this.state.email == '') {
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
Modal.createTrackedDialog('If you don\'t specify an email address...', '', QuestionDialog, { Modal.createTrackedDialog('If you don\'t specify an email address...', '', QuestionDialog, {
title: _t("Warning!"), title: _t("Warning!"),
@ -112,13 +117,13 @@ module.exports = React.createClass({
}, },
_doSubmit: function(ev) { _doSubmit: function(ev) {
const email = this.refs.email.value.trim(); const email = this.state.email.trim();
const promise = this.props.onRegisterClick({ const promise = this.props.onRegisterClick({
username: this.refs.username.value.trim(), username: this.state.username.trim(),
password: this.refs.password.value.trim(), password: this.state.password.trim(),
email: email, email: email,
phoneCountry: this.state.phoneCountry, phoneCountry: this.state.phoneCountry,
phoneNumber: this.refs.phoneNumber ? this.refs.phoneNumber.value.trim() : '', phoneNumber: this.state.phoneNumber,
}); });
if (promise) { if (promise) {
@ -143,13 +148,13 @@ module.exports = React.createClass({
}, },
validateField: function(fieldID, eventType) { validateField: function(fieldID, eventType) {
const pwd1 = this.refs.password.value.trim(); const pwd1 = this.state.password.trim();
const pwd2 = this.refs.passwordConfirm.value.trim(); const pwd2 = this.state.passwordConfirm.trim();
const allowEmpty = eventType === "blur"; const allowEmpty = eventType === "blur";
switch (fieldID) { switch (fieldID) {
case FIELD_EMAIL: { case FIELD_EMAIL: {
const email = this.refs.email.value; const email = this.state.email;
const emailValid = email === '' || Email.looksValid(email); const emailValid = email === '' || Email.looksValid(email);
if (this._authStepIsRequired('m.login.email.identity') && (!emailValid || email === '')) { if (this._authStepIsRequired('m.login.email.identity') && (!emailValid || email === '')) {
this.markFieldValid(fieldID, false, "RegistrationForm.ERR_MISSING_EMAIL"); this.markFieldValid(fieldID, false, "RegistrationForm.ERR_MISSING_EMAIL");
@ -157,7 +162,7 @@ module.exports = React.createClass({
break; break;
} }
case FIELD_PHONE_NUMBER: { case FIELD_PHONE_NUMBER: {
const phoneNumber = this.refs.phoneNumber ? this.refs.phoneNumber.value : ''; const phoneNumber = this.state.phoneNumber;
const phoneNumberValid = phoneNumber === '' || phoneNumberLooksValid(phoneNumber); const phoneNumberValid = phoneNumber === '' || phoneNumberLooksValid(phoneNumber);
if (this._authStepIsRequired('m.login.msisdn') && (!phoneNumberValid || phoneNumber === '')) { if (this._authStepIsRequired('m.login.msisdn') && (!phoneNumberValid || phoneNumber === '')) {
this.markFieldValid(fieldID, false, "RegistrationForm.ERR_MISSING_PHONE_NUMBER"); this.markFieldValid(fieldID, false, "RegistrationForm.ERR_MISSING_PHONE_NUMBER");
@ -165,7 +170,7 @@ module.exports = React.createClass({
break; break;
} }
case FIELD_USERNAME: { case FIELD_USERNAME: {
const username = this.refs.username.value.trim(); const username = this.state.username;
if (allowEmpty && username === '') { if (allowEmpty && username === '') {
this.markFieldValid(fieldID, true); this.markFieldValid(fieldID, true);
} else if (!SAFE_LOCALPART_REGEX.test(username)) { } else if (!SAFE_LOCALPART_REGEX.test(username)) {
@ -230,21 +235,6 @@ module.exports = React.createClass({
this.props.onValidationChange(fieldErrors); this.props.onValidationChange(fieldErrors);
}, },
fieldElementById(fieldID) {
switch (fieldID) {
case FIELD_EMAIL:
return this.refs.email;
case FIELD_PHONE_NUMBER:
return this.refs.phoneNumber;
case FIELD_USERNAME:
return this.refs.username;
case FIELD_PASSWORD:
return this.refs.password;
case FIELD_PASSWORD_CONFIRM:
return this.refs.passwordConfirm;
}
},
_classForField: function(fieldID, ...baseClasses) { _classForField: function(fieldID, ...baseClasses) {
let cls = baseClasses.join(' '); let cls = baseClasses.join(' ');
if (this.state.fieldErrors[fieldID]) { if (this.state.fieldErrors[fieldID]) {
@ -258,14 +248,32 @@ module.exports = React.createClass({
this.validateField(FIELD_EMAIL, ev.type); this.validateField(FIELD_EMAIL, ev.type);
}, },
onEmailChange(ev) {
this.setState({
email: ev.target.value,
});
},
onPasswordBlur(ev) { onPasswordBlur(ev) {
this.validateField(FIELD_PASSWORD, ev.type); this.validateField(FIELD_PASSWORD, ev.type);
}, },
onPasswordChange(ev) {
this.setState({
password: ev.target.value,
});
},
onPasswordConfirmBlur(ev) { onPasswordConfirmBlur(ev) {
this.validateField(FIELD_PASSWORD_CONFIRM, ev.type); this.validateField(FIELD_PASSWORD_CONFIRM, ev.type);
}, },
onPasswordConfirmChange(ev) {
this.setState({
passwordConfirm: ev.target.value,
});
},
onPhoneCountryChange(newVal) { onPhoneCountryChange(newVal) {
this.setState({ this.setState({
phoneCountry: newVal.iso2, phoneCountry: newVal.iso2,
@ -277,10 +285,22 @@ module.exports = React.createClass({
this.validateField(FIELD_PHONE_NUMBER, ev.type); this.validateField(FIELD_PHONE_NUMBER, ev.type);
}, },
onPhoneNumberChange(ev) {
this.setState({
phoneNumber: ev.target.value,
});
},
onUsernameBlur(ev) { onUsernameBlur(ev) {
this.validateField(FIELD_USERNAME, ev.type); this.validateField(FIELD_USERNAME, ev.type);
}, },
onUsernameChange(ev) {
this.setState({
username: ev.target.value,
});
},
/** /**
* A step is required if all flows include that step. * A step is required if all flows include that step.
* *
@ -343,12 +363,12 @@ module.exports = React.createClass({
<Field <Field
className={this._classForField(FIELD_EMAIL)} className={this._classForField(FIELD_EMAIL)}
id="mx_RegistrationForm_email" id="mx_RegistrationForm_email"
ref="email"
type="text" type="text"
label={emailPlaceholder} label={emailPlaceholder}
defaultValue={this.props.defaultEmail} defaultValue={this.props.defaultEmail}
value={this.state.email} value={this.state.email}
onBlur={this.onEmailBlur} onBlur={this.onEmailBlur}
onChange={this.onEmailChange}
/> />
); );
} }
@ -370,13 +390,13 @@ module.exports = React.createClass({
phoneSection = <Field phoneSection = <Field
className={this._classForField(FIELD_PHONE_NUMBER)} className={this._classForField(FIELD_PHONE_NUMBER)}
id="mx_RegistrationForm_phoneNumber" id="mx_RegistrationForm_phoneNumber"
ref="phoneNumber"
type="text" type="text"
label={phoneLabel} label={phoneLabel}
defaultValue={this.props.defaultPhoneNumber} defaultValue={this.props.defaultPhoneNumber}
value={this.state.phoneNumber} value={this.state.phoneNumber}
prefix={phoneCountry} prefix={phoneCountry}
onBlur={this.onPhoneNumberBlur} onBlur={this.onPhoneNumberBlur}
onChange={this.onPhoneNumberChange}
/>; />;
} }
@ -395,32 +415,35 @@ module.exports = React.createClass({
<Field <Field
className={this._classForField(FIELD_USERNAME)} className={this._classForField(FIELD_USERNAME)}
id="mx_RegistrationForm_username" id="mx_RegistrationForm_username"
ref="username"
type="text" type="text"
autoFocus={true} autoFocus={true}
label={_t("Username")} label={_t("Username")}
defaultValue={this.props.defaultUsername} defaultValue={this.props.defaultUsername}
value={this.state.username}
onBlur={this.onUsernameBlur} onBlur={this.onUsernameBlur}
onChange={this.onUsernameChange}
/> />
</div> </div>
<div className="mx_AuthBody_fieldRow"> <div className="mx_AuthBody_fieldRow">
<Field <Field
className={this._classForField(FIELD_PASSWORD)} className={this._classForField(FIELD_PASSWORD)}
id="mx_RegistrationForm_password" id="mx_RegistrationForm_password"
ref="password"
type="password" type="password"
label={_t("Password")} label={_t("Password")}
defaultValue={this.props.defaultPassword} defaultValue={this.props.defaultPassword}
value={this.state.password}
onBlur={this.onPasswordBlur} onBlur={this.onPasswordBlur}
onChange={this.onPasswordChange}
/> />
<Field <Field
className={this._classForField(FIELD_PASSWORD_CONFIRM)} className={this._classForField(FIELD_PASSWORD_CONFIRM)}
id="mx_RegistrationForm_passwordConfirm" id="mx_RegistrationForm_passwordConfirm"
ref="passwordConfirm"
type="password" type="password"
label={_t("Confirm")} label={_t("Confirm")}
defaultValue={this.props.defaultPassword} defaultValue={this.props.defaultPassword}
value={this.state.passwordConfirm}
onBlur={this.onPasswordConfirmBlur} onBlur={this.onPasswordConfirmBlur}
onChange={this.onPasswordConfirmChange}
/> />
</div> </div>
<div className="mx_AuthBody_fieldRow"> <div className="mx_AuthBody_fieldRow">

View file

@ -53,12 +53,6 @@ export default class Field extends React.PureComponent {
}; };
} }
/* TODO: Remove this once `RegistrationForm` no longer uses refs */
get value() {
if (!this.refs.fieldInput) return null;
return this.refs.fieldInput.value;
}
onChange = (ev) => { onChange = (ev) => {
if (this.props.onValidate) { if (this.props.onValidate) {
const result = this.props.onValidate(ev.target.value); const result = this.props.onValidate(ev.target.value);

View file

@ -1293,8 +1293,7 @@
"Find other public servers or use a custom server": "Find other public servers or use a custom server", "Find other public servers or use a custom server": "Find other public servers or use a custom server",
"Sorry, your browser is <b>not</b> able to run Riot.": "Sorry, your browser is <b>not</b> able to run Riot.", "Sorry, your browser is <b>not</b> able to run Riot.": "Sorry, your browser is <b>not</b> able to run Riot.",
"Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.", "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.": "Riot uses many advanced browser features, some of which are not available or experimental in your current browser.",
"Please install <chromeLink>Chrome</chromeLink> or <firefoxLink>Firefox</firefoxLink> for the best experience.": "Please install <chromeLink>Chrome</chromeLink> or <firefoxLink>Firefox</firefoxLink> for the best experience.", "Please install <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, or <safariLink>Safari</safariLink> for the best experience.": "Please install <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, or <safariLink>Safari</safariLink> for the best experience.",
"<safariLink>Safari</safariLink> and <operaLink>Opera</operaLink> work too.": "<safariLink>Safari</safariLink> and <operaLink>Opera</operaLink> work too.",
"With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!", "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!",
"I understand the risks and wish to continue": "I understand the risks and wish to continue", "I understand the risks and wish to continue": "I understand the risks and wish to continue",
"Couldn't load page": "Couldn't load page", "Couldn't load page": "Couldn't load page",

View file

@ -4065,10 +4065,10 @@ just-extend@^4.0.2:
resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.0.2.tgz#f3f47f7dfca0f989c55410a7ebc8854b07108afc" resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.0.2.tgz#f3f47f7dfca0f989c55410a7ebc8854b07108afc"
integrity sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw== integrity sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==
karma-chrome-launcher@^0.2.3: karma-chrome-launcher@^2.2.0:
version "0.2.3" version "2.2.0"
resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-0.2.3.tgz#4c6d700d163a9d34c618efd87918be49e7a4a8c9" resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz#cf1b9d07136cc18fe239327d24654c3dbc368acf"
integrity sha1-TG1wDRY6nTTGGO/YeRi+SeekqMk= integrity sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==
dependencies: dependencies:
fs-access "^1.0.0" fs-access "^1.0.0"
which "^1.2.1" which "^1.2.1"