Migrate string refs over to createRef

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski 2019-12-08 12:16:17 +00:00
parent 4c55f3c5b5
commit d22985f12e
39 changed files with 438 additions and 302 deletions

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React, {createRef} from 'react';
import createReactClass from 'create-react-class';
import PropTypes from 'prop-types';
import { _t } from '../../../languageHandler';
@ -48,6 +48,8 @@ module.exports = createReactClass({
componentWillMount: function() {
this._captchaWidgetId = null;
this._recaptchaContainer = createRef();
},
componentDidMount: function() {
@ -67,7 +69,7 @@ module.exports = createReactClass({
scriptTag.setAttribute(
'src', `${protocol}//www.recaptcha.net/recaptcha/api.js?onload=mx_on_recaptcha_loaded&render=explicit`,
);
this.refs.recaptchaContainer.appendChild(scriptTag);
this._recaptchaContainer.current.appendChild(scriptTag);
}
},
@ -124,11 +126,11 @@ module.exports = createReactClass({
}
return (
<div ref="recaptchaContainer">
<div ref={this._recaptchaContainer}>
<p>{_t(
"This homeserver would like to make sure you are not a robot.",
)}</p>
<div id={DIV_ID}></div>
<div id={DIV_ID} />
{ error }
</div>
);

View file

@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React, {createRef} from 'react';
import createReactClass from 'create-react-class';
import PropTypes from 'prop-types';
import url from 'url';
@ -581,6 +581,8 @@ export const FallbackAuthEntry = createReactClass({
// the popup if we open it immediately.
this._popupWindow = null;
window.addEventListener("message", this._onReceiveMessage);
this._fallbackButton = createRef();
},
componentWillUnmount: function() {
@ -591,8 +593,8 @@ export const FallbackAuthEntry = createReactClass({
},
focus: function() {
if (this.refs.fallbackButton) {
this.refs.fallbackButton.focus();
if (this._fallbackButton.current) {
this._fallbackButton.current.focus();
}
},
@ -624,7 +626,7 @@ export const FallbackAuthEntry = createReactClass({
}
return (
<div>
<a ref="fallbackButton" onClick={this._onShowFallbackClick}>{ _t("Start authentication") }</a>
<a ref={this._fallbackButton} onClick={this._onShowFallbackClick}>{ _t("Start authentication") }</a>
{errorSection}
</div>
);

View file

@ -17,7 +17,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
import createReactClass from 'create-react-class';
@ -106,10 +106,14 @@ module.exports = createReactClass({
};
},
UNSAFE_componentWillMount: function() {
this._textinput = createRef();
},
componentDidMount: function() {
if (this.props.focus) {
// Set the cursor at the end of the text input
this.refs.textinput.value = this.props.value;
this._textinput.current.value = this.props.value;
}
},
@ -126,8 +130,8 @@ module.exports = createReactClass({
let selectedList = this.state.selectedList.slice();
// Check the text input field to see if user has an unconverted address
// If there is and it's valid add it to the local selectedList
if (this.refs.textinput.value !== '') {
selectedList = this._addAddressesToList([this.refs.textinput.value]);
if (this._textinput.current.value !== '') {
selectedList = this._addAddressesToList([this._textinput.current.value]);
if (selectedList === null) return;
}
this.props.onFinished(true, selectedList);
@ -154,23 +158,23 @@ module.exports = createReactClass({
e.stopPropagation();
e.preventDefault();
if (this.addressSelector) this.addressSelector.chooseSelection();
} else if (this.refs.textinput.value.length === 0 && this.state.selectedList.length && e.keyCode === 8) { // backspace
} else if (this._textinput.current.value.length === 0 && this.state.selectedList.length && e.keyCode === 8) { // backspace
e.stopPropagation();
e.preventDefault();
this.onDismissed(this.state.selectedList.length - 1)();
} else if (e.keyCode === 13) { // enter
e.stopPropagation();
e.preventDefault();
if (this.refs.textinput.value === '') {
if (this._textinput.current.value === '') {
// if there's nothing in the input box, submit the form
this.onButtonClick();
} else {
this._addAddressesToList([this.refs.textinput.value]);
this._addAddressesToList([this._textinput.current.value]);
}
} else if (e.keyCode === 188 || e.keyCode === 9) { // comma or tab
e.stopPropagation();
e.preventDefault();
this._addAddressesToList([this.refs.textinput.value]);
this._addAddressesToList([this._textinput.current.value]);
}
},
@ -647,7 +651,7 @@ module.exports = createReactClass({
onPaste={this._onPaste}
rows="1"
id="textinput"
ref="textinput"
ref={this._textinput}
className="mx_AddressPickerDialog_input"
onChange={this.onQueryChanged}
placeholder={this.getPlaceholder()}

View file

@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React, {createRef} from 'react';
import createReactClass from 'create-react-class';
import PropTypes from 'prop-types';
import sdk from '../../../index';
@ -62,8 +62,13 @@ export default createReactClass({
};
},
UNSAFE_componentWillMount: function() {
this._input_value = createRef();
this._uiAuth = createRef();
},
componentDidMount: function() {
this.refs.input_value.select();
this._input_value.current.select();
this._matrixClient = MatrixClientPeg.get();
},
@ -102,8 +107,8 @@ export default createReactClass({
},
onSubmit: function(ev) {
if (this.refs.uiAuth) {
this.refs.uiAuth.tryContinue();
if (this._uiAuth.current) {
this._uiAuth.current.tryContinue();
}
this.setState({
doingUIAuth: true,
@ -215,7 +220,7 @@ export default createReactClass({
onAuthFinished={this._onUIAuthFinished}
inputs={{}}
poll={true}
ref="uiAuth"
ref={this._uiAuth}
continueIsManaged={true}
/>;
}
@ -257,7 +262,7 @@ export default createReactClass({
>
<div className="mx_Dialog_content" id='mx_Dialog_content'>
<div className="mx_SetMxIdDialog_input_group">
<input type="text" ref="input_value" value={this.state.username}
<input type="text" ref={this._input_value} value={this.state.username}
autoFocus={true}
onChange={this.onValueChange}
onKeyUp={this.onKeyUp}

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
import {Room, User, Group, RoomMember, MatrixEvent} from 'matrix-js-sdk';
import sdk from '../../../index';
@ -74,6 +74,8 @@ export default class ShareDialog extends React.Component {
// MatrixEvent defaults to share linkSpecificEvent
linkSpecificEvent: this.props.target instanceof MatrixEvent,
};
this._link = createRef();
}
static _selectText(target) {
@ -94,7 +96,7 @@ export default class ShareDialog extends React.Component {
onCopyClick(e) {
e.preventDefault();
ShareDialog._selectText(this.refs.link);
ShareDialog._selectText(this._link.current);
let successful;
try {
@ -195,7 +197,7 @@ export default class ShareDialog extends React.Component {
>
<div className="mx_ShareDialog_content">
<div className="mx_ShareDialog_matrixto">
<a ref="link"
<a ref={this._link}
href={matrixToUrl}
onClick={ShareDialog.onLinkClick}
className="mx_ShareDialog_matrixto_link"

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React, {createRef} from 'react';
import createReactClass from 'create-react-class';
import PropTypes from 'prop-types';
import sdk from '../../../index';
@ -42,15 +42,19 @@ export default createReactClass({
};
},
UNSAFE_componentWillMount: function() {
this._textinput = createRef();
},
componentDidMount: function() {
if (this.props.focus) {
// Set the cursor at the end of the text input
this.refs.textinput.value = this.props.value;
this._textinput.current.value = this.props.value;
}
},
onOk: function() {
this.props.onFinished(true, this.refs.textinput.value);
this.props.onFinished(true, this._textinput.current.value);
},
onCancel: function() {
@ -70,7 +74,13 @@ export default createReactClass({
<label htmlFor="textinput"> { this.props.description } </label>
</div>
<div>
<input id="textinput" ref="textinput" className="mx_TextInputDialog_input" defaultValue={this.props.value} autoFocus={this.props.focus} size="64" />
<input
id="textinput"
ref={this._textinput}
className="mx_TextInputDialog_input"
defaultValue={this.props.value}
autoFocus={this.props.focus}
size="64" />
</div>
</div>
</form>

View file

@ -64,6 +64,8 @@ export default class AppTile extends React.Component {
this._onReloadWidgetClick = this._onReloadWidgetClick.bind(this);
this._contextMenuButton = createRef();
this._appFrame = createRef();
this._menu_bar = createRef();
}
/**
@ -337,14 +339,14 @@ export default class AppTile extends React.Component {
// HACK: This is a really dirty way to ensure that Jitsi cleans up
// its hold on the webcam. Without this, the widget holds a media
// stream open, even after death. See https://github.com/vector-im/riot-web/issues/7351
if (this.refs.appFrame) {
if (this._appFrame.current) {
// In practice we could just do `+= ''` to trick the browser
// into thinking the URL changed, however I can foresee this
// being optimized out by a browser. Instead, we'll just point
// the iframe at a page that is reasonably safe to use in the
// event the iframe doesn't wink away.
// This is relative to where the Riot instance is located.
this.refs.appFrame.src = 'about:blank';
this._appFrame.current.src = 'about:blank';
}
WidgetUtils.setRoomWidget(
@ -389,7 +391,7 @@ export default class AppTile extends React.Component {
// FIXME: There's probably no reason to do this here: it should probably be done entirely
// in ActiveWidgetStore.
const widgetMessaging = new WidgetMessaging(
this.props.id, this.props.url, this.props.userWidget, this.refs.appFrame.contentWindow);
this.props.id, this.props.url, this.props.userWidget, this._appFrame.current.contentWindow);
ActiveWidgetStore.setWidgetMessaging(this.props.id, widgetMessaging);
widgetMessaging.getCapabilities().then((requestedCapabilities) => {
console.log(`Widget ${this.props.id} requested capabilities: ` + requestedCapabilities);
@ -496,7 +498,7 @@ export default class AppTile extends React.Component {
ev.preventDefault();
// Ignore clicks on menu bar children
if (ev.target !== this.refs.menu_bar) {
if (ev.target !== this._menu_bar.current) {
return;
}
@ -555,7 +557,7 @@ export default class AppTile extends React.Component {
_onReloadWidgetClick() {
// Reload iframe in this way to avoid cross-origin restrictions
this.refs.appFrame.src = this.refs.appFrame.src;
this._appFrame.current.src = this._appFrame.current.src;
}
_onContextMenuClick = () => {
@ -626,7 +628,7 @@ export default class AppTile extends React.Component {
{ this.state.loading && loadingElement }
<iframe
allow={iframeFeatures}
ref="appFrame"
ref={this._appFrame}
src={this._getSafeUrl()}
allowFullScreen={true}
sandbox={sandboxFlags}
@ -694,7 +696,7 @@ export default class AppTile extends React.Component {
return <React.Fragment>
<div className={appTileClass} id={this.props.id}>
{ this.props.showMenubar &&
<div ref="menu_bar" className={menuBarClasses} onClick={this.onClickMenuBar}>
<div ref={this._menu_bar} className={menuBarClasses} onClick={this.onClickMenuBar}>
<span className="mx_AppTileMenuBarTitle" style={{pointerEvents: (this.props.handleMinimisePointerEvents ? 'all' : false)}}>
{ /* Minimise widget */ }
{ showMinimiseButton && <AccessibleButton

View file

@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
import createReactClass from 'create-react-class';
import {Key} from "../../../Keyboard";
@ -65,7 +65,7 @@ module.exports = createReactClass({
componentWillReceiveProps: function(nextProps) {
if (nextProps.initialValue !== this.props.initialValue) {
this.value = nextProps.initialValue;
if (this.refs.editable_div) {
if (this._editable_div.current) {
this.showPlaceholder(!this.value);
}
}
@ -76,24 +76,27 @@ module.exports = createReactClass({
// as React doesn't play nice with contentEditable.
this.value = '';
this.placeholder = false;
this._editable_div = createRef();
},
componentDidMount: function() {
this.value = this.props.initialValue;
if (this.refs.editable_div) {
if (this._editable_div.current) {
this.showPlaceholder(!this.value);
}
},
showPlaceholder: function(show) {
if (show) {
this.refs.editable_div.textContent = this.props.placeholder;
this.refs.editable_div.setAttribute("class", this.props.className + " " + this.props.placeholderClassName);
this._editable_div.current.textContent = this.props.placeholder;
this._editable_div.current.setAttribute("class", this.props.className
+ " " + this.props.placeholderClassName);
this.placeholder = true;
this.value = '';
} else {
this.refs.editable_div.textContent = this.value;
this.refs.editable_div.setAttribute("class", this.props.className);
this._editable_div.current.textContent = this.value;
this._editable_div.current.setAttribute("class", this.props.className);
this.placeholder = false;
}
},
@ -120,7 +123,7 @@ module.exports = createReactClass({
this.value = this.props.initialValue;
this.showPlaceholder(!this.value);
this.onValueChanged(false);
this.refs.editable_div.blur();
this._editable_div.current.blur();
},
onValueChanged: function(shouldSubmit) {
@ -219,7 +222,7 @@ module.exports = createReactClass({
</div>;
} else {
// show the content editable div, but manually manage its contents as react and contentEditable don't play nice together
editableEl = <div ref="editable_div"
editableEl = <div ref={this._editable_div}
contentEditable={true}
className={className}
onKeyDown={this.onKeyDown}

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
import createReactClass from 'create-react-class';
import { _t } from '../../../languageHandler';
@ -34,6 +34,10 @@ module.exports = createReactClass({
};
},
UNSAFE_componentWillMount: function() {
this._user_id_input = createRef();
},
addUser: function(user_id) {
if (this.props.selected_users.indexOf(user_id == -1)) {
this.props.onChange(this.props.selected_users.concat([user_id]));
@ -47,20 +51,20 @@ module.exports = createReactClass({
},
onAddUserId: function() {
this.addUser(this.refs.user_id_input.value);
this.refs.user_id_input.value = "";
this.addUser(this._user_id_input.current.value);
this._user_id_input.current.value = "";
},
render: function() {
const self = this;
return (
<div>
<ul className="mx_UserSelector_UserIdList" ref="list">
<ul className="mx_UserSelector_UserIdList">
{ this.props.selected_users.map(function(user_id, i) {
return <li key={user_id}>{ user_id } - <span onClick={function() {self.removeUser(user_id);}}>X</span></li>;
}) }
</ul>
<input type="text" ref="user_id_input" defaultValue="" className="mx_UserSelector_userIdInput" placeholder={_t("ex. @bob:example.com")} />
<input type="text" ref={this._user_id_input} defaultValue="" className="mx_UserSelector_userIdInput" placeholder={_t("ex. @bob:example.com")} />
<button onClick={this.onAddUserId} className="mx_UserSelector_AddUserId">
{ _t("Add User") }
</button>

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
import * as HtmlUtils from '../../../HtmlUtils';
import { editBodyDiffToHtml } from '../../../utils/MessageDiffUtils';
@ -51,6 +51,8 @@ export default class EditHistoryMessage extends React.PureComponent {
}
const canRedact = room.currentState.maySendRedactionForEvent(event, userId);
this.state = {canRedact, sendStatus: event.getAssociatedStatus()};
this._content = createRef();
}
_onAssociatedStatusChanged = () => {
@ -78,8 +80,8 @@ export default class EditHistoryMessage extends React.PureComponent {
pillifyLinks() {
// not present for redacted events
if (this.refs.content) {
pillifyLinks(this.refs.content.children, this.props.mxEvent);
if (this._content.current) {
pillifyLinks(this._content.current.children, this.props.mxEvent);
}
}
@ -140,13 +142,13 @@ export default class EditHistoryMessage extends React.PureComponent {
if (mxEvent.getContent().msgtype === "m.emote") {
const name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender();
contentContainer = (
<div className="mx_EventTile_content" ref="content">*&nbsp;
<div className="mx_EventTile_content" ref={this._content}>*&nbsp;
<span className="mx_MEmoteBody_sender">{ name }</span>
&nbsp;{contentElements}
</div>
);
} else {
contentContainer = <div className="mx_EventTile_content" ref="content">{contentElements}</div>;
contentContainer = <div className="mx_EventTile_content" ref={this._content}>{contentElements}</div>;
}
}

View file

@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
import createReactClass from 'create-react-class';
import filesize from 'filesize';
@ -251,6 +251,12 @@ module.exports = createReactClass({
return MatrixClientPeg.get().mxcUrlToHttp(content.url);
},
UNSAFE_componentWillMount: function() {
this._iframe = createRef();
this._dummyLink = createRef();
this._downloadImage = createRef();
},
componentDidMount: function() {
// Add this to the list of mounted components to receive notifications
// when the tint changes.
@ -272,17 +278,17 @@ module.exports = createReactClass({
tint: function() {
// Update our tinted copy of require("../../../../res/img/download.svg")
if (this.refs.downloadImage) {
this.refs.downloadImage.src = tintedDownloadImageURL;
if (this._downloadImage.current) {
this._downloadImage.current.src = tintedDownloadImageURL;
}
if (this.refs.iframe) {
if (this._iframe.current) {
// If the attachment is encrypted then the download image
// will be inside the iframe so we wont be able to update
// it directly.
this.refs.iframe.contentWindow.postMessage({
this._iframe.current.contentWindow.postMessage({
code: remoteSetTint.toString(),
imgSrc: tintedDownloadImageURL,
style: computedStyle(this.refs.dummyLink),
style: computedStyle(this._dummyLink.current),
}, "*");
}
},
@ -340,7 +346,7 @@ module.exports = createReactClass({
ev.target.contentWindow.postMessage({
code: remoteRender.toString(),
imgSrc: tintedDownloadImageURL,
style: computedStyle(this.refs.dummyLink),
style: computedStyle(this._dummyLink.current),
blob: this.state.decryptedBlob,
// Set a download attribute for encrypted files so that the file
// will have the correct name when the user tries to download it.
@ -367,9 +373,9 @@ module.exports = createReactClass({
* We'll use it to learn how the download link
* would have been styled if it was rendered inline.
*/ }
<a ref="dummyLink" />
<a ref={this._dummyLink} />
</div>
<iframe src={renderer_url} onLoad={onIframeLoad} ref="iframe" />
<iframe src={renderer_url} onLoad={onIframeLoad} ref={this._iframe} />
</div>
</span>
);
@ -439,7 +445,7 @@ module.exports = createReactClass({
<span className="mx_MFileBody">
<div className="mx_MFileBody_download">
<a {...downloadProps}>
<img src={tintedDownloadImageURL} width="12" height="14" ref="downloadImage" />
<img src={tintedDownloadImageURL} width="12" height="14" ref={this._downloadImage} />
{ _t("Download %(text)s", { text: text }) }
</a>
</div>

View file

@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
import { MatrixClient } from 'matrix-js-sdk';
@ -65,6 +65,8 @@ export default class MImageBody extends React.Component {
hover: false,
showImage: SettingsStore.getValue("showImages"),
};
this._image = createRef();
}
componentWillMount() {
@ -158,8 +160,8 @@ export default class MImageBody extends React.Component {
let loadedImageDimensions;
if (this.refs.image) {
const { naturalWidth, naturalHeight } = this.refs.image;
if (this._image.current) {
const { naturalWidth, naturalHeight } = this._image.current;
// this is only used as a fallback in case content.info.w/h is missing
loadedImageDimensions = { naturalWidth, naturalHeight };
}
@ -342,7 +344,7 @@ export default class MImageBody extends React.Component {
imageElement = <HiddenImagePlaceholder />;
} else {
imageElement = (
<img style={{display: 'none'}} src={thumbUrl} ref="image"
<img style={{display: 'none'}} src={thumbUrl} ref={this._image}
alt={content.body}
onError={this.onImageError}
onLoad={this.onImageLoad}
@ -385,7 +387,7 @@ export default class MImageBody extends React.Component {
// which has the same width as the timeline
// mx_MImageBody_thumbnail resizes img to exactly container size
img = (
<img className="mx_MImageBody_thumbnail" src={thumbUrl} ref="image"
<img className="mx_MImageBody_thumbnail" src={thumbUrl} ref={this._image}
style={{ maxWidth: maxWidth + "px" }}
alt={content.body}
onError={this.onImageError}

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
import createReactClass from 'create-react-class';
import sdk from '../../../index';
@ -47,8 +47,12 @@ module.exports = createReactClass({
maxImageHeight: PropTypes.number,
},
UNSAFE_componentWillMount: function() {
this._body = createRef();
},
getEventTileOps: function() {
return this.refs.body && this.refs.body.getEventTileOps ? this.refs.body.getEventTileOps() : null;
return this._body.current && this._body.current.getEventTileOps ? this._body.current.getEventTileOps() : null;
},
onTileUpdate: function() {
@ -103,7 +107,8 @@ module.exports = createReactClass({
}
return <BodyType
ref="body" mxEvent={this.props.mxEvent}
ref={this._body}
mxEvent={this.props.mxEvent}
highlights={this.props.highlights}
highlightLink={this.props.highlightLink}
showUrlPreview={this.props.showUrlPreview}

View file

@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React, {createRef} from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import createReactClass from 'create-react-class';
@ -86,6 +86,10 @@ module.exports = createReactClass({
return successful;
},
UNSAFE_componentWillMount: function() {
this._content = createRef();
},
componentDidMount: function() {
this._unmounted = false;
if (!this.props.editState) {
@ -94,13 +98,13 @@ module.exports = createReactClass({
},
_applyFormatting() {
this.activateSpoilers(this.refs.content.children);
this.activateSpoilers(this._content.current.children);
// pillifyLinks BEFORE linkifyElement because plain room/user URLs in the composer
// are still sent as plaintext URLs. If these are ever pillified in the composer,
// we should be pillify them here by doing the linkifying BEFORE the pillifying.
pillifyLinks(this.refs.content.children, this.props.mxEvent);
HtmlUtils.linkifyElement(this.refs.content);
pillifyLinks(this._content.current.children, this.props.mxEvent);
HtmlUtils.linkifyElement(this._content.current);
this.calculateUrlPreview();
if (this.props.mxEvent.getContent().format === "org.matrix.custom.html") {
@ -163,7 +167,7 @@ module.exports = createReactClass({
//console.info("calculateUrlPreview: ShowUrlPreview for %s is %s", this.props.mxEvent.getId(), this.props.showUrlPreview);
if (this.props.showUrlPreview) {
let links = this.findLinks(this.refs.content.children);
let links = this.findLinks(this._content.current.children);
if (links.length) {
// de-dup the links (but preserve ordering)
const seen = new Set();
@ -327,7 +331,7 @@ module.exports = createReactClass({
},
getInnerText: () => {
return this.refs.content.innerText;
return this._content.current.innerText;
},
};
},
@ -452,7 +456,7 @@ module.exports = createReactClass({
case "m.emote":
const name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender();
return (
<span ref="content" className="mx_MEmoteBody mx_EventTile_content">
<span ref={this._content} className="mx_MEmoteBody mx_EventTile_content">
*&nbsp;
<span
className="mx_MEmoteBody_sender"
@ -467,14 +471,14 @@ module.exports = createReactClass({
);
case "m.notice":
return (
<span ref="content" className="mx_MNoticeBody mx_EventTile_content">
<span ref={this._content} className="mx_MNoticeBody mx_EventTile_content">
{ body }
{ widgets }
</span>
);
default: // including "m.text"
return (
<span ref="content" className="mx_MTextBody mx_EventTile_content">
<span ref={this._content} className="mx_MTextBody mx_EventTile_content">
{ body }
{ widgets }
</span>

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
import {_t} from "../../../languageHandler";
import MatrixClientPeg from "../../../MatrixClientPeg";
@ -58,13 +58,15 @@ export default class RoomProfileSettings extends React.Component {
canSetTopic: room.currentState.maySendStateEvent('m.room.topic', client.getUserId()),
canSetAvatar: room.currentState.maySendStateEvent('m.room.avatar', client.getUserId()),
};
this._avatarUpload = createRef();
}
_uploadAvatar = (e) => {
e.stopPropagation();
e.preventDefault();
this.refs.avatarUpload.click();
this._avatarUpload.current.click();
};
_saveProfile = async (e) => {
@ -178,7 +180,7 @@ export default class RoomProfileSettings extends React.Component {
return (
<form onSubmit={this._saveProfile} autoComplete="off" noValidate={true}>
<input type="file" ref="avatarUpload" className="mx_ProfileSettings_avatarUpload"
<input type="file" ref={this._avatarUpload} className="mx_ProfileSettings_avatarUpload"
onChange={this._onAvatarChanged} accept="image/*" />
<div className="mx_ProfileSettings_profile">
<div className="mx_ProfileSettings_controls">

View file

@ -19,7 +19,7 @@ limitations under the License.
import ReplyThread from "../elements/ReplyThread";
import React from 'react';
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
import createReactClass from 'create-react-class';
const classNames = require("classnames");
@ -224,6 +224,9 @@ module.exports = createReactClass({
// don't do RR animations until we are mounted
this._suppressReadReceiptAnimation = true;
this._verifyEvent(this.props.mxEvent);
this._tile = createRef();
this._replyThread = createRef();
},
componentDidMount: function() {
@ -512,11 +515,11 @@ module.exports = createReactClass({
},
getTile() {
return this.refs.tile;
return this._tile.current;
},
getReplyThread() {
return this.refs.replyThread;
return this._replyThread.current;
},
getReactions() {
@ -748,7 +751,7 @@ module.exports = createReactClass({
</a>
</div>
<div className="mx_EventTile_line">
<EventTileType ref="tile"
<EventTileType ref={this._tile}
mxEvent={this.props.mxEvent}
highlights={this.props.highlights}
highlightLink={this.props.highlightLink}
@ -762,7 +765,7 @@ module.exports = createReactClass({
return (
<div className={classes}>
<div className="mx_EventTile_line">
<EventTileType ref="tile"
<EventTileType ref={this._tile}
mxEvent={this.props.mxEvent}
highlights={this.props.highlights}
highlightLink={this.props.highlightLink}
@ -792,7 +795,7 @@ module.exports = createReactClass({
this.props.mxEvent,
this.props.onHeightChanged,
this.props.permalinkCreator,
'replyThread',
this._replyThread,
);
}
return (
@ -805,7 +808,7 @@ module.exports = createReactClass({
</a>
{ !isBubbleMessage && this._renderE2EPadlock() }
{ thread }
<EventTileType ref="tile"
<EventTileType ref={this._tile}
mxEvent={this.props.mxEvent}
highlights={this.props.highlights}
highlightLink={this.props.highlightLink}
@ -820,7 +823,7 @@ module.exports = createReactClass({
this.props.mxEvent,
this.props.onHeightChanged,
this.props.permalinkCreator,
'replyThread',
this._replyThread,
);
// tab-index=-1 to allow it to be focusable but do not add tab stop for it, primarily for screen readers
return (
@ -839,7 +842,7 @@ module.exports = createReactClass({
</a>
{ !isBubbleMessage && this._renderE2EPadlock() }
{ thread }
<EventTileType ref="tile"
<EventTileType ref={this._tile}
mxEvent={this.props.mxEvent}
replacingEventId={this.props.replacingEventId}
editState={this.props.editState}

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
import createReactClass from 'create-react-class';
import { linkifyElement } from '../../../HtmlUtils';
@ -54,17 +54,19 @@ module.exports = createReactClass({
}, (error)=>{
console.error("Failed to get URL preview: " + error);
});
this._description = createRef();
},
componentDidMount: function() {
if (this.refs.description) {
linkifyElement(this.refs.description);
if (this._description.current) {
linkifyElement(this._description.current);
}
},
componentDidUpdate: function() {
if (this.refs.description) {
linkifyElement(this.refs.description);
if (this._description.current) {
linkifyElement(this._description.current);
}
},
@ -129,7 +131,7 @@ module.exports = createReactClass({
<div className="mx_LinkPreviewWidget_caption">
<div className="mx_LinkPreviewWidget_title"><a href={this.props.link} target="_blank" rel="noopener">{ p["og:title"] }</a></div>
<div className="mx_LinkPreviewWidget_siteName">{ p["og:site_name"] ? (" - " + p["og:site_name"]) : null }</div>
<div className="mx_LinkPreviewWidget_description" ref="description">
<div className="mx_LinkPreviewWidget_description" ref={this._description}>
{ p["og:description"] }
</div>
</div>

View file

@ -14,7 +14,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
import { _t } from '../../../languageHandler';
import CallHandler from '../../../CallHandler';
@ -111,6 +111,8 @@ class UploadButton extends React.Component {
super(props, context);
this.onUploadClick = this.onUploadClick.bind(this);
this.onUploadFileInputChange = this.onUploadFileInputChange.bind(this);
this._uploadInput = createRef();
}
onUploadClick(ev) {
@ -118,7 +120,7 @@ class UploadButton extends React.Component {
dis.dispatch({action: 'require_registration'});
return;
}
this.refs.uploadInput.click();
this._uploadInput.current.click();
}
onUploadFileInputChange(ev) {
@ -150,7 +152,9 @@ class UploadButton extends React.Component {
onClick={this.onUploadClick}
title={_t('Upload file')}
>
<input ref="uploadInput" type="file"
<input
ref={this._uploadInput}
type="file"
style={uploadInputStyle}
multiple
onChange={this.onUploadFileInputChange}

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from "react";
import React, {createRef} from "react";
import dis from "../../../dispatcher";
import MatrixClientPeg from "../../../MatrixClientPeg";
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
@ -45,6 +45,8 @@ export default class RoomBreadcrumbs extends React.Component {
// The room IDs we're waiting to come down the Room handler and when we
// started waiting for them. Used to track a room over an upgrade/autojoin.
this._waitingRoomQueue = [/* { roomId, addedTs } */];
this._scroller = createRef();
}
componentWillMount() {
@ -284,8 +286,8 @@ export default class RoomBreadcrumbs extends React.Component {
}
this.setState({rooms});
if (this.refs.scroller) {
this.refs.scroller.moveToOrigin();
if (this._scroller.current) {
this._scroller.current.moveToOrigin();
}
// We don't track room aesthetics (badges, membership, etc) over the wire so we
@ -390,7 +392,7 @@ export default class RoomBreadcrumbs extends React.Component {
return (
<div role="toolbar" aria-label={_t("Recent rooms")}>
<IndicatorScrollbar
ref="scroller"
ref={this._scroller}
className="mx_RoomBreadcrumbs"
trackHorizontalOverflow={true}
verticalScrollsHorizontally={true}

View file

@ -15,7 +15,7 @@ limitations under the License.
*/
import sdk from '../../../index';
import React from 'react';
import React, {createRef} from 'react';
import { _t } from '../../../languageHandler';
import { linkifyElement } from '../../../HtmlUtils';
import { ContentRepo } from 'matrix-js-sdk';
@ -49,11 +49,15 @@ export default createReactClass({
},
_linkifyTopic: function() {
if (this.refs.topic) {
linkifyElement(this.refs.topic);
if (this._topic.current) {
linkifyElement(this._topic.current);
}
},
UNSAFE_componentWillMount: function() {
this._topic = createRef();
},
componentDidMount: function() {
this._linkifyTopic();
},
@ -104,7 +108,7 @@ export default createReactClass({
<td className="mx_RoomDirectory_roomDescription">
<div className="mx_RoomDirectory_name">{ name }</div>&nbsp;
{ perms }
<div className="mx_RoomDirectory_topic" ref="topic" onClick={this.onTopicClick}>
<div className="mx_RoomDirectory_topic" ref={this._topic} onClick={this.onTopicClick}>
{ room.topic }
</div>
<div className="mx_RoomDirectory_alias">{ getDisplayAliasForRoom(room) }</div>

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
import createReactClass from 'create-react-class';
import classNames from 'classnames';
@ -56,6 +56,10 @@ module.exports = createReactClass({
};
},
UNSAFE_componentWillMount: function() {
this._topic = createRef();
},
componentDidMount: function() {
const cli = MatrixClientPeg.get();
cli.on("RoomState.events", this._onRoomStateEvents);
@ -70,8 +74,8 @@ module.exports = createReactClass({
},
componentDidUpdate: function() {
if (this.refs.topic) {
linkifyElement(this.refs.topic);
if (this._topic.current) {
linkifyElement(this._topic.current);
}
},
@ -204,7 +208,7 @@ module.exports = createReactClass({
}
}
const topicElement =
<div className="mx_RoomHeader_topic" ref="topic" title={topic} dir="auto">{ topic }</div>;
<div className="mx_RoomHeader_topic" ref={this._topic} title={topic} dir="auto">{ topic }</div>;
const avatarSize = 28;
let roomAvatar;
if (this.props.room) {

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React, {createRef} from 'react';
import createReactClass from 'create-react-class';
const classNames = require('classnames');
const AccessibleButton = require('../../../components/views/elements/AccessibleButton');
@ -29,6 +29,10 @@ module.exports = createReactClass({
});
},
UNSAFE_componentWillMount: function() {
this._search_term = createRef();
},
onThisRoomClick: function() {
this.setState({ scope: 'Room' }, () => this._searchIfQuery());
},
@ -47,13 +51,13 @@ module.exports = createReactClass({
},
_searchIfQuery: function() {
if (this.refs.search_term.value) {
if (this._search_term.current.value) {
this.onSearch();
}
},
onSearch: function() {
this.props.onSearch(this.refs.search_term.value, this.state.scope);
this.props.onSearch(this._search_term.current.value, this.state.scope);
},
render: function() {
@ -66,10 +70,10 @@ module.exports = createReactClass({
<AccessibleButton className={ thisRoomClasses } onClick={this.onThisRoomClick}>{_t("This Room")}</AccessibleButton>
<AccessibleButton className={ allRoomsClasses } onClick={this.onAllRoomsClick}>{_t("All Rooms")}</AccessibleButton>
<div className="mx_SearchBar_input mx_textinput">
<input ref="search_term" type="text" autoFocus={true} placeholder={_t("Search…")} onKeyDown={this.onSearchChange} />
<AccessibleButton className={ searchButtonClasses } onClick={this.onSearch}></AccessibleButton>
<input ref={this._search_term} type="text" autoFocus={true} placeholder={_t("Search…")} onKeyDown={this.onSearchChange} />
<AccessibleButton className={ searchButtonClasses } onClick={this.onSearch} />
</div>
<AccessibleButton className="mx_SearchBar_cancel" onClick={this.props.onCancelClick}></AccessibleButton>
<AccessibleButton className="mx_SearchBar_cancel" onClick={this.props.onCancelClick} />
</div>
);
},

View file

@ -14,12 +14,11 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
import { _t, _td } from '../../../languageHandler';
import CallHandler from '../../../CallHandler';
import MatrixClientPeg from '../../../MatrixClientPeg';
import Modal from '../../../Modal';
import sdk from '../../../index';
import dis from '../../../dispatcher';
import RoomViewStore from '../../../stores/RoomViewStore';
@ -27,7 +26,6 @@ import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
import Stickerpicker from './Stickerpicker';
import { makeRoomPermalink } from '../../../utils/permalinks/Permalinks';
import ContentMessages from '../../../ContentMessages';
import classNames from 'classnames';
import E2EIcon from './E2EIcon';
@ -143,6 +141,8 @@ class UploadButton extends React.Component {
super(props, context);
this.onUploadClick = this.onUploadClick.bind(this);
this.onUploadFileInputChange = this.onUploadFileInputChange.bind(this);
this._uploadInput = createRef();
}
onUploadClick(ev) {
@ -150,7 +150,7 @@ class UploadButton extends React.Component {
dis.dispatch({action: 'require_registration'});
return;
}
this.refs.uploadInput.click();
this._uploadInput.current.click();
}
onUploadFileInputChange(ev) {
@ -182,7 +182,7 @@ class UploadButton extends React.Component {
onClick={this.onUploadClick}
title={_t('Upload file')}
>
<input ref="uploadInput" type="file"
<input ref={this._uploadInput} type="file"
style={uploadInputStyle}
multiple
onChange={this.onUploadFileInputChange}

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React, {createRef} from 'react';
import {_t} from "../../../languageHandler";
import MatrixClientPeg from "../../../MatrixClientPeg";
import Field from "../elements/Field";
@ -48,13 +48,15 @@ export default class ProfileSettings extends React.Component {
avatarFile: null,
enableProfileSave: false,
};
this._avatarUpload = createRef();
}
_uploadAvatar = (e) => {
e.stopPropagation();
e.preventDefault();
this.refs.avatarUpload.click();
this._avatarUpload.current.click();
};
_saveProfile = async (e) => {
@ -156,7 +158,7 @@ export default class ProfileSettings extends React.Component {
return (
<form onSubmit={this._saveProfile} autoComplete="off" noValidate={true}>
<input type="file" ref="avatarUpload" className="mx_ProfileSettings_avatarUpload"
<input type="file" ref={this._avatarUpload} className="mx_ProfileSettings_avatarUpload"
onChange={this._onAvatarChanged} accept="image/*" />
<div className="mx_ProfileSettings_profile">
<div className="mx_ProfileSettings_controls">

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
import {_t} from "../../../../../languageHandler";
import MatrixClientPeg from "../../../../../MatrixClientPeg";
@ -44,13 +44,15 @@ export default class NotificationsSettingsTab extends React.Component {
}
this.setState({currentSound: soundData.name || soundData.url});
});
this._soundUpload = createRef();
}
async _triggerUploader(e) {
e.stopPropagation();
e.preventDefault();
this.refs.soundUpload.click();
this._soundUpload.current.click();
}
async _onSoundUploadChanged(e) {
@ -157,7 +159,7 @@ export default class NotificationsSettingsTab extends React.Component {
<div>
<h3>{_t("Set a new custom sound")}</h3>
<form autoComplete="off" noValidate={true}>
<input ref="soundUpload" className="mx_NotificationSound_soundUpload" type="file" onChange={this._onSoundUploadChanged.bind(this)} accept="audio/*" />
<input ref={this._soundUpload} className="mx_NotificationSound_soundUpload" type="file" onChange={this._onSoundUploadChanged.bind(this)} accept="audio/*" />
</form>
{currentUploadedFile}

View file

@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
import createReactClass from 'create-react-class';
import dis from '../../../dispatcher';
@ -56,6 +56,10 @@ module.exports = createReactClass({
};
},
UNSAFE_componentWillMount: function() {
this._video = createRef();
},
componentDidMount: function() {
this.dispatcherRef = dis.register(this.onAction);
this.showCall();
@ -128,7 +132,7 @@ module.exports = createReactClass({
},
getVideoView: function() {
return this.refs.video;
return this._video.current;
},
render: function() {
@ -147,7 +151,9 @@ module.exports = createReactClass({
return (
<div>
<VideoView ref="video" onClick={this.props.onClick}
<VideoView
ref={this._video}
onClick={this.props.onClick}
onResize={this.props.onResize}
maxHeight={this.props.maxVideoHeight}
/>

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
import createReactClass from 'create-react-class';
@ -30,12 +30,16 @@ module.exports = createReactClass({
onResize: PropTypes.func,
},
UNSAFE_componentWillMount() {
this._vid = createRef();
},
componentDidMount() {
this.refs.vid.addEventListener('resize', this.onResize);
this._vid.current.addEventListener('resize', this.onResize);
},
componentWillUnmount() {
this.refs.vid.removeEventListener('resize', this.onResize);
this._vid.current.removeEventListener('resize', this.onResize);
},
onResize: function(e) {
@ -46,7 +50,7 @@ module.exports = createReactClass({
render: function() {
return (
<video ref="vid" style={{maxHeight: this.props.maxHeight}}>
<video ref={this._vid} style={{maxHeight: this.props.maxHeight}}>
</video>
);
},

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import React, {createRef} from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import createReactClass from 'create-react-class';
@ -49,6 +49,11 @@ module.exports = createReactClass({
onResize: PropTypes.func,
},
UNSAFE_componentWillMount: function() {
this._local = createRef();
this._remote = createRef();
},
componentDidMount: function() {
this.dispatcherRef = dis.register(this.onAction);
},
@ -58,7 +63,7 @@ module.exports = createReactClass({
},
getRemoteVideoElement: function() {
return ReactDOM.findDOMNode(this.refs.remote);
return ReactDOM.findDOMNode(this._remote.current);
},
getRemoteAudioElement: function() {
@ -74,7 +79,7 @@ module.exports = createReactClass({
},
getLocalVideoElement: function() {
return ReactDOM.findDOMNode(this.refs.local);
return ReactDOM.findDOMNode(this._local.current);
},
setContainer: function(c) {
@ -125,11 +130,11 @@ module.exports = createReactClass({
return (
<div className="mx_VideoView" ref={this.setContainer} onClick={this.props.onClick}>
<div className="mx_VideoView_remoteVideoFeed">
<VideoFeed ref="remote" onResize={this.props.onResize}
<VideoFeed ref={this._remote} onResize={this.props.onResize}
maxHeight={maxVideoHeight} />
</div>
<div className={localVideoFeedClasses}>
<VideoFeed ref="local" />
<VideoFeed ref={this._local} />
</div>
</div>
);