mirror of https://github.com/curbengh/hexo-yam
Compare commits
No commits in common. "master" and "v3.0.0" have entirely different histories.
|
|
@ -1,10 +0,0 @@
|
||||||
version: 2
|
|
||||||
updates:
|
|
||||||
- package-ecosystem: "npm"
|
|
||||||
directory: "/"
|
|
||||||
schedule:
|
|
||||||
interval: "daily"
|
|
||||||
- package-ecosystem: "github-actions"
|
|
||||||
directory: "/"
|
|
||||||
schedule:
|
|
||||||
interval: "daily"
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
name: Linter
|
|
||||||
|
|
||||||
on: [push, pull_request]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
linter:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v5
|
|
||||||
- name: Install Bun
|
|
||||||
uses: oven-sh/setup-bun@v2
|
|
||||||
- name: Cache NPM dependencies
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: node_modules
|
|
||||||
key: ${{ runner.os }}-npm-cache
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-npm-cache
|
|
||||||
- name: Install Dependencies
|
|
||||||
run: bun install
|
|
||||||
- name: Lint
|
|
||||||
run: bun run lint
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
name: Semgrep
|
|
||||||
on:
|
|
||||||
pull_request: {}
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
paths:
|
|
||||||
- .github/workflows/semgrep.yml
|
|
||||||
schedule:
|
|
||||||
# Weekly
|
|
||||||
- cron: "0 0 * * 0"
|
|
||||||
jobs:
|
|
||||||
semgrep:
|
|
||||||
name: Scan
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
env:
|
|
||||||
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
|
|
||||||
container:
|
|
||||||
image: returntocorp/semgrep
|
|
||||||
if: (github.actor != 'dependabot[bot]')
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v5
|
|
||||||
- run: semgrep ci
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
name: Snyk
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
# Weekly
|
|
||||||
- cron: "0 0 * * 0"
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- "dependabot/github_actions/github/codeql-action**"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
security:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v5
|
|
||||||
- name: Install Bun
|
|
||||||
uses: oven-sh/setup-bun@v2
|
|
||||||
- name: Install Dependencies
|
|
||||||
run: bun install
|
|
||||||
- name: Run Snyk to check for vulnerabilities
|
|
||||||
uses: snyk/actions/node@master
|
|
||||||
continue-on-error: true # To make sure that SARIF upload gets called
|
|
||||||
env:
|
|
||||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
|
||||||
with:
|
|
||||||
command: test
|
|
||||||
args: --sarif-file-output=snyk.sarif
|
|
||||||
- name: Upload result to GitHub Code Scanning
|
|
||||||
uses: github/codeql-action/upload-sarif@v3
|
|
||||||
with:
|
|
||||||
sarif_file: snyk.sarif
|
|
||||||
- name: Monitor for vulnerabilities
|
|
||||||
uses: snyk/actions/node@master
|
|
||||||
env:
|
|
||||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
|
||||||
with:
|
|
||||||
command: monitor
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
name: Tester
|
|
||||||
|
|
||||||
on: [push, pull_request]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
tester:
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
||||||
node-version: ["20", "22", "24"]
|
|
||||||
fail-fast: false
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v5
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: ${{ matrix.node-version }}
|
|
||||||
- name: Cache NPM dependencies
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: node_modules
|
|
||||||
key: ${{ runner.os }}-npm-cache
|
|
||||||
restore-keys: ${{ runner.os }}-npm-cache
|
|
||||||
- name: Determine unrs-resolver binary version
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
case "$RUNNER_OS" in
|
|
||||||
"Linux")
|
|
||||||
echo "PLATFORM=linux-x64-gnu" >> "$GITHUB_ENV" ;;
|
|
||||||
"Windows")
|
|
||||||
echo "PLATFORM=win32-x64-msvc" >> "$GITHUB_ENV" ;;
|
|
||||||
"macOS")
|
|
||||||
echo "PLATFORM=darwin-arm64" >> "$GITHUB_ENV" ;;
|
|
||||||
esac
|
|
||||||
- name: Install Dependencies
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
npm install
|
|
||||||
npm install --include=optional --force @mongodb-js/zstd
|
|
||||||
npm install "@unrs/resolver-binding-$PLATFORM"
|
|
||||||
- name: Test
|
|
||||||
run: npm run test
|
|
||||||
env:
|
|
||||||
CI: true
|
|
||||||
- name: Upload coverage report to Codecov
|
|
||||||
if: matrix.os == 'ubuntu-latest' && matrix.node-version == '22'
|
|
||||||
uses: codecov/codecov-action@v5
|
|
||||||
with:
|
|
||||||
fail_ci_if_error: true
|
|
||||||
env:
|
|
||||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
|
||||||
|
|
@ -3,5 +3,3 @@ node_modules/
|
||||||
package-lock.json
|
package-lock.json
|
||||||
tmp/
|
tmp/
|
||||||
*.log
|
*.log
|
||||||
coverage/
|
|
||||||
bun.lockb
|
|
||||||
|
|
|
||||||
6
.snyk
6
.snyk
|
|
@ -2,4 +2,8 @@
|
||||||
version: v1.12.0
|
version: v1.12.0
|
||||||
# ignores vulnerabilities until expiry date; change duration by modifying expiry date
|
# ignores vulnerabilities until expiry date; change duration by modifying expiry date
|
||||||
ignore:
|
ignore:
|
||||||
patch:
|
SNYK-JS-LODASH-450202:
|
||||||
|
- '*':
|
||||||
|
reason: Patch/update unavailable. Introduced through Snyk.
|
||||||
|
expires: '2019-12-31T00:00:00.000Z'
|
||||||
|
patch: {}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
dist: bionic
|
||||||
|
sudo: false
|
||||||
|
|
||||||
|
language: node_js
|
||||||
|
node_js:
|
||||||
|
- "node"
|
||||||
|
|
||||||
|
cache:
|
||||||
|
npm: true
|
||||||
|
|
||||||
|
script:
|
||||||
|
- npm install snyk
|
||||||
|
- snyk auth $SNYK_TOKEN
|
||||||
|
- snyk test # Check node modules for vulnerability
|
||||||
|
- snyk protect # Patch node modules (if available)
|
||||||
|
- snyk monitor # Update dependencies to snyk
|
||||||
|
|
||||||
|
- npm install standard
|
||||||
|
- standard
|
||||||
|
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master # Only build master branch
|
||||||
|
- /^greenkeeper.*$/ # Greenkeeper branches
|
||||||
2
LICENSE
2
LICENSE
|
|
@ -1,6 +1,6 @@
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2018-2024 curbengh, 2016-2018 rozbo
|
Copyright (c) 2018-2019 curbengh, 2016-2018 rozbo
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
|
||||||
320
README.md
320
README.md
|
|
@ -1,307 +1,193 @@
|
||||||
# hexo-yam
|
# hexo-yam
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/hexo-yam)
|
[](https://www.npmjs.com/package/hexo-yam)
|
||||||
[](https://github.com/curbengh/hexo-yam/actions?query=workflow%3ATester)
|
[](https://travis-ci.com/curbengh/hexo-yam)
|
||||||
[](https://codecov.io/gh/curbengh/hexo-yam)
|
[](https://david-dm.org/curbengh/hexo-yam)
|
||||||
[](https://libraries.io/npm/hexo-yam)
|
[](https://snyk.io/test/npm/hexo-yam)
|
||||||
[](https://snyk.io/test/github/curbengh/hexo-yam)
|
[](https://greenkeeper.io/)
|
||||||
|
|
||||||
Yet Another Minifier for Hexo. Minify HTML, JS, CSS, SVG, XML and JSON. Compress static [web assets](https://github.com/curbengh/hexo-yam/blob/ba77db0094a7c07ea9f70f010bfc15541d4105ca/index.js#L64) using gzip, brotli and zstd.
|
Yet Another Minifier for Hexo. Minify and compress HTML, JS, CSS and SVG. XML, JSON and [many more](https://github.com/curbengh/hexo-yam/blob/ba77db0094a7c07ea9f70f010bfc15541d4105ca/index.js#L64) are also compressed. Support gzip and [brotli](https://en.wikipedia.org/wiki/Brotli) [compressions](https://en.wikipedia.org/wiki/HTTP_compression).
|
||||||
|
|
||||||
## Table of contents
|
## Version 3
|
||||||
|
In v3 onwards, this plugin is enabled by default. Most [options](#options) have changed and they are now under `minify:` option.
|
||||||
|
|
||||||
- [Installation](#installation)
|
Example:
|
||||||
- [Options](#options)
|
|
||||||
- [HTML](#html)
|
```
|
||||||
- [CSS](#css)
|
neat_svg:
|
||||||
- [JS](#js)
|
plugins: [{cleanupIDs: false}]
|
||||||
- [SVG](#svg)
|
```
|
||||||
- [XML](#xml)
|
|
||||||
- [JSON](#json)
|
needs to be updated to
|
||||||
- [Gzip](#gzip)
|
|
||||||
- [Brotli](#brotli)
|
```
|
||||||
- [Zstd](#zstd)
|
minify:
|
||||||
- [Globbing](#globbing)
|
svg:
|
||||||
|
plugins: [{cleanupIDs: false}]
|
||||||
|
```
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
``` bash
|
||||||
```bash
|
$ npm install hexo-yam --save
|
||||||
$ npm install --save hexo-yam
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Options
|
## Options
|
||||||
|
|
||||||
```yaml
|
``` yaml
|
||||||
minify:
|
minify:
|
||||||
enable: true
|
enable: true
|
||||||
previewServer: true
|
|
||||||
html:
|
|
||||||
css:
|
|
||||||
js:
|
|
||||||
svg:
|
|
||||||
gzip:
|
|
||||||
brotli:
|
|
||||||
xml:
|
|
||||||
json:
|
|
||||||
```
|
```
|
||||||
|
|
||||||
- **enable** - Enable the plugin. Defaults to `true`.
|
- **enable** - Enable the plugin. Defaults to `true`.
|
||||||
- **previewServer** - Disable the plugin when running `hexo server`. Defaults to `true`.
|
|
||||||
- **html** - See [HTML](#html) section
|
|
||||||
- **css** - See [CSS](#css) section
|
|
||||||
- **js** - See [JS](#js) section
|
|
||||||
- **svg** - See [SVG](#svg) section
|
|
||||||
- **gzip** - See [Gzip](#gzip) section
|
|
||||||
- **brotli** - See [Brotli](#brotli) section
|
|
||||||
- **xml** - See [XML](#xml) section
|
|
||||||
- **json** - See [JSON](#json) section
|
|
||||||
|
|
||||||
## HTML
|
---
|
||||||
|
|
||||||
```yaml
|
``` yaml
|
||||||
minify:
|
minify:
|
||||||
html:
|
html:
|
||||||
enable: true
|
enable: true
|
||||||
exclude:
|
exclude:
|
||||||
```
|
```
|
||||||
|
|
||||||
- **enable** - Enable the plugin. Defaults to `true`.
|
- **enable** - Enable the plugin. Defaults to `true`.
|
||||||
- **priority** - Plugin's priority. Defaults to `10`. Set lower value to set higher priority and vice versa.
|
- **logger** - Verbose output. Defaults to `false`.
|
||||||
- **verbose** - Verbose output. Defaults to `false`.
|
- **exclude** - Exclude files.
|
||||||
- **exclude** - Exclude files. Support [wildcard](http://www.globtester.com/) pattern(s) in a string or array.
|
- Support one-liner, `exclude: [*.min.html, *.note.html]`.
|
||||||
- **globOptions** - See [globbing](#globbing) section.
|
- To exclude a file, double asterisk and the full path must be specified, `**/themes/typing/source/js/source.js`.
|
||||||
|
- `*source.js` also works, but it also excludes `resource.js`.
|
||||||
|
- Test glob pattern on the web using [Globtester](http://www.globtester.com/).
|
||||||
|
- **globOptions** - [micromatch options](https://github.com/micromatch/micromatch#options) to customise how glob patterns match files. Defaults to `{ basename: true }`, unless the pattern has a slash.
|
||||||
|
|
||||||
For more options, see [HTMLMinifier](https://github.com/kangax/html-minifier).
|
For more options, see [HTMLMinifier](https://github.com/kangax/html-minifier).
|
||||||
|
|
||||||
## CSS
|
---
|
||||||
|
|
||||||
```yaml
|
``` yaml
|
||||||
minify:
|
minify:
|
||||||
css:
|
css:
|
||||||
enable: true
|
enable: true
|
||||||
exclude:
|
exclude:
|
||||||
- "*.min.css"
|
- '*.min.css'
|
||||||
```
|
```
|
||||||
|
|
||||||
- **enable** - Enable the plugin. Defaults to `true`.
|
- **enable** - Enable the plugin. Defaults to `true`.
|
||||||
- **priority** - Plugin's priority. Defaults to `10`.
|
- **logger** - Verbose output. Defaults to `false`.
|
||||||
- **verbose** - Verbose output. Defaults to `false`.
|
- **exclude** - Exclude files. Support wildcard pattern.
|
||||||
- **exclude** - Exclude files. Support [wildcard](http://www.globtester.com/) pattern(s) in a string or array.
|
|
||||||
- **level** - Optimization level. Defaults to `2`.
|
- **level** - Optimization level. Defaults to `2`.
|
||||||
- **globOptions** - See [globbing](#globbing) section.
|
- **globOptions** - See [`html:`](#options).
|
||||||
|
|
||||||
For more options, see [clean-css](https://github.com/jakubpawlowicz/clean-css).
|
For more options, see [clean-css](https://github.com/jakubpawlowicz/clean-css).
|
||||||
|
|
||||||
## JS
|
---
|
||||||
|
|
||||||
```yaml
|
``` yaml
|
||||||
minify:
|
minify:
|
||||||
js:
|
js:
|
||||||
enable: true
|
enable: true
|
||||||
exclude:
|
exclude:
|
||||||
- "*.min.js"
|
- '*.min.js'
|
||||||
```
|
```
|
||||||
|
|
||||||
- **enable** - Enable the plugin. Defaults to `true`.
|
- **enable** - Enable the plugin. Defaults to `true`.
|
||||||
- **priority** - Plugin's priority. Defaults to `10`.
|
- **logger** - Verbose output. Defaults to `false`.
|
||||||
- **verbose** - Verbose output. Defaults to `false`.
|
- **exclude** - Exclude files. Support wildcard pattern.
|
||||||
- **exclude** - Exclude files. Support [wildcard](http://www.globtester.com/) pattern(s) in a string or array.
|
|
||||||
- **compress** - Compress options.
|
- **compress** - Compress options.
|
||||||
- **mangle** - Mangle variable names. Defaults to `true`. Pass an object to specify [mangle options](https://github.com/terser-js/terser#mangle-options).
|
- **mangle** - Mangle variable names. Defaults to `true`. Pass an object to specify [mangle options](https://github.com/terser-js/terser#mangle-options).
|
||||||
- **output** - Output options.
|
- **output** - Output options.
|
||||||
- To retain comments, `output: {comments: true}`.
|
- To retain comments, `output: {comments: true}`.
|
||||||
- **globOptions** - See [globbing](#globbing) section.
|
- **globOptions** - See [`html:`](#options).
|
||||||
|
|
||||||
For more options, see [Terser](https://github.com/terser-js/terser).
|
For more options, see [Terser](https://github.com/terser-js/terser).
|
||||||
|
|
||||||
## SVG
|
---
|
||||||
|
|
||||||
```yaml
|
``` yaml
|
||||||
minify:
|
minify:
|
||||||
svg:
|
svg:
|
||||||
enable: true
|
enable: true
|
||||||
include:
|
include:
|
||||||
- "*.svg"
|
- '*.svg'
|
||||||
- "!*.min.svg"
|
- '!*.min.svg'
|
||||||
```
|
```
|
||||||
|
|
||||||
- **enable** - Enable the plugin. Defaults to `true`.
|
- **enable** - Enable the plugin. Defaults to `true`.
|
||||||
- **priority** - Plugin's priority. Defaults to `10`.
|
- **logger** - Verbose output. Defaults to `false`.
|
||||||
- **verbose** - Verbose output. Defaults to `false`.
|
- **include** - Include files. Support wildcard pattern.
|
||||||
- **include** - Include files. Support [wildcard](http://www.globtester.com/) pattern(s) in a string or array.
|
|
||||||
- Exclude `*.min.svg` by default.
|
- Exclude `*.min.svg` by default.
|
||||||
- **plugins** - Plugin options.
|
- **plugins** - Plugin options.
|
||||||
- Examples:
|
- To retain comments, `plugins: [{removeComments: false}]`.
|
||||||
```yaml
|
- **globOptions** - See [`html:`](#options).
|
||||||
plugins:
|
|
||||||
# Retain comments
|
|
||||||
removeComments: false
|
|
||||||
# Do not remove unused ID attributes
|
|
||||||
cleanupIds: false
|
|
||||||
```
|
|
||||||
- For more options, see [svgo](https://github.com/svg/svgo).
|
|
||||||
- **globOptions** - See [globbing](#globbing) section.
|
|
||||||
|
|
||||||
## XML
|
For more options, see [svgo](https://github.com/svg/svgo).
|
||||||
|
|
||||||
Remove whitespaces in xml.
|
---
|
||||||
|
|
||||||
```yaml
|
``` yaml
|
||||||
minify:
|
|
||||||
xml:
|
|
||||||
enable: false
|
|
||||||
include:
|
|
||||||
- "*.xml"
|
|
||||||
- "!*.min.xml"
|
|
||||||
```
|
|
||||||
|
|
||||||
- **enable** - Enable the plugin. Defaults to `false`.
|
|
||||||
- **priority** - Plugin's priority. Defaults to `10`.
|
|
||||||
- **verbose** - Verbose output. Defaults to `false`.
|
|
||||||
- **include** - Include files. Support [wildcard](http://www.globtester.com/) pattern(s) in a string or array.
|
|
||||||
- Exclude `*.min.xml` by default.
|
|
||||||
- **removeComments** - Remove [comments](https://developer.mozilla.org/en-US/docs/Web/XML/XML_introduction) in xml. Defaults to `true`.
|
|
||||||
- **globOptions** - See [globbing](#globbing) section.
|
|
||||||
|
|
||||||
For more options, see [minify-xml](https://github.com/kristian/minify-xml#options).
|
|
||||||
|
|
||||||
## JSON
|
|
||||||
|
|
||||||
Remove whitespaces in json.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
minify:
|
|
||||||
json:
|
|
||||||
enable: false
|
|
||||||
include:
|
|
||||||
- "*.json"
|
|
||||||
- "!*.min.json"
|
|
||||||
```
|
|
||||||
|
|
||||||
- **enable** - Enable the plugin. Defaults to `false`.
|
|
||||||
- **priority** - Plugin's priority. Defaults to `10`.
|
|
||||||
- **verbose** - Verbose output. Defaults to `false`.
|
|
||||||
- **include** - Include files. Support [wildcard](http://www.globtester.com/) pattern(s) in a string or array.
|
|
||||||
- Exclude `*.min.json` by default.
|
|
||||||
- **globOptions** - See [globbing](#globbing) section.
|
|
||||||
|
|
||||||
## Gzip
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
minify:
|
minify:
|
||||||
gzip:
|
gzip:
|
||||||
enable: true
|
enable: true
|
||||||
include:
|
include:
|
||||||
- "*.html"
|
- '*.html'
|
||||||
- "*.css"
|
- '*.css'
|
||||||
- "*.js"
|
- '*.js'
|
||||||
- "*.txt"
|
- '*.txt'
|
||||||
- "*.ttf"
|
- '*.ttf'
|
||||||
- "*.atom"
|
- '*.atom'
|
||||||
- "*.stl"
|
- '*.stl'
|
||||||
- "*.xml"
|
- '*.xml'
|
||||||
- "*.svg"
|
- '*.svg'
|
||||||
- "*.eot"
|
- '*.eot'
|
||||||
- "*.json"
|
- '*.json'
|
||||||
```
|
```
|
||||||
|
|
||||||
- **enable** - Enable the plugin. Defaults to `true`.
|
- **enable** - Enable the plugin. Defaults to `true`.
|
||||||
- **priority** - Plugin's priority. Defaults to `10`.
|
- **logger** - Verbose output. Defaults to `false`.
|
||||||
- **verbose** - Verbose output. Defaults to `false`.
|
- **include** - Include files. Support wildcard pattern.
|
||||||
- **include** - Include files. Support [wildcard](http://www.globtester.com/) pattern(s) in a string or array.
|
|
||||||
- Support one-liner, `include: ['*.html','*.css','*.js']`.
|
- Support one-liner, `include: ['*.html','*.css','*.js']`.
|
||||||
- Must include asterisk and single quotes. `.html` is invalid. `'*.html'` is valid.
|
- Must include asterisk and single quotes. `.html` is invalid. `'*.html'` is valid.
|
||||||
- **globOptions** - See [globbing](#globbing) section.
|
- **globOptions** - See [`html:`](#options).
|
||||||
- **level** - Compression level; lower value may results in faster compression but slightly larger (compressed) file. Range `1-9`. Defaults to `9`, or the value of [`zlib.constants.Z_BEST_COMPRESSION`](https://nodejs.org/docs/latest-v12.x/api/zlib.html#zlib_zlib_constants)
|
|
||||||
|
|
||||||
## Brotli
|
---
|
||||||
|
|
||||||
```yaml
|
``` yaml
|
||||||
minify:
|
minify:
|
||||||
brotli:
|
brotli:
|
||||||
enable: true
|
enable: true
|
||||||
include:
|
include:
|
||||||
- "*.html"
|
- '*.html'
|
||||||
- "*.css"
|
- '*.css'
|
||||||
- "*.js"
|
- '*.js'
|
||||||
- "*.txt"
|
- '*.txt'
|
||||||
- "*.ttf"
|
- '*.ttf'
|
||||||
- "*.atom"
|
- '*.atom'
|
||||||
- "*.stl"
|
- '*.stl'
|
||||||
- "*.xml"
|
- '*.xml'
|
||||||
- "*.svg"
|
- '*.svg'
|
||||||
- "*.eot"
|
- '*.eot'
|
||||||
- "*.json"
|
- '*.json'
|
||||||
```
|
```
|
||||||
|
|
||||||
- **enable** - Enable the plugin. Defaults to `true`.
|
- **enable** - Enable the plugin. Defaults to `true`.
|
||||||
- **priority** - Plugin's priority. Defaults to `10`.
|
- **logger** - Verbose output. Defaults to `false`.
|
||||||
- **verbose** - Verbose output. Defaults to `false`.
|
- **include** - Include files. Support wildcard pattern.
|
||||||
- **include** - Include files. Support [wildcard](http://www.globtester.com/) pattern(s) in a string or array.
|
- **globOptions** - See [`html:`](#options).
|
||||||
- **globOptions** - See [globbing](#globbing) section.
|
|
||||||
- **level** - Compression level. Range `1-11`. Defaults to `11`, or the value of [`zlib.constants.BROTLI_MAX_QUALITY`](https://nodejs.org/docs/latest-v12.x/api/zlib.html#zlib_brotli_constants)
|
|
||||||
|
|
||||||
## Zstd
|
## HTTP Compression
|
||||||
|
While most modern web browsers [support Brotli](https://www.caniuse.com/#feat=brotli), you also need to consider whether the web/app server, hosting platform, reverse proxy or CDN (whichever relevant to you) support it.
|
||||||
|
|
||||||
```yaml
|
As of May 2019, GitHub Pages, GitLab Pages and Netlify *do not* support brotli yet. You can generate `.br` files, but they won't serve those files.
|
||||||
minify:
|
|
||||||
zstd:
|
|
||||||
enable: false
|
|
||||||
include:
|
|
||||||
- "*.html"
|
|
||||||
- "*.css"
|
|
||||||
- "*.js"
|
|
||||||
- "*.txt"
|
|
||||||
- "*.ttf"
|
|
||||||
- "*.atom"
|
|
||||||
- "*.stl"
|
|
||||||
- "*.xml"
|
|
||||||
- "*.svg"
|
|
||||||
- "*.eot"
|
|
||||||
- "*.json"
|
|
||||||
```
|
|
||||||
|
|
||||||
- **enable** - Enable the plugin. Defaults to `false`.
|
Name | Status (May 8, 2019)
|
||||||
- **priority** - Plugin's priority. Defaults to `10`.
|
--- | ---
|
||||||
- **verbose** - Verbose output. Defaults to `false`.
|
GitHub Pages | [In consideration](https://github.community/t5/GitHub-Pages/Support-for-pre-compressed-assets-and-brotli-compression/m-p/22055)
|
||||||
- **include** - Include files. Support [wildcard](http://www.globtester.com/) pattern(s) in a string or array.
|
GitLab Pages | [In progress](https://gitlab.com/gitlab-org/gitlab-pages/merge_requests/120)
|
||||||
- **globOptions** - See [globbing](#globbing) section.
|
Netlify | [In consideration](https://postimg.cc/qgxn0261)
|
||||||
- **level** - Compression level. Range `1-22`. Defaults to `3`, or the value of [`DEFAULT_LEVEL`](https://github.com/mongodb-js/zstd/blob/a3a08c61c9045411c8275e248498dbc583457fb5/src/lib.rs#L9)
|
|
||||||
|
|
||||||
## Globbing
|
If you have access to the web server config, you should disable on-the-fly compression for static files (that are already compressed by this plugin),
|
||||||
|
|
||||||
Use "globOptions" to customise how glob patterns match files. Refer to [micromatch](https://github.com/micromatch/micromatch#options) for available options.
|
- [nginx](https://github.com/google/ngx_brotli): Make sure both filter and static modules are enabled. This way pre-compressed `.br` files will be served while dynamic content can be compressed on-the-fly. Protip: `brotli_types text/plain text/css application/javascript application/json image/svg+xml application/xml+rss;` to prevent compressing media files (which are already compressed anyway).
|
||||||
|
- [Apache](https://httpd.apache.org/docs/2.4/en/mod/mod_brotli.html): See 'Serving pre-compressed content' section of [mod_brotli](https://httpd.apache.org/docs/2.4/en/mod/mod_brotli.html).
|
||||||
- basename is enabled by default, unless the pattern has a slash.
|
- [Caddy](https://caddyserver.com/features): [0.9.4+](https://caddyserver.com/blog/caddy-0_9_4-released) by default support pre-compressed `.gz` `.br` files and on-the-fly gzip compress dynamic files.
|
||||||
- basename is disabled depending on each pattern.
|
- [express](https://github.com/expressjs/express)/[connect](https://github.com/senchalabs/connect): Use [pre-compressed-assets](https://github.com/domadams/pre-compressed-assets). You still can continue to use [compression](https://github.com/expressjs/compression)/[shrink-ray-current](https://github.com/Alorel/shrink-ray) for dynamic files.
|
||||||
- This means the following options would work,
|
|
||||||
|
|
||||||
```yml
|
|
||||||
exclude:
|
|
||||||
- "*foo.html" # basename is enabled
|
|
||||||
- "**/bar/*/*.html" # basename is automatically disabled
|
|
||||||
- "*baz.css" # basename is enabled
|
|
||||||
globOptions:
|
|
||||||
basename: true # default
|
|
||||||
```
|
|
||||||
|
|
||||||
- This behaviour doesn't apply to pattern that starts with `!` (negation).
|
|
||||||
- This limitation only applies to `include:` option used in svg, gzip and brotli.
|
|
||||||
- This means the following options would _not_ work,
|
|
||||||
|
|
||||||
```yml
|
|
||||||
include:
|
|
||||||
- "!foo.svg"
|
|
||||||
- "!**/bar/*/*.svg"
|
|
||||||
globOptions:
|
|
||||||
basename: true
|
|
||||||
```
|
|
||||||
|
|
||||||
- basename will stay disabled, if explicitly disabled in "globOptions".
|
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
All credits go to the following work:
|
All credits go to the following work:
|
||||||
|
|
||||||
- [hexo-neat](https://github.com/rozbo/hexo-neat) by rozbo
|
- [hexo-neat](https://github.com/rozbo/hexo-neat) by rozbo
|
||||||
|
- neat html by [HTMLMinifier](https://github.com/kangax/html-minifier)
|
||||||
|
- neat css by [clean-css](https://github.com/jakubpawlowicz/clean-css)
|
||||||
|
- neat js by [terser](https://github.com/terser-js/terser)
|
||||||
- gzip feature is inspired by [hexo-generator-optimize](https://github.com/JackyRen/hexo-generator-optimize)
|
- gzip feature is inspired by [hexo-generator-optimize](https://github.com/JackyRen/hexo-generator-optimize)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
[install]
|
|
||||||
optional = false
|
|
||||||
|
|
||||||
[install.lockfile]
|
|
||||||
save = false
|
|
||||||
65
index.js
65
index.js
|
|
@ -2,14 +2,12 @@
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
hexo.config.minify = Object.assign({
|
hexo.config.minify = Object.assign({
|
||||||
enable: true,
|
enable: true
|
||||||
previewServer: true
|
|
||||||
}, hexo.config.minify)
|
}, hexo.config.minify)
|
||||||
|
|
||||||
hexo.config.minify.html = Object.assign({
|
hexo.config.minify.html = Object.assign({
|
||||||
enable: true,
|
enable: true,
|
||||||
priority: 10,
|
logger: false,
|
||||||
verbose: false,
|
|
||||||
exclude: [],
|
exclude: [],
|
||||||
collapseBooleanAttributes: true,
|
collapseBooleanAttributes: true,
|
||||||
collapseWhitespace: true,
|
collapseWhitespace: true,
|
||||||
|
|
@ -26,8 +24,7 @@ hexo.config.minify.html = Object.assign({
|
||||||
|
|
||||||
hexo.config.minify.css = Object.assign({
|
hexo.config.minify.css = Object.assign({
|
||||||
enable: true,
|
enable: true,
|
||||||
priority: 10,
|
logger: false,
|
||||||
verbose: false,
|
|
||||||
exclude: ['*.min.css'],
|
exclude: ['*.min.css'],
|
||||||
level: 2,
|
level: 2,
|
||||||
globOptions: { basename: true }
|
globOptions: { basename: true }
|
||||||
|
|
@ -35,8 +32,7 @@ hexo.config.minify.css = Object.assign({
|
||||||
|
|
||||||
hexo.config.minify.js = Object.assign({
|
hexo.config.minify.js = Object.assign({
|
||||||
enable: true,
|
enable: true,
|
||||||
priority: 10,
|
logger: false,
|
||||||
verbose: false,
|
|
||||||
exclude: ['*.min.js'],
|
exclude: ['*.min.js'],
|
||||||
compress: {},
|
compress: {},
|
||||||
mangle: true,
|
mangle: true,
|
||||||
|
|
@ -46,63 +42,32 @@ hexo.config.minify.js = Object.assign({
|
||||||
|
|
||||||
hexo.config.minify.svg = Object.assign({
|
hexo.config.minify.svg = Object.assign({
|
||||||
enable: true,
|
enable: true,
|
||||||
priority: 10,
|
logger: false,
|
||||||
verbose: false,
|
|
||||||
include: ['*.svg', '!*.min.svg'],
|
include: ['*.svg', '!*.min.svg'],
|
||||||
plugins: {},
|
plugins: [],
|
||||||
globOptions: { basename: true }
|
globOptions: { basename: true }
|
||||||
}, hexo.config.minify.svg)
|
}, hexo.config.minify.svg)
|
||||||
|
|
||||||
hexo.config.minify.gzip = Object.assign({
|
hexo.config.minify.gzip = Object.assign({
|
||||||
enable: true,
|
enable: true,
|
||||||
priority: 10,
|
logger: false,
|
||||||
verbose: false,
|
|
||||||
include: ['*.html', '*.css', '*.js', '*.txt', '*.ttf', '*.atom', '*.stl', '*.xml', '*.svg', '*.eot', '*.json'],
|
include: ['*.html', '*.css', '*.js', '*.txt', '*.ttf', '*.atom', '*.stl', '*.xml', '*.svg', '*.eot', '*.json'],
|
||||||
globOptions: { basename: true }
|
globOptions: { basename: true }
|
||||||
}, hexo.config.minify.gzip)
|
}, hexo.config.minify.gzip)
|
||||||
|
|
||||||
hexo.config.minify.brotli = Object.assign({
|
hexo.config.minify.brotli = Object.assign({
|
||||||
enable: true,
|
enable: true,
|
||||||
priority: 10,
|
logger: false,
|
||||||
verbose: false,
|
|
||||||
include: ['*.html', '*.css', '*.js', '*.txt', '*.ttf', '*.atom', '*.stl', '*.xml', '*.svg', '*.eot', '*.json'],
|
include: ['*.html', '*.css', '*.js', '*.txt', '*.ttf', '*.atom', '*.stl', '*.xml', '*.svg', '*.eot', '*.json'],
|
||||||
globOptions: { basename: true }
|
globOptions: { basename: true }
|
||||||
}, hexo.config.minify.brotli)
|
}, hexo.config.minify.brotli)
|
||||||
|
|
||||||
hexo.config.minify.zstd = Object.assign({
|
if (hexo.config.minify.enable === true) {
|
||||||
enable: false,
|
|
||||||
priority: 10,
|
|
||||||
verbose: false,
|
|
||||||
include: ['*.html', '*.css', '*.js', '*.txt', '*.ttf', '*.atom', '*.stl', '*.xml', '*.svg', '*.eot', '*.json'],
|
|
||||||
globOptions: { basename: true }
|
|
||||||
}, hexo.config.minify.zstd)
|
|
||||||
|
|
||||||
hexo.config.minify.xml = Object.assign({
|
|
||||||
enable: false,
|
|
||||||
priority: 10,
|
|
||||||
verbose: false,
|
|
||||||
include: ['*.xml', '!*.min.xml'],
|
|
||||||
removeComments: true,
|
|
||||||
globOptions: { basename: true }
|
|
||||||
}, hexo.config.minify.xml)
|
|
||||||
|
|
||||||
hexo.config.minify.json = Object.assign({
|
|
||||||
enable: false,
|
|
||||||
priority: 10,
|
|
||||||
verbose: false,
|
|
||||||
include: ['*.json', '!*.min.json'],
|
|
||||||
globOptions: { basename: true }
|
|
||||||
}, hexo.config.minify.json)
|
|
||||||
|
|
||||||
if (hexo.config.minify.enable === true && !(hexo.config.minify.previewServer === true && ['s', 'server'].includes(hexo.env.cmd))) {
|
|
||||||
const filter = require('./lib/filter')
|
const filter = require('./lib/filter')
|
||||||
hexo.extend.filter.register('after_render:html', filter.minifyHtml, hexo.config.minify.html.priority)
|
hexo.extend.filter.register('after_render:html', filter.logicHtml)
|
||||||
hexo.extend.filter.register('after_render:css', filter.minifyCss, hexo.config.minify.css.priority)
|
hexo.extend.filter.register('after_render:css', filter.logicCss)
|
||||||
hexo.extend.filter.register('after_render:js', filter.minifyJs, hexo.config.minify.js.priority)
|
hexo.extend.filter.register('after_render:js', filter.logicJs)
|
||||||
hexo.extend.filter.register('after_generate', filter.minifySvg, hexo.config.minify.svg.priority)
|
hexo.extend.filter.register('after_generate', filter.logicSvg)
|
||||||
hexo.extend.filter.register('after_generate', filter.gzipFn, hexo.config.minify.gzip.priority)
|
hexo.extend.filter.register('after_generate', filter.logicGzip)
|
||||||
hexo.extend.filter.register('after_generate', filter.brotliFn, hexo.config.minify.brotli.priority)
|
hexo.extend.filter.register('after_generate', filter.logicBrotli)
|
||||||
hexo.extend.filter.register('after_generate', filter.zstdFn, hexo.config.minify.zstd.priority)
|
|
||||||
hexo.extend.filter.register('after_generate', filter.minifyXml, hexo.config.minify.xml.priority)
|
|
||||||
hexo.extend.filter.register('after_generate', filter.minifyJson, hexo.config.minify.json.priority)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
382
lib/filter.js
382
lib/filter.js
|
|
@ -1,337 +1,247 @@
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const { minify: htmlMinify } = require('html-minifier-terser')
|
const Htmlminifier = require('html-minifier').minify
|
||||||
const CleanCSS = require('clean-css')
|
const CleanCSS = require('clean-css')
|
||||||
const { minify: terserMinify } = require('terser')
|
const Terser = require('terser')
|
||||||
const { optimize: svgOptimize } = require('svgo')
|
const Svgo = require('svgo')
|
||||||
const zlib = require('node:zlib')
|
const zlib = require('zlib')
|
||||||
const { promisify } = require('node:util')
|
const br = require('iltorb')
|
||||||
const gzip = promisify(zlib.gzip)
|
|
||||||
const br = promisify(zlib.brotliCompress)
|
|
||||||
const { minify: compressXml } = require('minify-xml')
|
|
||||||
const micromatch = require('micromatch')
|
const micromatch = require('micromatch')
|
||||||
const { compress: zstd } = require('@mongodb-js/zstd')
|
|
||||||
|
|
||||||
const isMatch = (path = '', patterns = [], options = {}) => {
|
function isMatch (path, patterns, options) {
|
||||||
if (path && patterns) {
|
if (path && patterns && patterns.length) {
|
||||||
if (path.length && patterns.length) {
|
return micromatch.isMatch(path, patterns, options)
|
||||||
if (typeof patterns === 'string') patterns = [patterns]
|
} else {
|
||||||
for (const pattern of patterns) {
|
|
||||||
// disable basename if a pattern includes a slash
|
|
||||||
let { basename } = options
|
|
||||||
// only disable when basename is enabled
|
|
||||||
basename = basename && !pattern.includes('/')
|
|
||||||
if (micromatch.isMatch(path, pattern, { ...options, basename })) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const match = (paths = [], patterns = [], options = {}) => {
|
function logicHtml (str, data) {
|
||||||
let input = paths
|
|
||||||
if (paths && patterns) {
|
|
||||||
if (paths.length && patterns.length) {
|
|
||||||
const output = []
|
|
||||||
if (typeof patterns === 'string') patterns = [patterns]
|
|
||||||
const exclude = patterns.filter((pattern) => pattern.startsWith('!'))
|
|
||||||
const include = patterns.filter((pattern) => !pattern.startsWith('!'))
|
|
||||||
if (exclude.length) input = micromatch(paths, exclude, options)
|
|
||||||
if (include.length) {
|
|
||||||
for (const pattern of include) {
|
|
||||||
let { basename } = options
|
|
||||||
basename = basename && !pattern.includes('/')
|
|
||||||
const tmp = micromatch(input, pattern, { ...options, basename })
|
|
||||||
if (tmp.length) output.push(...tmp)
|
|
||||||
}
|
|
||||||
return [...new Set(output)]
|
|
||||||
}
|
|
||||||
return input
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return paths
|
|
||||||
}
|
|
||||||
|
|
||||||
function logFn (original, minified, path, ext) {
|
|
||||||
const saved = ((original.length - minified.length) / original.length * 100).toFixed(2)
|
|
||||||
const log = this.log || console
|
|
||||||
log.log(`${ext}: ${path} [${saved}% saved]`)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function minifyHtml (str, data) {
|
|
||||||
const hexo = this
|
const hexo = this
|
||||||
const options = hexo.config.minify.html
|
const options = hexo.config.minify.html
|
||||||
if (options.enable === false || !str) return
|
// Return if disabled.
|
||||||
|
if (options.enable === false) return
|
||||||
|
|
||||||
const { path } = data
|
const path = data.path
|
||||||
const { exclude, globOptions, verbose } = options
|
const exclude = options.exclude
|
||||||
|
const globOptions = options.globOptions
|
||||||
|
|
||||||
|
let excludeString = exclude || ''
|
||||||
|
if (Array.isArray(exclude)) excludeString = exclude.join('')
|
||||||
|
if (excludeString.includes('/')) globOptions.basename = false
|
||||||
|
|
||||||
// Return if a path matches exclusion pattern
|
// Return if a path matches exclusion pattern
|
||||||
if (isMatch(path, exclude, globOptions)) return str
|
if (isMatch(path, exclude, globOptions)) return str
|
||||||
|
|
||||||
try {
|
const result = Htmlminifier(str, options)
|
||||||
const result = await htmlMinify(str, options)
|
const saved = ((str.length - result.length) / str.length * 100).toFixed(2)
|
||||||
if (verbose) logFn.call(this, str, result, path, 'html')
|
if (options.logger) {
|
||||||
|
const log = hexo.log || console.log
|
||||||
return result
|
log.log('Minify the html: %s [%s saved]', path, saved + '%')
|
||||||
} catch (err) {
|
|
||||||
throw new Error(`Path: ${path}\n${err}`)
|
|
||||||
}
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
async function minifyCss (str, data) {
|
function logicCss (str, data) {
|
||||||
const hexo = this
|
const hexo = this
|
||||||
const options = hexo.config.minify.css
|
const options = hexo.config.minify.css
|
||||||
if (options.enable === false || !str) return
|
if (options.enable === false) return
|
||||||
|
|
||||||
const { path } = data
|
const path = data.path
|
||||||
const { exclude, globOptions, verbose } = options
|
const exclude = options.exclude
|
||||||
|
const globOptions = options.globOptions
|
||||||
|
|
||||||
|
let excludeString = exclude || ''
|
||||||
|
if (exclude && Array.isArray(exclude)) excludeString = exclude.join('')
|
||||||
|
if (excludeString && excludeString.includes('/')) globOptions.basename = false
|
||||||
|
|
||||||
if (isMatch(path, exclude, globOptions)) return str
|
if (isMatch(path, exclude, globOptions)) return str
|
||||||
|
|
||||||
try {
|
return new Promise((resolve, reject) => {
|
||||||
const { styles } = await new CleanCSS(options).minify(str)
|
new CleanCSS(options).minify(str, (err, result) => {
|
||||||
if (verbose) logFn.call(this, str, styles, path, 'css')
|
if (err) return reject(err)
|
||||||
return styles
|
const saved = ((str.length - result.styles.length) / str.length * 100).toFixed(2)
|
||||||
} catch (err) {
|
resolve(result.styles)
|
||||||
throw new Error(`Path: ${path}\n${err}`)
|
if (options.logger) {
|
||||||
|
const log = hexo.log || console.log
|
||||||
|
log.log('Minify the css: %s [%s saved]', path, saved + '%')
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function minifyJs (str, data) {
|
function logicJs (str, data) {
|
||||||
const hexo = this
|
const hexo = this
|
||||||
const options = hexo.config.minify.js
|
const options = hexo.config.minify.js
|
||||||
if (options.enable === false || !str) return
|
if (options.enable === false) return
|
||||||
|
|
||||||
const { path } = data
|
const path = data.path
|
||||||
const { exclude, globOptions, verbose } = options
|
const exclude = options.exclude
|
||||||
|
const globOptions = options.globOptions
|
||||||
|
|
||||||
|
let excludeString = exclude || ''
|
||||||
|
if (exclude && Array.isArray(exclude)) excludeString = exclude.join('')
|
||||||
|
if (excludeString && excludeString.includes('/')) globOptions.basename = false
|
||||||
|
|
||||||
if (isMatch(path, exclude, globOptions)) return str
|
if (isMatch(path, exclude, globOptions)) return str
|
||||||
|
|
||||||
// Terser doesn't like unsupported options
|
// Terser doesn't like unsupported options
|
||||||
const jsOptions = Object.assign({}, options)
|
const jsOptions = Object.assign({}, options)
|
||||||
delete jsOptions.enable
|
delete jsOptions.enable
|
||||||
delete jsOptions.priority
|
|
||||||
delete jsOptions.verbose
|
|
||||||
// Old option, retained to avoid crash when upgrading to v4
|
|
||||||
delete jsOptions.logger
|
|
||||||
delete jsOptions.exclude
|
delete jsOptions.exclude
|
||||||
|
delete jsOptions.logger
|
||||||
delete jsOptions.globOptions
|
delete jsOptions.globOptions
|
||||||
|
|
||||||
try {
|
const result = Terser.minify(str, jsOptions)
|
||||||
const { code } = await terserMinify(str, jsOptions)
|
const saved = ((str.length - result.code.length) / str.length * 100).toFixed(2)
|
||||||
if (verbose) logFn.call(this, str, code, path, 'js')
|
if (options.logger) {
|
||||||
return code
|
const log = hexo.log || console.log
|
||||||
} catch (err) {
|
log.log('Minify the js: %s [%s saved]', path, saved + '%')
|
||||||
throw new Error(`Path: ${path}\n${err}`)
|
|
||||||
}
|
}
|
||||||
|
return result.code
|
||||||
}
|
}
|
||||||
|
|
||||||
function minifySvg () {
|
function logicSvg () {
|
||||||
const hexo = this
|
const hexo = this
|
||||||
const options = hexo.config.minify.svg
|
const options = hexo.config.minify.svg
|
||||||
|
// Return if disabled.
|
||||||
if (options.enable === false) return
|
if (options.enable === false) return
|
||||||
|
|
||||||
const { route } = hexo
|
const route = hexo.route
|
||||||
const routeList = route.list()
|
const routeList = route.list()
|
||||||
const { globOptions, include, verbose } = options
|
const include = options.include
|
||||||
// const plugins = Array.isArray(options.plugins) ? extendDefaultPlugins(options.plugins) : extendDefaultPlugins([])
|
const globOptions = options.globOptions
|
||||||
const pluginCfg = Object.prototype.toString.call(options.plugins) === '[object Object]' ? { ...options.plugins } : {}
|
|
||||||
const plugins = [{
|
|
||||||
name: 'preset-default',
|
|
||||||
params: {
|
|
||||||
overrides: pluginCfg
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
|
|
||||||
return Promise.all((match(routeList, include, globOptions)).map((path) => {
|
let includeString = include || ''
|
||||||
|
if (include && Array.isArray(include)) includeString = include.join('')
|
||||||
|
if (includeString && includeString.includes('/')) globOptions.basename = false
|
||||||
|
|
||||||
|
return Promise.all((micromatch(routeList, include, globOptions)).map(path => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
// Grab all assets using hexo router
|
||||||
const assetPath = route.get(path)
|
const assetPath = route.get(path)
|
||||||
let assetTxt = ''
|
let assetTxt = ''
|
||||||
|
// Extract the content
|
||||||
assetPath.on('data', (chunk) => (assetTxt += chunk))
|
assetPath.on('data', (chunk) => (assetTxt += chunk))
|
||||||
assetPath.on('end', async () => {
|
assetPath.on('end', () => {
|
||||||
if (assetTxt.length) {
|
if (assetTxt.length) {
|
||||||
try {
|
// Minify using svgo
|
||||||
const { data } = svgOptimize(assetTxt, { ...options, plugins })
|
new Svgo(options).optimize(assetTxt).then((result) => {
|
||||||
if (verbose) logFn.call(this, assetTxt, data, path, 'svg')
|
// Replace the original file with the minified.
|
||||||
resolve(route.set(path, data))
|
route.set(path, result.data)
|
||||||
} catch (err) {
|
// Logging
|
||||||
reject(new Error(`Path: ${path}\n${err}`))
|
const saved = ((assetTxt.length - result.data.length) / assetTxt.length * 100).toFixed(2)
|
||||||
|
if (options.logger) {
|
||||||
|
const log = hexo.log || console.log
|
||||||
|
log.log('Minify the svg: %s [%s saved]', path, saved + '%')
|
||||||
}
|
}
|
||||||
|
resolve(assetTxt)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
resolve()
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
function gzipFn () {
|
function logicGzip () {
|
||||||
const hexo = this
|
const hexo = this
|
||||||
const options = hexo.config.minify.gzip
|
const options = hexo.config.minify.gzip
|
||||||
|
// Return if disabled.
|
||||||
if (options.enable === false) return
|
if (options.enable === false) return
|
||||||
|
|
||||||
const { route } = hexo
|
const route = hexo.route
|
||||||
const routeList = route.list()
|
const routeList = route.list()
|
||||||
const { globOptions, include, verbose } = options
|
const include = options.include
|
||||||
let { level } = options
|
const globOptions = options.globOptions
|
||||||
if (typeof level !== 'number') level = zlib.constants.Z_BEST_COMPRESSION
|
|
||||||
|
|
||||||
return Promise.all((match(routeList, include, globOptions)).map((path) => {
|
let includeString = include || ''
|
||||||
|
if (include && Array.isArray(include)) includeString = include.join('')
|
||||||
|
if (includeString && includeString.includes('/')) globOptions.basename = false
|
||||||
|
|
||||||
|
return Promise.all((micromatch(routeList, include, globOptions)).map(path => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
// Grab all assets using hexo router
|
||||||
const assetPath = route.get(path)
|
const assetPath = route.get(path)
|
||||||
let assetTxt = ''
|
let assetTxt = ''
|
||||||
|
// Extract the content
|
||||||
assetPath.on('data', (chunk) => (assetTxt += chunk))
|
assetPath.on('data', (chunk) => (assetTxt += chunk))
|
||||||
assetPath.on('end', async () => {
|
assetPath.on('end', () => {
|
||||||
if (assetTxt.length) {
|
if (assetTxt.length) {
|
||||||
try {
|
// gzip compress using highest level
|
||||||
const result = await gzip(assetTxt, { level })
|
zlib.gzip(assetTxt, { level: zlib.constants.Z_BEST_COMPRESSION }, (err, Input) => {
|
||||||
if (verbose) logFn.call(this, assetTxt, result, path, 'gzip')
|
if (!err) {
|
||||||
resolve(route.set(path + '.gz', result))
|
// Save the compressed file to .gz
|
||||||
} catch (err) {
|
route.set(path + '.gz', Input)
|
||||||
reject(new Error(`Path: ${path}\n${err}`))
|
// Logging
|
||||||
|
const saved = ((assetTxt.length - Input.toString().length) / assetTxt.length * 100).toFixed(2)
|
||||||
|
if (options.logger) {
|
||||||
|
const log = hexo.log || console.log
|
||||||
|
log.log('Gzip-compressed %s [%s saved]', path, saved + '%')
|
||||||
}
|
}
|
||||||
|
resolve(assetTxt)
|
||||||
|
} else {
|
||||||
|
reject(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
resolve()
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
function brotliFn () {
|
function logicBrotli () {
|
||||||
const hexo = this
|
const hexo = this
|
||||||
const options = hexo.config.minify.brotli
|
const options = hexo.config.minify.brotli
|
||||||
|
// Return if disabled.
|
||||||
if (options.enable === false) return
|
if (options.enable === false) return
|
||||||
|
|
||||||
const { route } = hexo
|
const route = hexo.route
|
||||||
const routeList = route.list()
|
const routeList = route.list()
|
||||||
const { globOptions, include, verbose } = options
|
const include = options.include
|
||||||
let { level } = options
|
const globOptions = options.globOptions
|
||||||
if (typeof level !== 'number') level = zlib.constants.BROTLI_MAX_QUALITY
|
|
||||||
|
|
||||||
return Promise.all((match(routeList, include, globOptions)).map((path) => {
|
let includeString = include || ''
|
||||||
|
if (include && Array.isArray(include)) includeString = include.join('')
|
||||||
|
if (includeString && includeString.includes('/')) globOptions.basename = false
|
||||||
|
|
||||||
|
return Promise.all((micromatch(routeList, include, globOptions)).map(path => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
// Grab all assets using hexo router
|
||||||
const assetPath = route.get(path)
|
const assetPath = route.get(path)
|
||||||
let assetTxt = ''
|
let assetTxt = ''
|
||||||
|
// Extract the content
|
||||||
assetPath.on('data', (chunk) => (assetTxt += chunk))
|
assetPath.on('data', (chunk) => (assetTxt += chunk))
|
||||||
assetPath.on('end', async () => {
|
assetPath.on('end', () => {
|
||||||
if (assetTxt.length) {
|
if (assetTxt.length) {
|
||||||
try {
|
// Input has to be buffer for brotli
|
||||||
const result = await br(assetTxt, { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: level } })
|
|
||||||
if (verbose) logFn.call(this, assetTxt, result, path, 'brotli')
|
|
||||||
resolve(route.set(path + '.br', result))
|
|
||||||
} catch (err) {
|
|
||||||
reject(new Error(`Path: ${path}\n${err}`))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resolve()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
function zstdFn () {
|
|
||||||
const hexo = this
|
|
||||||
const options = hexo.config.minify.zstd
|
|
||||||
if (options.enable === false) return
|
|
||||||
|
|
||||||
const { route } = hexo
|
|
||||||
const routeList = route.list()
|
|
||||||
const { globOptions, include, verbose } = options
|
|
||||||
let { level } = options
|
|
||||||
if (typeof level !== 'number') level = undefined
|
|
||||||
|
|
||||||
return Promise.all((match(routeList, include, globOptions)).map((path) => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const assetPath = route.get(path)
|
|
||||||
let assetTxt = ''
|
|
||||||
assetPath.on('data', (chunk) => (assetTxt += chunk))
|
|
||||||
assetPath.on('end', async () => {
|
|
||||||
if (assetTxt.length) {
|
|
||||||
try {
|
|
||||||
const input = Buffer.from(assetTxt, 'utf-8')
|
const input = Buffer.from(assetTxt, 'utf-8')
|
||||||
const result = await zstd(input, level)
|
// brotli defaults to max compression level
|
||||||
if (verbose) logFn.call(this, assetTxt, result, path, 'zstd')
|
br.compress(input, (err, output) => {
|
||||||
resolve(route.set(path + '.zst', result))
|
if (!err) {
|
||||||
} catch (err) {
|
// Save the compressed file to .br
|
||||||
reject(new Error(`Path: ${path}\n${err}`))
|
route.set(path + '.br', output)
|
||||||
|
// Logging
|
||||||
|
const saved = ((input.length - output.toString().length) / input.length * 100).toFixed(2)
|
||||||
|
if (options.logger) {
|
||||||
|
const log = hexo.log || console.log
|
||||||
|
log.log('Brotli-compressed %s [%s saved]', path, saved + '%')
|
||||||
}
|
}
|
||||||
|
resolve(assetTxt)
|
||||||
|
} else {
|
||||||
|
reject(err)
|
||||||
}
|
}
|
||||||
resolve()
|
|
||||||
})
|
})
|
||||||
})
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
function minifyXml () {
|
|
||||||
const hexo = this
|
|
||||||
const options = hexo.config.minify.xml
|
|
||||||
if (options.enable === false) return
|
|
||||||
|
|
||||||
const { route } = hexo
|
|
||||||
const routeList = route.list()
|
|
||||||
const { globOptions, include, verbose } = options
|
|
||||||
|
|
||||||
return Promise.all((match(routeList, include, globOptions)).map((path) => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const assetPath = route.get(path)
|
|
||||||
let assetTxt = ''
|
|
||||||
assetPath.on('data', (chunk) => (assetTxt += chunk))
|
|
||||||
assetPath.on('end', () => {
|
|
||||||
if (assetTxt.length) {
|
|
||||||
try {
|
|
||||||
const result = compressXml(assetTxt, { ...options })
|
|
||||||
if (verbose) logFn.call(this, assetTxt, result, path, 'xml')
|
|
||||||
resolve(route.set(path, result))
|
|
||||||
} catch (err) {
|
|
||||||
reject(new Error(`Path: ${path}\n${err}`))
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
resolve()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
function minifyJson () {
|
|
||||||
const hexo = this
|
|
||||||
const options = hexo.config.minify.json
|
|
||||||
if (options.enable === false) return
|
|
||||||
|
|
||||||
const { route } = hexo
|
|
||||||
const routeList = route.list()
|
|
||||||
const { globOptions, include, verbose } = options
|
|
||||||
|
|
||||||
return Promise.all((match(routeList, include, globOptions)).map((path) => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const assetPath = route.get(path)
|
|
||||||
let assetTxt = ''
|
|
||||||
assetPath.on('data', (chunk) => (assetTxt += chunk))
|
|
||||||
assetPath.on('end', () => {
|
|
||||||
if (assetTxt.length) {
|
|
||||||
try {
|
|
||||||
const result = JSON.stringify(JSON.parse(assetTxt))
|
|
||||||
if (verbose) logFn.call(this, assetTxt, result, path, 'json')
|
|
||||||
resolve(route.set(path, result))
|
|
||||||
} catch (err) {
|
|
||||||
reject(new Error(`Path: ${path}\n${err}`))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resolve()
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
minifyHtml,
|
logicHtml: logicHtml,
|
||||||
minifyCss,
|
logicCss: logicCss,
|
||||||
minifyJs,
|
logicJs: logicJs,
|
||||||
minifySvg,
|
logicSvg: logicSvg,
|
||||||
gzipFn,
|
logicGzip: logicGzip,
|
||||||
brotliFn,
|
logicBrotli: logicBrotli
|
||||||
zstdFn,
|
|
||||||
minifyXml,
|
|
||||||
minifyJson
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
60
package.json
60
package.json
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "hexo-yam",
|
"name": "hexo-yam",
|
||||||
"description": "Yet Another Minifier. Minify and compress html, js, css, svg, xml and json",
|
"description": "Yet Another Minifier. Minify and compress html, js, css and svg",
|
||||||
"version": "9.0.0",
|
"version": "3.0.0",
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
|
|
@ -11,50 +11,50 @@
|
||||||
"lib/",
|
"lib/",
|
||||||
"index.js"
|
"index.js"
|
||||||
],
|
],
|
||||||
"scripts": {
|
|
||||||
"lint": "standard",
|
|
||||||
"test": "jest"
|
|
||||||
},
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 20.9.0"
|
"node": ">= 8.6.0"
|
||||||
},
|
},
|
||||||
"author": "curben",
|
"author": "curben",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"homepage": "https://github.com/curbengh/hexo-yam",
|
"homepage": "https://github.com/curbengh/hexo-yam",
|
||||||
"repository": {
|
"repository": "curbengh/hexo-yam",
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/curbengh/hexo-yam.git"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"clean-css": "^5.1.2",
|
"clean-css": "^4.2.1",
|
||||||
"html-minifier-terser": "^7.2.0",
|
"html-minifier": "^4.0.0",
|
||||||
|
"iltorb": "^2.4.2",
|
||||||
"micromatch": "^4.0.2",
|
"micromatch": "^4.0.2",
|
||||||
"minify-xml": "^3.2.0",
|
"svgo": "^1.2.2",
|
||||||
"svgo": "^4.0.0",
|
"terser": "^4.0.0"
|
||||||
"terser": "^5.3.0",
|
|
||||||
"@mongodb-js/zstd": "^2.0.1"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"hexo": "^7.1.0",
|
|
||||||
"jest": "^30.0.4",
|
|
||||||
"standard": "^17.0.0"
|
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
"html",
|
||||||
|
"js",
|
||||||
|
"css",
|
||||||
|
"svg",
|
||||||
"minify",
|
"minify",
|
||||||
"compress",
|
"compress",
|
||||||
"gzip",
|
"gzip",
|
||||||
"brotli",
|
"brotli",
|
||||||
"zstd",
|
|
||||||
"hexo-yam",
|
"hexo-yam",
|
||||||
"hexo"
|
"hexo"
|
||||||
],
|
],
|
||||||
"jest": {
|
"greenkeeper": {
|
||||||
"clearMocks": true,
|
"commitMessages": {
|
||||||
"collectCoverage": true,
|
"initialBadge": "docs(readme): Add Greenkeeper badge",
|
||||||
"coverageDirectory": "./coverage/",
|
"initialDependencies": "chore(deps): Update dependencies to enable Greenkeeper",
|
||||||
"testEnvironment": "node",
|
"initialBranches": "chore: Whitelist greenkeeper branches",
|
||||||
"testEnvironmentOptions": {
|
"dependencyUpdate": "chore(deps): Update ${dependency} from ${oldVersion} to ${version}",
|
||||||
"globalsCleanup": "off"
|
"devDependencyUpdate": "chore(deps-dev): Update ${dependency} from ${oldVersion} to ${version}",
|
||||||
|
"dependencyPin": "chore(deps): Pin ${dependency} to ${oldVersion}",
|
||||||
|
"devDependencyPin": "chore(deps-dev): Pin ${dependency} to ${oldVersion}"
|
||||||
|
},
|
||||||
|
"prTitles": {
|
||||||
|
"initialPR": "chore(deps): Update dependencies to enable Greenkeeper",
|
||||||
|
"initialPrBadge": "docs(readme): Add Greenkeeper badge",
|
||||||
|
"initialPrBadgeOnly": "docs(readme): Add Greenkeeper badge",
|
||||||
|
"initialSubgroupPR": "chore(deps): Update dependencies for ${group}",
|
||||||
|
"basicPR": "chore: Update ${dependency} from ${oldVersion} to ${version}",
|
||||||
|
"groupPR": "chore: Update ${dependency} in ${group} from ${oldVersion} to ${version}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,258 +0,0 @@
|
||||||
/* eslint-env jest */
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
const Hexo = require('hexo')
|
|
||||||
const zlib = require('node:zlib')
|
|
||||||
const { promisify } = require('node:util')
|
|
||||||
const brotli = promisify(zlib.brotliCompress)
|
|
||||||
const unbrotli = promisify(zlib.brotliDecompress)
|
|
||||||
|
|
||||||
describe('brotli', () => {
|
|
||||||
const hexo = new Hexo(__dirname)
|
|
||||||
const b = require('../lib/filter').brotliFn.bind(hexo)
|
|
||||||
const path = 'foo.txt'
|
|
||||||
const input = 'Lorem ipsum dolor sit amet consectetur adipiscing elit fusce'
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
hexo.config.minify = {
|
|
||||||
brotli: {
|
|
||||||
enable: true,
|
|
||||||
verbose: false,
|
|
||||||
include: ['*.html', '*.css', '*.js', '*.txt', '*.ttf', '*.atom', '*.stl', '*.xml', '*.svg', '*.eot', '*.json'],
|
|
||||||
globOptions: { basename: true }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
})
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
const routeList = hexo.route.list()
|
|
||||||
routeList.forEach((path) => hexo.route.remove(path))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('default', async () => {
|
|
||||||
await b()
|
|
||||||
|
|
||||||
const output = hexo.route.get(path.concat('.br'))
|
|
||||||
const buf = []
|
|
||||||
output.on('data', (chunk) => (buf.push(chunk)))
|
|
||||||
output.on('end', async () => {
|
|
||||||
const result = Buffer.concat(buf)
|
|
||||||
const expected = await brotli(input)
|
|
||||||
const resultUnbr = await unbrotli(result)
|
|
||||||
const expectedUnbr = await unbrotli(expected)
|
|
||||||
|
|
||||||
expect(result.equals(expected)).toBe(true)
|
|
||||||
expect(resultUnbr.toString()).toBe(input)
|
|
||||||
expect(expectedUnbr.toString()).toBe(input)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('disable', async () => {
|
|
||||||
hexo.config.minify.brotli.enable = false
|
|
||||||
const result = await b()
|
|
||||||
|
|
||||||
expect(result).toBeUndefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('empty file', async () => {
|
|
||||||
hexo.route.set(path, '')
|
|
||||||
|
|
||||||
const routeList = hexo.route.list()
|
|
||||||
expect(routeList).not.toContain(path.concat('.br'))
|
|
||||||
|
|
||||||
const result = await b()
|
|
||||||
expect(result).toBeDefined()
|
|
||||||
expect(result[0]).toBeUndefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('option', async () => {
|
|
||||||
const level = 1
|
|
||||||
hexo.config.minify.brotli.level = level
|
|
||||||
await b()
|
|
||||||
|
|
||||||
const output = hexo.route.get(path.concat('.br'))
|
|
||||||
const buf = []
|
|
||||||
output.on('data', (chunk) => (buf.push(chunk)))
|
|
||||||
output.on('end', async () => {
|
|
||||||
const result = Buffer.concat(buf)
|
|
||||||
const expected = await brotli(input, { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: level } })
|
|
||||||
|
|
||||||
expect(result.equals(expected)).toBe(true)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('option - verbose', async () => {
|
|
||||||
hexo.config.minify.brotli.verbose = true
|
|
||||||
hexo.log.log = jest.fn()
|
|
||||||
await b()
|
|
||||||
|
|
||||||
expect(hexo.log.log.mock.calls[0][0]).toContain(`brotli: ${path}`)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('option - level is string', async () => {
|
|
||||||
const level = 'foo'
|
|
||||||
hexo.config.minify.brotli.level = level
|
|
||||||
await b()
|
|
||||||
|
|
||||||
const output = hexo.route.get(path.concat('.br'))
|
|
||||||
const buf = []
|
|
||||||
output.on('data', (chunk) => (buf.push(chunk)))
|
|
||||||
output.on('end', async () => {
|
|
||||||
const result = Buffer.concat(buf)
|
|
||||||
const expected = await brotli(input, { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: zlib.constants.BROTLI_MAX_QUALITY } })
|
|
||||||
|
|
||||||
expect(result.equals(expected)).toBe(true)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - exclude non-text file by default', async () => {
|
|
||||||
const path = 'foo.jpg'
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
await b()
|
|
||||||
|
|
||||||
const result = hexo.route.get(path.concat('.br'))
|
|
||||||
|
|
||||||
expect(result).toBeUndefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - basename', async () => {
|
|
||||||
hexo.config.minify.brotli.include = 'bar.txt'
|
|
||||||
const path = 'foo/bar.txt'
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
await b()
|
|
||||||
|
|
||||||
const result = hexo.route.get(path.concat('.br'))
|
|
||||||
|
|
||||||
expect(result).toBeDefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - slash in pattern', async () => {
|
|
||||||
hexo.config.minify.brotli.include = '**/lectus/**/*.txt'
|
|
||||||
const path = 'eleifend/lectus/nullam/dapibus/netus.txt'
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
await b()
|
|
||||||
|
|
||||||
const result = hexo.route.get(path.concat('.br'))
|
|
||||||
|
|
||||||
expect(result).toBeDefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - basename + slash + basename enabled', async () => {
|
|
||||||
hexo.route.remove(path)
|
|
||||||
|
|
||||||
const paths = [
|
|
||||||
'lorem/ipsum/dolor.html',
|
|
||||||
'gravida/sociis/erat/ante.css',
|
|
||||||
'aptent/elementum.js',
|
|
||||||
'felis/blandit/cursus.svg'
|
|
||||||
]
|
|
||||||
hexo.config.minify.brotli.include = [
|
|
||||||
'*.html',
|
|
||||||
'**/sociis/**/*.css'
|
|
||||||
]
|
|
||||||
|
|
||||||
paths.forEach((inpath) => {
|
|
||||||
hexo.route.set(inpath, input)
|
|
||||||
})
|
|
||||||
await b()
|
|
||||||
|
|
||||||
const routeList = hexo.route.list()
|
|
||||||
const expected = [
|
|
||||||
'lorem/ipsum/dolor.html.br',
|
|
||||||
'gravida/sociis/erat/ante.css.br'
|
|
||||||
]
|
|
||||||
const notExpected = [
|
|
||||||
'aptent/elementum.js.br',
|
|
||||||
'felis/blandit/cursus.svg.br'
|
|
||||||
]
|
|
||||||
|
|
||||||
expect(routeList).toEqual(expect.arrayContaining(expected))
|
|
||||||
expect(routeList).toEqual(expect.not.arrayContaining(notExpected))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - basename + slash + basename disabled', async () => {
|
|
||||||
hexo.route.remove(path)
|
|
||||||
|
|
||||||
const paths = [
|
|
||||||
'lorem/ipsum/dolor.html',
|
|
||||||
'gravida/sociis/erat/ante.css',
|
|
||||||
'aptent/elementum.js',
|
|
||||||
'felis/blandit/cursus.svg'
|
|
||||||
]
|
|
||||||
hexo.config.minify.brotli.include = [
|
|
||||||
'*.html',
|
|
||||||
'**/sociis/**/*.css'
|
|
||||||
]
|
|
||||||
hexo.config.minify.brotli.globOptions = {
|
|
||||||
basename: false
|
|
||||||
}
|
|
||||||
|
|
||||||
paths.forEach((inpath) => {
|
|
||||||
hexo.route.set(inpath, input)
|
|
||||||
})
|
|
||||||
await b()
|
|
||||||
|
|
||||||
const routeList = hexo.route.list()
|
|
||||||
const expected = [
|
|
||||||
'gravida/sociis/erat/ante.css.br'
|
|
||||||
]
|
|
||||||
const notExpected = [
|
|
||||||
'lorem/ipsum/dolor.html.br',
|
|
||||||
'aptent/elementum.js.br',
|
|
||||||
'felis/blandit/cursus.svg.br'
|
|
||||||
]
|
|
||||||
|
|
||||||
expect(routeList).toEqual(expect.arrayContaining(expected))
|
|
||||||
expect(routeList).toEqual(expect.not.arrayContaining(notExpected))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - reverse pattern + basename disabled', async () => {
|
|
||||||
hexo.route.remove(path)
|
|
||||||
|
|
||||||
const paths = [
|
|
||||||
'lorem/ipsum/dolor.html',
|
|
||||||
'gravida/sociis/erat/ante.css',
|
|
||||||
'aptent/elementum.js',
|
|
||||||
'felis/blandit/cursus.svg'
|
|
||||||
]
|
|
||||||
hexo.config.minify.brotli.include = [
|
|
||||||
'!dolor.html'
|
|
||||||
]
|
|
||||||
hexo.config.minify.brotli.globOptions = {
|
|
||||||
basename: false
|
|
||||||
}
|
|
||||||
|
|
||||||
paths.forEach((inpath) => {
|
|
||||||
hexo.route.set(inpath, input)
|
|
||||||
})
|
|
||||||
await b()
|
|
||||||
|
|
||||||
const routeList = hexo.route.list()
|
|
||||||
const expected = paths.map((path) => path.concat('.br'))
|
|
||||||
|
|
||||||
expect(routeList).toEqual(expect.arrayContaining(expected))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('blns', async () => {
|
|
||||||
const blns = require('./fixtures/blns.json')
|
|
||||||
|
|
||||||
for (const nStr of blns) {
|
|
||||||
hexo.route.remove(path)
|
|
||||||
|
|
||||||
hexo.route.set(path, nStr)
|
|
||||||
|
|
||||||
await b()
|
|
||||||
|
|
||||||
const output = hexo.route.get(path.concat('.br'))
|
|
||||||
const buf = []
|
|
||||||
output.on('data', (chunk) => (buf.push(chunk)))
|
|
||||||
output.on('end', async () => {
|
|
||||||
const result = Buffer.concat(buf)
|
|
||||||
const resultUnbr = await unbrotli(result)
|
|
||||||
|
|
||||||
expect(resultUnbr.toString()).toBe(nStr)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
107
test/css.test.js
107
test/css.test.js
|
|
@ -1,107 +0,0 @@
|
||||||
/* eslint-env jest */
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
const Hexo = require('hexo')
|
|
||||||
const CleanCSS = require('clean-css')
|
|
||||||
|
|
||||||
describe('css', () => {
|
|
||||||
const hexo = new Hexo(__dirname)
|
|
||||||
const c = require('../lib/filter').minifyCss.bind(hexo)
|
|
||||||
const input = 'foo { bar: baz; } foo { aaa: bbb; }'
|
|
||||||
const path = 'foo.css'
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
hexo.config.minify = {
|
|
||||||
css: {
|
|
||||||
enable: true,
|
|
||||||
verbose: false,
|
|
||||||
exclude: ['*.min.css'],
|
|
||||||
level: 2,
|
|
||||||
globOptions: { basename: true }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
test('default', async () => {
|
|
||||||
const result = await c(input, { path })
|
|
||||||
const { styles } = await new CleanCSS(hexo.config.minify.css).minify(input)
|
|
||||||
|
|
||||||
expect(result).toBe(styles)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('disable', async () => {
|
|
||||||
hexo.config.minify.css.enable = false
|
|
||||||
const result = await c(input, { path })
|
|
||||||
|
|
||||||
expect(result).toBeUndefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('empty file', async () => {
|
|
||||||
const result = await c('', { path })
|
|
||||||
|
|
||||||
expect(result).toBeUndefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('option', async () => {
|
|
||||||
const customOpt = {
|
|
||||||
level: {
|
|
||||||
1: {
|
|
||||||
mergeAdjacentRules: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hexo.config.minify.css = customOpt
|
|
||||||
|
|
||||||
const result = await c(input, { path })
|
|
||||||
const { styles } = await new CleanCSS(customOpt).minify(input)
|
|
||||||
|
|
||||||
expect(result).toBe(styles)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('option - verbose', async () => {
|
|
||||||
hexo.config.minify.css.verbose = true
|
|
||||||
hexo.log.log = jest.fn()
|
|
||||||
await c(input, { path })
|
|
||||||
|
|
||||||
expect(hexo.log.log.mock.calls[0][0]).toContain(`css: ${path}`)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('option - invalid', async () => {
|
|
||||||
const customOpt = {
|
|
||||||
level: 9000
|
|
||||||
}
|
|
||||||
hexo.config.minify.css = customOpt
|
|
||||||
|
|
||||||
let expected
|
|
||||||
try {
|
|
||||||
await new CleanCSS(customOpt).minify(input)
|
|
||||||
} catch (err) {
|
|
||||||
expected = err
|
|
||||||
}
|
|
||||||
|
|
||||||
expect(expected).toBeDefined()
|
|
||||||
await expect(c(input, { path })).rejects.toThrow(`Path: ${path}\n${expected}`)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('exclude - *.min.css', async () => {
|
|
||||||
const result = await c(input, { path: 'foo/bar.min.css' })
|
|
||||||
|
|
||||||
expect(result).toBe(input)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('exclude - basename', async () => {
|
|
||||||
const exclude = '*baz.css'
|
|
||||||
hexo.config.minify.css.exclude = exclude
|
|
||||||
const result = await c(input, { path: 'foo/barbaz.css' })
|
|
||||||
|
|
||||||
expect(result).toBe(input)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('exclude - slash in pattern', async () => {
|
|
||||||
const exclude = '**/lectus/**/*.css'
|
|
||||||
hexo.config.minify.css.exclude = exclude
|
|
||||||
const result = await c(input, { path: 'eleifend/lectus/nullam/dapibus/netus.css' })
|
|
||||||
|
|
||||||
expect(result).toBe(input)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
@ -1,516 +0,0 @@
|
||||||
[
|
|
||||||
"undefined",
|
|
||||||
"undef",
|
|
||||||
"null",
|
|
||||||
"NULL",
|
|
||||||
"(null)",
|
|
||||||
"nil",
|
|
||||||
"NIL",
|
|
||||||
"true",
|
|
||||||
"false",
|
|
||||||
"True",
|
|
||||||
"False",
|
|
||||||
"TRUE",
|
|
||||||
"FALSE",
|
|
||||||
"None",
|
|
||||||
"hasOwnProperty",
|
|
||||||
"then",
|
|
||||||
"\\",
|
|
||||||
"\\\\",
|
|
||||||
"0",
|
|
||||||
"1",
|
|
||||||
"1.00",
|
|
||||||
"$1.00",
|
|
||||||
"1/2",
|
|
||||||
"1E2",
|
|
||||||
"1E02",
|
|
||||||
"1E+02",
|
|
||||||
"-1",
|
|
||||||
"-1.00",
|
|
||||||
"-$1.00",
|
|
||||||
"-1/2",
|
|
||||||
"-1E2",
|
|
||||||
"-1E02",
|
|
||||||
"-1E+02",
|
|
||||||
"1/0",
|
|
||||||
"0/0",
|
|
||||||
"-2147483648/-1",
|
|
||||||
"-9223372036854775808/-1",
|
|
||||||
"-0",
|
|
||||||
"-0.0",
|
|
||||||
"+0",
|
|
||||||
"+0.0",
|
|
||||||
"0.00",
|
|
||||||
"0..0",
|
|
||||||
".",
|
|
||||||
"0.0.0",
|
|
||||||
"0,00",
|
|
||||||
"0,,0",
|
|
||||||
",",
|
|
||||||
"0,0,0",
|
|
||||||
"0.0/0",
|
|
||||||
"1.0/0.0",
|
|
||||||
"0.0/0.0",
|
|
||||||
"1,0/0,0",
|
|
||||||
"0,0/0,0",
|
|
||||||
"--1",
|
|
||||||
"-",
|
|
||||||
"-.",
|
|
||||||
"-,",
|
|
||||||
"999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999",
|
|
||||||
"NaN",
|
|
||||||
"Infinity",
|
|
||||||
"-Infinity",
|
|
||||||
"INF",
|
|
||||||
"1#INF",
|
|
||||||
"-1#IND",
|
|
||||||
"1#QNAN",
|
|
||||||
"1#SNAN",
|
|
||||||
"1#IND",
|
|
||||||
"0x0",
|
|
||||||
"0xffffffff",
|
|
||||||
"0xffffffffffffffff",
|
|
||||||
"0xabad1dea",
|
|
||||||
"123456789012345678901234567890123456789",
|
|
||||||
"1,000.00",
|
|
||||||
"1 000.00",
|
|
||||||
"1'000.00",
|
|
||||||
"1,000,000.00",
|
|
||||||
"1 000 000.00",
|
|
||||||
"1'000'000.00",
|
|
||||||
"1.000,00",
|
|
||||||
"1 000,00",
|
|
||||||
"1'000,00",
|
|
||||||
"1.000.000,00",
|
|
||||||
"1 000 000,00",
|
|
||||||
"1'000'000,00",
|
|
||||||
"01000",
|
|
||||||
"08",
|
|
||||||
"09",
|
|
||||||
"2.2250738585072011e-308",
|
|
||||||
",./;'[]\\-=",
|
|
||||||
"<>?:\"{}|_+",
|
|
||||||
"!@#$%^&*()`~",
|
|
||||||
"\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f",
|
|
||||||
"ᅡタᅡチᅡツᅡテᅡトᅡニᅡヌᅡネᅡノᅡハᅡヒᅡフᅡヘᅡホᅡマᅡミᅡムᅡメᅡモᅡヤᅡユᅡヨᅡラᅡリᅡルᅡレᅡロᅡワᅡンᅡ゙ᅡ゚",
|
|
||||||
"\t\u000b\f ᅡナ £レタ¬タツ¬タテ¬タツ¬タテ¬タト¬タナ¬タニ¬タヌ¬タネ¬タノ¬タハ¬タヒ¬タᄄ¬タᄅ¬タᆵ¬チ゚ ̄タタ",
|
|
||||||
"ᅡᆳタチツテトナワᅴンᅵマ£ᅠホ¬タヒ¬タフ¬タヘ¬タホ¬タマ¬タᆰ¬タᆱ¬タᆲ¬タᆳ¬タᆴ¬チᅠ¬チᄀ¬チᄁ¬チᆪ¬チᄂ¬チᆭ¬チᄃ¬チᄄ¬チᄅ¬チᆰ¬チᆱ¬チᆲ¬チᆳ¬チᆴ¬チᆵᄏᄍᄎᄏムツᄑロᄇᅠロᄇᄀロᄇᄁロᄇᆪンナᄈンナᄡンナᄉンナᄊンナᄋンナᄌンナᄍンナᄎᅠタチᅠタᅠᅠタᄀᅠタᄁᅠタᆪᅠタᄂᅠタᆬᅠタᆭᅠタᄃᅠタᄄᅠタᄅᅠタᆰᅠタᆱᅠタᆲᅠタᆳᅠタᆴᅠタᆵᅠタᄚᅠタᄆᅠタᄇᅠタᄈᅠタᄡᅠタᄉᅠタᄊᅠタᄋᅠタᄌᅠタᄍᅠタᄎᅠタᄏᅠタᄐᅠタᄑᅠタᄒᅠタᅠチタᅠチチᅠチツᅠチテᅠチトᅠチナᅠチニᅠチヌᅠチネᅠチノᅠチハᅠチヒᅠチフᅠチヘᅠチホᅠチマᅠチミᅠチムᅠチメᅠチモᅠチヤᅠチユᅠチヨᅠチラᅠチリᅠチルᅠチレᅠチロᅠチワᅠチンᅠヂᅠチ゚ᅠチᅠᅠチᄀᅠチᄁᅠチᆪᅠチᄂᅠチᆬᅠチᆭᅠチᄃᅠチᄄᅠチᄅᅠチᆰᅠチᆱᅠチᆲᅠチᆳᅠチᆴᅠチᆵᅠチᄚᅠチᄆᅠチᄇᅠチᄈᅠチᄡᅠチᄉᅠチᄊᅠチᄋᅠチᄌᅠチᄍᅠチᄎᅠチᄏᅠチᄐᅠチᄑᅠチᄒᅠチ",
|
|
||||||
"ᄏ",
|
|
||||||
"ᄒ",
|
|
||||||
"ᅫᄅ¬ノネᅢᄃ¬ネレ¬ネᆱᅨワᅡᄉ¬ノᄂ¬ノᆬᅢᄋ",
|
|
||||||
"ᅢᆬᅢ゚¬ネツᅥメᅡ례ル¬ネニᅨレᅡᆲ¬タᆭᅢᆭ",
|
|
||||||
"ᅤモ¬ネムᅡᄡᅡᆴ¬タᅠᅡᆬᅡ뗴ニᅢ죄タ¬タワ¬タリ",
|
|
||||||
"ᅡᄀ¬ト깏ᅡᄁ¬ネ゙ᅡ다ᄊ¬タ깕ᅡᄎ¬タモ¬ノᅠ",
|
|
||||||
"ᅡ졔ロᅢヌ¬ラハᅣ몌ワᅢツᅡᆵᅨリᅡ",
|
|
||||||
"ᅢナᅢヘᅢホᅢマᅨンᅢモᅢヤᆪᅢメᅢレᅢニ¬リテ",
|
|
||||||
"ᅤメ¬ダᅡᄡ¬タᄚᅨヌᅢチᅡ뗴ニᅢリ¬ネマ¬タン¬タル",
|
|
||||||
"`¬チト¬ツᆲ¬タᄍ¬タᄎᆲチᆲツ¬タ가ᄚᅡᄋ¬タレ¬タヤᅡᄆ",
|
|
||||||
"¬ナロ¬ナワ¬ナン¬ナ゙",
|
|
||||||
"チツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚ᅠᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑᄒタチツテトナニヌネノハヒフヘホマ",
|
|
||||||
"ᅠᄀᄁᆪᄂᆬᆭᄃᄄᄅ",
|
|
||||||
"¬チᄚ¬チᄡ¬チᄉ",
|
|
||||||
"¬ツタ¬ツチ¬ツツ",
|
|
||||||
"¬チᄚ¬チᄡ¬チᄉ¬ツタ¬ツチ¬ツツ",
|
|
||||||
"¢ᄌヤ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ ¢ᄌヤ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ ¢ᄌヤ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍノ¢ᄍヌ¢ᄍヌ¢ᄍヌ¢ᄍヌ",
|
|
||||||
"'",
|
|
||||||
"\"",
|
|
||||||
"''",
|
|
||||||
"\"\"",
|
|
||||||
"'\"'",
|
|
||||||
"\"''''\"'\"",
|
|
||||||
"\"'\"'\"''''\"",
|
|
||||||
"<foo val=¬タワbar¬タン />",
|
|
||||||
"<foo val=¬タワbar¬タン />",
|
|
||||||
"<foo val=¬タンbar¬タワ />",
|
|
||||||
"<foo val=`bar' />",
|
|
||||||
"ヤᄚ¦ᄌᆳ ̄チユ ̄ツモ ̄チᆱ ̄チツ ̄チメ ̄チᆭ¦ᄌヒ ̄チユ ̄チト",
|
|
||||||
" ̄テム ̄テᄐ ̄テニ ̄ツᆪ ̄テᄐ ̄チᄌ│ᄀフ ̄チヒ ̄チᆰ ̄チト ̄チヒ",
|
|
||||||
"¥メフ│ᆪᄑ₩ᄐᄁ│ᆰ゙",
|
|
||||||
"←テᄄ│ミᄑ₩ᅠᄐ",
|
|
||||||
"↓ツᆲ■レフ↑ᄈᄐ■ユル↓ロミ ↓ヨᄡ■ユル↓ラᄚ↑ᄉᆲ↓ニフ",
|
|
||||||
"↓ᄚᆭ↓ᄚᄄ→ᆬᄐ ■テタ↑ᄈᅠ ↓リᄄ ■ホᄇ↓ヒワ→ᄃᄄ↑ᄈᄐ ↓ムロ→ヒᄂ→ᆭᆲ →リᅠ→ᄚᄅ↑ᄚチ■ユリ",
|
|
||||||
"ᄂᄒ₩ワテᄃム¥ᆳᄌ←ルᄁ│ᆰ゙¥ᆳᄌᅠヤᄅᄊ₩ノタ",
|
|
||||||
"↓レᄌ→゙タ→ᄚヤ■ニᅠ→ᆬᄡ",
|
|
||||||
"ᅠワホᅠワᄆᅠンᄍᅠᄆモᅠᄆᄌᅠᄇヨᅠᄈマ",
|
|
||||||
"ミミワ ミミヤミミヌミミンミミタミミᄀミミヌミミモ ミミルミミハミミᄀミミンミミモ/ミミンミミヌミミラミミハミミᄂミミヤ ミミメミミヒミミラ ミミメミミフ ミミワ ミミᄀミミタミミヨミミヌミミᄂミミモミミン ミミᄆミムツ ミムト ミミヤミミヌミミンミミタミミᄀミミヌミミモ ミミマミミニミミナミミᄂミミニミミレミミハミミᄀミミンミミニミミモミミニ",
|
|
||||||
"│ᄀᄄ ̄テン ̄チツA←ᄋラᅤメᅢᄅᄐᄁ←タヘᅢワᅢ゚ᅡᆰᅣナᅢᄆ¦ᄌツ ̄ミタᅠタタ",
|
|
||||||
"ᄎ",
|
|
||||||
"ᄒ",
|
|
||||||
" ̄テᄑ¢ᄐᄐ¢ᄎネトᅪワ¢ᄎネ¢ᄐᄑᄒノ  ̄テᄑ¢ᄐᄐ¢ᄎネトᅪワ¢ᄎネ¢ᄐᄑᄒノ",
|
|
||||||
"(ᄑᄀ¬ラユ ¬ネタ ¬ラユᄑᄀ)",
|
|
||||||
"ᄑタᄑᄄ(ᅡᄡ¬ネタᄑタ¬ネᄅ",
|
|
||||||
"__ᄒロ(,_,*)",
|
|
||||||
" ̄テᄏ(ᆪ¬ネタᆪ) ̄テᄏ:*:",
|
|
||||||
"ᄒ゚ᄑᆬ¬ワ ̄テᄒ¬ユᄇ(ᄑᄀ¬ラユ¬タ¬ラユᄑᄀ)¬ユᄆ¬ワᄑᆬᄒ゚",
|
|
||||||
", ̄タツ ̄テᄏ:*: ̄テᄏ ̄ツワ¬タル( ¬リᄏ ᅬノ ¬リᄏ ) ̄タツ ̄テᄏ:*: ̄テᄏ ̄ツワ¬タル",
|
|
||||||
"(¬ユᆵᅡᄚ¬ヨ가ᄚᄐノ¬ユᆵᄌᄉ ¬ヤᄏ¬ヤチ¬ヤᄏ)",
|
|
||||||
"(ᄒノ¢ᄇᆬロハ¢ᄇᆬᄐノᄒノᄏ ¬ヤᄏ¬ヤチ¬ヤᄏ",
|
|
||||||
"¬ヤᆲ¬ヤタ¬ヤᆲ ̄テホ( ᅡᄎ _ ᅡᄎ ̄テホ)",
|
|
||||||
"( ᅪ가ᄚ ᅪワᅧヨ ᅪ가ᄚ)",
|
|
||||||
"ᅡᆵ\\_( ̄テト)_/ᅡᆵ",
|
|
||||||
"゚リヘ",
|
|
||||||
"゚ムᄅ゚マᄑ",
|
|
||||||
"゚ムᄄ¬タペᆭᄚ ゚ムᄄ゚マ¬タペᆭᄚ ゚ムᄄ¬タペᆭᄆ ゚ムᄄ゚マ¬タペᆭᄆ ゚ᆭᄍ゚マ¬タヘ¬ルツᄌマ",
|
|
||||||
"゚ムᄒ ゚ルヌ ゚メチ ゚ルナ ゚ルニ ゚ルヒ ゚ルホ ゚ルヘ",
|
|
||||||
"゚ミᄉ ゚ルネ ゚ルノ ゚ルハ",
|
|
||||||
"¬ンᄂᄌマ ゚メヤ ゚メフ ゚メユ ゚メ゙ ゚メモ ゚メラ ゚メヨ ゚メリ ゚メン ゚メ゚ ゚メワ ゚メロ ゚メレ ゚メル",
|
|
||||||
"¬ワピマ ゚メᆰ゚マ ゚ムミ゚マ ゚ルプマ ゚ムマ゚マ ゚ルマ゚マ",
|
|
||||||
"゚ムᄄ¬タペムᄅ¬タペムᆭ ゚ムᄄ¬タペムᄅ¬タペムᄃ¬タペムᆭ ゚ムᄄ¬タペムᄄ¬タペムᆭ ゚ムᄅ¬タペムᄅ¬タペムᄃ ゚ムᄄ¬タペムᆭ ゚ムᄄ¬タペムᄃ¬タペムᆭ ゚ムᄅ¬タペムᆭ ゚ムᄅ¬タペムᄃ¬タペムᆭ",
|
|
||||||
"゚レᄒ ゚ニメ ゚ニモ ゚ニユ ゚ニヨ ゚ニラ ゚ニル ゚マᄃ",
|
|
||||||
"0ᄌマ¬テᆪ 1ᄌマ¬テᆪ 2ᄌマ¬テᆪ 3ᄌマ¬テᆪ 4ᄌマ¬テᆪ 5ᄌマ¬テᆪ 6ᄌマ¬テᆪ 7ᄌマ¬テᆪ 8ᄌマ¬テᆪ 9ᄌマ¬テᆪ ゚ヤ゚",
|
|
||||||
"゚ヌᄎ゚ヌᄌ゚ヌᄋ゚ヌᄎ゚ヌᄌ ゚ヌᆭ゚ヌᆱ゚ヌᆭ゚ヌᄇ゚ヌᄌ",
|
|
||||||
"゚ヌᄎ゚ヌᄌ゚ヌᄋ゚ヌᄎ゚ヌᄌ゚ヌᆭ゚ヌᆱ゚ヌᆭ゚ヌᄇ",
|
|
||||||
"゚ヌᄎ゚ヌᄌ゚ヌᄋ゚ヌᄎ゚ヌᄌ゚ヌᆭ",
|
|
||||||
"ᄐムᄐメᄐモ",
|
|
||||||
"ᄀᄁᆪ",
|
|
||||||
"ᆱナ ニチᄈ ᄈツᄋᆰ ネᄄᄃトᆰᆳᆵハᆵフ, ᆲᄇハᄆᆰハ ᄄᄃᄈᆰᆴᆵᄃナ ᆪニ ᆵニネ. ᆬᄚ ヌニᄃ゚ ᄃトᄈᆰᄃᄆ ネᆰニᄉハᄄ テᄃニ. ᆪヌムト ᄃハᄋᄃトハᄃフ ᄄᄆハᄋᄃニハᄃ-チᄆニᄈᄃ ツᆵ ᆪᆴᄚ. ᄈトハナᄃニフ ᆬᆰチᄃツハᄅ ᄄハニ ナᄃ, ハᄚテᄆ ᄃトᆳᆵネᆵ ᆪハ ᄄᄍᆵ, ナᄍᄃナトᄅ ᄄネトニᆵᄃフ ᄃトᆬᄋトᄃツ ᄍト ᆬハネ.",
|
|
||||||
"ᅲムᅱᄚᅱ튜뛰슈ミᅲ뤼ᄡᅲチᅲルᅲᆰ, ᅲムᅱ쥐튜뛰쥬ミ ᅲミᅱ뮤ワᅱ쮸ヤᅱᄡᅲルᅲン, ᅲミᅱ슑 ᅲヤᅱ유뤼쥐튜チᅲ゙ᅱ유ルᅱᄡᅲン, ᅲユᅱᄚᅲミᅱ슑 ᅲヤᅱ쥬ミᅱ쥬뛰쓙",
|
|
||||||
"ᅲヤᅱ쥬ルᅱᄚᅲᆰᅱ쥬ヤtestᄃトᄉチᆳᄃᆰ ᄃトᆰムᆳネト",
|
|
||||||
"ᄋᄑ",
|
|
||||||
"ᄋᄎ",
|
|
||||||
"ナマニホᄃツホᄡホᄅマ ᄈマᄄマトミ ᄃミᄈメᆰミᆴメᆵホᄃナミ ᄃトトマムᄎホᄅミ チミハ ᄃトニマムᄌマナミ ᄃトメツホᄃᆭミナホᄅミ ネホチミハナ ハホᆴマᄉホム ᄃトᆰホムᄋメᄄミハツホᄃᆰマ ᄃトメᆳᄃᄈマネᄄミハホムᄅマフ ",
|
|
||||||
"£レロ£レト£レモ£レミ£レヒ£レメ£レト£レタ£レム£レト£レツ£レム£レマ£レナ£レワ¬タᆰ¬タᆰ¬タᆰ",
|
|
||||||
"¬タᆰ¬タᆰ£レロ£レタ£レタ£レタ£レタ£レタ£レタ£レタ£レタ£レタ£レタ£レタ£レタ£レタ£レタ£レタ£レタ£レタ£レワ¬タᆰ",
|
|
||||||
"¬タᆰ¬タᆰtest¬タᆰ",
|
|
||||||
"¬タᆱtest¬タᆱ",
|
|
||||||
"¬タᄅtest¬タᄅ",
|
|
||||||
"test¬チᅠtest¬タᆱ",
|
|
||||||
"¬チᆭtest¬チᄃ",
|
|
||||||
"£ᄍᄚᅩ초초ユoᅪ゙ ᅩᄋiᅩ볿ᅪヌᅩᆰᅪルnᅩンᅩラᅪユvᅩ゚ᅩワᅩリᅩᆭᅪ゚oᅩ쏘ルᅩᄚᅩᅠkᅢ똬レᅩᆴᅩ촑ᅩ쪼모ᄂ ᅩヨtᅩンᅪユᅩ뽃ᅩ콝ᅪ゙hᅩ톼モᅩ볺ᅩ뽀リᅩᄇeᅪヌᅩᆪᅩᄚᅩᆭᅩᆲᅪホ ᅩ꼬토코모リhᅪレᅪホᅪルᅩワᅩᆪᅩ봐ナiᅩᆭᅩ볷ᅩᄚᅩᄂvᅩ콰ヘeᅩ촔ᅩ뽉ᅩᄚ-mᅩᄁiᅪナnᅩヨᅩ초゙ᅩ봂ᅩᄚdᅩ소토゚ᅪルᅩ로토リᅩᄈ ᅩ゙ᅩᆬᅩ모뽌rᅩロᅩラᅩリeᅪルpᅪᅠrᅩ토゙ᅩ콠ᅩラeᅩ초ᅠᅩᆪᅪ゚sᅩリᅪヌᅩ뽜ヘᅩンᅪノeᅪノᅩᆬᅩᆵᅩ゙ᅩ봐レᅩᆲᅪワᅦ쫇ᅪホᅪホᅩ゚ᅩヨᅪヌᅩᄂtᅪヘᅩᆲᅩ놔モᅩ톬ᅪリᅪナiᅩᆰᅩᄆnᅪᅠgᅩᄡᅪノ ᅪマᅪノᅪナcᅩᆲᅩ゚hᅪᄀaᅩᆱᅩ콢ᅪリoᅩᆱᅩ゚ᅩヨᅪヘᅩルᅩンᅪノsᅩラᅩᆭᅩᄇ.ᅩ또쫘ネᅩᆪ",
|
|
||||||
"ᅩ과モᅩ゙ᅪナIᅩラᅩリᅩᆭᅪンnᅪヌᅪヌᅪルvᅩᆴᅩᆱokᅩ볾ᅩルᅪネiᅩヨᅪルᅩᆳᅩ쪼ᅠᅩ゙nᅩ고콡ᅩᆪᅩᄎgᅩ봐ネᅪルᅩᆳᅪルᅩᆲᅪホ ᅩᄚtᅪヤᅩᆭhᅩ゙ᅩᄇeᅩ꼬ᄂ ᅪヘᅩᆲᅩ봐ヨfᅩᄡᅩリᅪユᅩᆪᅢ똬ヨ£ᄎ쫁ᅩᄅlᅪヨᅪヤᅪレiᅪモᅪレᅩᆭᅪᅠnᅪヨᅪヘᅩラᅪモᅩ뽍gᅪヘ ᅩᄄoᅪレᅩᆰᅪᄀfᅩリᅩᆪᅩᆲ ᅩヨᅩリᅪヨᅩ゚ᅪルᅩᆴcᅭノᅪヤᅩᆱᅪヨᅪモᅪヌᅪヨᅪナhᅩ소녻ᅪレᅪヤᅢ고ラᅩ톼ユᅪナoᅩ톣ᅩᆬsᅩ뫄ネᅩ초ヨᅩᆭᅩ콰ᄁ.ᅩロᅩヨᅩ゙ᅩᅠᅩᆱᅩᄚ",
|
|
||||||
"ᅩラᅩ촤ヨᅩ쫊ᅪモ£ᄍᆴᅩ놔ヘᅩᆬᅪヌᅪネhᅩ보チeᅪマᅪモᅩ토ラᅩルᅩ톣ᅪヤ ᅪヌᅩワᅩ모ᅠᅪモᅪヘᅪナNᅪユᅪᅠeᅩラᅩᄆzᅩリᅩンᅩワᅩ촤ルpᅩ노초쫘ヘᅩᆵᅪレeᅩᅠᅩ코ᅠᅪワrᅩ또놔ヘᅩ초ヨᅪヤᅩヨᅩヨdᅩᅠᅩ゚ᅩᆳᅩᆲᅩンᅪ゚iᅩᆭᅪヨᅩ롸モᅪヤᅩᄂaᅩᅠᅩラᅩᆲᅪノᅩルnᅪレᅪワ ᅩ코゙ᅩᄚᅪレᅪナhᅩ솨ノiᅩ뽀゙vᅩ꽈ヌ£ᄌルᅪホᅪ゚-ᅭノᅩᆳᅩ로톼ヤmᅩ놄ᅩᆱiᅪユᅪヌᅩンᅩᆭnᅩラᅪル£ᄌヘᅩ゚ ᅩᆵᅩ봐ユᅪ゙ᅦᆱᅩ゚ᅩᆵᅩᄚᅩ봐ルᅩ코ンf ᅩᆰᅩᄚᅩᄚᅩラᅩヨᅩᆳᅩリᅪリcᅩᆭᅪヘᅩ보゙ᅪヘᅩ로ル£ᄌᆬᅪレaᅩᆴᅪホᅩ゚ᅩルᅪワᅥ고로쫘ホsᅩᄂ.ᅩンᅩン ᅭノZᅩ고ヨᅩワᅪヨᅩᄚᅩᆪᅪノᅩワaᅪヨᅩᄚᅪルᅩᆲᅪᄀlᅩ볾ᅩ뽜ヘᅩᄅgᅩ고゚ᅩ토뫄レᅩ゙ᅩᆲᅪナoᅩラᅪワ.ᅩ゚",
|
|
||||||
"ᅩᆭHᅩᆲᅩ노ラᅩ놔ンeᅪワ ᅩワᅩᆬᅩンᅩ콰ヘᅩ゚ᅩチwᅩユhᅩヨᅩᆵᅪモoᅩンᅪルᅩヨᅪホᅩ몵 ᅭノᅩ초ルᅩ゙ᅩ゚ᅪネWᅩ오톬aᅩ촑ᅪヘᅣᆵᅪネᅪユᅩᆳᅪルᅩᆵᅩワtᅩ쏘톭sᅩリᅪルᅪヨᅩユ ᅩᅠᅩᆱᅩᅠBᅩ콰ヘᅪルᅪノᅩ뽜ナeᅩᄉhᅩ솗ᅪヌᅩᆱᅪルiᅩ쫘モᅩ뽀뽍ᅪホᅩᆱᅩユnᅪ゚dᅩᄡᅩᆰᅩワᅩヨ ᅩᄚᅪノᅩ롸ヌᅪルᅩ봐゙ᅪナTᅪヨᅩ톼モᅩᆰᅪᄁhᅪマᅪモᅩᆴᅩᄏeᅩᆲᅩンᅩ゚ᅪナ ᅩ노쪼ンWᅪルᅩ゙ᅩンᅪヤᅪヌᅪンᅪナaᅪマᅪモᅪヤᅩ쪼톣lᅩᄡᅪヤᅩᄚᅩ노゚ᅪヤ£ᄌ폶.ᅪユ",
|
|
||||||
"Zᅩᆴᅩ゙ᅩᅠᅪルᅪヤᅪナ£ᄌタᅩラᅩ゙ᅪネᅩ코ラ£ᄌ쏴ルᅪホᅩᆵᅩ쪼゙ᅪモGᅩᄏOᅩᆳᅩラᅩᆴ",
|
|
||||||
"ᅨルミnb£ᄡノlミ ミuᅥテミᆵ ᅦンᄍolop ᅧヌᅦン ᅦンᄍoqミl ᅧヌn ᅧヌunp£ᄡノp£ᄡノヤu£ᄡノ ᄍodᆵᅦンᅧヌ poᆵsn£ᄡノᅦン op pᅦンs 'ᅧヌ£ᄡノlᅦン ᅥテu£ᄡノヤs£ᄡノd£ᄡノpミ ᄍnᅧヌᅦンᅧヌヤᅦンsuoヤ 'ᅧヌᅦンᆵミ ᅧヌ£ᄡノs ᄍolop ᆵnsd£ᄡノ ᆵᅦンᄍoᅨᆬ",
|
|
||||||
"00ᅨルᅥヨ$-",
|
|
||||||
"ᄐᄡᄑネᄑナ ᄑムᄑユᄑノᄑテᄑヒ ᄑツᄑメᄑマᄑラᄑホ ᄑニᄑマᄑリ ᄑハᄑユᄑヘᄑミᄑモ ᄑマᄑヨᄑナᄑメ ᄑヤᄑネᄑナ ᄑフᄑチᄑレᄑル ᄑトᄑマᄑヌ",
|
|
||||||
"ンミモンミᄀンミ゙ ンミᆰンミᆴンミᄁンミワンミᄂ ンミロンミᆱンミᄄンミᄚンミᄃ ンミ゚ンミᄄンミᄆ ンミᆪンミᆴンミᆭンミᄅンミᆲ ンミᄄンミᆵンミ゙ンミᆱ ンミᆳンミᄀンミ゙ ンミᆬンミレンミᄈンミᄇ ンミンンミᄄンミᅠ",
|
|
||||||
"ンユンヨヘンヨハ ンヨヨンヨレンヨホンヨネンヨミ ンヨヌンヨランヨヤンヨワンヨモ ンヨヒンヨヤンヨン ンヨマンヨレンヨメンヨユンヨリ ンヨヤンヨロンヨハンヨラ ンヨルンヨヘンヨハ ンヨムンヨニンヨ゚ンヨ゙ ンヨノンヨヤンヨフ",
|
|
||||||
"ンムᄏンメノンメニ ンメメンメヨンメハンメトンメフ ンメテンメモンメミンメリンメマ ンメヌンメミンメル ンメヒンメヨンメホンメムンメヤ ンメミンメランメニンメモ ンメユンメノンメニ ンメヘンメツンメロンメレ ンメナンメミンメネ",
|
|
||||||
"ンモᆪンモᄆンモᆴ ンモᄎンモᄒンモᄇンモᆲンモᄡ ンモᆱンモᄏンモᄌンヤタンモᄋ ンモᆵンモᄌンヤチ ンモᄈンモᄒンモᄊンモᄍンモᄐ ンモᄌンモンモᆴンモᄏ ンモᄑンモᄆンモᆴ ンモᄉンモᆰンヤテンヤツ ンモᆳンモᄌンモᄚ",
|
|
||||||
"ンユヒンユルンユヨ ンユᄁンユᆭンユレンユヤンユワ ンユモンユᆪンユᅠンユᄄンユ゚ ンユランユᅠンユᄅ ンユロンユᆭンユ゙ンユᄀンユᄂ ンユᅠンユᄃンユヨンユᆪ ンユᆬンユルンユヨ ンユンンユメンユᆱンユᆰ ンユユンユᅠンユリ",
|
|
||||||
"ンレテンレムンレホ ンレレンレ゙ンレメンレフンレヤ ンレヒンレロンレリンレᅠンレラ ンレマンレリンレᄀ ンレモンレ゙ンレヨンレルンレワ ンレリンレ゚ンレホンレロ ンレンンレムンレホ ンレユンレハンレᆪンレᄁ ンレヘンレリンレミ",
|
|
||||||
"¬メᆵ¬メᆪ¬メᅠ ¬メᆲ¬メᄚ¬メᄂ¬メ゙¬メᆭ ¬メン¬メᆳ¬メᆰ¬メᄇ¬メᄅ ¬メᄀ¬メᆰ¬メᄈ ¬メᆬ¬メᄚ¬メᄄ¬メᆱ¬メᆴ ¬メᆰ¬メᄆ¬メᅠ¬メᆳ ¬メᆵ¬メᆪ¬メᅠ ¬メᄃ¬メワ¬メᄉ¬メᄡ ¬メ゚¬メᆰ¬メᄁ",
|
|
||||||
"<script>alert(123)</script>",
|
|
||||||
"<script>alert('123');</script>",
|
|
||||||
"<img src=x onerror=alert(123) />",
|
|
||||||
"<svg><script>123<1>alert(123)</script>",
|
|
||||||
"\"><script>alert(123)</script>",
|
|
||||||
"'><script>alert(123)</script>",
|
|
||||||
"><script>alert(123)</script>",
|
|
||||||
"</script><script>alert(123)</script>",
|
|
||||||
"< / script >< script >alert(123)< / script >",
|
|
||||||
" onfocus=JaVaSCript:alert(123) autofocus",
|
|
||||||
"\" onfocus=JaVaSCript:alert(123) autofocus",
|
|
||||||
"' onfocus=JaVaSCript:alert(123) autofocus",
|
|
||||||
"ᄐワscriptᄐ゙alert(123)ᄐワ/scriptᄐ゙",
|
|
||||||
"<sc<script>ript>alert(123)</sc</script>ript>",
|
|
||||||
"--><script>alert(123)</script>",
|
|
||||||
"\";alert(123);t=\"",
|
|
||||||
"';alert(123);t='",
|
|
||||||
"JavaSCript:alert(123)",
|
|
||||||
";alert(123);",
|
|
||||||
"src=JaVaSCript:prompt(132)",
|
|
||||||
"\"><script>alert(123);</script x=\"",
|
|
||||||
"'><script>alert(123);</script x='",
|
|
||||||
"><script>alert(123);</script x=",
|
|
||||||
"\" autofocus onkeyup=\"javascript:alert(123)",
|
|
||||||
"' autofocus onkeyup='javascript:alert(123)",
|
|
||||||
"<script\\x20type=\"text/javascript\">javascript:alert(1);</script>",
|
|
||||||
"<script\\x3Etype=\"text/javascript\">javascript:alert(1);</script>",
|
|
||||||
"<script\\x0Dtype=\"text/javascript\">javascript:alert(1);</script>",
|
|
||||||
"<script\\x09type=\"text/javascript\">javascript:alert(1);</script>",
|
|
||||||
"<script\\x0Ctype=\"text/javascript\">javascript:alert(1);</script>",
|
|
||||||
"<script\\x2Ftype=\"text/javascript\">javascript:alert(1);</script>",
|
|
||||||
"<script\\x0Atype=\"text/javascript\">javascript:alert(1);</script>",
|
|
||||||
"'`\"><\\x3Cscript>javascript:alert(1)</script>",
|
|
||||||
"'`\"><\\x00script>javascript:alert(1)</script>",
|
|
||||||
"ABC<div style=\"x\\x3Aexpression(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:expression\\x5C(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:expression\\x00(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:exp\\x00ression(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:exp\\x5Cression(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:\\x0Aexpression(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:\\x09expression(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:\\xE3\\x80\\x80expression(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:\\xE2\\x80\\x84expression(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:\\xC2\\xA0expression(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:\\xE2\\x80\\x80expression(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:\\xE2\\x80\\x8Aexpression(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:\\x0Dexpression(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:\\x0Cexpression(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:\\xE2\\x80\\x87expression(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:\\xEF\\xBB\\xBFexpression(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:\\x20expression(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:\\xE2\\x80\\x88expression(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:\\x00expression(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:\\xE2\\x80\\x8Bexpression(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:\\xE2\\x80\\x86expression(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:\\xE2\\x80\\x85expression(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:\\xE2\\x80\\x82expression(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:\\x0Bexpression(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:\\xE2\\x80\\x81expression(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:\\xE2\\x80\\x83expression(javascript:alert(1)\">DEF",
|
|
||||||
"ABC<div style=\"x:\\xE2\\x80\\x89expression(javascript:alert(1)\">DEF",
|
|
||||||
"<a href=\"\\x0Bjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x0Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\xC2\\xA0javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x05javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\xE1\\xA0\\x8Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x18javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x11javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\xE2\\x80\\x88javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\xE2\\x80\\x89javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\xE2\\x80\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x17javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x03javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x0Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x1Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x00javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x10javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\xE2\\x80\\x82javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x20javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x13javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x09javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\xE2\\x80\\x8Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x14javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x19javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\xE2\\x80\\xAFjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x1Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\xE2\\x80\\x81javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x1Djavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\xE2\\x80\\x87javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x07javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\xE1\\x9A\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\xE2\\x80\\x83javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x04javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x01javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x08javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\xE2\\x80\\x84javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\xE2\\x80\\x86javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\xE3\\x80\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x12javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x0Djavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x0Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x0Cjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x15javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\xE2\\x80\\xA8javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x16javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x02javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x1Bjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x06javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\xE2\\x80\\xA9javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\xE2\\x80\\x85javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x1Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\xE2\\x81\\x9Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"\\x1Cjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"javascript\\x00:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"javascript\\x3A:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"javascript\\x09:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"javascript\\x0D:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"<a href=\"javascript\\x0A:javascript:alert(1)\" id=\"fuzzelement1\">test</a>",
|
|
||||||
"`\"'><img src=xxx:x \\x0Aonerror=javascript:alert(1)>",
|
|
||||||
"`\"'><img src=xxx:x \\x22onerror=javascript:alert(1)>",
|
|
||||||
"`\"'><img src=xxx:x \\x0Bonerror=javascript:alert(1)>",
|
|
||||||
"`\"'><img src=xxx:x \\x0Donerror=javascript:alert(1)>",
|
|
||||||
"`\"'><img src=xxx:x \\x2Fonerror=javascript:alert(1)>",
|
|
||||||
"`\"'><img src=xxx:x \\x09onerror=javascript:alert(1)>",
|
|
||||||
"`\"'><img src=xxx:x \\x0Conerror=javascript:alert(1)>",
|
|
||||||
"`\"'><img src=xxx:x \\x00onerror=javascript:alert(1)>",
|
|
||||||
"`\"'><img src=xxx:x \\x27onerror=javascript:alert(1)>",
|
|
||||||
"`\"'><img src=xxx:x \\x20onerror=javascript:alert(1)>",
|
|
||||||
"\"`'><script>\\x3Bjavascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\x0Djavascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\xEF\\xBB\\xBFjavascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\xE2\\x80\\x81javascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\xE2\\x80\\x84javascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\xE3\\x80\\x80javascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\x09javascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\xE2\\x80\\x89javascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\xE2\\x80\\x85javascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\xE2\\x80\\x88javascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\x00javascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\xE2\\x80\\xA8javascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\xE2\\x80\\x8Ajavascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\xE1\\x9A\\x80javascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\x0Cjavascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\x2Bjavascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\xF0\\x90\\x96\\x9Ajavascript:alert(1)</script>",
|
|
||||||
"\"`'><script>-javascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\x0Ajavascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\xE2\\x80\\xAFjavascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\x7Ejavascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\xE2\\x80\\x87javascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\xE2\\x81\\x9Fjavascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\xE2\\x80\\xA9javascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\xC2\\x85javascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\xEF\\xBF\\xAEjavascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\xE2\\x80\\x83javascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\xE2\\x80\\x8Bjavascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\xEF\\xBF\\xBEjavascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\xE2\\x80\\x80javascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\x21javascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\xE2\\x80\\x82javascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\xE2\\x80\\x86javascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\xE1\\xA0\\x8Ejavascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\x0Bjavascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\x20javascript:alert(1)</script>",
|
|
||||||
"\"`'><script>\\xC2\\xA0javascript:alert(1)</script>",
|
|
||||||
"<img \\x00src=x onerror=\"alert(1)\">",
|
|
||||||
"<img \\x47src=x onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img \\x11src=x onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img \\x12src=x onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img\\x47src=x onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img\\x10src=x onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img\\x13src=x onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img\\x32src=x onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img\\x47src=x onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img\\x11src=x onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img \\x47src=x onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img \\x34src=x onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img \\x39src=x onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img \\x00src=x onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img src\\x09=x onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img src\\x10=x onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img src\\x13=x onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img src\\x32=x onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img src\\x12=x onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img src\\x11=x onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img src\\x00=x onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img src\\x47=x onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img src=x\\x09onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img src=x\\x10onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img src=x\\x11onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img src=x\\x12onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img src=x\\x13onerror=\"javascript:alert(1)\">",
|
|
||||||
"<img[a][b][c]src[d]=x[e]onerror=[f]\"alert(1)\">",
|
|
||||||
"<img src=x onerror=\\x09\"javascript:alert(1)\">",
|
|
||||||
"<img src=x onerror=\\x10\"javascript:alert(1)\">",
|
|
||||||
"<img src=x onerror=\\x11\"javascript:alert(1)\">",
|
|
||||||
"<img src=x onerror=\\x12\"javascript:alert(1)\">",
|
|
||||||
"<img src=x onerror=\\x32\"javascript:alert(1)\">",
|
|
||||||
"<img src=x onerror=\\x00\"javascript:alert(1)\">",
|
|
||||||
"<a href=javascript:javascript:alert(1)>XXX</a>",
|
|
||||||
"<img src=\"x` `<script>javascript:alert(1)</script>\"` `>",
|
|
||||||
"<img src onerror /\" '\"= alt=javascript:alert(1)//\">",
|
|
||||||
"<title onpropertychange=javascript:alert(1)></title><title title=>",
|
|
||||||
"<a href=http://foo.bar/#x=`y></a><img alt=\"`><img src=x:x onerror=javascript:alert(1)></a>\">",
|
|
||||||
"<!--[if]><script>javascript:alert(1)</script -->",
|
|
||||||
"<!--[if<img src=x onerror=javascript:alert(1)//]> -->",
|
|
||||||
"<script src=\"/\\%(jscript)s\"></script>",
|
|
||||||
"<script src=\"\\\\%(jscript)s\"></script>",
|
|
||||||
"<IMG \"\"\"><SCRIPT>alert(\"XSS\")</SCRIPT>\">",
|
|
||||||
"<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>",
|
|
||||||
"<IMG SRC=# onmouseover=\"alert('xxs')\">",
|
|
||||||
"<IMG SRC= onmouseover=\"alert('xxs')\">",
|
|
||||||
"<IMG onmouseover=\"alert('xxs')\">",
|
|
||||||
"<IMG SRC=javascript:alert('XSS')>",
|
|
||||||
"<IMG SRC=javascript:alert('XSS')>",
|
|
||||||
"<IMG SRC=javascript:alert('XSS')>",
|
|
||||||
"<IMG SRC=\"jav ascript:alert('XSS');\">",
|
|
||||||
"<IMG SRC=\"jav	ascript:alert('XSS');\">",
|
|
||||||
"<IMG SRC=\"jav
ascript:alert('XSS');\">",
|
|
||||||
"<IMG SRC=\"jav
ascript:alert('XSS');\">",
|
|
||||||
"perl -e 'print \"<IMG SRC=java\\0script:alert(\\\"XSS\\\")>\";' > out",
|
|
||||||
"<IMG SRC=\"  javascript:alert('XSS');\">",
|
|
||||||
"<SCRIPT/XSS SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>",
|
|
||||||
"<BODY onload!#$%&()*~+-_.,:;?@[/|\\]^`=alert(\"XSS\")>",
|
|
||||||
"<SCRIPT/SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>",
|
|
||||||
"<<SCRIPT>alert(\"XSS\");//<</SCRIPT>",
|
|
||||||
"<SCRIPT SRC=http://ha.ckers.org/xss.js?< B >",
|
|
||||||
"<SCRIPT SRC=//ha.ckers.org/.j>",
|
|
||||||
"<IMG SRC=\"javascript:alert('XSS')\"",
|
|
||||||
"<iframe src=http://ha.ckers.org/scriptlet.html <",
|
|
||||||
"\\\";alert('XSS');//",
|
|
||||||
"<u oncopy=alert()> Copy me</u>",
|
|
||||||
"<i onwheel=alert(1)> Scroll over me </i>",
|
|
||||||
"<plaintext>",
|
|
||||||
"http://a/%%30%30",
|
|
||||||
"</textarea><script>alert(123)</script>",
|
|
||||||
"1;DROP TABLE users",
|
|
||||||
"1'; DROP TABLE users-- 1",
|
|
||||||
"' OR 1=1 -- 1",
|
|
||||||
"' OR '1'='1",
|
|
||||||
"'; EXEC sp_MSForEachTable 'DROP TABLE ?'; --",
|
|
||||||
" ",
|
|
||||||
"%",
|
|
||||||
"_",
|
|
||||||
"-",
|
|
||||||
"--",
|
|
||||||
"--version",
|
|
||||||
"--help",
|
|
||||||
"$USER",
|
|
||||||
"/dev/null; touch /tmp/blns.fail ; echo",
|
|
||||||
"`touch /tmp/blns.fail`",
|
|
||||||
"$(touch /tmp/blns.fail)",
|
|
||||||
"@{[system \"touch /tmp/blns.fail\"]}",
|
|
||||||
"eval(\"puts 'hello world'\")",
|
|
||||||
"System(\"ls -al /\")",
|
|
||||||
"`ls -al /`",
|
|
||||||
"Kernel.exec(\"ls -al /\")",
|
|
||||||
"Kernel.exit(1)",
|
|
||||||
"%x('ls -al /')",
|
|
||||||
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><!DOCTYPE foo [ <!ELEMENT foo ANY ><!ENTITY xxe SYSTEM \"file:///etc/passwd\" >]><foo>&xxe;</foo>",
|
|
||||||
"$HOME",
|
|
||||||
"$ENV{'HOME'}",
|
|
||||||
"%d",
|
|
||||||
"%s%s%s%s%s",
|
|
||||||
"{0}",
|
|
||||||
"%*.*s",
|
|
||||||
"%@",
|
|
||||||
"%n",
|
|
||||||
"File:///",
|
|
||||||
"../../../../../../../../../../../etc/passwd%00",
|
|
||||||
"../../../../../../../../../../../etc/hosts",
|
|
||||||
"() { 0; }; touch /tmp/blns.shellshock1.fail;",
|
|
||||||
"() { _; } >_[$($())] { touch /tmp/blns.shellshock2.fail; }",
|
|
||||||
"<<< %s(un='%s') = %u",
|
|
||||||
"+++ATH0",
|
|
||||||
"CON",
|
|
||||||
"PRN",
|
|
||||||
"AUX",
|
|
||||||
"CLOCK$",
|
|
||||||
"NUL",
|
|
||||||
"A:",
|
|
||||||
"ZZ:",
|
|
||||||
"COM1",
|
|
||||||
"LPT1",
|
|
||||||
"LPT2",
|
|
||||||
"LPT3",
|
|
||||||
"COM2",
|
|
||||||
"COM3",
|
|
||||||
"COM4",
|
|
||||||
"DCC SEND STARTKEYLOGGER 0 0 0",
|
|
||||||
"Scunthorpe General Hospital",
|
|
||||||
"Penistone Community Church",
|
|
||||||
"Lightwater Country Park",
|
|
||||||
"Jimmy Clitheroe",
|
|
||||||
"Horniman Museum",
|
|
||||||
"shitake mushrooms",
|
|
||||||
"RomansInSussex.co.uk",
|
|
||||||
"http://www.cum.qc.ca/",
|
|
||||||
"Craig Cockburn, Software Specialist",
|
|
||||||
"Linda Callahan",
|
|
||||||
"Dr. Herman I. Libshitz",
|
|
||||||
"magna cum laude",
|
|
||||||
"Super Bowl XXX",
|
|
||||||
"medieval erection of parapets",
|
|
||||||
"evaluate",
|
|
||||||
"mocha",
|
|
||||||
"expression",
|
|
||||||
"Arsenal canal",
|
|
||||||
"classic",
|
|
||||||
"Tyson Gay",
|
|
||||||
"Dick Van Dyke",
|
|
||||||
"basement",
|
|
||||||
"If you're reading this, you've been in a coma for almost 20 years now. We're trying a new technique. We don't know where this message will end up in your dream, but we hope it works. Please wake up, we miss you.",
|
|
||||||
"Roses are \u001b[0;31mred\u001b[0m, violets are \u001b[0;34mblue. Hope you enjoy terminal hue",
|
|
||||||
"But now...\u001b[20Cfor my greatest trick...\u001b[8m",
|
|
||||||
"The quic\b\b\b\b\b\bk brown fo\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007x... [Beeeep]",
|
|
||||||
"Powerトマトマᄉムᄄマトマトᄉムᄄマᄆᄆヒ ¢ᆬᆪ ¢ᆬᆪh ¢ᆬᆪ ¢ᆬᆪ¥ニラ",
|
|
||||||
"゚マᄈ0゚フネᄌマ",
|
|
||||||
"¢ᄚワ¢ᄆヘ¢ᄚ゙¬タフ¢ᄚᄒ",
|
|
||||||
"ᅳᆵᅳニ흐リ",
|
|
||||||
"{% print 'x' * 64 * 1024**3 %}",
|
|
||||||
"{{ \"\".__class__.__mro__[2].__subclasses__()[40](\"/etc/passwd\").read() }}"
|
|
||||||
]
|
|
||||||
|
|
@ -1,260 +0,0 @@
|
||||||
/* eslint-env jest */
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
const Hexo = require('hexo')
|
|
||||||
const zlib = require('node:zlib')
|
|
||||||
const { promisify } = require('node:util')
|
|
||||||
const gzip = promisify(zlib.gzip)
|
|
||||||
const unzip = promisify(zlib.unzip)
|
|
||||||
|
|
||||||
describe('gzip', () => {
|
|
||||||
const hexo = new Hexo(__dirname)
|
|
||||||
const g = require('../lib/filter').gzipFn.bind(hexo)
|
|
||||||
const path = 'foo.txt'
|
|
||||||
const input = 'Lorem ipsum dolor sit amet consectetur adipiscing elit fusce'
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
hexo.config.minify = {
|
|
||||||
gzip: {
|
|
||||||
enable: true,
|
|
||||||
verbose: false,
|
|
||||||
include: ['*.html', '*.css', '*.js', '*.txt', '*.ttf', '*.atom', '*.stl', '*.xml', '*.svg', '*.eot', '*.json'],
|
|
||||||
globOptions: { basename: true }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
})
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
const routeList = hexo.route.list()
|
|
||||||
routeList.forEach((path) => hexo.route.remove(path))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('default', async () => {
|
|
||||||
await g()
|
|
||||||
|
|
||||||
const output = hexo.route.get(path.concat('.gz'))
|
|
||||||
const buf = []
|
|
||||||
output.on('data', (chunk) => (buf.push(chunk)))
|
|
||||||
output.on('end', async () => {
|
|
||||||
const result = Buffer.concat(buf)
|
|
||||||
const expected = await gzip(input, { level: zlib.constants.Z_BEST_COMPRESSION })
|
|
||||||
const resultUnzip = await unzip(result)
|
|
||||||
const expectedUnzip = await unzip(expected)
|
|
||||||
|
|
||||||
expect(result.equals(expected)).toBe(true)
|
|
||||||
expect(resultUnzip.toString()).toBe(input)
|
|
||||||
expect(expectedUnzip.toString()).toBe(input)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('disable', async () => {
|
|
||||||
hexo.config.minify.gzip.enable = false
|
|
||||||
const result = await g()
|
|
||||||
|
|
||||||
expect(result).toBeUndefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('empty file', async () => {
|
|
||||||
hexo.route.set(path, '')
|
|
||||||
|
|
||||||
const routeList = hexo.route.list()
|
|
||||||
expect(routeList).not.toContain(path.concat('.gz'))
|
|
||||||
|
|
||||||
const result = await g()
|
|
||||||
// empty file resolves to an array of undefined
|
|
||||||
expect(result).toBeDefined()
|
|
||||||
expect(result[0]).toBeUndefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('option', async () => {
|
|
||||||
const customOpt = {
|
|
||||||
level: 1
|
|
||||||
}
|
|
||||||
hexo.config.minify.gzip.level = customOpt.level
|
|
||||||
await g()
|
|
||||||
|
|
||||||
const output = hexo.route.get(path.concat('.gz'))
|
|
||||||
const buf = []
|
|
||||||
output.on('data', (chunk) => (buf.push(chunk)))
|
|
||||||
output.on('end', async () => {
|
|
||||||
const result = Buffer.concat(buf)
|
|
||||||
const expected = await gzip(input, customOpt)
|
|
||||||
|
|
||||||
expect(result.equals(expected)).toBe(true)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('option - verbose', async () => {
|
|
||||||
hexo.config.minify.gzip.verbose = true
|
|
||||||
hexo.log.log = jest.fn()
|
|
||||||
await g()
|
|
||||||
|
|
||||||
expect(hexo.log.log.mock.calls[0][0]).toContain(`gzip: ${path}`)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('option - invalid', async () => {
|
|
||||||
const customOpt = {
|
|
||||||
level: 9000
|
|
||||||
}
|
|
||||||
hexo.config.minify.gzip.level = customOpt.level
|
|
||||||
|
|
||||||
let expected
|
|
||||||
try {
|
|
||||||
await gzip(input, customOpt)
|
|
||||||
} catch (err) {
|
|
||||||
expected = err
|
|
||||||
}
|
|
||||||
expect(expected).toBeDefined()
|
|
||||||
await expect(g()).rejects.toThrow(`Path: ${path}\n${expected}`)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - exclude non-text file by default', async () => {
|
|
||||||
const path = 'foo.jpg'
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
await g()
|
|
||||||
|
|
||||||
const result = hexo.route.get(path.concat('.gz'))
|
|
||||||
expect(result).toBeUndefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - basename', async () => {
|
|
||||||
hexo.config.minify.gzip.include = 'bar.txt'
|
|
||||||
const path = 'foo/bar.txt'
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
await g()
|
|
||||||
|
|
||||||
const result = hexo.route.get(path.concat('.gz'))
|
|
||||||
|
|
||||||
expect(result).toBeDefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - slash in pattern', async () => {
|
|
||||||
hexo.config.minify.gzip.include = '**/lectus/**/*.txt'
|
|
||||||
const path = 'eleifend/lectus/nullam/dapibus/netus.txt'
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
await g()
|
|
||||||
|
|
||||||
const result = hexo.route.get(path.concat('.gz'))
|
|
||||||
|
|
||||||
expect(result).toBeDefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - basename + slash + basename enabled', async () => {
|
|
||||||
hexo.route.remove(path)
|
|
||||||
|
|
||||||
const paths = [
|
|
||||||
'lorem/ipsum/dolor.html',
|
|
||||||
'gravida/sociis/erat/ante.css',
|
|
||||||
'aptent/elementum.js',
|
|
||||||
'felis/blandit/cursus.svg'
|
|
||||||
]
|
|
||||||
hexo.config.minify.gzip.include = [
|
|
||||||
'*.html',
|
|
||||||
'**/sociis/**/*.css'
|
|
||||||
]
|
|
||||||
|
|
||||||
paths.forEach((inpath) => {
|
|
||||||
hexo.route.set(inpath, input)
|
|
||||||
})
|
|
||||||
await g()
|
|
||||||
|
|
||||||
const routeList = hexo.route.list()
|
|
||||||
const expected = [
|
|
||||||
'lorem/ipsum/dolor.html.gz',
|
|
||||||
'gravida/sociis/erat/ante.css.gz'
|
|
||||||
]
|
|
||||||
const notExpected = [
|
|
||||||
'aptent/elementum.js.gz',
|
|
||||||
'felis/blandit/cursus.svg.gz'
|
|
||||||
]
|
|
||||||
|
|
||||||
expect(routeList).toEqual(expect.arrayContaining(expected))
|
|
||||||
expect(routeList).toEqual(expect.not.arrayContaining(notExpected))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - basename + slash + basename disabled', async () => {
|
|
||||||
hexo.route.remove(path)
|
|
||||||
|
|
||||||
const paths = [
|
|
||||||
'lorem/ipsum/dolor.html',
|
|
||||||
'gravida/sociis/erat/ante.css',
|
|
||||||
'aptent/elementum.js',
|
|
||||||
'felis/blandit/cursus.svg'
|
|
||||||
]
|
|
||||||
hexo.config.minify.gzip.include = [
|
|
||||||
'*.html',
|
|
||||||
'**/sociis/**/*.css'
|
|
||||||
]
|
|
||||||
hexo.config.minify.gzip.globOptions = {
|
|
||||||
basename: false
|
|
||||||
}
|
|
||||||
|
|
||||||
paths.forEach((inpath) => {
|
|
||||||
hexo.route.set(inpath, input)
|
|
||||||
})
|
|
||||||
await g()
|
|
||||||
|
|
||||||
const routeList = hexo.route.list()
|
|
||||||
const expected = [
|
|
||||||
'gravida/sociis/erat/ante.css.gz'
|
|
||||||
]
|
|
||||||
const notExpected = [
|
|
||||||
'lorem/ipsum/dolor.html.gz',
|
|
||||||
'aptent/elementum.js.gz',
|
|
||||||
'felis/blandit/cursus.svg.gz'
|
|
||||||
]
|
|
||||||
|
|
||||||
expect(routeList).toEqual(expect.arrayContaining(expected))
|
|
||||||
expect(routeList).toEqual(expect.not.arrayContaining(notExpected))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - reverse pattern + basename disabled', async () => {
|
|
||||||
hexo.route.remove(path)
|
|
||||||
|
|
||||||
const paths = [
|
|
||||||
'lorem/ipsum/dolor.html',
|
|
||||||
'gravida/sociis/erat/ante.css',
|
|
||||||
'aptent/elementum.js',
|
|
||||||
'felis/blandit/cursus.svg'
|
|
||||||
]
|
|
||||||
hexo.config.minify.gzip.include = [
|
|
||||||
'!dolor.html'
|
|
||||||
]
|
|
||||||
hexo.config.minify.gzip.globOptions = {
|
|
||||||
basename: false
|
|
||||||
}
|
|
||||||
|
|
||||||
paths.forEach((inpath) => {
|
|
||||||
hexo.route.set(inpath, input)
|
|
||||||
})
|
|
||||||
await g()
|
|
||||||
|
|
||||||
const routeList = hexo.route.list()
|
|
||||||
const expected = paths.map((path) => path.concat('.gz'))
|
|
||||||
|
|
||||||
expect(routeList).toEqual(expect.arrayContaining(expected))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('blns', async () => {
|
|
||||||
const blns = require('./fixtures/blns.json')
|
|
||||||
|
|
||||||
for (const nStr of blns) {
|
|
||||||
hexo.route.remove(path)
|
|
||||||
|
|
||||||
hexo.route.set(path, nStr)
|
|
||||||
|
|
||||||
await g()
|
|
||||||
|
|
||||||
const output = hexo.route.get(path.concat('.gz'))
|
|
||||||
const buf = []
|
|
||||||
output.on('data', (chunk) => (buf.push(chunk)))
|
|
||||||
output.on('end', async () => {
|
|
||||||
const result = Buffer.concat(buf)
|
|
||||||
const resultUnzip = await unzip(result)
|
|
||||||
|
|
||||||
expect(resultUnzip.toString()).toBe(nStr)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
@ -1,132 +0,0 @@
|
||||||
/* eslint-env jest */
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
const Hexo = require('hexo')
|
|
||||||
const { minify: htmlMinify } = require('html-minifier-terser')
|
|
||||||
|
|
||||||
describe('html', () => {
|
|
||||||
const hexo = new Hexo(__dirname)
|
|
||||||
const h = require('../lib/filter').minifyHtml.bind(hexo)
|
|
||||||
const input = '<p id="">foo</p>'
|
|
||||||
const path = 'index.html'
|
|
||||||
const defaultCfg = {
|
|
||||||
html: {
|
|
||||||
enable: true,
|
|
||||||
verbose: false,
|
|
||||||
exclude: [],
|
|
||||||
collapseBooleanAttributes: true,
|
|
||||||
collapseWhitespace: true,
|
|
||||||
ignoreCustomComments: [/^\s*more/],
|
|
||||||
removeComments: true,
|
|
||||||
removeEmptyAttributes: true,
|
|
||||||
removeScriptTypeAttributes: true,
|
|
||||||
removeStyleLinkTypeAttributes: true,
|
|
||||||
minifyJS: true,
|
|
||||||
minifyCSS: true,
|
|
||||||
globOptions: { basename: true }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let expected = ''
|
|
||||||
|
|
||||||
beforeAll(async () => {
|
|
||||||
expected = await htmlMinify(input, defaultCfg.html)
|
|
||||||
})
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
hexo.config.minify = JSON.parse(JSON.stringify(defaultCfg))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('default', async () => {
|
|
||||||
const result = await h(input, { path })
|
|
||||||
|
|
||||||
expect(result).toBe(expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('disable', async () => {
|
|
||||||
hexo.config.minify.html.enable = false
|
|
||||||
|
|
||||||
const result = await h(input, { path })
|
|
||||||
|
|
||||||
expect(result).toBeUndefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('empty file', async () => {
|
|
||||||
const result = await h('', { path })
|
|
||||||
|
|
||||||
expect(result).toBeUndefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('option', async () => {
|
|
||||||
const customOpt = { removeEmptyAttributes: false }
|
|
||||||
hexo.config.minify.html = customOpt
|
|
||||||
|
|
||||||
const result = await h(input, { path })
|
|
||||||
const expected = await htmlMinify(input, customOpt)
|
|
||||||
|
|
||||||
expect(result).toBe(input)
|
|
||||||
expect(result).toBe(expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('option - verbose', async () => {
|
|
||||||
hexo.config.minify.html.verbose = true
|
|
||||||
hexo.log.log = jest.fn()
|
|
||||||
await h(input, { path })
|
|
||||||
|
|
||||||
expect(hexo.log.log.mock.calls[0][0]).toContain(`html: ${path}`)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('exclude', async () => {
|
|
||||||
const exclude = '*.min.html'
|
|
||||||
hexo.config.minify.html.exclude = exclude
|
|
||||||
|
|
||||||
const result = await h(input, { path: 'foo/bar.min.html' })
|
|
||||||
|
|
||||||
expect(result).toBe(input)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('exclude - slash in pattern', async () => {
|
|
||||||
const exclude = '**/lectus/**/*.html'
|
|
||||||
hexo.config.minify.html.exclude = exclude
|
|
||||||
|
|
||||||
const result = await h(input, { path: 'eleifend/lectus/nullam/dapibus/netus.html' })
|
|
||||||
|
|
||||||
expect(result).toBe(input)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('exclude - basename is true + slash', async () => {
|
|
||||||
const exclude = ['**/lectus/**/*.html', 'bar.html']
|
|
||||||
const globOptions = { basename: true }
|
|
||||||
hexo.config.minify.html.exclude = exclude
|
|
||||||
hexo.config.minify.html.globOptions = globOptions
|
|
||||||
|
|
||||||
const result = await h(input, { path: 'foo/bar.html' })
|
|
||||||
|
|
||||||
expect(result).toBe(input)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('exclude - basename is false + slash', async () => {
|
|
||||||
const exclude = ['**/lectus/**/*.html', 'bar.html']
|
|
||||||
const globOptions = { basename: false }
|
|
||||||
hexo.config.minify.html.exclude = exclude
|
|
||||||
hexo.config.minify.html.globOptions = globOptions
|
|
||||||
|
|
||||||
const result = await h(input, { path: 'foo/bar.html' })
|
|
||||||
|
|
||||||
expect(result).toBe(expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('null', async () => {
|
|
||||||
hexo.config.minify.html.exclude = null
|
|
||||||
hexo.config.minify.html.globOptions = null
|
|
||||||
|
|
||||||
const result = await h(input, { path: null })
|
|
||||||
|
|
||||||
expect(result).toBe(expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('invalid string', async () => {
|
|
||||||
const invalid = '<html><>?:"{}|_+</html>'
|
|
||||||
|
|
||||||
await expect(h(invalid, { path })).rejects.toThrow('Parse Error: <>?:"{}|_+</html>')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
123
test/js.test.js
123
test/js.test.js
|
|
@ -1,123 +0,0 @@
|
||||||
/* eslint-env jest */
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
const Hexo = require('hexo')
|
|
||||||
const { minify: terserMinify } = require('terser')
|
|
||||||
|
|
||||||
describe('js', () => {
|
|
||||||
const hexo = new Hexo(__dirname)
|
|
||||||
const j = require('../lib/filter').minifyJs.bind(hexo)
|
|
||||||
const input = 'var o = { "foo": 1, bar: 3 };'
|
|
||||||
const path = 'foo.js'
|
|
||||||
let expected = ''
|
|
||||||
|
|
||||||
beforeAll(async () => {
|
|
||||||
const { code } = await terserMinify(input, { mangle: true })
|
|
||||||
expected = code
|
|
||||||
})
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
hexo.config.minify = {
|
|
||||||
js: {
|
|
||||||
enable: true,
|
|
||||||
verbose: false,
|
|
||||||
exclude: ['*.min.js'],
|
|
||||||
compress: {},
|
|
||||||
mangle: true,
|
|
||||||
output: {},
|
|
||||||
globOptions: { basename: true }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
test('default', async () => {
|
|
||||||
const result = await j(input, { path })
|
|
||||||
|
|
||||||
expect(result).toBeDefined()
|
|
||||||
expect(expected).toBeDefined()
|
|
||||||
expect(result).toBe(expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('disable', async () => {
|
|
||||||
hexo.config.minify.js.enable = false
|
|
||||||
|
|
||||||
const result = await j(input, { path })
|
|
||||||
|
|
||||||
expect(result).toBeUndefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('empty file', async () => {
|
|
||||||
const result = await j('', { path })
|
|
||||||
|
|
||||||
expect(result).toBeUndefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('option', async () => {
|
|
||||||
const customOpt = {
|
|
||||||
mangle: {
|
|
||||||
properties: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hexo.config.minify.js = customOpt
|
|
||||||
|
|
||||||
const result = await j(input, { path })
|
|
||||||
const { code: expected } = await terserMinify(input, customOpt)
|
|
||||||
|
|
||||||
expect(result).toBe(expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('option - verbose', async () => {
|
|
||||||
hexo.config.minify.js.verbose = true
|
|
||||||
hexo.log.log = jest.fn()
|
|
||||||
await j(input, { path })
|
|
||||||
|
|
||||||
expect(hexo.log.log.mock.calls[0][0]).toContain(`js: ${path}`)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('option - invalid', async () => {
|
|
||||||
const customOpt = {
|
|
||||||
mangle: {
|
|
||||||
foo: 'bar'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hexo.config.minify.js = customOpt
|
|
||||||
|
|
||||||
let expected
|
|
||||||
try {
|
|
||||||
await terserMinify(input, customOpt)
|
|
||||||
} catch (err) {
|
|
||||||
expected = err
|
|
||||||
}
|
|
||||||
|
|
||||||
expect(expected).toBeDefined()
|
|
||||||
await expect(j(input, { path })).rejects.toThrow(`Path: ${path}\n${expected}`)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('exclude - *.min.js', async () => {
|
|
||||||
const result = await j(input, { path: 'foo/bar.min.js' })
|
|
||||||
|
|
||||||
expect(result).toBe(input)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('exclude - basename', async () => {
|
|
||||||
const exclude = '*baz.js'
|
|
||||||
hexo.config.minify.js.exclude = exclude
|
|
||||||
const result = await j(input, { path: 'foo/barbaz.js' })
|
|
||||||
|
|
||||||
expect(result).toBe(input)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('exclude - slash in pattern', async () => {
|
|
||||||
const exclude = '**/lectus/**/*.js'
|
|
||||||
hexo.config.minify.js.exclude = exclude
|
|
||||||
const result = await j(input, { path: 'eleifend/lectus/nullam/dapibus/netus.js' })
|
|
||||||
|
|
||||||
expect(result).toBe(input)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('invalid string', async () => {
|
|
||||||
const invalid = 'console.log("\\");'
|
|
||||||
|
|
||||||
await expect(j(invalid, { path })).rejects.toThrow(`Path: ${path}\nSyntaxError`)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
@ -1,190 +0,0 @@
|
||||||
/* eslint-env jest */
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
const Hexo = require('hexo')
|
|
||||||
|
|
||||||
describe('xml', () => {
|
|
||||||
const hexo = new Hexo(__dirname)
|
|
||||||
const jsonFn = require('../lib/filter').minifyJson.bind(hexo)
|
|
||||||
const path = 'foo.json'
|
|
||||||
const input = '{\n\t"vitae": "hendrerit",\n\t"tristique": [\n\t\t"primis",\n\t\t"quam"\n\t]\n}'
|
|
||||||
const expected = '{"vitae":"hendrerit","tristique":["primis","quam"]}'
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
hexo.config.minify = {
|
|
||||||
json: {
|
|
||||||
enable: false,
|
|
||||||
verbose: false,
|
|
||||||
include: ['*.json', '!*.min.json'],
|
|
||||||
globOptions: { basename: true }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// plugin is disabled by default
|
|
||||||
hexo.config.minify.json.enable = true
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
})
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
const routeList = hexo.route.list()
|
|
||||||
routeList.forEach((path) => hexo.route.remove(path))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('default', async () => {
|
|
||||||
await jsonFn()
|
|
||||||
|
|
||||||
const output = hexo.route.get(path)
|
|
||||||
let result = ''
|
|
||||||
output.on('data', (chunk) => (result += chunk))
|
|
||||||
output.on('end', () => {
|
|
||||||
expect(result).toBe(expected)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('disable', async () => {
|
|
||||||
hexo.config.minify.json.enable = false
|
|
||||||
const result = await jsonFn()
|
|
||||||
|
|
||||||
expect(result).toBeUndefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('option - verbose', async () => {
|
|
||||||
hexo.config.minify.json.verbose = true
|
|
||||||
hexo.log.log = jest.fn()
|
|
||||||
await jsonFn()
|
|
||||||
|
|
||||||
expect(hexo.log.log.mock.calls[0][0]).toContain(`json: ${path}`)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('invalid input', async () => {
|
|
||||||
hexo.route.set(path, 'foo')
|
|
||||||
await expect(jsonFn()).rejects.toThrow(`Path: ${path}\nSyntaxError`)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('empty file', async () => {
|
|
||||||
hexo.route.set(path, '')
|
|
||||||
const result = await jsonFn()
|
|
||||||
|
|
||||||
expect(result).toBeDefined()
|
|
||||||
expect(result[0]).toBeUndefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - exclude *.min.json by default', async () => {
|
|
||||||
const path = 'foo.min.json'
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
await jsonFn()
|
|
||||||
|
|
||||||
const output = hexo.route.get(path)
|
|
||||||
let result = ''
|
|
||||||
output.on('data', (chunk) => (result += chunk))
|
|
||||||
output.on('end', () => {
|
|
||||||
expect(result).toBe(input)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - basename', async () => {
|
|
||||||
hexo.config.minify.json.include = 'bar.json'
|
|
||||||
const path = 'foo/bar.json'
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
await jsonFn()
|
|
||||||
|
|
||||||
const output = hexo.route.get(path)
|
|
||||||
let result = ''
|
|
||||||
output.on('data', (chunk) => (result += chunk))
|
|
||||||
output.on('end', () => {
|
|
||||||
expect(result).toBe(expected)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - slash in pattern', async () => {
|
|
||||||
hexo.config.minify.json.include = '**/lectus/**/*.json'
|
|
||||||
const path = 'eleifend/lectus/nullam/dapibus/netus.json'
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
await jsonFn()
|
|
||||||
|
|
||||||
const output = hexo.route.get(path)
|
|
||||||
let result = ''
|
|
||||||
output.on('data', (chunk) => (result += chunk))
|
|
||||||
output.on('end', () => {
|
|
||||||
expect(result).toBe(expected)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - basename + slash', async () => {
|
|
||||||
hexo.route.remove(path)
|
|
||||||
|
|
||||||
const paths = [
|
|
||||||
'lorem/ipsum/dolor.json',
|
|
||||||
'gravida/sociis/erat/ante.json',
|
|
||||||
'aptent/elementum.json',
|
|
||||||
'felis/blandit/cursus.json'
|
|
||||||
]
|
|
||||||
hexo.config.minify.json.include = [
|
|
||||||
'dolor.json',
|
|
||||||
'**/sociis/**/*.json'
|
|
||||||
]
|
|
||||||
|
|
||||||
paths.forEach((inpath) => {
|
|
||||||
hexo.route.set(inpath, input)
|
|
||||||
})
|
|
||||||
await jsonFn()
|
|
||||||
|
|
||||||
const minPaths = paths.slice(0, 2)
|
|
||||||
const unminPaths = paths.slice(2)
|
|
||||||
|
|
||||||
minPaths.forEach((inpath) => {
|
|
||||||
const output = hexo.route.get(inpath)
|
|
||||||
let result = ''
|
|
||||||
output.on('data', (chunk) => (result += chunk))
|
|
||||||
output.on('end', () => {
|
|
||||||
expect(result).toBe(expected)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
unminPaths.forEach((inpath) => {
|
|
||||||
const output = hexo.route.get(inpath)
|
|
||||||
let result = ''
|
|
||||||
output.on('data', (chunk) => (result += chunk))
|
|
||||||
output.on('end', () => {
|
|
||||||
expect(result).toBe(input)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - reverse pattern + basename disabled', async () => {
|
|
||||||
hexo.route.remove(path)
|
|
||||||
|
|
||||||
const paths = [
|
|
||||||
'lorem/ipsum/dolor.json',
|
|
||||||
'gravida/sociis/erat/ante.json',
|
|
||||||
'aptent/elementum.json',
|
|
||||||
'felis/blandit/cursus.json'
|
|
||||||
]
|
|
||||||
hexo.config.minify.json.include = [
|
|
||||||
'!dolor.json'
|
|
||||||
]
|
|
||||||
hexo.config.minify.json.globOptions = {
|
|
||||||
basename: false
|
|
||||||
}
|
|
||||||
|
|
||||||
paths.forEach((inpath) => {
|
|
||||||
hexo.route.set(inpath, input)
|
|
||||||
})
|
|
||||||
await jsonFn()
|
|
||||||
|
|
||||||
paths.forEach((inpath) => {
|
|
||||||
const output = hexo.route.get(inpath)
|
|
||||||
let result = ''
|
|
||||||
output.on('data', (chunk) => (result += chunk))
|
|
||||||
output.on('end', () => {
|
|
||||||
expect(result).toBe(expected)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - empty route', async () => {
|
|
||||||
hexo.route.remove(path)
|
|
||||||
|
|
||||||
const result = await jsonFn()
|
|
||||||
expect(result.length).toBe(0)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
253
test/svg.test.js
253
test/svg.test.js
|
|
@ -1,253 +0,0 @@
|
||||||
/* eslint-env jest */
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
const Hexo = require('hexo')
|
|
||||||
const { optimize: svgOptimize } = require('svgo')
|
|
||||||
|
|
||||||
describe('svg', () => {
|
|
||||||
const hexo = new Hexo(__dirname)
|
|
||||||
const s = require('../lib/filter').minifySvg.bind(hexo)
|
|
||||||
const input = '<svg><rect x="1" y="2" width="3" height="4" id="a"/></svg>'
|
|
||||||
const path = 'foo.svg'
|
|
||||||
// svgo's plugins option
|
|
||||||
let plugins = [{
|
|
||||||
name: 'preset-default',
|
|
||||||
params: {
|
|
||||||
overrides: {}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
hexo.config.minify = {
|
|
||||||
svg: {
|
|
||||||
enable: true,
|
|
||||||
verbose: false,
|
|
||||||
include: ['*.svg', '!*.min.svg'],
|
|
||||||
plugins: {},
|
|
||||||
globOptions: { basename: true }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
plugins = [{
|
|
||||||
name: 'preset-default',
|
|
||||||
params: {
|
|
||||||
overrides: {}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
})
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
const routeList = hexo.route.list()
|
|
||||||
routeList.forEach((path) => hexo.route.remove(path))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('default', async () => {
|
|
||||||
await s()
|
|
||||||
const { data } = svgOptimize(input, { plugins })
|
|
||||||
|
|
||||||
const output = hexo.route.get(path)
|
|
||||||
let result = ''
|
|
||||||
output.on('data', (chunk) => (result += chunk))
|
|
||||||
output.on('end', () => {
|
|
||||||
expect(result).toBe(data)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('disable', async () => {
|
|
||||||
hexo.config.minify.svg.enable = false
|
|
||||||
const result = await s()
|
|
||||||
|
|
||||||
expect(result).toBeUndefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('empty file', async () => {
|
|
||||||
hexo.route.set(path, '')
|
|
||||||
const result = await s()
|
|
||||||
|
|
||||||
// empty file resolves to an array of undefined
|
|
||||||
expect(result).toBeDefined()
|
|
||||||
expect(result[0]).toBeUndefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('option', async () => {
|
|
||||||
const customOpt = {
|
|
||||||
cleanupIds: false
|
|
||||||
}
|
|
||||||
hexo.config.minify.svg.plugins = customOpt
|
|
||||||
plugins = [{
|
|
||||||
name: 'preset-default',
|
|
||||||
params: {
|
|
||||||
overrides: customOpt
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
await s()
|
|
||||||
const { data } = svgOptimize(input, { plugins })
|
|
||||||
|
|
||||||
const output = hexo.route.get(path)
|
|
||||||
let result = ''
|
|
||||||
output.on('data', (chunk) => (result += chunk))
|
|
||||||
output.on('end', () => {
|
|
||||||
expect(result).toBe(data)
|
|
||||||
expect(result).toContain('id="a"')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('option - verbose', async () => {
|
|
||||||
hexo.config.minify.svg.verbose = true
|
|
||||||
hexo.log.log = jest.fn()
|
|
||||||
await s()
|
|
||||||
|
|
||||||
expect(hexo.log.log.mock.calls[0][0]).toContain(`svg: ${path}`)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('option - plugins - invalid', async () => {
|
|
||||||
hexo.config.minify.svg.plugins = 'invalid'
|
|
||||||
await s()
|
|
||||||
const { data } = svgOptimize(input, { plugins })
|
|
||||||
|
|
||||||
const output = hexo.route.get(path)
|
|
||||||
let result = ''
|
|
||||||
output.on('data', (chunk) => (result += chunk))
|
|
||||||
output.on('end', () => {
|
|
||||||
expect(result).toBe(data)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('invalid svg', async () => {
|
|
||||||
const input = '{}'
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
|
|
||||||
let expected
|
|
||||||
try {
|
|
||||||
svgOptimize(input, { plugins })
|
|
||||||
} catch (err) {
|
|
||||||
expected = err
|
|
||||||
}
|
|
||||||
expect(expected).toBeDefined()
|
|
||||||
await expect(s()).rejects.toThrow(`Path: ${path}\n${expected}`)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - exclude *.min.svg by default', async () => {
|
|
||||||
const path = 'foo.min.svg'
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
await s()
|
|
||||||
|
|
||||||
const output = hexo.route.get(path)
|
|
||||||
let result = ''
|
|
||||||
output.on('data', (chunk) => (result += chunk))
|
|
||||||
output.on('end', () => {
|
|
||||||
expect(result).toBe(input)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - basename', async () => {
|
|
||||||
hexo.config.minify.svg.include = 'bar.svg'
|
|
||||||
const path = 'foo/bar.svg'
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
await s()
|
|
||||||
const { data } = svgOptimize(input, { plugins })
|
|
||||||
|
|
||||||
const output = hexo.route.get(path)
|
|
||||||
let result = ''
|
|
||||||
output.on('data', (chunk) => (result += chunk))
|
|
||||||
output.on('end', () => {
|
|
||||||
expect(result).toBe(data)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - slash in pattern', async () => {
|
|
||||||
hexo.config.minify.svg.include = '**/lectus/**/*.svg'
|
|
||||||
const path = 'eleifend/lectus/nullam/dapibus/netus.svg'
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
await s()
|
|
||||||
const { data } = svgOptimize(input, { plugins })
|
|
||||||
|
|
||||||
const output = hexo.route.get(path)
|
|
||||||
let result = ''
|
|
||||||
output.on('data', (chunk) => (result += chunk))
|
|
||||||
output.on('end', () => {
|
|
||||||
expect(result).toBe(data)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - basename + slash', async () => {
|
|
||||||
hexo.route.remove(path)
|
|
||||||
|
|
||||||
const paths = [
|
|
||||||
'lorem/ipsum/dolor.svg',
|
|
||||||
'gravida/sociis/erat/ante.svg',
|
|
||||||
'aptent/elementum.svg',
|
|
||||||
'felis/blandit/cursus.svg'
|
|
||||||
]
|
|
||||||
hexo.config.minify.svg.include = [
|
|
||||||
'dolor.svg',
|
|
||||||
'**/sociis/**/*.svg'
|
|
||||||
]
|
|
||||||
|
|
||||||
paths.forEach((inpath) => {
|
|
||||||
hexo.route.set(inpath, input)
|
|
||||||
})
|
|
||||||
await s()
|
|
||||||
const { data } = svgOptimize(input, { plugins })
|
|
||||||
|
|
||||||
const minPaths = paths.slice(0, 2)
|
|
||||||
const unminPaths = paths.slice(2)
|
|
||||||
|
|
||||||
minPaths.forEach((inpath) => {
|
|
||||||
const output = hexo.route.get(inpath)
|
|
||||||
let result = ''
|
|
||||||
output.on('data', (chunk) => (result += chunk))
|
|
||||||
output.on('end', () => {
|
|
||||||
expect(result).toBe(data)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
unminPaths.forEach((inpath) => {
|
|
||||||
const output = hexo.route.get(inpath)
|
|
||||||
let result = ''
|
|
||||||
output.on('data', (chunk) => (result += chunk))
|
|
||||||
output.on('end', () => {
|
|
||||||
expect(result).toBe(input)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - reverse pattern + basename disabled', async () => {
|
|
||||||
hexo.route.remove(path)
|
|
||||||
|
|
||||||
const paths = [
|
|
||||||
'lorem/ipsum/dolor.svg',
|
|
||||||
'gravida/sociis/erat/ante.svg',
|
|
||||||
'aptent/elementum.svg',
|
|
||||||
'felis/blandit/cursus.svg'
|
|
||||||
]
|
|
||||||
hexo.config.minify.svg.include = [
|
|
||||||
'!dolor.svg'
|
|
||||||
]
|
|
||||||
hexo.config.minify.svg.globOptions = {
|
|
||||||
basename: false
|
|
||||||
}
|
|
||||||
|
|
||||||
paths.forEach((inpath) => {
|
|
||||||
hexo.route.set(inpath, input)
|
|
||||||
})
|
|
||||||
await s()
|
|
||||||
const { data } = svgOptimize(input, { plugins })
|
|
||||||
|
|
||||||
paths.forEach((inpath) => {
|
|
||||||
const output = hexo.route.get(inpath)
|
|
||||||
let result = ''
|
|
||||||
output.on('data', (chunk) => (result += chunk))
|
|
||||||
output.on('end', () => {
|
|
||||||
expect(result).toBe(data)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - empty route', async () => {
|
|
||||||
hexo.route.remove(path)
|
|
||||||
|
|
||||||
const result = await s()
|
|
||||||
expect(result.length).toBe(0)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
213
test/xml.test.js
213
test/xml.test.js
|
|
@ -1,213 +0,0 @@
|
||||||
/* eslint-env jest */
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
const Hexo = require('hexo')
|
|
||||||
|
|
||||||
describe('xml', () => {
|
|
||||||
const hexo = new Hexo(__dirname)
|
|
||||||
const x = require('../lib/filter').minifyXml.bind(hexo)
|
|
||||||
const path = 'foo.xml'
|
|
||||||
const input = '<?xml version="1.0" encoding="utf-8"?>\n<feed xmlns="http://www.w3.org/2005/Atom">\n <!-- foo bar -->\n <title>foo</title>\n</feed>'
|
|
||||||
const expected = '<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title>foo</title></feed>'
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
hexo.config.minify = {
|
|
||||||
xml: {
|
|
||||||
enable: false,
|
|
||||||
verbose: false,
|
|
||||||
include: ['*.xml', '!*.min.xml'],
|
|
||||||
removeComments: true,
|
|
||||||
globOptions: { basename: true }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// plugin is disabled by default
|
|
||||||
hexo.config.minify.xml.enable = true
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
})
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
const routeList = hexo.route.list()
|
|
||||||
routeList.forEach((path) => hexo.route.remove(path))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('default', async () => {
|
|
||||||
await x()
|
|
||||||
|
|
||||||
const output = hexo.route.get(path)
|
|
||||||
let result = ''
|
|
||||||
output.on('data', (chunk) => (result += chunk))
|
|
||||||
output.on('end', () => {
|
|
||||||
expect(result).toBe(expected)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('disable', async () => {
|
|
||||||
hexo.config.minify.xml.enable = false
|
|
||||||
const result = await x()
|
|
||||||
|
|
||||||
expect(result).toBeUndefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('option - removeComments', async () => {
|
|
||||||
hexo.config.minify.xml.removeComments = false
|
|
||||||
|
|
||||||
await x()
|
|
||||||
|
|
||||||
const output = hexo.route.get(path)
|
|
||||||
let result = ''
|
|
||||||
output.on('data', (chunk) => (result += chunk))
|
|
||||||
output.on('end', () => {
|
|
||||||
expect(result).toContain('<!-- foo bar -->')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('option - verbose', async () => {
|
|
||||||
hexo.config.minify.xml.verbose = true
|
|
||||||
hexo.log.log = jest.fn()
|
|
||||||
await x()
|
|
||||||
|
|
||||||
expect(hexo.log.log.mock.calls[0][0]).toContain(`xml: ${path}`)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('empty file', async () => {
|
|
||||||
hexo.route.set(path, '')
|
|
||||||
const result = await x()
|
|
||||||
|
|
||||||
expect(result).toBeDefined()
|
|
||||||
expect(result[0]).toBeUndefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - exclude *.min.xml by default', async () => {
|
|
||||||
const path = 'foo.min.xml'
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
await x()
|
|
||||||
|
|
||||||
const output = hexo.route.get(path)
|
|
||||||
let result = ''
|
|
||||||
output.on('data', (chunk) => (result += chunk))
|
|
||||||
output.on('end', () => {
|
|
||||||
expect(result).toBe(input)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - basename', async () => {
|
|
||||||
hexo.config.minify.xml.include = 'bar.xml'
|
|
||||||
const path = 'foo/bar.xml'
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
await x()
|
|
||||||
|
|
||||||
const output = hexo.route.get(path)
|
|
||||||
let result = ''
|
|
||||||
output.on('data', (chunk) => (result += chunk))
|
|
||||||
output.on('end', () => {
|
|
||||||
expect(result).toBe(expected)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - slash in pattern', async () => {
|
|
||||||
hexo.config.minify.xml.include = '**/lectus/**/*.xml'
|
|
||||||
const path = 'eleifend/lectus/nullam/dapibus/netus.xml'
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
await x()
|
|
||||||
|
|
||||||
const output = hexo.route.get(path)
|
|
||||||
let result = ''
|
|
||||||
output.on('data', (chunk) => (result += chunk))
|
|
||||||
output.on('end', () => {
|
|
||||||
expect(result).toBe(expected)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - basename + slash', async () => {
|
|
||||||
hexo.route.remove(path)
|
|
||||||
|
|
||||||
const paths = [
|
|
||||||
'lorem/ipsum/dolor.xml',
|
|
||||||
'gravida/sociis/erat/ante.xml',
|
|
||||||
'aptent/elementum.xml',
|
|
||||||
'felis/blandit/cursus.xml'
|
|
||||||
]
|
|
||||||
hexo.config.minify.xml.include = [
|
|
||||||
'dolor.xml',
|
|
||||||
'**/sociis/**/*.xml'
|
|
||||||
]
|
|
||||||
|
|
||||||
paths.forEach((inpath) => {
|
|
||||||
hexo.route.set(inpath, input)
|
|
||||||
})
|
|
||||||
await x()
|
|
||||||
|
|
||||||
const minPaths = paths.slice(0, 2)
|
|
||||||
const unminPaths = paths.slice(2)
|
|
||||||
|
|
||||||
minPaths.forEach((inpath) => {
|
|
||||||
const output = hexo.route.get(inpath)
|
|
||||||
let result = ''
|
|
||||||
output.on('data', (chunk) => (result += chunk))
|
|
||||||
output.on('end', () => {
|
|
||||||
expect(result).toBe(expected)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
unminPaths.forEach((inpath) => {
|
|
||||||
const output = hexo.route.get(inpath)
|
|
||||||
let result = ''
|
|
||||||
output.on('data', (chunk) => (result += chunk))
|
|
||||||
output.on('end', () => {
|
|
||||||
expect(result).toBe(input)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - reverse pattern + basename disabled', async () => {
|
|
||||||
hexo.route.remove(path)
|
|
||||||
|
|
||||||
const paths = [
|
|
||||||
'lorem/ipsum/dolor.xml',
|
|
||||||
'gravida/sociis/erat/ante.xml',
|
|
||||||
'aptent/elementum.xml',
|
|
||||||
'felis/blandit/cursus.xml'
|
|
||||||
]
|
|
||||||
hexo.config.minify.xml.include = [
|
|
||||||
'!dolor.xml'
|
|
||||||
]
|
|
||||||
hexo.config.minify.xml.globOptions = {
|
|
||||||
basename: false
|
|
||||||
}
|
|
||||||
|
|
||||||
paths.forEach((inpath) => {
|
|
||||||
hexo.route.set(inpath, input)
|
|
||||||
})
|
|
||||||
await x()
|
|
||||||
|
|
||||||
paths.forEach((inpath) => {
|
|
||||||
const output = hexo.route.get(inpath)
|
|
||||||
let result = ''
|
|
||||||
output.on('data', (chunk) => (result += chunk))
|
|
||||||
output.on('end', () => {
|
|
||||||
expect(result).toBe(expected)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - empty route', async () => {
|
|
||||||
hexo.route.remove(path)
|
|
||||||
|
|
||||||
const result = await x()
|
|
||||||
expect(result.length).toBe(0)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('avoid processing CDATA', async () => {
|
|
||||||
const input = '<foo><![CDATA[<p>lorem</p>\n<p>ipsum</p>]]></foo>'
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
|
|
||||||
await x()
|
|
||||||
|
|
||||||
const output = hexo.route.get(path)
|
|
||||||
let result = ''
|
|
||||||
output.on('data', (chunk) => (result += chunk))
|
|
||||||
output.on('end', () => {
|
|
||||||
expect(result).toBe(input)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
@ -1,256 +0,0 @@
|
||||||
/* eslint-env jest */
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
const Hexo = require('hexo')
|
|
||||||
const { compress: zstd, decompress: unzstd } = require('@mongodb-js/zstd')
|
|
||||||
|
|
||||||
describe('zstd', () => {
|
|
||||||
const hexo = new Hexo(__dirname)
|
|
||||||
const z = require('../lib/filter').zstdFn.bind(hexo)
|
|
||||||
const path = 'foo.txt'
|
|
||||||
const input = 'Lorem ipsum dolor sit amet consectetur adipiscing elit fusce'
|
|
||||||
const inputBuf = Buffer.from(input, 'utf8')
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
hexo.config.minify = {
|
|
||||||
zstd: {
|
|
||||||
enable: true,
|
|
||||||
verbose: false,
|
|
||||||
include: ['*.html', '*.css', '*.js', '*.txt', '*.ttf', '*.atom', '*.stl', '*.xml', '*.svg', '*.eot', '*.json'],
|
|
||||||
globOptions: { basename: true }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
})
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
const routeList = hexo.route.list()
|
|
||||||
routeList.forEach((path) => hexo.route.remove(path))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('default', async () => {
|
|
||||||
await z()
|
|
||||||
|
|
||||||
const output = hexo.route.get(path.concat('.zst'))
|
|
||||||
const buf = []
|
|
||||||
output.on('data', (chunk) => (buf.push(chunk)))
|
|
||||||
output.on('end', async () => {
|
|
||||||
const result = Buffer.concat(buf)
|
|
||||||
const expected = await zstd(inputBuf)
|
|
||||||
const resultUnzst = await unzstd(result)
|
|
||||||
const expectedUnzst = await unzstd(expected)
|
|
||||||
|
|
||||||
expect(result.equals(expected)).toBe(true)
|
|
||||||
expect(resultUnzst.toString()).toBe(input)
|
|
||||||
expect(expectedUnzst.toString()).toBe(input)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('disable', async () => {
|
|
||||||
hexo.config.minify.zstd.enable = false
|
|
||||||
const result = await z()
|
|
||||||
|
|
||||||
expect(result).toBeUndefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('empty file', async () => {
|
|
||||||
hexo.route.set(path, '')
|
|
||||||
|
|
||||||
const routeList = hexo.route.list()
|
|
||||||
expect(routeList).not.toContain(path.concat('.zst'))
|
|
||||||
|
|
||||||
const result = await z()
|
|
||||||
expect(result).toBeDefined()
|
|
||||||
expect(result[0]).toBeUndefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('option', async () => {
|
|
||||||
const level = 1
|
|
||||||
hexo.config.minify.zstd.level = level
|
|
||||||
await z()
|
|
||||||
|
|
||||||
const output = hexo.route.get(path.concat('.zst'))
|
|
||||||
const buf = []
|
|
||||||
output.on('data', (chunk) => (buf.push(chunk)))
|
|
||||||
output.on('end', async () => {
|
|
||||||
const result = Buffer.concat(buf)
|
|
||||||
const expected = await zstd(inputBuf, level)
|
|
||||||
|
|
||||||
expect(result.equals(expected)).toBe(true)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('option - verbose', async () => {
|
|
||||||
hexo.config.minify.zstd.verbose = true
|
|
||||||
hexo.log.log = jest.fn()
|
|
||||||
await z()
|
|
||||||
|
|
||||||
expect(hexo.log.log.mock.calls[0][0]).toContain(`zstd: ${path}`)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('option - level is string', async () => {
|
|
||||||
const level = 'foo'
|
|
||||||
hexo.config.minify.zstd.level = level
|
|
||||||
await z()
|
|
||||||
|
|
||||||
const output = hexo.route.get(path.concat('.zst'))
|
|
||||||
const buf = []
|
|
||||||
output.on('data', (chunk) => (buf.push(chunk)))
|
|
||||||
output.on('end', async () => {
|
|
||||||
const result = Buffer.concat(buf)
|
|
||||||
const expected = await zstd(inputBuf, undefined)
|
|
||||||
|
|
||||||
expect(result.equals(expected)).toBe(true)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - exclude non-text file by default', async () => {
|
|
||||||
const path = 'foo.jpg'
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
await z()
|
|
||||||
|
|
||||||
const result = hexo.route.get(path.concat('.zst'))
|
|
||||||
|
|
||||||
expect(result).toBeUndefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - basename', async () => {
|
|
||||||
hexo.config.minify.zstd.include = 'bar.txt'
|
|
||||||
const path = 'foo/bar.txt'
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
await z()
|
|
||||||
|
|
||||||
const result = hexo.route.get(path.concat('.zst'))
|
|
||||||
|
|
||||||
expect(result).toBeDefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - slash in pattern', async () => {
|
|
||||||
hexo.config.minify.zstd.include = '**/lectus/**/*.txt'
|
|
||||||
const path = 'eleifend/lectus/nullam/dapibus/netus.txt'
|
|
||||||
hexo.route.set(path, input)
|
|
||||||
await z()
|
|
||||||
|
|
||||||
const result = hexo.route.get(path.concat('.zst'))
|
|
||||||
|
|
||||||
expect(result).toBeDefined()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - basename + slash + basename enabled', async () => {
|
|
||||||
hexo.route.remove(path)
|
|
||||||
|
|
||||||
const paths = [
|
|
||||||
'lorem/ipsum/dolor.html',
|
|
||||||
'gravida/sociis/erat/ante.css',
|
|
||||||
'aptent/elementum.js',
|
|
||||||
'felis/blandit/cursus.svg'
|
|
||||||
]
|
|
||||||
hexo.config.minify.zstd.include = [
|
|
||||||
'*.html',
|
|
||||||
'**/sociis/**/*.css'
|
|
||||||
]
|
|
||||||
|
|
||||||
paths.forEach((inpath) => {
|
|
||||||
hexo.route.set(inpath, input)
|
|
||||||
})
|
|
||||||
await z()
|
|
||||||
|
|
||||||
const routeList = hexo.route.list()
|
|
||||||
const expected = [
|
|
||||||
'lorem/ipsum/dolor.html.zst',
|
|
||||||
'gravida/sociis/erat/ante.css.zst'
|
|
||||||
]
|
|
||||||
const notExpected = [
|
|
||||||
'aptent/elementum.js.zst',
|
|
||||||
'felis/blandit/cursus.svg.zst'
|
|
||||||
]
|
|
||||||
|
|
||||||
expect(routeList).toEqual(expect.arrayContaining(expected))
|
|
||||||
expect(routeList).toEqual(expect.not.arrayContaining(notExpected))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - basename + slash + basename disabled', async () => {
|
|
||||||
hexo.route.remove(path)
|
|
||||||
|
|
||||||
const paths = [
|
|
||||||
'lorem/ipsum/dolor.html',
|
|
||||||
'gravida/sociis/erat/ante.css',
|
|
||||||
'aptent/elementum.js',
|
|
||||||
'felis/blandit/cursus.svg'
|
|
||||||
]
|
|
||||||
hexo.config.minify.zstd.include = [
|
|
||||||
'*.html',
|
|
||||||
'**/sociis/**/*.css'
|
|
||||||
]
|
|
||||||
hexo.config.minify.zstd.globOptions = {
|
|
||||||
basename: false
|
|
||||||
}
|
|
||||||
|
|
||||||
paths.forEach((inpath) => {
|
|
||||||
hexo.route.set(inpath, input)
|
|
||||||
})
|
|
||||||
await z()
|
|
||||||
|
|
||||||
const routeList = hexo.route.list()
|
|
||||||
const expected = [
|
|
||||||
'gravida/sociis/erat/ante.css.zst'
|
|
||||||
]
|
|
||||||
const notExpected = [
|
|
||||||
'lorem/ipsum/dolor.html.zst',
|
|
||||||
'aptent/elementum.js.zst',
|
|
||||||
'felis/blandit/cursus.svg.zst'
|
|
||||||
]
|
|
||||||
|
|
||||||
expect(routeList).toEqual(expect.arrayContaining(expected))
|
|
||||||
expect(routeList).toEqual(expect.not.arrayContaining(notExpected))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('include - reverse pattern + basename disabled', async () => {
|
|
||||||
hexo.route.remove(path)
|
|
||||||
|
|
||||||
const paths = [
|
|
||||||
'lorem/ipsum/dolor.html',
|
|
||||||
'gravida/sociis/erat/ante.css',
|
|
||||||
'aptent/elementum.js',
|
|
||||||
'felis/blandit/cursus.svg'
|
|
||||||
]
|
|
||||||
hexo.config.minify.zstd.include = [
|
|
||||||
'!dolor.html'
|
|
||||||
]
|
|
||||||
hexo.config.minify.zstd.globOptions = {
|
|
||||||
basename: false
|
|
||||||
}
|
|
||||||
|
|
||||||
paths.forEach((inpath) => {
|
|
||||||
hexo.route.set(inpath, input)
|
|
||||||
})
|
|
||||||
await z()
|
|
||||||
|
|
||||||
const routeList = hexo.route.list()
|
|
||||||
const expected = paths.map((path) => path.concat('.zst'))
|
|
||||||
|
|
||||||
expect(routeList).toEqual(expect.arrayContaining(expected))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('blns', async () => {
|
|
||||||
const blns = require('./fixtures/blns.json')
|
|
||||||
|
|
||||||
for (const nStr of blns) {
|
|
||||||
hexo.route.remove(path)
|
|
||||||
|
|
||||||
hexo.route.set(path, nStr)
|
|
||||||
|
|
||||||
await z()
|
|
||||||
|
|
||||||
const output = hexo.route.get(path.concat('.zst'))
|
|
||||||
const buf = []
|
|
||||||
output.on('data', (chunk) => (buf.push(chunk)))
|
|
||||||
output.on('end', async () => {
|
|
||||||
const result = Buffer.concat(buf)
|
|
||||||
const resultUnzst = await unzstd(result)
|
|
||||||
|
|
||||||
expect(resultUnzst.toString()).toBe(nStr)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
Loading…
Reference in New Issue