Skip to content

Commit

Permalink
Export standalone SVG for diagrams.net (including width, height and v…
Browse files Browse the repository at this point in the history
…iewBox)
  • Loading branch information
ggrossetie committed Jun 3, 2023
1 parent 48e510e commit b195d56
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 25 deletions.
14 changes: 9 additions & 5 deletions diagrams.net/src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const http = require('node:http')
const { Worker } = require('./worker')
const { Worker, SyntaxError } = require('./worker')
const Task = require('./task')
const instance = require('./browser-instance')
const micro = require('micro')
Expand All @@ -23,11 +23,15 @@ const puppeteer = require('puppeteer')
const output = await worker.convert(new Task(diagramSource, isPng))
res.setHeader('Content-Type', isPng ? 'image/png' : 'image/svg+xml')
return micro.send(res, 200, output)
} catch (e) {
if (!(e instanceof puppeteer.errors.TimeoutError)) {
console.log('Exception during convert', e)
} catch (err) {
if (err instanceof puppeteer.errors.TimeoutError) {
return micro.send(res, 408, 'Request timeout')
} else if (err instanceof SyntaxError) {
return micro.send(res, 400, err.message)
} else {
console.log('Exception during convert', err)
return micro.send(res, 500, 'An error occurred while converting the diagram')
}
return micro.send(res, 500, 'An error occurred while converting the diagram')
}
}
return micro.send(res, 400, 'Body must not be empty.')
Expand Down
55 changes: 35 additions & 20 deletions diagrams.net/src/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
const path = require('node:path')
const puppeteer = require('puppeteer')

class SyntaxError extends Error {
constructor (err) {
console.log({err})
super(`Syntax error in graph: ${JSON.stringify(err)}`)
}
}

class Worker {
constructor (browserInstance) {
this.browserWSEndpoint = browserInstance.wsEndpoint()
Expand All @@ -19,37 +26,44 @@ class Worker {
await page.setViewport({ height: 800, width: 600 })
await page.goto(this.pageUrl)
// QUESTION: should we reuse the page for performance reason ?
await page.evaluate((source) => {
/* global render */
return render({
xml: source,
format: 'svg'
})
}, task.source)

await page.waitForSelector('#LoadingComplete', { timeout: this.convertTimeout })
const evalResult = await Promise.race([
page.evaluate((source) => {
/* global render */
try {
const svgRoot = render({
xml: source,
format: 'svg'
}).getSvg()
const s = new XMLSerializer()
console.log({s})
return { svg: s.serializeToString(svgRoot), error: null }
} catch (err) {
console.log({err})
return { svg: null, error: err }
}
}, task.source),
page.waitForTimeout(this.convertTimeout)
]);

if (evalResult && evalResult.error) {
throw new SyntaxError(evalResult.error)
}

// const bounds = await page.mainFrame().$eval('#LoadingComplete', div => div.getAttribute('bounds'))
// const pageId = await page.mainFrame().$eval('#LoadingComplete', div => div.getAttribute('page-id'))
// const scale = await page.mainFrame().$eval('#LoadingComplete', div => div.getAttribute('scale'))
// const pageCount = parseInt(await page.mainFrame().$eval('#LoadingComplete', div => div.getAttribute('pageCount')))

// diagrams are directly under #graph, while the SVG generated upon syntax error is wrapped in a div
const svg = await page.$('#graph > svg')
if (task.isPng) {
return await svg.screenshot({
await page.setContent(evalResult.svg)
const container = await page.$('svg')
return await container.screenshot({
type: 'png',
omitBackground: true
})
} else {
return await page.$eval('#graph', container => {
const xmlSerializer = new XMLSerializer()
const nodes = []
for (let i = 0; i < container.childNodes.length; i++) {
nodes.push(xmlSerializer.serializeToString(container.childNodes[i]))
}
return nodes.join('')
})
return evalResult.svg
}
} finally {
try {
Expand All @@ -67,5 +81,6 @@ class Worker {
}

module.exports = {
Worker
Worker,
SyntaxError
}

0 comments on commit b195d56

Please sign in to comment.