apply-html
Advanced tools
Comparing version
@@ -10,4 +10,6 @@ 'use strict'; | ||
class SafeString { | ||
constructor(raw) { | ||
this.raw = String(raw); | ||
constructor(value) { | ||
this.raw = String(value); | ||
Object.freeze(this); | ||
} | ||
@@ -19,6 +21,2 @@ | ||
inspect() { | ||
return this.raw; | ||
} | ||
toJSON() { | ||
@@ -33,3 +31,17 @@ return this.raw; | ||
Object.freeze(SafeString.prototype); | ||
function raw(value) { | ||
if (value instanceof SafeString) { | ||
return value; | ||
} | ||
return new SafeString(value); | ||
} | ||
function escape(value) { | ||
if (value instanceof SafeString) { | ||
return value; | ||
} | ||
if (typeof value !== 'string') { | ||
@@ -39,9 +51,11 @@ throw new TypeError('Expected a string.'); | ||
return value | ||
.replace(/&/g, '&') | ||
.replace(/>/g, '>') | ||
.replace(/</g, '<') | ||
.replace(/"/g, '"') | ||
.replace(/'/g, ''') | ||
.replace(/`/g, '`'); | ||
return raw( | ||
value | ||
.replace(/&/g, '&') | ||
.replace(/>/g, '>') | ||
.replace(/</g, '<') | ||
.replace(/"/g, '"') | ||
.replace(/'/g, ''') | ||
.replace(/`/g, '`') | ||
); | ||
} | ||
@@ -51,4 +65,3 @@ | ||
if (value instanceof SafeString) { | ||
// Assume trustworthy | ||
return value.raw; | ||
return value; | ||
} | ||
@@ -87,3 +100,15 @@ | ||
function apply(element, string) { | ||
function html(strings, ...values) { | ||
const literals = strings.raw; | ||
let result = literals[0]; | ||
values.forEach((value, i) => { | ||
result += serialize(value); | ||
result += literals[i + 1]; | ||
}); | ||
return raw(result); | ||
} | ||
function apply(element, value) { | ||
if (!(element instanceof Element)) { | ||
@@ -93,7 +118,7 @@ throw new TypeError('Expected an element.'); | ||
if (string instanceof SafeString) { | ||
string = string.toString(); | ||
if (value instanceof SafeString) { | ||
value = value.toString(); | ||
} | ||
if (typeof string !== 'string') { | ||
if (typeof value !== 'string') { | ||
throw new TypeError('Expected a string.'); | ||
@@ -107,3 +132,3 @@ } | ||
// execution of custom-element lifecycle callbacks. | ||
template.innerHTML = string; | ||
template.innerHTML = value; | ||
@@ -118,30 +143,7 @@ // Patch live DOM with new inert DOM | ||
function html(strings, ...values) { | ||
const literals = strings.raw; | ||
let result = ''; | ||
values.forEach((value, i) => { | ||
result += literals[i]; | ||
result += serialize(value); | ||
}); | ||
result += literals[literals.length - 1]; | ||
return new SafeString(result); | ||
} | ||
function raw(string) { | ||
if (string instanceof SafeString) { | ||
return string; | ||
} | ||
return new SafeString(string); | ||
} | ||
exports.SafeString = SafeString; | ||
exports.raw = raw; | ||
exports.escape = escape; | ||
exports.serialize = serialize; | ||
exports.html = html; | ||
exports.apply = apply; | ||
exports.html = html; | ||
exports.raw = raw; | ||
//# sourceMappingURL=apply-html.cjs.js.map |
import nanomorph from 'nanomorph'; | ||
class SafeString { | ||
constructor(raw) { | ||
this.raw = String(raw); | ||
constructor(value) { | ||
this.raw = String(value); | ||
Object.freeze(this); | ||
} | ||
@@ -12,6 +14,2 @@ | ||
inspect() { | ||
return this.raw; | ||
} | ||
toJSON() { | ||
@@ -26,3 +24,17 @@ return this.raw; | ||
Object.freeze(SafeString.prototype); | ||
function raw(value) { | ||
if (value instanceof SafeString) { | ||
return value; | ||
} | ||
return new SafeString(value); | ||
} | ||
function escape(value) { | ||
if (value instanceof SafeString) { | ||
return value; | ||
} | ||
if (typeof value !== 'string') { | ||
@@ -32,9 +44,11 @@ throw new TypeError('Expected a string.'); | ||
return value | ||
.replace(/&/g, '&') | ||
.replace(/>/g, '>') | ||
.replace(/</g, '<') | ||
.replace(/"/g, '"') | ||
.replace(/'/g, ''') | ||
.replace(/`/g, '`'); | ||
return raw( | ||
value | ||
.replace(/&/g, '&') | ||
.replace(/>/g, '>') | ||
.replace(/</g, '<') | ||
.replace(/"/g, '"') | ||
.replace(/'/g, ''') | ||
.replace(/`/g, '`') | ||
); | ||
} | ||
@@ -44,4 +58,3 @@ | ||
if (value instanceof SafeString) { | ||
// Assume trustworthy | ||
return value.raw; | ||
return value; | ||
} | ||
@@ -80,3 +93,15 @@ | ||
function apply(element, string) { | ||
function html(strings, ...values) { | ||
const literals = strings.raw; | ||
let result = literals[0]; | ||
values.forEach((value, i) => { | ||
result += serialize(value); | ||
result += literals[i + 1]; | ||
}); | ||
return raw(result); | ||
} | ||
function apply(element, value) { | ||
if (!(element instanceof Element)) { | ||
@@ -86,7 +111,7 @@ throw new TypeError('Expected an element.'); | ||
if (string instanceof SafeString) { | ||
string = string.toString(); | ||
if (value instanceof SafeString) { | ||
value = value.toString(); | ||
} | ||
if (typeof string !== 'string') { | ||
if (typeof value !== 'string') { | ||
throw new TypeError('Expected a string.'); | ||
@@ -100,3 +125,3 @@ } | ||
// execution of custom-element lifecycle callbacks. | ||
template.innerHTML = string; | ||
template.innerHTML = value; | ||
@@ -111,25 +136,3 @@ // Patch live DOM with new inert DOM | ||
function html(strings, ...values) { | ||
const literals = strings.raw; | ||
let result = ''; | ||
values.forEach((value, i) => { | ||
result += literals[i]; | ||
result += serialize(value); | ||
}); | ||
result += literals[literals.length - 1]; | ||
return new SafeString(result); | ||
} | ||
function raw(string) { | ||
if (string instanceof SafeString) { | ||
return string; | ||
} | ||
return new SafeString(string); | ||
} | ||
export { SafeString, escape, serialize, apply, html, raw }; | ||
export { raw, escape, serialize, html, apply }; | ||
//# sourceMappingURL=apply-html.es.js.map |
{ | ||
"name": "apply-html", | ||
"version": "1.0.0-22", | ||
"version": "1.0.0-23", | ||
"description": "It's `.innerHTML = ''` for the 21st century.", | ||
@@ -10,3 +10,3 @@ "scripts": { | ||
"lint-eslint": "eslint --ignore-path .gitignore --fix \"**/*.js\"", | ||
"test": "nyc -r none run-s test-* && nyc report -r lcov -r text", | ||
"test": "nyc -r none run-s test-* && nyc report", | ||
"test-node": "NODE_ENV=test rollup test/node.js -c | node | tap-diff", | ||
@@ -17,3 +17,3 @@ "test-browser": "NODE_ENV=test rollup test/browser.js -c | run-headless | tap-diff", | ||
"precommit": "run-s test build && git add .", | ||
"prepublishOnly": "git diff-index --quiet HEAD" | ||
"prepublishOnly": "run-s test build" | ||
}, | ||
@@ -51,3 +51,3 @@ "keywords": [ | ||
"eslint-config-prettier": "^2.9.0", | ||
"eslint-config-whim": "^3.1.0-9", | ||
"eslint-config-whim": "^3.1.0", | ||
"husky": "^0.14.3", | ||
@@ -58,3 +58,3 @@ "npm-run-all": "^4.1.2", | ||
"rollup": "^0.55.5", | ||
"rollup-config-whim": "^1.0.0-10", | ||
"rollup-config-whim": "^1.0.1", | ||
"run-headless": "^2.0.1", | ||
@@ -77,2 +77,6 @@ "tap-diff": "^0.1.1" | ||
"src/**" | ||
], | ||
"reporter": [ | ||
"lcov", | ||
"text" | ||
] | ||
@@ -79,0 +83,0 @@ }, |
@@ -104,4 +104,5 @@ # apply-html | ||
- `Function` - Throws a `TypeError`. | ||
- `Number` - Inserted as-is. | ||
- `Object` - Converted to an HTML-escaped JSON blob. | ||
- `SafeString|Number` - Inserted as-is. | ||
- `SafeString` - Inserted as-is. | ||
- `String` - HTML-escaped to safeguard against [XSS](https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)). To opt out of escaping, use [`raw()`](#rawstring-safestring). | ||
@@ -152,18 +153,6 @@ | ||
- [morphdom](http://npm.im/morphdom) | ||
- [petit-dom](http://npm.im/petit-dom) | ||
- [react](http://npm.im/react) | ||
- [snabbdom](http://npm.im/snabbdom) | ||
- [vue.js](http://npm.im/vue) | ||
- and [more...](https://rawgit.com/krausest/js-framework-benchmark/master/webdriver-ts-results/table.html) | ||
## Contribute | ||
Standards for this project, including tests, code coverage, and semantics are enforced with a build tool. Pull requests must include passing tests with 100% code coverage and no linting errors. | ||
### Test | ||
```command | ||
$ npm test | ||
``` | ||
---- | ||
@@ -170,0 +159,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
23644
0.19%205
1.49%167
-6.18%