Demos and documentation for the individual patterns
diff --git a/src/core/base.js b/src/core/base.js
index b118ce487..285a6107e 100644
--- a/src/core/base.js
+++ b/src/core/base.js
@@ -46,6 +46,10 @@ const initBasePattern = function ($el, options, trigger) {
};
const Base = async function ($el, options, trigger) {
+ if (!$el) {
+ log.warn("No element given to pattern.");
+ return;
+ }
if (!$el.jquery) {
$el = $($el);
}
diff --git a/src/core/base.test.js b/src/core/base.test.js
index d1bfb2770..79ad83e88 100644
--- a/src/core/base.test.js
+++ b/src/core/base.test.js
@@ -58,6 +58,18 @@ describe("pat-base: The Base class for patterns", function () {
expect(tmp.el).toBe(node);
});
+ it("Does nothing when initialized with no DOM node", function () {
+ const Tmp = Base.extend({
+ name: "example",
+ init: () => {},
+ });
+ const tmp = new Tmp(null);
+ console.log(tmp);
+ expect(tmp instanceof Tmp).toBeTruthy();
+ expect(tmp.$el).toBeFalsy();
+ expect(tmp.el).toBeFalsy();
+ });
+
it("will automatically register a pattern in the registry when extended", function () {
jest.spyOn(registry, "register");
var NewPattern = Base.extend({
diff --git a/src/core/dom.js b/src/core/dom.js
index 1cd739706..ccb8ade37 100644
--- a/src/core/dom.js
+++ b/src/core/dom.js
@@ -4,8 +4,14 @@ import events from "./events";
const DATA_PREFIX = "__patternslib__data_prefix__";
const DATA_STYLE_DISPLAY = "__patternslib__style__display";
+/**
+ * Return an array of DOM nodes.
+ *
+ * @param {Node|NodeList|jQuery} nodes - The DOM node to start the search from.
+ *
+ * @returns {Array} - An array of DOM nodes.
+ */
const toNodeArray = (nodes) => {
- // Return an array of DOM nodes
if (nodes.jquery || nodes instanceof NodeList) {
// jQuery or document.querySelectorAll
nodes = [...nodes];
@@ -15,10 +21,15 @@ const toNodeArray = (nodes) => {
return nodes;
};
+/**
+ * Like querySelectorAll but including the element where it starts from.
+ * Returns an Array, not a NodeList
+ *
+ * @param {Node} el - The DOM node to start the search from.
+ *
+ * @returns {Array} - The DOM nodes found.
+ */
const querySelectorAllAndMe = (el, selector) => {
- // Like querySelectorAll but including the element where it starts from.
- // Returns an Array, not a NodeList
-
if (!el) {
return [];
}
@@ -30,16 +41,23 @@ const querySelectorAllAndMe = (el, selector) => {
return all;
};
+/**
+ * Wrap a element with a wrapper element.
+ *
+ * @param {Node} el - The DOM node to wrap.
+ */
const wrap = (el, wrapper) => {
- // Wrap a element with a wrapper element.
// See: https://stackoverflow.com/a/13169465/1337474
-
el.parentNode.insertBefore(wrapper, el);
wrapper.appendChild(el);
};
+/**
+ * Hides the element with ``display: none`` and stores the current display value.
+ *
+ * @param {Node} el - The DOM node to hide.
+ */
const hide = (el) => {
- // Hides the element with ``display: none``
if (el.style.display === "none") {
// Nothing to do.
return;
@@ -51,38 +69,65 @@ const hide = (el) => {
el.setAttribute("hidden", "");
};
+/**
+ * Shows element by removing ``display: none`` and restoring the display value
+ * to whatever it was before.
+ *
+ * @param {Node} el - The DOM node to show.
+ */
const show = (el) => {
- // Shows element by removing ``display: none`` and restoring the display
- // value to whatever it was before.
const val = el[DATA_STYLE_DISPLAY] || null;
el.style.display = val;
delete el[DATA_STYLE_DISPLAY];
el.removeAttribute("hidden", "");
};
+/**
+ * Return all direct parents of ``el`` matching ``selector``.
+ * This matches against all parents but not the element itself.
+ * The order of elements is from the search starting point up to higher
+ * DOM levels.
+ *
+ * @param {Node} el - The DOM node to start the search from.
+ * @param {String} selector - CSS selector to match against.
+ * @returns {Array} - List of matching DOM nodes.
+ */
const find_parents = (el, selector) => {
- // Return all direct parents of ``el`` matching ``selector``.
- // This matches against all parents but not the element itself.
- // The order of elements is from the search starting point up to higher
- // DOM levels.
const ret = [];
- let parent = el?.parentNode?.closest?.(selector);
+ let parent = el;
while (parent) {
- ret.push(parent);
parent = parent.parentNode?.closest?.(selector);
+ if (parent) ret.push(parent);
}
return ret;
};
+/**
+ * Find an element in the whole DOM tree if the selector is an ID selector,
+ * otherwise use the given element as the starting point.
+ *
+ * @param {Node} el - The DOM node to start the search from.
+ * @param {String} selector - The CSS selector to search for.
+ *
+ * @returns {NodeList} - The DOM nodes found.
+ *
+ */
const find_scoped = (el, selector) => {
// If the selector starts with an object id do a global search,
// otherwise do a local search.
return (selector.indexOf("#") === 0 ? document : el).querySelectorAll(selector);
};
+/**
+ * Return all HTMLElement parents of el, starting from the direct parent of el.
+ * The document itself is excluded because it's not a real DOM node.
+ *
+ * @param {Node} el - The DOM node to start the search from.
+ *
+ * @returns {Array} - The DOM nodes found.
+ */
const get_parents = (el) => {
// Return all HTMLElement parents of el, starting from the direct parent of el.
- // The document itself is excluded because it's not a real DOM node.
const parents = [];
let parent = el?.parentNode;
while (parent) {
@@ -211,7 +256,7 @@ const find_scroll_container = (el, direction, fallback = document.body) => {
* @param name {String} - The name of the variable. Note - this is stored on
* the DOM node prefixed with the DATA_PREFIX.
* @param default_value {Any} - Optional default value.
- * @return {Any} - The value which is stored on the DOM node.
+ * @returns {Any} - The value which is stored on the DOM node.
*/
const get_data = (el, name, default_value) => {
return el[`${DATA_PREFIX}${name}`] || default_value;
diff --git a/src/core/dom.test.js b/src/core/dom.test.js
index 96f47442c..6595b8cfd 100644
--- a/src/core/dom.test.js
+++ b/src/core/dom.test.js
@@ -177,12 +177,14 @@ describe("core.dom tests", () => {
done();
});
+
it("don't break with no element.", (done) => {
const res = dom.find_parents(null, ".findme");
expect(res.length).toEqual(0);
done();
});
+
it("don't break with DocumentFragment without a parent.", (done) => {
const el = new DocumentFragment();
el.innerHTML = ``;
diff --git a/src/core/utils.js b/src/core/utils.js
index 2c93bc832..b96b20728 100644
--- a/src/core/utils.js
+++ b/src/core/utils.js
@@ -156,14 +156,6 @@ function extend(obj) {
}
// END: Taken from Underscore.js until here.
-function rebaseURL(base, url) {
- base = new URL(base, window.location).href; // If base is relative make it absolute.
- if (url.indexOf("://") !== -1 || url[0] === "/" || url.indexOf("data:") === 0) {
- return url;
- }
- return base.slice(0, base.lastIndexOf("/") + 1) + url;
-}
-
function findLabel(input) {
var $label;
for (
@@ -683,7 +675,6 @@ var utils = {
escapeRegExp: escapeRegExp,
isObject: isObject,
extend: extend,
- rebaseURL: rebaseURL,
findLabel: findLabel,
elementInViewport: elementInViewport,
removeWildcardClass: removeWildcardClass,
diff --git a/src/core/utils.test.js b/src/core/utils.test.js
index 6ff61683b..c0d0cdb64 100644
--- a/src/core/utils.test.js
+++ b/src/core/utils.test.js
@@ -3,50 +3,6 @@ import $ from "jquery";
import { jest } from "@jest/globals";
describe("basic tests", function () {
- describe("rebaseURL", function () {
- it("Keep URL with scheme", function () {
- expect(
- utils.rebaseURL("http://example.com/foo/", "http://other.com/me")
- ).toBe("http://other.com/me");
- });
-
- it("Keep URL with absolute path", function () {
- expect(utils.rebaseURL("http://example.com/foo/", "/me")).toBe("/me");
- });
-
- it("Rebase to base with filename", function () {
- expect(
- utils.rebaseURL("http://example.com/foo/index.html", "me/page.html")
- ).toBe("http://example.com/foo/me/page.html");
- });
-
- it("Rebase to base with directory path", function () {
- expect(utils.rebaseURL("http://example.com/foo/", "me/page.html")).toBe(
- "http://example.com/foo/me/page.html"
- );
- });
-
- it("Rebase with absolute base url", function () {
- expect(
- utils.rebaseURL("/foo/", "me/page.html").indexOf("/foo/me/page.html") > 0
- ).toBe(true);
- });
-
- it("Rebase with relative base url", function () {
- expect(
- utils
- .rebaseURL("example.com/foo/", "me/page.html")
- .indexOf("example.com/foo/me/page.html") > 0
- ).toBe(true);
- });
-
- it("Doesn't rebase data: urls", function () {
- expect(
- utils.rebaseURL("http://example.com/foo/", "data:image-base64gibberish")
- ).toBe("data:image-base64gibberish");
- });
- });
-
describe("removeDuplicateObjects", function () {
it("removes removes duplicates inside an array of objects", function () {
var objs = [];
diff --git a/src/pat/auto-scale/index.html b/src/pat/auto-scale/index.html
index 19abaa51d..4d5b172cc 100644
--- a/src/pat/auto-scale/index.html
+++ b/src/pat/auto-scale/index.html
@@ -1,14 +1,10 @@
-
Auto scale
-
-
+
+
+
@@ -82,8 +78,7 @@
>
open in fullscreen
-
-