Socket
Socket
Sign inDemoInstall

hexo-util

Package Overview
Dependencies
Maintainers
8
Versions
55
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hexo-util - npm Package Compare versions

Comparing version 1.7.0 to 1.8.0

lib/cache.js

4

lib/color.js

@@ -275,3 +275,5 @@ 'use strict';

if (!s) {
this.r = this.g = this.b = l * 255;
this.r = l * 255;
this.g = this.r;
this.b = this.r;
}

@@ -278,0 +280,0 @@

@@ -6,3 +6,3 @@ 'use strict';

const safeDecodeURI = (str) => {
const safeDecodeURI = str => {
try {

@@ -15,3 +15,3 @@ return decodeURI(str);

const decodeURL = (str) => {
const decodeURL = str => {
if (parse(str).protocol) {

@@ -18,0 +18,0 @@ const parsed = new URL(str);

@@ -6,3 +6,3 @@ 'use strict';

const safeDecodeURI = (str) => {
const safeDecodeURI = str => {
try {

@@ -15,3 +15,3 @@ return decodeURI(str);

const encodeURL = (str) => {
const encodeURL = str => {
if (parse(str).protocol) {

@@ -18,0 +18,0 @@ const parsed = new URL(str);

@@ -7,2 +7,5 @@ 'use strict';

const Cache = require('./cache');
const cache = new Cache();
function fullUrlForHelper(path = '/') {

@@ -13,10 +16,2 @@ const pathRegex = /^(\/\/|http(s)?:)/;

const { config } = this;
const sitehost = parse(config.url).hostname || config.url;
const data = new URL(path, `http://${sitehost}`);
// Exit if input is an external link or a data url
if (data.hostname !== sitehost || data.origin === 'null') return path;
path = encodeURL(config.url + `/${path}`.replace(/\/{2,}/g, '/'));
const prettyUrlsOptions = Object.assign({

@@ -27,7 +22,17 @@ trailing_index: true,

path = prettyUrls(path, prettyUrlsOptions);
// cacheId is designed to works across different hexo.config & options
return cache.apply(`${config.url}-${prettyUrlsOptions.trailing_index}-${prettyUrlsOptions.trailing_html}-${path}`, () => {
const sitehost = parse(config.url).hostname || config.url;
const data = new URL(path, `http://${sitehost}`);
return path;
// Exit if input is an external link or a data url
if (data.hostname !== sitehost || data.origin === 'null') return path;
path = encodeURL(config.url + `/${path}`.replace(/\/{2,}/g, '/'));
path = prettyUrls(path, prettyUrlsOptions);
return path;
});
}
module.exports = fullUrlForHelper;

@@ -6,2 +6,5 @@ 'use strict';

const Cache = require('./cache');
const cache = new Cache();
function md5(str) {

@@ -16,3 +19,5 @@ return createHash('md5').update(str).digest('hex');

let str = `https://www.gravatar.com/avatar/${md5(email.toLowerCase())}`;
const hash = cache.has(email) ? cache.get(email) : md5(email.toLowerCase());
let str = `https://www.gravatar.com/avatar/${hash}`;
const qs = stringify(options);

@@ -22,2 +27,4 @@

cache.set('email', hash);
return str;

@@ -24,0 +31,0 @@ }

@@ -6,2 +6,3 @@ 'use strict';

const regexUrl = /(cite|download|href|src|url)$/i;
const regexMeta = /^(og:|twitter:)(audio|image|url|video)(:secure_url)?$/i;

@@ -13,3 +14,3 @@ function encSrcset(str) {

subStr = subStr.trim();
str = str.replace(subStr, encodeURI(subStr));
str = str.replace(subStr, encodeURL(subStr));
}

@@ -26,6 +27,8 @@ });

for (const i in attrs) {
if (attrs[i] === null || typeof attrs[i] === 'undefined') result += '';
if (attrs[i] == null) result += '';
else {
if (i.match(regexUrl)) result += ` ${escapeHTML(i)}="${encodeURL(attrs[i])}"`;
else if (attrs[i] === true || i === attrs[i]) result += ` ${escapeHTML(i)}`;
if (i.match(regexUrl)
|| (tag === 'meta' && !attrs[i].match(regexMeta) && Object.values(attrs)[0].match(regexMeta))) {
result += ` ${escapeHTML(i)}="${encodeURL(attrs[i])}"`;
} else if (attrs[i] === true || i === attrs[i]) result += ` ${escapeHTML(i)}`;
else if (i.match(/srcset$/i)) result += ` ${escapeHTML(i)}="${encSrcset(attrs[i])}"`;

@@ -43,3 +46,3 @@ else result += ` ${escapeHTML(i)}="${escapeHTML(String(attrs[i]))}"`;

if (text === null || typeof text === 'undefined') result += '>';
if (text == null) result += '>';
else result += `>${text}</${escapeHTML(tag)}>`;

@@ -46,0 +49,0 @@

@@ -5,2 +5,3 @@ 'use strict';

exports.Cache = require('./cache');
exports.CacheStream = require('./cache_stream');

@@ -30,2 +31,3 @@ exports.camelCaseKeys = require('./camel_case_keys');

exports.stripHTML = require('./strip_html');
exports.tocObj = require('./toc_obj');
exports.truncate = require('./truncate');

@@ -32,0 +34,0 @@ exports.unescapeHTML = require('./unescape_html');

@@ -5,2 +5,5 @@ 'use strict';

const Cache = require('./cache');
const cache = new Cache();
/**

@@ -17,25 +20,27 @@ * Check whether the link is external

// handle relative url
const data = new URL(input, `http://${sitehost}`);
return cache.apply(`${input}-${sitehost}-${exclude}`, () => {
// handle relative url
const data = new URL(input, `http://${sitehost}`);
// handle mailto: javascript: vbscript: and so on
if (data.origin === 'null') return false;
// handle mailto: javascript: vbscript: and so on
if (data.origin === 'null') return false;
const host = data.hostname;
const host = data.hostname;
if (exclude) {
exclude = Array.isArray(exclude) ? exclude : [exclude];
if (exclude) {
exclude = Array.isArray(exclude) ? exclude : [exclude];
if (exclude && exclude.length) {
for (const i of exclude) {
if (host === i) return false;
if (exclude && exclude.length) {
for (const i of exclude) {
if (host === i) return false;
}
}
}
}
if (host !== sitehost) return true;
if (host !== sitehost) return true;
return false;
return false;
});
}
module.exports = isExternalLink;

@@ -5,28 +5,33 @@ 'use strict';

const Cache = require('./cache');
const cache = new Cache();
function relativeUrlHelper(from = '', to = '') {
const fromParts = from.split('/');
const toParts = to.split('/');
const length = Math.min(fromParts.length, toParts.length);
let i = 0;
return cache.apply(`${from}-${to}`, () => {
const fromParts = from.split('/');
const toParts = to.split('/');
const length = Math.min(fromParts.length, toParts.length);
let i = 0;
for (; i < length; i++) {
if (fromParts[i] !== toParts[i]) break;
}
for (; i < length; i++) {
if (fromParts[i] !== toParts[i]) break;
}
let out = toParts.slice(i);
let out = toParts.slice(i);
for (let j = fromParts.length - i - 1; j > 0; j--) {
out.unshift('..');
}
for (let j = fromParts.length - i - 1; j > 0; j--) {
out.unshift('..');
}
const outLength = out.length;
const outLength = out.length;
// If the last 2 elements of `out` is empty strings, replace them with `index.html`.
if (outLength > 1 && !out[outLength - 1] && !out[outLength - 2]) {
out = out.slice(0, outLength - 2).concat('index.html');
}
// If the last 2 elements of `out` is empty strings, replace them with `index.html`.
if (outLength > 1 && !out[outLength - 1] && !out[outLength - 2]) {
out = out.slice(0, outLength - 2).concat('index.html');
}
return encodeURL(out.join('/').replace(/\/{2,}/g, '/'));
return encodeURL(out.join('/').replace(/\/{2,}/g, '/'));
});
}
module.exports = relativeUrlHelper;

@@ -16,3 +16,3 @@ 'use strict';

const unescapeHTML = (str) => {
const unescapeHTML = str => {
if (typeof str !== 'string') throw new TypeError('str must be a string!');

@@ -19,0 +19,0 @@

@@ -8,14 +8,8 @@ 'use strict';

const Cache = require('./cache');
const cache = new Cache();
function urlForHelper(path = '/', options) {
const pathRegex = /^(#|\/\/|http(s)?:)/;
if (pathRegex.test(path)) return path;
const { config } = this;
const { root } = config;
const sitehost = parse(config.url).hostname || config.url;
const data = new URL(path, `http://${sitehost}`);
// Exit if input is an external link or a data url
if (data.hostname !== sitehost || data.origin === 'null') return path;
options = Object.assign({

@@ -30,5 +24,3 @@ relative: config.relative_link

// Prepend root path
path = encodeURL((root + path).replace(/\/{2,}/g, '/'));
const { root } = config;
const prettyUrlsOptions = Object.assign({

@@ -39,7 +31,26 @@ trailing_index: true,

path = prettyUrls(path, prettyUrlsOptions);
// cacheId is designed to works across different hexo.config & options
return cache.apply(`${config.url}-${root}-${prettyUrlsOptions.trailing_index}-${prettyUrlsOptions.trailing_html}-${path}`, () => {
const pathRegex = /^(#|\/\/|http(s)?:)/;
if (pathRegex.test(path)) {
return path;
}
return path;
const sitehost = parse(config.url).hostname || config.url;
const data = new URL(path, `http://${sitehost}`);
// Exit if input is an external link or a data url
if (data.hostname !== sitehost || data.origin === 'null') {
return path;
}
// Prepend root path
path = encodeURL((root + path).replace(/\/{2,}/g, '/'));
path = prettyUrls(path, prettyUrlsOptions);
return path;
});
}
module.exports = urlForHelper;
{
"name": "hexo-util",
"version": "1.7.0",
"version": "1.8.0",
"description": "Utilities for Hexo.",

@@ -38,3 +38,3 @@ "main": "lib/index",

"eslint": "^6.0.1",
"eslint-config-hexo": "^3.0.0",
"eslint-config-hexo": "^4.0.0",
"html-entities": "^1.2.1",

@@ -52,2 +52,3 @@ "html-tag-validator": "^1.5.0",

"highlight.js": "^9.13.1",
"htmlparser2": "^4.0.0",
"punycode.js": "^2.1.0",

@@ -54,0 +55,0 @@ "striptags": "^3.1.1"

@@ -15,2 +15,3 @@ # hexo-util

- [Usage](#usage)
- [Cache](#cache)
- [CacheStream](#cachestream)

@@ -39,2 +40,3 @@ - [camelCaseKeys](#camelcasekeysobj-options)

- [wordWrap](#wordwrapstr-options)
- [tocObj](#tocobjstr-options)
- [truncate](#truncatestr-options)

@@ -57,2 +59,43 @@ - [unescapeHTML](#unescapehtmlstr)

### Cache()
A simple plain object cache
``` js
const cache = new Cache();
// set(key, value)
cache.set('foo', 'bar');
// get(key) => value
cache.get('foo');
// 'bar'
// has(key) => Boolean
cache.has('foo');
// true
cache.has('bar');
// false
// apply(key. value)
cache.apply('baz', () => 123);
// 123
cache.apply('baz', () => 456);
// 123
cache.apply('qux', 456);
// 456
cache.apply('qux', '789');
// 456
// del(key)
cache.del('baz');
cache.has('baz');
// false
// flush()
cache.flush();
cache.has('foo');
// false
```
### CacheStream()

@@ -473,2 +516,63 @@

### tocObj(str, [options])
Generate a table of contents in JSON format based on the given html string.
Option | Description | Default
--- | --- | ---
`min_depth` | The minimum level of TOC | 1
`max_depth` | The maximum level of TOC | 6
``` js
const html = [
'<h1 id="title_1">Title 1</h1>',
'<div id="title_1_1"><h2>Title 1.1</h2></div>',
'<h3 id="title_1_1_1">Title 1.1.1</h3>',
'<h2 id="title_1_2">Title 1.2</h2>',
'<h2 id="title_1_3">Title 1.3</h2>',
'<h3 id="title_1_3_1">Title 1.3.1</h3>',
'<h1 id="title_2">Title 2</h1>',
'<h2 id="title_2_1">Title 2.1</h2>'
].join('\n');
tocObj(html);
/*
[
{ text: 'Title 1', id: 'title_1', level: 1 },
{ text: 'Title 1.1', id: 'title_1_1', level: 2 },
{ text: 'Title 1.1.1', id: 'title_1_1_1', level: 3 },
{ text: 'Title 1.2', id: 'title_1_2', level: 2 },
{ text: 'Title 1.3', id: 'title_1_3', level: 2 },
{ text: 'Title 1.3.1', id: 'title_1_3_1', level: 3 },
{ text: 'Title 2', id: 'title_2', level: 1 },
{ text: 'Title 2.1', id: 'title_2_1', level: 2 },
]
*/
tocObj(html, { min_depth: 2 });
/*
[
{ text: 'Title 1.1', id: 'title_1_1', level: 2 },
{ text: 'Title 1.1.1', id: 'title_1_1_1', level: 3 },
{ text: 'Title 1.2', id: 'title_1_2', level: 2 },
{ text: 'Title 1.3', id: 'title_1_3', level: 2 },
{ text: 'Title 1.3.1', id: 'title_1_3_1', level: 3 },
{ text: 'Title 2.1', id: 'title_2_1', level: 2 },
]
*/
tocObj(html, { max_depth: 2 });
/*
[
{ text: 'Title 1', id: 'title_1', level: 1 },
{ text: 'Title 1.1', id: 'title_1_1', level: 2 },
{ text: 'Title 1.2', id: 'title_1_2', level: 2 },
{ text: 'Title 1.3', id: 'title_1_3', level: 2 },
{ text: 'Title 2', id: 'title_2', level: 1 },
{ text: 'Title 2.1', id: 'title_2_1', level: 2 },
]
*/
```
### truncate(str, [options])

@@ -475,0 +579,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc