Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/pat/contentbrowser/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ Note: the `name` of the registered component must match the `componentRegistryKe
It can be any unique identifier.
If no custom component is registered for the configured key, the pattern falls back to the default component registered as `pat-contentbrowser.SelectedItem`.

To replace the component site-wide without any pattern configuration, register your component under the default key `pat-contentbrowser.SelectedItem` instead.
The pattern only registers its own default component if nothing is registered under that key yet, so an add-on registration is kept no matter whether the add-on bundle initializes before or after the pattern.

```javascript
...
import plone_registry from "@plone/registry";
Expand Down
23 changes: 16 additions & 7 deletions src/pat/contentbrowser/contentbrowser.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,25 @@ class Pattern extends BasePattern {
static trigger = ".pat-contentbrowser";
static parser = parser;

static async register_default_components() {
// Register the default components in @plone/registry — but only if
// nothing is registered under that key yet. This lets add-ons
// replace a component site-wide by registering their own under the
// default key, regardless of whether their bundle initializes before
// or after this pattern (registerComponent overwrites silently).
if (!plone_registry.getComponent("pat-contentbrowser.SelectedItem").component) {
const SelectedItem = (await import("./src/SelectedItem.svelte")).default;
plone_registry.registerComponent({
name: "pat-contentbrowser.SelectedItem",
component: SelectedItem,
});
}
}

async init() {
this.el.style.display = "none";

// register default components in @plone/registry
const SelectedItem = (await import("./src/SelectedItem.svelte")).default;

plone_registry.registerComponent({
name: "pat-contentbrowser.SelectedItem",
component: SelectedItem,
});
await Pattern.register_default_components();

// ensure an id on our element (TinyMCE doesn't have one)
let nodeId = this.el.getAttribute("id");
Expand Down
48 changes: 47 additions & 1 deletion src/pat/contentbrowser/contentbrowser.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
import "./contentbrowser";
import Pattern from "./contentbrowser";
import plone_registry from "@plone/registry";
import registry from "@patternslib/patternslib/src/core/registry";
import utils from "@patternslib/patternslib/src/core/utils";

const DEFAULT_KEY = "pat-contentbrowser.SelectedItem";

// The jest setup cannot compile Svelte components, so stand in for the
// default component with a plain function.
const mockDefaultSelectedItem = () => "default SelectedItem";
jest.mock("./src/SelectedItem.svelte", () => ({
__esModule: true,
default: mockDefaultSelectedItem,
}));


describe("Content Browser", () => {
beforeEach(() => {
Expand Down Expand Up @@ -29,3 +40,38 @@ describe("Content Browser", () => {
});

});

describe("Content Browser default components", () => {
afterEach(() => {
delete plone_registry.components[DEFAULT_KEY];
});

it("registers the default SelectedItem component", async function () {
expect(plone_registry.getComponent(DEFAULT_KEY).component).toBeUndefined();

await Pattern.register_default_components();

expect(plone_registry.getComponent(DEFAULT_KEY).component).toBe(
mockDefaultSelectedItem,
);
});

it("keeps a component an add-on registered under the default key", async function () {
const custom = () => "custom SelectedItem";
plone_registry.registerComponent({ name: DEFAULT_KEY, component: custom });

await Pattern.register_default_components();

expect(plone_registry.getComponent(DEFAULT_KEY).component).toBe(custom);
});

it("does not overwrite the add-on component on repeated initialization", async function () {
const custom = () => "custom SelectedItem";
plone_registry.registerComponent({ name: DEFAULT_KEY, component: custom });

await Pattern.register_default_components();
await Pattern.register_default_components();

expect(plone_registry.getComponent(DEFAULT_KEY).component).toBe(custom);
});
});
Loading