Merge branch 'develop' into travis/browser-support-docs
This commit is contained in:
commit
6ad2bb515f
17 changed files with 167 additions and 106 deletions
60
.buildkite/pipeline.yaml
Normal file
60
.buildkite/pipeline.yaml
Normal 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
|
38
.travis.yml
38
.travis.yml
|
@ -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
|
|
|
@ -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',
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
2
scripts/travis/build.sh → scripts/ci/build.sh
Executable file → Normal 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.
|
||||||
|
|
4
scripts/travis/end-to-end-tests.sh → scripts/ci/end-to-end-tests.sh
Executable file → Normal file
4
scripts/travis/end-to-end-tests.sh → scripts/ci/end-to-end-tests.sh
Executable file → Normal 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
|
0
scripts/travis/install-deps.sh → scripts/ci/install-deps.sh
Executable file → Normal file
0
scripts/travis/install-deps.sh → scripts/ci/install-deps.sh
Executable file → Normal file
4
scripts/travis/riot-unit-tests.sh → scripts/ci/riot-unit-tests.sh
Executable file → Normal file
4
scripts/travis/riot-unit-tests.sh → scripts/ci/riot-unit-tests.sh
Executable file → Normal 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
10
scripts/ci/unit-tests.sh
Normal 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
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
|
|
@ -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}>
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue