@patternslib/patternslib
Advanced tools
Comparing version 4.6.1 to 4.7.0
{ | ||
"name": "@patternslib/patternslib", | ||
"version": "4.6.1", | ||
"version": "4.7.0", | ||
"title": "Markup patterns to drive behaviour.", | ||
@@ -26,3 +26,3 @@ "description": "Patternslib is a JavaScript library that enables designers to build rich interactive prototypes without the need for writing any Javascript. All events are triggered by classes and other attributes in the HTML, without abusing the HTML as a programming language. Accessibility, SEO and well structured HTML are core values of Patterns.", | ||
"@juggle/resize-observer": "^3.3.1", | ||
"@stomp/stompjs": "^6.1.0", | ||
"@stomp/stompjs": "^6.1.2", | ||
"google-code-prettify": "^1.0.5", | ||
@@ -54,9 +54,9 @@ "imagesloaded": "^4.1.4", | ||
"devDependencies": { | ||
"@babel/core": "^7.14.6", | ||
"@babel/eslint-parser": "^7.14.7", | ||
"@babel/core": "^7.15.5", | ||
"@babel/eslint-parser": "^7.15.4", | ||
"@babel/plugin-proposal-optional-chaining": "^7.14.5", | ||
"@babel/preset-env": "^7.14.7", | ||
"@commitlint/cli": "^12.1.4", | ||
"@commitlint/config-conventional": "^12.1.4", | ||
"@release-it/conventional-changelog": "^3.0.1", | ||
"@babel/preset-env": "^7.15.4", | ||
"@commitlint/cli": "^13.1.0", | ||
"@commitlint/config-conventional": "^13.1.0", | ||
"@release-it/conventional-changelog": "^3.3.0", | ||
"@testing-library/jest-dom": "^5.14.1", | ||
@@ -66,19 +66,19 @@ "babel-loader": "^8.2.2", | ||
"copy-webpack-plugin": "^6.4.1", | ||
"core-js": "3.15.2", | ||
"core-js": "3.17.2", | ||
"css-loader": "^5.2.6", | ||
"duplicate-package-checker-webpack-plugin": "^3.0.0", | ||
"eslint": "^7.30.0", | ||
"eslint": "^7.32.0", | ||
"eslint-config-prettier": "^8.3.0", | ||
"expose-loader": "^1.0.3", | ||
"file-loader": "^6.2.0", | ||
"husky": "^6.0.0", | ||
"husky": "^7.0.2", | ||
"identity-obj-proxy": "^3.0.0", | ||
"imports-loader": "^1.2.0", | ||
"jest": "^27.0.6", | ||
"jest": "^27.1.1", | ||
"jest-watch-typeahead": "^0.6.4", | ||
"prettier": "^2.3.2", | ||
"raw-loader": "^4.0.1", | ||
"regenerator-runtime": "^0.13.5", | ||
"release-it": "^14.10.0", | ||
"sass": "^1.35.2", | ||
"regenerator-runtime": "^0.13.9", | ||
"release-it": "^14.11.5", | ||
"sass": "^1.39.0", | ||
"sass-loader": "^10.1.1", | ||
@@ -88,10 +88,10 @@ "style-loader": "^2.0.0", | ||
"terser-webpack-plugin": "^4.2.3", | ||
"timezone-mock": "^1.1.4", | ||
"timezone-mock": "^1.2.1", | ||
"webpack": "^4.43.0", | ||
"webpack-bundle-analyzer": "^3.9.0", | ||
"webpack-cli": "^4.7.0", | ||
"webpack-cli": "^4.8.0", | ||
"webpack-dev-server": "^3.11.2", | ||
"webpack-modernizr-loader": "^5.0.0", | ||
"whybundled": "^2.0.0", | ||
"yarn": "^1.22.10" | ||
"yarn": "^1.22.11" | ||
}, | ||
@@ -98,0 +98,0 @@ "resolutions": {}, |
@@ -39,3 +39,2 @@ /** | ||
} | ||
$el.data(`pattern-${name}`, pattern); | ||
} | ||
@@ -53,2 +52,7 @@ return pattern; | ||
await this.init($el, options, trigger); | ||
// Store pattern instance on element | ||
this.$el.data(`pattern-${this.name}`, this); | ||
this.el[`pattern-${this.name}`] = this; | ||
this.emit("init"); | ||
@@ -55,0 +59,0 @@ }; |
@@ -179,2 +179,30 @@ import registry from "./registry"; | ||
}); | ||
it("adds the pattern instance on the element when manually initialized", async () => { | ||
const Tmp = Base.extend({ | ||
name: "example", | ||
init: () => {}, | ||
}); | ||
const node = document.createElement("div"); | ||
node.setAttribute("class", "pat-example"); | ||
const tmp = new Tmp(node); | ||
await utils.timeout(1); | ||
expect(tmp instanceof Tmp).toBeTruthy(); | ||
expect(tmp.el["pattern-example"]).toBe(tmp); | ||
expect(tmp.$el.data("pattern-example")).toBe(tmp); | ||
}); | ||
it("adds the pattern instance on the element when scanning the DOM tree", async () => { | ||
const Tmp = Base.extend({ | ||
name: "example", | ||
trigger: ".pat-example", | ||
init: () => {}, | ||
}); | ||
const node = document.createElement("div"); | ||
node.setAttribute("class", "pat-example"); | ||
registry.scan(node); | ||
await utils.timeout(1); | ||
expect(node["pattern-example"] instanceof Tmp).toBeTruthy(); | ||
expect($(node).data("pattern-example") instanceof Tmp).toBeTruthy(); | ||
}); | ||
}); |
@@ -105,2 +105,60 @@ /* Utilities for DOM traversal or navigation */ | ||
// Event listener registration for easy-to-remove event listeners. | ||
// once Safari supports the ``signal`` option for addEventListener we can abort | ||
// event handlers by calling AbortController.abort(). | ||
const event_listener_map = {}; | ||
/** | ||
* Add an event listener to a DOM element under a unique id. | ||
* If a event is registered under the same id for the same element, the old hander is removed first. | ||
* | ||
* @param {DOM Node} el - The element to register the event for. | ||
* @param {string} event_type - The event type to listen for. | ||
* @param {string} id - A unique id under which the event is registered. | ||
* @param {function} cb - The event handler / callback function. | ||
* @param {Object} opts - Options for the addEventListener API. | ||
* | ||
*/ | ||
const add_event_listener = (el, event_type, id, cb, opts = {}) => { | ||
if (!el?.addEventListener) { | ||
return; // nothing to do. | ||
} | ||
remove_event_listener(el, id); // do not register one listener twice. | ||
if (!event_listener_map[el]) { | ||
event_listener_map[el] = {}; | ||
} | ||
event_listener_map[el][id] = [event_type, cb, opts.capture ? opts : undefined]; // prettier-ignore | ||
el.addEventListener(event_type, cb, opts); | ||
}; | ||
/** | ||
* Remove an event listener from a DOM element under a unique id. | ||
* | ||
* @param {DOM Node} el - The element to register the event for. | ||
* @param {string} id - A unique id under which the event is registered. | ||
* | ||
*/ | ||
const remove_event_listener = (el, id) => { | ||
if (!el?.removeEventListener) { | ||
return; // nothing to do. | ||
} | ||
const el_events = event_listener_map[el]; | ||
if (!el_events) { | ||
return; | ||
} | ||
let entries; | ||
if (id) { | ||
// remove event listener with specific id | ||
const entry = el_events[id]; | ||
entries = entry ? [entry] : []; | ||
} else { | ||
// remove all event listeners of element | ||
entries = Object.entries(el_events); | ||
} | ||
for (const entry of entries || []) { | ||
el.removeEventListener(entry[0], entry[1], entry[2]); | ||
} | ||
}; | ||
const dom = { | ||
@@ -117,4 +175,6 @@ toNodeArray: toNodeArray, | ||
create_from_string: create_from_string, | ||
add_event_listener: add_event_listener, | ||
remove_event_listener: remove_event_listener, | ||
}; | ||
export default dom; |
@@ -324,2 +324,49 @@ import $ from "jquery"; | ||
}); | ||
describe("add / remove event listener", () => { | ||
const _el = { | ||
event_list: [], | ||
addEventListener(event_type, cb) { | ||
this.event_list.push([event_type, cb]); | ||
}, | ||
removeEventListener(event_type, cb) { | ||
const idx = this.event_list.indexOf([event_type, cb]); | ||
this.event_list.splice(idx, 1); | ||
}, | ||
}; | ||
it("Registers events only once and unregisters events.", (done) => { | ||
const cb1 = () => {}; | ||
const cb2 = () => {}; | ||
// register one event handler | ||
dom.add_event_listener(_el, "click", "test_click", cb1); | ||
expect(_el.event_list.length).toBe(1); | ||
expect(_el.event_list[0][1]).toBe(cb1); | ||
// register another event hander under the same id | ||
dom.add_event_listener(_el, "click", "test_click", cb2); | ||
expect(_el.event_list.length).toBe(1); | ||
expect(_el.event_list[0][1]).toBe(cb2); | ||
// register two more event handlers with unique ids | ||
dom.add_event_listener(_el, "click", "test_click_2", () => {}); | ||
dom.add_event_listener(_el, "click", "test_click_3", () => {}); | ||
expect(_el.event_list.length).toBe(3); | ||
// remove one specific event handler | ||
dom.remove_event_listener(_el, "test_click_2"); | ||
expect(_el.event_list.length).toBe(2); | ||
// try to remove an unregistered event handler | ||
dom.remove_event_listener(_el, "test_click_4"); | ||
expect(_el.event_list.length).toBe(2); | ||
// remove all registered event handlers on that element | ||
dom.remove_event_listener(_el); | ||
expect(_el.event_list.length).toBe(0); | ||
done(); | ||
}); | ||
}); | ||
}); |
@@ -196,4 +196,4 @@ import $ from "jquery"; | ||
}, | ||
destroy() { | ||
// if working without injection, destroy right away. | ||
async destroy() { | ||
await utils.timeout(1); // wait a tick for event handlers (e.g. form submit) have a chance to kick in first. | ||
$(document).off(".pat-modal"); | ||
@@ -208,18 +208,13 @@ this.$el.remove(); | ||
// once that has been triggered | ||
let destroy_handler = () => { | ||
$(document).off(".pat-modal"); | ||
this.$el.remove(); | ||
$("body").removeClass("modal-active"); | ||
$("body").removeClass("modal-panel"); | ||
const destroy_handler = () => { | ||
this.destroy(); | ||
$("body").off("patterns-inject-triggered", destroy_handler); | ||
}; | ||
$("body").on("patterns-inject-triggered", destroy_handler); | ||
$("body").on("patterns-inject-triggered", destroy_handler.bind(this)); | ||
} else { | ||
// if working without injection, destroy right away. | ||
$(document).off(".pat-modal"); | ||
this.$el.remove(); | ||
$("body").removeClass("modal-active"); | ||
$("body").removeClass("modal-panel"); | ||
// if working without injection, destroy after waiting a tick to let | ||
// eventually registered on-submit handlers kick in first. | ||
this.destroy(); | ||
} | ||
}, | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
7306765
39944
Updated@stomp/stompjs@^6.1.2