From 922cfd02b9a882040f000721e471385ec2d963f8 Mon Sep 17 00:00:00 2001 From: Enoch Riese Date: Mon, 14 Nov 2022 14:01:50 -0600 Subject: [PATCH] add pre-layout hook for consistency between getRenderProps and render --- packages/core/src/hooks.mjs | 1 + packages/core/src/pattern.mjs | 116 ++++++++++++++++++---------------- packages/core/src/svg.mjs | 3 +- 3 files changed, 64 insertions(+), 56 deletions(-) diff --git a/packages/core/src/hooks.mjs b/packages/core/src/hooks.mjs index be4dca5b7f5..4ad4e809f76 100644 --- a/packages/core/src/hooks.mjs +++ b/packages/core/src/hooks.mjs @@ -17,6 +17,7 @@ export function Hooks() { preSample: [], postSample: [], preRender: [], + preLayout: [], postLayout: [], postRender: [], insertText: [], diff --git a/packages/core/src/pattern.mjs b/packages/core/src/pattern.mjs index 160923b9281..2b3b676bd5d 100644 --- a/packages/core/src/pattern.mjs +++ b/packages/core/src/pattern.mjs @@ -11,6 +11,7 @@ import { Store } from './store.mjs' import { Hooks } from './hooks.mjs' import { version } from '../data.mjs' import { __loadPatternDefaults } from './config.mjs' +import cloneDeep from 'lodash.clonedeep' ////////////////////////////////////////////// // CONSTRUCTOR // @@ -53,7 +54,7 @@ export function Pattern(designConfig) { __addNonEnumProp(this, '__hide', {}) // Enumerable properties - this.designConfig = designConfig // The design configuration (unresolved) + this.designConfig = cloneDeep(designConfig) // The design configuration (unresolved) this.config = {} // Will hold the resolved pattern after calling __init() this.store = new Store() // Pattern-wide store this.setStores = [] // Per-set stores @@ -108,56 +109,7 @@ Pattern.prototype.draft = function () { this.__loadAbsoluteOptionsSet(set) for (const partName of this.config.draftOrder) { - // Create parts - this.setStores[set].log.debug(`📦 Creating part \`${partName}\` (set ${set})`) - this.parts[set][partName] = this.__createPartWithContext(partName, set) - - // Handle inject/inheritance - if (typeof this.__inject[partName] === 'string') { - this.setStores[set].log.debug( - `Creating part \`${partName}\` from part \`${this.__inject[partName]}\`` - ) - try { - this.parts[set][partName].__inject(this.parts[set][this.__inject[partName]]) - } catch (err) { - this.setStores[set].log.error([ - `Could not inject part \`${this.__inject[partName]}\` into part \`${partName}\``, - err, - ]) - } - } - if (this.__needs(partName, set)) { - // Draft part - if (typeof this.__designParts?.[partName]?.draft === 'function') { - this.activePart = partName - try { - this.__runHooks('prePartDraft') - const result = this.__designParts[partName].draft(this.parts[set][partName].shorthand()) - this.__runHooks('postPartDraft') - if (typeof result === 'undefined') { - this.setStores[set].log.error( - `Result of drafting part ${partName} was undefined. Did you forget to return the part?` - ) - } else this.parts[set][partName] = result - } catch (err) { - this.setStores[set].log.error([ - `Unable to draft part \`${partName}\` (set ${set})`, - err, - ]) - } - } else - this.setStores[set].log.error( - `Unable to draft pattern part __${partName}__. Part.draft() is not callable` - ) - // FIXME: THis won't work not that this is immutable - // But is it still needed? - // this.parts[set][partName].hidden === true ? true : !this.__wants(partName, set) - } else { - this.setStores[set].log.debug( - `Part \`${partName}\` is not needed. Skipping draft and setting hidden to \`true\`` - ) - this.parts[set][partName].hidden = true - } + this.createPartForSet(partName, set) } this.__runHooks('postSetDraft') } @@ -166,6 +118,61 @@ Pattern.prototype.draft = function () { return this } +Pattern.prototype.createPartForSet = function (partName, set = 0) { + // Create parts + this.setStores[set].log.debug(`📦 Creating part \`${partName}\` (set ${set})`) + this.parts[set][partName] = this.__createPartWithContext(partName, set) + + // Handle inject/inheritance + if (typeof this.__inject[partName] === 'string') { + this.setStores[set].log.debug( + `Creating part \`${partName}\` from part \`${this.__inject[partName]}\`` + ) + try { + this.parts[set][partName].__inject(this.parts[set][this.__inject[partName]]) + } catch (err) { + this.setStores[set].log.error([ + `Could not inject part \`${this.__inject[partName]}\` into part \`${partName}\``, + err, + ]) + } + } + if (this.__needs(partName, set)) { + // Draft part + const result = this.draftPartForSet(partName, set) + if (typeof result === 'undefined') { + this.setStores[set].log.error( + `Result of drafting part ${partName} was undefined. Did you forget to return the part?` + ) + } else this.parts[set][partName] = result + // FIXME: THis won't work not that this is immutable + // But is it still needed? + // this.parts[set][partName].hidden === true ? true : !this.__wants(partName, set) + } else { + this.setStores[set].log.debug( + `Part \`${partName}\` is not needed. Skipping draft and setting hidden to \`true\`` + ) + this.parts[set][partName].hidden = true + } +} + +Pattern.prototype.draftPartForSet = function (partName, set) { + if (typeof this.__designParts?.[partName]?.draft === 'function') { + this.activePart = partName + try { + this.__runHooks('prePartDraft') + const result = this.__designParts[partName].draft(this.parts[set][partName].shorthand()) + this.__runHooks('postPartDraft') + return result + } catch (err) { + this.setStores[set].log.error([`Unable to draft part \`${partName}\` (set ${set})`, err]) + } + } else + this.setStores[set].log.error( + `Unable to draft pattern part __${partName}__. Part.draft() is not callable` + ) +} + /** * Return the initialized configuration * @@ -185,11 +192,10 @@ Pattern.prototype.getRenderProps = function () { // Run pre-render hook let svg = new Svg(this) svg.hooks = this.hooks - svg.__runHooks('preRender') this.__pack() - // Run post-layout hook - this.__runHooks('postLayout') + svg.__runHooks('preRender') + let props = { svg } props.width = this.width props.height = this.height @@ -1105,6 +1111,7 @@ Pattern.prototype.__optionSets = function (optionName) { * @return {Pattern} this - The Pattern instance */ Pattern.prototype.__pack = function () { + this.__runHooks('preLayout') for (const set in this.settings) { if (this.setStores[set].logs.error.length > 0) { this.setStores[set].log.warning(`One or more errors occured. Not packing pattern parts`) @@ -1165,6 +1172,7 @@ Pattern.prototype.__pack = function () { } } + this.__runHooks('postLayout') return this } diff --git a/packages/core/src/svg.mjs b/packages/core/src/svg.mjs index 3c44f1a82e3..d77412ce6ac 100644 --- a/packages/core/src/svg.mjs +++ b/packages/core/src/svg.mjs @@ -47,7 +47,6 @@ export function Svg(pattern) { Svg.prototype.render = function () { this.idPrefix = this.pattern?.settings?.[0]?.idPrefix || 'fs-' this.__runHooks('preRender') - this.pattern.__runHooks('postLayout') if (!this.pattern.settings[0].embed) { this.attributes.add('width', round(this.pattern.width) + 'mm') this.attributes.add('height', round(this.pattern.height) + 'mm') @@ -62,7 +61,7 @@ Svg.prototype.render = function () { this.activeStack = stackId this.idPrefix = this.pattern.settings[this.activeStackIndex]?.idPrefix || 'fs-' const stack = this.pattern.stacks[stackId] - if (!stack.hidden) { + if (!this.pattern.__isStackHidden(stackId)) { const stackSvg = this.__renderStack(stack) this.layout[stackId] = { svg: stackSvg,