Skip to content

Commit b3ca7d8

Browse files
committed
Made link target attribute configurable and allowed individual ops to override it
1 parent 4c71ac3 commit b3ca7d8

11 files changed

+310
-243
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ var html = converter.convert();
4444
|multiLineHeader| true | Same deal as `multiLineBlockquote` for headers|
4545
|multiLineCodeblock| true | Same deal as `multiLineBlockquote` for code-blocks|
4646
|linkRel| '' | Specifies a value to put on the `rel` attr on links|
47+
|linkTarget| '_blank' | Specifies target for all links; use `''` (empty string) to not generate `target` attribute. This can be overridden by an individual link op by specifiying the `target` with a value in the respective op's attributes|
4748
|allowBackgroundClasses| false | If true, css classes will be added for background attr|
4849

4950
## Rendering Quill Formats ##

dist/browser/QuillDeltaToHtmlConverter.bundle.js

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ var OpAttributeSanitizer = (function () {
215215
'blockquote', 'code-block'
216216
];
217217
var colorAttrs = ['background', 'color'];
218-
var font = dirtyAttrs.font, size = dirtyAttrs.size, link = dirtyAttrs.link, script = dirtyAttrs.script, list = dirtyAttrs.list, header = dirtyAttrs.header, align = dirtyAttrs.align, direction = dirtyAttrs.direction, indent = dirtyAttrs.indent, mentions = dirtyAttrs.mentions, mention = dirtyAttrs.mention, width = dirtyAttrs.width;
218+
var font = dirtyAttrs.font, size = dirtyAttrs.size, link = dirtyAttrs.link, script = dirtyAttrs.script, list = dirtyAttrs.list, header = dirtyAttrs.header, align = dirtyAttrs.align, direction = dirtyAttrs.direction, indent = dirtyAttrs.indent, mentions = dirtyAttrs.mentions, mention = dirtyAttrs.mention, width = dirtyAttrs.width, target = dirtyAttrs.target;
219219
var sanitizedAttrs = booleanAttrs.concat(colorAttrs, ['font', 'size', 'link', 'script', 'list', 'header', 'align',
220220
'direction', 'indent', 'mentions', 'mention', 'width']);
221221
booleanAttrs.forEach(function (prop) {
@@ -243,6 +243,9 @@ var OpAttributeSanitizer = (function () {
243243
if (link) {
244244
cleanAttrs.link = (link + '')._scrubUrl();
245245
}
246+
if (target && OpAttributeSanitizer.isValidTarget(target)) {
247+
cleanAttrs.target = target;
248+
}
246249
if (script === value_types_1.ScriptType.Sub || value_types_1.ScriptType.Super === script) {
247250
cleanAttrs.script = script;
248251
}
@@ -291,6 +294,9 @@ var OpAttributeSanitizer = (function () {
291294
OpAttributeSanitizer.IsValidWidth = function (width) {
292295
return !!width.match(/^[0-9]*(px|em|%)?$/);
293296
};
297+
OpAttributeSanitizer.isValidTarget = function (target) {
298+
return !!target.match(/^[_a-zA-Z0-9\-]{1,50}$/);
299+
};
294300
return OpAttributeSanitizer;
295301
}());
296302
exports.OpAttributeSanitizer = OpAttributeSanitizer;
@@ -419,11 +425,16 @@ var OpToHtmlConverter = (function () {
419425
tagAttrs = tagAttrs
420426
.concat(styleAttr)
421427
.concat(this.op.isLink() ? [
422-
makeAttr('href', funcs_html_1.encodeLink(this.op.attributes.link)),
423-
makeAttr('target', '_blank')
428+
makeAttr('href', funcs_html_1.encodeLink(this.op.attributes.link))
424429
] : []);
425-
if (this.op.isLink() && !!this.options.linkRel && OpToHtmlConverter.IsValidRel(this.options.linkRel)) {
426-
tagAttrs.push(makeAttr('rel', this.options.linkRel));
430+
if (this.op.isLink()) {
431+
var target = this.op.attributes.target || this.options.linkTarget;
432+
tagAttrs = tagAttrs
433+
.concat(makeAttr('href', funcs_html_1.encodeLink(this.op.attributes.link)))
434+
.concat(target ? makeAttr('target', target) : []);
435+
if (!!this.options.linkRel && OpToHtmlConverter.IsValidRel(this.options.linkRel)) {
436+
tagAttrs.push(makeAttr('rel', this.options.linkRel));
437+
}
427438
}
428439
return tagAttrs;
429440
};
@@ -489,7 +500,8 @@ var QuillDeltaToHtmlConverter = (function () {
489500
multiLineBlockquote: true,
490501
multiLineHeader: true,
491502
multiLineCodeblock: true,
492-
allowBackgroundClasses: false
503+
allowBackgroundClasses: false,
504+
linkTarget: '_blank'
493505
}, options, {
494506
orderedListTag: 'ol',
495507
bulletListTag: 'ul',
@@ -501,6 +513,7 @@ var QuillDeltaToHtmlConverter = (function () {
501513
listItemTag: this.options.listItemTag,
502514
paragraphTag: this.options.paragraphTag,
503515
linkRel: this.options.linkRel,
516+
linkTarget: this.options.linkTarget,
504517
allowBackgroundClasses: this.options.allowBackgroundClasses
505518
};
506519
this.rawDeltaOps = deltaOps;

dist/commonjs/OpAttributeSanitizer.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ var OpAttributeSanitizer = (function () {
1616
'blockquote', 'code-block'
1717
];
1818
var colorAttrs = ['background', 'color'];
19-
var font = dirtyAttrs.font, size = dirtyAttrs.size, link = dirtyAttrs.link, script = dirtyAttrs.script, list = dirtyAttrs.list, header = dirtyAttrs.header, align = dirtyAttrs.align, direction = dirtyAttrs.direction, indent = dirtyAttrs.indent, mentions = dirtyAttrs.mentions, mention = dirtyAttrs.mention, width = dirtyAttrs.width;
19+
var font = dirtyAttrs.font, size = dirtyAttrs.size, link = dirtyAttrs.link, script = dirtyAttrs.script, list = dirtyAttrs.list, header = dirtyAttrs.header, align = dirtyAttrs.align, direction = dirtyAttrs.direction, indent = dirtyAttrs.indent, mentions = dirtyAttrs.mentions, mention = dirtyAttrs.mention, width = dirtyAttrs.width, target = dirtyAttrs.target;
2020
var sanitizedAttrs = booleanAttrs.concat(colorAttrs, ['font', 'size', 'link', 'script', 'list', 'header', 'align',
2121
'direction', 'indent', 'mentions', 'mention', 'width']);
2222
booleanAttrs.forEach(function (prop) {
@@ -44,6 +44,9 @@ var OpAttributeSanitizer = (function () {
4444
if (link) {
4545
cleanAttrs.link = (link + '')._scrubUrl();
4646
}
47+
if (target && OpAttributeSanitizer.isValidTarget(target)) {
48+
cleanAttrs.target = target;
49+
}
4750
if (script === value_types_1.ScriptType.Sub || value_types_1.ScriptType.Super === script) {
4851
cleanAttrs.script = script;
4952
}
@@ -92,6 +95,9 @@ var OpAttributeSanitizer = (function () {
9295
OpAttributeSanitizer.IsValidWidth = function (width) {
9396
return !!width.match(/^[0-9]*(px|em|%)?$/);
9497
};
98+
OpAttributeSanitizer.isValidTarget = function (target) {
99+
return !!target.match(/^[_a-zA-Z0-9\-]{1,50}$/);
100+
};
95101
return OpAttributeSanitizer;
96102
}());
97103
exports.OpAttributeSanitizer = OpAttributeSanitizer;

dist/commonjs/OpToHtmlConverter.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,16 @@ var OpToHtmlConverter = (function () {
121121
tagAttrs = tagAttrs
122122
.concat(styleAttr)
123123
.concat(this.op.isLink() ? [
124-
makeAttr('href', funcs_html_1.encodeLink(this.op.attributes.link)),
125-
makeAttr('target', '_blank')
124+
makeAttr('href', funcs_html_1.encodeLink(this.op.attributes.link))
126125
] : []);
127-
if (this.op.isLink() && !!this.options.linkRel && OpToHtmlConverter.IsValidRel(this.options.linkRel)) {
128-
tagAttrs.push(makeAttr('rel', this.options.linkRel));
126+
if (this.op.isLink()) {
127+
var target = this.op.attributes.target || this.options.linkTarget;
128+
tagAttrs = tagAttrs
129+
.concat(makeAttr('href', funcs_html_1.encodeLink(this.op.attributes.link)))
130+
.concat(target ? makeAttr('target', target) : []);
131+
if (!!this.options.linkRel && OpToHtmlConverter.IsValidRel(this.options.linkRel)) {
132+
tagAttrs.push(makeAttr('rel', this.options.linkRel));
133+
}
129134
}
130135
return tagAttrs;
131136
};

dist/commonjs/QuillDeltaToHtmlConverter.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ var QuillDeltaToHtmlConverter = (function () {
2020
multiLineBlockquote: true,
2121
multiLineHeader: true,
2222
multiLineCodeblock: true,
23-
allowBackgroundClasses: false
23+
allowBackgroundClasses: false,
24+
linkTarget: '_blank'
2425
}, options, {
2526
orderedListTag: 'ol',
2627
bulletListTag: 'ul',
@@ -32,6 +33,7 @@ var QuillDeltaToHtmlConverter = (function () {
3233
listItemTag: this.options.listItemTag,
3334
paragraphTag: this.options.paragraphTag,
3435
linkRel: this.options.linkRel,
36+
linkTarget: this.options.linkTarget,
3537
allowBackgroundClasses: this.options.allowBackgroundClasses
3638
};
3739
this.rawDeltaOps = deltaOps;

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "quill-delta-to-html",
3-
"version": "0.7.2",
3+
"version": "0.8.0",
44
"description": "Converts Quill's delta ops to HTML",
55
"main": "dist/commonjs/main.js",
66
"dependencies": {},

src/OpAttributeSanitizer.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ interface IOpAttributes {
2929
indent?: number,
3030

3131
mentions?: boolean,
32-
mention?: IMention
32+
mention?: IMention,
33+
target?: string
3334
}
3435

3536
class OpAttributeSanitizer {
@@ -49,7 +50,7 @@ class OpAttributeSanitizer {
4950
let colorAttrs = ['background', 'color'];
5051

5152
let { font, size, link, script, list, header, align,
52-
direction, indent, mentions, mention, width
53+
direction, indent, mentions, mention, width, target
5354
} = dirtyAttrs;
5455

5556
let sanitizedAttrs = [...booleanAttrs, ...colorAttrs,
@@ -86,6 +87,9 @@ class OpAttributeSanitizer {
8687
if (link) {
8788
cleanAttrs.link = (link + '')._scrubUrl();
8889
}
90+
if (target && OpAttributeSanitizer.isValidTarget(target)) {
91+
cleanAttrs.target = target;
92+
}
8993

9094
if (script === ScriptType.Sub || ScriptType.Super === script) {
9195
cleanAttrs.script = script;
@@ -110,7 +114,7 @@ class OpAttributeSanitizer {
110114
if (indent && Number(indent)) {
111115
cleanAttrs.indent = Math.min(Number(indent), 30);
112116
}
113-
117+
114118
if (mentions && mention) {
115119
let sanitizedMention = MentionSanitizer.sanitize(mention);
116120
if (Object.keys(sanitizedMention).length > 0) {
@@ -144,7 +148,11 @@ class OpAttributeSanitizer {
144148
}
145149

146150
static IsValidWidth(width: string) {
147-
return !!width.match(/^[0-9]*(px|em|%)?$/)
151+
return !!width.match(/^[0-9]*(px|em|%)?$/)
152+
}
153+
154+
static isValidTarget(target: string) {
155+
return !!target.match(/^[_a-zA-Z0-9\-]{1,50}$/);
148156
}
149157
}
150158

0 commit comments

Comments
 (0)