-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[embedding] feat: allow user configured navbar site #1535
base: develop
Are you sure you want to change the base?
Changes from all commits
c12c68e
2b0db83
bb46a88
69def1c
a989914
f830976
fe30b70
cf05a6f
74a0af0
8e5f080
d9871e1
738c39a
cdde500
288d05d
02daac4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -88,6 +88,19 @@ window.$docsify = { | |
}; | ||
``` | ||
|
||
## navEl | ||
|
||
- Type: `String` | ||
- Default: `null` | ||
|
||
The DOM element to use for rendering the navbar. It can be a CSS selector string or an actual [HTMLElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement). If `null`, the first `<nav>` element on the page is used. If it doesn't exist, it is created at the top of the DOM. | ||
|
||
```js | ||
window.$docsify = { | ||
nav_el: '#navbar, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The configuration option would be |
||
}; | ||
``` | ||
|
||
## loadSidebar | ||
|
||
- Type: `Boolean|String` | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -300,9 +300,10 @@ export function Render(Base) { | |
} | ||
|
||
_renderNav(text) { | ||
text && this._renderTo('nav', this.compiler.compile(text)); | ||
text && | ||
this._renderTo(this.config.navEl || 'nav', this.compiler.compile(text)); | ||
if (this.config.loadNavbar) { | ||
getAndActive(this.router, 'nav'); | ||
getAndActive(this.router, this.config.navEl || 'nav'); | ||
} | ||
} | ||
|
||
|
@@ -409,10 +410,9 @@ export function Render(Base) { | |
window.__current_docsify_compiler__ = this.compiler; | ||
} | ||
|
||
const id = config.el || '#app'; | ||
const navEl = dom.find('nav') || dom.create('nav'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can solve this issue by using more specific CSS selectors instead of adding another configuration option:
const navEl = dom.find('nav.app-nav, main > aside.sidebar > nav') || dom.create('nav'); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Won't this break a lot of existing configurations? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, should this be a CSS id rather than class since there is probably only one There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jhildenbiddle that doesn't cover the use case that a person embeds docsify into a wrapper that has a nav on the outside, and that nav matching neither of those two selectors. That's what the main use case is here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Of course the user could modify the wrapper so the nav has a matching selector. Also not sure what should happen on mobile There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Evidlo -- The updated selector will not break existing configurations because it targets the same element: the Rather than write a lengthy comment explaining what changes need to be made, I made the necessary changes available in new fix-1525 branch. The changes are as follows:
Feel free to check out the branch, build, and test to determine if these changes address your issue. FWIW, here are desktop and mobile screenshots of the demo with the custom <body>
<nav id="mynav" style=" background: red; color: white; text-align: center; padding: 1em; font-weight: bold;">
<p>Custom Nav Element</p>
</nav>
<div id="app">Loading ...</div>
</body> I'll close by saying that the changes I've made here are intended to fix the issue without modifying the HTML output so that we can publish the fix as a non-breaking change. There are better ways to solve this problem and there are a lot of things about the UI rendering that we can and should clean up, but that is work for a later date IMHO. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @trusktr --
Perhaps we're interpreting the issue differently. Here's what @Evidlo said in #1525:
This is what the new selectors address: they prevent docsify from targeting the first @Evidlo -- Let me know if I misinterpreted here. |
||
const el = dom.find(config.el || '#app'); | ||
const navEl = dom.find(config.navEl || 'nav') || dom.create('nav'); | ||
|
||
const el = dom.find(id); | ||
let html = ''; | ||
let navAppendToTarget = dom.body; | ||
|
||
|
@@ -442,7 +442,7 @@ export function Render(Base) { | |
this.rendered = true; | ||
} | ||
|
||
if (config.mergeNavbar && isMobile) { | ||
if (config.mergeNavbar && isMobile && !config.navEl) { | ||
navAppendToTarget = dom.find('.sidebar'); | ||
} else { | ||
navEl.classList.add('app-nav'); | ||
|
@@ -453,7 +453,7 @@ export function Render(Base) { | |
} | ||
|
||
// Add nav | ||
if (config.loadNavbar) { | ||
if (config.loadNavbar && !config.navEl) { | ||
dom.before(navAppendToTarget, navEl); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
const docsifyInit = require('../helpers/docsify-init'); | ||
|
||
describe(`Navbar tests`, function() { | ||
test('specify custom navbar element in config with nav_el', async () => { | ||
const docsifyInitConfig = { | ||
html: ` | ||
<html> | ||
<body> | ||
<nav id="mynav"></nav> | ||
<div id="app"></nav> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are closing |
||
</body> | ||
</html> | ||
`, | ||
markdown: { | ||
navbar: ` | ||
- [Foo](foo) | ||
- [Bar](bar) | ||
`, | ||
homepage: ` | ||
# hello world | ||
foo | ||
`, | ||
}, | ||
config: { | ||
nav_el: '#mynav', | ||
}, | ||
}; | ||
|
||
await docsifyInit(docsifyInitConfig); | ||
|
||
// Check that our custom <nav> element contains nav links | ||
let navHTML; | ||
navHTML = await page.$eval('#mynav', el => el.innerHTML); | ||
expect(navHTML).toMatch('<li><a href="#/foo" title="Foo">Foo</a></li>'); | ||
navHTML = await page.$eval('#mynav', el => el.innerHTML); | ||
expect(navHTML).toMatch('<li><a href="#/bar" title="Bar">Bar</a></li>'); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on the source, this option accepts a string only (not an HTMLElement). Either the description or the source needs to be updated to match.