From eea41a1207c46533ea9c6c59d82e2c94aa4dd70e Mon Sep 17 00:00:00 2001 From: James George Date: Thu, 19 Dec 2019 14:08:21 +0530 Subject: [PATCH 01/42] feat(chore): configure pre-commit hook (#983) * chore: add husky as a devDep * chore: add lint-staged as a devDep * configure: pre-commit hook for staged files * fix: minor tweak * chore: update glob --- package-lock.json | 814 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 10 + 2 files changed, 824 insertions(+) diff --git a/package-lock.json b/package-lock.json index ba2f7519d..11d6127e3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1224,12 +1224,40 @@ "glob-to-regexp": "^0.3.0" } }, + "@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + }, + "dependencies": { + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true + } + } + }, "@nodelib/fs.stat": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", "dev": true }, + "@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + } + }, "@octokit/endpoint": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-5.4.0.tgz", @@ -1325,6 +1353,15 @@ "universal-user-agent": "^4.0.0" } }, + "@samverschueren/stream-to-observable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz", + "integrity": "sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg==", + "dev": true, + "requires": { + "any-observable": "^0.3.0" + } + }, "@types/estree": { "version": "0.0.39", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", @@ -1360,6 +1397,12 @@ "integrity": "sha512-KPYGmfD0/b1eXurQ59fXD1GBzhSQfz6/lKBxkaHX9dKTzjXbK68Zt7yGUxUsCS1jeTy/8aL+d9JEr+S54mpkWQ==", "dev": true }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, "@types/q": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz", @@ -1476,6 +1519,24 @@ "humanize-ms": "^1.2.1" } }, + "aggregate-error": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", + "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "dependencies": { + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + } + } + }, "ajv": { "version": "6.10.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", @@ -1521,6 +1582,12 @@ "color-convert": "^1.9.0" } }, + "any-observable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz", + "integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==", + "dev": true + }, "any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", @@ -2252,6 +2319,12 @@ } } }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, "cli-cursor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", @@ -2261,6 +2334,59 @@ "restore-cursor": "^2.0.0" } }, + "cli-truncate": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", + "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", + "dev": true, + "requires": { + "slice-ansi": "0.0.4", + "string-width": "^1.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, "cli-width": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", @@ -3082,6 +3208,12 @@ "whatwg-url": "^7.0.0" } }, + "date-fns": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", + "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", + "dev": true + }, "dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", @@ -3213,6 +3345,111 @@ } } }, + "del": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/del/-/del-5.1.0.tgz", + "integrity": "sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA==", + "dev": true, + "requires": { + "globby": "^10.0.1", + "graceful-fs": "^4.2.2", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.1", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0" + }, + "dependencies": { + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "fast-glob": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.1.tgz", + "integrity": "sha512-nTCREpBY8w8r+boyFYAx21iL6faSsQynliPHM4Uf56SbkyohCNxpVPEH9xrF5TXKy+IsjkPUHDKiUkzBVRXn9g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2" + } + }, + "globby": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz", + "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + } + }, + "ignore": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", + "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + } + } + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -3413,6 +3650,12 @@ "integrity": "sha512-oxXKngPjTWRmXFy4vV9FeAkPl7wU4xMejfOY+HXjGrj4T0z9l96loWWVDLJEtbT/aPKOWKrSz6xoYxd+YJ/gJA==", "dev": true }, + "elegant-spinner": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", + "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=", + "dev": true + }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", @@ -3795,6 +4038,72 @@ "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", "dev": true }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", @@ -4009,6 +4318,15 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fastq": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz", + "integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==", + "dev": true, + "requires": { + "reusify": "^1.0.0" + } + }, "faye-websocket": { "version": "0.11.3", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", @@ -4408,6 +4726,12 @@ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, + "get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "dev": true + }, "get-pkg-repo": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz", @@ -4895,6 +5219,23 @@ "function-bind": "^1.1.1" } }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + } + } + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -5115,6 +5456,127 @@ "ms": "^2.0.0" } }, + "husky": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/husky/-/husky-3.1.0.tgz", + "integrity": "sha512-FJkPoHHB+6s4a+jwPqBudBDvYZsoQW5/HBuMSehC8qDiCe50kpcxeqFoDSlow+9I6wg47YxBoT3WxaURlrDIIQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "ci-info": "^2.0.0", + "cosmiconfig": "^5.2.1", + "execa": "^1.0.0", + "get-stdin": "^7.0.0", + "opencollective-postinstall": "^2.0.2", + "pkg-dir": "^4.2.0", + "please-upgrade-node": "^3.2.0", + "read-pkg": "^5.2.0", + "run-node": "^1.0.0", + "slash": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "get-stdin": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz", + "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -5472,6 +5934,27 @@ "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", "dev": true }, + "is-observable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz", + "integrity": "sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==", + "dev": true, + "requires": { + "symbol-observable": "^1.1.0" + } + }, + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true + }, + "is-path-inside": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", + "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", + "dev": true + }, "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", @@ -5511,6 +5994,12 @@ "has": "^1.0.1" } }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "dev": true + }, "is-resolvable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", @@ -5797,6 +6286,220 @@ "type-check": "~0.3.2" } }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "lint-staged": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-9.5.0.tgz", + "integrity": "sha512-nawMob9cb/G1J98nb8v3VC/E8rcX1rryUYXVZ69aT9kde6YWX+uvNOEHY5yf2gcWcTJGiD0kqXmCnS3oD75GIA==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "commander": "^2.20.0", + "cosmiconfig": "^5.2.1", + "debug": "^4.1.1", + "dedent": "^0.7.0", + "del": "^5.0.0", + "execa": "^2.0.3", + "listr": "^0.14.3", + "log-symbols": "^3.0.0", + "micromatch": "^4.0.2", + "normalize-path": "^3.0.0", + "please-upgrade-node": "^3.1.1", + "string-argv": "^0.3.0", + "stringify-object": "^3.3.0" + }, + "dependencies": { + "execa": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz", + "integrity": "sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^3.0.0", + "onetime": "^5.1.0", + "p-finally": "^2.0.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "npm-run-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz", + "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "p-finally": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", + "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", + "dev": true + } + } + }, + "listr": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz", + "integrity": "sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA==", + "dev": true, + "requires": { + "@samverschueren/stream-to-observable": "^0.3.0", + "is-observable": "^1.1.0", + "is-promise": "^2.1.0", + "is-stream": "^1.1.0", + "listr-silent-renderer": "^1.1.1", + "listr-update-renderer": "^0.5.0", + "listr-verbose-renderer": "^0.5.0", + "p-map": "^2.0.0", + "rxjs": "^6.3.3" + } + }, + "listr-silent-renderer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz", + "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=", + "dev": true + }, + "listr-update-renderer": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz", + "integrity": "sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA==", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "cli-truncate": "^0.2.1", + "elegant-spinner": "^1.0.1", + "figures": "^1.7.0", + "indent-string": "^3.0.0", + "log-symbols": "^1.0.2", + "log-update": "^2.3.0", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + } + }, + "log-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", + "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", + "dev": true, + "requires": { + "chalk": "^1.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "listr-verbose-renderer": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz", + "integrity": "sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "cli-cursor": "^2.1.0", + "date-fns": "^1.27.2", + "figures": "^2.0.0" + } + }, "live-server": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/live-server/-/live-server-1.2.1.tgz", @@ -6654,6 +7357,38 @@ "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", "dev": true }, + "log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2" + } + }, + "log-update": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz", + "integrity": "sha1-iDKP19HOeTiykoN0bwsbwSayRwg=", + "dev": true, + "requires": { + "ansi-escapes": "^3.0.0", + "cli-cursor": "^2.0.0", + "wrap-ansi": "^3.0.1" + }, + "dependencies": { + "wrap-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz", + "integrity": "sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0" + } + } + } + }, "loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", @@ -7624,6 +8359,23 @@ } } }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + }, + "dependencies": { + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + } + } + }, "npmlog": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", @@ -8326,6 +9078,15 @@ } } }, + "please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "requires": { + "semver-compare": "^1.0.0" + } + }, "pn": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", @@ -9356,6 +10117,12 @@ "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=", "dev": true }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, "rgb-regex": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", @@ -9569,6 +10336,18 @@ "is-promise": "^2.1.0" } }, + "run-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/run-node/-/run-node-1.0.0.tgz", + "integrity": "sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A==", + "dev": true + }, + "run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true + }, "run-queue": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", @@ -9635,6 +10414,12 @@ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true + }, "send": { "version": "0.17.1", "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", @@ -10247,6 +11032,12 @@ "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", "dev": true }, + "string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "dev": true + }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -10297,6 +11088,17 @@ "safe-buffer": "~5.2.0" } }, + "stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "requires": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + } + }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", @@ -10318,6 +11120,12 @@ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, "strip-indent": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", @@ -10451,6 +11259,12 @@ "util.promisify": "~1.0.0" } }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", + "dev": true + }, "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", diff --git a/package.json b/package.json index 17572fdd1..86beeb21e 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,14 @@ "pub": "sh build/release.sh", "postinstall": "opencollective-postinstall" }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "*.js": "npm run lint" + }, "dependencies": { "marked": "^0.7.0", "medium-zoom": "^1.0.4", @@ -59,8 +67,10 @@ "eslint": "^5.16.0", "eslint-config-xo-space": "^0.21.0", "esm": "^3.1.4", + "husky": "^3.1.0", "jsdom": "^15.1.1", "lerna": "^3.17.0", + "lint-staged": "^9.5.0", "live-server": "^1.2.1", "mkdirp": "^0.5.1", "mocha": "^5.2.0", From daf54b9d36a9ff079061afdddc39065f8423392a Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Fri, 20 Dec 2019 19:12:39 +0700 Subject: [PATCH 02/42] There are currently {three=>four} themes available. (#892) * There are currently {three=>four} themes available. * Remove number --- docs/themes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/themes.md b/docs/themes.md index 1de912505..31df80e16 100644 --- a/docs/themes.md +++ b/docs/themes.md @@ -1,6 +1,6 @@ # Themes -There are currently three themes available. Copy [Vue](//vuejs.org) and [buble](//buble.surge.sh) website custom theme and [@liril-net](https://github.com/liril-net) contribution to the theme of the black style. +There is a handful of themes available, both official and community-made. Copy [Vue](//vuejs.org) and [buble](//buble.surge.sh) website custom theme and [@liril-net](https://github.com/liril-net) contribution to the theme of the black style. ```html From 808123bc3034626b6384475ae4a90ce61969669c Mon Sep 17 00:00:00 2001 From: Rodrigo Asensio Date: Fri, 20 Dec 2019 13:12:53 +0100 Subject: [PATCH 03/42] Added a redirect for images to show up in Amplify (#918) Without the redirect images are not displaying in Amplify after deploying. Once added the redirect all PNGs showed up. --- docs/deploy.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/deploy.md b/docs/deploy.md index 6bfe90445..d68b5c9dc 100644 --- a/docs/deploy.md +++ b/docs/deploy.md @@ -128,9 +128,10 @@ frontend: ``` -6. Add the following Redirect rules in their displayed order. +6. Add the following Redirect rules in their displayed order. Note that the second record is a PNG image where you can change it with any image format you are using. | Source address | Target address | Type | |----------------|----------------|---------------| | /<*>.md | /<*>.md | 200 (Rewrite) | +| /<*>.png | /<*>.png | 200 (Rewrite) | | /<*> | /index.html | 200 (Rewrite) | From 8416275e2550d780a85a9ebedddf2d934dd102a9 Mon Sep 17 00:00:00 2001 From: "cinwell.li" Date: Sun, 22 Dec 2019 19:46:23 +0800 Subject: [PATCH 04/42] docs: about cache (#854) --- docs/configuration.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/configuration.md b/docs/configuration.md index bcbe2e0de..ec5ee3c46 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -480,6 +480,18 @@ window.$docsify = { }; ``` +Such as setting the cache + +```js +window.$docsify = { + requestHeaders: { + 'cache-control': 'max-age=600' + } +}; +``` + + + ## ext - type: `String` From 5b77b0f628f056b7ebb6d0b617561d19964516a2 Mon Sep 17 00:00:00 2001 From: James George Date: Sun, 22 Dec 2019 17:18:28 +0530 Subject: [PATCH 05/42] fix: stage modified files as part of pre-commit hook (#985) --- package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 86beeb21e..9c0197143 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,10 @@ } }, "lint-staged": { - "*.js": "npm run lint" + "*.js": [ + "npm run lint", + "git add" + ] }, "dependencies": { "marked": "^0.7.0", From 7d0c164bf5bbef4e24428114c0bde4ad998b7470 Mon Sep 17 00:00:00 2001 From: anikethsaha Date: Sat, 28 Dec 2019 22:08:36 +0530 Subject: [PATCH 06/42] chore: removed the escaping of the name of sidebar --- src/core/render/tpl.js | 23 +++++++++++------------ src/core/util/core.js | 15 --------------- 2 files changed, 11 insertions(+), 27 deletions(-) diff --git a/src/core/render/tpl.js b/src/core/render/tpl.js index 2b5862287..9e3fab126 100644 --- a/src/core/render/tpl.js +++ b/src/core/render/tpl.js @@ -1,5 +1,4 @@ -import {isMobile} from '../util/env' -import {escapeString} from '../util/core' +import { isMobile } from '../util/env' /** * Render github corner * @param {Object} data @@ -9,11 +8,13 @@ export function corner(data, cornerExternalLinkTarge) { if (!data) { return '' } + if (!/\/\//.test(data)) { data = 'https://github.com/' + data } + data = data.replace(/^git\+/, '') - // double check + // Double check cornerExternalLinkTarge = cornerExternalLinkTarge || '_blank' return ( @@ -31,8 +32,7 @@ export function corner(data, cornerExternalLinkTarge) { * Render main content */ export function main(config) { - - const name = config.name? escapeString(config.name):'' + const name = config.name ? config.name : '' const aside = '' + '' @@ -88,6 +86,7 @@ export function tree(toc, tpl = '
    {inner}
') { if (!toc || !toc.length) { return '' } + let innerHTML = '' toc.forEach(node => { innerHTML += `
  • ${node.title}
  • ` diff --git a/src/core/util/core.js b/src/core/util/core.js index c538e2223..0df54c9c3 100644 --- a/src/core/util/core.js +++ b/src/core/util/core.js @@ -57,18 +57,3 @@ export function isFn(obj) { return typeof obj === 'function' } -/** - * escape String - */ -export function escapeString(string) { - const entityMap = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - '\'': ''', - '/': '/' - } - - return String(string).replace(/[&<>"'/]/g, s => entityMap[s]) -} \ No newline at end of file From 67a981b8d95aa0e7f603fd4ce244b3c0ca47eceb Mon Sep 17 00:00:00 2001 From: Joe Pea Date: Sun, 29 Dec 2019 12:28:26 -0800 Subject: [PATCH 07/42] update docs for the `name` config option --- docs/configuration.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/configuration.md b/docs/configuration.md index ec5ee3c46..77a0ed0ae 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -239,6 +239,14 @@ window.$docsify = { }; ``` +The name field can also contain custom HTML for easier customization: + +```js +window.$docsify = { + name: 'docsify' +}; +``` + ## nameLink - Type: `String` From db97a1d22a89ddb8de0e1dcbb290a7d7ca4ec1f5 Mon Sep 17 00:00:00 2001 From: Giulio Ambrogi Date: Mon, 30 Dec 2019 16:31:46 +0000 Subject: [PATCH 08/42] Eslint fixes for v4x (#989) * UPDATE .eslintrc * UPDATE lint task * FIX lint errors * CLEANUP * FIX no-eq-null warning * FIX many jsdoc warnings * FIX jsdoc issues * FIX jsdoc warnings * FIX jsdoc * FIX eqeq and no-eq-null * ADD lint to travis * UPDATE test env for eslint --- .eslintrc | 20 +++- .travis.yml | 3 + docs/_media/example.js | 10 +- package.json | 8 +- packages/docsify-server-renderer/index.js | 3 + src/core/config.js | 8 +- src/core/event/scroll.js | 13 ++- src/core/event/sidebar.js | 26 +++-- src/core/fetch/ajax.js | 17 +-- src/core/fetch/index.js | 36 +++--- src/core/index.js | 13 ++- src/core/render/compiler.js | 56 +++++++--- src/core/render/embed.js | 28 ++--- src/core/render/gen-tree.js | 8 +- src/core/render/index.js | 8 ++ src/core/render/progressbar.js | 1 + src/core/render/tpl.js | 26 +++-- src/core/router/history/base.js | 1 + src/core/router/history/hash.js | 11 +- src/core/router/history/html5.js | 12 +- src/core/router/util.js | 13 ++- src/core/util/core.js | 14 ++- src/core/util/dom.js | 25 +++-- src/plugins/ga.js | 1 + src/plugins/matomo.js | 7 +- src/plugins/search/component.js | 3 + src/plugins/search/search.js | 20 ++-- test/_helper.js | 129 +++++++++++----------- test/integration/render.js | 21 ++-- test/integration/router.js | 21 ++-- test/unit/base.js | 123 ++++++++++----------- test/unit/render.js | 73 ++++++------ test/unit/util.js | 59 +++++----- 33 files changed, 464 insertions(+), 353 deletions(-) diff --git a/.eslintrc b/.eslintrc index a8f7cd0c9..3d14bbc2f 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,7 +1,10 @@ { "extends": "xo-space/browser", "rules": { - "semi": [2, "never"], + "semi": [ + 2, + "never" + ], "no-return-assign": "off", "no-unused-expressions": "off", "no-new-func": "off", @@ -10,11 +13,22 @@ "max-params": "off", "no-script-url": "off", "camelcase": "off", - "no-warning-comments": "off" + "object-curly-spacing": "off", + "no-warning-comments": "off", + "no-negated-condition": "off", + "eqeqeq": "warn", + "no-eq-null": "warn", + "max-statements-per-line": "warn" }, "globals": { "Docsify": true, "$docsify": true, "process": true + }, + "env": { + "browser": true, + "amd": true, + "node": true, + "jest": true } -} +} \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 87576c5a3..b97f8f1ca 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,6 @@ sudo: false language: node_js node_js: stable + +script: + - npm run lint diff --git a/docs/_media/example.js b/docs/_media/example.js index 7b6f668cc..8cad2d730 100644 --- a/docs/_media/example.js +++ b/docs/_media/example.js @@ -5,12 +5,12 @@ const PORT = 8080 /// [demo] const result = fetch(`${URL}:${PORT}`) - .then(function(response) { - return response.json(); + .then(function (response) { + return response.json() + }) + .then(function (myJson) { + console.log(JSON.stringify(myJson)) }) - .then(function(myJson) { - console.log(JSON.stringify(myJson)); - }); /// [demo] result.then(console.log).catch(console.error) diff --git a/package.json b/package.json index 9c0197143..c29c8dfff 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "serve:ssr": "cross-env SSR=1 node server", "dev": "run-p serve watch:*", "dev:ssr": "run-p serve:ssr watch:*", - "lint": "eslint {src,packages} --fix", + "lint": "eslint . --fix", "test": "mocha test/*/**", "css": "node build/css", "watch:css": "npm run css -- -o themes -w", @@ -48,8 +48,8 @@ }, "lint-staged": { "*.js": [ - "npm run lint", - "git add" + "npm run lint", + "git add" ] }, "dependencies": { @@ -98,4 +98,4 @@ "collective": { "url": "https://opencollective.com/docsify" } -} +} \ No newline at end of file diff --git a/packages/docsify-server-renderer/index.js b/packages/docsify-server-renderer/index.js index 21fb5c797..5b62effee 100644 --- a/packages/docsify-server-renderer/index.js +++ b/packages/docsify-server-renderer/index.js @@ -21,6 +21,7 @@ function mainTpl(config) { if (config.repo) { html += tpl.corner(config.repo) } + if (config.coverpage) { html += tpl.cover() } @@ -154,12 +155,14 @@ export default class Renderer { if (!res.ok) { throw Error() } + content = await res.text() this.lock = 0 } else { content = await readFileSync(filePath, 'utf8') this.lock = 0 } + return content } catch (e) { this.lock = this.lock || 0 diff --git a/src/core/config.js b/src/core/config.js index f77773726..9a3251e72 100644 --- a/src/core/config.js +++ b/src/core/config.js @@ -23,9 +23,9 @@ export default function () { ext: '.md', mergeNavbar: false, formatUpdated: '', - // this config for the links inside markdown + // This config for the links inside markdown externalLinkTarget: '_blank', - // this config for the corner + // This config for the corner cornerExternalLinkTarget: '_blank', externalLinkRel: 'noopener', routerMode: 'hash', @@ -55,15 +55,19 @@ export default function () { if (config.loadSidebar === true) { config.loadSidebar = '_sidebar' + config.ext } + if (config.loadNavbar === true) { config.loadNavbar = '_navbar' + config.ext } + if (config.coverpage === true) { config.coverpage = '_coverpage' + config.ext } + if (config.repo === true) { config.repo = '' } + if (config.name === true) { config.name = '' } diff --git a/src/core/event/scroll.js b/src/core/event/scroll.js index 3e9e33265..e1f80b77b 100644 --- a/src/core/event/scroll.js +++ b/src/core/event/scroll.js @@ -1,4 +1,4 @@ -import {isMobile} from '../util/env' +import { isMobile } from '../util/env' import * as dom from '../util/dom' import Tweezer from 'tweezer.js' @@ -12,6 +12,7 @@ function scrollTo(el) { if (scroller) { scroller.stop() } + enableScrollEvent = false scroller = new Tweezer({ start: window.pageYOffset, @@ -30,6 +31,7 @@ function highlight(path) { if (!enableScrollEvent) { return } + const sidebar = dom.getNode('.sidebar') const anchors = dom.findAll('.anchor') const wrap = dom.find(sidebar, '.sidebar-nav') @@ -45,14 +47,17 @@ function highlight(path) { if (!last) { last = node } + break } else { last = node } } + if (!last) { return } + const li = nav[getNavKey(decodeURIComponent(path), last.getAttribute('data-id'))] if (!li || li === active) { @@ -88,7 +93,7 @@ export function scrollActiveSidebar(router) { const sidebar = dom.getNode('.sidebar') let lis = [] - if (sidebar != null) { + if (sidebar !== null && sidebar !== undefined) { lis = dom.findAll(sidebar, 'li') } @@ -98,10 +103,11 @@ export function scrollActiveSidebar(router) { if (!a) { continue } + let href = a.getAttribute('href') if (href !== '/') { - const {query: {id}, path} = router.parse(href) + const { query: { id }, path } = router.parse(href) if (id) { href = getNavKey(path, id) } @@ -115,6 +121,7 @@ export function scrollActiveSidebar(router) { if (isMobile) { return } + const path = router.getCurrentPath() dom.off('scroll', () => highlight(path)) dom.on('scroll', () => highlight(path)) diff --git a/src/core/event/sidebar.js b/src/core/event/sidebar.js index 81c3003f5..8aa2bb8b8 100644 --- a/src/core/event/sidebar.js +++ b/src/core/event/sidebar.js @@ -1,17 +1,20 @@ -import {isMobile} from '../util/env' +import { isMobile } from '../util/env' import * as dom from '../util/dom' const title = dom.$.title /** * Toggle button + * @param {Element} el Button to be toggled + * @void */ export function btn(el) { const toggle = _ => dom.body.classList.toggle('close') el = dom.getNode(el) - if (el == null) { + if (el === null || el === undefined) { return } + dom.on(el, 'click', e => { e.stopPropagation() toggle() @@ -27,10 +30,11 @@ export function btn(el) { export function collapse(el) { el = dom.getNode(el) - if (el == null) { + if (el === null || el === undefined) { return } - dom.on(el, 'click', ({target}) => { + + dom.on(el, 'click', ({ target }) => { if ( target.nodeName === 'A' && target.nextSibling && @@ -46,6 +50,7 @@ export function sticky() { if (!cover) { return } + const coverHeight = cover.getBoundingClientRect().height if (window.pageYOffset >= coverHeight || cover.classList.contains('hidden')) { @@ -57,18 +62,19 @@ export function sticky() { /** * Get and active link - * @param {object} router - * @param {string|element} el - * @param {Boolean} isParent acitve parent - * @param {Boolean} autoTitle auto set title - * @return {element} + * @param {Object} router Router + * @param {String|Element} el Target element + * @param {Boolean} isParent Active parent + * @param {Boolean} autoTitle Automatically set title + * @return {Element} Active element */ export function getAndActive(router, el, isParent, autoTitle) { el = dom.getNode(el) let links = [] - if (el != null) { + if (el !== null && el !== undefined) { links = dom.findAll(el, 'a') } + const hash = decodeURI(router.toURL(router.getCurrentPath())) let target diff --git a/src/core/fetch/ajax.js b/src/core/fetch/ajax.js index 5911b7994..c70944a2e 100644 --- a/src/core/fetch/ajax.js +++ b/src/core/fetch/ajax.js @@ -1,23 +1,25 @@ import progressbar from '../render/progressbar' -import {noop, hasOwn} from '../util/core' +import { noop, hasOwn } from '../util/core' const cache = {} /** - * Simple ajax get - * @param {string} url - * @param {boolean} [hasBar=false] has progress bar - * @return { then(resolve, reject), abort } + * Ajax GET implmentation + * @param {string} url Resource URL + * @param {boolean} [hasBar=false] Has progress bar + * @param {String[]} headers Array of headers + * @return {Promise} Promise response */ export function get(url, hasBar = false, headers = {}) { const xhr = new XMLHttpRequest() const on = function () { xhr.addEventListener.apply(xhr, arguments) } + const cached = cache[url] if (cached) { - return {then: cb => cb(cached.content, cached.opt), abort: noop} + return { then: cb => cb(cached.content, cached.opt), abort: noop } } xhr.open('GET', url) @@ -26,6 +28,7 @@ export function get(url, hasBar = false, headers = {}) { xhr.setRequestHeader(i, headers[i]) } } + xhr.send() return { @@ -47,7 +50,7 @@ export function get(url, hasBar = false, headers = {}) { } on('error', error) - on('load', ({target}) => { + on('load', ({ target }) => { if (target.status >= 400) { error(target) } else { diff --git a/src/core/fetch/index.js b/src/core/fetch/index.js index 17208df69..fb4f0d20a 100644 --- a/src/core/fetch/index.js +++ b/src/core/fetch/index.js @@ -1,8 +1,8 @@ -import {get} from './ajax' -import {callHook} from '../init/lifecycle' -import {getParentPath, stringifyQuery} from '../router/util' -import {noop} from '../util/core' -import {getAndActive} from '../event/sidebar' +import { get } from './ajax' +import { callHook } from '../init/lifecycle' +import { getParentPath, stringifyQuery } from '../router/util' +import { noop } from '../util/core' +import { getAndActive } from '../event/sidebar' function loadNested(path, qs, file, next, vm, first) { path = first ? path : path.replace(/\/$/, '') @@ -30,7 +30,7 @@ export function fetchMixin(proto) { } const get404Path = (path, config) => { - const {notFoundPage, ext} = config + const { notFoundPage, ext } = config const defaultPath = '_404' + (ext || '.md') let key let path404 @@ -75,9 +75,9 @@ export function fetchMixin(proto) { } proto._fetch = function (cb = noop) { - const {path, query} = this.route + const { path, query } = this.route const qs = stringifyQuery(query, ['id']) - const {loadNavbar, requestHeaders, loadSidebar} = this.config + const { loadNavbar, requestHeaders, loadSidebar } = this.config // Abort last request const file = this.router.getFile(path) @@ -112,7 +112,7 @@ export function fetchMixin(proto) { } proto._fetchCover = function () { - const {coverpage, requestHeaders} = this.config + const { coverpage, requestHeaders } = this.config const query = this.route.query const root = getParentPath(this.route.path) @@ -140,6 +140,7 @@ export function fetchMixin(proto) { } else { this._renderCover(null, coverOnly) } + return coverOnly } } @@ -163,7 +164,7 @@ export function fetchMixin(proto) { } proto._fetchFallbackPage = function (path, qs, cb = noop) { - const {requestHeaders, fallbackLanguages, loadSidebar} = this.config + const { requestHeaders, fallbackLanguages, loadSidebar } = this.config if (!fallbackLanguages) { return false @@ -174,6 +175,7 @@ export function fetchMixin(proto) { if (fallbackLanguages.indexOf(local) === -1) { return false } + const newPath = path.replace(new RegExp(`^/${local}`), '') const req = request(newPath + qs, true, requestHeaders) @@ -189,16 +191,17 @@ export function fetchMixin(proto) { return true } + /** * Load the 404 page - * @param path - * @param qs - * @param cb - * @returns {*} + * @param {String} path URL to be loaded + * @param {*} qs TODO: define + * @param {Function} cb Callback + * @returns {Boolean} True if the requested page is not found * @private */ proto._fetch404 = function (path, qs, cb = noop) { - const {loadSidebar, requestHeaders, notFoundPage} = this.config + const { loadSidebar, requestHeaders, notFoundPage } = this.config const fnLoadSideAndNav = this._loadSideAndNav(path, qs, loadSidebar, cb) if (notFoundPage) { @@ -217,7 +220,7 @@ export function fetchMixin(proto) { } export function initFetch(vm) { - const {loadSidebar} = vm.config + const { loadSidebar } = vm.config // Server-Side Rendering if (vm.rendered) { @@ -225,6 +228,7 @@ export function initFetch(vm) { if (loadSidebar && activeEl) { activeEl.parentNode.innerHTML += window.__SUB_SIDEBAR__ } + vm._bindEventOnRendered(activeEl) vm.$resetEvents() callHook(vm, 'doneEach') diff --git a/src/core/index.js b/src/core/index.js index ebb7fe3f2..cc00cc1f2 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -1,12 +1,15 @@ -import {initMixin} from './init' -import {routerMixin} from './router' -import {renderMixin} from './render' -import {fetchMixin} from './fetch' -import {eventMixin} from './event' +import { initMixin } from './init' +import { routerMixin } from './router' +import { renderMixin } from './render' +import { fetchMixin } from './fetch' +import { eventMixin } from './event' import initGlobalAPI from './global-api' /** * Fork https://github.com/bendrucker/document-ready/blob/master/index.js + * @param {Function} callback The callbacack to be called when the page is loaded + * @returns {Number|void} If the page is already laoded returns the result of the setTimeout callback, + * otherwise it only attaches the callback to the DOMContentLoaded event */ function ready(callback) { const state = document.readyState diff --git a/src/core/render/compiler.js b/src/core/render/compiler.js index 2f7ce1528..ff74711a3 100644 --- a/src/core/render/compiler.js +++ b/src/core/render/compiler.js @@ -1,11 +1,11 @@ import marked from 'marked' import Prism from 'prismjs' -import {helper as helperTpl, tree as treeTpl} from './tpl' -import {genTree} from './gen-tree' -import {slugify} from './slugify' -import {emojify} from './emojify' -import {isAbsolutePath, getPath, getParentPath} from '../router/util' -import {isFn, merge, cached, isPrimitive} from '../util/core' +import { helper as helperTpl, tree as treeTpl } from './tpl' +import { genTree } from './gen-tree' +import { slugify } from './slugify' +import { emojify } from './emojify' +import { isAbsolutePath, getPath, getParentPath } from '../router/util' +import { isFn, merge, cached, isPrimitive } from '../util/core' // See https://github.com/PrismJS/prism/pull/1367 import 'prismjs/components/prism-markup-templating' @@ -26,7 +26,7 @@ export function getAndRemoveConfig(str = '') { .trim() } - return {str, config} + return { str, config } } const compileMedia = { @@ -132,7 +132,7 @@ export class Compiler { } compileEmbed(href, title) { - const {str, config} = getAndRemoveConfig(title) + const { str, config } = getAndRemoveConfig(title) let embed title = str @@ -162,9 +162,11 @@ export class Compiler { } else if (/\.mp3/.test(href)) { type = 'audio' } + embed = compileMedia[type].call(this, href, title) embed.type = type } + embed.fragment = config.fragment return embed @@ -186,17 +188,20 @@ export class Compiler { _initRenderer() { const renderer = new marked.Renderer() - const {linkTarget, linkRel, router, contentBase} = this + const { linkTarget, linkRel, router, contentBase } = this const _self = this const origin = {} /** * Render anchor tag * @link https://github.com/markedjs/marked#overriding-renderer-methods + * @param {String} text Text content + * @param {Number} level Type of heading (h tag) + * @returns {String} Heading element */ origin.heading = renderer.heading = function (text, level) { - let {str, config} = getAndRemoveConfig(text) - const nextToc = {level, title: str} + let { str, config } = getAndRemoveConfig(text) + const nextToc = { level, title: str } if (/{docsify-ignore}/g.test(str)) { str = str.replace('{docsify-ignore}', '') @@ -211,12 +216,13 @@ export class Compiler { } const slug = slugify(config.id || str) - const url = router.toURL(router.getCurrentPath(), {id: slug}) + const url = router.toURL(router.getCurrentPath(), { id: slug }) nextToc.slug = url _self.toc.push(nextToc) return `${str}` } + // Highlight code origin.code = renderer.code = function (code, lang = '') { code = code.replace(/@DOCSIFY_QM@/g, '`') @@ -227,10 +233,11 @@ export class Compiler { return `
    ${hl}
    ` } + origin.link = renderer.link = function (href, title = '', text) { let attrs = '' - const {str, config} = getAndRemoveConfig(title) + const { str, config } = getAndRemoveConfig(title) title = str if ( @@ -241,6 +248,7 @@ export class Compiler { if (href === _self.config.homepage) { href = 'README' } + href = router.toURL(href, null, router.getCurrentPath()) } else { attrs += href.indexOf('mailto:') === 0 ? '' : ` target="${linkTarget}"` @@ -262,6 +270,7 @@ export class Compiler { return `${text}` } + origin.paragraph = renderer.paragraph = function (text) { let result if (/^!>/.test(text)) { @@ -271,13 +280,15 @@ export class Compiler { } else { result = `

    ${text}

    ` } + return result } + origin.image = renderer.image = function (href, title, text) { let url = href let attrs = '' - const {str, config} = getAndRemoveConfig(title) + const { str, config } = getAndRemoveConfig(title) title = str if (config['no-zoom']) { @@ -304,6 +315,7 @@ export class Compiler { return `${text}` } + origin.list = renderer.list = function (body, ordered, start) { const isTaskList = /
  • /.test(body.split('class="task-list"')[0]) const isStartReq = start && start > 1 @@ -315,6 +327,7 @@ export class Compiler { return `<${tag} ${tagAttrs}>${body}` } + origin.listitem = renderer.listitem = function (text) { const isTaskItem = /^(]*>)/.test(text) const html = isTaskItem ? `
  • ` : `
  • ${text}
  • ` @@ -329,9 +342,12 @@ export class Compiler { /** * Compile sidebar + * @param {String} text Text content + * @param {Number} level Type of heading (h tag) + * @returns {String} Sidebar element */ sidebar(text, level) { - const {toc} = this + const { toc } = this const currentPath = this.router.getCurrentPath() let html = '' @@ -346,9 +362,11 @@ export class Compiler { for (let j = i; deletedHeaderLevel < toc[j].level && j < toc.length; j++) { toc.splice(j, 1) && j-- && i++ } + i-- } } + const tree = this.cacheTree[currentPath] || genTree(toc, level) html = treeTpl(tree, '
      {inner}
    ') this.cacheTree[currentPath] = tree @@ -359,14 +377,17 @@ export class Compiler { /** * Compile sub sidebar + * @param {Number} level Type of heading (h tag) + * @returns {String} Sub-sidebar element */ subSidebar(level) { if (!level) { this.toc = [] return } + const currentPath = this.router.getCurrentPath() - const {cacheTree, toc} = this + const { cacheTree, toc } = this toc[0] && toc[0].ignoreAllSubs && toc.splice(0) toc[0] && toc[0].level === 1 && toc.shift() @@ -374,6 +395,7 @@ export class Compiler { for (let i = 0; i < toc.length; i++) { toc[i].ignoreSubHeading && toc.splice(i, 1) && i-- } + const tree = cacheTree[currentPath] || genTree(toc, level) cacheTree[currentPath] = tree @@ -387,6 +409,8 @@ export class Compiler { /** * Compile cover page + * @param {Text} text Text content + * @returns {String} Cover page */ cover(text) { const cacheToc = this.toc.slice() diff --git a/src/core/render/embed.js b/src/core/render/embed.js index 821837488..eefa07bda 100644 --- a/src/core/render/embed.js +++ b/src/core/render/embed.js @@ -1,9 +1,9 @@ -import {get} from '../fetch/ajax' -import {merge} from '../util/core' +import { get } from '../fetch/ajax' +import { merge } from '../util/core' const cached = {} -function walkFetchEmbed({embedTokens, compile, fetch}, cb) { +function walkFetchEmbed({ embedTokens, compile, fetch }, cb) { let token let step = 0 let count = 1 @@ -23,26 +23,28 @@ function walkFetchEmbed({embedTokens, compile, fetch}, cb) { if (token.embed.fragment) { const fragment = token.embed.fragment const pattern = new RegExp(`(?:###|\\/\\/\\/)\\s*\\[${fragment}\\]([\\s\\S]*)(?:###|\\/\\/\\/)\\s*\\[${fragment}\\]`) - text = ((text.match(pattern) || [])[1] || '').trim() + text = ((text.match(pattern) || [])[1] || '').trim() } + embedToken = compile.lexer( '```' + - token.embed.lang + - '\n' + - text.replace(/`/g, '@DOCSIFY_QM@') + - '\n```\n' + token.embed.lang + + '\n' + + text.replace(/`/g, '@DOCSIFY_QM@') + + '\n```\n' ) } else if (token.embed.type === 'mermaid') { embedToken = [ - {type: 'html', text: `
    \n${text}\n
    `} + { type: 'html', text: `
    \n${text}\n
    ` } ] embedToken.links = {} } else { - embedToken = [{type: 'html', text}] + embedToken = [{ type: 'html', text }] embedToken.links = {} } } - cb({token, embedToken}) + + cb({ token, embedToken }) if (++count >= step) { cb({}) } @@ -61,7 +63,7 @@ function walkFetchEmbed({embedTokens, compile, fetch}, cb) { } } -export function prerenderEmbed({compiler, raw = '', fetch}, done) { +export function prerenderEmbed({ compiler, raw = '', fetch }, done) { let hit = cached[raw] if (hit) { const copy = hit.slice() @@ -96,7 +98,7 @@ export function prerenderEmbed({compiler, raw = '', fetch}, done) { }) let moveIndex = 0 - walkFetchEmbed({compile, embedTokens, fetch}, ({embedToken, token}) => { + walkFetchEmbed({ compile, embedTokens, fetch }, ({ embedToken, token }) => { if (token) { const index = token.index + moveIndex diff --git a/src/core/render/gen-tree.js b/src/core/render/gen-tree.js index 81ba4bd22..24dffe70c 100644 --- a/src/core/render/gen-tree.js +++ b/src/core/render/gen-tree.js @@ -1,9 +1,9 @@ /** * Gen toc tree * @link https://github.com/killercup/grock/blob/5280ae63e16c5739e9233d9009bc235ed7d79a50/styles/solarized/assets/js/behavior.coffee#L54-L81 - * @param {Array} toc - * @param {Number} maxLevel - * @return {Array} + * @param {Array} toc List of TOC elements + * @param {Number} maxLevel Deep level + * @return {Array} Headlines */ export function genTree(toc, maxLevel) { const headlines = [] @@ -16,11 +16,13 @@ export function genTree(toc, maxLevel) { if (level > maxLevel) { return } + if (last[len]) { last[len].children = (last[len].children || []).concat(headline) } else { headlines.push(headline) } + last[level] = headline }) diff --git a/src/core/render/index.js b/src/core/render/index.js index b4d16006d..5df3c4cd5 100644 --- a/src/core/render/index.js +++ b/src/core/render/index.js @@ -18,6 +18,7 @@ function executeScript() { if (!script) { return false } + const code = script.innerText.trim() if (!code) { return false @@ -102,6 +103,7 @@ export function renderMixin(proto) { // Reset toc this.compiler.subSidebar() } + // Bind event this._bindEventOnRendered(activeEl) } @@ -145,6 +147,7 @@ export function renderMixin(proto) { callHook(this, 'afterEach', html, text => renderMain.call(this, text)) } + if (this.isHTML) { html = this.result = text callback() @@ -173,6 +176,7 @@ export function renderMixin(proto) { dom.toggleClass(el, 'remove', 'show') return } + dom.toggleClass(el, 'add', 'show') let html = this.coverIsHTML ? text : this.compiler.cover(text) @@ -191,10 +195,12 @@ export function renderMixin(proto) { if (!isAbsolutePath(m[1])) { path = getPath(this.router.getBasePath(), m[1]) } + el.style.backgroundImage = `url(${path})` el.style.backgroundSize = 'cover' el.style.backgroundPosition = 'center center' } + html = html.replace(m[0], '') } @@ -228,6 +234,7 @@ export function initRender(vm) { if (config.repo) { html += tpl.corner(config.repo, config.cornerExternalLinkTarge) } + if (config.coverpage) { html += tpl.cover() } @@ -271,6 +278,7 @@ export function initRender(vm) { // Polyfll cssVars(config.themeColor) } + vm._updateRender() dom.toggleClass(dom.body, 'ready') } diff --git a/src/core/render/progressbar.js b/src/core/render/progressbar.js index df1546469..61a2aae22 100644 --- a/src/core/render/progressbar.js +++ b/src/core/render/progressbar.js @@ -13,6 +13,7 @@ function init() { dom.appendTo(dom.body, div) barEl = div } + /** * Render progress bar */ diff --git a/src/core/render/tpl.js b/src/core/render/tpl.js index 9e3fab126..41f63a75b 100644 --- a/src/core/render/tpl.js +++ b/src/core/render/tpl.js @@ -1,8 +1,9 @@ import { isMobile } from '../util/env' /** * Render github corner - * @param {Object} data - * @return {String} + * @param {Object} data URL for the View Source on Github link + * @param {String} cornerExternalLinkTarge value of the target attribute of the link + * @return {String} SVG element as string */ export function corner(data, cornerExternalLinkTarge) { if (!data) { @@ -29,7 +30,9 @@ export function corner(data, cornerExternalLinkTarge) { } /** - * Render main content + * Renders main content + * @param {Object} config Configuration object + * @returns {String} HTML of the main content */ export function main(config) { const name = config.name ? config.name : '' @@ -41,11 +44,11 @@ export function main(config) { '' + '' + '' @@ -60,6 +63,7 @@ export function main(config) { /** * Cover Page + * @returns {String} Cover page */ export function cover() { const SL = ', 100%, 85%' @@ -78,9 +82,9 @@ export function cover() { /** * Render tree - * @param {Array} tree - * @param {String} tpl - * @return {String} + * @param {Array} toc Array of TOC section links + * @param {String} tpl TPL list + * @return {String} Rendered tree */ export function tree(toc, tpl = '
      {inner}
    ') { if (!toc || !toc.length) { diff --git a/src/core/router/history/base.js b/src/core/router/history/base.js index 7ea763d8d..4c570df1c 100644 --- a/src/core/router/history/base.js +++ b/src/core/router/history/base.js @@ -81,6 +81,7 @@ export class History { const currentDir = currentRoute.substring(0, currentRoute.lastIndexOf('/') + 1) return cleanPath(resolvePath(currentDir + path)) } + return cleanPath('/' + path) } } diff --git a/src/core/router/history/hash.js b/src/core/router/history/hash.js index 2674d5d0d..4e1b1a361 100644 --- a/src/core/router/history/hash.js +++ b/src/core/router/history/hash.js @@ -1,7 +1,7 @@ -import {History} from './base' -import {noop} from '../../util/core' -import {on} from '../../util/dom' -import {parseQuery, cleanPath, replaceSlug} from '../util' +import { History } from './base' +import { noop } from '../../util/core' +import { on } from '../../util/dom' +import { parseQuery, cleanPath, replaceSlug } from '../util' function replaceHash(path) { const i = location.href.indexOf('#') @@ -41,12 +41,13 @@ export class HashHistory extends History { if (path.charAt(0) === '/') { return replaceHash(path) } + replaceHash('/' + path) } /** * Parse the url - * @param {string} [path=location.herf] + * @param {string} [path=location.herf] URL to be parsed * @return {object} { path, query } */ parse(path = location.href) { diff --git a/src/core/router/history/html5.js b/src/core/router/history/html5.js index 04c53919b..a3bda1391 100644 --- a/src/core/router/history/html5.js +++ b/src/core/router/history/html5.js @@ -1,7 +1,7 @@ -import {History} from './base' -import {noop} from '../../util/core' -import {on} from '../../util/dom' -import {parseQuery, getPath} from '../util' +import { History } from './base' +import { noop } from '../../util/core' +import { on } from '../../util/dom' +import { parseQuery, getPath } from '../util' export class HTML5History extends History { constructor(config) { @@ -27,7 +27,7 @@ export class HTML5History extends History { if (el.tagName === 'A' && !/_blank/.test(el.target)) { e.preventDefault() const url = el.href - window.history.pushState({key: url}, '', url) + window.history.pushState({ key: url }, '', url) cb() } }) @@ -37,7 +37,7 @@ export class HTML5History extends History { /** * Parse the url - * @param {string} [path=location.href] + * @param {string} [path=location.href] URL to be parsed * @return {object} { path, query } */ parse(path = location.href) { diff --git a/src/core/router/util.js b/src/core/router/util.js index 2ed88c58f..8b3ce7b4a 100644 --- a/src/core/router/util.js +++ b/src/core/router/util.js @@ -1,4 +1,4 @@ -import {cached} from '../util/core' +import { cached } from '../util/core' const decode = decodeURIComponent const encode = encodeURIComponent @@ -29,6 +29,7 @@ export function stringifyQuery(obj, ignores = []) { if (ignores.indexOf(key) > -1) { continue } + qs.push( obj[key] ? `${encode(key)}=${encode(obj[key])}`.toLowerCase() : @@ -44,9 +45,12 @@ export const isAbsolutePath = cached(path => { }) export const getParentPath = cached(path => { - return /\/$/g.test(path) ? - path : - (path = path.match(/(\S*\/)[^/]+$/)) ? path[1] : '' + if (/\/$/g.test(path)) { + return path + } + + const matchingParts = path.match(/(\S*\/)[^/]+$/) + return matchingParts ? matchingParts[1] : '' }) export const cleanPath = cached(path => { @@ -64,6 +68,7 @@ export const resolvePath = cached(path => { resolved.push(segment) } } + return '/' + resolved.join('/') }) diff --git a/src/core/util/core.js b/src/core/util/core.js index 0df54c9c3..2d4f20c9b 100644 --- a/src/core/util/core.js +++ b/src/core/util/core.js @@ -1,6 +1,9 @@ /** * Create a cached version of a pure function. + * @param {*} fn The function call to be cached + * @void */ + export function cached(fn) { const cache = Object.create(null) return function (str) { @@ -21,6 +24,8 @@ export const hasOwn = Object.prototype.hasOwnProperty /** * Simple Object.assign polyfill + * @param {Object} to The object to be merged with + * @returns {Object} The merged object */ export const merge = Object.assign || @@ -40,18 +45,23 @@ export const merge = /** * Check if value is primitive + * @param {*} value Checks if a value is primitive + * @returns {Boolean} Result of the check */ export function isPrimitive(value) { return typeof value === 'string' || typeof value === 'number' } /** - * Perform no operation. + * Performs no operation. + * @void */ -export function noop() {} +export function noop() { } /** * Check if value is function + * @param {*} obj Any javascript object + * @returns {Boolean} True if the passed-in value is a function */ export function isFn(obj) { return typeof obj === 'function' diff --git a/src/core/util/dom.js b/src/core/util/dom.js index 388927d11..3d529bba5 100644 --- a/src/core/util/dom.js +++ b/src/core/util/dom.js @@ -1,19 +1,20 @@ -import {isFn} from '../util/core' -import {inBrowser} from './env' +import { isFn } from '../util/core' +import { inBrowser } from './env' const cacheNode = {} /** * Get Node - * @param {String|Element} el - * @param {Boolean} noCache - * @return {Element} + * @param {String|Element} el A DOM element + * @param {Boolean} noCache Flag to use or not use the cache + * @return {Element} The found node element */ export function getNode(el, noCache = false) { if (typeof el === 'string') { if (typeof window.Vue !== 'undefined') { return find(el) } + el = noCache ? find(el) : cacheNode[el] || (cacheNode[el] = find(el)) } @@ -27,7 +28,10 @@ export const body = inBrowser && $.body export const head = inBrowser && $.head /** - * Find element + * Find elements + * @param {String|Element} el The root element where to perform the search from + * @param {Element} node The query + * @returns {Element} The found DOM element * @example * find('nav') => document.querySelector('nav') * find(nav, 'a') => nav.querySelector('a') @@ -38,6 +42,9 @@ export function find(el, node) { /** * Find all elements + * @param {String|Element} el The root element where to perform the search from + * @param {Element} node The query + * @returns {Array} An array of DOM elements * @example * findAll('a') => [].slice.call(document.querySelectorAll('a')) * findAll(nav, 'a') => [].slice.call(nav.querySelectorAll('a')) @@ -53,6 +60,7 @@ export function create(node, tpl) { if (tpl) { node.innerHTML = tpl } + return node } @@ -78,7 +86,10 @@ export function off(el, type, handler) { /** * Toggle class - * + * @param {String|Element} el The element that needs the class to be toggled + * @param {Element} type The type of action to be performed on the classList (toggle by default) + * @param {String} val Name of the class to be toggled + * @void * @example * toggleClass(el, 'active') => el.classList.toggle('active') * toggleClass(el, 'add', 'active') => el.classList.add('active') diff --git a/src/plugins/ga.js b/src/plugins/ga.js index 2d6419bbf..b327d9b5d 100644 --- a/src/plugins/ga.js +++ b/src/plugins/ga.js @@ -13,6 +13,7 @@ function init(id) { function () { (window.ga.q = window.ga.q || []).push(arguments) } + window.ga.l = Number(new Date()) window.ga('create', id, 'auto') } diff --git a/src/plugins/matomo.js b/src/plugins/matomo.js index 7b61cba7c..a27de2a06 100644 --- a/src/plugins/matomo.js +++ b/src/plugins/matomo.js @@ -9,10 +9,10 @@ function init(options) { window._paq = window._paq || [] window._paq.push(['trackPageView']) window._paq.push(['enableLinkTracking']) - setTimeout(function() { + setTimeout(function () { appendScript(options) window._paq.push(['setTrackerUrl', options.host + '/matomo.php']) - window._paq.push(['setSiteId', options.id + '']) + window._paq.push(['setSiteId', String(options.id)]) }, 0) } @@ -20,7 +20,8 @@ function collect() { if (!window._paq) { init($docsify.matomo) } - window._paq.push(['setCustomUrl', window.location.hash.substr(1)]) + + window._paq.push(['setCustomUrl', window.location.hash.substr(1)]) window._paq.push(['setDocumentTitle', document.title]) window._paq.push(['trackPageView']) } diff --git a/src/plugins/search/component.js b/src/plugins/search/component.js index 4daf5fd3e..37f964e9c 100644 --- a/src/plugins/search/component.js +++ b/src/plugins/search/component.js @@ -139,8 +139,10 @@ function doSearch(value) { $sidebarNav.classList.remove('hide') $appName.classList.remove('hide') } + return } + const matchs = search(value) let html = '' @@ -193,6 +195,7 @@ function updatePlaceholder(text, path) { if (!$input) { return } + if (typeof text === 'string') { $input.placeholder = text } else { diff --git a/src/plugins/search/search.js b/src/plugins/search/search.js index 2c9febfbc..73dbdb2c0 100644 --- a/src/plugins/search/search.js +++ b/src/plugins/search/search.js @@ -8,6 +8,7 @@ const LOCAL_STORAGE = { function resolveExpireKey(namespace) { return namespace ? `${LOCAL_STORAGE.EXPIRE_KEY}/${namespace}` : LOCAL_STORAGE.EXPIRE_KEY } + function resolveIndexKey(namespace) { return namespace ? `${LOCAL_STORAGE.INDEX_KEY}/${namespace}` : LOCAL_STORAGE.INDEX_KEY } @@ -58,14 +59,15 @@ export function genIndex(path, content = '', router, depth) { tokens.forEach(token => { if (token.type === 'heading' && token.depth <= depth) { - slug = router.toURL(path, {id: slugify(token.text)}) - index[slug] = {slug, title: token.text, body: ''} + slug = router.toURL(path, { id: slugify(token.text) }) + index[slug] = { slug, title: token.text, body: '' } } else { if (!slug) { return } + if (!index[slug]) { - index[slug] = {slug, title: '', body: ''} + index[slug] = { slug, title: '', body: '' } } else if (index[slug].body) { index[slug].body += '\n' + (token.text || '') } else { @@ -78,8 +80,8 @@ export function genIndex(path, content = '', router, depth) { } /** - * @param {String} query - * @returns {Array} + * @param {String} query Search query + * @returns {Array} Array of results */ export function search(query) { const matchingResults = [] @@ -103,12 +105,12 @@ export function search(query) { const postUrl = post.slug || '' if (postTitle) { - keywords.forEach( keyword => { + keywords.forEach(keyword => { // From https://github.com/sindresorhus/escape-string-regexp const regEx = new RegExp( keyword.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&'), 'gi' - ); + ) let indexTitle = -1 let indexContent = -1 @@ -116,7 +118,7 @@ export function search(query) { indexContent = postContent ? postContent.search(regEx) : -1 if (indexTitle >= 0 || indexContent >= 0) { - matchesScore += indexTitle >= 0 ? 3 : indexContent >= 0 ? 2 : 0; + matchesScore += indexTitle >= 0 ? 3 : indexContent >= 0 ? 2 : 0 if (indexContent < 0) { indexContent = 0 } @@ -155,7 +157,7 @@ export function search(query) { } } - return matchingResults.sort((r1, r2) => r2.score - r1.score); + return matchingResults.sort((r1, r2) => r2.score - r1.score) } export function init(config, vm) { diff --git a/test/_helper.js b/test/_helper.js index 4b4abce89..b638cd819 100644 --- a/test/_helper.js +++ b/test/_helper.js @@ -1,10 +1,10 @@ -// load ES6 modules in Node.js on the fly -require = require('esm')(module/*, options*/) +// Load ES6 modules in Node.js on the fly +require = require('esm')(module/* , options */) /* eslint-disable-line no-global-assign */ const path = require('path') -const {expect} = require('chai') +const { expect } = require('chai') -const {JSDOM} = require('jsdom') +const { JSDOM } = require('jsdom') function ready(callback) { const state = document.readyState @@ -15,9 +15,10 @@ function ready(callback) { document.addEventListener('DOMContentLoaded', callback) } -module.exports.init = function(fixture = 'default', config = {}, markup) { - if (markup == null) { - markup = ` + +module.exports.init = function (fixture = 'default', config = {}, markup = null) { + if (markup === null || markup === undefined) { + markup = ` @@ -27,61 +28,63 @@ module.exports.init = function(fixture = 'default', config = {}, markup) { ` - } - const rootPath = path.join(__dirname, 'fixtures', fixture) - - const dom = new JSDOM(markup) - dom.reconfigure({ url: 'file:///' + rootPath }) - - global.window = dom.window - global.document = dom.window.document - global.navigator = dom.window.navigator - global.location = dom.window.location - global.XMLHttpRequest = dom.window.XMLHttpRequest - - // mimic src/core/index.js but for Node.js - function Docsify() { - this._init() - } - - const proto = Docsify.prototype - - const {initMixin} = require('../src/core/init') - const {routerMixin} = require('../src/core//router') - const {renderMixin} = require('../src/core//render') - const {fetchMixin} = require('../src/core/fetch') - const {eventMixin} = require('../src/core//event') - - initMixin(proto) - routerMixin(proto) - renderMixin(proto) - fetchMixin(proto) - eventMixin(proto) - - const NOT_INIT_PATTERN = '' - - return new Promise((resolve, reject) => { - ready(() => { - const docsify = new Docsify() - // NOTE: I was not able to get it working with a callback, but polling works usually at the first time - const id = setInterval(() => { - if (dom.window.document.body.innerHTML.indexOf(NOT_INIT_PATTERN) == -1) { - clearInterval(id) - return resolve({ - docsify: docsify, - dom: dom - }) - } - }, 10) - }) - - }) + } + + const rootPath = path.join(__dirname, 'fixtures', fixture) + + const dom = new JSDOM(markup) + dom.reconfigure({ url: 'file:///' + rootPath }) + + global.window = dom.window + global.document = dom.window.document + global.navigator = dom.window.navigator + global.location = dom.window.location + global.XMLHttpRequest = dom.window.XMLHttpRequest + + // Mimic src/core/index.js but for Node.js + function Docsify() { + this._init() + } + + const proto = Docsify.prototype + + const { initMixin } = require('../src/core/init') + const { routerMixin } = require('../src/core//router') + const { renderMixin } = require('../src/core//render') + const { fetchMixin } = require('../src/core/fetch') + const { eventMixin } = require('../src/core//event') + + initMixin(proto) + routerMixin(proto) + renderMixin(proto) + fetchMixin(proto) + eventMixin(proto) + + const NOT_INIT_PATTERN = '' + + return new Promise(resolve => { + ready(() => { + const docsify = new Docsify() + // NOTE: I was not able to get it working with a callback, but polling works usually at the first time + const id = setInterval(() => { + if (dom.window.document.body.innerHTML.indexOf(NOT_INIT_PATTERN) === -1) { + clearInterval(id) + return resolve({ + docsify: docsify, + dom: dom + }) + } + }, 10) + }) + }) } -module.exports.expectSameDom = function(actual, expected) { - const WHITESPACES_BETWEEN_TAGS = />(\s\s+)(\s\s+) **Time** is money, my friend!') + expect(output).equal('

    Time is money, my friend!

    ') + }) -describe('render', function() { - it('important content (tips)', async function() { - const {docsify, dom} = await init() - const output = docsify.compiler.compile('!> **Time** is money, my friend!') - expect(output).equal('

    Time is money, my friend!

    ') - }) - - describe('lists', function() { - it('as unordered task list', async function() { - const {docsify, dom} = await init() - const output = docsify.compiler.compile(` + describe('lists', function () { + it('as unordered task list', async function () { + const { docsify } = await init() + const output = docsify.compiler.compile(` - [x] Task 1 - [ ] Task 2 - [ ] Task 3`) - expect(output, `