feat(typeit): add some config for TypeIt (#314)

This commit is contained in:
Dillon 2020-05-04 13:20:01 +08:00 committed by GitHub
parent 8c706548c7
commit e4c71edddf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 126 additions and 74 deletions

View file

@ -2,15 +2,14 @@
.wrapper {
display: flex;
flex-direction: column;
min-height: 97.5vh;
min-height: 100vh;
width: 100%;
main {
flex: 1 0 auto;
.container {
padding-left: 1rem;
padding-right: 1rem;
padding: 0 1rem;
}
}
}

View file

@ -2,8 +2,8 @@ footer {
height: 2rem;
width: 100%;
text-align: center;
line-height: 1.5rem;
padding-top: 2rem;
line-height: 1.25rem;
padding: 1rem 0;
.footer-container {
font-size: .875rem;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -14,7 +14,7 @@ lg-thumbnail.js@1.1.0 https://github.com/sachinchoolur/lg-thumbnail.js
lg-zoom.js@1.0.1 https://github.com/sachinchoolur/lg-zoom.js
clipboard.js@2.0.6 https://github.com/zenorocha/clipboard.js
sharer.js@0.4.0 https://github.com/ellisonleao/sharer.js
typeit@6.5.1 https://github.com/alexmacarthur/typeit
typeit@7.0.4 https://github.com/alexmacarthur/typeit
katex@0.11.1 https://katex.org/
mermaid@8.5.0 https://github.com/knsv/mermaid
echarts@4.7.0 https://echarts.apache.org/

File diff suppressed because one or more lines are too long

View file

@ -656,7 +656,7 @@ enableEmoji = true
# 你可以在名称 (允许 HTML 格式) 之后添加其他信息, 例如图标
post = ""
# whether to use typeit animation for title name
# 是否为标题显示打字机动画
# 是否为标题显示打字机动画
typeit = false
# Footer config
@ -914,6 +914,22 @@ enableEmoji = true
width = 800
height = 600
# TypeIt config
# TypeIt 配置
[params.typeit]
# typing speed between each step (measured in milliseconds)
# 每一步的打字速度 (单位是毫秒)
speed = 100
# blinking speed of the cursor (measured in milliseconds)
# 光标的闪烁速度 (单位是毫秒)
cursorSpeed = 1000
# character used for the cursor (HTML format is supported)
# 光标的字符 (支持 HTML 格式)
cursorChar = "|"
# cursor duration after typing finishing (measured in milliseconds, "-1" means unlimited)
# 打字结束之后光标的持续时间 (单位是毫秒, "-1" 代表无限大)
duration = -1
# Site verification code for Google/Bing/Yandex/Pinterest/Baidu
# 网站验证代码,用于 Google/Bing/Yandex/Pinterest/Baidu
[params.verification]
@ -980,7 +996,7 @@ enableEmoji = true
clipboardJS = ""
# sharer.js@0.4.0 https://github.com/ellisonleao/sharer.js
sharerJS = ""
# typeit@6.5.1 https://github.com/alexmacarthur/typeit
# typeit@7.0.4 https://github.com/alexmacarthur/typeit
typeitJS = ""
# katex@0.11.1 https://katex.org/
katexCSS = ""

View file

@ -254,7 +254,7 @@ Please open the code block below to view the complete sample configuration :(far
pre = ""
# you can add extra information after the name (HTML format is supported), such as icons
post = ""
# whether to use typeit animation for title name
# {{< version 0.2.5 >}} whether to use typeit animation for title name
typeit = false
# Footer config
@ -317,7 +317,8 @@ Please open the code block below to view the complete sample configuration :(far
enable = true
# special amount of posts in each home posts page
paginate = 6
# {{< version 0.2.0 deleted >}} default behavior when you don't set "hiddenFromHomePage" in front matter
# {{< version 0.2.0 deleted >}} replaced with hiddenFromHomePage in params.page
# default behavior when you don't set "hiddenFromHomePage" in front matter
defaultHiddenFromHomePage = false
# Social config about the author
@ -550,6 +551,17 @@ Please open the code block below to view the complete sample configuration :(far
width = 800
height = 600
# {{< version 0.2.5 >}} TypeIt config
[params.typeit]
# typing speed between each step (measured in milliseconds)
speed = 100
# blinking speed of the cursor (measured in milliseconds)
cursorSpeed = 1000
# character used for the cursor (HTML format is supported)
cursorChar = "|"
# cursor duration after typing finishing (measured in milliseconds, "-1" means unlimited)
duration = -1
# Site verification code config for Google/Bing/Yandex/Pinterest/Baidu
[params.verification]
google = ""
@ -610,7 +622,7 @@ Please open the code block below to view the complete sample configuration :(far
clipboardJS = ""
# {{< link "https://github.com/ellisonleao/sharer.js" "sharer.js" >}}@0.4.0
sharerJS = ""
# {{< link "https://github.com/alexmacarthur/typeit" "typeit" >}}@6.5.1
# {{< link "https://github.com/alexmacarthur/typeit" "typeit" >}}@7.0.4
typeitJS = ""
# {{< link "https://github.com/KaTeX/KaTeX" "katex" >}}@0.11.1
katexCSS = ""

View file

@ -259,7 +259,7 @@ Please open the code block below to view the complete sample configuration :(far
pre = ""
# you can add extra information after the name (HTML format is supported), such as icons
post = ""
# whether to use typeit animation for title name
# {{< version 0.2.5 >}} whether to use typeit animation for title name
typeit = false
# Footer config
@ -322,7 +322,8 @@ Please open the code block below to view the complete sample configuration :(far
enable = true
# special amount of posts in each home posts page
paginate = 6
# {{< version 0.2.0 deleted >}} default behavior when you don't set "hiddenFromHomePage" in front matter
# {{< version 0.2.0 deleted >}} replaced with hiddenFromHomePage in params.page
# default behavior when you don't set "hiddenFromHomePage" in front matter
defaultHiddenFromHomePage = false
# Social config about the author
@ -555,6 +556,17 @@ Please open the code block below to view the complete sample configuration :(far
width = 800
height = 600
# {{< version 0.2.5 >}} TypeIt config
[params.typeit]
# typing speed between each step (measured in milliseconds)
speed = 100
# blinking speed of the cursor (measured in milliseconds)
cursorSpeed = 1000
# character used for the cursor (HTML format is supported)
cursorChar = "|"
# cursor duration after typing finishing (measured in milliseconds, "-1" means unlimited)
duration = -1
# Site verification code config for Google/Bing/Yandex/Pinterest/Baidu
[params.verification]
google = ""
@ -615,7 +627,7 @@ Please open the code block below to view the complete sample configuration :(far
clipboardJS = ""
# {{< link "https://github.com/ellisonleao/sharer.js" "sharer.js" >}}@0.4.0
sharerJS = ""
# {{< link "https://github.com/alexmacarthur/typeit" "typeit" >}}@6.5.1
# {{< link "https://github.com/alexmacarthur/typeit" "typeit" >}}@7.0.4
typeitJS = ""
# {{< link "https://github.com/KaTeX/KaTeX" "katex" >}}@0.11.1
katexCSS = ""

View file

@ -257,7 +257,7 @@ hugo
pre = ""
# 你可以在名称 (允许 HTML 格式) 之后添加其他信息, 例如图标
post = ""
# 是否为标题显示打字机动画
# {{< version 0.2.5 >}} 是否为标题显示打字机动画
typeit = false
# 页面底部信息配置
@ -320,7 +320,8 @@ hugo
enable = true
# 主页每页显示文章数量
paginate = 6
# {{< version 0.2.0 deleted >}} 当你没有在文章前置参数中设置 "hiddenFromHomePage" 时的默认行为
# {{< version 0.2.0 deleted >}} 被 params.page 中的 hiddenFromHomePage 替代
# 当你没有在文章前置参数中设置 "hiddenFromHomePage" 时的默认行为
defaultHiddenFromHomePage = false
# 作者的社交信息设置
@ -553,6 +554,17 @@ hugo
width = 800
height = 600
# {{< version 0.2.5 >}} TypeIt 配置
[params.typeit]
# 每一步的打字速度 (单位是毫秒)
speed = 100
# 光标的闪烁速度 (单位是毫秒)
cursorSpeed = 1000
# 光标的字符 (支持 HTML 格式)
cursorChar = "|"
# 打字结束之后光标的持续时间 (单位是毫秒, "-1" 代表无限大)
duration = -1
# 网站验证代码,用于 Google/Bing/Yandex/Pinterest/Baidu
[params.verification]
google = ""
@ -613,7 +625,7 @@ hugo
clipboardJS = ""
# {{< link "https://github.com/ellisonleao/sharer.js" "sharer.js" >}}@0.4.0
sharerJS = ""
# {{< link "https://github.com/alexmacarthur/typeit" "typeit" >}}@6.5.1
# {{< link "https://github.com/alexmacarthur/typeit" "typeit" >}}@7.0.4
typeitJS = ""
# {{< link "https://github.com/KaTeX/KaTeX" "katex" >}}@0.11.1
katexCSS = ""
@ -1010,7 +1022,7 @@ defaultContentLanguage = "zh-cn"
* `lunr`: 简单, 无需同步 `index.json`, 没有 `contentLength` 的限制, 但占用带宽大且性能低 (特别是中文需要一个较大的分词依赖库)
* `algolia`: 高性能并且占用带宽低, 但需要同步 `index.json` 且有 `contentLength` 的限制
{{< version 0.2.3 >}} 文章内容被 `h2``h3` HTML 标签切分来提查询效果并且基本实现全文搜索.
{{< version 0.2.3 >}} 文章内容被 `h2``h3` HTML 标签切分来提查询效果并且基本实现全文搜索.
`contentLength` 用来限制 `h2``h3` HTML 标签开头的内容部分的最大长度.
{{< /admonition >}}

View file

@ -8,30 +8,30 @@
{{- dict "source" $source "fingerprint" $fingerprint | dict "scratch" $.Scratch "data" | partial "scratch/script.html" -}}
{{- /* Search */ -}}
{{- if .Site.Params.search.enable -}}
{{- if .Site.Params.search | and .Site.Params.search.enable -}}
{{- $search := .Site.Params.search -}}
{{- $source := $cdn.autocompleteJS | default "lib/autocomplete/autocomplete.min.js" -}}
{{- dict "source" $source "fingerprint" $fingerprint | dict "scratch" $.Scratch "data" | partial "scratch/script.html" -}}
{{- $searchConfig := dict "noResultsFound" (T "noResultsFound") -}}
{{- if eq .Site.Params.search.type "lunr" -}}
{{- $config = dict "maxResultLength" $search.maxResultLength "snippetLength" $search.snippetLength "highlightTag" $search.highlightTag "noResultsFound" (T "noResultsFound") | dict "search" | merge $config -}}
{{- if eq $search.type "lunr" -}}
{{- with .Site.Home.OutputFormats.Get "json" -}}
{{- $searchConfig = dict "type" "lunr" "lunrIndexURL" .RelPermalink | merge $searchConfig -}}
{{- $config = dict "type" "lunr" "lunrIndexURL" .RelPermalink | dict "search" | merge $config -}}
{{- end -}}
{{- $source := $cdn.lunrJS | default "lib/lunr/lunr.min.js" -}}
{{- dict "source" $source "fingerprint" $fingerprint | dict "scratch" $.Scratch "data" | partial "scratch/script.html" -}}
{{- if ne .Language.Lang "en" -}}
{{- $searchConfig = T "lunrLanguageCode" | dict "lunrLanguageCode" | merge $searchConfig -}}
{{- $config = T "lunrLanguageCode" | dict "lunrLanguageCode" | dict "search" | merge $config -}}
{{- if eq .Language.Lang "zh-cn" -}}
{{- $searchConfig = dict "lunrSegmentitURL" (resources.Get "lib/lunr/lunr.segmentit.js").RelPermalink | merge $searchConfig -}}
{{- $config = dict "lunrSegmentitURL" (resources.Get "lib/lunr/lunr.segmentit.js").RelPermalink | dict "search" | merge $config -}}
{{- end -}}
{{- dict "source" "lib/lunr/lunr.stemmer.support.js" "minify" true "fingerprint" $fingerprint | dict "scratch" $.Scratch "data" | partial "scratch/script.html" -}}
{{- dict "source" (T "lunrLanguageLib") "minify" true "fingerprint" $fingerprint | dict "scratch" $.Scratch "data" | partial "scratch/script.html" -}}
{{- end -}}
{{- else if eq .Site.Params.search.type "algolia" -}}
{{- else if eq $search.type "algolia" -}}
{{- $source := $cdn.algoliasearchJS | default "lib/algoliasearch/algoliasearch-lite.umd.min.js" -}}
{{- dict "source" $source "fingerprint" $fingerprint | dict "scratch" $.Scratch "data" | partial "scratch/script.html" -}}
{{- $searchConfig = dict "type" "algolia" "algoliaIndex" .Site.Params.search.algolia.index "algoliaAppID" .Site.Params.search.algolia.appID "algoliaSearchKey" .Site.Params.search.algolia.searchKey | merge $searchConfig -}}
{{- $config = dict "type" "algolia" "algoliaIndex" $search.algolia.index "algoliaAppID" $search.algolia.appID "algoliaSearchKey" $search.algolia.searchKey | dict "search" | merge $config -}}
{{- end -}}
{{- $config = dict "search" $searchConfig | merge $config -}}
{{- end -}}
{{- /* lazysizes */ -}}
@ -59,8 +59,7 @@
{{- dict "source" $source "fingerprint" $fingerprint | dict "scratch" $.Scratch "data" | partial "scratch/script.html" -}}
{{- $source := $cdn.lightgalleryZoomJS | default "lib/lightgallery/lg-zoom.min.js" -}}
{{- dict "source" $source "fingerprint" $fingerprint | dict "scratch" $.Scratch "data" | partial "scratch/script.html" -}}
{{- $lightGalleryConfig := dict "selector" ".lightgallery" "speed" 400 "hideBarsDelay" 2000 "thumbnail" true "exThumbImage" "data-thumbnail" "thumbWidth" 80 "thumbContHeight" 80 "actualSize" false -}}
{{- $config = dict "lightGallery" $lightGalleryConfig | merge $config -}}
{{- $config = dict "selector" ".lightgallery" "speed" 400 "hideBarsDelay" 2000 "thumbnail" true "exThumbImage" "data-thumbnail" "thumbWidth" 80 "thumbContHeight" 80 "actualSize" false | dict "lightGallery" | merge $config -}}
{{- $styleArr := (.Scratch.Get "this").styleArr | default slice -}}
{{- $styleArr | append ".lg-toolbar .lg-icon::after { color: #999; }" | .Scratch.SetInMap "this" "styleArr" -}}
{{- end -}}
@ -83,24 +82,21 @@
{{- /* TypeIt */ -}}
{{- with (.Scratch.Get "this").typeitMap -}}
{{- $typeit := $.Site.Params.typeit -}}
{{- $source := $cdn.typeitJS | default "lib/typeit/typeit.min.js" -}}
{{- dict "source" $source "fingerprint" $fingerprint | dict "scratch" $.Scratch "data" | partial "scratch/script.html" -}}
{{- $typeitConfig := slice -}}
{{- range $key, $val := . -}}
{{- $typeitConfig = $typeitConfig | append (slice $val) -}}
{{- end -}}
{{- $config = dict "typeit" $typeitConfig | merge $config -}}
{{- $config = dict "speed" $typeit.speed "cursorSpeed" $typeit.cursorSpeed "cursorChar" $typeit.cursorChar "duration" $typeit.duration "data" . | dict "typeit" | merge $config -}}
{{- end -}}
{{- /* KaTeX */ -}}
{{- if $params.math.enable -}}
{{- $math := $params.math -}}
{{- $source := $cdn.katexCSS | default "lib/katex/katex.min.css" -}}
{{- dict "source" $source "fingerprint" $fingerprint | dict "scratch" $.Scratch "data" | partial "scratch/stylesheet.html" -}}
{{- $source := $cdn.katexJS | default "lib/katex/katex.min.js" -}}
{{- dict "source" $source "fingerprint" $fingerprint | dict "scratch" $.Scratch "data" | partial "scratch/script.html" -}}
{{- $source := $cdn.katexAutoRenderJS | default "lib/katex/auto-render.min.js" -}}
{{- dict "source" $source "fingerprint" $fingerprint | dict "scratch" $.Scratch "data" | partial "scratch/script.html" -}}
{{- $math := $params.math -}}
{{- if $math.copyTex -}}
{{- $source := $cdn.katexCopyTexCSS | default "lib/katex/copy-tex.min.css" -}}
{{- dict "source" $source "fingerprint" $fingerprint | dict "scratch" $.Scratch "data" | partial "scratch/stylesheet.html" -}}
@ -111,7 +107,6 @@
{{- $source := $cdn.katexMhchemJS | default "lib/katex/mhchem.min.js" -}}
{{- dict "source" $source "fingerprint" $fingerprint | dict "scratch" $.Scratch "data" | partial "scratch/script.html" -}}
{{- end -}}
{{- $mathConfig := dict "strict" false -}}
{{- $delimiters := slice (dict "left" "$$" "right" "$$" "display" true) (dict "left" "\\[" "right" "\\]" "display" true) -}}
{{- if and $math.blockLeftDelimiter $math.blockRightDelimiter -}}
{{- $delimiters = $delimiters | append (dict "left" $math.blockLeftDelimiter "right" $math.blockRightDelimiter "display" true) -}}
@ -120,8 +115,7 @@
{{- if and $math.inlineLeftDelimiter $math.inlineRightDelimiter -}}
{{- $delimiters = $delimiters | append (dict "left" $math.inlineRightDelimiter "right" $math.inlineRightDelimiter "display" false) -}}
{{- end -}}
{{- $mathConfig = dict "delimiters" $delimiters | merge $mathConfig -}}
{{- $config = dict "math" $mathConfig | merge $config -}}
{{- $config = dict "strict" false "delimiters" $delimiters | dict "math" | merge $config -}}
{{- end -}}
{{- /* mermaid */ -}}
@ -182,7 +176,7 @@
</script>
{{- /* Polyfill.io */ -}}
{{- dict "source" "https://polyfill.io/v3/polyfill.min.js?features=Element.prototype.closest%2CrequestAnimationFrame%2CCustomEvent%2CPromise%2CObject.entries%2CObject.assign%2CObject.values%2Cfetch%2CElement.prototype.after%2CArray.prototype.fill%2CIntersectionObserver%2CArray.from%2CArray.prototype.find%2CMath.sign" | partial "plugin/script.html" -}}
{{- dict "source" "https://polyfill.io/v3/polyfill.min.js?features=html5shiv%2CElement.prototype.closest%2CrequestAnimationFrame%2CCustomEvent%2CPromise%2CObject.entries%2CObject.assign%2CObject.values%2Cfetch%2CElement.prototype.after%2CArray.prototype.fill%2CIntersectionObserver%2CArray.from%2CArray.prototype.find%2CMath.sign" | partial "plugin/script.html" -}}
{{- range (.Scratch.Get "this").script -}}
{{- partial "plugin/script.html" . -}}

View file

@ -15,7 +15,7 @@
<span id="{{ $id }}" class="typeit"></span>
{{- dict $id (slice $id) | dict "typeitMap" | merge ($.Scratch.Get "this") | $.Scratch.Set "this" -}}
{{- else -}}
{{- .name -}}
{{- .name -}}
{{- end -}}
{{- with .post -}}
<span class="header-title-post">{{ . | safeHTML }}</span>
@ -99,7 +99,7 @@
<span id="{{ $id }}" class="typeit"></span>
{{- dict $id (slice $id) | dict "typeitMap" | merge ($.Scratch.Get "this") | $.Scratch.Set "this" -}}
{{- else -}}
{{- .name -}}
{{- .name -}}
{{- end -}}
{{- with .post -}}
<span class="header-title-post">{{ . | safeHTML }}</span>

View file

@ -97,9 +97,9 @@ class Theme {
const isMobile = this.util.isMobile();
if (!searchConfig || isMobile && this._searchMobileOnce || !isMobile && this._searchDesktopOnce) return;
if (!searchConfig.maxResultLength) searchConfig.maxResultLength = 10;
if (!searchConfig.snippetLength) searchConfig.snippetLength = 50;
if (!searchConfig.highlightTag) searchConfig.highlightTag = 'em';
const maxResultLength = searchConfig.maxResultLength ? searchConfig.maxResultLength : 10;
const snippetLength = searchConfig.snippetLength ? searchConfig.snippetLength : 50;
const highlightTag = searchConfig.highlightTag ? searchConfig.highlightTag : 'em';
const suffix = isMobile ? 'mobile' : 'desktop';
const $header = document.getElementById(`header-${suffix}`);
@ -190,16 +190,16 @@ class Theme {
if (matchPosition < position || position === 0) position = matchPosition;
}
});
position -= searchConfig.snippetLength / 5;
position -= snippetLength / 5;
if (position > 0) {
position += context.substr(position, 20).lastIndexOf(' ') + 1;
context = '...' + context.substr(position, searchConfig.snippetLength);
context = '...' + context.substr(position, snippetLength);
} else {
context = context.substr(0, searchConfig.snippetLength);
context = context.substr(0, snippetLength);
}
Object.keys(metadata).forEach(key => {
title = title.replace(new RegExp(`(${key})`, 'gi'), `<${searchConfig.highlightTag}>$1</${searchConfig.highlightTag}>`);
context = context.replace(new RegExp(`(${key})`, 'gi'), `<${searchConfig.highlightTag}>$1</${searchConfig.highlightTag}>`);
title = title.replace(new RegExp(`(${key})`, 'gi'), `<${highlightTag}>$1</${highlightTag}>`);
context = context.replace(new RegExp(`(${key})`, 'gi'), `<${highlightTag}>$1</${highlightTag}>`);
});
results[uri] = {
'uri': uri,
@ -208,7 +208,7 @@ class Theme {
'context' : context,
};
});
return Object.values(results).slice(0, searchConfig.maxResultLength);
return Object.values(results).slice(0, maxResultLength);
}
if (!this._index) {
fetch(searchConfig.lunrIndexURL)
@ -240,11 +240,11 @@ class Theme {
this._algoliaIndex
.search(query, {
offset: 0,
length: searchConfig.maxResultLength * 8,
length: maxResultLength * 8,
attributesToHighlight: ['title'],
attributesToSnippet: [`content:${searchConfig.snippetLength}`],
highlightPreTag: `<${searchConfig.highlightTag}>`,
highlightPostTag: `</${searchConfig.highlightTag}>`,
attributesToSnippet: [`content:${snippetLength}`],
highlightPreTag: `<${highlightTag}>`,
highlightPostTag: `</${highlightTag}>`,
})
.then(({ hits }) => {
const results = {};
@ -257,7 +257,7 @@ class Theme {
context: content.value,
};
});
finish(Object.values(results).slice(0, searchConfig.maxResultLength));
finish(Object.values(results).slice(0, maxResultLength));
})
.catch(err => {
console.error(err);
@ -281,7 +281,7 @@ class Theme {
return `<div class="search-footer">Search by <a href="${href}" rel="noopener noreffer" target="_blank">${icon} ${searchType}</a></div>`;},
},
});
autosearch.on('autocomplete:selected', (event, suggestion, dataset, context) => {
autosearch.on('autocomplete:selected', (_event, suggestion, _dataset, _context) => {
window.location.assign(suggestion.uri);
});
if (isMobile) this._searchMobile = autosearch;
@ -366,7 +366,7 @@ class Theme {
$copy.setAttribute('data-clipboard-text', code);
$copy.title = this.config.code.copyTitle;
const clipboard = new ClipboardJS($copy);
clipboard.on('success', e => {
clipboard.on('success', _e => {
this.util.animateCSS($code, 'flash');
});
$header.appendChild($copy);
@ -558,18 +558,27 @@ class Theme {
initTypeit() {
if (this.config.typeit) {
this.config.typeit.forEach(group => {
const typeitConfig = this.config.typeit;
const speed = typeitConfig.speed ? typeitConfig.speed : 100;
const cursorSpeed = typeitConfig.cursorSpeed ? typeitConfig.cursorSpeed : 1000;
const cursorChar = typeitConfig.cursorChar ? typeitConfig.cursorChar : '|';
Object.values(typeitConfig.data).forEach(group => {
const typeone = (i) => {
const id = group[i];
if (i === group.length - 1) {
new TypeIt(`#${id}`, {
strings: this.data[id],
}).go();
return;
}
let instance = new TypeIt(`#${id}`, {
const instance = new TypeIt(`#${id}`, {
strings: this.data[id],
speed: speed,
lifeLike: true,
cursorSpeed: cursorSpeed,
cursorChar: cursorChar,
waitUntilVisible: true,
afterComplete: () => {
if (i === group.length - 1) {
if (typeitConfig.duration >= 0) window.setTimeout(() => {
instance.destroy();
}, typeitConfig.duration);
return;
}
instance.destroy();
typeone(i + 1);
},