@paperbits/core
Version:
Paperbits core components.
116 lines (95 loc) • 4.65 kB
text/typescript
import { Contract, Bag } from "@paperbits/common";
import { IPermalinkResolver, HyperlinkModel } from "@paperbits/common/permalinks";
import { StyleCompiler } from "@paperbits/common/styles";
import { InlineModel, MarkModel, ColorModel } from "@paperbits/common/text/models";
import { InlineContract, MarkContract } from "../contracts";
export class InlineModelBinder {
constructor(
private readonly styleCompiler: StyleCompiler,
private readonly permalinkResolver: IPermalinkResolver
) { }
public canHandleContract(contract: Contract): boolean {
return contract.type === "text";
}
public canHandleModel(model: InlineModel): boolean {
return model.type === "text"; // TODO: Replace with instanceOf
}
public async contractToModel(contract: InlineContract, bindingContent?: Bag<any>): Promise<InlineModel> {
const model = new InlineModel();
model.text = contract.text;
if (contract.marks && contract.marks.length > 0) {
const modelPromises = contract.marks.map(async (markContract: MarkContract) => {
const markModel = new MarkModel(markContract.type);
switch (markContract.type) {
case "hyperlink":
const target: string = markContract.attrs?.target;
const targetKey: string = markContract.attrs?.targetKey;
const anchor: string = markContract.attrs?.anchor;
const anchorName: string = markContract.attrs?.anchorName;
const download: string = targetKey?.startsWith("uploads/") ? "" : undefined;
const triggerEvent: string = markContract.attrs?.triggerEvent;
const href = targetKey
? await this.permalinkResolver.getUrlByTargetKey(targetKey, bindingContent?.locale)
: null;
markModel.attrs = <HyperlinkModel>{
href: href || "#",
target: target,
targetKey: targetKey,
anchor: anchor,
anchorName: anchorName,
download: download,
triggerEvent: triggerEvent
};
break;
case "color":
const colorModel = <ColorModel>markContract.attrs;
if (colorModel?.colorKey) {
// TODO: check is it required async resolution
const colorClass = this.styleCompiler.getClassNameByColorKey(colorModel.colorKey);
markModel.attrs = {
colorKey: colorModel.colorKey,
colorClass: colorClass
};
}
break;
}
return markModel;
});
model.marks = await Promise.all<any>(modelPromises);
}
return model;
}
public modelToContract(inlineModel: InlineModel): Contract {
const textContract: InlineContract = {
type: "text",
text: inlineModel.text
};
if (inlineModel.marks && inlineModel.marks.length > 0) {
textContract.marks = inlineModel.marks.map(markModel => {
const contract = <MarkContract>{ type: markModel.type };
if (markModel.type === "hyperlink") {
const model = <HyperlinkModel>markModel.attrs;
contract.attrs = {
anchor: model.anchor,
anchorName: model.anchorName,
target: model.target,
targetKey: model.targetKey,
triggerEvent: model.triggerEvent
};
}
else {
if (markModel.type === "color") {
const model = <ColorModel>markModel.attrs;
if (model && model.colorKey) {
contract.attrs = {
colorKey: model.colorKey
};
}
}
}
return contract;
});
}
return textContract;
}
}