From 1d2f422627bf0ea4a1664a46ca497e91edc1956c Mon Sep 17 00:00:00 2001 From: curbengh <43627182+curbengh@users.noreply.github.com> Date: Sun, 15 Sep 2019 03:40:12 +0100 Subject: [PATCH 1/4] fix(html_tag): escape html and encode url by default --- lib/html_tag.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/html_tag.js b/lib/html_tag.js index 8c7541f2..6b8036ac 100644 --- a/lib/html_tag.js +++ b/lib/html_tag.js @@ -1,15 +1,25 @@ 'use strict'; -function htmlTag(tag, attrs, text) { +const encodeURL = require('./encode_url'); +const escapeHTML = require('./escape_html'); + +function htmlTag(tag, attrs, text, escape = true) { if (!tag) throw new TypeError('tag is required!'); - let result = `<${tag}`; + let result = `<${escapeHTML(tag)}`; for (const i in attrs) { - if (attrs[i] != null) result += ` ${i}="${attrs[i]}"`; + if (attrs[i] === null || typeof attrs[i] === 'undefined') result += ''; + else { + if (i === 'href' || i === 'src') result += ` ${i}="${encodeURL(attrs[i])}"`; + else result += ` ${escapeHTML(i)}="${escapeHTML(String(attrs[i]))}"`; + } } - result += text == null ? '>' : `>${text}`; + if (escape && text) text = escapeHTML(String(text)); + + if (text === null || typeof text === 'undefined') result += '>'; + else result += `>${text}` return result; } From 86f41d3cc0210204d4c18a9671cd9100d8292381 Mon Sep 17 00:00:00 2001 From: curbengh <43627182+curbengh@users.noreply.github.com> Date: Sun, 15 Sep 2019 03:40:48 +0100 Subject: [PATCH 2/4] test(html_tag): escape html and encode url by default --- test/html_tag.spec.js | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/test/html_tag.spec.js b/test/html_tag.spec.js index c3601498..dc286773 100644 --- a/test/html_tag.spec.js +++ b/test/html_tag.spec.js @@ -24,7 +24,7 @@ describe('htmlTag', () => { it('tag + attrs + text', () => { htmlTag('a', { href: 'http://zespia.tw' - }, 'My blog').should.eql('My blog'); + }, 'My blog').should.eql('My blog'); }); it('tag + empty ALT attr', () => { @@ -38,21 +38,21 @@ describe('htmlTag', () => { htmlTag('a', { href: 'http://zespia.tw', tabindex: 0 - }, 'My blog').should.eql('My blog'); + }, 'My blog').should.eql('My blog'); }); it('passing a null alt attribute', () => { htmlTag('a', { href: 'http://zespia.tw', alt: null - }, 'My blog').should.eql('My blog'); + }, 'My blog').should.eql('My blog'); }); it('passing a undefined alt attribute', () => { htmlTag('a', { href: 'http://zespia.tw', alt: undefined - }, 'My blog').should.eql('My blog'); + }, 'My blog').should.eql('My blog'); }); it('tag is required', () => { @@ -62,4 +62,23 @@ describe('htmlTag', () => { err.should.have.property('message', 'tag is required!'); } }); + + it('encode url', () => { + htmlTag('img', { + src: 'http://foo.com/bár.jpg' + }).should.eql(''); + }); + + it('escape html tag', () => { + htmlTag('foo', { + bar: '' + }, '').should.eql('<baz>'); + }); + + it('escape html tag (escape off)', () => { + htmlTag('foo', { + bar: '' + }, '', false).should.eql(''); + }); + }); From 85ec95f8aa2e40bc38c2c091b00a3f67efdc9c6a Mon Sep 17 00:00:00 2001 From: curbengh <43627182+curbengh@users.noreply.github.com> Date: Sun, 15 Sep 2019 03:57:03 +0100 Subject: [PATCH 3/4] style: semicolon --- lib/html_tag.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/html_tag.js b/lib/html_tag.js index 6b8036ac..caad51ac 100644 --- a/lib/html_tag.js +++ b/lib/html_tag.js @@ -19,7 +19,7 @@ function htmlTag(tag, attrs, text, escape = true) { if (escape && text) text = escapeHTML(String(text)); if (text === null || typeof text === 'undefined') result += '>'; - else result += `>${text}` + else result += `>${text}`; return result; } From 9c8bfe220d51828bf543a541632f3dbbdacb590c Mon Sep 17 00:00:00 2001 From: curbengh <43627182+curbengh@users.noreply.github.com> Date: Sun, 15 Sep 2019 04:15:13 +0100 Subject: [PATCH 4/4] docs(html_tag): escape html and encode url by default --- README.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 19e30d77..f646225d 100644 --- a/README.md +++ b/README.md @@ -165,16 +165,29 @@ Option | Description | Default `tab`| Replace tabs | `autoDetect` | Detect language automatically | false -### htmlTag(tag, attrs, text) +### htmlTag(tag, attrs, text, escape) Creates a html tag. +Option | Description | Default +--- | --- | --- +`tag` | Tag / element name | +`attrs` | Attribute(s) and its value.
Value is always [escaped](#escapehtmlstr), URL is always [encoded](#encodeurlstr). | +`text` | Text | +`escape` | Whether to escape the text | true + ``` js htmlTag('img', {src: 'example.png'}) // htmlTag('a', {href: 'http://hexo.io/'}, 'Hexo') // Hexo + +htmlTag('link', {href: 'http://foo.com/'}, 'bar') +// <bar> + +htmlTag('a', {href: 'http://foo.com/'}, 'bold', false) +// bold ``` ### Pattern(rule)