mirror of https://github.com/vector-im/riot-web
Support deserialising HR tags for editing (#7543)
parent
f4a6219c88
commit
2ef36507fd
|
@ -399,7 +399,7 @@ class EditMessageComposer extends React.Component<IEditMessageComposerProps, ISt
|
||||||
const room = this.getRoom();
|
const room = this.getRoom();
|
||||||
const partCreator = new CommandPartCreator(room, this.props.mxClient);
|
const partCreator = new CommandPartCreator(room, this.props.mxClient);
|
||||||
|
|
||||||
let parts;
|
let parts: Part[];
|
||||||
let isRestored = false;
|
let isRestored = false;
|
||||||
if (editState.hasEditorState()) {
|
if (editState.hasEditorState()) {
|
||||||
// if restoring state from a previous editor,
|
// if restoring state from a previous editor,
|
||||||
|
|
|
@ -24,9 +24,9 @@ import { Part, PartCreator, Type } from "./parts";
|
||||||
import SdkConfig from "../SdkConfig";
|
import SdkConfig from "../SdkConfig";
|
||||||
import { textToHtmlRainbow } from "../utils/colour";
|
import { textToHtmlRainbow } from "../utils/colour";
|
||||||
|
|
||||||
function parseAtRoomMentions(text: string, partCreator: PartCreator) {
|
function parseAtRoomMentions(text: string, partCreator: PartCreator): Part[] {
|
||||||
const ATROOM = "@room";
|
const ATROOM = "@room";
|
||||||
const parts = [];
|
const parts: Part[] = [];
|
||||||
text.split(ATROOM).forEach((textPart, i, arr) => {
|
text.split(ATROOM).forEach((textPart, i, arr) => {
|
||||||
if (textPart.length) {
|
if (textPart.length) {
|
||||||
parts.push(partCreator.plain(textPart));
|
parts.push(partCreator.plain(textPart));
|
||||||
|
@ -42,7 +42,7 @@ function parseAtRoomMentions(text: string, partCreator: PartCreator) {
|
||||||
return parts;
|
return parts;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseLink(a: HTMLAnchorElement, partCreator: PartCreator) {
|
function parseLink(a: HTMLAnchorElement, partCreator: PartCreator): Part {
|
||||||
const { href } = a;
|
const { href } = a;
|
||||||
const resourceId = getPrimaryPermalinkEntity(href); // The room/user ID
|
const resourceId = getPrimaryPermalinkEntity(href); // The room/user ID
|
||||||
const prefix = resourceId ? resourceId[0] : undefined; // First character of ID
|
const prefix = resourceId ? resourceId[0] : undefined; // First character of ID
|
||||||
|
@ -61,13 +61,13 @@ function parseLink(a: HTMLAnchorElement, partCreator: PartCreator) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseImage(img: HTMLImageElement, partCreator: PartCreator) {
|
function parseImage(img: HTMLImageElement, partCreator: PartCreator): Part {
|
||||||
const { src } = img;
|
const { src } = img;
|
||||||
return partCreator.plain(`![${img.alt.replace(/[[\\\]]/g, c => "\\" + c)}](${src})`);
|
return partCreator.plain(`![${img.alt.replace(/[[\\\]]/g, c => "\\" + c)}](${src})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseCodeBlock(n: HTMLElement, partCreator: PartCreator) {
|
function parseCodeBlock(n: HTMLElement, partCreator: PartCreator): Part[] {
|
||||||
const parts = [];
|
const parts: Part[] = [];
|
||||||
let language = "";
|
let language = "";
|
||||||
if (n.firstChild && n.firstChild.nodeName === "CODE") {
|
if (n.firstChild && n.firstChild.nodeName === "CODE") {
|
||||||
for (const className of (<HTMLElement>n.firstChild).classList) {
|
for (const className of (<HTMLElement>n.firstChild).classList) {
|
||||||
|
@ -87,7 +87,7 @@ function parseCodeBlock(n: HTMLElement, partCreator: PartCreator) {
|
||||||
return parts;
|
return parts;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseHeader(el: HTMLElement, partCreator: PartCreator) {
|
function parseHeader(el: HTMLElement, partCreator: PartCreator): Part {
|
||||||
const depth = parseInt(el.nodeName.substr(1), 10);
|
const depth = parseInt(el.nodeName.substr(1), 10);
|
||||||
return partCreator.plain("#".repeat(depth) + " ");
|
return partCreator.plain("#".repeat(depth) + " ");
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,12 @@ interface IState {
|
||||||
listDepth?: number;
|
listDepth?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseElement(n: HTMLElement, partCreator: PartCreator, lastNode: HTMLElement | undefined, state: IState) {
|
function parseElement(
|
||||||
|
n: HTMLElement,
|
||||||
|
partCreator: PartCreator,
|
||||||
|
lastNode: Node | undefined,
|
||||||
|
state: IState,
|
||||||
|
): Part | Part[] {
|
||||||
switch (n.nodeName) {
|
switch (n.nodeName) {
|
||||||
case "H1":
|
case "H1":
|
||||||
case "H2":
|
case "H2":
|
||||||
|
@ -112,6 +117,14 @@ function parseElement(n: HTMLElement, partCreator: PartCreator, lastNode: HTMLEl
|
||||||
return parseImage(<HTMLImageElement>n, partCreator);
|
return parseImage(<HTMLImageElement>n, partCreator);
|
||||||
case "BR":
|
case "BR":
|
||||||
return partCreator.newline();
|
return partCreator.newline();
|
||||||
|
case "HR":
|
||||||
|
// the newline arrangement here is quite specific otherwise it may be misconstrued as marking the previous
|
||||||
|
// text line as a header instead of acting as a horizontal rule.
|
||||||
|
return [
|
||||||
|
partCreator.newline(),
|
||||||
|
partCreator.plain("---"),
|
||||||
|
partCreator.newline(),
|
||||||
|
];
|
||||||
case "EM":
|
case "EM":
|
||||||
return partCreator.plain(`_${n.textContent}_`);
|
return partCreator.plain(`_${n.textContent}_`);
|
||||||
case "STRONG":
|
case "STRONG":
|
||||||
|
@ -222,13 +235,13 @@ function parseHtmlMessage(html: string, partCreator: PartCreator, isQuotedMessag
|
||||||
// we're only taking text, so that is fine
|
// we're only taking text, so that is fine
|
||||||
const rootNode = new DOMParser().parseFromString(html, "text/html").body;
|
const rootNode = new DOMParser().parseFromString(html, "text/html").body;
|
||||||
const parts: Part[] = [];
|
const parts: Part[] = [];
|
||||||
let lastNode;
|
let lastNode: Node;
|
||||||
let inQuote = isQuotedMessage;
|
let inQuote = isQuotedMessage;
|
||||||
const state: IState = {
|
const state: IState = {
|
||||||
listIndex: [],
|
listIndex: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
function onNodeEnter(n) {
|
function onNodeEnter(n: Node) {
|
||||||
if (checkIgnored(n)) {
|
if (checkIgnored(n)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -256,7 +269,7 @@ function parseHtmlMessage(html: string, partCreator: PartCreator, isQuotedMessag
|
||||||
newParts.push(partCreator.newline());
|
newParts.push(partCreator.newline());
|
||||||
}
|
}
|
||||||
} else if (n.nodeType === Node.ELEMENT_NODE) {
|
} else if (n.nodeType === Node.ELEMENT_NODE) {
|
||||||
const parseResult = parseElement(n, partCreator, lastNode, state);
|
const parseResult = parseElement(n as HTMLElement, partCreator, lastNode, state);
|
||||||
if (parseResult) {
|
if (parseResult) {
|
||||||
if (Array.isArray(parseResult)) {
|
if (Array.isArray(parseResult)) {
|
||||||
newParts.push(...parseResult);
|
newParts.push(...parseResult);
|
||||||
|
@ -280,7 +293,7 @@ function parseHtmlMessage(html: string, partCreator: PartCreator, isQuotedMessag
|
||||||
return descend;
|
return descend;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onNodeLeave(n) {
|
function onNodeLeave(n: Node) {
|
||||||
if (checkIgnored(n)) {
|
if (checkIgnored(n)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue