feat: Native emoji w/ image-based fallbacks and improved parsing (#1746)

* Render native emoji with image fallback

Fix #779

* Deprecate emoji plugin

* Add emoji tests

* Remove console.log statement

* Fix emoji image alt attribute

* Set nativeEmoji to false by default (non-breaking)

* Fix parsing emoji in HTML comments and script tags

* Add nativeEmoji and update noEmoji details

* Add Emoji plugin deprecation notice

* Fix ESLint issues

* Create build:emoji task

- Auto-generate emoji data from GitHub API
- Auto-generate emoji markdown for website
- Add emoji page to navigation

* Fix rendering of GitHub emoji without unicode

* Adjust and match size of native and image emoji

* Update emoji test snapshot

* Update docs test snapshot

* Fix ci/codesandbox error

* Update native emoji font-stack

* Fix rendering of native multi-character emoji

* Kick GitHub Workflow

* Replace rollup’s uglify plugin with terser

* Switch “npm ci” instead of “npm i” for stability

* Change emoji data from default to named export

* Revert "Replace rollup’s uglify plugin with terser"

This reverts commit 7ba8513636.

* Revert "Switch “npm ci” instead of “npm i” for stability"

This reverts commit d52b476a38.

* Revert "Change emoji data from default to named export"

This reverts commit 3f2dd467cf.

* Specify codesandbox template and node version

* Update codesandbox config

* Revert "Revert "Replace rollup’s uglify plugin with terser""

This reverts commit e06fed49f0.

* Revert "Revert "Revert "Replace rollup’s uglify plugin with terser"""

This reverts commit 27d49521f6.

* Update codesandbox config

* Revert "Update codesandbox config"

This reverts commit 5120dd23d4.

* Fix codesandbox uglify error

* Emoji docs tweaks

* Restore and update emoji plugin code

* Restore and update emoji plugin docs

* Prettier updates

* Match lowercase shortcodes only

Co-authored-by: Koy Zhuang <369491420@qq.com>
This commit is contained in:
John Hildenbiddle 2022-03-05 22:25:09 -06:00 committed by GitHub
parent fd883e62de
commit 35002c92b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 6092 additions and 1956 deletions

View File

@ -1,4 +1,5 @@
{
"sandboxes": ["2d17z"],
"packages": [".", "packages/docsify-server-renderer"]
"packages": [".", "packages/docsify-server-renderer"],
"node": "16"
}

91
build/emoji.js Normal file
View File

@ -0,0 +1,91 @@
const axios = require('axios');
const fs = require('fs');
const path = require('path');
const filePaths = {
emojiMarkdown: path.resolve(process.cwd(), 'docs', 'emoji.md'),
emojiJS: path.resolve(
process.cwd(),
'src',
'core',
'render',
'emojify-data.js'
),
};
async function getEmojiData() {
const emojiDataURL = 'https://api.github.com/emojis';
const response = await axios.get(emojiDataURL);
const baseURL = Object.values(response.data)
.find(url => /unicode\//)
.split('unicode/')[0];
const data = { ...response.data };
// Remove base URL from emoji URLs
Object.entries(data).forEach(
([key, value]) => (data[key] = value.replace(baseURL, ''))
);
return {
baseURL,
data,
};
}
function writeEmojiPage(emojiData) {
const emojiPage =
(fs.existsSync(filePaths.emojiMarkdown) &&
fs.readFileSync(filePaths.emojiMarkdown, 'utf8')) ||
`<!-- START -->\n\n<!-- END -->`;
const emojiRegEx = /(<!--\s*START.*-->\n)([\s\S]*)(\n<!--\s*END.*-->)/;
const emojiMatch = emojiPage.match(emojiRegEx);
const emojiMarkdownStart = emojiMatch[1].trim();
const emojiMarkdown = emojiMatch[2].trim();
const emojiMarkdownEnd = emojiMatch[3].trim();
const newEmojiMarkdown = Object.keys(emojiData.data)
.reduce(
(preVal, curVal) =>
(preVal += `:${curVal}: ` + '`' + `:${curVal}:` + '`' + '\n\n'),
''
)
.trim();
if (emojiMarkdown !== newEmojiMarkdown) {
const newEmojiPage = emojiPage.replace(
emojiMatch[0],
`${emojiMarkdownStart}\n${newEmojiMarkdown}\n${emojiMarkdownEnd}`
);
fs.writeFileSync(filePaths.emojiMarkdown, newEmojiPage);
console.info(`- Created new file: ${filePaths.emojiMarkdown}`);
} else {
console.info(`- No changes to file: ${filePaths.emojiMarkdown}`);
}
}
function writeEmojiJS(emojiData) {
const emojiJS =
fs.existsSync(filePaths.emojiJS) &&
fs.readFileSync(filePaths.emojiJS, 'utf8');
const newEmojiJS = `export default ${JSON.stringify(emojiData, {}, 2)}`;
if (!emojiJS || emojiJS !== newEmojiJS) {
fs.writeFileSync(filePaths.emojiJS, newEmojiJS);
console.info(`- Created new file: ${filePaths.emojiJS}`);
} else {
console.info(`- No changes to file: ${filePaths.emojiJS}`);
}
}
(async () => {
console.log('Build emoji');
try {
const emojiData = await getEmojiData();
writeEmojiPage(emojiData);
writeEmojiJS(emojiData);
} catch (e) {
console.error(e);
}
})();

View File

@ -13,6 +13,7 @@
- [Write a Plugin](write-a-plugin.md)
- [Markdown configuration](markdown.md)
- [Language highlighting](language-highlight.md)
- [Emoji](emoji.md)
- Guide

View File

@ -16,7 +16,7 @@ The config can also be defined as a function, in which case the first argument i
```html
<script>
window.$docsify = function(vm) {
window.$docsify = function (vm) {
return {
markdown: {
renderer: {
@ -319,14 +319,14 @@ window.$docsify = {
markdown: {
smartypants: true,
renderer: {
link: function() {
link: function () {
// ...
},
},
},
// function
markdown: function(marked, renderer) {
markdown: function (marked, renderer) {
// ...
return marked;
},
@ -398,11 +398,65 @@ window.$docsify = {
Note that if you are running an external script, e.g. an embedded jsfiddle demo, make sure to include the [external-script](plugins.md?id=external-script) plugin.
## nativeEmoji
- type: `Boolean`
- default: `false`
Render emoji shorthand codes using GitHub-style emoji images or platform-native emoji characters.
```js
window.$docsify = {
nativeEmoji: true,
};
```
```markdown
:smile:
:partying_face:
:joy:
:+1:
:-1:
```
GitHub-style images when `false`:
<output data-lang="output">
<img class="emoji" src="https://github.githubassets.com/images/icons/emoji/unicode/1f604.png" alt="smile">
<img class="emoji" src="https://github.githubassets.com/images/icons/emoji/unicode/1f973.png" alt="partying_face">
<img class="emoji" src="https://github.githubassets.com/images/icons/emoji/unicode/1f602.png" alt="joy">
<img class="emoji" src="https://github.githubassets.com/images/icons/emoji/unicode/1f44d.png" alt="+1">
<img class="emoji" src="https://github.githubassets.com/images/icons/emoji/unicode/1f44e.png" alt="-1">
</output>
Platform-native characters when `true`:
<output data-lang="output">
<span class="emoji">😄︎</span>
<span class="emoji">🥳︎</span>
<span class="emoji">😂︎</span>
<span class="emoji">👍︎</span>
<span class="emoji">👎︎</span>
</output>
To render shorthand codes as text, replace `:` characters with the `&colon;` HTML entity.
```markdown
&colon;100&colon;
```
<output data-lang="output">
&colon;100&colon;
</output>
## noEmoji
- type: `Boolean`
- default: `false`
Disabled emoji parse.
Disabled emoji parsing and render all emoji shorthand as text.
```js
window.$docsify = {
@ -410,7 +464,31 @@ window.$docsify = {
};
```
?> If this option is `false` but you don't want to emojify some specific colons, [refer to this](https://github.com/docsifyjs/docsify/issues/742#issuecomment-586313143)
```markdown
:100:
```
<output data-lang="output">
&colon;100&colon;
</output>
To disable emoji parsing of individual shorthand codes, replace `:` characters with the `&colon;` HTML entity.
```markdown
:100:
&colon;100&colon;
```
<output data-lang="output">
:100:
&colon;100&colon;
</output>
## mergeNavbar
@ -435,7 +513,7 @@ See https://github.com/lukeed/tinydate#patterns
window.$docsify = {
formatUpdated: '{MM}/{DD} {HH}:{mm}',
formatUpdated: function(time) {
formatUpdated: function (time) {
// ...
return time;

3759
docs/emoji.md Normal file

File diff suppressed because it is too large Load Diff

View File

@ -4,12 +4,13 @@
By default, the hyperlink on the current page is recognized and the content is saved in `localStorage`. You can also specify the path to the files.
<!-- prettier-ignore -->
```html
<script>
window.$docsify = {
search: 'auto', // default
search : [
search: [
'/', // => /README.md
'/guide', // => /guide.md
'/get-started', // => /get-started.md
@ -25,7 +26,7 @@ By default, the hyperlink on the current page is recognized and the content is s
// Localization
placeholder: {
'/zh-cn/': '搜索',
'/': 'Type to search'
'/': 'Type to search',
},
noData: 'No Results!',
@ -33,7 +34,7 @@ By default, the hyperlink on the current page is recognized and the content is s
// Localization
noData: {
'/zh-cn/': '找不到结果',
'/': 'No Results'
'/': 'No Results',
},
// Headline depth, 1 - 6
@ -54,9 +55,9 @@ By default, the hyperlink on the current page is recognized and the content is s
// You can provide a regexp to match prefixes. In this case,
// the matching substring will be used to identify the index
pathNamespaces: /^(\/(zh-cn|ru-ru))?(\/(v1|v2))?/
}
}
pathNamespaces: /^(\/(zh-cn|ru-ru))?(\/(v1|v2))?/,
},
};
</script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/docsify.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/search.min.js"></script>
@ -75,8 +76,8 @@ Install the plugin and configure the track id.
```html
<script>
window.$docsify = {
ga: 'UA-XXXXX-Y'
}
ga: 'UA-XXXXX-Y',
};
</script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/docsify.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/ga.min.js"></script>
@ -84,21 +85,22 @@ Install the plugin and configure the track id.
Configure by `data-ga`.
<!-- prettier-ignore -->
```html
<script src="//cdn.jsdelivr.net/npm/docsify/lib/docsify.min.js" data-ga="UA-XXXXX-Y"></script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/ga.min.js"></script>
```
## emoji
## Emoji
The default is to support parsing emoji. For example `:100:` will be parsed to :100:. But it is not precise because there is no matching non-emoji string. If you need to correctly parse the emoji string, you need install this plugin.
Renders a larger collection of emoji shorthand codes. Without this plugin, Docsify is able to render only a limited number of emoji shorthand codes.
!> Deprecated as of v4.13. Docsify no longer requires this plugin for full emoji support.
```html
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/emoji.min.js"></script>
```
?> If you don't want to parse to emoji, you can use __colon_<span>_</span> or `&#58;`. If you need to use in the title, we recommend using `&#58;`. For example, `&#58;100:`
## External Script
If the script on the page is an external one (imports a js file via `src` attribute), you'll need this plugin to make it work.
@ -118,7 +120,7 @@ Medium's image zoom. Based on [medium-zoom](https://github.com/francoischalifour
Exclude the special image
```markdown
![](image.png ":no-zoom")
![](image.png ':no-zoom')
```
## Edit on github
@ -150,8 +152,8 @@ Disqus comments. https://disqus.com/
```html
<script>
window.$docsify = {
disqus: 'shortname'
}
disqus: 'shortname',
};
</script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/disqus.min.js"></script>
```
@ -161,7 +163,7 @@ Disqus comments. https://disqus.com/
[Gitalk](https://github.com/gitalk/gitalk) is a modern comment component based on Github Issue and Preact.
```html
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/gitalk/dist/gitalk.css">
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/gitalk/dist/gitalk.css" />
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/gitalk.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/gitalk/dist/gitalk.min.js"></script>
@ -171,10 +173,12 @@ Disqus comments. https://disqus.com/
clientSecret: 'Github Application Client Secret',
repo: 'Github repo',
owner: 'Github repo owner',
admin: ['Github repo collaborators, only these guys can initialize github issues'],
admin: [
'Github repo collaborators, only these guys can initialize github issues',
],
// facebook-like distraction free mode
distractionFreeMode: false
})
distractionFreeMode: false,
});
</script>
```

View File

@ -18,9 +18,9 @@ docsify init ./docs
After the `init` is complete, you can see the file list in the `./docs` subdirectory.
* `index.html` as the entry file
* `README.md` as the home page
* `.nojekyll` prevents GitHub Pages from ignoring files that begin with an underscore
- `index.html` as the entry file
- `README.md` as the home page
- `.nojekyll` prevents GitHub Pages from ignoring files that begin with an underscore
You can easily update the documentation in `./docs/README.md`, of course you can add [more pages](more-pages.md).
@ -43,21 +43,24 @@ If you don't like `npm` or have trouble installing the tool, you can manually cr
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta charset="UTF-8">
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@4/themes/vue.css" />
</head>
<body>
<div id="app"></div>
<script>
window.$docsify = {
//...
}
</script>
<script src="//cdn.jsdelivr.net/npm/docsify@4"></script>
</body>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<meta charset="UTF-8" />
<link
rel="stylesheet"
href="//cdn.jsdelivr.net/npm/docsify@4/themes/vue.css"
/>
</head>
<body>
<div id="app"></div>
<script>
window.$docsify = {
//...
};
</script>
<script src="//cdn.jsdelivr.net/npm/docsify@4"></script>
</body>
</html>
```
@ -75,7 +78,10 @@ Specifying a major version in the URL (`@4`) will allow your site will receive n
If you prefer to lock docsify to a specific version, specify the full version after the `@` symbol in the URL. This is the safest way to ensure your site will look and behave the same way regardless of any changes made to future versions of docsify.
```html
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@4.11.4/themes/vue.css">
<link
rel="stylesheet"
href="//cdn.jsdelivr.net/npm/docsify@4.11.4/themes/vue.css"
/>
<script src="//cdn.jsdelivr.net/npm/docsify@4.11.4"></script>
```
@ -86,6 +92,7 @@ If you have Python installed on your system, you can easily use it to run a stat
```python2
cd docs && python -m SimpleHTTPServer 3000
```
```python3
cd docs && python -m http.server 3000
```
@ -107,11 +114,11 @@ You should set the `data-app` attribute if you changed `el`:
<div data-app id="main">Please wait...</div>
<script>
window.$docsify = {
el: '#main'
}
</script>
<script>
window.$docsify = {
el: '#main',
};
</script>
```
Compare [el configuration](configuration.md#el).

View File

@ -24,6 +24,7 @@
"build:cover": "node build/cover.js",
"build:css:min": "mkdirp lib/themes && npm run css -- -o lib/themes && node build/mincss.js",
"build:css": "mkdirp themes && npm run css -- -o themes",
"build:emoji": "node ./build/emoji.js && eslint ./src/core/render/emojify-data.js --fix --quiet",
"build:js": "cross-env NODE_ENV=production node build/build.js",
"build:ssr": "node build/ssr.js",
"build:test": "npm run build && npm test",

4
sandbox.config.json Normal file
View File

@ -0,0 +1,4 @@
{
"template": "node",
"node": "16"
}

View File

@ -21,6 +21,7 @@ export default function (vm) {
nameLink: window.location.pathname,
autoHeader: false,
executeScript: null,
nativeEmoji: false,
noEmoji: false,
ga: '',
ext: '.md',

View File

@ -104,7 +104,7 @@ export class Compiler {
html = compile.parser(text);
}
html = config.noEmoji ? html : emojify(html);
html = config.noEmoji ? html : emojify(html, config.nativeEmoji);
slugify.clear();
return html;

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,45 @@
import { inBrowser } from '../util/env';
import emojiData from './emoji-data.js';
function replace(m, $1) {
function replaceEmojiShorthand(m, $1, useNativeEmoji) {
const emojiMatch = emojiData.data[$1];
let result = m;
if (emojiMatch) {
if (useNativeEmoji && /unicode/.test(emojiMatch)) {
const emojiUnicode = emojiMatch
.replace('unicode/', '')
.replace(/\.png.*/, '')
.split('-')
.map(u => `&#x${u};`)
// Separate multi-character emoji with zero width joiner sequence (ZWJ)
// Hat tip: https://about.gitlab.com/blog/2018/05/30/journey-in-native-unicode-emoji/#emoji-made-up-of-multiple-characters
.join('&zwj;')
.concat('&#xFE0E;');
result = `<span class="emoji">${emojiUnicode}</span>`;
} else {
result = `<img src="${emojiData.baseURL}${emojiMatch}.png" alt="${$1}" class="emoji" loading="lazy">`;
}
}
return result;
}
export function emojify(text, useNativeEmoji) {
return (
'<img class="emoji" src="https://github.githubassets.com/images/icons/emoji/' +
$1 +
'.png" alt="' +
$1 +
'" />'
text
// Mark colons in tags
.replace(
/<(code|pre|script|template)[^>]*?>[\s\S]+?<\/(code|pre|script|template)>/g,
m => m.replace(/:/g, '__colon__')
)
// Mark colons in comments
.replace(/<!--[\s\S]+?-->/g, m => m.replace(/:/g, '__colon__'))
// Replace emoji shorthand codes
.replace(/:([a-z0-9_\-+]+?):/g, (m, $1) =>
replaceEmojiShorthand(m, $1, useNativeEmoji)
)
// Restore colons in tags and comments
.replace(/__colon__/g, ':')
);
}
export function emojify(text) {
return text
.replace(/<(pre|template|code)[^>]*?>[\s\S]+?<\/(pre|template|code)>/g, m =>
m.replace(/:/g, '__colon__')
)
.replace(/:([a-z0-9_\-+]+?):/g, (inBrowser && window.emojify) || replace)
.replace(/__colon__/g, ':');
}

File diff suppressed because it is too large Load Diff

View File

@ -21,8 +21,13 @@ div#app
&:empty::before
content 'Loading...'
.emoji
height 1.2rem
img.emoji
height 1.2em
vertical-align middle
span.emoji
font-family "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"
font-size 1.2em
vertical-align middle
.progress

View File

@ -7,6 +7,6 @@ exports[`Docs Site coverpage renders and is unchanged 1`] = `
<a href=\\"#/?id=docsify\\">Getting Started</a></p></div></section>"
`;
exports[`Docs Site navbar renders and is unchanged 1`] = `"<nav class=\\"app-nav no-badge\\"><ul><li>Translations<ul><li><a href=\\"#/\\" title=\\"undefined\\" class=\\"active\\"><img class=\\"emoji\\" src=\\"https://github.githubassets.com/images/icons/emoji/uk.png\\" alt=\\"uk\\"> English</a></li><li><a href=\\"#/zh-cn/\\" title=\\"undefined\\"><img class=\\"emoji\\" src=\\"https://github.githubassets.com/images/icons/emoji/cn.png\\" alt=\\"cn\\"> 中文</a></li><li><a href=\\"#/de-de/\\" title=\\"undefined\\"><img class=\\"emoji\\" src=\\"https://github.githubassets.com/images/icons/emoji/de.png\\" alt=\\"de\\"> Deutsch</a></li><li><a href=\\"#/es/\\" title=\\"undefined\\"><img class=\\"emoji\\" src=\\"https://github.githubassets.com/images/icons/emoji/es.png\\" alt=\\"es\\"> Español</a></li><li><a href=\\"#/ru-ru/\\" title=\\"undefined\\"><img class=\\"emoji\\" src=\\"https://github.githubassets.com/images/icons/emoji/ru.png\\" alt=\\"ru\\"> Русский</a></li></ul></li></ul></nav>"`;
exports[`Docs Site navbar renders and is unchanged 1`] = `"<nav class=\\"app-nav no-badge\\"><ul><li>Translations<ul><li><a href=\\"#/\\" title=\\"undefined\\" class=\\"active\\"><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f1ec-1f1e7.png?v8.png\\" alt=\\"uk\\" class=\\"emoji\\" loading=\\"lazy\\"> English</a></li><li><a href=\\"#/zh-cn/\\" title=\\"undefined\\"><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f1e8-1f1f3.png?v8.png\\" alt=\\"cn\\" class=\\"emoji\\" loading=\\"lazy\\"> 中文</a></li><li><a href=\\"#/de-de/\\" title=\\"undefined\\"><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f1e9-1f1ea.png?v8.png\\" alt=\\"de\\" class=\\"emoji\\" loading=\\"lazy\\"> Deutsch</a></li><li><a href=\\"#/es/\\" title=\\"undefined\\"><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f1ea-1f1f8.png?v8.png\\" alt=\\"es\\" class=\\"emoji\\" loading=\\"lazy\\"> Español</a></li><li><a href=\\"#/ru-ru/\\" title=\\"undefined\\"><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f1f7-1f1fa.png?v8.png\\" alt=\\"ru\\" class=\\"emoji\\" loading=\\"lazy\\"> Русский</a></li></ul></li></ul></nav>"`;
exports[`Docs Site sidebar renders and is unchanged 1`] = `"<aside class=\\"sidebar\\"><div class=\\"sidebar-nav\\"><ul><li><p>Getting started</p><ul><li><a href=\\"#/quickstart\\" title=\\"undefined\\">Quick start</a></li><li><a href=\\"#/more-pages\\" title=\\"undefined\\">Writing more pages</a></li><li><a href=\\"#/custom-navbar\\" title=\\"undefined\\">Custom navbar</a></li><li><a href=\\"#/cover\\" title=\\"undefined\\">Cover page</a></li></ul></li><li><p>Customization</p><ul><li><a href=\\"#/configuration\\" title=\\"undefined\\">Configuration</a></li><li><a href=\\"#/themes\\" title=\\"undefined\\">Themes</a></li><li><a href=\\"#/plugins\\" title=\\"undefined\\">List of Plugins</a></li><li><a href=\\"#/write-a-plugin\\" title=\\"undefined\\">Write a Plugin</a></li><li><a href=\\"#/markdown\\" title=\\"undefined\\">Markdown configuration</a></li><li><a href=\\"#/language-highlight\\" title=\\"undefined\\">Language highlighting</a></li></ul></li><li><p>Guide</p><ul><li><a href=\\"#/deploy\\" title=\\"undefined\\">Deploy</a></li><li><a href=\\"#/helpers\\" title=\\"undefined\\">Helpers</a></li><li><a href=\\"#/vue\\" title=\\"undefined\\">Vue compatibility</a></li><li><a href=\\"#/cdn\\" title=\\"undefined\\">CDN</a></li><li><a href=\\"#/pwa\\" title=\\"undefined\\">Offline Mode (PWA)</a></li><li><a href=\\"#/ssr\\" title=\\"undefined\\">Server-Side Rendering (SSR)</a></li><li><a href=\\"#/embed-files\\" title=\\"undefined\\">Embed Files</a></li></ul></li><li><p><a href=\\"#/awesome\\" title=\\"undefined\\">Awesome docsify</a></p></li><li><p><a href=\\"#/changelog\\" title=\\"undefined\\">Changelog</a></p></li></ul></div></aside>"`;
exports[`Docs Site sidebar renders and is unchanged 1`] = `"<aside class=\\"sidebar\\"><div class=\\"sidebar-nav\\"><ul><li><p>Getting started</p><ul><li><a href=\\"#/quickstart\\" title=\\"undefined\\">Quick start</a></li><li><a href=\\"#/more-pages\\" title=\\"undefined\\">Writing more pages</a></li><li><a href=\\"#/custom-navbar\\" title=\\"undefined\\">Custom navbar</a></li><li><a href=\\"#/cover\\" title=\\"undefined\\">Cover page</a></li></ul></li><li><p>Customization</p><ul><li><a href=\\"#/configuration\\" title=\\"undefined\\">Configuration</a></li><li><a href=\\"#/themes\\" title=\\"undefined\\">Themes</a></li><li><a href=\\"#/plugins\\" title=\\"undefined\\">List of Plugins</a></li><li><a href=\\"#/write-a-plugin\\" title=\\"undefined\\">Write a Plugin</a></li><li><a href=\\"#/markdown\\" title=\\"undefined\\">Markdown configuration</a></li><li><a href=\\"#/language-highlight\\" title=\\"undefined\\">Language highlighting</a></li><li><a href=\\"#/emoji\\" title=\\"undefined\\">Emoji</a></li></ul></li><li><p>Guide</p><ul><li><a href=\\"#/deploy\\" title=\\"undefined\\">Deploy</a></li><li><a href=\\"#/helpers\\" title=\\"undefined\\">Helpers</a></li><li><a href=\\"#/vue\\" title=\\"undefined\\">Vue compatibility</a></li><li><a href=\\"#/cdn\\" title=\\"undefined\\">CDN</a></li><li><a href=\\"#/pwa\\" title=\\"undefined\\">Offline Mode (PWA)</a></li><li><a href=\\"#/ssr\\" title=\\"undefined\\">Server-Side Rendering (SSR)</a></li><li><a href=\\"#/embed-files\\" title=\\"undefined\\">Embed Files</a></li></ul></li><li><p><a href=\\"#/awesome\\" title=\\"undefined\\">Awesome docsify</a></p></li><li><p><a href=\\"#/changelog\\" title=\\"undefined\\">Changelog</a></p></li></ul></div></aside>"`;

View File

@ -0,0 +1,23 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Emoji Ignores all emoji shorthand codes (noEmoji:true) 1`] = `"<p>:smile:</p><p>:smile::smile:</p><p>:smile: :smile:</p><p>:smile::smile::smile:</p><p>:smile: :smile: :smile:</p><p>text:smile:</p><p>:smile:text</p><p>text:smile:text</p>"`;
exports[`Emoji Ignores emoji shorthand codes in code, pre, script, and template tags 1`] = `
"<pre>:100:</pre>
<p><code>:100:</code></p><script>
var test = ':100:';
</script>
<template>
<p>:100</p>
</template>"
`;
exports[`Emoji Ignores emoji shorthand codes in comments 1`] = `"<p>Text <!-- :foo: :100: --></p>"`;
exports[`Emoji Ignores unmatched emoji shorthand codes 1`] = `"<p>hh:mm</p><p>hh:mm:ss</p><p>Namespace::SubNameSpace</p><p>Namespace::SubNameSpace::Class</p><p>2014-12-29T16:11:20+00:00</p>"`;
exports[`Emoji Renders GitHub emoji images (nativeEmoji:false) 1`] = `"<p><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f604.png?v8.png\\" alt=\\"smile\\" class=\\"emoji\\" loading=\\"lazy\\"></p><p><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f604.png?v8.png\\" alt=\\"smile\\" class=\\"emoji\\" loading=\\"lazy\\"><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f604.png?v8.png\\" alt=\\"smile\\" class=\\"emoji\\" loading=\\"lazy\\"></p><p><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f604.png?v8.png\\" alt=\\"smile\\" class=\\"emoji\\" loading=\\"lazy\\"> <img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f604.png?v8.png\\" alt=\\"smile\\" class=\\"emoji\\" loading=\\"lazy\\"></p><p><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f604.png?v8.png\\" alt=\\"smile\\" class=\\"emoji\\" loading=\\"lazy\\"><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f604.png?v8.png\\" alt=\\"smile\\" class=\\"emoji\\" loading=\\"lazy\\"><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f604.png?v8.png\\" alt=\\"smile\\" class=\\"emoji\\" loading=\\"lazy\\"></p><p><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f604.png?v8.png\\" alt=\\"smile\\" class=\\"emoji\\" loading=\\"lazy\\"> <img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f604.png?v8.png\\" alt=\\"smile\\" class=\\"emoji\\" loading=\\"lazy\\"> <img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f604.png?v8.png\\" alt=\\"smile\\" class=\\"emoji\\" loading=\\"lazy\\"></p><p>text<img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f604.png?v8.png\\" alt=\\"smile\\" class=\\"emoji\\" loading=\\"lazy\\"></p><p><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f604.png?v8.png\\" alt=\\"smile\\" class=\\"emoji\\" loading=\\"lazy\\">text</p><p>text<img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f604.png?v8.png\\" alt=\\"smile\\" class=\\"emoji\\" loading=\\"lazy\\">text</p>"`;
exports[`Emoji Renders native emoji characters (nativeEmoji:true) 1`] = `"<p><span class=\\"emoji\\">😄︎</span></p><p><span class=\\"emoji\\">😄︎</span><span class=\\"emoji\\">😄︎</span></p><p><span class=\\"emoji\\">😄︎</span> <span class=\\"emoji\\">😄︎</span></p><p><span class=\\"emoji\\">😄︎</span><span class=\\"emoji\\">😄︎</span><span class=\\"emoji\\">😄︎</span></p><p><span class=\\"emoji\\">😄︎</span> <span class=\\"emoji\\">😄︎</span> <span class=\\"emoji\\">😄︎</span></p><p>text<span class=\\"emoji\\">😄︎</span></p><p><span class=\\"emoji\\">😄︎</span>text</p><p>text<span class=\\"emoji\\">😄︎</span>text</p>"`;

View File

@ -0,0 +1,134 @@
const docsifyInit = require('../helpers/docsify-init');
// Suite
// -----------------------------------------------------------------------------
describe('Emoji', function () {
// Tests
// ---------------------------------------------------------------------------
const emojiMarkdown = `
:smile:
:smile::smile:
:smile: :smile:
:smile::smile::smile:
:smile: :smile: :smile:
text:smile:
:smile:text
text:smile:text
`;
test('Renders native emoji characters (nativeEmoji:true)', async () => {
await docsifyInit({
config: {
nativeEmoji: true,
},
markdown: {
homepage: emojiMarkdown,
},
// _logHTML: true,
});
const mainElm = document.querySelector('#main');
expect(mainElm.innerHTML).toMatchSnapshot();
});
test('Renders GitHub emoji images (nativeEmoji:false)', async () => {
await docsifyInit({
config: {
nativeEmoji: false,
},
markdown: {
homepage: emojiMarkdown,
},
// _logHTML: true,
});
const mainElm = document.querySelector('#main');
expect(mainElm.innerHTML).toMatchSnapshot();
});
test('Ignores all emoji shorthand codes (noEmoji:true)', async () => {
await docsifyInit({
config: {
noEmoji: true,
},
markdown: {
homepage: emojiMarkdown,
},
// _logHTML: true,
});
const mainElm = document.querySelector('#main');
expect(mainElm.innerHTML).toMatchSnapshot();
});
test('Ignores unmatched emoji shorthand codes', async () => {
await docsifyInit({
markdown: {
homepage: `
hh:mm
hh:mm:ss
Namespace::SubNameSpace
Namespace::SubNameSpace::Class
2014-12-29T16:11:20+00:00
`,
},
// _logHTML: true,
});
const mainElm = document.querySelector('#main');
expect(mainElm.innerHTML).toMatchSnapshot();
});
test('Ignores emoji shorthand codes in comments', async () => {
await docsifyInit({
markdown: {
homepage: 'Text <!-- :foo: :100: -->',
},
// _logHTML: true,
});
const mainElm = document.querySelector('#main');
expect(mainElm.innerHTML).toMatchSnapshot();
});
test('Ignores emoji shorthand codes in code, pre, script, and template tags', async () => {
await docsifyInit({
markdown: {
homepage: `
<pre>:100:</pre>
<code>:100:</code>
<script>
var test = ':100:';
</script>
<template>
<p>:100</p>
</template>
`,
},
// _logHTML: true,
});
const mainElm = document.querySelector('#main');
expect(mainElm.innerHTML).toMatchSnapshot();
});
});