diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 5326336cc6..0c8ea6d125 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -33,7 +33,7 @@ body: label: Steps to reproduce description: | A description with steps to reproduce the issue. - Provide a link to a public repository or create a reproducible [sandbox](https://codesandbox.io/s/307qqv236): + Provide a link to a public repository or create a reproducible [sandbox](https://sandbox.docsifyjs.org/): placeholder: | 1. Step 1 2. Step 2 diff --git a/.github/semantic.yml b/.github/semantic.yml deleted file mode 100644 index e7f5bb59b9..0000000000 --- a/.github/semantic.yml +++ /dev/null @@ -1,4 +0,0 @@ -titleAndCommits: true -allowMergeCommits: true -allowRevertCommits: true -anyCommit: true diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8bb0b5348b..8019d5ce43 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -96,7 +96,7 @@ jobs: uses: actions/upload-artifact@v7 if: failure() with: - name: ${{ matrix.os }}-${{ matrix.node-version }}-artifacts + name: test-artifacts-${{ github.run_id }}-${{ github.run_attempt }} path: | _playwright-results/ _playwright-report/ diff --git a/README.md b/README.md index 192a8c00f4..5813199be6 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ Docsify turns one or more Markdown files into a Website, with no build process r Get going fast by using a static web server or GitHub Pages with this ready-to-use [Docsify Template](https://github.com/docsifyjs/docsify-template), review the [quick start tutorial](https://docsify.js.org/#/quickstart) or jump right into a CodeSandbox example site with the button below. -[![Edit 307qqv236](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/307qqv236) +[![Edit in CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://sandbox.docsifyjs.org/) ## Showcase diff --git a/docs/README.md b/docs/README.md index 48fb465889..b3aefaa74e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -17,7 +17,7 @@ Docsify turns your Markdown files into a documentation website instantly. Unlike ## Examples -Check out the [Showcase](https://github.com/docsifyjs/awesome-docsify#showcase) to see docsify in use. +Check out the [Showcase](awesome?id=showcase) to see docsify in use. ## Donate diff --git a/docs/configuration.md b/docs/configuration.md index 7b61752984..23ca300b93 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -306,6 +306,20 @@ window.$docsify = { }; ``` +## sidebarPosition + +- Type: `String` +- Default: `'left'` + +Controls which side of the page displays the sidebar. Set this to `'right'` to +place the sidebar and its toggle on the right. + +```js +window.$docsify = { + sidebarPosition: 'right', +}; +``` + ## homepage - Type: `String` diff --git a/docs/plugins.md b/docs/plugins.md index 00da722c81..bca83191b4 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -65,6 +65,11 @@ By default, the hyperlink on the current page is recognized and the content is s // You can provide a regexp to match prefixes. In this case, // the matching substring will be used to identify the index pathNamespaces: /^(\/(zh-cn|ru-ru))?(\/(v1|v2))?/, + + // Show where each result comes from (default: 'none') + // 'page': the page title, e.g. "Guide" + // 'breadcrumb': the sidebar path, e.g. "Basics โ€บ Guide" + resultSource: 'none', }, }; diff --git a/docs/v5-upgrade.md b/docs/v5-upgrade.md index cd30ce455d..4a7f6b6cdd 100644 --- a/docs/v5-upgrade.md +++ b/docs/v5-upgrade.md @@ -101,7 +101,7 @@ View [Theme Classes](themes.md?id=classes) for more details. - + ``` **Note:** If you're using additional Docsify plugins (such as emoji, external-script, front-matter, etc.), you'll need to update those URLs as well following the same pattern: @@ -115,7 +115,6 @@ View [Theme Classes](themes.md?id=classes) for more details. - **CDN Path**: Changed from `/lib/` to `/dist/` - **Version**: Updated from `@4` to `@5` - **Themes**: v5 uses a core theme (with optional add-ons available) -- **Plugin Names**: `zoom-image` โ†’ `zoom` ## Additional Notes diff --git a/package-lock.json b/package-lock.json index 387390f197..d5e8ec87fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "@types/eslint": "^8.40.2", "@types/prismjs": "^1.26.5", "axios": "^1.5.0", - "browser-sync": "^3.0.2", + "browser-sync": "^3.0.4", "cross-env": "^10.0.0", "cssnano": "^8.0.2", "eslint": "^9.3.0", @@ -15181,9 +15181,9 @@ "dev": true }, "node_modules/nanoid": { - "version": "3.3.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", - "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", "dev": true, "funding": [ { @@ -15908,9 +15908,9 @@ } }, "node_modules/postcss": { - "version": "8.5.15", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", - "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "version": "8.5.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz", + "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==", "dev": true, "funding": [ { @@ -15928,7 +15928,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.12", + "nanoid": "^3.3.16", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, diff --git a/src/core/config.js b/src/core/config.js index b2e2fdb9e2..2648a9824e 100644 --- a/src/core/config.js +++ b/src/core/config.js @@ -58,6 +58,7 @@ const defaultDocsifyConfig = () => ({ skipLink: /** @type {false | string | Record} */ ( 'Skip to main content' ), + sidebarPosition: /** @type {'left' | 'right'} */ ('left'), subMaxLevel: 0, vueComponents: /** @type {Record} */ ({}), vueGlobalOptions: /** @type {Record} */ ({}), diff --git a/src/core/event/index.js b/src/core/event/index.js index 8395761430..ad194647c5 100644 --- a/src/core/event/index.js +++ b/src/core/event/index.js @@ -504,12 +504,10 @@ export function Events(Base) { href = stripUrlExceptId(href); const oldActive = dom.find(sidebar, 'li.active'); - const newActive = dom - .find( - sidebar, - `a[href="${href}"], a[href="${decodeURIComponent(/** @type {string} */ (href))}"]`, - ) - ?.closest('li'); + const sidebarSelector = `.sidebar-nav a[href="${href}"], .sidebar-nav a[href="${decodeURIComponent( + /** @type {string} */ (href), + )}"]`; + const newActive = dom.find(sidebar, sidebarSelector)?.closest('li'); if (newActive && newActive !== oldActive) { oldActive?.classList.remove('active'); diff --git a/src/core/render/index.js b/src/core/render/index.js index f4db193754..94f3316fc8 100644 --- a/src/core/render/index.js +++ b/src/core/render/index.js @@ -324,8 +324,12 @@ export function Render(Base) { this.#addTextAsTitleAttribute('.sidebar-nav a'); if (loadSidebar && activeEl) { - const parent = /** @type {HTMLElement} */ (activeEl.parentElement); - parent.innerHTML += this.compiler.subSidebar(subMaxLevel) || ''; + activeEl + .closest('li') + ?.insertAdjacentHTML( + 'beforeend', + this.compiler.subSidebar(subMaxLevel) || '', + ); } else { this.compiler.resetToc(); } diff --git a/src/core/render/slugify.js b/src/core/render/slugify.js index 6f1f6a7ee2..825011779b 100644 --- a/src/core/render/slugify.js +++ b/src/core/render/slugify.js @@ -23,7 +23,7 @@ export function slugify(str) { .replace(/^(\d)/, '_$1'); let count = cache[slug]; - count = Object.keys(cache).includes(slug) ? count + 1 : 0; + count = Object.prototype.hasOwnProperty.call(cache, slug) ? count + 1 : 0; cache[slug] = count; if (count) { diff --git a/src/core/render/tpl.js b/src/core/render/tpl.js index 88b732a78f..b4c6de3b5c 100644 --- a/src/core/render/tpl.js +++ b/src/core/render/tpl.js @@ -36,18 +36,20 @@ export function corner(data, cornerExternalLinkTarget) { * @returns {String} HTML of the main content */ export function main(config) { - const { hideSidebar, name } = config; + const { hideSidebar, name, sidebarPosition } = config; + const sidebarPositionClass = + sidebarPosition === 'right' ? ' sidebar-right' : ''; // const name = config.name ? config.name : ''; const aside = /* html */ hideSidebar ? '' : ` - -