feat(core): Move plugins to part-level config
This commit is contained in:
parent
fa14ad0fa3
commit
8a74a36697
5 changed files with 124 additions and 196 deletions
|
@ -8,12 +8,12 @@ import { addPartConfig } from './utils.mjs'
|
||||||
*/
|
*/
|
||||||
export function Design(config) {
|
export function Design(config) {
|
||||||
|
|
||||||
// Merge config with defaults
|
// Initialize config with defaults
|
||||||
config = {
|
config = {
|
||||||
parts: [],
|
|
||||||
options: {},
|
|
||||||
measurements: [],
|
measurements: [],
|
||||||
optionalMeasurements: [],
|
optionalMeasurements: [],
|
||||||
|
options: {},
|
||||||
|
parts: [],
|
||||||
plugins: [],
|
plugins: [],
|
||||||
...config
|
...config
|
||||||
}
|
}
|
||||||
|
@ -37,16 +37,7 @@ export function Design(config) {
|
||||||
const pattern = function (settings) {
|
const pattern = function (settings) {
|
||||||
Pattern.call(this, config)
|
Pattern.call(this, config)
|
||||||
|
|
||||||
// Load plugins
|
return this.init().apply(settings)
|
||||||
if (!Array.isArray(config.plugins)) config.plugins = [ config.plugins ]
|
|
||||||
for (const plugin of config.plugins) {
|
|
||||||
if (plugin.plugin && plugin.condition) this.useIf(plugin, settings)
|
|
||||||
else this.use(plugin)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.apply(settings)
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up inheritance
|
// Set up inheritance
|
||||||
|
|
|
@ -173,6 +173,10 @@ Pattern.prototype.getPartList = function () {
|
||||||
*/
|
*/
|
||||||
Pattern.prototype.init = function () {
|
Pattern.prototype.init = function () {
|
||||||
this.initialized++
|
this.initialized++
|
||||||
|
// Load plugins
|
||||||
|
if (this.config.plugins) {
|
||||||
|
for (const plugin of Object.values(this.config.plugins)) this.use(plugin)
|
||||||
|
}
|
||||||
// Resolve all dependencies
|
// Resolve all dependencies
|
||||||
this.dependencies = this.config.dependencies
|
this.dependencies = this.config.dependencies
|
||||||
this.inject = this.config.inject
|
this.inject = this.config.inject
|
||||||
|
@ -522,12 +526,19 @@ Pattern.prototype.render = function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
Pattern.prototype.on = function (hook, method, data) {
|
Pattern.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 })
|
this.hooks[hook].push({ method, data })
|
||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
Pattern.prototype.use = function (plugin, data) {
|
Pattern.prototype.use = function (plugin, data) {
|
||||||
|
// Conditional plugin?
|
||||||
|
if (plugin.plugin && plugin.condition) return this.useIf(plugin, data)
|
||||||
|
// Regular plugin
|
||||||
this.raise.info(`Loaded plugin \`${plugin.name}:${plugin.version}\``)
|
this.raise.info(`Loaded plugin \`${plugin.name}:${plugin.version}\``)
|
||||||
if (plugin.hooks) this.loadPluginHooks(plugin, data)
|
if (plugin.hooks) this.loadPluginHooks(plugin, data)
|
||||||
if (plugin.macros) this.loadPluginMacros(plugin)
|
if (plugin.macros) this.loadPluginMacros(plugin)
|
||||||
|
|
|
@ -567,12 +567,25 @@ export const addPartDependencies = (part, config) => {
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add part-level plugins
|
||||||
|
export const addPartPlugins = (part, config) => {
|
||||||
|
if (!part.plugins) return config
|
||||||
|
if (!Array.isArray(part.plugins)) part.plugins = [ part.plugins ]
|
||||||
|
for (const plugin of part.plugins) {
|
||||||
|
if (plugin.plugin && plugin.condition) config.plugins[plugin.plugin.name] = plugin
|
||||||
|
else config.plugins[plugin.name] = plugin
|
||||||
|
}
|
||||||
|
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
export const addPartConfig = (part, config) => {
|
export const addPartConfig = (part, config) => {
|
||||||
config = addPartOptions(part, config)
|
config = addPartOptions(part, config)
|
||||||
config = addPartMeasurements(part, config)
|
config = addPartMeasurements(part, config)
|
||||||
config = addPartOptionalMeasurements(part, config)
|
config = addPartOptionalMeasurements(part, config)
|
||||||
config = addPartDependencies(part, config)
|
config = addPartDependencies(part, config)
|
||||||
config = addPartOptionGroups(part, config)
|
config = addPartOptionGroups(part, config)
|
||||||
|
config = addPartPlugins(part, config)
|
||||||
|
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,99 +24,6 @@ describe('Design', () => {
|
||||||
expect(pattern.settings.options.percentage).to.equal(0.3);
|
expect(pattern.settings.options.percentage).to.equal(0.3);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Design constructor should load single plugin", () => {
|
|
||||||
let plugin = {
|
|
||||||
name: "example",
|
|
||||||
version: 1,
|
|
||||||
hooks: {
|
|
||||||
preRender: function(svg, attributes) {
|
|
||||||
svg.attributes.add("freesewing:plugin-example", version);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let design = new Design({plugins: plugin});
|
|
||||||
let pattern = new design();
|
|
||||||
expect(pattern.hooks.preRender.length).to.equal(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Design constructor should load array of plugins", () => {
|
|
||||||
let plugin1 = {
|
|
||||||
name: "example1",
|
|
||||||
version: 1,
|
|
||||||
hooks: {
|
|
||||||
preRender: function(svg, attributes) {
|
|
||||||
svg.attributes.add("freesewing:plugin-example1", version);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let plugin2 = {
|
|
||||||
name: "example2",
|
|
||||||
version: 2,
|
|
||||||
hooks: {
|
|
||||||
preRender: function(svg, attributes) {
|
|
||||||
svg.attributes.add("freesewing:plugin-example2", version);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let design = new Design( { plugins: [plugin1, plugin2] });
|
|
||||||
let pattern = new design();
|
|
||||||
expect(pattern.hooks.preRender.length).to.equal(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Design constructor should load conditional plugin", () => {
|
|
||||||
const plugin = {
|
|
||||||
name: "example",
|
|
||||||
version: 1,
|
|
||||||
hooks: {
|
|
||||||
preRender: function(svg, attributes) {
|
|
||||||
svg.attributes.add("freesewing:plugin-example", version);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const condition = () => true
|
|
||||||
const design = new Design({ plugins: { plugin, condition } });
|
|
||||||
const pattern = new design();
|
|
||||||
expect(pattern.hooks.preRender.length).to.equal(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Design constructor should not load conditional plugin", () => {
|
|
||||||
const plugin = {
|
|
||||||
name: "example",
|
|
||||||
version: 1,
|
|
||||||
hooks: {
|
|
||||||
preRender: function(svg, attributes) {
|
|
||||||
svg.attributes.add("freesewing:plugin-example", version);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const condition = () => false
|
|
||||||
const design = new Design({ plugins: { plugin, condition } });
|
|
||||||
const pattern = new design();
|
|
||||||
expect(pattern.hooks.preRender.length).to.equal(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Design constructor should load multiple conditional plugins", () => {
|
|
||||||
const plugin = {
|
|
||||||
name: "example",
|
|
||||||
version: 1,
|
|
||||||
hooks: {
|
|
||||||
preRender: function(svg, attributes) {
|
|
||||||
svg.attributes.add("freesewing:plugin-example", version);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const condition1 = () => true
|
|
||||||
const condition2 = () => false
|
|
||||||
const design = new Design({ plugins: [
|
|
||||||
{ plugin, condition: condition1 },
|
|
||||||
{ plugin, condition: condition2 },
|
|
||||||
]});
|
|
||||||
const pattern = new design();
|
|
||||||
expect(pattern.hooks.preRender.length).to.equal(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
it("Design constructor should not require depencies for injected parts", () => {
|
it("Design constructor should not require depencies for injected parts", () => {
|
||||||
let design = new freesewing.Design({
|
let design = new freesewing.Design({
|
||||||
|
|
|
@ -1059,98 +1059,104 @@ describe('Pattern', () => {
|
||||||
expect(pattern.parts.partD.paths.d.ops[1].to.x).to.equal(44)
|
expect(pattern.parts.partD.paths.d.ops[1].to.x).to.equal(44)
|
||||||
expect(pattern.parts.partD.paths.d.ops[1].to.y).to.equal(44)
|
expect(pattern.parts.partD.paths.d.ops[1].to.y).to.equal(44)
|
||||||
})
|
})
|
||||||
it("Pattern should merge optiongroups", () => {
|
|
||||||
const partA = {
|
it("Pattern should load single plugin", () => {
|
||||||
name: "partA",
|
const plugin = {
|
||||||
options: { optionA: { bool: true } },
|
name: "example",
|
||||||
measurements: [ 'measieA' ],
|
version: 1,
|
||||||
optionalMeasurements: [ 'optmeasieA' ],
|
hooks: {
|
||||||
optionGroups: {
|
preRender: function(svg, attributes) {
|
||||||
simple: ['simplea1', 'simplea2', 'simplea3'],
|
svg.attributes.add("freesewing:plugin-example", version);
|
||||||
nested: {
|
|
||||||
nested1: [ 'nested1a1', 'nested1a2', 'nested1a3' ],
|
|
||||||
},
|
|
||||||
subnested: {
|
|
||||||
subnested1: [
|
|
||||||
'subnested1a1',
|
|
||||||
'subnested1a2',
|
|
||||||
'subnested1a3',
|
|
||||||
{
|
|
||||||
subsubgroup: [
|
|
||||||
'subsuba1',
|
|
||||||
'subsuba2',
|
|
||||||
{
|
|
||||||
subsubsubgroup: [ 'subsubsub1', 'simplea1' ],
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
draft: part => part,
|
};
|
||||||
|
|
||||||
|
const part = {
|
||||||
|
name: 'test.part',
|
||||||
|
plugins: plugin,
|
||||||
|
draft: (part) => part
|
||||||
}
|
}
|
||||||
const partB = {
|
const design = new Design({ parts: [ part ] })
|
||||||
name: "partB",
|
const pattern = new design();
|
||||||
from: partA,
|
pattern.init()
|
||||||
options: { optionB: { pct: 12, min: 2, max: 20 } },
|
console.log(pattern)
|
||||||
measurements: [ 'measieB' ],
|
expect(pattern.hooks.preRender.length).to.equal(1);
|
||||||
optionalMeasurements: [ 'optmeasieB', 'measieA' ],
|
});
|
||||||
optionGroups: {
|
/*
|
||||||
simple: ['simpleb1', 'simpleb2', 'simpleb3'],
|
it("Design constructor should load array of plugins", () => {
|
||||||
bsimple: ['bsimpleb1', 'bsimpleb2', 'bsimpleb3'],
|
let plugin1 = {
|
||||||
nested: {
|
name: "example1",
|
||||||
nested2: [ 'nested2b1', 'nested2b2', 'nested2b3' ],
|
version: 1,
|
||||||
},
|
hooks: {
|
||||||
subnested: {
|
preRender: function(svg, attributes) {
|
||||||
subnested1: [
|
svg.attributes.add("freesewing:plugin-example1", version);
|
||||||
'subnested1b1',
|
|
||||||
'subnested1b2',
|
|
||||||
'subnested1b3',
|
|
||||||
{
|
|
||||||
subsubgroup: [
|
|
||||||
'subsubb1',
|
|
||||||
'subsubb2',
|
|
||||||
{
|
|
||||||
subsubsubgroup: [ 'bsubsubsub1', 'simplea1' ],
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
draft: part => part,
|
};
|
||||||
}
|
let plugin2 = {
|
||||||
let design, pattern
|
name: "example2",
|
||||||
try {
|
version: 2,
|
||||||
design = new Design({ parts: [ partB ] });
|
hooks: {
|
||||||
pattern = new design().init()
|
preRender: function(svg, attributes) {
|
||||||
} catch(err) {
|
svg.attributes.add("freesewing:plugin-example2", version);
|
||||||
console.log(err)
|
}
|
||||||
}
|
}
|
||||||
const og = pattern.config.optionGroups
|
};
|
||||||
expect(og.simple.length).to.equal(6)
|
|
||||||
expect(og.simple.indexOf('simplea1') === -1).to.equal(false)
|
let design = new Design( { plugins: [plugin1, plugin2] });
|
||||||
expect(og.simple.indexOf('simplea2') === -1).to.equal(false)
|
let pattern = new design();
|
||||||
expect(og.simple.indexOf('simplea3') === -1).to.equal(false)
|
expect(pattern.hooks.preRender.length).to.equal(2);
|
||||||
expect(og.simple.indexOf('simpleb1') === -1).to.equal(false)
|
});
|
||||||
expect(og.simple.indexOf('simpleb2') === -1).to.equal(false)
|
it("Design constructor should load conditional plugin", () => {
|
||||||
expect(og.simple.indexOf('simpleb3') === -1).to.equal(false)
|
const plugin = {
|
||||||
expect(og.nested.nested1.length).to.equal(3)
|
name: "example",
|
||||||
expect(og.nested.nested1.indexOf('nested1a1') === -1).to.equal(false)
|
version: 1,
|
||||||
expect(og.nested.nested1.indexOf('nested1a2') === -1).to.equal(false)
|
hooks: {
|
||||||
expect(og.nested.nested1.indexOf('nested1a3') === -1).to.equal(false)
|
preRender: function(svg, attributes) {
|
||||||
expect(og.nested.nested2.length).to.equal(3)
|
svg.attributes.add("freesewing:plugin-example", version);
|
||||||
expect(og.nested.nested2.indexOf('nested2b1') === -1).to.equal(false)
|
}
|
||||||
expect(og.nested.nested2.indexOf('nested2b2') === -1).to.equal(false)
|
}
|
||||||
expect(og.nested.nested2.indexOf('nested2b3') === -1).to.equal(false)
|
};
|
||||||
expect(og.subnested.subnested1.length).to.equal(8)
|
const condition = () => true
|
||||||
expect(og.subnested.subnested1.indexOf('subnested1a1') === -1).to.equal(false)
|
const design = new Design({ plugins: { plugin, condition } });
|
||||||
expect(og.subnested.subnested1.indexOf('subnested1a2') === -1).to.equal(false)
|
const pattern = new design();
|
||||||
expect(og.subnested.subnested1.indexOf('subnested1a3') === -1).to.equal(false)
|
expect(pattern.hooks.preRender.length).to.equal(1);
|
||||||
expect(og.subnested.subnested1.indexOf('subnested1b1') === -1).to.equal(false)
|
});
|
||||||
expect(og.subnested.subnested1.indexOf('subnested1b2') === -1).to.equal(false)
|
|
||||||
expect(og.subnested.subnested1.indexOf('subnested1b3') === -1).to.equal(false)
|
it("Design constructor should not load conditional plugin", () => {
|
||||||
// FIXME: Some work to be done still with deep-nesting of groups with the same name
|
const plugin = {
|
||||||
})
|
name: "example",
|
||||||
|
version: 1,
|
||||||
|
hooks: {
|
||||||
|
preRender: function(svg, attributes) {
|
||||||
|
svg.attributes.add("freesewing:plugin-example", version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const condition = () => false
|
||||||
|
const design = new Design({ plugins: { plugin, condition } });
|
||||||
|
const pattern = new design();
|
||||||
|
expect(pattern.hooks.preRender.length).to.equal(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Design constructor should load multiple conditional plugins", () => {
|
||||||
|
const plugin = {
|
||||||
|
name: "example",
|
||||||
|
version: 1,
|
||||||
|
hooks: {
|
||||||
|
preRender: function(svg, attributes) {
|
||||||
|
svg.attributes.add("freesewing:plugin-example", version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const condition1 = () => true
|
||||||
|
const condition2 = () => false
|
||||||
|
const design = new Design({ plugins: [
|
||||||
|
{ plugin, condition: condition1 },
|
||||||
|
{ plugin, condition: condition2 },
|
||||||
|
]});
|
||||||
|
const pattern = new design();
|
||||||
|
expect(pattern.hooks.preRender.length).to.equal(1);
|
||||||
|
*/
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue