support (de)serializing parts with other dependencies than text

pull/21833/head
Bruno Windels 2019-06-12 18:32:32 +02:00
parent 678fd37549
commit e674f39e3b
4 changed files with 46 additions and 16 deletions

View File

@ -18,12 +18,13 @@ limitations under the License.
import {UserPillPart, RoomPillPart, PlainPart} from "./parts";
export default class AutocompleteWrapperModel {
constructor(updateCallback, getAutocompleterComponent, updateQuery, room) {
constructor(updateCallback, getAutocompleterComponent, updateQuery, room, client) {
this._updateCallback = updateCallback;
this._getAutocompleterComponent = getAutocompleterComponent;
this._updateQuery = updateQuery;
this._query = null;
this._room = room;
this._client = client;
}
onEscape(e) {
@ -106,7 +107,7 @@ export default class AutocompleteWrapperModel {
}
case "#": {
const displayAlias = completion.completionId;
return new RoomPillPart(displayAlias);
return new RoomPillPart(displayAlias, this._client);
}
// also used for emoji completion
default:

View File

@ -21,7 +21,7 @@ import { walkDOMDepthFirst } from "./dom";
const REGEX_MATRIXTO = new RegExp(MATRIXTO_URL_PATTERN);
function parseLink(a, room) {
function parseLink(a, room, client) {
const {href} = a;
const pillMatch = REGEX_MATRIXTO.exec(href) || [];
const resourceId = pillMatch[1]; // The room/user ID
@ -34,7 +34,7 @@ function parseLink(a, room) {
room.getMember(resourceId),
);
case "#":
return new RoomPillPart(resourceId);
return new RoomPillPart(resourceId, client);
default: {
if (href === a.textContent) {
return new PlainPart(a.textContent);
@ -57,10 +57,10 @@ function parseCodeBlock(n) {
return parts;
}
function parseElement(n, room) {
function parseElement(n, room, client) {
switch (n.nodeName) {
case "A":
return parseLink(n, room);
return parseLink(n, room, client);
case "BR":
return new NewlinePart("\n");
case "EM":
@ -140,7 +140,7 @@ function prefixQuoteLines(isFirstNode, parts) {
}
}
function parseHtmlMessage(html, room) {
function parseHtmlMessage(html, room, client) {
// no nodes from parsing here should be inserted in the document,
// as scripts in event handlers, etc would be executed then.
// we're only taking text, so that is fine
@ -165,7 +165,7 @@ function parseHtmlMessage(html, room) {
if (n.nodeType === Node.TEXT_NODE) {
newParts.push(new PlainPart(n.nodeValue));
} else if (n.nodeType === Node.ELEMENT_NODE) {
const parseResult = parseElement(n, room);
const parseResult = parseElement(n, room, client);
if (parseResult) {
if (Array.isArray(parseResult)) {
newParts.push(...parseResult);
@ -205,10 +205,10 @@ function parseHtmlMessage(html, room) {
return parts;
}
export function parseEvent(event, room) {
export function parseEvent(event, room, client) {
const content = event.getContent();
if (content.format === "org.matrix.custom.html") {
return parseHtmlMessage(content.formatted_body || "", room);
return parseHtmlMessage(content.formatted_body || "", room, client);
} else {
const body = content.body || "";
const lines = body.split("\n");

View File

@ -73,7 +73,7 @@ export default class EditorModel {
}
serializeParts() {
return this._parts.map(({type, text}) => {return {type, text};});
return this._parts.map(p => p.serialize());
}
_diff(newValue, inputType, caret) {

View File

@ -102,6 +102,10 @@ class BasePart {
toString() {
return `${this.type}(${this.text})`;
}
serialize() {
return {type: this.type, text: this.text};
}
}
export class PlainPart extends BasePart {
@ -233,13 +237,12 @@ export class NewlinePart extends BasePart {
}
export class RoomPillPart extends PillPart {
constructor(displayAlias) {
constructor(displayAlias, client) {
super(displayAlias, displayAlias);
this._room = this._findRoomByAlias(displayAlias);
this._room = this._findRoomByAlias(displayAlias, client);
}
_findRoomByAlias(alias) {
const client = MatrixClientPeg.get();
_findRoomByAlias(alias, client) {
if (alias[0] === '#') {
return client.getRooms().find((r) => {
return r.getAliases().includes(alias);
@ -300,6 +303,12 @@ export class UserPillPart extends PillPart {
get className() {
return "mx_UserPill mx_Pill";
}
serialize() {
const obj = super.serialize();
obj.userId = this.resourceId;
return obj;
}
}
@ -335,13 +344,16 @@ export class PillCandidatePart extends PlainPart {
}
export class PartCreator {
constructor(getAutocompleterComponent, updateQuery, room) {
constructor(getAutocompleterComponent, updateQuery, room, client) {
this._room = room;
this._client = client;
this._autoCompleteCreator = (updateCallback) => {
return new AutocompleteWrapperModel(
updateCallback,
getAutocompleterComponent,
updateQuery,
room,
client,
);
};
}
@ -362,5 +374,22 @@ export class PartCreator {
createDefaultPart(text) {
return new PlainPart(text);
}
deserializePart(part) {
switch (part.type) {
case "plain":
return new PlainPart(part.text);
case "newline":
return new NewlinePart(part.text);
case "pill-candidate":
return new PillCandidatePart(part.text, this._autoCompleteCreator);
case "room-pill":
return new RoomPillPart(part.text, this._client);
case "user-pill": {
const member = this._room.getMember(part.userId);
return new UserPillPart(part.userId, part.text, member);
}
}
}
}