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

View File

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

View File

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

View File

@ -102,6 +102,10 @@ class BasePart {
toString() { toString() {
return `${this.type}(${this.text})`; return `${this.type}(${this.text})`;
} }
serialize() {
return {type: this.type, text: this.text};
}
} }
export class PlainPart extends BasePart { export class PlainPart extends BasePart {
@ -233,13 +237,12 @@ export class NewlinePart extends BasePart {
} }
export class RoomPillPart extends PillPart { export class RoomPillPart extends PillPart {
constructor(displayAlias) { constructor(displayAlias, client) {
super(displayAlias, displayAlias); super(displayAlias, displayAlias);
this._room = this._findRoomByAlias(displayAlias); this._room = this._findRoomByAlias(displayAlias, client);
} }
_findRoomByAlias(alias) { _findRoomByAlias(alias, client) {
const client = MatrixClientPeg.get();
if (alias[0] === '#') { if (alias[0] === '#') {
return client.getRooms().find((r) => { return client.getRooms().find((r) => {
return r.getAliases().includes(alias); return r.getAliases().includes(alias);
@ -300,6 +303,12 @@ export class UserPillPart extends PillPart {
get className() { get className() {
return "mx_UserPill mx_Pill"; 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 { export class PartCreator {
constructor(getAutocompleterComponent, updateQuery, room) { constructor(getAutocompleterComponent, updateQuery, room, client) {
this._room = room;
this._client = client;
this._autoCompleteCreator = (updateCallback) => { this._autoCompleteCreator = (updateCallback) => {
return new AutocompleteWrapperModel( return new AutocompleteWrapperModel(
updateCallback, updateCallback,
getAutocompleterComponent, getAutocompleterComponent,
updateQuery, updateQuery,
room, room,
client,
); );
}; };
} }
@ -362,5 +374,22 @@ export class PartCreator {
createDefaultPart(text) { createDefaultPart(text) {
return new PlainPart(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);
}
}
}
} }