= [];
+
+ for (const format of inlineAttributes) {
+ const value = attributes[format];
+ if (value) {
+ const customTag = this.options.customTag?.(format, this.op);
+ if (customTag) {
+ tags.push(customTag);
+ } else {
+ switch (format) {
+ case 'link':
+ case 'mentions':
+ tags.push(this.options.mentionTag || 'a');
+ break;
+ case 'script':
+ tags.push(value === ScriptType.Sub ? 'sub' : 'sup');
+ break;
+ case 'bold':
+ tags.push('strong');
+ break;
+ case 'italic':
+ tags.push('em');
+ break;
+ case 'strike':
+ tags.push('s');
+ break;
+ case 'underline':
+ tags.push('u');
+ break;
+ case 'code':
+ tags.push('code');
+ }
+ }
+ }
+ }
+
+ // Note that this array may be empty, which is the case when there's no formatting or attributes needed for inline text.
+ // The caller of this function may still render a wrapper tag if there are attributes.
+ return tags;
+ }
+}
diff --git a/src/sanitize-mention.ts b/src/sanitize-mention.ts
new file mode 100644
index 0000000..33114f7
--- /dev/null
+++ b/src/sanitize-mention.ts
@@ -0,0 +1,61 @@
+import {
+ OpAttributeSanitizer,
+ OpAttributeSanitizerOptions,
+} from './OpAttributeSanitizer.js';
+
+// See https://github.com/quill-mention/quill-mention
+export type Mention = {
+ class?: string;
+ target?: string;
+ link?: string;
+ [index: string]: unknown;
+};
+
+type UnknownDirtyMention = {
+ [key in keyof Mention]?: unknown;
+};
+
+const isDirtyMention = (value: unknown): value is UnknownDirtyMention =>
+ !!value && typeof value === 'object';
+
+const validClassRegex = /^[\w -]{1,500}$/i;
+
+const isValidClass = (value: string) => validClassRegex.test(value);
+
+export const sanitizeMention = (
+ dirtyObj: unknown,
+ sanitizeOptions: OpAttributeSanitizerOptions,
+): Mention => {
+ const cleanObj: Mention = {};
+
+ if (!isDirtyMention(dirtyObj)) {
+ return cleanObj;
+ }
+
+ for (const [key, value] of Object.entries(dirtyObj)) {
+ switch (key) {
+ case 'class':
+ if (typeof value === 'string' && isValidClass(value)) {
+ cleanObj.class = value;
+ }
+ break;
+ case 'target':
+ if (
+ typeof value === 'string' &&
+ OpAttributeSanitizer.isValidTarget(value)
+ ) {
+ cleanObj.target = value;
+ }
+ break;
+ case 'link':
+ if (typeof value === 'string') {
+ cleanObj.link = sanitizeOptions.urlSanitizer(value);
+ }
+ break;
+ default:
+ cleanObj[key] = value;
+ }
+ }
+
+ return cleanObj;
+};
diff --git a/src/value-types.ts b/src/value-types.ts
index 3ad8f01..c2dbfaf 100644
--- a/src/value-types.ts
+++ b/src/value-types.ts
@@ -1,50 +1,37 @@
-type NewLine = '\n';
-const NewLine = '\n' as NewLine;
-
-enum ListType {
+export enum ListType {
Ordered = 'ordered',
Bullet = 'bullet',
Checked = 'checked',
Unchecked = 'unchecked',
}
-enum ScriptType {
+export enum ScriptType {
Sub = 'sub',
Super = 'super',
}
-enum DirectionType {
+export enum DirectionType {
Rtl = 'rtl',
}
-enum AlignType {
+export enum AlignType {
Left = 'left',
Center = 'center',
Right = 'right',
Justify = 'justify',
}
-enum DataType {
+export enum DataType {
Image = 'image',
Video = 'video',
Formula = 'formula',
Text = 'text',
}
-enum GroupType {
+export enum GroupType {
Block = 'block',
InlineGroup = 'inline-group',
List = 'list',
Video = 'video',
Table = 'table',
}
-
-export {
- NewLine,
- ListType,
- ScriptType,
- DirectionType,
- AlignType,
- DataType,
- GroupType,
-};
diff --git a/test/DeltaInsertOp.test.ts b/test/DeltaInsertOp.test.ts
index 628aaa2..63132c2 100644
--- a/test/DeltaInsertOp.test.ts
+++ b/test/DeltaInsertOp.test.ts
@@ -1,179 +1,174 @@
-import 'mocha';
-import * as assert from 'assert';
-
-import { InsertDataQuill } from './../src/InsertData';
-import { DeltaInsertOp } from './../src/DeltaInsertOp';
-import { DataType, AlignType, ListType } from './../src/value-types';
-
-describe('DeltaInsertOp', function () {
- describe('constructor()', function () {
+import { describe, it } from 'vitest';
+import { strict as assert } from 'node:assert';
+import { InsertDataQuill } from '../src/InsertData.js';
+import { DeltaInsertOp } from '../src/DeltaInsertOp.js';
+import { DataType, ListType } from '../src/value-types.js';
+
+describe('DeltaInsertOp', () => {
+ describe('constructor', function () {
it('should instantiate', function () {
- var embed = new InsertDataQuill(DataType.Image, 'https://');
- var t = new DeltaInsertOp(embed);
+ const embed = new InsertDataQuill(DataType.Image, 'https://');
+ const t = new DeltaInsertOp(embed);
assert.equal(t instanceof DeltaInsertOp, true);
assert.equal(t.insert instanceof InsertDataQuill, true);
assert.equal(t.attributes instanceof Object, true);
- t = new DeltaInsertOp('test');
- assert.deepEqual(t.insert.value, 'test');
-
- t = new DeltaInsertOp(new InsertDataQuill(DataType.Formula, 'x=data'));
- assert.equal(t.insert.value, 'x=data');
- });
- });
-
- describe('isContainerBlock()', function () {
- it('should successfully check if the op is a block container', function () {
- var op = new DeltaInsertOp('test');
- assert.equal(op.isContainerBlock(), false);
-
- op = new DeltaInsertOp('test', { blockquote: true });
- assert.equal(op.isContainerBlock(), true);
- });
- });
-
- describe('hasSameAdiAs()', function () {
- it('should successfully if two ops have same align indent and direction', function () {
- var op1 = new DeltaInsertOp('\n', { align: AlignType.Right, indent: 2 });
- var op2 = new DeltaInsertOp('\n', { align: AlignType.Right, indent: 2 });
+ const t2 = new DeltaInsertOp(new InsertDataQuill(DataType.Text, 'test'));
+ assert.deepEqual(t2.insert.value, 'test');
- assert.ok(op1.hasSameAdiAs(op2));
-
- var op2 = new DeltaInsertOp('\n', { align: AlignType.Right, indent: 3 });
- assert.ok(!op1.hasSameAdiAs(op2));
+ const t3 = new DeltaInsertOp(
+ new InsertDataQuill(DataType.Formula, 'x=data'),
+ );
+ assert.equal(t3.insert.value, 'x=data');
});
});
- describe('hasHigherIndentThan()', function () {
- it('should successfully if two ops have same align indent and direction', function () {
- var op1 = new DeltaInsertOp('\n', { indent: undefined });
- var op2 = new DeltaInsertOp('\n', { indent: undefined });
-
- assert.ok(!op1.hasHigherIndentThan(op2));
+ describe('isContainerBlock', function () {
+ it('should check if the op is a block container', function () {
+ const inlineOp = new DeltaInsertOp(
+ new InsertDataQuill(DataType.Text, 'test'),
+ );
+ assert.equal(inlineOp.isContainerBlock(), false);
+
+ const blockOp = new DeltaInsertOp(
+ new InsertDataQuill(DataType.Text, 'test'),
+ {
+ blockquote: true,
+ },
+ );
+ assert.equal(blockOp.isContainerBlock(), true);
});
});
- describe('isInline()', function () {
+ describe('isInline', function () {
it('should return true if op is an inline', function () {
- var op = new DeltaInsertOp('\n', {});
+ const op = new DeltaInsertOp(
+ new InsertDataQuill(DataType.Text, '\n'),
+ {},
+ );
assert.equal(op.isInline(), true);
});
});
describe('isJustNewline()', function () {
it('should return true if op is a list', function () {
- var op = new DeltaInsertOp('\n', {});
+ let op = new DeltaInsertOp(new InsertDataQuill(DataType.Text, '\n'), {});
assert.equal(op.isJustNewline(), true);
- op = new DeltaInsertOp('\n\n ', { list: ListType.Ordered });
+ op = new DeltaInsertOp(new InsertDataQuill(DataType.Text, '\n\n '), {
+ list: ListType.Ordered,
+ });
assert.equal(op.isJustNewline(), false);
});
});
describe('isList()', function () {
it('should return true if op is a list', function () {
- var op = new DeltaInsertOp('\n', {});
+ let op = new DeltaInsertOp(new InsertDataQuill(DataType.Text, '\n'), {});
assert.equal(op.isList(), false);
- op = new DeltaInsertOp('fds ', { list: ListType.Ordered });
+ op = new DeltaInsertOp(new InsertDataQuill(DataType.Text, 'fds '), {
+ list: ListType.Ordered,
+ });
assert.equal(op.isList(), true);
- op = new DeltaInsertOp('fds ', { list: ListType.Unchecked });
+ op = new DeltaInsertOp(new InsertDataQuill(DataType.Text, 'fds '), {
+ list: ListType.Unchecked,
+ });
assert.equal(op.isList(), true);
});
});
describe('isBulletList()', function () {
it('should return true if op is a bullet list', function () {
- var op = new DeltaInsertOp('\n', { list: ListType.Bullet });
+ let op = new DeltaInsertOp(new InsertDataQuill(DataType.Text, '\n'), {
+ list: ListType.Bullet,
+ });
assert.equal(op.isBulletList(), true);
- op = new DeltaInsertOp('fds ', { list: ListType.Ordered });
+ op = new DeltaInsertOp(new InsertDataQuill(DataType.Text, 'fds '), {
+ list: ListType.Ordered,
+ });
assert.equal(op.isBulletList(), false);
});
});
describe('isOrderedList()', function () {
it('should return true if op is an ordered list', function () {
- var op = new DeltaInsertOp('\n', { list: ListType.Bullet });
+ let op = new DeltaInsertOp(new InsertDataQuill(DataType.Text, '\n'), {
+ list: ListType.Bullet,
+ });
assert.equal(op.isOrderedList(), false);
- op = new DeltaInsertOp('fds ', { list: ListType.Ordered });
+ op = new DeltaInsertOp(new InsertDataQuill(DataType.Text, 'fds '), {
+ list: ListType.Ordered,
+ });
assert.equal(op.isOrderedList(), true);
});
});
- describe('isCheckedList()', function () {
+ describe('isCheckedList', function () {
it('should return true if op is an checked list', function () {
- var op = new DeltaInsertOp('\n', { list: ListType.Unchecked });
+ let op = new DeltaInsertOp(new InsertDataQuill(DataType.Text, '\n'), {
+ list: ListType.Unchecked,
+ });
assert.equal(op.isCheckedList(), false);
- op = new DeltaInsertOp('fds ', { list: ListType.Checked });
+ op = new DeltaInsertOp(new InsertDataQuill(DataType.Text, 'fds '), {
+ list: ListType.Checked,
+ });
assert.equal(op.isCheckedList(), true);
});
});
- describe('isUncheckedList()', function () {
+ describe('isUncheckedList', function () {
it('should return true if op is an unchecked list', function () {
- var op = new DeltaInsertOp('\n', { list: ListType.Bullet });
+ let op = new DeltaInsertOp(new InsertDataQuill(DataType.Text, '\n'), {
+ list: ListType.Bullet,
+ });
assert.equal(op.isUncheckedList(), false);
- op = new DeltaInsertOp('fds ', { list: ListType.Unchecked });
+ op = new DeltaInsertOp(new InsertDataQuill(DataType.Text, 'fds '), {
+ list: ListType.Unchecked,
+ });
assert.equal(op.isUncheckedList(), true);
});
});
- describe('isSameListAs()', function () {
+ describe('isSameListAs', function () {
it('should return true if op list type same as the comparison', function () {
- var op = new DeltaInsertOp('\n', { list: ListType.Bullet });
- var op2 = new DeltaInsertOp('ds', { list: ListType.Bullet });
+ const op = new DeltaInsertOp(new InsertDataQuill(DataType.Text, '\n'), {
+ list: ListType.Bullet,
+ });
+ const op2 = new DeltaInsertOp(new InsertDataQuill(DataType.Text, 'ds'), {
+ list: ListType.Bullet,
+ });
assert.equal(op.isSameListAs(op2), true);
- var op3 = new DeltaInsertOp('fds ', { list: ListType.Ordered });
+ const op3 = new DeltaInsertOp(
+ new InsertDataQuill(DataType.Text, 'fds '),
+ {
+ list: ListType.Ordered,
+ },
+ );
assert.equal(op.isSameListAs(op3), false);
});
});
- describe('isText()', function () {
- it('should correctly identify insert type', function () {
- var op = new DeltaInsertOp('\n', { list: ListType.Bullet });
- assert.equal(op.isVideo(), false);
- assert.equal(op.isText(), true);
-
- op = new DeltaInsertOp(new InsertDataQuill(DataType.Image, 'd'), {
- list: ListType.Ordered,
- });
- assert.equal(op.isImage(), true);
- assert.equal(op.isText(), false);
- });
- });
-
- describe('isVideo()/isImage()/isFormula()', function () {
- it('should correctly identify embed type', function () {
- var op = new DeltaInsertOp(new InsertDataQuill(DataType.Video, ''));
- assert.equal(op.isVideo(), true);
- assert.equal(op.isFormula(), false);
- assert.equal(op.isImage(), false);
-
- op = new DeltaInsertOp(new InsertDataQuill(DataType.Image, 'd'));
- assert.equal(op.isImage(), true);
- assert.equal(op.isFormula(), false);
-
- op = new DeltaInsertOp(new InsertDataQuill(DataType.Formula, 'd'));
- assert.equal(op.isVideo(), false);
- assert.equal(op.isFormula(), true);
- });
- });
-
- describe('isLink()', function () {
+ describe('isLink', () => {
it('should correctly identify if op is a link', function () {
- var op = new DeltaInsertOp(new InsertDataQuill(DataType.Video, ''), {
+ const op = new DeltaInsertOp(new InsertDataQuill(DataType.Video, ''), {
link: 'http://',
});
assert.equal(op.isLink(), false);
- op = new DeltaInsertOp('http', { link: 'http://' });
- assert.equal(op.isLink(), true);
+ const op2 = new DeltaInsertOp(
+ new InsertDataQuill(DataType.Text, 'http'),
+ {
+ link: 'http://',
+ },
+ );
+ assert.equal(op2.isLink(), true);
});
});
});
diff --git a/test/InsertData.test.ts b/test/InsertData.test.ts
index f73ab78..2e33df1 100644
--- a/test/InsertData.test.ts
+++ b/test/InsertData.test.ts
@@ -1,31 +1,27 @@
-import 'mocha';
-import * as assert from 'assert';
+import { describe, it } from 'vitest';
+import { strict as assert } from 'node:assert';
+import { InsertDataQuill, InsertDataCustom } from './../src/InsertData.js';
+import { DataType } from './../src/value-types.js';
-import { InsertDataQuill, InsertDataCustom } from './../src/InsertData';
-import { DataType } from './../src/value-types';
+describe('InsertDataQuill', () => {
+ describe('constructor', () => {
+ it('should instantiate', () => {
+ const t1 = new InsertDataQuill(DataType.Video, 'https://');
+ assert.equal(t1.type === DataType.Video, true);
+ assert.equal(t1.value === 'https://', true);
-describe('InsertData', function () {
- describe('InsertDataQuill', function () {
- describe('constructor()', function () {
- it('should instantiate', function () {
- var t = new InsertDataQuill(DataType.Video, 'https://');
- assert.equal(t.type === 'video', true);
- assert.equal(t.value === 'https://', true);
-
- t = new InsertDataQuill(DataType.Text, 'hello');
- assert.equal(t.type === 'text', true);
- assert.equal(t.value === 'hello', true);
- });
+ const t2 = new InsertDataQuill(DataType.Text, 'hello');
+ assert.equal(t2.type === DataType.Text, true);
+ assert.equal(t2.value === 'hello', true);
});
});
+});
- describe('InsertDataCustom', function () {
- describe('constructor()', function () {
- it('should instantiate', function () {
- var t = new InsertDataCustom('biu', {});
- assert.equal(t.type === 'biu', true);
- assert.deepEqual(t.value, {});
- });
+describe('InsertDataCustom', () => {
+ describe('constructor', () => {
+ it('should instantiate', () => {
+ const instance = new InsertDataCustom({ yoyoyo: 1 });
+ assert.deepEqual(instance.value, { yoyoyo: 1 });
});
});
});
diff --git a/test/InsertOpDenormalizer.test.ts b/test/InsertOpDenormalizer.test.ts
deleted file mode 100644
index 9e6df44..0000000
--- a/test/InsertOpDenormalizer.test.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import 'mocha';
-import * as assert from 'assert';
-
-import { InsertOpDenormalizer } from './../src/InsertOpDenormalizer';
-
-describe('InsertOpDenormalizer', function () {
- describe('#denormalize()', function () {
- it('should return denormalized op as array of ops', function () {
- var op = { insert: '\n' };
- var act = InsertOpDenormalizer.denormalize({ insert: '\n' });
- assert.deepEqual(act, [op]);
-
- op = { insert: 'abc' };
- act = InsertOpDenormalizer.denormalize(op);
- assert.deepEqual(act, [op]);
-
- var op2 = { insert: 'abc\n', attributes: { link: 'cold' } };
- act = InsertOpDenormalizer.denormalize(op2);
- assert.equal(act.length, 2);
- assert.equal(act[0].insert, 'abc');
- assert.equal(act[0].attributes.link, 'cold');
-
- var op3 = { insert: '\n\n', attributes: { bold: true } };
- act = InsertOpDenormalizer.denormalize(op3);
- assert.equal(act.length, 2);
- assert.equal(act[1].insert, '\n');
-
- act = InsertOpDenormalizer.denormalize(null);
- assert.deepEqual(act, []);
- act = InsertOpDenormalizer.denormalize('..');
- assert.deepEqual(act, []);
- });
- });
-});
diff --git a/test/InsertOpsConverter.test.ts b/test/InsertOpsConverter.test.ts
deleted file mode 100644
index 190caf1..0000000
--- a/test/InsertOpsConverter.test.ts
+++ /dev/null
@@ -1,92 +0,0 @@
-import 'mocha';
-import * as assert from 'assert';
-
-import { DeltaInsertOp } from './../src/DeltaInsertOp';
-import { InsertDataQuill } from './../src/InsertData';
-import { InsertOpsConverter } from './../src/InsertOpsConverter';
-
-var data = [
- {
- ops: [
- { insert: 'This ' },
- { attributes: { font: 'monospace' }, insert: 'is' },
- { insert: ' a ' },
- { attributes: { size: 'large' }, insert: 'test' },
- { insert: ' ' },
- { attributes: { italic: true, bold: true }, insert: 'data' },
- { insert: ' ' },
- { attributes: { underline: true, strike: true }, insert: 'that' },
- { insert: ' is ' },
- { attributes: { color: '#e60000' }, insert: 'will' },
- { insert: ' ' },
- { attributes: { background: '#ffebcc' }, insert: 'test' },
- { insert: ' ' },
- { attributes: { script: 'sub' }, insert: 'the' },
- { insert: ' ' },
- { attributes: { script: 'super' }, insert: 'rendering' },
- { insert: ' of ' },
- { attributes: { link: 'yahoo' }, insert: 'inline' },
- { insert: ' ' },
- { insert: { formula: 'x=data' } },
- { insert: ' formats.\n' },
- ],
- html: [
- '',
- 'This ',
- 'is',
- ' a ',
- 'test',
- ' ',
- 'data',
- ' ',
- 'that',
- ' is ',
- 'will',
- ' ',
- 'test',
- ' ',
- 'the',
- ' ',
- 'rendering',
- ' of ',
- 'inline',
- ' ',
- 'x=data',
- ' formats.
',
- ].join(''),
- },
-];
-
-describe('InsertOpsConverter', function () {
- describe('#convert()', function () {
- it('should transform raw delta ops to DeltaInsertOp[]', function () {
- var objs = InsertOpsConverter.convert(data[0].ops, {});
-
- assert.equal(objs[0] instanceof DeltaInsertOp, true);
- assert.equal(objs[objs.length - 1] instanceof DeltaInsertOp, true);
- assert.deepEqual(InsertOpsConverter.convert(null, {}), []);
- assert.deepEqual(InsertOpsConverter.convert([{ insert: '' }], {}), []);
- assert.deepEqual(
- InsertOpsConverter.convert([{ insert: { cake: '' } }], {}),
- [{ insert: { type: 'cake', value: '' }, attributes: {} }]
- );
- assert.deepEqual(InsertOpsConverter.convert([{ insert: 2 }], {}), []);
- //console.log(objs);
- });
- });
-
- describe('#convertInsertVal()', function () {
- it('should convert raw .insert value to valid TInsert or null', function () {
- [null, undefined, 3, {}].forEach((v) => {
- var act = InsertOpsConverter.convertInsertVal(v, {});
- assert.equal(act, null);
- });
-
- ['fdsf', { image: 'ff' }, { video: '' }, { formula: '' }].forEach((v) => {
- var act = InsertOpsConverter.convertInsertVal(v, {});
- assert.notEqual(act, null);
- assert.ok(act instanceof InsertDataQuill);
- });
- });
- });
-});
diff --git a/test/OpAttributeSanitizer.test.ts b/test/OpAttributeSanitizer.test.ts
index 690ce65..1734f7a 100644
--- a/test/OpAttributeSanitizer.test.ts
+++ b/test/OpAttributeSanitizer.test.ts
@@ -1,33 +1,63 @@
-import 'mocha';
-import * as assert from 'assert';
-
-import { OpAttributeSanitizer } from './../src/OpAttributeSanitizer';
-import { ListType, AlignType, DirectionType } from './../src/value-types';
+import { describe, it } from 'vitest';
+import { strict as assert } from 'node:assert';
+import {
+ OpAttributeSanitizer,
+ OpAttributeSanitizerOptions,
+} from './../src/OpAttributeSanitizer.js';
+import { ListType, AlignType, DirectionType } from './../src/value-types.js';
describe('OpAttributeSanitizer', function () {
- describe('#IsValidHexColor()', function () {
- it('should return true if hex color is valid', function () {
- assert.ok(OpAttributeSanitizer.IsValidHexColor('#234'));
- assert.ok(OpAttributeSanitizer.IsValidHexColor('#f23'));
- assert.ok(OpAttributeSanitizer.IsValidHexColor('#fFe234'));
- assert.equal(OpAttributeSanitizer.IsValidHexColor('#g34'), false);
+ describe('isValidHexColor', function () {
+ it('should return true for valid HEX colors', () => {
+ assert.ok(OpAttributeSanitizer.isValidHexColor('#234'));
+ assert.ok(OpAttributeSanitizer.isValidHexColor('#f23'));
+ assert.ok(OpAttributeSanitizer.isValidHexColor('#fFe234'));
+ assert.equal(OpAttributeSanitizer.isValidHexColor('#g34'), false);
+ });
+
+ it('should return false for invalid strings', () => {
+ assert.equal(OpAttributeSanitizer.isValidHexColor('e34'), false);
+ assert.equal(OpAttributeSanitizer.isValidHexColor('123434'), false);
+ });
+ });
+
+ describe('isValidFontName', () => {
+ it('should return true for valid font names', () => {
+ assert.equal(
+ OpAttributeSanitizer.isValidFontName('gooD-ol times 2'),
+ true,
+ );
+ });
- assert.equal(OpAttributeSanitizer.IsValidHexColor('e34'), false);
- assert.equal(OpAttributeSanitizer.IsValidHexColor('123434'), false);
+ it('should return false for invalid strings', () => {
+ assert.equal(OpAttributeSanitizer.isValidFontName(''), false);
+ assert.equal(OpAttributeSanitizer.isValidHexColor('bad"str?'), false);
});
});
- describe('#IsValidFontName()', function () {
- it('should return true if font name is valid', function () {
- assert.ok(OpAttributeSanitizer.IsValidFontName('gooD-ol times 2'));
- assert.equal(OpAttributeSanitizer.IsValidHexColor('bad"times?'), false);
+ describe('isValidSize', () => {
+ it('should return true for valid sizes', function () {
+ assert.ok(OpAttributeSanitizer.isValidSize('bigfaT-size'));
+ });
+
+ it('should return false for invalid strings', () => {
+ assert.equal(OpAttributeSanitizer.isValidSize(''), false);
+ assert.equal(OpAttributeSanitizer.isValidSize('big-fat-size!'), false);
+ assert.equal(OpAttributeSanitizer.isValidSize('small.size?'), false);
});
});
- describe('#IsValidSize()', function () {
- it('should return true if size is valid', function () {
- assert.ok(OpAttributeSanitizer.IsValidSize('bigfaT-size'));
- assert.equal(OpAttributeSanitizer.IsValidSize('small.sizetimes?'), false);
+ describe('isValidTarget', () => {
+ it('should return true for valid targets', () => {
+ ['_self', '_blank', '_parent', '_top'].forEach((target) => {
+ assert.ok(OpAttributeSanitizer.isValidTarget(target));
+ });
+ });
+
+ it('should return false for invalid strings', () => {
+ assert.equal(OpAttributeSanitizer.isValidTarget('<'), false);
+ assert.equal(OpAttributeSanitizer.isValidTarget('~'), false);
+ assert.equal(OpAttributeSanitizer.isValidTarget('_blank+'), false);
});
});
@@ -53,7 +83,7 @@ describe('OpAttributeSanitizer', function () {
assert.equal(OpAttributeSanitizer.IsValidColorLiteral('red1'), false);
assert.equal(
OpAttributeSanitizer.IsValidColorLiteral('red-green'),
- false
+ false,
);
assert.equal(OpAttributeSanitizer.IsValidColorLiteral(''), false);
});
@@ -70,11 +100,11 @@ describe('OpAttributeSanitizer', function () {
assert.equal(OpAttributeSanitizer.IsValidRGBColor('rgb(260,0,0)'), false);
assert.equal(
OpAttributeSanitizer.IsValidRGBColor('rgb(2000,0,0)'),
- false
+ false,
);
});
});
- describe('#IsValidRel()', function () {
+ describe('IsValidRel', function () {
it('should return true if rel is valid', function () {
assert.ok(OpAttributeSanitizer.IsValidRel('nofollow'));
assert.ok(OpAttributeSanitizer.IsValidRel('tag'));
@@ -84,7 +114,7 @@ describe('OpAttributeSanitizer', function () {
assert.equal(OpAttributeSanitizer.IsValidRel(''), false);
});
});
- describe('#IsValidLang()', function () {
+ describe('IsValidLang', function () {
it('should return true if lang is valid', function () {
assert.ok(OpAttributeSanitizer.IsValidLang('javascript'));
assert.ok(OpAttributeSanitizer.IsValidLang(true));
@@ -95,49 +125,25 @@ describe('OpAttributeSanitizer', function () {
});
});
- describe('#sanitize()', function () {
- it('should return empty object', function () {
- [null, 3, undefined, 'fd'].forEach((v) => {
- assert.deepEqual(OpAttributeSanitizer.sanitize(v, {}), {});
- });
- });
-
- var attrs = {
- bold: 'nonboolval',
- color: '#12345H',
- background: '#333',
- font: 'times new roman',
- size: 'x.large',
- link: 'http://<',
- script: 'supper',
- list: ListType.Ordered,
- header: '3',
- indent: 40,
- direction: DirectionType.Rtl,
- align: AlignType.Center,
- width: '3',
- customAttr1: 'shouldnt be touched',
- mentions: true,
- mention: {
- class: 'A-cls-9',
- id: 'An-id_9:.',
- target: '_blank',
- avatar: 'http://www.yahoo.com',
- 'end-point': 'http://abc.com',
- slug: 'my-name',
- },
+ describe('sanitize', () => {
+ const noopSanitizeOptions: OpAttributeSanitizerOptions = {
+ urlSanitizer: (url) => url,
};
- it('should return sanitized attributes', function () {
- assert.deepEqual(OpAttributeSanitizer.sanitize(attrs, {}), {
- bold: true,
+
+ it('should return sanitized attributes', () => {
+ const attrs = {
+ bold: 'nonboolval',
+ color: '#12345H',
background: '#333',
font: 'times new roman',
- link: 'http://<',
- list: 'ordered',
- header: 3,
- indent: 30,
- direction: 'rtl',
- align: 'center',
+ size: 'x.large',
+ link: 'http://<',
+ script: 'supper',
+ list: ListType.Ordered,
+ header: '3',
+ indent: 40,
+ direction: DirectionType.Rtl,
+ align: AlignType.Center,
width: '3',
customAttr1: 'shouldnt be touched',
mentions: true,
@@ -146,43 +152,106 @@ describe('OpAttributeSanitizer', function () {
id: 'An-id_9:.',
target: '_blank',
avatar: 'http://www.yahoo.com',
- 'end-point': 'http://abc.com',
slug: 'my-name',
},
- });
+ };
+ assert.deepEqual(
+ OpAttributeSanitizer.sanitize(attrs, noopSanitizeOptions),
+ {
+ bold: true,
+ background: '#333',
+ font: 'times new roman',
+ link: 'http://<',
+ list: 'ordered',
+ header: 3,
+ indent: 30,
+ direction: 'rtl',
+ align: 'center',
+ width: '3',
+ customAttr1: 'shouldnt be touched',
+ mentions: true,
+ mention: {
+ class: 'A-cls-9',
+ id: 'An-id_9:.',
+ target: '_blank',
+ avatar: 'http://www.yahoo.com',
+ slug: 'my-name',
+ },
+ },
+ );
+ });
+ it('should sanitize mentions', () => {
assert.deepEqual(
OpAttributeSanitizer.sanitize(
- {
+ {
mentions: true,
mention: 1,
},
- {}
+ noopSanitizeOptions,
),
- {}
+ {
+ mentions: true,
+ mention: {},
+ },
);
+ });
- assert.deepEqual(OpAttributeSanitizer.sanitize({ header: 1 }, {}), {
- header: 1,
- });
+ it('should keep a valid header value of 1', () => {
assert.deepEqual(
- OpAttributeSanitizer.sanitize({ header: undefined }, {}),
- {}
+ OpAttributeSanitizer.sanitize({ header: 1 }, noopSanitizeOptions),
+ {
+ header: 1,
+ },
);
- assert.deepEqual(OpAttributeSanitizer.sanitize({ header: 100 }, {}), {
- header: 6,
- });
+ });
+
+ it('should exclude an undefined header value', () => {
assert.deepEqual(
- OpAttributeSanitizer.sanitize({ align: AlignType.Center }, {}),
- { align: 'center' }
+ OpAttributeSanitizer.sanitize(
+ { header: undefined },
+ noopSanitizeOptions,
+ ),
+ {},
);
+ });
+
+ it('should clamp a header value to 6', () => {
assert.deepEqual(
- OpAttributeSanitizer.sanitize({ direction: DirectionType.Rtl }, {}),
- { direction: 'rtl' }
+ OpAttributeSanitizer.sanitize({ header: 100 }, noopSanitizeOptions),
+ {
+ header: 6,
+ },
+ );
+ });
+
+ it('should keep a valid align value', () => {
+ assert.deepEqual(
+ OpAttributeSanitizer.sanitize(
+ { align: AlignType.Center },
+ noopSanitizeOptions,
+ ),
+ { align: 'center' },
+ );
+ });
+
+ it('should keep a valid direction value', () => {
+ assert.deepEqual(
+ OpAttributeSanitizer.sanitize(
+ { direction: DirectionType.Rtl },
+ noopSanitizeOptions,
+ ),
+ { direction: 'rtl' },
+ );
+ });
+
+ it('should keep a valid indent value', () => {
+ assert.deepEqual(
+ OpAttributeSanitizer.sanitize({ indent: 2 }, noopSanitizeOptions),
+ {
+ indent: 2,
+ },
);
- assert.deepEqual(OpAttributeSanitizer.sanitize({ indent: 2 }, {}), {
- indent: 2,
- });
});
});
});
diff --git a/test/OpToHtmlConverter.test.ts b/test/OpToHtmlConverter.test.ts
deleted file mode 100644
index a0aec11..0000000
--- a/test/OpToHtmlConverter.test.ts
+++ /dev/null
@@ -1,536 +0,0 @@
-import {
- OpToHtmlConverter,
- IOpToHtmlConverterOptions,
-} from './../src/OpToHtmlConverter';
-import { DeltaInsertOp } from './../src/DeltaInsertOp';
-import { InsertDataQuill } from './../src/InsertData';
-import {
- ScriptType,
- DirectionType,
- AlignType,
- DataType,
-} from './../src/value-types';
-
-let assert = require('assert');
-
-describe('OpToHtmlConverter', function () {
- describe('constructor()', function () {
- var op = new DeltaInsertOp('hello');
- it('should instantiate just fine :)', function () {
- var conv = new OpToHtmlConverter(op);
- assert.equal(conv instanceof OpToHtmlConverter, true);
- });
- });
-
- describe('prefixClass()', function () {
- it('should prefix class if an empty string prefix is not given', () => {
- var op = new DeltaInsertOp('aa');
- var c = new OpToHtmlConverter(op, { classPrefix: '' });
- var act = c.prefixClass('my-class');
- assert.equal(act, 'my-class');
-
- c = new OpToHtmlConverter(op, { classPrefix: 'xx' });
- act = c.prefixClass('my-class');
- assert.equal(act, 'xx-my-class');
-
- c = new OpToHtmlConverter(op);
- act = c.prefixClass('my-class');
- assert.equal(act, 'ql-my-class');
- });
- });
-
- describe('getCssStyles()', function () {
- var op = new DeltaInsertOp('hello');
- it('should return styles', () => {
- var c = new OpToHtmlConverter(op);
- assert.deepEqual(c.getCssStyles(), []);
-
- var o = new DeltaInsertOp('f', { background: 'red', attr1: 'red' });
- c = new OpToHtmlConverter(o, {
- customCssStyles: (op) => {
- if (op.attributes['attr1']) {
- return `color:${op.attributes['attr1']}`;
- }
- },
- });
- assert.deepEqual(c.getCssStyles(), ['color:red', 'background-color:red']);
-
- new DeltaInsertOp('f', { background: 'red', attr1: 'red' });
- c = new OpToHtmlConverter(o, {
- customCssStyles: (op) => {
- if (op.attributes['attr1']) {
- return [`color:${op.attributes['attr1']}`];
- }
- },
- });
- assert.deepEqual(c.getCssStyles(), ['color:red', 'background-color:red']);
-
- o = new DeltaInsertOp('f', { background: 'red', color: 'blue' });
- c = new OpToHtmlConverter(o);
- assert.deepEqual(c.getCssStyles(), [
- 'color:blue',
- 'background-color:red',
- ]);
-
- c = new OpToHtmlConverter(o, { allowBackgroundClasses: true });
- assert.deepEqual(c.getCssStyles(), ['color:blue']);
- });
-
- it('should return inline styles', function () {
- var op = new DeltaInsertOp('hello');
- var c = new OpToHtmlConverter(op, { inlineStyles: {} });
- assert.deepEqual(c.getCssStyles(), []);
-
- var attrs = {
- indent: 1,
- align: AlignType.Center,
- direction: DirectionType.Rtl,
- font: 'roman',
- size: 'small',
- background: 'red',
- };
- var o = new DeltaInsertOp('f', attrs);
- c = new OpToHtmlConverter(o, { inlineStyles: {} });
- var styles = [
- 'background-color:red',
- 'padding-right:3em',
- 'text-align:center',
- 'direction:rtl',
- 'font-family:roman',
- 'font-size: 0.75em',
- ];
- assert.deepEqual(c.getCssStyles(), styles);
-
- o = new DeltaInsertOp(new InsertDataQuill(DataType.Image, ''), attrs);
- c = new OpToHtmlConverter(o, { inlineStyles: {} });
- assert.deepEqual(c.getCssStyles(), styles);
-
- o = new DeltaInsertOp(new InsertDataQuill(DataType.Video, ''), attrs);
- c = new OpToHtmlConverter(o, { inlineStyles: {} });
- assert.deepEqual(c.getCssStyles(), styles);
-
- o = new DeltaInsertOp(new InsertDataQuill(DataType.Formula, ''), attrs);
- c = new OpToHtmlConverter(o, { inlineStyles: {} });
- assert.deepEqual(c.getCssStyles(), styles);
-
- o = new DeltaInsertOp('f', attrs);
- c = new OpToHtmlConverter(o, { inlineStyles: {} });
- assert.deepEqual(c.getCssStyles(), styles);
-
- o = new DeltaInsertOp(new InsertDataQuill(DataType.Image, ''), {
- direction: DirectionType.Rtl,
- });
- c = new OpToHtmlConverter(o, { inlineStyles: {} });
- assert.deepEqual(c.getCssStyles(), ['direction:rtl; text-align:inherit']);
-
- o = new DeltaInsertOp(new InsertDataQuill(DataType.Image, ''), {
- indent: 2,
- });
- c = new OpToHtmlConverter(o, { inlineStyles: {} });
- assert.deepEqual(c.getCssStyles(), ['padding-left:6em']);
-
- // Ignore invalid direction
- o = new DeltaInsertOp(new InsertDataQuill(DataType.Image, ''), {
- direction: 'ltr',
- } as any);
- c = new OpToHtmlConverter(o, { inlineStyles: {} });
- assert.deepEqual(c.getCssStyles(), []);
- });
-
- it('should allow setting inline styles', function () {
- var op = new DeltaInsertOp('f', { size: 'huge' });
- var c = new OpToHtmlConverter(op, {
- inlineStyles: {
- size: {
- huge: 'font-size: 6em',
- },
- },
- });
- assert.deepEqual(c.getCssStyles(), ['font-size: 6em']);
- });
-
- it('should fall back to defaults for inline styles that are not specified', function () {
- // Here there's no inlineStyle specified for "size", but we still render it
- // because we fall back to the default.
- var op = new DeltaInsertOp('f', { size: 'huge' });
- var c = new OpToHtmlConverter(op, {
- inlineStyles: {
- font: {
- serif: 'font-family: serif',
- },
- },
- });
- assert.deepEqual(c.getCssStyles(), ['font-size: 2.5em']);
- });
-
- it('should render default font inline styles correctly', function () {
- var op = new DeltaInsertOp('f', { font: 'monospace' });
- var c = new OpToHtmlConverter(op, { inlineStyles: {} });
- assert.deepEqual(c.getCssStyles(), [
- 'font-family: Monaco, Courier New, monospace',
- ]);
- });
-
- it('should return nothing for an inline style with no mapped entry', function () {
- var op = new DeltaInsertOp('f', { size: 'biggest' });
- var c = new OpToHtmlConverter(op, {
- inlineStyles: {
- size: {
- small: 'font-size: 0.75em',
- },
- },
- });
- assert.deepEqual(c.getCssStyles(), []);
- });
-
- it('should return nothing for an inline style where the converter returns undefined', function () {
- var op = new DeltaInsertOp('f', { size: 'biggest' });
- var c = new OpToHtmlConverter(op, {
- inlineStyles: {
- size: () => undefined,
- },
- });
- assert.deepEqual(c.getCssStyles(), []);
- });
- });
-
- describe('getCssClasses()', function () {
- it('should return prefixed classes', () => {
- var op = new DeltaInsertOp('hello');
- const options: IOpToHtmlConverterOptions = {
- customCssClasses: (op) => {
- if (op.attributes.size === 'small') {
- return ['small-size'];
- }
- },
- };
- var c = new OpToHtmlConverter(op, options);
- assert.deepEqual(c.getCssClasses(), []);
-
- var attrs = {
- indent: 1,
- align: AlignType.Center,
- direction: DirectionType.Rtl,
- font: 'roman',
- size: 'small',
- background: 'red',
- };
- var o = new DeltaInsertOp('f', attrs);
- c = new OpToHtmlConverter(o, options);
- var classes = [
- 'small-size',
- 'ql-indent-1',
- 'ql-align-center',
- 'ql-direction-rtl',
- 'ql-font-roman',
- 'ql-size-small',
- ];
- assert.deepEqual(c.getCssClasses(), classes);
-
- o = new DeltaInsertOp(new InsertDataQuill(DataType.Image, ''), attrs);
- c = new OpToHtmlConverter(o, options);
- assert.deepEqual(c.getCssClasses(), classes.concat('ql-image'));
-
- o = new DeltaInsertOp(new InsertDataQuill(DataType.Video, ''), attrs);
- c = new OpToHtmlConverter(o, options);
- assert.deepEqual(c.getCssClasses(), classes.concat('ql-video'));
-
- o = new DeltaInsertOp(new InsertDataQuill(DataType.Formula, ''), attrs);
- c = new OpToHtmlConverter(o, options);
- assert.deepEqual(c.getCssClasses(), classes.concat('ql-formula'));
-
- o = new DeltaInsertOp('f', attrs);
- c = new OpToHtmlConverter(o, {
- ...options,
- allowBackgroundClasses: true,
- });
- assert.deepEqual(c.getCssClasses(), classes.concat('ql-background-red'));
- });
-
- it('should return no classes if `inlineStyles` is specified', function () {
- var attrs = {
- indent: 1,
- align: AlignType.Center,
- direction: DirectionType.Rtl,
- font: 'roman',
- size: 'small',
- background: 'red',
- };
- var o = new DeltaInsertOp('f', attrs);
- var c = new OpToHtmlConverter(o, { inlineStyles: {} });
- assert.deepEqual(c.getCssClasses(), []);
- });
- });
-
- describe('getTags()', function () {
- it('should return tags to render this op', () => {
- var op = new DeltaInsertOp('hello');
- var c = new OpToHtmlConverter(op);
- assert.deepEqual(c.getTags(), []);
-
- var o = new DeltaInsertOp('', { code: true });
- c = new OpToHtmlConverter(o);
- assert.deepEqual(c.getTags(), ['code']);
-
- [
- ['image', 'img'],
- ['video', 'iframe'],
- ['formula', 'span'],
- ].forEach((item: DataType[]) => {
- o = new DeltaInsertOp(new InsertDataQuill(item[0], ''));
- c = new OpToHtmlConverter(o);
- assert.deepEqual(c.getTags(), [item[1]]);
- });
-
- [
- ['blockquote', 'blockquote'],
- ['code-block', 'pre'],
- ['list', 'li'],
- ['header', 'h2'],
- ].forEach((item) => {
- o = new DeltaInsertOp('', { [item[0]]: true, header: 2 });
- c = new OpToHtmlConverter(o);
- assert.deepEqual(c.getTags(), [item[1]]);
- });
-
- [
- ['blockquote', 'blockquote'],
- ['code-block', 'div'],
- ['bold', 'h2'],
- ['list', 'li'],
- ['header', 'h2'],
- ].forEach((item) => {
- o = new DeltaInsertOp('', { [item[0]]: true, header: 2 });
- c = new OpToHtmlConverter(o, {
- customTag: (format) => {
- if (format === 'code-block') {
- return 'div';
- }
- if (format === 'bold') {
- return 'b';
- }
- },
- });
- assert.deepEqual(c.getTags(), [item[1]]);
- });
-
- [
- ['blockquote', 'blockquote'],
- ['code-block', 'pre'],
- ['list', 'li'],
- ['attr1', 'attr1'],
- ].forEach((item) => {
- o = new DeltaInsertOp('', { [item[0]]: true, renderAsBlock: true });
- c = new OpToHtmlConverter(o, {
- customTag: (format, op) => {
- if (format === 'renderAsBlock' && op.attributes['attr1']) {
- return 'attr1';
- }
- },
- });
- assert.deepEqual(c.getTags(), [item[1]]);
- });
-
- var attrs = {
- link: 'http',
- script: ScriptType.Sub,
- bold: true,
- italic: true,
- strike: true,
- underline: true,
- attr1: true,
- };
- o = new DeltaInsertOp('', attrs);
- c = new OpToHtmlConverter(o, {
- customTag: (format) => {
- if (format === 'bold') {
- return 'b';
- }
- if (format === 'attr1') {
- return 'attr2';
- }
- },
- });
- assert.deepEqual(c.getTags(), ['a', 'sub', 'b', 'em', 's', 'u', 'attr2']);
- });
- });
-
- describe('getTagAttributes()', function () {
- it('should return tag attributes', () => {
- var op = new DeltaInsertOp('hello');
- var c = new OpToHtmlConverter(op);
- assert.deepEqual(c.getTagAttributes(), []);
-
- var o = new DeltaInsertOp('', { code: true, color: 'red' });
- var c = new OpToHtmlConverter(o);
- assert.deepEqual(c.getTagAttributes(), []);
-
- var o = new DeltaInsertOp(new InsertDataQuill(DataType.Image, 'http:'), {
- color: 'red',
- });
- var c = new OpToHtmlConverter(o, {
- customTagAttributes: (op) => {
- if (op.attributes.color) {
- return {
- 'data-color': op.attributes.color,
- };
- }
- },
- });
- assert.deepEqual(c.getTagAttributes(), [
- { key: 'data-color', value: 'red' },
- { key: 'class', value: 'ql-image' },
- { key: 'src', value: 'http:' },
- ]);
-
- var o = new DeltaInsertOp(new InsertDataQuill(DataType.Image, 'http:'), {
- width: '200',
- });
- var c = new OpToHtmlConverter(o);
- assert.deepEqual(c.getTagAttributes(), [
- { key: 'class', value: 'ql-image' },
- { key: 'width', value: '200' },
- { key: 'src', value: 'http:' },
- ]);
-
- var o = new DeltaInsertOp(new InsertDataQuill(DataType.Formula, '-'), {
- color: 'red',
- });
- var c = new OpToHtmlConverter(o);
- assert.deepEqual(c.getTagAttributes(), [
- { key: 'class', value: 'ql-formula' },
- ]);
-
- var o = new DeltaInsertOp(new InsertDataQuill(DataType.Video, 'http:'), {
- color: 'red',
- });
- var c = new OpToHtmlConverter(o);
- assert.deepEqual(c.getTagAttributes(), [
- { key: 'class', value: 'ql-video' },
- { key: 'frameborder', value: '0' },
- { key: 'allowfullscreen', value: 'true' },
- { key: 'src', value: 'http:' },
- ]);
-
- var o = new DeltaInsertOp('link', { color: 'red', link: 'l' });
-
- var c = new OpToHtmlConverter(o);
- assert.deepEqual(c.getTagAttributes(), [
- { key: 'style', value: 'color:red' },
- { key: 'href', value: 'l' },
- ]);
-
- var c = new OpToHtmlConverter(o, { linkRel: 'nofollow' });
- assert.deepEqual(c.getTagAttributes(), [
- { key: 'style', value: 'color:red' },
- { key: 'href', value: 'l' },
- { key: 'rel', value: 'nofollow' },
- ]);
-
- var o = new DeltaInsertOp('', { 'code-block': 'javascript' });
- var c = new OpToHtmlConverter(o);
- assert.deepEqual(c.getTagAttributes(), [
- { key: 'data-language', value: 'javascript' },
- ]);
-
- var o = new DeltaInsertOp('', { 'code-block': true });
- var c = new OpToHtmlConverter(o);
- assert.deepEqual(c.getTagAttributes(), []);
- });
- });
-
- describe('getContent()', function () {
- it('should return proper content depending on type', () => {
- var o = new DeltaInsertOp('aa', { indent: 1 });
- var c = new OpToHtmlConverter(o);
- assert.equal(c.getContent(), '');
-
- o = new DeltaInsertOp('sss<&>,', { bold: true });
- c = new OpToHtmlConverter(o);
- assert.equal(c.getContent(), 'sss<&>,');
-
- o = new DeltaInsertOp(new InsertDataQuill(DataType.Formula, 'ff'), {
- bold: true,
- });
- c = new OpToHtmlConverter(o);
- assert.equal(c.getContent(), 'ff');
-
- o = new DeltaInsertOp(new InsertDataQuill(DataType.Video, 'ff'), {
- bold: true,
- });
- c = new OpToHtmlConverter(o);
- assert.equal(c.getContent(), '');
- });
- });
-
- describe('html retrieval', function () {
- var attributes = {
- link: 'http://',
- bold: true,
- italic: true,
- underline: true,
- strike: true,
- script: ScriptType.Super,
- font: 'verdana',
- size: 'small',
- color: 'red',
- background: '#fff',
- };
- var op1 = new DeltaInsertOp('aaa', attributes);
- var c1 = new OpToHtmlConverter(op1);
- var result = [
- '',
- '',
- 'aaa',
- '',
- '',
- ].join('');
-
- describe('getHtmlParts()', function () {
- it('should return inline html', () => {
- var op = new DeltaInsertOp('');
- var c1 = new OpToHtmlConverter(op);
- var act = c1.getHtmlParts();
- assert.equal(act.closingTag + act.content + act.openingTag, '');
-
- c1 = new OpToHtmlConverter(op1);
- act = c1.getHtmlParts();
- assert.equal(act.openingTag + act.content + act.closingTag, result);
- });
- });
-
- describe('getHtml()', function () {
- it('should return inline html', () => {
- c1 = new OpToHtmlConverter(op1);
- var act = c1.getHtml();
- assert.equal(act, result);
-
- var op = new DeltaInsertOp('\n', { bold: true });
- c1 = new OpToHtmlConverter(op, { encodeHtml: false });
- assert.equal(c1.getHtml(), '\n');
-
- var op = new DeltaInsertOp('\n', { color: '#fff' });
- c1 = new OpToHtmlConverter(op);
- assert.equal(c1.getHtml(), '\n');
-
- var op = new DeltaInsertOp('\n', { 'code-block': 'javascript' });
- c1 = new OpToHtmlConverter(op);
- assert.equal(c1.getHtml(), '');
-
- var op = new DeltaInsertOp(
- new InsertDataQuill(DataType.Image, 'http://')
- );
- c1 = new OpToHtmlConverter(op, {
- customCssClasses: (_) => {
- return 'ql-custom';
- },
- });
- assert.equal(
- c1.getHtml(),
- ''
- );
- });
- });
- });
-});
diff --git a/test/QuillDeltaToHtmlConverter.test.ts b/test/QuillDeltaToHtmlConverter.test.ts
deleted file mode 100644
index 5a04560..0000000
--- a/test/QuillDeltaToHtmlConverter.test.ts
+++ /dev/null
@@ -1,1033 +0,0 @@
-import 'mocha';
-import * as assert from 'assert';
-
-import { DeltaInsertOp } from './../src/DeltaInsertOp';
-import { QuillDeltaToHtmlConverter } from './../src/QuillDeltaToHtmlConverter';
-import { callWhenXEqualY } from './_helper';
-
-import { delta1 } from './data/delta1';
-import { GroupType, ListType } from './../src/value-types';
-import { encodeHtml } from './../src/funcs-html';
-
-describe('QuillDeltaToHtmlConverter', function () {
- describe('constructor()', function () {
- var hugeOps = [
- { insert: 'huge', attributes: { size: 'huge', attr1: 'red' } },
- { insert: '\n' },
- ];
-
- it('should instantiate return proper html', function () {
- var qdc = new QuillDeltaToHtmlConverter(delta1.ops, {
- classPrefix: 'noz',
- });
- var html = qdc.convert();
- assert.equal(html, delta1.html);
- });
-
- it('should set default inline styles for `inlineStyles: true`', function () {
- var qdc = new QuillDeltaToHtmlConverter(hugeOps, {
- inlineStyles: true,
- customCssStyles: (op) => {
- if (op.attributes['attr1'] === 'red') {
- return ['color:red'];
- }
- },
- });
- var html = qdc.convert();
- assert.equal(
- html.includes('huge'),
- true,
- html
- );
- });
-
- it('should set default inline styles when `inlineStyles` is a truthy non-object', function () {
- var qdc = new QuillDeltaToHtmlConverter(hugeOps, {
- inlineStyles: 1,
- } as any);
- var html = qdc.convert();
- assert.equal(
- html.includes('huge'),
- true,
- html
- );
- });
-
- it('should allow setting inline styles', function () {
- var qdc = new QuillDeltaToHtmlConverter(hugeOps, {
- inlineStyles: {
- size: {
- huge: 'font-size: 6em',
- },
- },
- });
- var html = qdc.convert();
- assert.equal(
- html.includes('huge'),
- true,
- html
- );
- });
- });
-
- describe('convert()', function () {
- var ops2 = [
- { insert: 'this is text' },
- { insert: '\n' },
- { insert: 'this is code' },
- { insert: '\n', attributes: { 'code-block': true } },
- { insert: 'this is code TOO!' },
- { insert: '\n', attributes: { 'code-block': true } },
- ];
-
- it('should render html', function () {
- var qdc = new QuillDeltaToHtmlConverter(ops2);
-
- var html = qdc.convert();
- assert.equal(html.indexOf('this is code') > -1, true, html);
- });
-
- it('should render mention', function () {
- let ops = [
- {
- insert: 'mention',
- attributes: {
- mentions: true,
- mention: {
- 'end-point': 'http://abc.com',
- slug: 'a',
- class: 'abc',
- target: '_blank',
- },
- },
- },
- ];
- var qdc = new QuillDeltaToHtmlConverter(ops);
- var html = qdc.convert();
- assert.equal(
- html,
- [
- 'mention
',
- ].join('')
- );
-
- var qdc = new QuillDeltaToHtmlConverter([
- {
- insert: 'mention',
- attributes: {
- mentions: true,
- mention: { slug: 'aa' },
- },
- },
- ]);
- var html = qdc.convert();
- assert.equal(
- html,
- ['mention
'].join('')
- );
- });
- it('should render links with rels', function () {
- var ops = [
- {
- attributes: {
- link: '#',
- rel: 'nofollow noopener',
- },
- insert: 'external link',
- },
- {
- attributes: {
- link: '#',
- },
- insert: 'internal link',
- },
- ];
- var qdc = new QuillDeltaToHtmlConverter(ops, {
- linkRel: 'license',
- });
- var html = qdc.convert();
- assert.equal(
- html,
- 'external linkinternal link
'
- );
-
- qdc = new QuillDeltaToHtmlConverter(ops);
- html = qdc.convert();
- assert.equal(
- html,
- 'external linkinternal link
'
- );
- });
- it('should render image and image links', function () {
- let ops = [
- { insert: { image: 'http://yahoo.com/abc.jpg' } },
- {
- insert: { image: 'http://yahoo.com/def.jpg' },
- attributes: { link: 'http://aha' },
- },
- ];
- let qdc = new QuillDeltaToHtmlConverter(ops);
- let html = qdc.convert();
- assert.equal(
- html,
- [
- '',
- '',
- '',
- '',
- '',
- '
',
- ].join('')
- );
- });
-
- it('should open and close list tags', function () {
- var ops4 = [
- { insert: 'mr\n' },
- { insert: 'hello' },
- { insert: '\n', attributes: { list: 'ordered' } },
- { insert: 'there' },
- { insert: '\n', attributes: { list: 'bullet' } },
- { insert: '\n', attributes: { list: 'ordered' } },
- ];
- var qdc = new QuillDeltaToHtmlConverter(ops4);
- var html = qdc.convert();
-
- assert.equal(html.indexOf('mr') > -1, true);
- assert.equal(html.indexOf('
- there') > -1, true);
- });
-
- it('should render as separate paragraphs', function () {
- var ops4 = [{ insert: 'hello\nhow areyou?\n\nbye' }];
- var qdc = new QuillDeltaToHtmlConverter(ops4, {
- multiLineParagraph: false,
- });
- var html = qdc.convert();
-
- assert.equal(
- html,
- '
hello
how areyou?
bye
'
- );
- });
-
- it('should create checked/unchecked lists', function () {
- var ops4 = [
- { insert: 'hello' },
- { insert: '\n', attributes: { list: 'checked' } },
- { insert: 'there' },
- { insert: '\n', attributes: { list: 'unchecked' } },
- { insert: 'man' },
- { insert: '\n', attributes: { list: 'checked' } },
- { insert: 'not done' },
- { insert: '\n', attributes: { indent: 1, list: 'unchecked' } },
- ];
- var qdc = new QuillDeltaToHtmlConverter(ops4);
- var html = qdc.convert();
- assert.equal(
- html,
- [
- '',
- '- hello
',
- '- there
',
- '- man',
- '',
- '
',
- '
',
- ].join('')
- );
- });
-
- it('should wrap positional styles in right tag', function () {
- var ops4 = [
- { insert: 'mr' },
- { insert: '\n', attributes: { align: 'center' } },
- { insert: '\n', attributes: { direction: 'rtl' } },
- { insert: '\n', attributes: { indent: 2 } },
- ];
- var qdc = new QuillDeltaToHtmlConverter(ops4, { paragraphTag: 'div' });
- var html = qdc.convert();
- assert.equal(html.indexOf(' -1, true);
- assert.equal(html.indexOf('
-1, true);
- assert.equal(html.indexOf('
-1, true);
- });
- it('should render target attr correctly', () => {
- let ops = [
- { attributes: { target: '_self', link: 'http://#' }, insert: 'A' },
- { attributes: { target: '_blank', link: 'http://#' }, insert: 'B' },
- { attributes: { link: 'http://#' }, insert: 'C' },
- { insert: '\n' },
- ];
- let qdc = new QuillDeltaToHtmlConverter(ops, { linkTarget: '' });
- let html = qdc.convert();
- assert.equal(
- html,
- [
- `
A`,
- `B`,
- `C
`,
- ].join('')
- );
-
- qdc = new QuillDeltaToHtmlConverter(ops);
- html = qdc.convert();
- assert.equal(
- html,
- [
- `
A`,
- `B`,
- `C
`,
- ].join('')
- );
-
- qdc = new QuillDeltaToHtmlConverter(ops, { linkTarget: '_top' });
- html = qdc.convert();
- assert.equal(
- html,
- [
- `
A`,
- `B`,
- `C
`,
- ].join('')
- );
- });
-
- it('should convert using custom url sanitizer', () => {
- let ops = [
- { attributes: { link: 'http://yahoo<%=abc%>/ed' }, insert: 'test' },
- { attributes: { link: 'http://abc<' }, insert: 'hi' },
- ];
-
- let qdc = new QuillDeltaToHtmlConverter(ops, {
- urlSanitizer: (link: string) => {
- if (link.indexOf('<%') > -1) {
- return link;
- }
- return undefined;
- },
- });
- assert.equal(
- qdc.convert(),
- [
- `
test`,
- `hi
`,
- ].join('')
- );
- });
-
- it('should render empty table', () => {
- let ops = [
- {
- insert: '\n\n\n',
- attributes: {
- table: 'row-1',
- },
- },
- {
- attributes: {
- table: 'row-2',
- },
- insert: '\n\n\n',
- },
- {
- attributes: {
- table: 'row-3',
- },
- insert: '\n\n\n',
- },
- {
- insert: '\n',
- },
- ];
-
- let qdc = new QuillDeltaToHtmlConverter(ops);
- assert.equal(
- qdc.convert(),
- [
- `
`,
- `
`,
- ].join('')
- );
- });
-
- it('should render singe cell table', () => {
- let ops = [
- {
- insert: 'cell',
- },
- {
- insert: '\n',
- attributes: {
- table: 'row-1',
- },
- },
- ];
-
- let qdc = new QuillDeltaToHtmlConverter(ops);
- assert.equal(
- qdc.convert(),
- [
- `
`,
- ].join('')
- );
- });
-
- it('should render filled table', () => {
- let ops = [
- {
- insert: '11',
- },
- {
- attributes: {
- table: 'row-1',
- },
- insert: '\n',
- },
- {
- insert: '12',
- },
- {
- attributes: {
- table: 'row-1',
- },
- insert: '\n',
- },
- {
- insert: '13',
- },
- {
- attributes: {
- table: 'row-1',
- },
- insert: '\n',
- },
- {
- insert: '21',
- },
- {
- attributes: {
- table: 'row-2',
- },
- insert: '\n',
- },
- {
- insert: '22',
- },
- {
- attributes: {
- table: 'row-2',
- },
- insert: '\n',
- },
- {
- insert: '23',
- },
- {
- attributes: {
- table: 'row-2',
- },
- insert: '\n',
- },
- {
- insert: '31',
- },
- {
- attributes: {
- table: 'row-3',
- },
- insert: '\n',
- },
- {
- insert: '32',
- },
- {
- attributes: {
- table: 'row-3',
- },
- insert: '\n',
- },
- {
- insert: '33',
- },
- {
- attributes: {
- table: 'row-3',
- },
- insert: '\n',
- },
- {
- insert: '\n',
- },
- ];
-
- let qdc = new QuillDeltaToHtmlConverter(ops);
- assert.equal(
- qdc.convert(),
- [
- `
`,
- `11 | 12 | 13 |
`,
- `21 | 22 | 23 |
`,
- `31 | 32 | 33 |
`,
- `
`,
- `
`,
- ].join('')
- );
- });
- });
-
- describe('custom types', () => {
- it(`should return empty string if renderer not defined for
- custom blot`, () => {
- let ops = [{ insert: { customstuff: 'my val' } }];
- let qdc = new QuillDeltaToHtmlConverter(ops);
- assert.equal(qdc.convert(), '
');
- });
- it('should render custom insert types with given renderer', () => {
- let ops = [
- { insert: { bolditalic: 'my text' } },
- { insert: { blah: 1 } },
- ];
- let qdc = new QuillDeltaToHtmlConverter(ops);
- qdc.renderCustomWith((op) => {
- if (op.insert.type === 'bolditalic') {
- return '
' + op.insert.value + '';
- }
- return 'unknown';
- });
- let html = qdc.convert();
- assert.equal(html, '
my textunknown
');
- });
-
- it('should render custom insert types as blocks if renderAsBlock is specified', () => {
- let ops = [
- { insert: 'hello ' },
- { insert: { myblot: 'my friend' } },
- { insert: '!' },
- { insert: { myblot: 'how r u?' }, attributes: { renderAsBlock: true } },
- ];
- let qdc = new QuillDeltaToHtmlConverter(ops);
- qdc.renderCustomWith((op) => {
- if (op.insert.type === 'myblot') {
- return op.attributes.renderAsBlock
- ? '
' + op.insert.value + '
'
- : op.insert.value;
- }
- return 'unknown';
- });
- let html = qdc.convert();
- assert.equal(html, '
hello my friend!
how r u?
');
- });
-
- it('should render custom insert types in code blocks with given renderer', () => {
- let ops = [
- { insert: { colonizer: ':' } },
- { insert: '\n', attributes: { 'code-block': true } },
- { insert: 'code1' },
- { insert: '\n', attributes: { 'code-block': true } },
- { insert: { colonizer: ':' } },
- { insert: '\n', attributes: { 'code-block': true } },
- ];
- let renderer = (op: DeltaInsertOp) => {
- if (op.insert.type === 'colonizer') {
- return op.insert.value;
- }
- return '';
- };
- let qdc = new QuillDeltaToHtmlConverter(ops.slice(0, 2));
- qdc.renderCustomWith(renderer);
- assert.equal(qdc.convert(), '
:
');
-
- qdc = new QuillDeltaToHtmlConverter(ops);
- qdc.renderCustomWith(renderer);
- assert.equal(qdc.convert(), '
:\ncode1\n:
');
-
- qdc = new QuillDeltaToHtmlConverter(ops, {
- customTag: (format) => {
- if (format === 'code-block') {
- return 'code';
- }
- },
- });
- qdc.renderCustomWith(renderer);
- assert.equal(qdc.convert(), '
:\ncode1\n:
');
- });
-
- it('should render custom insert types in headers with given renderer', () => {
- let ops = [
- { insert: { colonizer: ':' } },
- { insert: '\n', attributes: { header: 1 } },
- { insert: 'hello' },
- { insert: '\n', attributes: { header: 1 } },
- { insert: { colonizer: ':' } },
- { insert: '\n', attributes: { header: 1 } },
- ];
- let renderer = (op: DeltaInsertOp) => {
- if (op.insert.type === 'colonizer') {
- return op.insert.value;
- }
- return '';
- };
- let qdc = new QuillDeltaToHtmlConverter(ops.slice(0, 2));
- qdc.renderCustomWith(renderer);
- assert.equal(qdc.convert(), '
:
');
-
- qdc = new QuillDeltaToHtmlConverter(ops);
- qdc.renderCustomWith(renderer);
- assert.equal(qdc.convert(), '
:
hello
:
');
- });
- });
-
- describe('_getListTag()', function () {
- it('should return proper list tag', function () {
- var op = new DeltaInsertOp('\n', { list: ListType.Ordered });
- var qdc = new QuillDeltaToHtmlConverter(delta1.ops);
- assert.equal(qdc._getListTag(op), 'ol');
-
- var op = new DeltaInsertOp('\n', { list: ListType.Bullet });
- assert.equal(qdc._getListTag(op), 'ul');
-
- var op = new DeltaInsertOp('\n', { list: ListType.Checked });
- assert.equal(qdc._getListTag(op), 'ul');
-
- var op = new DeltaInsertOp('\n', { list: ListType.Unchecked });
- assert.equal(qdc._getListTag(op), 'ul');
-
- var op = new DeltaInsertOp('d');
- assert.equal(qdc._getListTag(op), '');
- });
- });
-
- describe(' prepare data before inline and block renders', function () {
- var ops: any;
- beforeEach(function () {
- ops = [
- { insert: 'Hello' },
- { insert: ' my ', attributes: { italic: true } },
- { insert: '\n', attributes: { italic: true } },
- { insert: ' name is joey' },
- ].map((v: any) => new DeltaInsertOp(v.insert, v.attributes));
- });
-
- describe('renderInlines()', function () {
- it('should render inlines', function () {
- var qdc = new QuillDeltaToHtmlConverter([]);
- var inlines = qdc._renderInlines(ops);
- assert.equal(
- inlines,
- ['
Hello', ' my
name is joey
'].join('')
- );
-
- qdc = new QuillDeltaToHtmlConverter([], { paragraphTag: 'div' });
- var inlines = qdc._renderInlines(ops);
- assert.equal(
- inlines,
- '
Hello my
name is joey
'
- );
-
- qdc = new QuillDeltaToHtmlConverter([], { paragraphTag: '' });
- var inlines = qdc._renderInlines(ops);
- assert.equal(inlines, 'Hello
my name is joey');
- });
-
- it('should render inlines custom tag', function () {
- var qdc = new QuillDeltaToHtmlConverter([], {
- customTag: (format) => {
- if (format === 'italic') {
- return 'i';
- }
- },
- });
- var inlines = qdc._renderInlines(ops);
- assert.equal(
- inlines,
- ['
Hello', ' my
name is joey
'].join('')
- );
-
- qdc = new QuillDeltaToHtmlConverter([], { paragraphTag: 'div' });
- var inlines = qdc._renderInlines(ops);
- assert.equal(
- inlines,
- '
Hello my
name is joey
'
- );
-
- qdc = new QuillDeltaToHtmlConverter([], { paragraphTag: '' });
- var inlines = qdc._renderInlines(ops);
- assert.equal(inlines, 'Hello
my name is joey');
- });
-
- it('should render plain new line string', function () {
- var ops = [new DeltaInsertOp('\n')];
- var qdc = new QuillDeltaToHtmlConverter([]);
- assert.equal(qdc._renderInlines(ops), '
');
- });
-
- it('should render styled new line string', function () {
- var ops = [new DeltaInsertOp('\n', { font: 'arial' })];
- var qdc = new QuillDeltaToHtmlConverter([]);
- assert.equal(qdc._renderInlines(ops), '
');
-
- var qdc = new QuillDeltaToHtmlConverter([], { paragraphTag: '' });
- assert.equal(qdc._renderInlines(ops), '
');
- });
-
- it('should render when first line is new line', function () {
- var ops = [new DeltaInsertOp('\n'), new DeltaInsertOp('aa')];
- var qdc = new QuillDeltaToHtmlConverter([]);
- assert.equal(qdc._renderInlines(ops), '
aa
');
- });
-
- it('should render when last line is new line', function () {
- var ops = [new DeltaInsertOp('aa'), new DeltaInsertOp('\n')];
- var qdc = new QuillDeltaToHtmlConverter([]);
- assert.equal(qdc._renderInlines(ops), '
aa
');
- });
-
- it('should render mixed lines', function () {
- var ops = [new DeltaInsertOp('aa'), new DeltaInsertOp('bb')];
- var nlop = new DeltaInsertOp('\n');
- var stylednlop = new DeltaInsertOp('\n', {
- color: '#333',
- italic: true,
- });
- var qdc = new QuillDeltaToHtmlConverter([]);
- assert.equal(qdc._renderInlines(ops), '
aabb
');
-
- var ops0 = [nlop, ops[0], nlop, ops[1]];
- assert.equal(qdc._renderInlines(ops0), '
aa
bb
');
-
- var ops4 = [ops[0], stylednlop, stylednlop, stylednlop, ops[1]];
- assert.equal(
- qdc._renderInlines(ops4),
- ['
aa
bb
'].join('')
- );
- });
- });
-
- describe('renderBlock()', function () {
- var op = new DeltaInsertOp('\n', { header: 3, indent: 2 });
- var inlineop = new DeltaInsertOp('hi there');
- it('should render container block', function () {
- var qdc = new QuillDeltaToHtmlConverter([]);
- var blockhtml = qdc._renderBlock(op, [inlineop]);
- assert.equal(
- blockhtml,
- ['
', 'hi there
'].join('')
- );
-
- var qdc = new QuillDeltaToHtmlConverter([]);
- var blockhtml = qdc._renderBlock(op, []);
- assert.equal(
- blockhtml,
- ['
', '
'].join('')
- );
- });
-
- it('should correctly render code block', function () {
- let ops = [
- {
- insert: 'line 1',
- },
- {
- attributes: {
- 'code-block': true,
- },
- insert: '\n',
- },
- {
- insert: 'line 2',
- },
- {
- attributes: {
- 'code-block': true,
- },
- insert: '\n',
- },
- {
- insert: 'line 3',
- },
- {
- attributes: {
- 'code-block': 'javascript',
- },
- insert: '\n',
- },
- {
- insert: '
line 4
',
- },
- {
- attributes: {
- 'code-block': true,
- },
- insert: '\n',
- },
- {
- insert: 'line 5',
- },
- {
- attributes: {
- 'code-block': 'ja"va',
- },
- insert: '\n',
- },
- ];
- //console.log(encodeHtml("
line 4
"));
- var qdc = new QuillDeltaToHtmlConverter(ops);
- let html = qdc.convert();
- assert.equal(
- html,
- [
- '
line 1\nline 2
',
- '
line 3
',
- '
',
- encodeHtml('line 4
'),
- '\nline 5' + '
',
- ].join('')
- );
-
- qdc = new QuillDeltaToHtmlConverter(ops, {
- multiLineCodeblock: false,
- });
- html = qdc.convert();
- assert.equal(
- '
line 1
line 2
' +
- '
line 3
' +
- '
' +
- encodeHtml('line 4
') +
- '
' +
- '
line 5
',
- html
- );
- qdc = new QuillDeltaToHtmlConverter([ops[0], ops[1]]);
- html = qdc.convert();
- assert.equal(html, '
line 1
');
- });
- });
-
- it('should correctly render custom text block', function () {
- let ops = [
- {
- insert: 'line 1',
- },
- {
- attributes: {
- renderAsBlock: true,
- attr1: true,
- },
- insert: '\n',
- },
- {
- insert: 'line 2',
- },
- {
- attributes: {
- renderAsBlock: true,
- attr1: true,
- },
- insert: '\n',
- },
- {
- insert: 'line 3',
- },
- {
- attributes: {
- renderAsBlock: true,
- attr2: true,
- },
- insert: '\n',
- },
- {
- insert: '
line 4
',
- },
- {
- attributes: {
- renderAsBlock: true,
- attr1: true,
- },
- insert: '\n',
- },
- {
- insert: 'line 5',
- },
- {
- attributes: {
- renderAsBlock: true,
- attr1: 'test',
- },
- insert: '\n',
- },
- ];
- //console.log(encodeHtml("
line 4
"));
- var qdc = new QuillDeltaToHtmlConverter(ops, {
- customTag: (format, op) => {
- if (format === 'renderAsBlock' && op.attributes['attr1'] === 'test') {
- return 'test';
- }
- },
- customTagAttributes: (op) => {
- if (op.attributes['attr1'] === 'test') {
- return {
- attr1: op.attributes['attr1'],
- };
- }
- },
- customCssClasses: (op) => {
- if (op.attributes['attr1'] === 'test') {
- return ['ql-test'];
- }
- },
- customCssStyles: (op) => {
- if (op.attributes['attr1'] === 'test') {
- return ['color:red'];
- }
- },
- });
- let html = qdc.convert();
- assert.equal(
- html,
- [
- '
line 1
line 2
',
- '
line 3
',
- '
',
- encodeHtml('
line 4
'),
- '',
- '
line 5',
- ].join('')
- );
-
- qdc = new QuillDeltaToHtmlConverter(ops, {
- multiLineCustomBlock: false,
- });
- html = qdc.convert();
- assert.equal(
- '
line 1
line 2
' +
- '
line 3
' +
- '
' +
- encodeHtml('
line 4
') +
- '' +
- '
line 5
',
- html
- );
- qdc = new QuillDeltaToHtmlConverter([ops[0], ops[1]]);
- html = qdc.convert();
- assert.equal(html, '
line 1
');
- });
-
- describe('before n after renders()', function () {
- var ops = [
- { insert: 'hello', attributes: { bold: true } },
- { insert: '\n', attributes: { bold: true } },
- { insert: 'how r u?' },
- { insert: 'r u fine' },
- { insert: '\n', attributes: { blockquote: true } },
- { insert: { video: 'http://' } },
- { insert: 'list item 1' },
- { insert: '\n', attributes: { list: 'bullet' } },
- { insert: 'list item 1 indented' },
- { insert: '\n', attributes: { list: 'bullet', indent: 1 } },
- ];
- var qdc = new QuillDeltaToHtmlConverter(ops);
-
- it('should call before/after render callbacks ', function (done) {
- let status = { x: 0, y: 8 };
- qdc.beforeRender((groupType, data) => {
- if (groupType === GroupType.InlineGroup) {
- var op = (
data).ops[0];
- assert.ok(op.attributes.bold);
- } else if (groupType === GroupType.Video) {
- var op = (data).op;
- assert.ok(op.insert.type === 'video');
- } else if (groupType === GroupType.Block) {
- var d = data;
- assert.ok(d.op.attributes.blockquote && d.ops.length === 2);
- } else {
- var d = data;
- assert.ok(d.items.length === 1);
- }
- status.x++;
- return '';
- });
- qdc.afterRender((groupType, html) => {
- if (groupType === GroupType.InlineGroup) {
- assert.ok(html.indexOf('hello') > -1);
- } else if (groupType === GroupType.Video) {
- assert.ok(html.indexOf('