diff --git a/README.md b/README.md
index 5871190..9832b4e 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,13 @@
**Social Media Photo by [chuttersnap](https://unsplash.com/@chuttersnap) on [Unsplash](https://unsplash.com/)**
+### 📣 Community Announcement
-This module integrates [augmentor](https://github.com/WebReflection/augmentor#readme) in [wickedElements](https://github.com/WebReflection/wicked-elements#readme) for a ~2.4K all-inclusive package and zero polyfills needed whatsoever.
+Please ask questions in the [dedicated discussions repository](https://github.com/WebReflection/discussions), to help the community around this project grow ♥
+
+---
+
+This module integrates [µhooks](https://github.com/WebReflection/uhooks#readme) in [wickedElements](https://github.com/WebReflection/wicked-elements#readme) for a *~2K* all-inclusive package and zero polyfills needed whatsoever.
The compatibility is the same as _wickedElements_, meaning IE11+ and other Desktop/Mobile browsers.
@@ -25,7 +30,7 @@ The callback is used as `render` method and automatically augmented and invoked
### In A Nutshell
-All [augmentor hooks](https://github.com/WebReflection/augmentor#available-hooks) are available, and `useEffect` is granted to run *before* `disconnected`, if it returns a callback to drop the effect.
+All [hooks](https://github.com/WebReflection/augmentor#available-hooks) are available, and `useEffect` is granted to run *before* `disconnected`, if it returns a callback to drop the effect.
**[Live Demo](https://codepen.io/WebReflection/pen/mdJVERz)**
@@ -73,22 +78,22 @@ define('button.counter', {
- Sure thing! Following a
lighterhtml integration example, also
live in CodePen:
+ Sure thing! Following a
µhtml integration example, also
live in CodePen:
**[Live Demo](https://codepen.io/WebReflection/pen/poJyjGy)**
```js
-import {render, html, svg} from 'lighterhtml';
+import {render, html, svg} from 'uhtml';
import {define, useState} from 'hooked-elements';
// as mixin
-const LighterHTML = {
+const MicroHTML = {
html() { return render(this.element, html.apply(null, arguments)); },
svg() { return render(this.element, svg.apply(null, arguments)); }
};
define('button.counter', {
- ...LighterHTML,
+ ...MicroHTML,
render(element) {
const [count, update] = useState(1);
element.onclick = () => update(count + 1);
diff --git a/cjs/index.js b/cjs/index.js
index 1da81b4..70dfdbe 100644
--- a/cjs/index.js
+++ b/cjs/index.js
@@ -1,5 +1,5 @@
'use strict';
-const {augmentor, dropEffect, hasEffect} = require('augmentor');
+const {hooked, dropEffect, hasEffect} = require('uhooks');
const {define: $define, defineAsync: $async} = require('wicked-elements');
// default init with auto-augmented and invoked render
@@ -22,7 +22,7 @@ exports.defineAsync = defineAsync;
const render = wicked => {
const {disconnected, element, render} = wicked;
- const hook = augmentor(render.bind(wicked, element));
+ const hook = hooked(render.bind(wicked, element));
wicked.disconnected = () => {
if (hasEffect(hook))
dropEffect(hook);
@@ -43,7 +43,7 @@ exports.render = render;
exports.useCallback = m.useCallback;
exports.useMemo = m.useMemo;
exports.useRef = m.useRef;
-})(require('augmentor'));
+})(require('uhooks'));
(m => {
exports.get = m.get;
diff --git a/esm/index.js b/esm/index.js
index ad7b1f7..33e25ca 100644
--- a/esm/index.js
+++ b/esm/index.js
@@ -1,4 +1,4 @@
-import {augmentor, dropEffect, hasEffect} from 'augmentor';
+import {hooked, dropEffect, hasEffect} from 'uhooks';
import {define as $define, defineAsync as $async} from 'wicked-elements';
// default init with auto-augmented and invoked render
@@ -19,7 +19,7 @@ export const defineAsync = (selector, callback) => {
export const render = wicked => {
const {disconnected, element, render} = wicked;
- const hook = augmentor(render.bind(wicked, element));
+ const hook = hooked(render.bind(wicked, element));
wicked.disconnected = () => {
if (hasEffect(hook))
dropEffect(hook);
@@ -37,7 +37,7 @@ export {
useCallback,
useMemo,
useRef
-} from 'augmentor';
+} from 'uhooks';
export {
get,
diff --git a/index.js b/index.js
index db729d0..be4504f 100644
--- a/index.js
+++ b/index.js
@@ -1,519 +1,447 @@
var hookedElements = (function (exports) {
'use strict';
- var compat = typeof cancelAnimationFrame === 'function';
- var cAF = compat ? cancelAnimationFrame : clearTimeout;
- var rAF = compat ? requestAnimationFrame : setTimeout;
- function reraf(limit) {
- var force, timer, callback, self, args;
- reset();
- return function reschedule(_callback, _self, _args) {
- callback = _callback;
- self = _self;
- args = _args;
- if (!timer) timer = rAF(invoke);
- if (--force < 0) stop(true);
- return stop;
+ var Lie = typeof Promise === 'function' ? Promise : function (fn) {
+ var queue = [],
+ resolved = 0,
+ value;
+ fn(function ($) {
+ value = $;
+ resolved = 1;
+ queue.splice(0).forEach(then);
+ });
+ return {
+ then: then
};
- function invoke() {
- reset();
- callback.apply(self, args || []);
+ function then(fn) {
+ return resolved ? setTimeout(fn, 0, value) : queue.push(fn), this;
}
+ };
- function reset() {
- force = limit || Infinity;
- timer = compat ? 0 : null;
+ var info = null,
+ schedule = new Set();
+
+ var invoke = function invoke(effect) {
+ var $ = effect.$,
+ r = effect.r,
+ h = effect.h;
+
+ if (isFunction(r)) {
+ fx.get(h)["delete"](effect);
+ r();
}
- function stop(flush) {
- var didStop = !!timer;
+ if (isFunction(effect.r = $())) fx.get(h).add(effect);
+ };
- if (didStop) {
- cAF(timer);
- if (flush) invoke();
- }
+ var runSchedule = function runSchedule() {
+ var previous = schedule;
+ schedule = new Set();
+ previous.forEach(function (_ref) {
+ var h = _ref.h,
+ c = _ref.c,
+ a = _ref.a,
+ e = _ref.e;
+ // avoid running schedules when the hook is
+ // re-executed before such schedule happens
+ if (e) h.apply(c, a);
+ });
+ };
- return didStop;
- }
+ var fx = new WeakMap();
+ var effects = [];
+ var layoutEffects = [];
+ function different(value, i) {
+ return value !== this[i];
}
-
- var umap = (function (_) {
- return {
- // About: get: _.get.bind(_)
- // It looks like WebKit/Safari didn't optimize bind at all,
- // so that using bind slows it down by 60%.
- // Firefox and Chrome are just fine in both cases,
- // so let's use the approach that works fast everywhere 👍
- get: function get(key) {
- return _.get(key);
- },
- set: function set(key, value) {
- return _.set(key, value), value;
- }
+ var dropEffect = function dropEffect(hook) {
+ var effects = fx.get(hook);
+ if (effects) wait.then(function () {
+ effects.forEach(function (effect) {
+ effect.r();
+ effect.r = null;
+ });
+ effects.clear();
+ });
+ };
+ var getInfo = function getInfo() {
+ return info;
+ };
+ var hasEffect = function hasEffect(hook) {
+ return fx.has(hook);
+ };
+ var isFunction = function isFunction(f) {
+ return typeof f === 'function';
+ };
+ var hooked = function hooked(callback) {
+ var current = {
+ h: hook,
+ c: null,
+ a: null,
+ e: 0,
+ i: 0,
+ s: []
};
- });
+ return hook;
- /*! (c) Andrea Giammarchi - ISC */
- var state = null; // main exports
-
- var augmentor = function augmentor(fn) {
- var stack = [];
- return function hook() {
- var prev = state;
- var after = [];
- state = {
- hook: hook,
- args: arguments,
- stack: stack,
- i: 0,
- length: stack.length,
- after: after
- };
+ function hook() {
+ var prev = info;
+ info = current;
+ current.e = current.i = 0;
try {
- return fn.apply(null, arguments);
+ return callback.apply(current.c = this, current.a = arguments);
} finally {
- state = prev;
-
- for (var i = 0, length = after.length; i < length; i++) {
- after[i]();
- }
+ info = prev;
+ if (effects.length) wait.then(effects.forEach.bind(effects.splice(0), invoke));
+ if (layoutEffects.length) layoutEffects.splice(0).forEach(invoke);
}
- };
- };
-
- var updates = umap(new WeakMap());
-
- var hookdate = function hookdate(hook, ctx, args) {
- hook.apply(ctx, args);
+ }
};
-
- var defaults = {
- async: false,
- always: false
+ var reschedule = function reschedule(info) {
+ if (!schedule.has(info)) {
+ info.e = 1;
+ schedule.add(info);
+ wait.then(runSchedule);
+ }
};
+ var wait = new Lie(function ($) {
+ return $();
+ });
- var getValue = function getValue(value, f) {
- return typeof f == 'function' ? f(value) : f;
+ var createContext = function createContext(value) {
+ return {
+ _: new Set(),
+ provide: provide,
+ value: value
+ };
};
+ var useContext = function useContext(_ref) {
+ var _ = _ref._,
+ value = _ref.value;
- var useReducer = function useReducer(reducer, value, init, options) {
- var i = state.i++;
- var _state = state,
- hook = _state.hook,
- args = _state.args,
- stack = _state.stack,
- length = _state.length;
- if (i === length) state.length = stack.push({});
- var ref = stack[i];
- ref.args = args;
-
- if (i === length) {
- var fn = typeof init === 'function';
+ _.add(getInfo());
- var _ref = (fn ? options : init) || options || defaults,
- asy = _ref.async,
- always = _ref.always;
-
- ref.$ = fn ? init(value) : getValue(void 0, value);
- ref._ = asy ? updates.get(hook) || updates.set(hook, reraf()) : hookdate;
+ return value;
+ };
- ref.f = function (value) {
- var $value = reducer(ref.$, value);
+ function provide(newValue) {
+ var _ = this._,
+ value = this.value;
- if (always || ref.$ !== $value) {
- ref.$ = $value;
+ if (value !== newValue) {
+ this._ = new Set();
+ this.value = newValue;
- ref._(hook, null, ref.args);
- }
- };
+ _.forEach(function (_ref2) {
+ var h = _ref2.h,
+ c = _ref2.c,
+ a = _ref2.a;
+ h.apply(c, a);
+ });
}
+ }
- return [ref.$, ref.f];
- }; // useState
-
- var useState = function useState(value, options) {
- return useReducer(getValue, value, void 0, options);
- }; // useContext
-
- var hooks = new WeakMap();
-
- var invoke = function invoke(_ref2) {
- var hook = _ref2.hook,
- args = _ref2.args;
- hook.apply(null, args);
- };
-
- var createContext = function createContext(value) {
- var context = {
- value: value,
- provide: provide
- };
- hooks.set(context, []);
- return context;
+ var useCallback = function useCallback(fn, guards) {
+ return useMemo(function () {
+ return fn;
+ }, guards);
};
- var useContext = function useContext(context) {
- var _state2 = state,
- hook = _state2.hook,
- args = _state2.args;
- var stack = hooks.get(context);
- var info = {
- hook: hook,
- args: args
+ var useMemo = function useMemo(memo, guards) {
+ var info = getInfo();
+ var i = info.i,
+ s = info.s;
+ if (i === s.length || !guards || guards.some(different, s[i]._)) s[i] = {
+ $: memo(),
+ _: guards
};
- if (!stack.some(update, info)) stack.push(info);
- return context.value;
+ return s[info.i++].$;
};
- function provide(value) {
- if (this.value !== value) {
- this.value = value;
- hooks.get(this).forEach(invoke);
- }
- }
-
- function update(_ref3) {
- var hook = _ref3.hook;
- return hook === this.hook;
- } // dropEffect, hasEffect, useEffect, useLayoutEffect
-
-
- var effects = new WeakMap();
- var fx = umap(effects);
-
- var stop = function stop() {};
-
- var createEffect = function createEffect(asy) {
- return function (effect, guards) {
- var i = state.i++;
- var _state3 = state,
- hook = _state3.hook,
- after = _state3.after,
- stack = _state3.stack,
- length = _state3.length;
-
- if (i < length) {
- var info = stack[i];
- var _update = info.update,
- values = info.values,
- _stop = info.stop;
-
- if (!guards || guards.some(different, values)) {
- info.values = guards;
- if (asy) _stop(asy);
- var clean = info.clean;
-
- if (clean) {
- info.clean = null;
- clean();
- }
-
- var _invoke = function _invoke() {
- info.clean = effect();
- };
-
- if (asy) _update(_invoke);else after.push(_invoke);
- }
- } else {
- var _update2 = asy ? reraf() : stop;
-
- var _info = {
- clean: null,
- update: _update2,
- values: guards,
- stop: stop
+ var createEffect = function createEffect(stack) {
+ return function (callback, guards) {
+ var info = getInfo();
+ var i = info.i,
+ s = info.s,
+ h = info.h;
+ var call = i === s.length;
+ info.i++;
+
+ if (call) {
+ if (!fx.has(h)) fx.set(h, new Set());
+ s[i] = {
+ $: callback,
+ _: guards,
+ r: null,
+ h: h
};
- state.length = stack.push(_info);
- (fx.get(hook) || fx.set(hook, [])).push(_info);
-
- var _invoke2 = function _invoke2() {
- _info.clean = effect();
- };
-
- if (asy) _info.stop = _update2(_invoke2);else after.push(_invoke2);
}
+
+ if (call || !guards || guards.some(different, s[i]._)) stack.push(s[i]);
+ s[i].$ = callback;
+ s[i]._ = guards;
};
};
- var dropEffect = function dropEffect(hook) {
- (effects.get(hook) || []).forEach(function (info) {
- var clean = info.clean,
- stop = info.stop;
- stop();
-
- if (clean) {
- info.clean = null;
- clean();
+ var useEffect = createEffect(effects);
+ var useLayoutEffect = createEffect(layoutEffects);
+
+ var getValue = function getValue(value, f) {
+ return isFunction(f) ? f(value) : f;
+ };
+
+ var useReducer = function useReducer(reducer, value, init) {
+ var info = getInfo();
+ var i = info.i,
+ s = info.s;
+ if (i === s.length) s.push({
+ $: isFunction(init) ? init(value) : getValue(void 0, value),
+ set: function set(value) {
+ s[i].$ = reducer(s[i].$, value);
+ reschedule(info);
}
});
+ var _s$info$i = s[info.i++],
+ $ = _s$info$i.$,
+ set = _s$info$i.set;
+ return [$, set];
};
- var hasEffect = effects.has.bind(effects);
- var useEffect = createEffect(true);
- var useLayoutEffect = createEffect(false); // useMemo, useCallback
-
- var useMemo = function useMemo(memo, guards) {
- var i = state.i++;
- var _state4 = state,
- stack = _state4.stack,
- length = _state4.length;
- if (i === length) state.length = stack.push({
- $: memo(),
- _: guards
- });else if (!guards || guards.some(different, stack[i]._)) stack[i] = {
- $: memo(),
- _: guards
- };
- return stack[i].$;
+ var useState = function useState(value) {
+ return useReducer(getValue, value);
};
- var useCallback = function useCallback(fn, guards) {
- return useMemo(function () {
- return fn;
- }, guards);
- }; // useRef
-
- var useRef = function useRef(value) {
- var i = state.i++;
- var _state5 = state,
- stack = _state5.stack,
- length = _state5.length;
- if (i === length) state.length = stack.push({
- current: value
+
+ var useRef = function useRef(current) {
+ var info = getInfo();
+ var i = info.i,
+ s = info.s;
+ if (i === s.length) s.push({
+ current: current
});
- return stack[i];
+ return s[info.i++];
};
- function different(value, i) {
- return value !== this[i];
- }
-
- var asCustomElement = (function (root, upgrade) {
- var wm = new WeakMap();
- var ao = new WeakMap();
- var filter = [].filter;
-
- var attributeChanged = function attributeChanged(records, mo) {
- for (var i = 0, length = records.length; i < length; i++) {
- var _records$i = records[i],
- target = _records$i.target,
- attributeName = _records$i.attributeName,
- oldValue = _records$i.oldValue;
- var newValue = target.getAttribute(attributeName);
- ao.get(mo).call(target, attributeName, oldValue, newValue);
- }
- };
+ var TRUE = true,
+ FALSE = false;
+ var QSA$1 = 'querySelectorAll';
- var elements = function elements(target) {
- return 'querySelectorAll' in target;
- };
+ function add(node) {
+ this.observe(node, {
+ subtree: TRUE,
+ childList: TRUE
+ });
+ }
+ /**
+ * Start observing a generic document or root element.
+ * @param {Function} callback triggered per each dis/connected node
+ * @param {Element?} root by default, the global document to observe
+ * @param {Function?} MO by default, the global MutationObserver
+ * @returns {MutationObserver}
+ */
- var mainLoop = function mainLoop(records) {
- for (var i = 0, length = records.length; i < length; i++) {
- var _records$i2 = records[i],
- addedNodes = _records$i2.addedNodes,
- removedNodes = _records$i2.removedNodes;
- parse(filter.call(addedNodes, elements), 'c', new Set());
- parse(filter.call(removedNodes, elements), 'd', new Set());
- }
- };
- var parse = function parse(nodes, key, parsed) {
+ var notify = function notify(callback, root, MO) {
+ var loop = function loop(nodes, added, removed, connected, pass) {
for (var i = 0, length = nodes.length; i < length; i++) {
- var target = nodes[i];
+ var node = nodes[i];
+
+ if (pass || QSA$1 in node) {
+ if (connected) {
+ if (!added.has(node)) {
+ added.add(node);
+ removed["delete"](node);
+ callback(node, connected);
+ }
+ } else if (!removed.has(node)) {
+ removed.add(node);
+ added["delete"](node);
+ callback(node, connected);
+ }
- if (!parsed.has(target)) {
- parsed.add(target);
- if (wm.has(target)) wm.get(target)[key].forEach(call, target);else if (key === 'c') upgrade(target);
- parse(target.querySelectorAll('*'), key, parsed);
+ if (!pass) loop(node[QSA$1]('*'), added, removed, connected, TRUE);
}
}
};
- var set = function set(target) {
- var sets = {
- c: new Set(),
- d: new Set()
- };
- wm.set(target, sets);
- return sets;
- };
-
- var sdo = new MutationObserver(mainLoop);
- sdo.observe(root, {
- childList: true,
- subtree: true
- });
- return function (target, _ref) {
- var connectedCallback = _ref.connectedCallback,
- disconnectedCallback = _ref.disconnectedCallback,
- observedAttributes = _ref.observedAttributes,
- attributeChangedCallback = _ref.attributeChangedCallback;
- mainLoop(sdo.takeRecords());
-
- var _ref2 = wm.get(target) || set(target),
- c = _ref2.c,
- d = _ref2.d;
-
- if (observedAttributes) {
- var mo = new MutationObserver(attributeChanged);
- mo.observe(target, {
- attributes: true,
- attributeOldValue: true,
- attributeFilter: observedAttributes.map(function (attributeName) {
- if (target.hasAttribute(attributeName)) attributeChangedCallback.call(target, attributeName, null, target.getAttribute(attributeName));
- return attributeName;
- })
- });
- ao.set(mo, attributeChangedCallback);
+ var observer = new (MO || MutationObserver)(function (records) {
+ for (var added = new Set(), removed = new Set(), i = 0, length = records.length; i < length; i++) {
+ var _records$i = records[i],
+ addedNodes = _records$i.addedNodes,
+ removedNodes = _records$i.removedNodes;
+ loop(removedNodes, added, removed, FALSE, FALSE);
+ loop(addedNodes, added, removed, TRUE, FALSE);
}
+ });
+ observer.add = add;
+ observer.add(root || document);
+ return observer;
+ };
- if (disconnectedCallback) d.add(disconnectedCallback);
+ var QSA = 'querySelectorAll';
+ var _self = self,
+ document$1 = _self.document,
+ Element = _self.Element,
+ MutationObserver$1 = _self.MutationObserver,
+ Set$1 = _self.Set,
+ WeakMap$1 = _self.WeakMap;
- if (connectedCallback) {
- c.add(connectedCallback);
- if (!(target.ownerDocument.compareDocumentPosition(target) & target.DOCUMENT_POSITION_DISCONNECTED)) connectedCallback.call(target);
- }
+ var elements = function elements(element) {
+ return QSA in element;
+ };
- return target;
- };
- });
+ var filter = [].filter;
+ var QSAO = (function (options) {
+ var live = new WeakMap$1();
- function call(back) {
- back.call(this);
- }
-
- var Lie = typeof Promise === 'function' ? Promise : function (fn) {
- var queue = [],
- resolved = 0;
- fn(function () {
- resolved = 1;
- queue.splice(0).forEach(then);
- });
- return {
- then: then
+ var drop = function drop(elements) {
+ for (var i = 0, length = elements.length; i < length; i++) {
+ live["delete"](elements[i]);
+ }
};
- function then(fn) {
- return resolved ? setTimeout(fn) : queue.push(fn), this;
- }
- };
- var utils = (function (root, query, config, defined, setup) {
- // exports
- var get = function get(selector) {
- var i = query.indexOf(selector);
- return i < 0 ? void 0 : config[i].o;
- };
+ var flush = function flush() {
+ var records = observer.takeRecords();
- var upgrade = function upgrade(node) {
- upgradeNode(node, new Set());
+ for (var i = 0, length = records.length; i < length; i++) {
+ parse(filter.call(records[i].removedNodes, elements), false);
+ parse(filter.call(records[i].addedNodes, elements), true);
+ }
};
- var whenDefined = function whenDefined(selector) {
- if (!(selector in defined)) {
- var _,
- $ = new Lie(function ($) {
- _ = $;
- });
-
- defined[selector] = {
- _: _,
- $: $
- };
- }
+ var matches = function matches(element) {
+ return element.matches || element.webkitMatchesSelector || element.msMatchesSelector;
+ };
- return defined[selector].$;
- }; // util
+ var notifier = function notifier(element, connected) {
+ var selectors;
+ if (connected) {
+ for (var q, m = matches(element), i = 0, length = query.length; i < length; i++) {
+ if (m.call(element, q = query[i])) {
+ if (!live.has(element)) live.set(element, new Set$1());
+ selectors = live.get(element);
- var setupList = function setupList(nodes, parsed) {
- for (var i = 0, length = nodes.length; i < length; i++) {
- if (!parsed.has(nodes[i])) {
- parsed.add(nodes[i]);
- upgradeNode(nodes[i], parsed);
+ if (!selectors.has(q)) {
+ selectors.add(q);
+ options.handle(element, connected, q);
+ }
+ }
}
+ } else if (live.has(element)) {
+ selectors = live.get(element);
+ live["delete"](element);
+ selectors.forEach(function (q) {
+ options.handle(element, connected, q);
+ });
}
};
- var upgradeAll = function upgradeAll(node, parsed) {
- if (query.length) setupList(node.querySelectorAll(query), parsed);
- };
+ var parse = function parse(elements) {
+ var connected = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
- var upgradeNode = function upgradeNode(node, parsed) {
- for (var i = 0, length = query.length; i < length; i++) {
- if ((node.matches || node.webkitMatchesSelector || node.msMatchesSelector).call(node, query[i])) setup(node, config[i]);
+ for (var i = 0, length = elements.length; i < length; i++) {
+ notifier(elements[i], connected);
}
-
- if (parsed) upgradeAll(node, parsed);
};
+ var query = options.query;
+ var root = options.root || document$1;
+ var observer = notify(notifier, root, MutationObserver$1);
+ var attachShadow = Element.prototype.attachShadow;
+ if (attachShadow) Element.prototype.attachShadow = function (init) {
+ var shadowRoot = attachShadow.call(this, init);
+ observer.add(shadowRoot);
+ return shadowRoot;
+ };
+ if (query.length) parse(root[QSA](query));
return {
- get: get,
- upgrade: upgrade,
- whenDefined: whenDefined,
- $: setupList,
- _: asCustomElement(root, upgradeNode)
+ drop: drop,
+ flush: flush,
+ observer: observer,
+ parse: parse
};
});
var create = Object.create,
keys = Object.keys;
- var config = [];
+ var attributes = new WeakMap();
+ var lazy = new Set();
var query = [];
+ var config = {};
var defined = {};
- var lazy = new Set();
- var wicked = new WeakMap();
- var callbacks = new WeakMap();
-
- var _utils = utils(document, query, config, defined, function (value, _ref) {
- var m = _ref.m,
- l = _ref.l,
- o = _ref.o;
-
- if (!m.has(value)) {
- var handler = create(o, {
- element: {
- enumerable: true,
- value: value
- }
- });
- m.set(value, 0);
- if (!wicked.has(value)) wicked.set(value, []);
- wicked.get(value).push(handler);
- for (var i = 0, length = l.length; i < length; i++) {
- value.addEventListener(l[i].t, handler, l[i].o);
+ var attributeChangedCallback = function attributeChangedCallback(records, o) {
+ for (var h = attributes.get(o), i = 0, length = records.length; i < length; i++) {
+ var _records$i = records[i],
+ target = _records$i.target,
+ attributeName = _records$i.attributeName,
+ oldValue = _records$i.oldValue;
+ var newValue = target.getAttribute(attributeName);
+ h.attributeChanged(attributeName, oldValue, newValue);
+ }
+ };
+
+ var set = function set(value, m, l, o) {
+ var handler = create(o, {
+ element: {
+ enumerable: true,
+ value: value
}
+ });
- if (handler.init) handler.init();
- asCustomElement$1(value, o);
+ for (var i = 0, length = l.length; i < length; i++) {
+ value.addEventListener(l[i].t, handler, l[i].o);
}
- }),
- get = _utils.get,
- upgrade = _utils.upgrade,
- whenDefined = _utils.whenDefined,
- setupList = _utils.$,
- asCustomElement$1 = _utils._;
-
- var delegate = function delegate(key, method, notAC) {
- return function (name) {
- for (var h = wicked.get(this), i = 0, length = h.length; i < length; i++) {
- if (method === h[i][key] && (notAC || -1 < (h[i].observedAttributes || []).indexOf(name))) method.apply(h[i], arguments);
- }
- };
+
+ m.set(value, handler);
+ if (handler.init) handler.init();
+ var observedAttributes = o.observedAttributes;
+
+ if (observedAttributes) {
+ var mo = new MutationObserver(attributeChangedCallback);
+ mo.observe(value, {
+ attributes: true,
+ attributeOldValue: true,
+ attributeFilter: observedAttributes.map(function (attributeName) {
+ if (value.hasAttribute(attributeName)) handler.attributeChanged(attributeName, null, value.getAttribute(attributeName));
+ return attributeName;
+ })
+ });
+ attributes.set(mo, handler);
+ }
+
+ return handler;
};
- var define = function define(selector, definition) {
- if (get(selector)) throw new Error('duplicated: ' + selector);
+ var _QSAO = QSAO({
+ query: query,
+ handle: function handle(element, connected, selector) {
+ var _config$selector = config[selector],
+ m = _config$selector.m,
+ l = _config$selector.l,
+ o = _config$selector.o;
+ var handler = m.get(element) || set(element, m, l, o);
+ var method = connected ? 'connected' : 'disconnected';
+ if (method in handler) handler[method]();
+ }
+ }),
+ drop = _QSAO.drop,
+ flush = _QSAO.flush,
+ parse = _QSAO.parse;
+
+ var get = function get(selector) {
+ return (config[selector] || attributes).o;
+ };
+ var define$1 = function define(selector, definition) {
+ if (-1 < query.indexOf(selector)) throw new Error('duplicated: ' + selector);
+ flush();
var listeners = [];
var retype = create(null);
for (var k = keys(definition), i = 0, length = k.length; i < length; i++) {
var key = k[i];
- if (/^(?:connected|disconnected|attributeChanged)$/.test(key)) {
- if (!callbacks.has(definition[key])) callbacks.set(definition[key], delegate(key, definition[key], key[0] !== 'a'));
- definition[key + 'Callback'] = callbacks.get(definition[key]);
- } else if (/^on/.test(key) && !/Options$/.test(key)) {
+ if (/^on/.test(key) && !/Options$/.test(key)) {
var options = definition[key + 'Options'] || false;
var lower = key.toLowerCase();
var type = lower.slice(2);
@@ -541,52 +469,72 @@ var hookedElements = (function (exports) {
}
query.push(selector);
- config.push({
+ config[selector] = {
m: new WeakMap(),
l: listeners,
o: definition
- });
- setupList(document.querySelectorAll(selector), new Set());
+ };
+ parse(document.querySelectorAll(selector));
whenDefined(selector);
if (!lazy.has(selector)) defined[selector]._();
};
- var defineAsync = function defineAsync(selector, callback, _) {
+ var defineAsync$1 = function defineAsync(selector, callback, _) {
lazy.add(selector);
- define(selector, {
+ define$1(selector, {
init: function init() {
if (lazy.has(selector)) {
lazy["delete"](selector);
- callback().then(function (_ref2) {
- var definition = _ref2["default"];
- var i = query.indexOf(selector);
- query.splice(i, 1);
- config.splice(i, 1);
+ callback().then(function (_ref) {
+ var definition = _ref["default"];
+ query.splice(query.indexOf(selector), 1);
+ drop(document.querySelectorAll(selector));
- (_ || define)(selector, definition);
+ (_ || define$1)(selector, definition);
});
}
}
});
};
+ var upgrade = function upgrade(element) {
+ if (query.length) {
+ flush();
+ parse([element]);
+ }
+ };
+ var whenDefined = function whenDefined(selector) {
+ if (!(selector in defined)) {
+ var _,
+ $ = new Lie(function ($) {
+ _ = $;
+ });
+
+ defined[selector] = {
+ _: _,
+ $: $
+ };
+ }
+
+ return defined[selector].$;
+ };
function init() {
render(this);
}
- var define$1 = function define$1(selector, definition) {
- define(selector, typeof definition === 'function' ? {
+ var define = function define(selector, definition) {
+ define$1(selector, typeof definition === 'function' ? {
init: init,
render: definition
} : (definition.init || (definition.init = init), definition));
};
- var defineAsync$1 = function defineAsync$1(selector, callback) {
- defineAsync(selector, callback, define$1);
+ var defineAsync = function defineAsync(selector, callback) {
+ defineAsync$1(selector, callback, define);
};
var render = function render(wicked) {
var disconnected = wicked.disconnected,
element = wicked.element,
render = wicked.render;
- var hook = augmentor(render.bind(wicked, element));
+ var hook = hooked(render.bind(wicked, element));
wicked.disconnected = function () {
if (hasEffect(hook)) dropEffect(hook);
@@ -597,8 +545,8 @@ var hookedElements = (function (exports) {
};
exports.createContext = createContext;
- exports.define = define$1;
- exports.defineAsync = defineAsync$1;
+ exports.define = define;
+ exports.defineAsync = defineAsync;
exports.get = get;
exports.render = render;
exports.upgrade = upgrade;
diff --git a/min.js b/min.js
index 03c7c71..0a373a5 100644
--- a/min.js
+++ b/min.js
@@ -1,2 +1 @@
-var hookedElements=function(e){"use strict";var t="function"==typeof cancelAnimationFrame,n=t?cancelAnimationFrame:clearTimeout,r=t?requestAnimationFrame:setTimeout;function a(e){var a,u,o,i,c;return s(),function(e,t,n){return o=e,i=t,c=n,u||(u=r(l)),--a<0&&f(!0),f};function l(){s(),o.apply(i,c||[])}function s(){a=e||1/0,u=t?0:null}function f(e){var t=!!u;return t&&(n(u),e&&l()),t}}var u=function(e){return{get:function(t){return e.get(t)},set:function(t,n){return e.set(t,n),n}}},o=null,i=u(new WeakMap),c=function(e,t,n){e.apply(t,n)},l={async:!1,always:!1},s=function(e,t){return"function"==typeof t?t(e):t},f=function(e,t,n,r){var u=o.i++,f=o,h=f.hook,v=f.args,d=f.stack,p=f.length;u===p&&(o.length=d.push({}));var g=d[u];if(g.args=v,u===p){var m="function"==typeof n,k=(m?r:n)||r||l,b=k.async,w=k.always;g.$=m?n(t):s(void 0,t),g._=b?i.get(h)||i.set(h,a()):c,g.f=function(t){var n=e(g.$,t);(w||g.$!==n)&&(g.$=n,g._(h,null,g.args))}}return[g.$,g.f]},h=new WeakMap,v=function(e){var t=e.hook,n=e.args;t.apply(null,n)};
-/*! (c) Andrea Giammarchi - ISC */function d(e){this.value!==e&&(this.value=e,h.get(this).forEach(v))}function p(e){return e.hook===this.hook}var g=new WeakMap,m=u(g),k=function(){},b=function(e){return function(t,n){var r=o.i++,u=o,i=u.hook,c=u.after,l=u.stack;if(r
1&&void 0!==arguments[1])||arguments[1],r=0,u=e.length;r({get:t=>e.get(t),set:(t,n)=>(e.set(t,n),n)})
-/*! (c) Andrea Giammarchi - ISC */;let l=null;const r=a(new WeakMap),c=(e,t,n)=>{e.apply(t,n)},u={async:!1,always:!1},i=(e,t)=>"function"==typeof t?t(e):t,h=(e,t,n,s)=>{const a=l.i++,{hook:h,args:d,stack:f,length:p}=l;a===p&&(l.length=f.push({}));const g=f[a];if(g.args=d,a===p){const a="function"==typeof n,{async:l,always:d}=(a?s:n)||s||u;g.$=a?n(t):i(void 0,t),g._=l?r.get(h)||r.set(h,o()):c,g.f=t=>{const n=e(g.$,t);(d||g.$!==n)&&(g.$=n,g._(h,null,g.args))}}return[g.$,g.f]},d=new WeakMap,f=({hook:e,args:t})=>{e.apply(null,t)};function p(e){this.value!==e&&(this.value=e,d.get(this).forEach(f))}function g({hook:e}){return e===this.hook}const m=new WeakMap,k=a(m),w=()=>{},b=e=>(t,n)=>{const s=l.i++,{hook:a,after:r,stack:c,length:u}=l;if(s{o.clean=t()};e?a(l):r.push(l)}}else{const s=e?o():w,u={clean:null,update:s,values:n,stop:w};l.length=c.push(u),(k.get(a)||k.set(a,[])).push(u);const i=()=>{u.clean=t()};e?u.stop=s(i):r.push(i)}},v=m.has.bind(m),y=b(!0),S=b(!1),C=(e,t)=>{const n=l.i++,{stack:s,length:o}=l;return n===o?l.length=s.push({$:e(),_:t}):t&&!t.some(M,s[n]._)||(s[n]={$:e(),_:t}),s[n].$};function M(e,t){return e!==this[t]}var $=(e,t)=>{const n=new WeakMap,s=new WeakMap,{filter:o}=[],a=(e,t)=>{for(let n=0,{length:o}=e;n"querySelectorAll"in e,r=e=>{for(let t=0,{length:n}=e;t{for(let a=0,{length:l}=e;a{r(u.takeRecords());const{c:i,d:h}=n.get(e)||(e=>{const t={c:new Set,d:new Set};return n.set(e,t),t})(e);if(l){const t=new MutationObserver(a);t.observe(e,{attributes:!0,attributeOldValue:!0,attributeFilter:l.map(t=>(e.hasAttribute(t)&&c.call(e,t,null,e.getAttribute(t)),t))}),s.set(t,c)}return o&&h.add(o),t&&(i.add(t),e.ownerDocument.compareDocumentPosition(e)&e.DOCUMENT_POSITION_DISCONNECTED||t.call(e)),e}};function A(e){e.call(this)}const E="function"==typeof Promise?Promise:function(e){let t=[],n=0;return e(()=>{n=1,t.splice(0).forEach(s)}),{then:s};function s(e){return n?setTimeout(e):t.push(e),this}};const{create:O,keys:_}=Object,D=[],W=[],N={},T=new Set,q=new WeakMap,x=new WeakMap,{get:L,upgrade:F,whenDefined:P,$:I,_:R}=((e,t,n,s,o)=>{const a=(e,t)=>{for(let n=0,{length:s}=e;n{for(let s=0,{length:a}=t;s{t.length&&a(e.querySelectorAll(t),n)})(e,s)};return{get:e=>{const s=t.indexOf(e);return s<0?void 0:n[s].o},upgrade:e=>{l(e,new Set)},whenDefined:e=>{if(!(e in s)){let t,n=new E(e=>{t=e});s[e]={_:t,$:n}}return s[e].$},$:a,_:$(e,l)}})(document,W,D,N,(e,{m:t,l:n,o:s})=>{if(!t.has(e)){const o=O(s,{element:{enumerable:!0,value:e}});t.set(e,0),q.has(e)||q.set(e,[]),q.get(e).push(o);for(let t=0,{length:s}=n;tfunction(s){for(let o=q.get(this),a=0,{length:l}=o;a{if(L(e))throw new Error("duplicated: "+e);const n=[],s=O(null);for(let e=_(t),o=0,{length:a}=e;o{j(e,"function"==typeof t?{init:U,render:t}:(t.init||(t.init=U),t))},B=e=>{const{disconnected:t,element:n,render:s}=e,o=(e=>{const t=[];return function n(){const s=l,o=[];l={hook:n,args:arguments,stack:t,i:0,length:t.length,after:o};try{return e.apply(null,arguments)}finally{l=s;for(let e=0,{length:t}=o;e{v(o)&&(e=>{(m.get(e)||[]).forEach(e=>{const{clean:t,stop:n}=e;n(),t&&(e.clean=null,t())})})(o),t&&t.call(e)},(e.render=o)()};return e.createContext=e=>{const t={value:e,provide:p};return d.set(t,[]),t},e.define=z,e.defineAsync=(e,t)=>{((e,t,n)=>{T.add(e),j(e,{init(){T.has(e)&&(T.delete(e),t().then(({default:t})=>{const s=W.indexOf(e);W.splice(s,1),D.splice(s,1),(n||j)(e,t)}))}})})(e,t,z)},e.get=L,e.render=B,e.upgrade=F,e.useCallback=(e,t)=>C(()=>e,t),e.useContext=e=>{const{hook:t,args:n}=l,s=d.get(e),o={hook:t,args:n};return s.some(g,o)||s.push(o),e.value},e.useEffect=y,e.useLayoutEffect=S,e.useMemo=C,e.useReducer=h,e.useRef=e=>{const t=l.i++,{stack:n,length:s}=l;return t===s&&(l.length=n.push({current:e})),n[t]},e.useState=(e,t)=>h(i,e,void 0,t),e.whenDefined=P,e}({});
+var hookedElements=function(e){"use strict";var t=Promise;let n=null,s=new Set;const o=e=>{const{$:t,r:n,h:s}=e;u(n)&&(l.get(s).delete(e),n()),u(e.r=t())&&l.get(s).add(e)},r=()=>{const e=s;s=new Set,e.forEach((({h:e,c:t,a:n,e:s})=>{s&&e.apply(t,n)}))},l=new WeakMap,a=[],c=[];function i(e,t){return e!==this[t]}const d=()=>n,u=e=>"function"==typeof e,h=e=>{const t={h:s,c:null,a:null,e:0,i:0,s:[]};return s;function s(){const s=n;n=t,t.e=t.i=0;try{return e.apply(t.c=this,t.a=arguments)}finally{n=s,a.length&&f.then(a.forEach.bind(a.splice(0),o)),c.length&&c.splice(0).forEach(o)}}},f=new t((e=>e()));function p(e){const{_:t,value:n}=this;n!==e&&(this._=new Set,this.value=e,t.forEach((({h:e,c:t,a:n})=>{e.apply(t,n)})))}const g=(e,t)=>{const n=d(),{i:s,s:o}=n;return s!==o.length&&t&&!t.some(i,o[s]._)||(o[s]={$:e(),_:t}),o[n.i++].$},w=e=>(t,n)=>{const s=d(),{i:o,s:r,h:a}=s,c=o===r.length;s.i++,c&&(l.has(a)||l.set(a,new Set),r[o]={$:t,_:n,r:null,h:a}),(c||!n||n.some(i,r[o]._))&&e.push(r[o]),r[o].$=t,r[o]._=n},b=w(a),m=w(c),v=(e,t)=>u(t)?t(e):t,y=(e,t,n)=>{const o=d(),{i:l,s:a}=o;l===a.length&&a.push({$:u(n)?n(t):v(void 0,t),set:t=>{a[l].$=e(a[l].$,t),(e=>{s.has(e)||(e.e=1,s.add(e),f.then(r))})(o)}});const{$:c,set:i}=a[o.i++];return[c,i]},S=!0,E=!1,$="querySelectorAll";function _(e){this.observe(e,{subtree:S,childList:S})}const M="querySelectorAll",{document:k,Element:A,MutationObserver:O,Set:C,WeakMap:q}=self,L=e=>M in e,{filter:N}=[];const{create:x,keys:W}=Object,R=new WeakMap,V=new Set,j=[],D={},F={},P=(e,t)=>{for(let n=R.get(t),s=0,{length:o}=e;s{const t=new q,n=(n,s)=>{let r;if(s)for(let l,a=(e=>e.matches||e.webkitMatchesSelector||e.msMatchesSelector)(n),c=0,{length:i}=o;c{e.handle(n,s,t)})))},s=(e,t=!0)=>{for(let s=0,{length:o}=e;s{const s=(t,n,o,r,l)=>{for(let a=0,{length:c}=t;a{for(let t=new Set,n=new Set,o=0,{length:r}=e;o{for(let n=0,{length:s}=e;n{const e=l.takeRecords();for(let t=0,{length:n}=e;t{const o=x(s,{element:{enumerable:!0,value:e}});for(let t=0,{length:s}=n;t(e.hasAttribute(t)&&o.attributeChanged(t,null,e.getAttribute(t)),t)))}),R.set(t,o)}return o})(e,s,o,r),a=t?"connected":"disconnected";a in l&&l[a]()}}),H=(e,t)=>{if(-1{if(!(e in F)){let n,s=new t((e=>{n=e}));F[e]={_:n,$:s}}return F[e].$};function J(){Q(this)}const K=(e,t)=>{H(e,"function"==typeof t?{init:J,render:t}:(t.init||(t.init=J),t))},Q=e=>{const{disconnected:t,element:n,render:s}=e,o=h(s.bind(e,n));return e.disconnected=()=>{(e=>l.has(e))(o)&&(e=>{const t=l.get(e);t&&f.then((()=>{t.forEach((e=>{e.r(),e.r=null})),t.clear()}))})(o),t&&t.call(e)},(e.render=o)()};return e.createContext=e=>({_:new Set,provide:p,value:e}),e.define=K,e.defineAsync=(e,t)=>{((e,t,n)=>{V.add(e),H(e,{init(){V.has(e)&&(V.delete(e),t().then((({default:t})=>{j.splice(j.indexOf(e),1),z(document.querySelectorAll(e)),(n||H)(e,t)})))}})})(e,t,K)},e.get=e=>(D[e]||R).o,e.render=Q,e.upgrade=e=>{j.length&&(B(),G([e]))},e.useCallback=(e,t)=>g((()=>e),t),e.useContext=({_:e,value:t})=>(e.add(d()),t),e.useEffect=b,e.useLayoutEffect=m,e.useMemo=g,e.useReducer=y,e.useRef=e=>{const t=d(),{i:n,s:s}=t;return n===s.length&&s.push({current:e}),s[t.i++]},e.useState=e=>y(v,e),e.whenDefined=I,e}({});
diff --git a/package.json b/package.json
index 2bb41b7..8626aaa 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "hooked-elements",
- "version": "1.2.1",
+ "version": "2.2.2",
"description": "wickedElements 🧙 with render hooks",
"main": "./cjs/index.js",
"scripts": {
@@ -21,23 +21,23 @@
"author": "Andrea Giammarchi",
"license": "ISC",
"devDependencies": {
- "@babel/core": "^7.10.5",
- "@babel/preset-env": "^7.10.4",
- "@ungap/degap": "^0.2.0",
- "ascjs": "^4.0.1",
+ "@babel/core": "^7.14.0",
+ "@babel/preset-env": "^7.14.1",
+ "@ungap/degap": "^0.2.6",
+ "ascjs": "^5.0.1",
"http-server": "^0.12.3",
- "rollup": "^2.23.0",
+ "rollup": "^2.47.0",
"rollup-plugin-babel": "^4.4.0",
- "rollup-plugin-includepaths": "^0.2.3",
+ "rollup-plugin-includepaths": "^0.2.4",
"rollup-plugin-node-resolve": "^5.2.0",
- "rollup-plugin-terser": "^6.1.0",
- "terser": "^4.8.0"
+ "rollup-plugin-terser": "^7.0.2",
+ "terser": "^5.7.0"
},
"module": "./esm/index.js",
"unpkg": "min.js",
"dependencies": {
- "augmentor": "^2.2.0",
- "wicked-elements": "^3.0.19"
+ "uhooks": "^0.2.8",
+ "wicked-elements": "^3.1.2"
},
"repository": {
"type": "git",
diff --git a/rollup/babel.config.js b/rollup/babel.config.js
index 02974e8..db109e4 100644
--- a/rollup/babel.config.js
+++ b/rollup/babel.config.js
@@ -10,6 +10,7 @@ export default {
],
output: {
+ esModule: false,
exports: 'named',
file: './index.js',
format: 'iife',
diff --git a/rollup/new.config.js b/rollup/new.config.js
index 023ab1f..74f9b6f 100644
--- a/rollup/new.config.js
+++ b/rollup/new.config.js
@@ -8,7 +8,8 @@ export default {
includePaths({
include: {
'@ungap/element-matches': 'node_modules/@ungap/degap/element-matches.js',
- '@ungap/node-contains': 'node_modules/@ungap/degap/node-contains.js'
+ '@ungap/node-contains': 'node_modules/@ungap/degap/node-contains.js',
+ '@webreflection/lie': 'node_modules/@ungap/degap/promise.js'
},
}),
resolve({module: true}),
@@ -16,6 +17,7 @@ export default {
],
output: {
+ esModule: false,
exports: 'named',
file: './new.js',
format: 'iife',
diff --git a/test/counter.html b/test/counter.html
index 475a031..a8baa76 100644
--- a/test/counter.html
+++ b/test/counter.html
@@ -4,7 +4,7 @@
- wicked counter
+ hooked counter