hexo-util
Advanced tools
Comparing version 1.5.0 to 1.6.0
@@ -32,7 +32,5 @@ 'use strict'; | ||
const keys = Object.keys(obj); | ||
const { length } = keys; | ||
const result = {}; | ||
for (let i = 0; i < length; i++) { | ||
const oldKey = keys[i]; | ||
for (const oldKey of keys) { | ||
const newKey = toCamelCase(oldKey); | ||
@@ -39,0 +37,0 @@ |
'use strict'; | ||
const { URL } = require('url'); | ||
const { parse, URL } = require('url'); | ||
const { toUnicode } = require('./punycode'); | ||
const urlObj = (str) => { | ||
try { | ||
return new URL(str); | ||
} catch (err) { | ||
return str; | ||
} | ||
}; | ||
const safeDecodeURI = (str) => { | ||
@@ -23,4 +15,6 @@ try { | ||
const decodeURL = (str) => { | ||
const parsed = urlObj(str); | ||
if (typeof parsed === 'object') { | ||
if (parse(str).protocol) { | ||
const parsed = new URL(str); | ||
// Exit if input is a data url | ||
if (parsed.origin === 'null') return str; | ||
@@ -27,0 +21,0 @@ |
'use strict'; | ||
const { toUnicode } = require('./punycode'); | ||
const { URL } = require('url'); | ||
const { parse, URL } = require('url'); | ||
const urlObj = (str) => { | ||
try { | ||
return new URL(str); | ||
} catch (err) { | ||
return str; | ||
} | ||
}; | ||
const safeDecodeURI = (str) => { | ||
@@ -23,4 +15,6 @@ try { | ||
const encodeURL = (str) => { | ||
const parsed = urlObj(str); | ||
if (typeof parsed === 'object') { | ||
if (parse(str).protocol) { | ||
const parsed = new URL(str); | ||
// Exit if input is a data url | ||
if (parsed.origin === 'null') return str; | ||
@@ -27,0 +21,0 @@ |
@@ -94,7 +94,7 @@ 'use strict'; | ||
for (let i = 0; i < defaultDiacriticsRemovalap.length; i++) { | ||
const letters = defaultDiacriticsRemovalap[i].letters.split(''); | ||
for (const i of defaultDiacriticsRemovalap) { | ||
const letters = i.letters.split(''); | ||
for (let j = 0; j < letters.length; j++) { | ||
diacriticsMap[letters[j]] = defaultDiacriticsRemovalap[i].base; | ||
for (const letter of letters) { | ||
diacriticsMap[letter] = i.base; | ||
} | ||
@@ -101,0 +101,0 @@ } |
@@ -12,3 +12,4 @@ 'use strict'; | ||
'`': '`', | ||
'/': '/' | ||
'/': '/', | ||
'=': '=' | ||
}; | ||
@@ -22,5 +23,5 @@ | ||
// http://stackoverflow.com/a/12034334 | ||
return str.replace(/[&<>"'`/]/g, a => htmlEntityMap[a]); | ||
return str.replace(/[&<>"'`/=]/g, a => htmlEntityMap[a]); | ||
} | ||
module.exports = escapeHTML; |
'use strict'; | ||
const { URL } = require('url'); | ||
const { parse, URL } = require('url'); | ||
const encodeURL = require('./encode_url'); | ||
const urlObj = (str) => { | ||
try { | ||
return new URL(str); | ||
} catch (err) { | ||
return str; | ||
} | ||
}; | ||
function fullUrlForHelper(path = '/') { | ||
if (path.startsWith('//')) return path; | ||
const { config } = this; | ||
const data = urlObj(path); | ||
const sitehost = parse(config.url).hostname || config.url; | ||
const data = new URL(path, `http://${sitehost}`); | ||
// Exit if this is an external path | ||
if (typeof data === 'object') { | ||
if (data.origin !== 'null') 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, '/')); | ||
const { trailing_index } = Object.assign({ | ||
trailing_index: true | ||
}, config.pretty_url); | ||
if (!trailing_index) path = path.replace(/index\.html$/, ''); | ||
return path; | ||
@@ -26,0 +25,0 @@ } |
'use strict'; | ||
const hljs = require('highlight.js'); | ||
const Entities = require('html-entities').XmlEntities; | ||
const entities = new Entities(); | ||
const alias = require('../highlight_alias.json'); | ||
const escapeHTML = require('./escape_html'); | ||
function highlightUtil(str, options = {}) { | ||
@@ -35,13 +35,2 @@ if (typeof str !== 'string') throw new TypeError('str must be a string!'); | ||
const lines = data.value.split('\n'); | ||
let numbers = ''; | ||
let content = ''; | ||
for (let i = 0, len = lines.length; i < len; i++) { | ||
let line = lines[i]; | ||
if (tab) line = replaceTabs(line, tab); | ||
numbers += `<span class="line">${Number(firstLine) + i}</span><br>`; | ||
content += formatLine(line, Number(firstLine) + i, mark, options); | ||
} | ||
let result = `<figure class="highlight${data.language ? ` ${data.language}` : ''}">`; | ||
@@ -53,10 +42,19 @@ | ||
result += '<table><tr>'; | ||
result += '<table>'; | ||
if (gutter) { | ||
result += `<td class="gutter"><pre>${numbers}</pre></td>`; | ||
const lines = data.value.split('\n'); | ||
for (let i = 0, len = lines.length; i < len; i++) { | ||
let line = lines[i]; | ||
if (tab) line = replaceTabs(line, tab); | ||
let content = formatLine(line, Number(firstLine) + i, mark, options); | ||
result += '<tr>'; | ||
if (gutter) { | ||
result += `<td class="gutter"><pre><span class="line">${Number(firstLine) + i}</span></pre></td>`; | ||
} | ||
result += `<td class="code">${before}${content}${after}</td></tr>`; | ||
} | ||
result += `<td class="code">${before}${content}${after}</td>`; | ||
result += '</tr></table></figure>'; | ||
result += '</table></figure>'; | ||
@@ -76,3 +74,2 @@ return result; | ||
res += '<br>'; | ||
return res; | ||
@@ -82,3 +79,3 @@ } | ||
function encodePlainString(str) { | ||
return entities.encode(str); | ||
return escapeHTML(str); | ||
} | ||
@@ -85,0 +82,0 @@ |
'use strict'; | ||
const { URL } = require('url'); | ||
const { parse, URL } = require('url'); | ||
const urlObj = (str) => { | ||
try { | ||
return new URL(str); | ||
} catch (err) { | ||
return str; | ||
} | ||
}; | ||
/** | ||
* Check whether the link is external | ||
* @param {String} url The url to check | ||
* @param {String} input The url to check | ||
* @returns {Boolean} True if the link doesn't have protocol or link has same host with config.url | ||
*/ | ||
function isExternalLink(url) { | ||
const { config } = this; | ||
const exclude = Array.isArray(config.external_link.exclude) ? config.external_link.exclude | ||
: [config.external_link.exclude]; | ||
const data = urlObj(url); | ||
const host = data.hostname; | ||
const sitehost = typeof urlObj(config.url) === 'object' ? urlObj(config.url).hostname : config.url; | ||
function isExternalLink(input, sitehost, exclude) { | ||
sitehost = parse(sitehost).hostname || sitehost; | ||
if (!sitehost || typeof data === 'string') return false; | ||
if (!sitehost) return false; | ||
// handle relative url | ||
const data = new URL(input, `http://${sitehost}`); | ||
// handle mailto: javascript: vbscript: and so on | ||
if (data.origin === 'null') return false; | ||
if (exclude && exclude.length) { | ||
for (const i of exclude) { | ||
if (host === i) return false; | ||
const host = data.hostname; | ||
if (exclude) { | ||
exclude = Array.isArray(exclude) ? exclude : [exclude]; | ||
if (exclude && exclude.length) { | ||
for (const i of exclude) { | ||
if (host === i) return false; | ||
} | ||
} | ||
@@ -36,0 +32,0 @@ } |
@@ -5,3 +5,3 @@ 'use strict'; | ||
const rParam = /:(\w+)/g; | ||
const rParam = /:(\w*[^_\W])/g; | ||
@@ -8,0 +8,0 @@ function Permalink(rule, options) { |
@@ -18,5 +18,3 @@ 'use strict'; | ||
for (let i = 0, len = words.length; i < len; i++) { | ||
const word = words[i]; | ||
for (const word of words) { | ||
if (resultLength + word.length + omissionLength < length) { | ||
@@ -23,0 +21,0 @@ result += word + separator; |
@@ -10,3 +10,4 @@ 'use strict'; | ||
'`': '`', | ||
'/': '/' | ||
'/': '/', | ||
'=': '=' | ||
}; | ||
@@ -13,0 +14,0 @@ |
'use strict'; | ||
const { URL } = require('url'); | ||
const { parse, URL } = require('url'); | ||
const encodeURL = require('./encode_url'); | ||
const relative_url = require('./relative_url'); | ||
const urlObj = (str) => { | ||
try { | ||
return new URL(str); | ||
} catch (err) { | ||
return str; | ||
} | ||
}; | ||
function urlForHelper(path = '/', options) { | ||
if (path[0] === '#' || path.startsWith('//')) { | ||
return path; | ||
} | ||
if (path.startsWith('#') || path.startsWith('//')) return path; | ||
const { config } = this; | ||
const { root } = config; | ||
const data = urlObj(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; | ||
options = Object.assign({ | ||
@@ -28,7 +22,2 @@ relative: config.relative_link | ||
// Exit if this is an external path | ||
if (typeof data === 'object') { | ||
if (data.origin !== 'null') return path; | ||
} | ||
// Resolve relative url | ||
@@ -42,2 +31,8 @@ if (options.relative) { | ||
const { trailing_index } = Object.assign({ | ||
trailing_index: true | ||
}, config.pretty_url); | ||
if (!trailing_index) path = path.replace(/index\.html$/, ''); | ||
return path; | ||
@@ -44,0 +39,0 @@ } |
{ | ||
"name": "hexo-util", | ||
"version": "1.5.0", | ||
"version": "1.6.0", | ||
"description": "Utilities for Hexo.", | ||
@@ -39,2 +39,3 @@ "main": "lib/index", | ||
"eslint-config-hexo": "^3.0.0", | ||
"html-entities": "^1.2.1", | ||
"html-tag-validator": "^1.5.0", | ||
@@ -50,3 +51,2 @@ "mocha": "^6.0.1", | ||
"highlight.js": "^9.13.1", | ||
"html-entities": "^1.2.1", | ||
"striptags": "^3.1.1" | ||
@@ -53,0 +53,0 @@ }, |
@@ -28,3 +28,3 @@ # hexo-util | ||
- [htmlTag](#htmltagtag-attrs-text-escape) | ||
- [isExternalLink](#isexternallinkurl) | ||
- [isExternalLink](#isexternallinkurl-sitehost-exclude) | ||
- [Pattern](#patternrule) | ||
@@ -217,3 +217,3 @@ - [Permalink](#permalinkrule-options) | ||
`gutter` | Whether to show line numbers | true | ||
`wrap` | Whether to wrap the code block | true | ||
`wrap` | Whether to wrap the code block in [`<table>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table) | true | ||
`firstLine` | First line number | 1 | ||
@@ -225,2 +225,3 @@ `hljs` | Whether to use the `hljs-*` prefix for CSS classes | false | ||
`autoDetect` | Detect language automatically | false | ||
`mark` | Line highlight specific line(s) | | ||
@@ -260,34 +261,35 @@ ### htmlTag(tag, attrs, text, escape) | ||
### isExternalLink(url) | ||
### isExternalLink(url, sitehost, [exclude]) | ||
Returns if a given url is external link relative to `config.url` and `config.exclude`. | ||
Option | Description | Default | ||
--- | --- | --- | ||
`url` | The input URL. | | ||
`sitehost` | The hostname / url of website. You can also pass `hexo.config.url`. | | ||
`exclude` | Exclude hostnames. Specific subdomain is required when applicable, including www. | `[]` | ||
``` yml | ||
_config.yml | ||
url: https://example.com # example | ||
``` | ||
Returns if a given url is external link relative to given `sitehost` and `[exclude]`. | ||
``` js | ||
isExternalLink('https://example.com'); | ||
// 'sitehost' can be a domain or url | ||
isExternalLink('https://example.com', 'example.com'); | ||
// false | ||
isExternalLink('/archives/foo.html'); | ||
isExternalLink('https://example.com', 'https://example.com'); | ||
// false | ||
isExternalLink('https://foo.com/'); | ||
// true | ||
isExternalLink('https://example.com', '//example.com/blog/'); | ||
// false | ||
``` | ||
``` yml | ||
_config.yml | ||
url: https://example.com # example | ||
exclude: | ||
- foo.com | ||
- bar.com | ||
``` js | ||
isExternalLink('/archives/foo.html', 'example.com'); | ||
// false | ||
isExternalLink('https://foo.com/', 'example.com'); | ||
// true | ||
``` | ||
``` js | ||
isExternalLink('https://foo.com'); | ||
isExternalLink('https://foo.com', 'example.com', ['foo.com', 'bar.com']); | ||
// false | ||
isExternalLink('https://bar.com'); | ||
isExternalLink('https://bar.com', 'example.com', ['foo.com', 'bar.com']); | ||
// false | ||
isExternalLink('https://baz.com/'); | ||
isExternalLink('https://baz.com/', 'example.com', ['foo.com', 'bar.com']); | ||
// true | ||
@@ -492,3 +494,2 @@ ``` | ||
- [`relative_url()`](#relative_urlfrom-to) | ||
- [`isExternalLink()`](#isexternallinkurl) | ||
@@ -495,0 +496,0 @@ Below examples demonstrate different approaches to creating a [helper](https://hexo.io/api/helper) (each example is separated by `/******/`), |
72929
5
557
9
1306
- Removedhtml-entities@^1.2.1
- Removedhtml-entities@1.4.0(transitive)