Skip to content
Merged
3 changes: 2 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const path = require("path");
const config = require("@patternslib/dev/jest.config.js");

config.setupFilesAfterEnv.push(path.resolve(__dirname, "./src/setup-tests.js"));
config.moduleNameMapper["@patternslib/patternslib/(.*)"] = "<rootDir>/$1";
config.moduleNameMapper["@patternslib/patternslib/(.*)"] =
path.resolve(__dirname) + "/$1";

module.exports = config;
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@
"jquery": "^3.6.1",
"jquery-jcrop": "^0.9.13",
"luxon": "2.4.0",
"marked": "^4.1.0",
"marked": "^4.1.1",
"masonry-layout": "^4.2.2",
"moment": "^2.29.4",
"moment-timezone": "^0.5.37",
"moment-timezone": "^0.5.38",
"photoswipe": "^4.1.3",
"pikaday": "^1.8.0",
"prettier": "^2.7.1",
Expand All @@ -43,7 +43,7 @@
"whatwg-fetch": "^3.4.0"
},
"devDependencies": {
"@patternslib/dev": "^2.7.2",
"@patternslib/dev": "^3.0.0",
"@patternslib/pat-content-mirror": "^3.0.0",
"@patternslib/pat-doclock": "^3.0.0",
"@patternslib/pat-shopping-cart": "^3.0.0",
Expand Down
18 changes: 12 additions & 6 deletions src/core/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,18 @@ const show = (el) => {
delete el[DATA_STYLE_DISPLAY];
};

/**
* Test, if a element is visible or not.
*
* @param {Node} el - The DOM node to test.
* @returns {Boolean} - True if the element is visible.
*/
const is_visible = (el) => {
// Check, if element is visible in DOM.
// https://stackoverflow.com/a/19808107/1337474
return el.offsetWidth > 0 && el.offsetHeight > 0;
};

/**
* Return all direct parents of ``el`` matching ``selector``.
* This matches against all parents but not the element itself.
Expand Down Expand Up @@ -169,12 +181,6 @@ const acquire_attribute = (
}
};

const is_visible = (el) => {
// Check, if element is visible in DOM.
// https://stackoverflow.com/a/19808107/1337474
return el.offsetWidth > 0 && el.offsetHeight > 0;
};

/**
* Return a DocumentFragment from a given string.
*
Expand Down
2 changes: 1 addition & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Webpack entry point for module federation.
import "../webpack/module_federation";
import "@patternslib/dev/webpack/module_federation";
// The next import needs to be kept with parentheses, otherwise we get this error:
// "Shared module is not available for eager consumption."
import("./patterns");
Expand Down
2 changes: 0 additions & 2 deletions src/pat/clone-code/clone-code.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ describe("pat-clone-code", () => {
new Pattern(el);
await utils.timeout(1); // wait a tick for async to settle.

console.log(document.body.innerHTML);
const _el = document.body.querySelector(
".pat-clone-code pre code.language-html"
);
Expand Down Expand Up @@ -66,7 +65,6 @@ describe("pat-clone-code", () => {
".pat-clone-code pre code.language-html"
);
expect(_el).toBeTruthy();
console.log(document.body.innerHTML);
expect(_el.textContent.trim()).toBe(`<div>
<div>1</div>

Expand Down
2 changes: 1 addition & 1 deletion src/pat/inject/inject.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ describe("pat-inject", function () {

expect($div.hasClass("injecting")).toBeTruthy();

answer("<html><body>" + '<div id="someid">repl</div>' + "</body></html>");
answer(`<html><body><div id="someid">repl</div></body></html>`);
await utils.timeout(1); // wait a tick for async to settle.
expect($div.hasClass("injecting")).toBeFalsy();
expect(callback).toHaveBeenCalled();
Expand Down
2 changes: 0 additions & 2 deletions src/pat/validation/validation.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1071,7 +1071,6 @@ describe("pat-validation", function () {
await utils.timeout(1); // wait a tick for async to settle.
expect(el.querySelectorAll("em.warning").length).toBe(2);

console.log(document.body.innerHTML);
expect(el.querySelectorAll("em.warning")[0].textContent).toBe(
"The date must be before woo date"
);
Expand Down Expand Up @@ -1113,7 +1112,6 @@ describe("pat-validation", function () {
await utils.timeout(1); // wait a tick for async to settle.
expect(el.querySelectorAll("em.warning").length).toBe(2);

console.log(document.body.innerHTML);
expect(el.querySelectorAll("em.warning")[0].textContent).toBe(
"The date must be before date2"
);
Expand Down
8 changes: 7 additions & 1 deletion src/setup-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
import jquery from "jquery";
global.$ = global.jQuery = jquery;

jquery.expr.pseudos.visible = function () {
// Fix jQuery ":visible" selector always returns false in JSDOM.
// https://github.com/jsdom/jsdom/issues/1048#issuecomment-401599392
return true;
};

// Do not output error messages
import logging from "./core/logging";
logging.setLevel(50);
Expand All @@ -12,5 +18,5 @@ logging.setLevel(50);
// simply on el.hidden.
import dom from "./core/dom";
dom.is_visible = (el) => {
return !el.hidden;
return !el.hidden && el.style.display !== "none";
};
41 changes: 1 addition & 40 deletions webpack/module_federation--dynamic-federation.js
Original file line number Diff line number Diff line change
@@ -1,40 +1 @@
// Author: Manfred Steyer <[email protected]>
// Author: Johannes Raggam <[email protected]>

// From:
// https://github.com/manfredsteyer/plugin-demo.git
// https://github.com/thet/module-federation-minimaltest.git

/**
* Load remote module / bundle.
*
* Wrapper around webpack runtime API
*
* Usage: get_container("bundle-name-xyz")
*
* @param {string} remote - the remote global name
* @returns {Promise<object>} - Federated Module Container
*/
const container_map = {};
let is_default_scope_initialized = false;

export default async function get_container(remote) {
const container = window[remote];

// Do we still need to initialize the remote?
if (container_map[remote]) {
return container;
}

// Do we still need to initialize the shared scope?
if (!is_default_scope_initialized) {
await __webpack_init_sharing__("default"); // eslint-disable-line no-undef
is_default_scope_initialized = true;
}

await container.init(__webpack_share_scopes__.default); // eslint-disable-line no-undef

// Remember that the container has been initialized.
container_map[remote] = true;
return container;
}
export { get_container } from "@patternslib/dev/webpack/module_federation--dynamic-federation";
72 changes: 1 addition & 71 deletions webpack/module_federation--getOrLoadRemote.js
Original file line number Diff line number Diff line change
@@ -1,71 +1 @@
// Author: ScriptedAlchemy <[email protected]>
// Author: Johannes Raggam <[email protected]>

// From:
// https://twitter.com/ScriptedAlchemy/status/1505135006158532612
// https://gist.github.com/ScriptedAlchemy/3a24008ef60adc47fad1af7d3299a063
// https://github.com/module-federation/module-federation-examples/blob/master/dynamic-system-host/app1/src/utils/getOrLoadRemote.js

/**
* Load remote module / bundle.
*
* Usage: get_container("bundle-name-xyz", "default", "http://theRemote.com")
*
*
* @param {string} remote - the remote global name
* @param {string} share_scope - the scope key
* @param {string} remote_fallback_url - fallback url for remote module
* @returns {Promise<object>} - Federated Module Container
*/
export default function get_container(
remote,
share_scope = "default",
remote_fallback_url = undefined
) {
new Promise((resolve, reject) => {
if (!window[remote]) {
// Remote not yet globally available.

// onload hook when Module Federated resource is loaded.
const onload = async () => {
// When remote is loaded, initialize it if it wasn't already.
if (!window[remote].__initialized) {
await window[remote].init(__webpack_share_scopes__[share_scope]); // eslint-disable-line no-undef
// Mark remote as initialized.
window[remote].__initialized = true;
}
// Resolve promise so marking remote as loaded.
resolve(window[remote]);
};

// Search dom to see if the remote exists as script tag.
// It might still be loading (async).
const existing_remote = document.querySelector(`[data-webpack="${remote}"]`);

if (existing_remote) {
// If remote exists but was not loaded, hook into its onload
// and wait for it to be ready.
existing_remote.onload = onload;
existing_remote.onerror = reject;
} else if (remote_fallback_url) {
// Inject remote if a fallback exists and call the same onload
// function
const script = document.createElement("script");
script.type = "text/javascript";
// Mark as data-webpack so runtime can track it internally.
script.setAttribute("data-webpack", `${remote}`);
script.async = true;
script.onerror = reject;
script.onload = onload;
script.src = remote_fallback_url;
document.getElementsByTagName("head")[0].appendChild(script);
} else {
// No remote and no fallback exist, reject.
reject(`Cannot Find Remote ${remote} to inject`);
}
} else {
// Remote already instantiated, resolve
resolve(window[remote]);
}
});
}
export { get_container } from "@patternslib/dev/webpack/module_federation--getOrLoadRemote";
59 changes: 2 additions & 57 deletions webpack/module_federation.js
Original file line number Diff line number Diff line change
@@ -1,57 +1,2 @@
/**
* Initialize dynamic module federation.
*/
import get_container from "./module_federation--dynamic-federation";

// Patternslib Module Federation bundle prefix.
// This is used to filter for module federation enabled bundles.
// NOTE: This is also defined in ``webpack.mf.js``.
export const MF_NAME_PREFIX = "__patternslib_mf__";

if (typeof window.__patternslib_container_map === "undefined") {
window.__patternslib_container_map = {};
}
const container_map = window.__patternslib_container_map;

export async function initialize_remote({ remote_name, exposed_module = "./main" }) {
if (container_map[`${remote_name}-${exposed_module}`]) {
// already initialized, return.
return;
}
const container = await get_container(remote_name);
const factory = await container.get(exposed_module);
const module = factory();

container_map[`${remote_name}-${exposed_module}`] = true;

console.debug(
`Patternslib Module Federation: Loaded and initialized bundle "${remote_name}".`
);

return module;
}

function document_ready(fn) {
// see if DOM is already available
if (document.readyState === "complete" || document.readyState === "interactive") {
// call on next available tick
setTimeout(fn, 1);
} else {
document.addEventListener("DOMContentLoaded", fn);
}
}

document_ready(function () {
// Automatically initialize all Module Federation enabled Patternslib based
// bundles by filtering for the prefix ``__patternslib_mf__``.
// Do this on document ready, as this is the time where all MF bundles have
// been registered in the global namespace.
const bundles = Object.keys(window).filter((it) => it.indexOf(MF_NAME_PREFIX) === 0);
for (const bundle_name of bundles) {
// Now load + initialize each bundle.
initialize_remote({ remote_name: bundle_name });
}
document.dispatchEvent(
new Event("patternslib__mf--loaded", { bubbles: true, cancelable: false })
);
});
export { MF_NAME_PREFIX } from "@patternslib/dev/webpack/module_federation";
export { initialize_remote } from "@patternslib/dev/webpack/module_federation";
Loading