Skip to content

Commit

Permalink
Made link target attribute configurable and allowed individual ops to…
Browse files Browse the repository at this point in the history
… override it
  • Loading branch information
nozer committed Apr 22, 2018
1 parent 4c71ac3 commit b3ca7d8
Show file tree
Hide file tree
Showing 11 changed files with 310 additions and 243 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ var html = converter.convert();
|multiLineHeader| true | Same deal as `multiLineBlockquote` for headers|
|multiLineCodeblock| true | Same deal as `multiLineBlockquote` for code-blocks|
|linkRel| '' | Specifies a value to put on the `rel` attr on links|
|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|
|allowBackgroundClasses| false | If true, css classes will be added for background attr|

## Rendering Quill Formats ##
Expand Down
25 changes: 19 additions & 6 deletions dist/browser/QuillDeltaToHtmlConverter.bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ var OpAttributeSanitizer = (function () {
'blockquote', 'code-block'
];
var colorAttrs = ['background', 'color'];
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;
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;
var sanitizedAttrs = booleanAttrs.concat(colorAttrs, ['font', 'size', 'link', 'script', 'list', 'header', 'align',
'direction', 'indent', 'mentions', 'mention', 'width']);
booleanAttrs.forEach(function (prop) {
Expand Down Expand Up @@ -243,6 +243,9 @@ var OpAttributeSanitizer = (function () {
if (link) {
cleanAttrs.link = (link + '')._scrubUrl();
}
if (target && OpAttributeSanitizer.isValidTarget(target)) {
cleanAttrs.target = target;
}
if (script === value_types_1.ScriptType.Sub || value_types_1.ScriptType.Super === script) {
cleanAttrs.script = script;
}
Expand Down Expand Up @@ -291,6 +294,9 @@ var OpAttributeSanitizer = (function () {
OpAttributeSanitizer.IsValidWidth = function (width) {
return !!width.match(/^[0-9]*(px|em|%)?$/);
};
OpAttributeSanitizer.isValidTarget = function (target) {
return !!target.match(/^[_a-zA-Z0-9\-]{1,50}$/);
};
return OpAttributeSanitizer;
}());
exports.OpAttributeSanitizer = OpAttributeSanitizer;
Expand Down Expand Up @@ -419,11 +425,16 @@ var OpToHtmlConverter = (function () {
tagAttrs = tagAttrs
.concat(styleAttr)
.concat(this.op.isLink() ? [
makeAttr('href', funcs_html_1.encodeLink(this.op.attributes.link)),
makeAttr('target', '_blank')
makeAttr('href', funcs_html_1.encodeLink(this.op.attributes.link))
] : []);
if (this.op.isLink() && !!this.options.linkRel && OpToHtmlConverter.IsValidRel(this.options.linkRel)) {
tagAttrs.push(makeAttr('rel', this.options.linkRel));
if (this.op.isLink()) {
var target = this.op.attributes.target || this.options.linkTarget;
tagAttrs = tagAttrs
.concat(makeAttr('href', funcs_html_1.encodeLink(this.op.attributes.link)))
.concat(target ? makeAttr('target', target) : []);
if (!!this.options.linkRel && OpToHtmlConverter.IsValidRel(this.options.linkRel)) {
tagAttrs.push(makeAttr('rel', this.options.linkRel));
}
}
return tagAttrs;
};
Expand Down Expand Up @@ -489,7 +500,8 @@ var QuillDeltaToHtmlConverter = (function () {
multiLineBlockquote: true,
multiLineHeader: true,
multiLineCodeblock: true,
allowBackgroundClasses: false
allowBackgroundClasses: false,
linkTarget: '_blank'
}, options, {
orderedListTag: 'ol',
bulletListTag: 'ul',
Expand All @@ -501,6 +513,7 @@ var QuillDeltaToHtmlConverter = (function () {
listItemTag: this.options.listItemTag,
paragraphTag: this.options.paragraphTag,
linkRel: this.options.linkRel,
linkTarget: this.options.linkTarget,
allowBackgroundClasses: this.options.allowBackgroundClasses
};
this.rawDeltaOps = deltaOps;
Expand Down
8 changes: 7 additions & 1 deletion dist/commonjs/OpAttributeSanitizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ var OpAttributeSanitizer = (function () {
'blockquote', 'code-block'
];
var colorAttrs = ['background', 'color'];
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;
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;
var sanitizedAttrs = booleanAttrs.concat(colorAttrs, ['font', 'size', 'link', 'script', 'list', 'header', 'align',
'direction', 'indent', 'mentions', 'mention', 'width']);
booleanAttrs.forEach(function (prop) {
Expand Down Expand Up @@ -44,6 +44,9 @@ var OpAttributeSanitizer = (function () {
if (link) {
cleanAttrs.link = (link + '')._scrubUrl();
}
if (target && OpAttributeSanitizer.isValidTarget(target)) {
cleanAttrs.target = target;
}
if (script === value_types_1.ScriptType.Sub || value_types_1.ScriptType.Super === script) {
cleanAttrs.script = script;
}
Expand Down Expand Up @@ -92,6 +95,9 @@ var OpAttributeSanitizer = (function () {
OpAttributeSanitizer.IsValidWidth = function (width) {
return !!width.match(/^[0-9]*(px|em|%)?$/);
};
OpAttributeSanitizer.isValidTarget = function (target) {
return !!target.match(/^[_a-zA-Z0-9\-]{1,50}$/);
};
return OpAttributeSanitizer;
}());
exports.OpAttributeSanitizer = OpAttributeSanitizer;
13 changes: 9 additions & 4 deletions dist/commonjs/OpToHtmlConverter.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,16 @@ var OpToHtmlConverter = (function () {
tagAttrs = tagAttrs
.concat(styleAttr)
.concat(this.op.isLink() ? [
makeAttr('href', funcs_html_1.encodeLink(this.op.attributes.link)),
makeAttr('target', '_blank')
makeAttr('href', funcs_html_1.encodeLink(this.op.attributes.link))
] : []);
if (this.op.isLink() && !!this.options.linkRel && OpToHtmlConverter.IsValidRel(this.options.linkRel)) {
tagAttrs.push(makeAttr('rel', this.options.linkRel));
if (this.op.isLink()) {
var target = this.op.attributes.target || this.options.linkTarget;
tagAttrs = tagAttrs
.concat(makeAttr('href', funcs_html_1.encodeLink(this.op.attributes.link)))
.concat(target ? makeAttr('target', target) : []);
if (!!this.options.linkRel && OpToHtmlConverter.IsValidRel(this.options.linkRel)) {
tagAttrs.push(makeAttr('rel', this.options.linkRel));
}
}
return tagAttrs;
};
Expand Down
4 changes: 3 additions & 1 deletion dist/commonjs/QuillDeltaToHtmlConverter.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ var QuillDeltaToHtmlConverter = (function () {
multiLineBlockquote: true,
multiLineHeader: true,
multiLineCodeblock: true,
allowBackgroundClasses: false
allowBackgroundClasses: false,
linkTarget: '_blank'
}, options, {
orderedListTag: 'ol',
bulletListTag: 'ul',
Expand All @@ -32,6 +33,7 @@ var QuillDeltaToHtmlConverter = (function () {
listItemTag: this.options.listItemTag,
paragraphTag: this.options.paragraphTag,
linkRel: this.options.linkRel,
linkTarget: this.options.linkTarget,
allowBackgroundClasses: this.options.allowBackgroundClasses
};
this.rawDeltaOps = deltaOps;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "quill-delta-to-html",
"version": "0.7.2",
"version": "0.8.0",
"description": "Converts Quill's delta ops to HTML",
"main": "dist/commonjs/main.js",
"dependencies": {},
Expand Down
16 changes: 12 additions & 4 deletions src/OpAttributeSanitizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ interface IOpAttributes {
indent?: number,

mentions?: boolean,
mention?: IMention
mention?: IMention,
target?: string
}

class OpAttributeSanitizer {
Expand All @@ -49,7 +50,7 @@ class OpAttributeSanitizer {
let colorAttrs = ['background', 'color'];

let { font, size, link, script, list, header, align,
direction, indent, mentions, mention, width
direction, indent, mentions, mention, width, target
} = dirtyAttrs;

let sanitizedAttrs = [...booleanAttrs, ...colorAttrs,
Expand Down Expand Up @@ -86,6 +87,9 @@ class OpAttributeSanitizer {
if (link) {
cleanAttrs.link = (link + '')._scrubUrl();
}
if (target && OpAttributeSanitizer.isValidTarget(target)) {
cleanAttrs.target = target;
}

if (script === ScriptType.Sub || ScriptType.Super === script) {
cleanAttrs.script = script;
Expand All @@ -110,7 +114,7 @@ class OpAttributeSanitizer {
if (indent && Number(indent)) {
cleanAttrs.indent = Math.min(Number(indent), 30);
}

if (mentions && mention) {
let sanitizedMention = MentionSanitizer.sanitize(mention);
if (Object.keys(sanitizedMention).length > 0) {
Expand Down Expand Up @@ -144,7 +148,11 @@ class OpAttributeSanitizer {
}

static IsValidWidth(width: string) {
return !!width.match(/^[0-9]*(px|em|%)?$/)
return !!width.match(/^[0-9]*(px|em|%)?$/)
}

static isValidTarget(target: string) {
return !!target.match(/^[_a-zA-Z0-9\-]{1,50}$/);
}
}

Expand Down
Loading

0 comments on commit b3ca7d8

Please sign in to comment.