diff --git a/src/core/jquery-ext.js b/src/core/jquery-ext.js
index b7a46a211..367aeab35 100644
--- a/src/core/jquery-ext.js
+++ b/src/core/jquery-ext.js
@@ -12,7 +12,8 @@ var methods = {
var settings = {
time: 3 /* time it will wait before moving to "timeout" after a move event */,
initialTime: 8 /* time it will wait before first adding the "timeout" class */,
- exceptionAreas: [] /* IDs of elements that, if the mouse is over them, will reset the timer */,
+ exceptionAreas:
+ [] /* IDs of elements that, if the mouse is over them, will reset the timer */,
};
return this.each(function () {
var $this = $(this),
@@ -156,43 +157,6 @@ $.extend($.expr[":"], {
},
});
-// Make Visible in scroll
-$.fn.makeVisibleInScroll = function (parent_id) {
- var absoluteParent = null;
- if (typeof parent_id === "string") {
- absoluteParent = $("#" + parent_id);
- } else if (parent_id) {
- absoluteParent = $(parent_id);
- }
-
- return this.each(function () {
- var $this = $(this),
- parent;
- if (!absoluteParent) {
- parent = $this.parents(":scrollable");
- if (parent.length > 0) {
- parent = $(parent[0]);
- } else {
- parent = $(window);
- }
- } else {
- parent = absoluteParent;
- }
-
- var elemTop = $this.position().top;
- var elemBottom = $this.height() + elemTop;
-
- var viewTop = parent.scrollTop();
- var viewBottom = parent.height() + viewTop;
-
- if (elemTop < viewTop) {
- parent.scrollTop(elemTop);
- } else if (elemBottom > viewBottom - parent.height() / 2) {
- parent.scrollTop(elemTop - (parent.height() - $this.height()) / 2);
- }
- });
-};
-
//Work around warning for jQuery 3.x:
//JQMIGRATE: jQuery.fn.offset() requires an element connected to a document
$.fn.safeOffset = function () {
@@ -212,67 +176,6 @@ $.fn.safeOffset = function () {
return $.fn.offset.apply(this, arguments);
};
-//Make absolute location
-$.fn.setPositionAbsolute = function (element, offsettop, offsetleft) {
- return this.each(function () {
- // set absolute location for based on the element passed
- // dynamically since every browser has different settings
- var $this = $(this);
- var thiswidth = $(this).width();
- var pos = element.safeOffset();
- var width = element.width();
- var height = element.height();
- var setleft = pos.left + width - thiswidth + offsetleft;
- var settop = pos.top + height + offsettop;
- $this.css({
- "z-index": 1,
- "position": "absolute",
- "marginLeft": 0,
- "marginTop": 0,
- "left": setleft + "px",
- "top": settop + "px",
- "width": thiswidth,
- });
- $this.remove().appendTo("body").show();
- });
-};
-
-$.fn.positionAncestor = function (selector) {
- var left = 0;
- var top = 0;
- this.each(function () {
- // check if current element has an ancestor matching a selector
- // and that ancestor is positioned
- var $ancestor = $(this).closest(selector);
- if ($ancestor.length && $ancestor.css("position") !== "static") {
- var $child = $(this);
- var childMarginEdgeLeft =
- $child.safeOffset().left - parseInt($child.css("marginLeft"), 10);
- var childMarginEdgeTop =
- $child.safeOffset().top - parseInt($child.css("marginTop"), 10);
- var ancestorPaddingEdgeLeft =
- $ancestor.safeOffset().left +
- parseInt($ancestor.css("borderLeftWidth"), 10);
- var ancestorPaddingEdgeTop =
- $ancestor.safeOffset().top +
- parseInt($ancestor.css("borderTopWidth"), 10);
- left = childMarginEdgeLeft - ancestorPaddingEdgeLeft;
- top = childMarginEdgeTop - ancestorPaddingEdgeTop;
- // we have found the ancestor and computed the position
- // stop iterating
- return false;
- }
- });
- return {
- left: left,
- top: top,
- };
-};
-
-$.fn.findInclusive = function (selector) {
- return this.find("*").addBack().filter(selector);
-};
-
$.fn.slideIn = function (speed, easing, callback) {
return this.animate({ width: "show" }, speed, easing, callback);
};
@@ -281,20 +184,4 @@ $.fn.slideOut = function (speed, easing, callback) {
return this.animate({ width: "hide" }, speed, easing, callback);
};
-// case-insensitive :contains
-$.expr[":"].Contains = function (a, i, m) {
- return $(a).text().toUpperCase().indexOf(m[3].toUpperCase()) >= 0;
-};
-
-$.fn.scopedFind = function (selector) {
- /* If the selector starts with an object id do a global search,
- * otherwise do a local search.
- */
- if (selector.indexOf("#") === 0) {
- return $(selector);
- } else {
- return this.find(selector);
- }
-};
-
export default undefined;
diff --git a/src/core/jquery-ext.test.js b/src/core/jquery-ext.test.js
deleted file mode 100644
index 73e298d07..000000000
--- a/src/core/jquery-ext.test.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import "./jquery-ext";
-import $ from "jquery";
-
-describe("Find including top-level elements", function () {
- it("Top-level elements are included", function () {
- var $col = $(
- "
" +
- "" +
- ""
- ),
- $match = $col.findInclusive("div p");
- expect($match.length).toBe(1);
- });
-});
diff --git a/src/core/registry.js b/src/core/registry.js
index 4418ca93a..c666adfee 100644
--- a/src/core/registry.js
+++ b/src/core/registry.js
@@ -20,6 +20,7 @@ import $ from "jquery";
import dom from "./dom";
import logging from "./logging";
import utils from "./utils";
+import "./remove";
const log = logging.getLogger("registry");
const disable_re = /patterns-disable=([^&]+)/g;
diff --git a/src/core/url.js b/src/core/url.js
deleted file mode 100644
index 601231d4f..000000000
--- a/src/core/url.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * Patterns URL - URL parsing utilities
- *
- * Copyright 2013 Simplon B.V.
- */
-
-function UrlArgumentParser() {
- this._cache = null;
- if (window.addEventListener) window.addEventListener("popstate", this._reset);
-}
-
-UrlArgumentParser.prototype = {
- space_pattern: /\+/g,
- keyvalue_pattern: /^(.+?)(?:=(.*))/,
-
- _reset: function UrlArgumentParser_reset() {
- this._cache = null;
- },
-
- _decodeQS: function UrlArgumentParser_decodeQS(bit) {
- return decodeURIComponent(bit.replace(this.space_pattern, " "));
- },
-
- _parse: function UrlArgumentParser_parse(qs) {
- var query = /\?(.+)/.exec(qs),
- params = {};
-
- if (query === null) return params;
-
- var parameters = query[1].split("&"),
- i,
- parts,
- key,
- value;
-
- for (i = 0; i < parameters.length; i++) {
- if ((parts = this.keyvalue_pattern.exec(parameters[i])) === null) {
- key = this._decodeQS(parameters[i]);
- value = null;
- } else {
- key = this._decodeQS(parts[1]);
- value = this._decodeQS(parts[2]);
- }
-
- if (params[key] === undefined) params[key] = [];
- params[key].push(value);
- }
-
- return params;
- },
-
- get: function UrlArgumentParser_get() {
- if (this._cache === null) this._cache = this._parse(window.location.search);
- return this._cache;
- },
-};
-
-var url_parser = new UrlArgumentParser();
-
-export default {
- UrlArgumentParser: UrlArgumentParser,
- parameters: url_parser.get.bind(url_parser),
-};
diff --git a/src/core/url.test.js b/src/core/url.test.js
deleted file mode 100644
index 1f99fc728..000000000
--- a/src/core/url.test.js
+++ /dev/null
@@ -1,68 +0,0 @@
-import url from "./url";
-
-describe("Core / url / UrlArgumentParser", function () {
- describe("_decodeQS", function () {
- it("Basic string", function () {
- var parser = new url.UrlArgumentParser();
- expect(parser._decodeQS("Foo")).toBe("Foo");
- });
-
- it("String with whitespace", function () {
- var parser = new url.UrlArgumentParser();
- expect(parser._decodeQS("Aap+Noot+Mies")).toBe("Aap Noot Mies");
- });
-
- it("String with encoded characters", function () {
- var parser = new url.UrlArgumentParser();
- expect(parser._decodeQS("Jip%26Janneke")).toBe("Jip&Janneke");
- });
- });
-
- describe("_parse", function () {
- it("No query string", function () {
- var parser = new url.UrlArgumentParser();
- expect(parser._parse("")).toEqual({});
- });
-
- it("No parameter specified", function () {
- var parser = new url.UrlArgumentParser();
- expect(parser._parse("?")).toEqual({});
- });
-
- it("Parameter without value", function () {
- var parser = new url.UrlArgumentParser();
- expect(parser._parse("?key")).toEqual({ key: [null] });
- });
-
- it("Parameter with empty value", function () {
- var parser = new url.UrlArgumentParser();
- expect(parser._parse("?key=")).toEqual({ key: [""] });
- });
-
- it("Parameter with plain value", function () {
- var parser = new url.UrlArgumentParser();
- expect(parser._parse("?key=value")).toEqual({ key: ["value"] });
- });
-
- it("Multiple parameters", function () {
- var parser = new url.UrlArgumentParser();
- expect(parser._parse("?one=en&two=to")).toEqual({
- one: ["en"],
- two: ["to"],
- });
- });
-
- it("Parameter with multiple values", function () {
- var parser = new url.UrlArgumentParser();
- expect(parser._parse("?key=value&key=other")).toEqual({
- key: ["value", "other"],
- });
- });
- });
-});
-
-describe("Core / url / parameters", function () {
- it("Bound to working parser", function () {
- expect(url.parameters()).not.toBe(undefined);
- });
-});
diff --git a/src/pat/slides/slides.js b/src/pat/slides/slides.js
index ece5cc7f6..bf5e1ba4d 100644
--- a/src/pat/slides/slides.js
+++ b/src/pat/slides/slides.js
@@ -1,48 +1,37 @@
/**
* Patterns slides - Automatic and customised slideshows.
- *
- * Copyright 2013 Simplon B.V. - Wichert Akkerman
*/
import $ from "jquery";
-import registry from "../../core/registry";
+import Base from "../../core/base";
import utils from "../../core/utils";
-import url from "../../core/url";
-import "../../core/remove";
-var slides = {
+export default Base.extend({
name: "slides",
trigger: ".pat-slides",
- setup: function () {
- $(document).on("patterns-injected", utils.debounce(slides._reset, 100));
- },
-
- async init($el) {
- if (!this.el.querySelector(".slide")) {
- // no slides, nothing to do.
- return;
- }
+ async init() {
await import("slides/src/slides"); // loads ``Presentation`` globally.
- var parameters = url.parameters();
- if (parameters.slides !== undefined) {
- var requested_ids = slides._collapse_ids(parameters.slides);
- if (requested_ids) slides._remove_slides($el, requested_ids);
+ const slides_filter = new URL(window.location).searchParams.get("slides");
+ if (slides_filter) {
+ const requested_ids = this._collapse_ids(slides_filter);
+ if (requested_ids) {
+ this._remove_slides(requested_ids);
+ }
}
- $el.each(function () {
- var presentation = new window.Presentation(this),
- $container = $(this);
- $container
- .data("pat-slide", presentation)
- .on("SlideDisplay", slides._onSlideDisplay)
- .on("SlideHide", slides._onSlideHide);
- });
- return slides._hook($el);
+ this.presentation = new window.Presentation(this.el);
+ this.$el
+ .on("SlideDisplay", this._on_slide_display.bind(this))
+ .on("SlideHide", this._on_slide_hide.bind(this));
+
+ $(document).on("patterns-injected", utils.debounce(this._reset.bind(this), 100));
+
+ this._hook();
},
- _onSlideDisplay: function (event) {
- var slide = event.originalEvent.detail.slide.element,
- $videos = $("video", slide);
+ _on_slide_display(event) {
+ const slide = event.originalEvent.detail.slide.element;
+ const $videos = $("video", slide);
$videos.each(function () {
if (this.paused) {
@@ -52,54 +41,40 @@ var slides = {
});
},
- _onSlideHide: function (event) {
- var slide = event.originalEvent.detail.slide.element,
- $videos = $("video", slide);
+ _on_slide_hide(event) {
+ const slide = event.originalEvent.detail.slide.element;
+ const $videos = $("video", slide);
$videos.each(function () {
- if (!this.paused) this.pause();
+ if (!this.paused) {
+ this.pause();
+ }
});
},
- _collapse_ids: function (params) {
- var ids = [];
- params.forEach(function (param) {
- if (param)
- ids = ids.concat(
- param.split(",").filter(function (id) {
- return !!id;
- })
- );
- });
- return ids;
+ _collapse_ids(id_string) {
+ return (id_string || "").split(",").filter((it) => !!it);
},
- _remove_slides: function ($shows, ids) {
- var has_bad_id = function (idx, el) {
- return ids.indexOf(el.id) === -1;
- };
-
- for (var i = 0; i < $shows.length; i++) {
- var $show = $shows.eq(i),
- $bad_slides = $show.find(".slide[id]").filter(has_bad_id);
- $bad_slides.remove();
+ _remove_slides(keep_ids) {
+ for (const slide of this.el.querySelectorAll(".slide[id]")) {
+ if (keep_ids.indexOf(slide.id) !== -1) {
+ // Not an id to remove
+ continue;
+ }
+ console.log("remove slide", slide);
+ slide.remove();
}
},
- _hook: function ($el) {
- return $el
+ _hook() {
+ this.$el
.off("destroy.pat-slide")
- .on("destroy.pat-slide", utils.debounce(slides._reset, 100));
+ .on("destroy.pat-slide", utils.debounce(this._reset.bind(this), 100));
},
- _reset: function () {
- var $container = $(this).closest(".pat-slides"),
- presentation = $container.data("pat-slide");
- if (presentation) presentation.scan();
- slides._hook($(this.trigger));
+ _reset() {
+ this.presentation.scan();
+ this._hook();
},
-};
-
-slides.setup();
-registry.register(slides);
-export default slides;
+});
diff --git a/src/pat/slides/slides.test.js b/src/pat/slides/slides.test.js
index c9c6940c1..d160f4fe0 100644
--- a/src/pat/slides/slides.test.js
+++ b/src/pat/slides/slides.test.js
@@ -1,4 +1,4 @@
-import pattern from "./slides";
+import Pattern from "./slides";
import $ from "jquery";
import utils from "../../core/utils";
import { jest } from "@jest/globals";
@@ -8,39 +8,44 @@ describe("pat-slides", function () {
jest.restoreAllMocks();
});
- describe("_collapse_ids", function () {
+ describe("1 - _collapse_ids", function () {
it("Single id", function () {
- expect(pattern._collapse_ids(["foo"])).toEqual(["foo"]);
+ const instance = new Pattern(document.createElement("div"));
+ expect(instance._collapse_ids("foo")).toEqual(["foo"]);
});
it("Comma-separated list of ids", function () {
- expect(pattern._collapse_ids(["foo,bar"])).toEqual(["foo", "bar"]);
+ const instance = new Pattern(document.createElement("div"));
+ expect(instance._collapse_ids("foo,bar")).toEqual(["foo", "bar"]);
});
it("Skip empty ids", function () {
- expect(pattern._collapse_ids(["foo,,bar"])).toEqual(["foo", "bar"]);
+ const instance = new Pattern(document.createElement("div"));
+ expect(instance._collapse_ids("foo,,bar")).toEqual(["foo", "bar"]);
});
it("Parameter without value", function () {
- expect(pattern._collapse_ids([null])).toEqual([]);
+ const instance = new Pattern(document.createElement("div"));
+ expect(instance._collapse_ids(null)).toEqual([]);
});
it("Parameter with empty value", function () {
- expect(pattern._collapse_ids([""])).toEqual([]);
- });
-
- it("Multiple parameters", function () {
- expect(pattern._collapse_ids(["foo", "bar"])).toEqual(["foo", "bar"]);
+ const instance = new Pattern(document.createElement("div"));
+ expect(instance._collapse_ids("")).toEqual([]);
});
});
- describe("_remove_slides", function () {
- it("Remove slides from DOM", function () {
- var $show = $("", { class: "pat-slides" });
- for (var i = 1; i <= 4; i++)
+ describe("2 - _remove_slides", function () {
+ it("Remove slides from DOM", async function () {
+ const $show = $("", { class: "pat-slides" });
+ for (let i = 1; i <= 4; i++)
$("", { class: "slide", id: "slide" + i }).appendTo($show);
- pattern._remove_slides($show, ["slide1", "slide3"]);
- var ids = $.makeArray(
+
+ const instance = new Pattern($show);
+ await utils.timeout(1); // wait a tick for async to settle.
+
+ instance._remove_slides(["slide1", "slide3"]);
+ const ids = $.makeArray(
$show.find(".slide").map(function (idx, el) {
return el.id;
})
@@ -48,26 +53,34 @@ describe("pat-slides", function () {
expect(ids).toEqual(["slide1", "slide3"]);
});
- it.skip("Trigger reset when removing slides", function () {
- var $show = $("", { class: "pat-slides" });
- for (var i = 1; i <= 4; i++) {
+ it.skip("Trigger reset when removing slides", async function () {
+ const $show = $("", { class: "pat-slides" });
+ for (let i = 1; i <= 4; i++) {
$("", { class: "slide", id: "slide" + i }).appendTo($show);
}
jest.spyOn(utils, "debounce").mockImplementation((func) => {
return func;
});
- var spy_reset = jest.spyOn(pattern, "_reset");
- pattern._hook($show);
- pattern._remove_slides($show, ["slide1", "slide3"]);
+
+ const instance = new Pattern($show);
+ await utils.timeout(1); // wait a tick for async to settle.
+
+ const spy_reset = jest.spyOn(instance, "_reset");
+ instance._hook();
+ instance._remove_slides(["slide1", "slide3"]);
expect(spy_reset).toHaveBeenCalled();
});
- it("Do not trigger reset when not doing anything", function () {
- var $show = $("", { class: "pat-slides" });
- for (var i = 1; i <= 2; i++)
+ it("Do not trigger reset when not doing anything", async function () {
+ const $show = $("", { class: "pat-slides" });
+ for (let i = 1; i <= 2; i++)
$("", { class: "slide", id: "slide" + i }).appendTo($show);
- var spy_reset = jest.spyOn(pattern, "_reset");
- pattern._remove_slides($show, ["slide1", "slide2"]);
+
+ const instance = new Pattern($show);
+ await utils.timeout(1); // wait a tick for async to settle.
+
+ const spy_reset = jest.spyOn(instance, "_reset");
+ instance._remove_slides(["slide1", "slide2"]);
expect(spy_reset).not.toHaveBeenCalled();
});
});