refactor (core) move plugin and hook handling to its own class
This commit is contained in:
parent
e59341effa
commit
c5baaab234
5 changed files with 225 additions and 184 deletions
|
@ -11,9 +11,10 @@ import { Store } from '../store.mjs'
|
||||||
import { Hooks } from '../hooks.mjs'
|
import { Hooks } from '../hooks.mjs'
|
||||||
import { version } from '../../data.mjs'
|
import { version } from '../../data.mjs'
|
||||||
import { __loadPatternDefaults } from '../config.mjs'
|
import { __loadPatternDefaults } from '../config.mjs'
|
||||||
import { PatternConfig, getPluginName } from './pattern-config.mjs'
|
import { PatternConfig } from './pattern-config.mjs'
|
||||||
import { PatternDraftQueue } from './pattern-draft-queue.mjs'
|
import { PatternDraftQueue } from './pattern-draft-queue.mjs'
|
||||||
import { PatternSampler } from './pattern-sampler.mjs'
|
import { PatternSampler } from './pattern-sampler.mjs'
|
||||||
|
import { PatternPlugins, getPluginName } from './pattern-plugins.mjs'
|
||||||
import cloneDeep from 'lodash.clonedeep'
|
import cloneDeep from 'lodash.clonedeep'
|
||||||
|
|
||||||
//////////////////////////////////////////////
|
//////////////////////////////////////////////
|
||||||
|
@ -35,7 +36,6 @@ export function Pattern(designConfig = {}) {
|
||||||
this.setStores = [] // Per-set stores
|
this.setStores = [] // Per-set stores
|
||||||
|
|
||||||
// Non-enumerable properties
|
// Non-enumerable properties
|
||||||
__addNonEnumProp(this, 'plugins', {})
|
|
||||||
__addNonEnumProp(this, 'width', 0)
|
__addNonEnumProp(this, 'width', 0)
|
||||||
__addNonEnumProp(this, 'height', 0)
|
__addNonEnumProp(this, 'height', 0)
|
||||||
__addNonEnumProp(this, 'autoLayout', { stacks: {} })
|
__addNonEnumProp(this, 'autoLayout', { stacks: {} })
|
||||||
|
@ -49,7 +49,8 @@ export function Pattern(designConfig = {}) {
|
||||||
__addNonEnumProp(this, '__initialized', false)
|
__addNonEnumProp(this, '__initialized', false)
|
||||||
__addNonEnumProp(this, 'config.parts', {})
|
__addNonEnumProp(this, 'config.parts', {})
|
||||||
__addNonEnumProp(this, 'config.resolvedDependencies', {})
|
__addNonEnumProp(this, 'config.resolvedDependencies', {})
|
||||||
__addNonEnumProp(this, '__storeMethods', new Set())
|
|
||||||
|
__addNonEnumProp(this, 'plugins', new PatternPlugins(this))
|
||||||
__addNonEnumProp(this, '__configResolver', new PatternConfig(this)) // handles config resolution during __init() as well as runtime part adding
|
__addNonEnumProp(this, '__configResolver', new PatternConfig(this)) // handles config resolution during __init() as well as runtime part adding
|
||||||
|
|
||||||
return this
|
return this
|
||||||
|
@ -202,7 +203,7 @@ Pattern.prototype.getRenderProps = function () {
|
||||||
this.store.log.info('Gathering render props')
|
this.store.log.info('Gathering render props')
|
||||||
// Run pre-render hook
|
// Run pre-render hook
|
||||||
let svg = new Svg(this)
|
let svg = new Svg(this)
|
||||||
svg.hooks = this.hooks
|
svg.hooks = this.plugins.hooks
|
||||||
|
|
||||||
this.__pack()
|
this.__pack()
|
||||||
svg.__runHooks('preRender')
|
svg.__runHooks('preRender')
|
||||||
|
@ -294,11 +295,7 @@ Pattern.prototype.sampleOption = function (optionName) {
|
||||||
* @return {object} this - The Pattern instance
|
* @return {object} this - The Pattern instance
|
||||||
*/
|
*/
|
||||||
Pattern.prototype.on = function (hook, method, data) {
|
Pattern.prototype.on = function (hook, method, data) {
|
||||||
for (const added of this.hooks[hook]) {
|
this.plugins.on(hook, method, data)
|
||||||
// Don't add it twice
|
|
||||||
if (added.method === method) return this
|
|
||||||
}
|
|
||||||
this.hooks[hook].push({ method, data })
|
|
||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
@ -310,7 +307,7 @@ Pattern.prototype.on = function (hook, method, data) {
|
||||||
*/
|
*/
|
||||||
Pattern.prototype.render = function () {
|
Pattern.prototype.render = function () {
|
||||||
this.svg = new Svg(this)
|
this.svg = new Svg(this)
|
||||||
this.svg.hooks = this.hooks
|
this.svg.hooks = this.plugins.hooks
|
||||||
|
|
||||||
return this.__pack().svg.render()
|
return this.__pack().svg.render()
|
||||||
}
|
}
|
||||||
|
@ -323,13 +320,7 @@ Pattern.prototype.render = function () {
|
||||||
* @return {object} this - The Pattern instance
|
* @return {object} this - The Pattern instance
|
||||||
*/
|
*/
|
||||||
Pattern.prototype.use = function (plugin, data) {
|
Pattern.prototype.use = function (plugin, data) {
|
||||||
const name = getPluginName(plugin)
|
this.plugins.use(plugin, data, this.settings)
|
||||||
if (!this.plugins?.[name])
|
|
||||||
return plugin.plugin && plugin.condition
|
|
||||||
? this.__useIf(plugin, data) // Conditional plugin
|
|
||||||
: this.__loadPlugin(plugin, data) // Regular plugin
|
|
||||||
|
|
||||||
this.store.log.info(`Plugin \`${name}\` was requested, but it's already loaded. Skipping.`)
|
|
||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
@ -347,7 +338,7 @@ Pattern.prototype.use = function (plugin, data) {
|
||||||
Pattern.prototype.__createSetStore = function () {
|
Pattern.prototype.__createSetStore = function () {
|
||||||
const store = new Store()
|
const store = new Store()
|
||||||
store.set('data', this.store.data)
|
store.set('data', this.store.data)
|
||||||
store.extend([...this.__storeMethods])
|
store.extend([...this.plugins.__storeMethods])
|
||||||
|
|
||||||
return store
|
return store
|
||||||
}
|
}
|
||||||
|
@ -400,15 +391,15 @@ Pattern.prototype.__createPartWithContext = function (name, set) {
|
||||||
config: this.config,
|
config: this.config,
|
||||||
settings: this.settings[set],
|
settings: this.settings[set],
|
||||||
store: this.setStores[set],
|
store: this.setStores[set],
|
||||||
macros: this.macros,
|
macros: this.plugins.macros,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.settings[set]?.partClasses) {
|
if (this.settings[set]?.partClasses) {
|
||||||
part.attr('class', this.settings[set].partClasses)
|
part.attr('class', this.settings[set].partClasses)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const macro in this.macros) {
|
for (const macro in this.plugins.macros) {
|
||||||
part[__macroName(macro)] = this.macros[macro]
|
part[__macroName(macro)] = this.plugins.macros[macro]
|
||||||
}
|
}
|
||||||
|
|
||||||
return part
|
return part
|
||||||
|
@ -457,9 +448,10 @@ Pattern.prototype.__init = function () {
|
||||||
*/
|
*/
|
||||||
this.__resolveParts() // Resolves parts
|
this.__resolveParts() // Resolves parts
|
||||||
.__resolveConfig() // Gets the config from the resolver
|
.__resolveConfig() // Gets the config from the resolver
|
||||||
.__loadOptionDefaults() // Merges default options with user provided ones
|
|
||||||
.__loadPlugins() // Loads plugins
|
|
||||||
.__loadConfigData() // Makes config data available in store
|
.__loadConfigData() // Makes config data available in store
|
||||||
|
.__loadOptionDefaults() // Merges default options with user provided ones
|
||||||
|
|
||||||
|
this.plugins.loadConfigPlugins(this.config, this.settings) // Loads plugins
|
||||||
|
|
||||||
this.store.log.info(`Pattern initialized. Draft order is: ${this.config.draftOrder.join(', ')}`)
|
this.store.log.info(`Pattern initialized. Draft order is: ${this.config.draftOrder.join(', ')}`)
|
||||||
this.__runHooks('postInit')
|
this.__runHooks('postInit')
|
||||||
|
@ -577,104 +569,6 @@ Pattern.prototype.__loadOptionDefaults = function () {
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads a plugin
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {object} plugin - The plugin object, or an object with `plugin` and `condition` keys
|
|
||||||
* @param {object} data - Any plugin data to load
|
|
||||||
* @return {Pattern} this - The Pattern instance
|
|
||||||
*/
|
|
||||||
Pattern.prototype.__loadPlugin = function (plugin, data) {
|
|
||||||
this.plugins[plugin.name] = plugin
|
|
||||||
if (plugin.hooks) this.__loadPluginHooks(plugin, data)
|
|
||||||
if (plugin.macros) this.__loadPluginMacros(plugin)
|
|
||||||
if (plugin.store) this.__loadPluginStoreMethods(plugin)
|
|
||||||
this.store.log.info(`Loaded plugin \`${plugin.name}:${plugin.version}\``)
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads a plugin's hooks
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {object} plugin - The plugin object
|
|
||||||
* @param {object} data - Any plugin data to load
|
|
||||||
* @return {Pattern} this - The Pattern instance
|
|
||||||
*/
|
|
||||||
Pattern.prototype.__loadPluginHooks = function (plugin, data) {
|
|
||||||
for (let hook of Object.keys(this.hooks)) {
|
|
||||||
if (typeof plugin.hooks[hook] === 'function') {
|
|
||||||
this.on(hook, plugin.hooks[hook], data)
|
|
||||||
} else if (Array.isArray(plugin.hooks[hook])) {
|
|
||||||
for (let method of plugin.hooks[hook]) {
|
|
||||||
this.on(hook, method, data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads a plugin's macros
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {object} plugin - The plugin object
|
|
||||||
* @return {Pattern} this - The Pattern instance
|
|
||||||
*/
|
|
||||||
Pattern.prototype.__loadPluginMacros = function (plugin) {
|
|
||||||
for (let macro in plugin.macros) {
|
|
||||||
if (typeof plugin.macros[macro] === 'function') {
|
|
||||||
this.__macro(macro, plugin.macros[macro])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads the plugins that are part of the config
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @return {Pattern} this - The Pattern instance
|
|
||||||
*/
|
|
||||||
Pattern.prototype.__loadPlugins = function () {
|
|
||||||
if (!this.config.plugins) return this
|
|
||||||
for (const plugin in this.config.plugins)
|
|
||||||
this.use(this.config.plugins[plugin], this.config.plugins[plugin]?.data)
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads a plugin's store methods
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {object} plugin - The plugin object
|
|
||||||
* @return {Pattern} this - The Pattern instance
|
|
||||||
*/
|
|
||||||
Pattern.prototype.__loadPluginStoreMethods = function (plugin) {
|
|
||||||
if (Array.isArray(plugin.store)) {
|
|
||||||
for (const method of plugin.store) this.__storeMethods.add(method)
|
|
||||||
} else this.store.log.warning(`Plugin store methods should be an Array`)
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a method for a macro
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {string} macro - Name of the macro to run
|
|
||||||
* @param {function} method - The macro method
|
|
||||||
* @return {object} this - The Pattern instance
|
|
||||||
*/
|
|
||||||
Pattern.prototype.__macro = function (key, method) {
|
|
||||||
this.macros[key] = method
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether a part is needed, depending on the 'only' setting and the configured dependencies
|
* Determines whether a part is needed, depending on the 'only' setting and the configured dependencies
|
||||||
*
|
*
|
||||||
|
@ -815,7 +709,7 @@ Pattern.prototype.__resolveParts = function () {
|
||||||
*/
|
*/
|
||||||
Pattern.prototype.__runHooks = function (hookName, data = false) {
|
Pattern.prototype.__runHooks = function (hookName, data = false) {
|
||||||
if (data === false) data = this
|
if (data === false) data = this
|
||||||
let hooks = this.hooks[hookName]
|
let hooks = this.plugins.hooks[hookName]
|
||||||
if (hooks.length > 0) {
|
if (hooks.length > 0) {
|
||||||
this.store.log.debug(`Running \`${hookName}\` hooks`)
|
this.store.log.debug(`Running \`${hookName}\` hooks`)
|
||||||
for (let hook of hooks) {
|
for (let hook of hooks) {
|
||||||
|
@ -863,32 +757,6 @@ Pattern.prototype.__snappedPercentageOption = function (optionName, set) {
|
||||||
return abs
|
return abs
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads a conditional plugin
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {object} plugin - An object with `plugin` and `condition` keys
|
|
||||||
* @return {Pattern} this - The Pattern instance
|
|
||||||
*/
|
|
||||||
Pattern.prototype.__useIf = function (plugin) {
|
|
||||||
let load = 0
|
|
||||||
for (const set of this.settings) {
|
|
||||||
if (plugin.condition(set)) load++
|
|
||||||
}
|
|
||||||
if (load > 0) {
|
|
||||||
this.store.log.info(
|
|
||||||
`Condition met: Loaded plugin \`${plugin.plugin.name}:${plugin.plugin.version}\``
|
|
||||||
)
|
|
||||||
this.__loadPlugin(plugin.plugin, plugin.data)
|
|
||||||
} else {
|
|
||||||
this.store.log.info(
|
|
||||||
`Condition not met: Skipped loading plugin \`${plugin.plugin.name}:${plugin.plugin.version}\``
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether a part is wanted, depending on the 'only' setting and the configured dependencies
|
* Determines whether a part is wanted, depending on the 'only' setting and the configured dependencies
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { __addNonEnumProp } from '../utils.mjs'
|
import { __addNonEnumProp } from '../utils.mjs'
|
||||||
|
import { getPluginName } from './pattern-plugins.mjs'
|
||||||
|
|
||||||
export const hidePresets = {
|
export const hidePresets = {
|
||||||
HIDE_ALL: {
|
HIDE_ALL: {
|
||||||
|
@ -13,17 +14,6 @@ export const hidePresets = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the name of the given plugin config
|
|
||||||
*
|
|
||||||
* @param {(Object|Object[])} plugin the plugin to get the name of
|
|
||||||
* @return {(string|false)} the name, or false if there isn't one
|
|
||||||
*/
|
|
||||||
export function getPluginName(plugin) {
|
|
||||||
const toCheck = Array.isArray(plugin) ? plugin[0] : plugin
|
|
||||||
return toCheck.name || toCheck.plugin?.name || false
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////
|
/////////////////
|
||||||
// CONSTRUCTOR //
|
// CONSTRUCTOR //
|
||||||
/////////////////
|
/////////////////
|
||||||
|
|
185
packages/core/src/pattern/pattern-plugins.mjs
Normal file
185
packages/core/src/pattern/pattern-plugins.mjs
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
import { Hooks } from '../hooks.mjs'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name of the given plugin config
|
||||||
|
*
|
||||||
|
* @param {(Object|Object[])} plugin the plugin to get the name of
|
||||||
|
* @return {(string|false)} the name, or false if there isn't one
|
||||||
|
*/
|
||||||
|
export function getPluginName(plugin) {
|
||||||
|
const toCheck = Array.isArray(plugin) ? plugin[0] : plugin
|
||||||
|
return toCheck.name || toCheck.plugin?.name || false
|
||||||
|
}
|
||||||
|
|
||||||
|
export function PatternPlugins(pattern) {
|
||||||
|
this.store = pattern.store
|
||||||
|
|
||||||
|
this.plugins = {}
|
||||||
|
this.hooks = new Hooks()
|
||||||
|
this.macros = {}
|
||||||
|
this.__storeMethods = new Set()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a plugin
|
||||||
|
*
|
||||||
|
* @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.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
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a lifecycle hook method to the pattern
|
||||||
|
*
|
||||||
|
* @param {string} hook - Name of the lifecycle hook
|
||||||
|
* @param {function} method - The method to run
|
||||||
|
* @param {object} data - Any data to pass to the hook method
|
||||||
|
* @return {object} this - The Pattern instance
|
||||||
|
*/
|
||||||
|
PatternPlugins.prototype.on = function (hook, method, data) {
|
||||||
|
for (const added of this.hooks[hook]) {
|
||||||
|
// Don't add it twice
|
||||||
|
if (added.method === method) return this
|
||||||
|
}
|
||||||
|
this.hooks[hook].push({ method, data })
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the plugins that are part of the config
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @return {Pattern} 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)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a plugin
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {object} plugin - The plugin object, or an object with `plugin` and `condition` keys
|
||||||
|
* @param {object} data - Any plugin data to load
|
||||||
|
* @return {Pattern} this - The Pattern instance
|
||||||
|
*/
|
||||||
|
PatternPlugins.prototype.__loadPlugin = function (plugin, data) {
|
||||||
|
const name = getPluginName(plugin)
|
||||||
|
this.plugins[name] = plugin
|
||||||
|
if (plugin.hooks) this.__loadPluginHooks(plugin, data)
|
||||||
|
if (plugin.macros) this.__loadPluginMacros(plugin)
|
||||||
|
if (plugin.store) this.__loadPluginStoreMethods(plugin)
|
||||||
|
this.store.log.info(`Loaded plugin \`${plugin.name}:${plugin.version}\``)
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a plugin's hooks
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {object} plugin - The plugin object
|
||||||
|
* @param {object} data - Any plugin data to load
|
||||||
|
* @return {Pattern} this - The Pattern instance
|
||||||
|
*/
|
||||||
|
PatternPlugins.prototype.__loadPluginHooks = function (plugin, data) {
|
||||||
|
// console.log('hooks', plugin)
|
||||||
|
for (let hook of Object.keys(this.hooks)) {
|
||||||
|
if (typeof plugin.hooks[hook] === 'function') {
|
||||||
|
this.on(hook, plugin.hooks[hook], data)
|
||||||
|
} else if (Array.isArray(plugin.hooks[hook])) {
|
||||||
|
for (let method of plugin.hooks[hook]) {
|
||||||
|
this.on(hook, method, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a plugin's macros
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {object} plugin - The plugin object
|
||||||
|
* @return {Pattern} this - The Pattern instance
|
||||||
|
*/
|
||||||
|
PatternPlugins.prototype.__loadPluginMacros = function (plugin) {
|
||||||
|
// console.log('macros', plugin)
|
||||||
|
for (let macro in plugin.macros) {
|
||||||
|
if (typeof plugin.macros[macro] === 'function') {
|
||||||
|
this.__macro(macro, plugin.macros[macro])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a plugin's store methods
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {object} plugin - The plugin object
|
||||||
|
* @return {Pattern} this - The Pattern instance
|
||||||
|
*/
|
||||||
|
PatternPlugins.prototype.__loadPluginStoreMethods = function (plugin) {
|
||||||
|
if (Array.isArray(plugin.store)) {
|
||||||
|
for (const method of plugin.store) this.__storeMethods.add(method)
|
||||||
|
} else this.store.log.warning(`Plugin store methods should be an Array`)
|
||||||
|
|
||||||
|
// console.log('store', plugin, this.__storeMethods)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a method for a macro
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {string} macro - Name of the macro to run
|
||||||
|
* @param {function} method - The macro method
|
||||||
|
* @return {object} this - The Pattern instance
|
||||||
|
*/
|
||||||
|
PatternPlugins.prototype.__macro = function (key, method) {
|
||||||
|
this.macros[key] = method
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a conditional plugin
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {object} plugin - An object with `plugin` and `condition` keys
|
||||||
|
* @return {Pattern} this - The Pattern instance
|
||||||
|
*/
|
||||||
|
PatternPlugins.prototype.__useIf = function (plugin, settings = [{}]) {
|
||||||
|
let load = 0
|
||||||
|
for (const set of settings) {
|
||||||
|
if (plugin.condition(set)) load++
|
||||||
|
}
|
||||||
|
if (load > 0) {
|
||||||
|
this.store.log.info(
|
||||||
|
`Condition met: Loaded plugin \`${plugin.plugin.name}:${plugin.plugin.version}\``
|
||||||
|
)
|
||||||
|
this.__loadPlugin(plugin.plugin, plugin.data)
|
||||||
|
} else {
|
||||||
|
this.store.log.info(
|
||||||
|
`Condition not met: Skipped loading plugin \`${plugin.plugin.name}:${plugin.plugin.version}\``
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
|
@ -18,7 +18,7 @@ describe('Pattern', () => {
|
||||||
expect(Array.isArray(pattern.setStores)).to.equal(true)
|
expect(Array.isArray(pattern.setStores)).to.equal(true)
|
||||||
expect(typeof pattern.store).to.equal('object')
|
expect(typeof pattern.store).to.equal('object')
|
||||||
expect(typeof pattern.config).to.equal('object')
|
expect(typeof pattern.config).to.equal('object')
|
||||||
expect(Object.keys(pattern).length).to.equal(5)
|
expect(Object.keys(pattern)).to.have.lengthOf(5)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Pattern constructor should add non-enumerable properties', () => {
|
it('Pattern constructor should add non-enumerable properties', () => {
|
||||||
|
@ -26,12 +26,10 @@ describe('Pattern', () => {
|
||||||
const pattern = new Pattern()
|
const pattern = new Pattern()
|
||||||
expect(typeof pattern.plugins).to.equal('object')
|
expect(typeof pattern.plugins).to.equal('object')
|
||||||
expect(typeof pattern.autoLayout).to.equal('object')
|
expect(typeof pattern.autoLayout).to.equal('object')
|
||||||
expect(typeof pattern.hooks).to.equal('object')
|
|
||||||
expect(typeof pattern.Point).to.equal('function')
|
expect(typeof pattern.Point).to.equal('function')
|
||||||
expect(typeof pattern.Path).to.equal('function')
|
expect(typeof pattern.Path).to.equal('function')
|
||||||
expect(typeof pattern.Snippet).to.equal('function')
|
expect(typeof pattern.Snippet).to.equal('function')
|
||||||
expect(typeof pattern.Attributes).to.equal('function')
|
expect(typeof pattern.Attributes).to.equal('function')
|
||||||
expect(typeof pattern.macros).to.equal('object')
|
|
||||||
// expect(typeof pattern.__designParts).to.equal('object')
|
// expect(typeof pattern.__designParts).to.equal('object')
|
||||||
// expect(typeof pattern.config.inject).to.equal('object')
|
// expect(typeof pattern.config.inject).to.equal('object')
|
||||||
// expect(typeof pattern.config.directDependencies).to.equal('object')
|
// expect(typeof pattern.config.directDependencies).to.equal('object')
|
||||||
|
@ -58,7 +56,7 @@ describe('Pattern', () => {
|
||||||
absoluteOptions: {},
|
absoluteOptions: {},
|
||||||
}
|
}
|
||||||
for (const [key, value] of Object.entries(dflts)) {
|
for (const [key, value] of Object.entries(dflts)) {
|
||||||
if (typeof value === 'object') expect(Object.keys(value).length).to.equal(0)
|
if (typeof value === 'object') expect(Object.keys(value)).to.have.lengthOf(0)
|
||||||
else expect(pattern.settings[0][key]).to.equal(value)
|
else expect(pattern.settings[0][key]).to.equal(value)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -120,19 +118,19 @@ describe('Pattern', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Pattern.__init() should resolve required measurements', () => {
|
it('Pattern.__init() should resolve required measurements', () => {
|
||||||
expect(pattern.config.measurements.length).to.equal(2)
|
expect(pattern.config.measurements).to.have.lengthOf(2)
|
||||||
expect(pattern.config.measurements[0]).to.equal('head')
|
expect(pattern.config.measurements[0]).to.equal('head')
|
||||||
expect(pattern.config.measurements[1]).to.equal('knee')
|
expect(pattern.config.measurements[1]).to.equal('knee')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Pattern.__init() should resolve optional measurements', () => {
|
it('Pattern.__init() should resolve optional measurements', () => {
|
||||||
expect(pattern.config.optionalMeasurements.length).to.equal(2)
|
expect(pattern.config.optionalMeasurements).to.have.lengthOf(2)
|
||||||
expect(pattern.config.optionalMeasurements[0]).to.equal('chest')
|
expect(pattern.config.optionalMeasurements[0]).to.equal('chest')
|
||||||
expect(pattern.config.optionalMeasurements[1]).to.equal('waist')
|
expect(pattern.config.optionalMeasurements[1]).to.equal('waist')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Pattern.__init() should resolve options', () => {
|
it('Pattern.__init() should resolve options', () => {
|
||||||
expect(Object.keys(pattern.config.options).length).to.equal(3)
|
expect(Object.keys(pattern.config.options)).to.have.lengthOf(3)
|
||||||
for (const [key, value] of Object.entries(partA.options.optA)) {
|
for (const [key, value] of Object.entries(partA.options.optA)) {
|
||||||
expect(pattern.config.options.optA[key]).to.equal(value)
|
expect(pattern.config.options.optA[key]).to.equal(value)
|
||||||
}
|
}
|
||||||
|
@ -149,7 +147,7 @@ describe('Pattern', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Pattern.__init() should resolve plugins', () => {
|
it('Pattern.__init() should resolve plugins', () => {
|
||||||
expect(Object.keys(pattern.config.plugins).length).to.equal(1)
|
expect(Object.keys(pattern.config.plugins)).to.have.lengthOf(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Pattern.__init() should set config data in the store', () => {
|
it('Pattern.__init() should set config data in the store', () => {
|
||||||
|
@ -160,12 +158,12 @@ describe('Pattern', () => {
|
||||||
it('Pattern.__init() should resolve dependencies', () => {
|
it('Pattern.__init() should resolve dependencies', () => {
|
||||||
expect(typeof pattern.config.resolvedDependencies).to.equal('object')
|
expect(typeof pattern.config.resolvedDependencies).to.equal('object')
|
||||||
expect(Array.isArray(pattern.config.resolvedDependencies['test.partA'])).to.equal(true)
|
expect(Array.isArray(pattern.config.resolvedDependencies['test.partA'])).to.equal(true)
|
||||||
expect(pattern.config.resolvedDependencies['test.partA'].length).to.equal(0)
|
expect(pattern.config.resolvedDependencies['test.partA']).to.have.lengthOf(0)
|
||||||
expect(Array.isArray(pattern.config.resolvedDependencies['test.partB'])).to.equal(true)
|
expect(Array.isArray(pattern.config.resolvedDependencies['test.partB'])).to.equal(true)
|
||||||
expect(pattern.config.resolvedDependencies['test.partB'].length).to.equal(1)
|
expect(pattern.config.resolvedDependencies['test.partB']).to.have.lengthOf(1)
|
||||||
expect(pattern.config.resolvedDependencies['test.partB'][0]).to.equal('test.partA')
|
expect(pattern.config.resolvedDependencies['test.partB'][0]).to.equal('test.partA')
|
||||||
expect(Array.isArray(pattern.config.resolvedDependencies['test.partC'])).to.equal(true)
|
expect(Array.isArray(pattern.config.resolvedDependencies['test.partC'])).to.equal(true)
|
||||||
expect(pattern.config.resolvedDependencies['test.partC'].length).to.equal(2)
|
expect(pattern.config.resolvedDependencies['test.partC']).to.have.lengthOf(2)
|
||||||
expect(
|
expect(
|
||||||
pattern.config.resolvedDependencies['test.partC'].indexOf('test.partA') !== -1
|
pattern.config.resolvedDependencies['test.partC'].indexOf('test.partA') !== -1
|
||||||
).to.equal(true)
|
).to.equal(true)
|
||||||
|
@ -325,13 +323,13 @@ describe('Pattern', () => {
|
||||||
const design = new Design({ parts: [partC] })
|
const design = new Design({ parts: [partC] })
|
||||||
const pattern = new design().addPart(partR).draft()
|
const pattern = new design().addPart(partR).draft()
|
||||||
// Measurements
|
// Measurements
|
||||||
expect(pattern.config.measurements.length).to.equal(4)
|
expect(pattern.config.measurements).to.have.lengthOf(4)
|
||||||
expect(pattern.config.measurements.indexOf('measieA') === -1).to.equal(false)
|
expect(pattern.config.measurements.indexOf('measieA') === -1).to.equal(false)
|
||||||
expect(pattern.config.measurements.indexOf('measieB') === -1).to.equal(false)
|
expect(pattern.config.measurements.indexOf('measieB') === -1).to.equal(false)
|
||||||
expect(pattern.config.measurements.indexOf('measieC') === -1).to.equal(false)
|
expect(pattern.config.measurements.indexOf('measieC') === -1).to.equal(false)
|
||||||
expect(pattern.config.measurements.indexOf('measieR') === -1).to.equal(false)
|
expect(pattern.config.measurements.indexOf('measieR') === -1).to.equal(false)
|
||||||
// Optional measurements
|
// Optional measurements
|
||||||
expect(pattern.config.optionalMeasurements.length).to.equal(4)
|
expect(pattern.config.optionalMeasurements).to.have.lengthOf(4)
|
||||||
expect(pattern.config.optionalMeasurements.indexOf('optmeasieA') === -1).to.equal(false)
|
expect(pattern.config.optionalMeasurements.indexOf('optmeasieA') === -1).to.equal(false)
|
||||||
expect(pattern.config.optionalMeasurements.indexOf('optmeasieB') === -1).to.equal(false)
|
expect(pattern.config.optionalMeasurements.indexOf('optmeasieB') === -1).to.equal(false)
|
||||||
expect(pattern.config.optionalMeasurements.indexOf('optmeasieC') === -1).to.equal(false)
|
expect(pattern.config.optionalMeasurements.indexOf('optmeasieC') === -1).to.equal(false)
|
||||||
|
@ -473,13 +471,13 @@ describe('Pattern', () => {
|
||||||
const design = new Design({ parts: [partD] })
|
const design = new Design({ parts: [partD] })
|
||||||
const pattern = new design().draft()
|
const pattern = new design().draft()
|
||||||
// Measurements
|
// Measurements
|
||||||
expect(pattern.config.measurements.length).to.equal(4)
|
expect(pattern.config.measurements).to.have.lengthOf(4)
|
||||||
expect(pattern.config.measurements.indexOf('measieA') === -1).to.equal(false)
|
expect(pattern.config.measurements.indexOf('measieA') === -1).to.equal(false)
|
||||||
expect(pattern.config.measurements.indexOf('measieB') === -1).to.equal(false)
|
expect(pattern.config.measurements.indexOf('measieB') === -1).to.equal(false)
|
||||||
expect(pattern.config.measurements.indexOf('measieC') === -1).to.equal(false)
|
expect(pattern.config.measurements.indexOf('measieC') === -1).to.equal(false)
|
||||||
expect(pattern.config.measurements.indexOf('measieD') === -1).to.equal(false)
|
expect(pattern.config.measurements.indexOf('measieD') === -1).to.equal(false)
|
||||||
// Optional measurements
|
// Optional measurements
|
||||||
expect(pattern.config.optionalMeasurements.length).to.equal(4)
|
expect(pattern.config.optionalMeasurements).to.have.lengthOf(4)
|
||||||
expect(pattern.config.optionalMeasurements.indexOf('optmeasieA') === -1).to.equal(false)
|
expect(pattern.config.optionalMeasurements.indexOf('optmeasieA') === -1).to.equal(false)
|
||||||
expect(pattern.config.optionalMeasurements.indexOf('optmeasieB') === -1).to.equal(false)
|
expect(pattern.config.optionalMeasurements.indexOf('optmeasieB') === -1).to.equal(false)
|
||||||
expect(pattern.config.optionalMeasurements.indexOf('optmeasieC') === -1).to.equal(false)
|
expect(pattern.config.optionalMeasurements.indexOf('optmeasieC') === -1).to.equal(false)
|
||||||
|
@ -578,7 +576,7 @@ describe('Pattern', () => {
|
||||||
const design = new Design({ parts: [part] })
|
const design = new Design({ parts: [part] })
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
pattern.draft()
|
pattern.draft()
|
||||||
expect(pattern.hooks.preRender.length).to.equal(1)
|
expect(pattern.plugins.hooks.preRender).to.have.lengthOf(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Pattern.__init() should load array of plugins', () => {
|
it('Pattern.__init() should load array of plugins', () => {
|
||||||
|
@ -608,7 +606,7 @@ describe('Pattern', () => {
|
||||||
const design = new Design({ parts: [part] })
|
const design = new Design({ parts: [part] })
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
pattern.__init()
|
pattern.__init()
|
||||||
expect(pattern.hooks.preRender.length).to.equal(2)
|
expect(pattern.plugins.hooks.preRender).to.have.lengthOf(2)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Pattern.__init() should load conditional plugin if condition is met', () => {
|
it('Pattern.__init() should load conditional plugin if condition is met', () => {
|
||||||
|
@ -629,8 +627,8 @@ describe('Pattern', () => {
|
||||||
}
|
}
|
||||||
const design = new Design({ parts: [part] })
|
const design = new Design({ parts: [part] })
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
pattern.draft()
|
pattern.__init()
|
||||||
expect(pattern.hooks.preRender.length).to.equal(1)
|
expect(pattern.plugins.hooks.preRender).to.have.lengthOf(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Pattern.__init() should not load conditional plugin if condition is not mett', () => {
|
it('Pattern.__init() should not load conditional plugin if condition is not mett', () => {
|
||||||
|
@ -651,7 +649,7 @@ describe('Pattern', () => {
|
||||||
}
|
}
|
||||||
const design = new Design({ parts: [part] })
|
const design = new Design({ parts: [part] })
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
expect(pattern.hooks.preRender.length).to.equal(0)
|
expect(pattern.plugins.hooks.preRender).to.have.lengthOf(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Pattern.__init() should load multiple conditional plugins', () => {
|
it('Pattern.__init() should load multiple conditional plugins', () => {
|
||||||
|
@ -686,7 +684,7 @@ describe('Pattern', () => {
|
||||||
const design = new Design({ parts: [part] })
|
const design = new Design({ parts: [part] })
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
pattern.draft()
|
pattern.draft()
|
||||||
expect(pattern.hooks.preRender.length).to.equal(1)
|
expect(pattern.plugins.hooks.preRender).to.have.lengthOf(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Pattern.__init() should load a conditional plugin multiple times with different conditions', () => {
|
it('Pattern.__init() should load a conditional plugin multiple times with different conditions', () => {
|
||||||
|
@ -718,7 +716,7 @@ describe('Pattern', () => {
|
||||||
expect(pattern.config.plugins).to.be.an('object').that.has.all.keys('example1', 'example1_')
|
expect(pattern.config.plugins).to.be.an('object').that.has.all.keys('example1', 'example1_')
|
||||||
expect(pattern.config.plugins.example1.plugin).to.deep.equal(plugin1)
|
expect(pattern.config.plugins.example1.plugin).to.deep.equal(plugin1)
|
||||||
expect(pattern.config.plugins.example1_.plugin).to.deep.equal(plugin1)
|
expect(pattern.config.plugins.example1_.plugin).to.deep.equal(plugin1)
|
||||||
expect(pattern.hooks.preRender.length).to.equal(1)
|
expect(pattern.plugins.hooks.preRender).to.have.lengthOf(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Load conditional plugins that are also passing data', () => {
|
it('Load conditional plugins that are also passing data', () => {
|
||||||
|
@ -757,7 +755,7 @@ describe('Pattern', () => {
|
||||||
})
|
})
|
||||||
const pattern = new design()
|
const pattern = new design()
|
||||||
pattern.__init()
|
pattern.__init()
|
||||||
expect(pattern.hooks.preRender.length).to.equal(2)
|
expect(pattern.plugins.hooks.preRender).to.have.lengthOf(2)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Pattern.__init() should register a hook via on', () => {
|
it('Pattern.__init() should register a hook via on', () => {
|
||||||
|
|
|
@ -90,8 +90,8 @@ describe('Pattern', () => {
|
||||||
pattern.use(plugin)
|
pattern.use(plugin)
|
||||||
pattern.use({ plugin })
|
pattern.use({ plugin })
|
||||||
pattern.use({ plugin })
|
pattern.use({ plugin })
|
||||||
expect(Object.keys(pattern.plugins).length).to.equal(1)
|
expect(Object.keys(pattern.plugins.plugins)).to.have.lengthOf(1)
|
||||||
expect(Object.keys(pattern.plugins)[0]).to.equal('test')
|
expect(Object.keys(pattern.plugins.plugins)[0]).to.equal('test')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should log an error of added parts do not have a draft method', () => {
|
it('Should log an error of added parts do not have a draft method', () => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue