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

Commit

Permalink
Refactor matrix-linkify module (#7279)
Browse files Browse the repository at this point in the history
Refactor the module to make it easier for upgrade and proper separation of code contexts
  • Loading branch information
Palid committed Dec 3, 2021
1 parent 3b9e39f commit 961fec9
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 208 deletions.
22 changes: 9 additions & 13 deletions src/HtmlUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,20 @@ limitations under the License.
import React, { ReactNode } from 'react';
import sanitizeHtml from 'sanitize-html';
import cheerio from 'cheerio';
import * as linkify from 'linkifyjs';
import _linkifyElement from 'linkifyjs/element';
import _linkifyString from 'linkifyjs/string';
import { _linkifyElement, _linkifyString } from './linkify-matrix';
import classNames from 'classnames';
import EMOJIBASE_REGEX from 'emojibase-regex';
import katex from 'katex';
import { AllHtmlEntities } from 'html-entities';
import { IContent } from 'matrix-js-sdk/src/models/event';

import { IExtendedSanitizeOptions } from './@types/sanitize-html';
import linkifyMatrix from './linkify-matrix';
import SettingsStore from './settings/SettingsStore';
import { tryTransformPermalinkToLocalHref } from "./utils/permalinks/Permalinks";
import { getEmojiFromUnicode } from "./emoji";
import ReplyChain from "./components/views/elements/ReplyChain";
import { mediaFromMxc } from "./customisations/Media";

linkifyMatrix(linkify);
import { ELEMENT_URL_PATTERN, options as linkifyMatrixOptions } from './linkify-matrix';

// Anything outside the basic multilingual plane will be a surrogate pair
const SURROGATE_PAIR_PATTERN = /([\ud800-\udbff])([\udc00-\udfff])/;
Expand Down Expand Up @@ -180,7 +176,7 @@ const transformTags: IExtendedSanitizeOptions["transformTags"] = { // custom to
attribs.target = '_blank'; // by default

const transformed = tryTransformPermalinkToLocalHref(attribs.href);
if (transformed !== attribs.href || attribs.href.match(linkifyMatrix.ELEMENT_URL_PATTERN)) {
if (transformed !== attribs.href || attribs.href.match(ELEMENT_URL_PATTERN)) {
attribs.href = transformed;
delete attribs.target;
}
Expand Down Expand Up @@ -537,32 +533,32 @@ export function bodyToHtml(content: IContent, highlights: string[], opts: IOpts
* Linkifies the given string. This is a wrapper around 'linkifyjs/string'.
*
* @param {string} str string to linkify
* @param {object} [options] Options for linkifyString. Default: linkifyMatrix.options
* @param {object} [options] Options for linkifyString. Default: linkifyMatrixOptions
* @returns {string} Linkified string
*/
export function linkifyString(str: string, options = linkifyMatrix.options): string {
export function linkifyString(str: string, options = linkifyMatrixOptions): string {
return _linkifyString(str, options);
}

/**
* Linkifies the given DOM element. This is a wrapper around 'linkifyjs/element'.
*
* @param {object} element DOM element to linkify
* @param {object} [options] Options for linkifyElement. Default: linkifyMatrix.options
* @param {object} [options] Options for linkifyElement. Default: linkifyMatrixOptions
* @returns {object}
*/
export function linkifyElement(element: HTMLElement, options = linkifyMatrix.options): HTMLElement {
export function linkifyElement(element: HTMLElement, options = linkifyMatrixOptions): HTMLElement {
return _linkifyElement(element, options);
}

/**
* Linkify the given string and sanitize the HTML afterwards.
*
* @param {string} dirtyHtml The HTML string to sanitize and linkify
* @param {object} [options] Options for linkifyString. Default: linkifyMatrix.options
* @param {object} [options] Options for linkifyString. Default: linkifyMatrixOptions
* @returns {string}
*/
export function linkifyAndSanitizeHtml(dirtyHtml: string, options = linkifyMatrix.options): string {
export function linkifyAndSanitizeHtml(dirtyHtml: string, options = linkifyMatrixOptions): string {
return sanitizeHtml(linkifyString(dirtyHtml, options), sanitizeHtmlParams);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Markdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ limitations under the License.
import * as commonmark from 'commonmark';
import { escape } from "lodash";
import { logger } from 'matrix-js-sdk/src/logger';
import * as linkify from 'linkifyjs';
import { linkify } from './linkify-matrix';

const ALLOWED_HTML_TAGS = ['sub', 'sup', 'del', 'u'];

Expand Down
37 changes: 0 additions & 37 deletions src/components/structures/MatrixChat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ limitations under the License.
import React, { ComponentType, createRef } from 'react';
import { createClient } from "matrix-js-sdk/src/matrix";
import { InvalidStoreError } from "matrix-js-sdk/src/errors";
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { sleep, defer, IDeferred, QueryDict } from "matrix-js-sdk/src/utils";

Expand All @@ -38,7 +37,6 @@ import Notifier from '../../Notifier';
import Modal from "../../Modal";
import { showRoomInviteDialog, showStartChatInviteDialog } from '../../RoomInvite';
import * as Rooms from '../../Rooms';
import linkifyMatrix from "../../linkify-matrix";
import * as Lifecycle from '../../Lifecycle';
// LifecycleStore is not used but does listen to and dispatch actions
import '../../stores/LifecycleStore';
Expand All @@ -59,7 +57,6 @@ import { storeRoomAliasInCache } from '../../RoomAliasCache';
import ToastStore from "../../stores/ToastStore";
import * as StorageManager from "../../utils/StorageManager";
import type LoggedInViewType from "./LoggedInView";
import { ViewUserPayload } from "../../dispatcher/payloads/ViewUserPayload";
import { Action } from "../../dispatcher/actions";
import {
showToast as showAnalyticsToast,
Expand Down Expand Up @@ -347,18 +344,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
// we don't do it as react state as i'm scared about triggering needless react refreshes.
this.subTitleStatus = '';

// this can technically be done anywhere but doing this here keeps all
// the routing url path logic together.
if (this.onAliasClick) {
linkifyMatrix.onAliasClick = this.onAliasClick;
}
if (this.onUserClick) {
linkifyMatrix.onUserClick = this.onUserClick;
}
if (this.onGroupClick) {
linkifyMatrix.onGroupClick = this.onGroupClick;
}

// the first thing to do is to try the token params in the query-string
// if the session isn't soft logged out (ie: is a clean session being logged in)
if (!Lifecycle.isSoftLogout()) {
Expand Down Expand Up @@ -1898,28 +1883,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
}
this.setPageSubtitle();
}

onAliasClick(event: MouseEvent, alias: string) {
event.preventDefault();
dis.dispatch({ action: Action.ViewRoom, room_alias: alias });
}

onUserClick(event: MouseEvent, userId: string) {
event.preventDefault();

const member = new RoomMember(null, userId);
if (!member) { return; }
dis.dispatch<ViewUserPayload>({
action: Action.ViewUser,
member: member,
});
}

onGroupClick(event: MouseEvent, groupId: string) {
event.preventDefault();
dis.dispatch({ action: 'view_group', group_id: groupId });
}

onLogoutClick(event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) {
dis.dispatch({
action: 'logout',
Expand Down
Loading

0 comments on commit 961fec9

Please sign in to comment.