Skip to content

Commit

Permalink
feat(cli, client): export pages for every clicks
Browse files Browse the repository at this point in the history
  • Loading branch information
chaokun.qian committed Jun 21, 2021
1 parent 2218e5e commit 5a00648
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 13 deletions.
3 changes: 2 additions & 1 deletion demo/composable-vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"scripts": {
"dev": "nodemon -w '../../packages/slidev/dist/*.js' --exec 'slidev --log=info'",
"build": "slidev build",
"export": "slidev export"
"export": "slidev export",
"export:everyClicks": "slidev export --everyClicks"
},
"devDependencies": {
"@slidev/cli": "workspace:*",
Expand Down
1 change: 1 addition & 0 deletions packages/client/logic/nav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export { rawRoutes }
export const route = computed(() => router.currentRoute.value)

export const isPrintMode = computed(() => route.value.query.print !== undefined)
export const isPrintEveryClick = computed(() => isPrintMode.value && route.value.query.everyClick !== undefined)
export const isEmbedded = computed(() => route.value.query.embedded !== undefined)
export const isPresenter = computed(() => route.value.path.startsWith('/presenter'))

Expand Down
8 changes: 4 additions & 4 deletions packages/client/modules/directives.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { App, DirectiveBinding, InjectionKey, Ref, watch } from 'vue'
import { remove } from '@antfu/utils'
import { isPrintMode } from '../logic/nav'
import { isPrintMode, isPrintEveryClick } from '../logic/nav'

export const injectionClicks: InjectionKey<Ref<number>> = Symbol('v-click-clicks')
export const injectionClicksElements: InjectionKey<Ref<(Element | string)[]>> = Symbol('v-click-clicks-elements')
Expand All @@ -23,7 +23,7 @@ export default function createDirectives() {
name: 'v-click',

mounted(el: HTMLElement, dir) {
if (isPrintMode.value || dirInject(dir, injectionClicksDisabled)?.value)
if ((isPrintMode.value && !isPrintEveryClick.value) || dirInject(dir, injectionClicksDisabled)?.value)
return

const elements = dirInject(dir, injectionClicksElements)
Expand Down Expand Up @@ -64,7 +64,7 @@ export default function createDirectives() {
name: 'v-after',

mounted(el: HTMLElement, dir) {
if (isPrintMode.value || dirInject(dir, injectionClicksDisabled)?.value)
if ((isPrintMode.value && !isPrintEveryClick.value) || dirInject(dir, injectionClicksDisabled)?.value)
return

const elements = dirInject(dir, injectionClicksElements)
Expand Down Expand Up @@ -96,7 +96,7 @@ export default function createDirectives() {
name: 'v-click-hide',

mounted(el: HTMLElement, dir) {
if (isPrintMode.value || dirInject(dir, injectionClicksDisabled)?.value)
if ((isPrintMode.value && !isPrintEveryClick.value) || dirInject(dir, injectionClicksDisabled)?.value)
return

const clicks = dirInject(dir, injectionClicks)
Expand Down
7 changes: 7 additions & 0 deletions packages/slidev/node/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,11 @@ cli.command(
type: 'boolean',
describe: 'export as dark theme',
})
.option('everyClicks', {
default: false,
type: 'boolean',
describe: 'export pages for every clicks',
})
.strict()
.help(),
async({
Expand All @@ -305,6 +310,7 @@ cli.command(
timeout,
range,
dark,
everyClicks,
}) => {
output = output || `${path.basename(entry, '.md')}-export`
process.env.NODE_ENV = 'production'
Expand Down Expand Up @@ -336,6 +342,7 @@ cli.command(
routerMode: options.data.config.routerMode,
width,
height,
everyClicks,
})
console.log(`${green(' ✓ ')}${dim('exported to ')}./${output}\n`)
server.close()
Expand Down
36 changes: 28 additions & 8 deletions packages/slidev/node/export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export interface ExportOptions {
routerMode?: 'hash' | 'history'
width?: number
height?: number
everyClicks?: boolean
}

function createSlidevProgress() {
Expand Down Expand Up @@ -68,6 +69,7 @@ export async function exportSlides({
routerMode = 'history',
width = 1920,
height = 1080,
everyClicks = false,
}: ExportOptions) {
if (!packageExists('playwright-chromium'))
throw new Error('The exporting for Slidev is powered by Playwright, please installed it via `npm i playwright-chromium`')
Expand All @@ -84,12 +86,12 @@ export async function exportSlides({
const page = await context.newPage()
const progress = createSlidevProgress()

async function go(no: number) {
async function go(no: number, clicks?: string) {
progress.update(no)

const url = routerMode === 'hash'
? `http://localhost:${port}/#${base}${no}?print`
: `http://localhost:${port}${base}${no}?print`
? `http://localhost:${port}/#${base}${no}?print${everyClicks ? '&everyClick' : ''}${clicks ? `&clicks=${clicks}` : ''}`
: `http://localhost:${port}${base}${no}?print${everyClicks ? '&everyClick' : ''}${clicks ? `&clicks=${clicks}` : ''}`
await page.goto(url, {
waitUntil: 'networkidle',
})
Expand All @@ -98,14 +100,28 @@ export async function exportSlides({
await page.emulateMedia({ colorScheme: dark ? 'dark' : 'light', media: 'screen' })
}

function getClicks(url: string) {
return url.match(/clicks=([1-9][0-9]*)/)?.[1]
}

async function genPageWithClicks(fn: (i: number, clicks?: string) => Promise<any>, i: number, clicks?: string) {
await fn(i, clicks)
if (everyClicks) {
await page.keyboard.press('ArrowRight', { delay: 100 })
const _clicks = getClicks(page.url())
if (_clicks && clicks !== _clicks)
await genPageWithClicks(fn, i, _clicks)
}
}

const pages = parseRangeString(total, range)

progress.start(pages.length)

if (format === 'pdf') {
const buffers: Buffer[] = []
for (const i of pages) {
await go(i)
const genPdfBuffer = async(i: number, clicks?: string) => {
await go(i, clicks)
const pdf = await page.pdf({
width,
height,
Expand All @@ -121,6 +137,8 @@ export async function exportSlides({
})
buffers.push(pdf)
}
for (const i of pages)
await genPageWithClicks(genPdfBuffer, i)

const mergedPdf = await PDFDocument.create({})
for (const pdfBytes of buffers) {
Expand All @@ -137,13 +155,15 @@ export async function exportSlides({
await fs.writeFile(output, buffer)
}
else if (format === 'png') {
for (const i of pages) {
await go(i)
const genScreenshot = async(i: number, clicks?: string) => {
await go(i, clicks)
await page.screenshot({
omitBackground: false,
path: path.join(output, `${i.toString().padStart(2, '0')}.png`),
path: path.join(output, `${i.toString().padStart(2, '0')}${clicks ? `-${clicks}` : ''}.png`),
})
}
for (const i of pages)
await genPageWithClicks(genScreenshot, i)
}
else {
throw new Error(`Unsupported exporting format "${format}"`)
Expand Down

0 comments on commit 5a00648

Please sign in to comment.