quill-delta-to-html
Version:
Converts Quill's delta ops to HTML
102 lines (81 loc) • 3.31 kB
text/typescript
import { DeltaInsertOp } from './../DeltaInsertOp';
import './../extensions/Array';
import {
VideoItem, InlineGroup, BlockGroup, TDataGroup
} from './group-types';
class Grouper {
static pairOpsWithTheirBlock(ops: DeltaInsertOp[]): TDataGroup[] {
let result: TDataGroup[] = [];
const canBeInBlock = (op: DeltaInsertOp) => {
return !(op.isJustNewline() || op.isVideo() || op.isContainerBlock());
};
const isInlineData = (op: DeltaInsertOp) => op.isInline();
let lastInd = ops.length - 1;
let opsSlice: IArraySlice;
for (var i = lastInd; i >= 0; i--) {
let op = ops[i];
if (op.isVideo()) {
result.push(new VideoItem(op));
} else if (op.isContainerBlock()) {
opsSlice = ops._sliceFromReverseWhile(i - 1, canBeInBlock);
result.push(new BlockGroup(op, opsSlice.elements));
i = opsSlice.sliceStartsAt > -1 ? opsSlice.sliceStartsAt : i;
} else {
opsSlice = ops._sliceFromReverseWhile(i - 1, isInlineData);
result.push(new InlineGroup(opsSlice.elements.concat(op)));
i = opsSlice.sliceStartsAt > -1 ? opsSlice.sliceStartsAt : i;
}
}
result.reverse();
return result;
}
static groupConsecutiveSameStyleBlocks(groups: TDataGroup[], blocksOf = {
header: true,
codeBlocks: true,
blockquotes: true
}): Array<TDataGroup | BlockGroup[]> {
return groups._groupConsecutiveElementsWhile((g: TDataGroup, gPrev: TDataGroup) => {
if (!(g instanceof BlockGroup) || !(gPrev instanceof BlockGroup)) {
return false;
}
return blocksOf.codeBlocks && Grouper.areBothCodeblocks(g, gPrev)
|| blocksOf.blockquotes && Grouper.areBothBlockquotesWithSameAdi(g, gPrev)
|| blocksOf.header && Grouper.areBothSameHeadersWithSameAdi(g, gPrev);
});
}
// Moves all ops of same style consecutive blocks to the ops of first block
// and discards the rest.
static reduceConsecutiveSameStyleBlocksToOne(
groups: Array<TDataGroup | BlockGroup[]>): TDataGroup[] {
var newLineOp = DeltaInsertOp.createNewLineOp();
return groups.map(function (elm: TDataGroup | BlockGroup[]) {
if (!Array.isArray(elm)) {
if (elm instanceof BlockGroup && !elm.ops.length) {
elm.ops.push(newLineOp);
}
return elm;
}
var groupsLastInd = elm.length - 1;
elm[0].ops = elm.map((g: BlockGroup, i: number) => {
if (!g.ops.length) {
return [newLineOp];
}
return g.ops.concat(i < groupsLastInd ? [newLineOp] : []);
})._flatten();
return elm[0];
});
}
static areBothCodeblocks(g1: BlockGroup, gOther: BlockGroup) {
return g1.op.isCodeBlock() && gOther.op.isCodeBlock();
}
static areBothSameHeadersWithSameAdi(g1: BlockGroup, gOther: BlockGroup) {
return g1.op.isSameHeaderAs(gOther.op) && g1.op.hasSameAdiAs(gOther.op);
}
static areBothBlockquotesWithSameAdi(g: BlockGroup, gOther: BlockGroup) {
return g.op.isBlockquote() && gOther.op.isBlockquote()
&& g.op.hasSameAdiAs(gOther.op);
}
}
export {
Grouper
}