Skip to content

Commit

Permalink
Merge pull request nozer#73 from volser/#67_data-language
Browse files Browse the repository at this point in the history
feat: code-block language attr
  • Loading branch information
nozer authored Oct 31, 2019
2 parents 050b773 + 4f65952 commit 3fe125a
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 10 deletions.
4 changes: 4 additions & 0 deletions src/DeltaInsertOp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ class DeltaInsertOp {
return !!this.attributes['code-block'];
}

hasSameLangAs(op: DeltaInsertOp) {
return this.attributes['code-block'] === op.attributes['code-block'];
}

isJustNewline() {
return this.insert.value === NewLine;
}
Expand Down
21 changes: 19 additions & 2 deletions src/OpAttributeSanitizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ interface IOpAttributes {

list?: ListType;
blockquote?: boolean | undefined;
'code-block'?: boolean | undefined;
'code-block'?: string | boolean | undefined;
header?: number | undefined;
align?: AlignType;
direction?: DirectionType;
Expand Down Expand Up @@ -84,6 +84,7 @@ class OpAttributeSanitizer {
target,
rel
} = dirtyAttrs;
let codeBlock = dirtyAttrs['code-block'];

let sanitizedAttrs = [
...booleanAttrs,
Expand All @@ -101,7 +102,8 @@ class OpAttributeSanitizer {
'mention',
'width',
'target',
'rel'
'rel',
'code-block'
];
booleanAttrs.forEach(function(prop: string) {
var v = (<any>dirtyAttrs)[prop];
Expand Down Expand Up @@ -148,6 +150,14 @@ class OpAttributeSanitizer {
cleanAttrs.rel = rel;
}

if (codeBlock) {
if (OpAttributeSanitizer.IsValidLang(codeBlock)) {
cleanAttrs['code-block'] = codeBlock;
} else {
cleanAttrs['code-block'] = !!codeBlock;
}
}

if (script === ScriptType.Sub || ScriptType.Super === script) {
cleanAttrs.script = script;
}
Expand Down Expand Up @@ -246,6 +256,13 @@ class OpAttributeSanitizer {
static IsValidRel(relStr: string) {
return !!relStr.match(/^[a-zA-Z\s\-]{1,250}$/i);
}

static IsValidLang(lang: string | boolean) {
if (typeof lang === 'boolean') {
return true;
}
return !!lang.match(/^[a-zA-Z\s\-\\\/\+]{1,50}$/i);
}
}

export { OpAttributeSanitizer, IOpAttributes, IOpAttributeSanitizerOptions };
9 changes: 9 additions & 0 deletions src/OpToHtmlConverter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,15 @@ class OpToHtmlConverter {
tagAttrs.push(makeAttr('style', styles.join(';')));
}

if (
this.op.isCodeBlock() &&
typeof this.op.attributes['code-block'] === 'string'
) {
return tagAttrs.concat(
makeAttr('data-language', this.op.attributes['code-block'])
);
}

if (this.op.isContainerBlock()) {
return tagAttrs;
}
Expand Down
11 changes: 8 additions & 3 deletions src/grouper/Grouper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ class Grouper {
}

return (
(blocksOf.codeBlocks && Grouper.areBothCodeblocks(g, gPrev)) ||
(blocksOf.codeBlocks &&
Grouper.areBothCodeblocksWithSameLang(g, gPrev)) ||
(blocksOf.blockquotes &&
Grouper.areBothBlockquotesWithSameAdi(g, gPrev)) ||
(blocksOf.header && Grouper.areBothSameHeadersWithSameAdi(g, gPrev))
Expand Down Expand Up @@ -104,8 +105,12 @@ class Grouper {
});
}

static areBothCodeblocks(g1: BlockGroup, gOther: BlockGroup) {
return g1.op.isCodeBlock() && gOther.op.isCodeBlock();
static areBothCodeblocksWithSameLang(g1: BlockGroup, gOther: BlockGroup) {
return (
g1.op.isCodeBlock() &&
gOther.op.isCodeBlock() &&
g1.op.hasSameLangAs(gOther.op)
);
}

static areBothSameHeadersWithSameAdi(g1: BlockGroup, gOther: BlockGroup) {
Expand Down
10 changes: 10 additions & 0 deletions test/OpAttributeSanitizer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,16 @@ describe('OpAttributeSanitizer', function() {
assert.equal(OpAttributeSanitizer.IsValidRel(''), false);
});
});
describe('#IsValidLang()', function() {
it('should return true if lang is valid', function() {
assert.ok(OpAttributeSanitizer.IsValidLang('javascript'));
assert.ok(OpAttributeSanitizer.IsValidLang(true));
assert.ok(OpAttributeSanitizer.IsValidLang('C++'));
assert.ok(OpAttributeSanitizer.IsValidLang('HTML/XML'));
assert.equal(OpAttributeSanitizer.IsValidLang('lang"uage'), false);
assert.equal(OpAttributeSanitizer.IsValidLang(''), false);
});
});

describe('#sanitize()', function() {
it('should return empty object', function() {
Expand Down
14 changes: 14 additions & 0 deletions test/OpToHtmlConverter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,16 @@ describe('OpToHtmlConverter', function() {
{ 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(), []);
});
});

Expand Down Expand Up @@ -415,6 +425,10 @@ describe('OpToHtmlConverter', function() {
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(), '<pre data-language="javascript"></pre>');

var op = new DeltaInsertOp(
new InsertDataQuill(DataType.Image, 'http://')
);
Expand Down
23 changes: 18 additions & 5 deletions test/QuillDeltaToHtmlConverter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ describe('QuillDeltaToHtmlConverter', function() {
},
{
attributes: {
'code-block': true
'code-block': 'javascript'
},
insert: '\n'
},
Expand All @@ -564,6 +564,15 @@ describe('QuillDeltaToHtmlConverter', function() {
'code-block': true
},
insert: '\n'
},
{
insert: 'line 5'
},
{
attributes: {
'code-block': 'ja"va'
},
insert: '\n'
}
];
//console.log(encodeHtml("<p>line 4</p>"));
Expand All @@ -572,9 +581,11 @@ describe('QuillDeltaToHtmlConverter', function() {
assert.equal(
html,
[
'<pre>line 1\nline 2\nline 3\n',
'<pre>line 1\nline 2</pre>',
'<pre data-language="javascript">line 3</pre>',
'<pre>',
encodeHtml('<p>line 4</p>'),
'</pre>'
'\nline 5' + '</pre>'
].join('')
);

Expand All @@ -583,10 +594,12 @@ describe('QuillDeltaToHtmlConverter', function() {
});
html = qdc.convert();
assert.equal(
'<pre>line 1</pre><pre>line 2</pre><pre>line 3</pre>' +
'<pre>line 1</pre><pre>line 2</pre>' +
'<pre data-language="javascript">line 3</pre>' +
'<pre>' +
encodeHtml('<p>line 4</p>') +
'</pre>',
'</pre>' +
'<pre>line 5</pre>',
html
);
qdc = new QuillDeltaToHtmlConverter([ops[0], ops[1]]);
Expand Down

0 comments on commit 3fe125a

Please sign in to comment.