diff --git a/packages/core/src/pattern/pattern-drafter.mjs b/packages/core/src/pattern/pattern-drafter.mjs index da6f6ef87bb..8db3b11c0b7 100644 --- a/packages/core/src/pattern/pattern-drafter.mjs +++ b/packages/core/src/pattern/pattern-drafter.mjs @@ -2,6 +2,10 @@ import { PatternDraftQueue } from './pattern-draft-queue.mjs' import { Part } from '../part.mjs' import { __macroName } from '../utils.mjs' +/** + * A class to handle drafting a pattern + * @param {Pattern} pattern the pattern to draft + */ export function PatternDrafter(pattern) { this.pattern = pattern } @@ -32,6 +36,7 @@ PatternDrafter.prototype.draft = function () { // Handle snap for pct options this.__loadAbsoluteOptionsSet(set) + // draft all the parts for this set this.pattern.draftQueue.start() while (this.pattern.draftQueue.hasNext()) { const partName = this.pattern.draftQueue.next() @@ -46,6 +51,12 @@ PatternDrafter.prototype.draft = function () { this.pattern.__runHooks('postDraft') } +/** + * Draft and save a part for the given set of settings + * @param {String} partName the name of the part + * @param {number} set the index of the settings set + * @return {Part} the drafted part, which is also stored in the Pattern + */ PatternDrafter.prototype.draftPartForSet = function (partName, set) { // gotta protect against attacks if (set === '__proto__') { @@ -54,6 +65,7 @@ PatternDrafter.prototype.draftPartForSet = function (partName, set) { this.__useSet(set) this.__createPartForSet(partName, set) + // don't draft what can't be drafted const configPart = this.pattern.config.parts?.[partName] if (typeof configPart?.draft !== 'function') { this.activeStore.log.error( @@ -62,10 +74,12 @@ PatternDrafter.prototype.draftPartForSet = function (partName, set) { return } + // set the active part for use by hooks and such this.pattern.activePart = partName this.activeStore.set('activePart', partName) try { this.pattern.__runHooks('prePartDraft') + // draft const result = configPart.draft(this.pattern.parts[set][partName].shorthand()) if (typeof result === 'undefined') { @@ -73,8 +87,10 @@ PatternDrafter.prototype.draftPartForSet = function (partName, set) { `Result of drafting part ${partName} was undefined. Did you forget to return the part?` ) } else { + // hide if necessary if (!this.pattern.__wants(partName, set)) result.hide() this.pattern.__runHooks('postPartDraft') + // save the result this.pattern.parts[set][partName] = result } return result @@ -83,30 +99,6 @@ PatternDrafter.prototype.draftPartForSet = function (partName, set) { } } -PatternDrafter.prototype.__createPartForSet = function (partName, set = 0) { - // gotta protect against attacks - if (set === '__proto__') { - throw new Error('malicious attempt at altering Object.prototype. Stopping action') - } - // Create parts - this.activeStore.log.debug(`📦 Creating part \`${partName}\` (set ${set})`) - this.pattern.parts[set][partName] = this.__createPartWithContext(partName, set) - - // Handle inject/inheritance - const parent = this.pattern.config.inject[partName] - if (typeof parent === 'string') { - this.activeStore.log.debug(`Creating part \`${partName}\` from part \`${parent}\``) - try { - this.pattern.parts[set][partName].__inject(this.pattern.parts[set][parent]) - } catch (err) { - this.activeStore.log.error([ - `Could not inject part \`${parent}\` into part \`${partName}\``, - err, - ]) - } - } -} - /** * Instantiates a new Part instance and populates it with the pattern context * @@ -207,8 +199,12 @@ PatternDrafter.prototype.__snappedPercentageOption = function (optionName, set) return abs } +/** + * Sets the active set + * @param {Number} set the set to use + * @private + */ PatternDrafter.prototype.__useSet = function (set = 0) { this.pattern.activeSet = set - this.activeSettings = this.pattern.settings[set] this.activeStore = this.pattern.setStores[set] } diff --git a/packages/core/src/pattern/pattern-plugins.mjs b/packages/core/src/pattern/pattern-plugins.mjs index e41d6a5b78d..a8006abf0ec 100644 --- a/packages/core/src/pattern/pattern-plugins.mjs +++ b/packages/core/src/pattern/pattern-plugins.mjs @@ -11,6 +11,10 @@ export function getPluginName(plugin) { return toCheck.name || toCheck.plugin?.name || false } +/** + * A class for managing the plugins and lifecycle hooks of a pattern + * @param {Pattern} pattern the pattern to manage + */ export function PatternPlugins(pattern) { this.store = pattern.store @@ -21,21 +25,15 @@ export function PatternPlugins(pattern) { } /** - * Loads a plugin + * Loads the plugins that are part of the config * - * @param {object} plugin - The plugin to load - * @param {object} data - Any data to pass to the plugin - * @return {object} this - The Pattern instance + * @private + * @return {Pattern} this - The Pattern instance */ -PatternPlugins.prototype.use = function (plugin, data, settings = [{}]) { - const name = getPluginName(plugin) - if (!this.plugins?.[name]) - return plugin.plugin && plugin.condition - ? this.__useIf(plugin, data, settings) // Conditional plugin - : this.__loadPlugin(plugin, data) // Regular plugin - - this.store.log.info(`Plugin \`${name}\` was requested, but it's already loaded. Skipping.`) - +PatternPlugins.prototype.loadConfigPlugins = function (config, settings) { + if (!config.plugins) return this + for (const plugin in config.plugins) + this.use(config.plugins[plugin], config.plugins[plugin]?.data, settings) return this } @@ -58,15 +56,21 @@ PatternPlugins.prototype.on = function (hook, method, data) { } /** - * Loads the plugins that are part of the config + * Loads a plugin * - * @private - * @return {Pattern} this - The Pattern instance + * @param {object} plugin - The plugin to load + * @param {object} data - Any data to pass to the plugin + * @return {object} this - The Pattern instance */ -PatternPlugins.prototype.loadConfigPlugins = function (config, settings) { - if (!config.plugins) return this - for (const plugin in config.plugins) - this.use(config.plugins[plugin], config.plugins[plugin]?.data, settings) +PatternPlugins.prototype.use = function (plugin, data, settings = [{}]) { + const name = getPluginName(plugin) + if (!this.plugins?.[name]) + return plugin.plugin && plugin.condition + ? this.__useIf(plugin, data, settings) // Conditional plugin + : this.__loadPlugin(plugin, data) // Regular plugin + + this.store.log.info(`Plugin \`${name}\` was requested, but it's already loaded. Skipping.`) + return this } diff --git a/packages/core/src/pattern/pattern-renderer.mjs b/packages/core/src/pattern/pattern-renderer.mjs index 071553a9341..4e418b0f0f7 100644 --- a/packages/core/src/pattern/pattern-renderer.mjs +++ b/packages/core/src/pattern/pattern-renderer.mjs @@ -2,6 +2,10 @@ import { Svg } from '../svg.mjs' import { Stack } from '../stack.mjs' import pack from 'bin-pack-with-constraints' +/** + * A class for handling layout and rendering for a pattern + * @param {Pattern} pattern the pattern to layout or render + */ export function PatternRenderer(pattern) { this.pattern = pattern this.autoLayout = pattern.autoLayout diff --git a/packages/core/src/pattern/pattern-sampler.mjs b/packages/core/src/pattern/pattern-sampler.mjs index a65fb30a71e..07e5687765c 100644 --- a/packages/core/src/pattern/pattern-sampler.mjs +++ b/packages/core/src/pattern/pattern-sampler.mjs @@ -1,3 +1,7 @@ +/** + * A class for handling pattern sampling + * @param {Pattern} pattern the pattern that will be sampled + */ export function PatternSampler(pattern) { this.pattern = pattern } @@ -47,20 +51,6 @@ PatternSampler.prototype.sampleOption = function (optionName) { return this.pattern.draft() } -/** - * Returns the base/defaults to generate a set of settings - * - * @private - * @return {object} settings - The settings object - */ -PatternSampler.prototype.__setBase = function () { - return { - measurements: {}, - options: {}, - ...this.pattern.settings[0], - } -} - /** * Generates an array of settings.options objects for sampling a list or boolean option * @@ -210,3 +200,17 @@ PatternSampler.prototype.__optionSets = function (optionName) { return sets } + +/** + * Returns the base/defaults to generate a set of settings + * + * @private + * @return {object} settings - The settings object + */ +PatternSampler.prototype.__setBase = function () { + return { + measurements: {}, + options: {}, + ...this.pattern.settings[0], + } +}