diff --git a/README.md b/README.md index ae660cc..b119c59 100644 --- a/README.md +++ b/README.md @@ -310,6 +310,35 @@ The following arguments are passed into your middleware function: - suffix: The symbol name suffix (e.g. `/Desktop`) - RESIZING_CONSTRAINTS: Object containing constants for the `setResizingConstraint` API +#### Text Middleware + +This middleware is executed for every text layer within a document. + +```js +module.exports = { + textMiddleware: args => { ... } +}; +``` + +The following arguments are passed into your middleware function: + +- layer: The current symbol layer +- node: The source HTML node + +Example for preserving text across library updates (by hardcoding an ID): + +```js +textMiddleware: ({ layer, node }) => { + const parentNode = node.parentNode; + if (parentNode && parentNode.dataset) { + const { sketchId } = parentNode.dataset; + + if (sketchId) { + layer.setObjectID(`text:${sketchId}`); + } + } +} +``` #### Symbol Instance Middleware diff --git a/bin/cli.js b/bin/cli.js index 5487937..7b98119 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -95,6 +95,7 @@ require('yargs') const symbolLayerMiddleware = resolveMiddleware(argv.symbolLayerMiddleware); const symbolMiddleware = resolveMiddleware(argv.symbolMiddleware); const symbolInstanceMiddleware = resolveMiddleware(argv.symbolInstanceMiddleware); + const textMiddleware = resolveMiddleware(argv.textMiddleware); const launchArgs = { args: argv.puppeteerArgs ? argv.puppeteerArgs.split(' ') : [], @@ -129,7 +130,7 @@ require('yargs') await page.addScriptTag({ content: code }); - await page.evaluate('generateAlmostSketch.setupSymbols({ name: "html-sketchapp symbols" })'); + await page.evaluate(`generateAlmostSketch.setupSymbols({ ${argv.name ? `id: '${argv.name}', ` : ''}name: "html-sketchapp symbols" })`); await page.evaluate('generateAlmostSketch.snapshotColorStyles()'); @@ -142,12 +143,12 @@ require('yargs') const [ width, height ] = size.split('x').map(x => parseInt(x, 10)); const deviceScaleFactor = typeof scale === 'undefined' ? 1 : parseFloat(scale); await page.setViewport({ width, height, deviceScaleFactor }); - await page.evaluate(`generateAlmostSketch.snapshotTextStyles({ suffix: "${hasViewports ? `/${viewportName}` : ''}" })`); - await page.evaluate(`generateAlmostSketch.snapshotSymbols({ suffix: "${hasViewports ? `/${viewportName}` : ''}", symbolLayerMiddleware: ${symbolLayerMiddleware}, symbolMiddleware: ${symbolMiddleware}, symbolInstanceMiddleware: ${symbolInstanceMiddleware} })`); + await page.evaluate(`generateAlmostSketch.snapshotTextStyles({ ${argv.customIds ? 'customIds: true, ' : ''}suffix: "${hasViewports ? `/${viewportName}` : ''}" })`); + await page.evaluate(`generateAlmostSketch.snapshotSymbols({ suffix: "${hasViewports ? `/${viewportName}` : ''}", symbolLayerMiddleware: ${symbolLayerMiddleware}, symbolMiddleware: ${symbolMiddleware}, symbolInstanceMiddleware: ${symbolInstanceMiddleware}, textMiddleware: ${textMiddleware} })`); } } - const asketchDocumentJSON = await page.evaluate('generateAlmostSketch.getDocumentJSON()'); + const asketchDocumentJSON = await page.evaluate(`generateAlmostSketch.getDocumentJSON('${argv.name || ''}')`); const asketchPageJSON = await page.evaluate('generateAlmostSketch.getPageJSON()'); const outputPath = path.resolve(process.cwd(), argv.outDir); diff --git a/package.json b/package.json index 701d83b..509f094 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ }, "homepage": "https://github.com/seek-oss/html-sketchapp-cli#readme", "dependencies": { - "@brainly/html-sketchapp": "^4.0.0", + "@brainly/html-sketchapp": "^4.1.0", "axios": "^0.18.0", "decompress": "^4.2.0", "es6-promisify": "^6.0.0", diff --git a/script/generateAlmostSketch.js b/script/generateAlmostSketch.js index 76a83ff..0785b62 100644 --- a/script/generateAlmostSketch.js +++ b/script/generateAlmostSketch.js @@ -12,7 +12,7 @@ const { ShapeGroup } = htmlSketchapp; -const getAllLayers = (rootNode, symbolMastersByName = {}, symbolInstanceMiddleware = {}) => { +const getAllLayers = (rootNode, symbolMastersByName = {}, symbolInstanceMiddleware = {}, textMiddleware = null) => { const rootNodeAndChildren = [rootNode, ...rootNode.querySelectorAll('*')]; const symbolInstanceChildren = new Set([ @@ -42,7 +42,9 @@ const getAllLayers = (rootNode, symbolMastersByName = {}, symbolInstanceMiddlewa return []; } - return nodeToSketchLayers(node); + return nodeToSketchLayers(node, { + onTextGenerate: textMiddleware, + }); }); return layers.reduce((prev, current) => prev.concat(current), []); @@ -59,7 +61,7 @@ export function snapshotColorStyles() { }); } -export function snapshotTextStyles({ suffix = '' }) { +export function snapshotTextStyles({ suffix = '', customIds }) { Array.from(document.querySelectorAll('[data-sketch-text]')) .forEach(node => { getAllLayers(node) @@ -67,13 +69,21 @@ export function snapshotTextStyles({ suffix = '' }) { .forEach(layer => { const name = node.dataset.sketchText; - layer.setName(`${name}${suffix}`); - doc.addTextStyle(layer); + const id = `${name}${suffix}`; + layer.setName(id); + if (customIds) { + doc.addTextStyle(layer, id); + } else { + doc.addTextStyle(layer); + } }); }); } -export function getDocumentJSON() { +export function getDocumentJSON(name) { + if (name) { + doc.setObjectID(name); + } return JSON.stringify(doc.toJSON()); } @@ -82,11 +92,14 @@ const page = new Page({ height: document.body.offsetHeight }); -export function setupSymbols({ name }) { +export function setupSymbols({ name, id }) { + if (id) { + page.setObjectID(id); + } page.setName(name); } -export function snapshotSymbols({ suffix = '', symbolLayerMiddleware = () => {}, symbolMiddleware = () => {}, symbolInstanceMiddleware = () => {} },) { +export function snapshotSymbols({ suffix = '', symbolLayerMiddleware = () => {}, symbolMiddleware = () => {}, symbolInstanceMiddleware = () => {}, textMiddleware },) { const nodes = Array.from(document.querySelectorAll('[data-sketch-symbol]')); const symbolMastersByName = nodes.reduce((obj, node) => { @@ -105,12 +118,12 @@ export function snapshotSymbols({ suffix = '', symbolLayerMiddleware = () => {}, const name = node.dataset.sketchSymbol; const symbol = symbolMastersByName[name]; - const layers = getAllLayers(node, symbolMastersByName, symbolInstanceMiddleware); + const layers = getAllLayers(node, symbolMastersByName, symbolInstanceMiddleware, textMiddleware); layers .filter(layer => layer !== null) .forEach(layer => { - symbolLayerMiddleware({layer, SVG, Text, ShapeGroup, Rectangle, RESIZING_CONSTRAINTS}); + symbolLayerMiddleware({layer, node, SVG, Text, ShapeGroup, Rectangle, RESIZING_CONSTRAINTS}); symbol.addLayer(layer); });