diff --git a/docs/customization/plugin-api.md b/docs/customization/plugin-api.md
index defba722..e5d1846c 100644
--- a/docs/customization/plugin-api.md
+++ b/docs/customization/plugin-api.md
@@ -388,6 +388,10 @@ const MyWrapComponentPlugin = function(system) {
}
```
+**Note:**
+
+If you have multiple plugins wrapping the same component, you may want to change the [`pluginsOptions.pluginLoadType`](/docs/usage/configuration.md#Plugins-options) parameter to `chain`.
+
#### `rootInjects`
The `rootInjects` interface allows you to inject values at the top level of the system.
diff --git a/docs/usage/configuration.md b/docs/usage/configuration.md
index 39ee5cd2..17faa008 100644
--- a/docs/usage/configuration.md
+++ b/docs/usage/configuration.md
@@ -39,9 +39,16 @@ Read more about the plugin system in the [Customization documentation](/docs/cus
Parameter name | Docker variable | Description
--- | --- | -----
`layout` | _Unavailable_ | `String="BaseLayout"`. The name of a component available via the plugin system to use as the top-level layout for Swagger UI.
+`pluginsOptions` | _Unavailable_ | `Object`. A Javascript object to configure plugin integration and behaviors (see below).
`plugins` | _Unavailable_ | `Array=[]`. An array of plugin functions to use in Swagger UI.
`presets` | _Unavailable_ | `Array=[SwaggerUI.presets.ApisPreset]`. An array of presets to use in Swagger UI. Usually, you'll want to include `ApisPreset` if you use this option.
+##### Plugins options
+
+Parameter name | Docker variable | Description
+--- | --- | -----
+`pluginLoadType` | _Unavailable_ | `String=["legacy", "chain"]`. Control behavior of plugins when targeting the same component with wrapComponent.
- `legacy` (default) : last plugin takes precedence over the others
- `chain` : chain wrapComponents when targeting the same core component, allowing multiple plugins to wrap the same component
+
##### Display
Parameter name | Docker variable | Description
diff --git a/src/core/index.js b/src/core/index.js
index 000b1d3c..e5f68527 100644
--- a/src/core/index.js
+++ b/src/core/index.js
@@ -93,6 +93,13 @@ export default function SwaggerUI(opts) {
plugins: [
],
+ pluginsOptions: {
+ // Behavior during plugin registration. Can be :
+ // - legacy (default) : the current behavior for backward compatibility – last plugin takes precedence over the others
+ // - chain : chain wrapComponents when targeting the same core component
+ pluginLoadType: "legacy"
+ },
+
// Initial state
initialState: { },
@@ -118,6 +125,7 @@ export default function SwaggerUI(opts) {
configs: constructorConfig.configs
},
plugins: constructorConfig.presets,
+ pluginsOptions: constructorConfig.pluginsOptions,
state: deepExtend({
layout: {
layout: constructorConfig.layout,
diff --git a/src/core/system.js b/src/core/system.js
index 30a41ddf..a756039c 100644
--- a/src/core/system.js
+++ b/src/core/system.js
@@ -35,6 +35,7 @@ export default class Store {
deepExtend(this, {
state: {},
plugins: [],
+ pluginsOptions: {},
system: {
configs: {},
fn: {},
@@ -63,7 +64,7 @@ export default class Store {
}
register(plugins, rebuild=true) {
- var pluginSystem = combinePlugins(plugins, this.getSystem())
+ var pluginSystem = combinePlugins(plugins, this.getSystem(), this.pluginsOptions)
systemExtend(this.system, pluginSystem)
if(rebuild) {
this.buildSystem()
@@ -310,19 +311,21 @@ export default class Store {
}
-function combinePlugins(plugins, toolbox) {
+function combinePlugins(plugins, toolbox, pluginOptions) {
if(isObject(plugins) && !isArray(plugins)) {
return assignDeep({}, plugins)
}
if(isFunc(plugins)) {
- return combinePlugins(plugins(toolbox), toolbox)
+ return combinePlugins(plugins(toolbox), toolbox, pluginOptions)
}
if(isArray(plugins)) {
+ const dest = pluginOptions.pluginLoadType === "chain" ? toolbox.getComponents() : {}
+
return plugins
- .map(plugin => combinePlugins(plugin, toolbox))
- .reduce(systemExtend, {})
+ .map(plugin => combinePlugins(plugin, toolbox, pluginOptions))
+ .reduce(systemExtend, dest)
}
return {}
diff --git a/test/unit/core/system/wrapComponent.jsx b/test/unit/core/system/wrapComponent.jsx
index 0605b0d5..594167ce 100644
--- a/test/unit/core/system/wrapComponent.jsx
+++ b/test/unit/core/system/wrapComponent.jsx
@@ -5,7 +5,7 @@ import System from "core/system"
describe("wrapComponents", () => {
describe("should wrap a component and provide a reference to the original", () => {
- it("with stateless components", function(){
+ it("with stateless components", function () {
// Given
const system = new System({
plugins: [
@@ -40,7 +40,7 @@ describe("wrapComponents", () => {
expect(children.eq(1).text()).toEqual("Wrapped component")
})
- it("with React classes", function(){
+ it("with React classes", function () {
class MyComponent extends React.Component {
render() {
return