feat(app/metrics): add extras_js support (#798)

This commit is contained in:
Simon Lecoq
2022-01-21 05:16:19 +01:00
committed by GitHub
parent ce19ceb715
commit 4571a89b57
4 changed files with 33 additions and 6 deletions

View File

@@ -24,7 +24,7 @@ export default async function metrics({login, q}, {graphql, rest, plugins, conf,
//Initialization //Initialization
const pending = [] const pending = []
const {queries} = conf const {queries} = conf
const extras = {css:(conf.settings.extras?.css ?? conf.settings.extras?.default ? q["extras.css"] ?? "" : "")} const extras = {css:(conf.settings.extras?.css ?? conf.settings.extras?.default) ? q["extras.css"] ?? "" : "", js:(conf.settings.extras?.js ?? conf.settings.extras?.default) ? q["extras.js"] ?? "" : ""}
const data = {q, animated:true, large:false, base:{}, config:{}, errors:[], plugins:{}, computed:{}, extras} const data = {q, animated:true, large:false, base:{}, config:{}, errors:[], plugins:{}, computed:{}, extras}
const imports = { const imports = {
plugins:Plugins, plugins:Plugins,
@@ -189,7 +189,7 @@ export default async function metrics({login, q}, {graphql, rest, plugins, conf,
console.debug(`metrics/compute/${login} > verified SVG, no parsing errors found`) console.debug(`metrics/compute/${login} > verified SVG, no parsing errors found`)
} }
//Resizing //Resizing
const {resized, mime} = await imports.svg.resize(rendered, {paddings:q["config.padding"] || conf.settings.padding, convert:convert === "svg" ? null : convert}) const {resized, mime} = await imports.svg.resize(rendered, {paddings:q["config.padding"] || conf.settings.padding, convert:convert === "svg" ? null : convert, js:extras.js || null})
rendered = resized rendered = resized
//Result //Result

View File

@@ -401,7 +401,7 @@ export const svg = {
return {rendered, mime:"application/pdf"} return {rendered, mime:"application/pdf"}
}, },
/**Render and resize svg */ /**Render and resize svg */
async resize(rendered, {paddings, convert}) { async resize(rendered, {paddings, convert, js}) {
//Instantiate browser if needed //Instantiate browser if needed
if (!svg.resize.browser) { if (!svg.resize.browser) {
svg.resize.browser = await puppeteer.launch() svg.resize.browser = await puppeteer.launch()
@@ -425,7 +425,9 @@ export const svg = {
console.debug("metrics/svg/resize > loading svg") console.debug("metrics/svg/resize > loading svg")
const page = await svg.resize.browser.newPage() const page = await svg.resize.browser.newPage()
page.setViewport({width:980, height:980}) page.setViewport({width:980, height:980})
page.on("console", ({_text:text}) => console.debug(`metrics/svg/resize > puppeteer > ${text}`)) page
.on("console", message => console.debug(`metrics/svg/resize > puppeteer > ${message.text()}`))
.on("pageerror", error => console.debug(`metrics/svg/resize > puppeteer > ${error.message}`))
await page.setContent(rendered, {waitUntil:["load", "domcontentloaded", "networkidle2"]}) await page.setContent(rendered, {waitUntil:["load", "domcontentloaded", "networkidle2"]})
console.debug("metrics/svg/resize > loaded svg successfully") console.debug("metrics/svg/resize > loaded svg successfully")
await page.addStyleTag({content:"body { margin: 0; padding: 0; }"}) await page.addStyleTag({content:"body { margin: 0; padding: 0; }"})
@@ -433,7 +435,18 @@ export const svg = {
console.debug("metrics/svg/resize > resizing svg") console.debug("metrics/svg/resize > resizing svg")
let height, resized, width let height, resized, width
try { try {
({resized, width, height} = await page.evaluate(async padding => { ({resized, width, height} = await page.evaluate(async (padding, js) => {
//Execute user JavaScript if provided
if (js) {
try {
console.debug(`metrics/svg/resize > executing ${js}`)
await new Function("document", `return (async () => {${js}})()`)(document) //eslint-disable-line no-new-func
console.debug("metrics/svg/resize > successfully executed user javascript")
}
catch (error) {
console.debug(`an error occured while evaluating user js: ${error}`)
}
}
//Disable animations //Disable animations
const animated = !document.querySelector("svg").classList.contains("no-animations") const animated = !document.querySelector("svg").classList.contains("no-animations")
if (animated) if (animated)
@@ -456,7 +469,7 @@ export const svg = {
document.querySelector("svg").classList.remove("no-animations") document.querySelector("svg").classList.remove("no-animations")
//Result //Result
return {resized:new XMLSerializer().serializeToString(document.querySelector("svg")), height, width} return {resized:new XMLSerializer().serializeToString(document.querySelector("svg")), height, width}
}, padding)) }, padding, js))
} }
catch (error) { catch (error) {
console.error(error) console.error(error)

View File

@@ -28,6 +28,7 @@
"extras": { "extras": {
"default": false, "//": "Default extras state (advised to let 'false' unless in debug mode)", "default": false, "//": "Default extras state (advised to let 'false' unless in debug mode)",
"css": false, "//": "Allow use of 'extras.css' option", "css": false, "//": "Allow use of 'extras.css' option",
"js": false, "//": "Allow use of 'extras.js' option",
"features": false, "//": "Enable extra features (advised to let 'false' on web instances)" "features": false, "//": "Enable extra features (advised to let 'false' on web instances)"
}, },
"plugins.default": false, "//": "Default plugin state (advised to let 'false' unless in debug mode)", "plugins.default": false, "//": "Default plugin state (advised to let 'false' unless in debug mode)",

View File

@@ -175,6 +175,19 @@ inputs:
type: string type: string
default: "" default: ""
extras_js:
extras: yes
description: |
Extra JavaScript
Custom JavaScript that will be executed during puppeteer rendering.
Useful to avoid creating a new template just to tweak some content.
Note that is it executed within puppeteer context and **not** *metrics* context.
It is run after transformations and optimizations, but just before resizing.
type: string
default: ""
config_timezone: config_timezone:
description: | description: |
Timezone for dates Timezone for dates