-
-
Notifications
You must be signed in to change notification settings - Fork 5.8k
feat: The timing of the doneEach hook call for the cover
#2427
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
base: develop
Are you sure you want to change the base?
Changes from all commits
bd5f879
bcd1090
117eb08
f7666ca
dea1229
56c922f
b2a9c06
a3c3359
837d04a
ec48f93
7cc7cdf
0333d96
e796604
2c55a47
9dd2a67
1526a78
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 |
|---|---|---|
|
|
@@ -433,7 +433,6 @@ export function Render(Base) { | |
| { | ||
| compiler: /** @type {Compiler} */ (this.compiler), | ||
| raw: result, | ||
| fetch: undefined, | ||
| }, | ||
| tokens => { | ||
| html = /** @type {Compiler} */ (this.compiler).compile(tokens); | ||
|
|
@@ -444,108 +443,71 @@ export function Render(Base) { | |
| }); | ||
| } | ||
|
|
||
| _renderCover(text, coverOnly) { | ||
| const el = dom.getNode('.cover'); | ||
| _renderCover(text, coverOnly, next) { | ||
| const el = /** @type {HTMLElement} */ (dom.getNode('.cover')); | ||
| const rootElm = document.documentElement; | ||
| // TODO this is now unused. What did we break? | ||
| // eslint-disable-next-line no-unused-vars | ||
| const coverBg = getComputedStyle(rootElm).getPropertyValue('--cover-bg'); | ||
|
|
||
| dom.getNode('main').classList[coverOnly ? 'add' : 'remove']('hidden'); | ||
|
|
||
| if (!text) { | ||
| el.classList.remove('show'); | ||
| next(); | ||
| return; | ||
| } | ||
|
|
||
| el.classList.add('show'); | ||
|
|
||
| let html = this.coverIsHTML | ||
| ? text | ||
| : /** @type {Compiler} */ (this.compiler).cover(text); | ||
|
|
||
| if (!coverBg) { | ||
| const mdBgMatch = html | ||
| const callback = html => { | ||
| const m = html | ||
| .trim() | ||
| .match( | ||
| '<p><img.*?data-origin="(.*?)".*?alt="(.*?)"[^>]*?>([^<]*?)</p>$', | ||
| ); | ||
|
|
||
| let mdCoverBg; | ||
| .match('<p><img.*?data-origin="(.*?)"[^a]+alt="(.*?)">([^<]*?)</p>$'); | ||
|
|
||
| if (mdBgMatch) { | ||
| const [bgMatch, bgValue, bgType] = mdBgMatch; | ||
| if (m) { | ||
| if (m[2] === 'color') { | ||
| el.style.background = m[1] + (m[3] || ''); | ||
| } else { | ||
| let path = m[1]; | ||
|
|
||
| // Color | ||
| if (bgType === 'color') { | ||
| mdCoverBg = bgValue; | ||
| } | ||
| // Image | ||
| else { | ||
| const path = !isAbsolutePath(bgValue) | ||
| ? getPath(this.router.getBasePath(), bgValue) | ||
| : bgValue; | ||
| el.classList.add('has-mask'); | ||
| if (!isAbsolutePath(m[1])) { | ||
| path = getPath(this.router.getBasePath(), m[1]); | ||
| } | ||
|
|
||
| mdCoverBg = `center center / cover url(${path})`; | ||
| el.style.backgroundImage = `url(${path})`; | ||
| el.style.backgroundSize = 'cover'; | ||
| el.style.backgroundPosition = 'center center'; | ||
| } | ||
|
|
||
| html = html.replace(bgMatch, ''); | ||
| html = html.replace(m[0], ''); | ||
| } | ||
| // Gradient background | ||
| else { | ||
| const degrees = Math.round((Math.random() * 120) / 2); | ||
|
Member
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. Looks like this gradient background code is removed. Need to restore it. @YiiGuxing would you mind restoring the random gradient? |
||
|
|
||
| let hue1 = Math.round(Math.random() * 360); | ||
| let hue2 = Math.round(Math.random() * 360); | ||
|
|
||
| // Ensure hue1 and hue2 are at least 50 degrees apart | ||
| if (Math.abs(hue1 - hue2) < 50) { | ||
| const hueShift = Math.round(Math.random() * 25) + 25; | ||
|
|
||
| hue1 = Math.max(hue1, hue2) + hueShift; | ||
| hue2 = Math.min(hue1, hue2) - hueShift; | ||
| } | ||
| dom.setHTML('.cover-main', html); | ||
| next(); | ||
| }; | ||
|
|
||
| // OKLCH color | ||
| if (window?.CSS?.supports('color', 'oklch(0 0 0 / 1%)')) { | ||
| const l = 90; // Lightness | ||
| const c = 20; // Chroma | ||
|
|
||
| // prettier-ignore | ||
| mdCoverBg = `linear-gradient( | ||
| ${degrees}deg, | ||
| oklch(${l}% ${c}% ${hue1}) 0%, | ||
| oklch(${l}% ${c}% ${hue2}) 100% | ||
| )`.replace(/\s+/g, ' '); | ||
| } | ||
| // HSL color (Legacy) | ||
| else { | ||
| const s = 100; // Saturation | ||
| const l = 85; // Lightness | ||
| const o = 100; // Opacity | ||
|
|
||
| // prettier-ignore | ||
| mdCoverBg = `linear-gradient( | ||
| ${degrees}deg, | ||
| hsl(${hue1} ${s}% ${l}% / ${o}%) 0%, | ||
| hsl(${hue2} ${s}% ${l}% / ${o}%) 100% | ||
| )`.replace(/\s+/g, ' '); | ||
| } | ||
| // TODO: Call the 'beforeEach' and 'afterEach' hooks. | ||
| // However, when the cover and the home page are on the same page, | ||
| // the 'beforeEach' and 'afterEach' hooks are called multiple times. | ||
| // It is difficult to determine the target of the hook within the | ||
| // hook functions. We might need to make some changes. | ||
|
Member
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. @YiiGuxing I think we should update the hooks in a backwards compatible way, such that the hook can somehow see which content it is called for. For example it can see string values like "cover", "sidebar", etc. The default (right now no sort of value to determine the target of the hook) would work the same as before for anyone who hasn't updated their plugin code.
Member
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 ultimate result should be, that all markdown files are handled the same, regardless where in the app they are rendered (cover, sidebar, nav, etc) but any plugin can easily decide which to handle. Something like hook.doneEach((section) => {
if (section === 'cover') {
// run logic after cover rendered
} else if (section === 'sidebar') {
// run logic after sidebar rendered
} else if (section === 'nav') {
// run logic after nav bar rendered
} else if (section === 'main') {
// run logic after main content rendered (new way)
} else {
// run logic after main content rendered (old way, fallback)
}
})or similar. |
||
| if (this.coverIsHTML) { | ||
| callback(text); | ||
| } else { | ||
| const compiler = this.compiler; | ||
| if (!compiler) { | ||
| throw new Error('Compiler is not initialized'); | ||
| } | ||
|
|
||
| rootElm.style.setProperty('--cover-bg', mdCoverBg); | ||
| prerenderEmbed( | ||
| { | ||
| compiler, | ||
| raw: text, | ||
| }, | ||
| tokens => callback(compiler.cover(tokens)), | ||
| ); | ||
| } | ||
|
|
||
| dom.setHTML('.cover-main', html); | ||
|
|
||
| // Button styles | ||
| dom | ||
| .findAll('.cover-main > p:last-of-type > a:not([class])') | ||
| .forEach(elm => { | ||
| const buttonType = elm.matches(':first-child') | ||
| ? 'primary' | ||
| : 'secondary'; | ||
|
|
||
| elm.classList.add('button', buttonType); | ||
| }); | ||
| } | ||
|
|
||
| _updateRender() { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| import docsifyInit from '../helpers/docsify-init.js'; | ||
| import { test, expect } from './fixtures/docsify-init-fixture.js'; | ||
|
|
||
| test.describe('Embed files', () => { | ||
| const routes = { | ||
| 'fragment.md': '## Fragment', | ||
| }; | ||
|
|
||
| test('embed into homepage', async ({ page }) => { | ||
| await docsifyInit({ | ||
| routes, | ||
| markdown: { | ||
| homepage: "# Hello World\n\n[fragment](fragment.md ':include')", | ||
| }, | ||
| // _logHTML: {}, | ||
| }); | ||
|
|
||
| await expect(page.locator('#main')).toContainText('Fragment'); | ||
| }); | ||
|
|
||
| test('embed into cover', async ({ page }) => { | ||
| await docsifyInit({ | ||
| routes, | ||
| markdown: { | ||
| homepage: '# Hello World', | ||
| coverpage: "# Cover\n\n[fragment](fragment.md ':include')", | ||
| }, | ||
| // _logHTML: {}, | ||
| }); | ||
|
|
||
| await expect(page.locator('.cover-main')).toContainText('Fragment'); | ||
| }); | ||
| }); |
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.
This variable is now unused in the PR. Is the feature relating to that now deleted? If so, we need to fix that.
Also there are type errors I'm fixing (my recent changes added type checking to the code base).
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.
Now that tests run, a jest test is failing. https://github.com/docsifyjs/docsify/actions/runs/19981379473/job/57308351783?pr=2427
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.
I fixed the error, a method moved to the utils file.
Now the only thing failing is snapshots for the cover page. The diff shows this failure:
Looks like a couple classes are missing.
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.
Here's the visual difference:
Before:
After (broken):
Maybe I missed something when merging in
develop?