Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@oddbird/popover-polyfill

Package Overview
Dependencies
Maintainers
3
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@oddbird/popover-polyfill - npm Package Compare versions

Comparing version 0.0.10 to 0.0.11

1

dist/data.d.ts

@@ -6,1 +6,2 @@ export declare const popovers: Set<HTMLElement>;

export declare const popoverInvokerSelector: string;
export declare const openPopoverSelector = "[popover=\"\" i].\\:open, [popover=auto i].\\:open";

118

dist/popover-fn.js

@@ -19,2 +19,3 @@ // src/data.ts

}).join(", ");
var openPopoverSelector = '[popover="" i].\\:open, [popover=auto i].\\:open';

@@ -34,2 +35,26 @@ // src/popover-helpers.ts

}
function* getOpenAutoPopovers() {
for (const popover of popovers) {
if (popover.matches(openPopoverSelector)) {
yield popover;
}
}
}
function hideOpenAutoPopovers(except) {
for (const popover of getOpenAutoPopovers()) {
if (popover !== except)
popover.hidePopover();
}
}
function closestShadowPenetrating(selector, target) {
const found = target.closest(selector);
if (found) {
return found;
}
const root = target.getRootNode();
if (root === document || !(root instanceof ShadowRoot)) {
return;
}
return closestShadowPenetrating(selector, root.host);
}
function setInvokerAriaExpanded(el) {

@@ -167,20 +192,5 @@ if (!initialAriaExpandedValue.has(el)) {

}
var closestElement = (selector, target) => {
const found = target.closest(selector);
if (found) {
return found;
}
const root = target.getRootNode();
if (root === document || !(root instanceof ShadowRoot)) {
return null;
}
return closestElement(selector, root.host);
};
var queryAncestorAll = (element, selector, popovers2 = []) => {
const ancestor = closestElement(selector, element);
const parent = ancestor?.parentElement || ancestor?.getRootNode()?.host;
return ancestor && parent ? queryAncestorAll(parent, selector, [ancestor, ...popovers2]) : popovers2;
};
function apply() {
const visibleElements = /* @__PURE__ */ new WeakSet();
let lastFocusedElement = null;
function checkPopoverValidity(element, expectedToBeShowing) {

@@ -254,8 +264,12 @@ if (element.popover !== "auto" && element.popover !== "manual") {

visibleElements.add(this);
const focusEl = this.hasAttribute("autofocus") ? this : this.querySelector("[autofocus]");
if (this.ownerDocument.activeElement instanceof HTMLElement) {
lastFocusedElement = this.ownerDocument.activeElement;
}
focusEl?.focus();
if (this.popover === "auto") {
const focusEl = this.hasAttribute("autofocus") ? this : this.querySelector("[autofocus]");
focusEl?.focus();
for (const invoker of getInvokersFor(this)) {
setInvokerAriaExpanded(invoker);
}
hideOpenAutoPopovers(this);
}

@@ -280,2 +294,6 @@ }

if (this.popover === "auto") {
if (lastFocusedElement) {
lastFocusedElement.focus();
lastFocusedElement = null;
}
for (const invoker of getInvokersFor(this)) {

@@ -344,25 +362,2 @@ setInvokerAriaExpanded(invoker);

definePopoverTargetElementProperty("popoverHideTarget");
const handlePopoverTargetElementInvocation = (invoker) => {
if (!(invoker instanceof HTMLButtonElement) && !(invoker instanceof HTMLInputElement)) {
return;
}
let popoverTargetElement = null;
if (invoker.popoverToggleTargetElement) {
popoverTargetElement = invoker.popoverToggleTargetElement;
if (popoverTargetElement) {
if (visibleElements.has(popoverTargetElement)) {
popoverTargetElement.hidePopover();
} else {
popoverTargetElement.showPopover();
}
}
} else if (invoker.popoverShowTargetElement) {
popoverTargetElement = invoker.popoverShowTargetElement;
popoverTargetElement?.showPopover();
} else if (invoker.popoverHideTargetElement) {
popoverTargetElement = invoker.popoverHideTargetElement;
popoverTargetElement?.hidePopover();
}
return popoverTargetElement;
};
const onClick = (event) => {

@@ -378,12 +373,39 @@ const target = event.target;

const invoker = target.closest(popoverInvokerSelector);
const popoverTargetElement = handlePopoverTargetElementInvocation(invoker);
for (const popover of [...popovers]) {
if (popover.matches('[popover="" i].\\:open, [popover=auto i].\\:open') && popover !== popoverTargetElement && !queryAncestorAll(target, "[popover]").includes(popover)) {
popover.hidePopover();
let popoverTargetElement = null;
if (invoker instanceof HTMLButtonElement || invoker instanceof HTMLInputElement) {
if (invoker.popoverToggleTargetElement) {
popoverTargetElement = invoker.popoverToggleTargetElement;
if (popoverTargetElement) {
if (visibleElements.has(popoverTargetElement)) {
popoverTargetElement.hidePopover();
} else {
popoverTargetElement.showPopover();
}
}
} else if (invoker.popoverShowTargetElement) {
popoverTargetElement = invoker.popoverShowTargetElement;
if (popoverTargetElement && !visibleElements.has(popoverTargetElement)) {
popoverTargetElement.showPopover();
}
} else if (invoker.popoverHideTargetElement) {
popoverTargetElement = invoker.popoverHideTargetElement;
if (popoverTargetElement && visibleElements.has(popoverTargetElement)) {
popoverTargetElement.hidePopover();
}
}
}
hideOpenAutoPopovers(
popoverTargetElement || closestShadowPenetrating(openPopoverSelector, target)
);
};
const addOnClickEventListener = ((callback) => (root) => {
root.addEventListener("click", callback);
})(onClick);
const onKeydown = (event) => {
const key = event.key;
if (key === "Escape" || key === "Esc") {
hideOpenAutoPopovers();
}
};
const addOnClickEventListener = (root) => {
root.addEventListener("click", onClick);
root.addEventListener("keydown", onKeydown);
};
observePopoversMutations(document);

@@ -390,0 +412,0 @@ addOnClickEventListener(document);

export declare const initialAriaExpandedValue: WeakMap<HTMLInputElement | HTMLButtonElement, string | null>;
export declare function getInvokersFor(el: HTMLElement): Generator<HTMLInputElement | HTMLButtonElement, void, unknown>;
export declare function getPopoverFor(el: HTMLButtonElement | HTMLInputElement): HTMLElement | null;
export declare function getOpenAutoPopovers(): Generator<HTMLElement, void, unknown>;
export declare function hideOpenAutoPopovers(except?: Element): void;
export declare function closestShadowPenetrating(selector: string, target: Element): Element | undefined;
export declare function setInvokerAriaExpanded(el: HTMLButtonElement | HTMLInputElement): void;
export declare function getPopoversFromNode(node: Node): Generator<HTMLElement, void, unknown>;
export declare function getInvokersFromNode(node: Node): Generator<HTMLButtonElement | HTMLInputElement>;

@@ -1,2 +0,2 @@

"use strict";(()=>{var a=new Set,v=new Set,P=["button",'input[type="button"]','input[type="submit"]','input[type="image"]','input[type="reset"]'],E=["popoverToggleTarget","popoverShowTarget","popoverHideTarget"],d=P.flatMap(e=>E.map(t=>`${e}[${t}]`)).join(", ");var h=new WeakMap;function*T(e){if(a.has(e))for(let t of v)w(t)===e&&(yield t)}function w(e){return e.popoverToggleTargetElement||e.popoverShowTargetElement||e.popoverHideTargetElement}function c(e){h.has(e)||h.set(e,e.getAttribute("aria-expanded"));let t=w(e);if(t?v.add(e):v.delete(e),t&&t.popover==="auto")e.setAttribute("aria-expanded",String(t.classList.contains(":open")));else{let r=h.get(e);r?e.setAttribute("aria-expanded",r):e.removeAttribute("aria-expanded")}}function*m(e){if(e instanceof HTMLElement&&e.hasAttribute("popover")&&(yield e),e instanceof Document||e instanceof ShadowRoot||e instanceof HTMLElement)for(let t of e.querySelectorAll("[popover]"))t instanceof HTMLElement&&(yield t)}function*g(e){if((e instanceof HTMLInputElement||e instanceof HTMLButtonElement)&&e.matches(d)&&(yield e),e instanceof Document||e instanceof ShadowRoot||e instanceof HTMLElement)for(let t of e.querySelectorAll(d))(t instanceof HTMLInputElement||t instanceof HTMLButtonElement)&&(yield t)}var x=e=>{for(let t of e.addedNodes){for(let r of g(t))c(r);for(let r of m(t))a.add(r)}for(let t of e.removedNodes){for(let r of g(t))v.delete(r);for(let r of m(t))a.delete(r)}},A=e=>{let t=e.target;t instanceof HTMLElement&&(t.hasAttribute("popover")?a.add(t):a.delete(t))},B=e=>{let t=e.target;(t instanceof HTMLButtonElement||t instanceof HTMLInputElement)&&c(t)},R=e=>{e.forEach(t=>{switch(t.type){case"attributes":switch(t.attributeName){case"popover":A(t);break;default:B(t);break}break;case"childList":x(t);break}})},N=new MutationObserver(R),M=e=>{if(e===document){for(let t of m(e))a.add(t);for(let t of g(e))c(t)}N.observe(e,{attributeFilter:["popover",...E],childList:!0,subtree:!0})};function H(){return typeof HTMLElement<"u"&&typeof HTMLElement.prototype=="object"&&"popover"in HTMLElement.prototype}function L(e){let t=Element.prototype.attachShadow;Element.prototype.attachShadow=function(r){let i=t.call(this,r);return e(i),i}}var S=(e,t)=>{let r=t.closest(e);if(r)return r;let i=t.getRootNode();return i===document||!(i instanceof ShadowRoot)?null:S(e,i.host)},y=(e,t,r=[])=>{let i=S(t,e),f=i?.parentElement||i?.getRootNode()?.host;return i&&f?y(f,t,[i,...r]):r};function k(){let e=new WeakSet;function t(o,n){return!(o.popover!=="auto"&&o.popover!=="manual"||!o.isConnected||o instanceof HTMLDialogElement&&o.hasAttribute("open")||n&&!e.has(o)||!n&&e.has(o)||document.fullscreenElement===o)}function r(o,n){if(!t(o,n))throw new DOMException("Cannot show or hide popover on invalid or already visible element","InvalidStateError")}class i extends Event{constructor(l,{currentState:s="",newState:u="",...p}={}){super(l,p);this.currentState=String(s||""),this.newState=String(u||"")}}window.BeforeToggleEvent=window.BeforeToggleEvent||i,Object.defineProperties(HTMLElement.prototype,{popover:{enumerable:!0,configurable:!0,get(){let o=(this.getAttribute("popover")||"").toLowerCase();return o==="manual"?"manual":o===""||o=="auto"?"auto":null},set(o){this.setAttribute("popover",o)}},showPopover:{enumerable:!0,configurable:!0,value(){r(this,!1);let o=new i("beforetoggle",{cancelable:!0,currentState:"closed",newState:"open"});if(this.dispatchEvent(o)&&(r(this,!1),this.classList.add(":open"),e.add(this),this.popover==="auto")){(this.hasAttribute("autofocus")?this:this.querySelector("[autofocus]"))?.focus();for(let l of T(this))c(l)}}},hidePopover:{enumerable:!0,configurable:!0,value(){if(r(this,!0),this.dispatchEvent(new i("beforetoggle",{cancelable:!1,currentState:"open",newState:"closed"})),r(this,!0),this.classList.remove(":open"),e.delete(this),this.popover==="auto")for(let o of T(this))c(o)}}});let f=o=>{let n=new WeakMap,l={set(s){if(s===null)this.removeAttribute(o.toLowerCase()),n.delete(this);else if(s instanceof Element)this.setAttribute(o.toLowerCase(),""),n.set(this,s);else throw new TypeError(`${o}Element must be an element or null`)},get(){if(this.localName!=="button"&&this.localName!=="input"||this.localName==="input"&&this.type!=="reset"&&this.type!=="image"&&this.type!=="button"||this.disabled||this.form&&this.type==="submit")return null;let s=n.get(this);if(s?.isConnected||n.delete(this),s)return s;let u=this.getRootNode(),p=this.getAttribute(o.toLowerCase());return(u instanceof Document||u instanceof ShadowRoot)&&p&&u.getElementById(p)||null}};Object.defineProperty(HTMLButtonElement.prototype,`${o}Element`,l),Object.defineProperty(HTMLInputElement.prototype,`${o}Element`,l)};f("popoverToggleTarget"),f("popoverShowTarget"),f("popoverHideTarget");let I=o=>{if(!(o instanceof HTMLButtonElement)&&!(o instanceof HTMLInputElement))return;let n=null;return o.popoverToggleTargetElement?(n=o.popoverToggleTargetElement,n&&(e.has(n)?n.hidePopover():n.showPopover())):o.popoverShowTargetElement?(n=o.popoverShowTargetElement,n?.showPopover()):o.popoverHideTargetElement&&(n=o.popoverHideTargetElement,n?.hidePopover()),n},b=(o=>n=>{n.addEventListener("click",o)})(o=>{let n=o.target;if(!(n instanceof Element)||n?.shadowRoot)return;let l=n.getRootNode();if(!(l instanceof ShadowRoot||l instanceof Document))return;let s=n.closest(d),u=I(s);for(let p of[...a])p.matches('[popover="" i].\\:open, [popover=auto i].\\:open')&&p!==u&&!y(n,"[popover]").includes(p)&&p.hidePopover()});M(document),b(document),L(M),L(b)}H()||k();})();
"use strict";(()=>{var l=new Set,c=new Set,B=["button",'input[type="button"]','input[type="submit"]','input[type="image"]','input[type="reset"]'],M=["popoverToggleTarget","popoverShowTarget","popoverHideTarget"],f=B.flatMap(e=>M.map(t=>`${e}[${t}]`)).join(", "),d='[popover="" i].\\:open, [popover=auto i].\\:open';var w=new WeakMap;function*b(e){if(l.has(e))for(let t of c)k(t)===e&&(yield t)}function k(e){return e.popoverToggleTargetElement||e.popoverShowTargetElement||e.popoverHideTargetElement}function*R(){for(let e of l)e.matches(d)&&(yield e)}function m(e){for(let t of R())t!==e&&t.hidePopover()}function L(e,t){let s=t.closest(e);if(s)return s;let a=t.getRootNode();if(!(a===document||!(a instanceof ShadowRoot)))return L(e,a.host)}function u(e){w.has(e)||w.set(e,e.getAttribute("aria-expanded"));let t=k(e);if(t?c.add(e):c.delete(e),t&&t.popover==="auto")e.setAttribute("aria-expanded",String(t.classList.contains(":open")));else{let s=w.get(e);s?e.setAttribute("aria-expanded",s):e.removeAttribute("aria-expanded")}}function*h(e){if(e instanceof HTMLElement&&e.hasAttribute("popover")&&(yield e),e instanceof Document||e instanceof ShadowRoot||e instanceof HTMLElement)for(let t of e.querySelectorAll("[popover]"))t instanceof HTMLElement&&(yield t)}function*E(e){if((e instanceof HTMLInputElement||e instanceof HTMLButtonElement)&&e.matches(f)&&(yield e),e instanceof Document||e instanceof ShadowRoot||e instanceof HTMLElement)for(let t of e.querySelectorAll(f))(t instanceof HTMLInputElement||t instanceof HTMLButtonElement)&&(yield t)}var N=e=>{for(let t of e.addedNodes){for(let s of E(t))u(s);for(let s of h(t))l.add(s)}for(let t of e.removedNodes){for(let s of E(t))c.delete(s);for(let s of h(t))l.delete(s)}},D=e=>{let t=e.target;t instanceof HTMLElement&&(t.hasAttribute("popover")?l.add(t):l.delete(t))},C=e=>{let t=e.target;(t instanceof HTMLButtonElement||t instanceof HTMLInputElement)&&u(t)},F=e=>{e.forEach(t=>{switch(t.type){case"attributes":switch(t.attributeName){case"popover":D(t);break;default:C(t);break}break;case"childList":N(t);break}})},O=new MutationObserver(F),H=e=>{if(e===document){for(let t of h(e))l.add(t);for(let t of E(e))u(t)}O.observe(e,{attributeFilter:["popover",...M],childList:!0,subtree:!0})};function P(){return typeof HTMLElement<"u"&&typeof HTMLElement.prototype=="object"&&"popover"in HTMLElement.prototype}function y(e){let t=Element.prototype.attachShadow;Element.prototype.attachShadow=function(s){let a=t.call(this,s);return e(a),a}}function I(){let e=new WeakSet,t=null;function s(o,n){return!(o.popover!=="auto"&&o.popover!=="manual"||!o.isConnected||o instanceof HTMLDialogElement&&o.hasAttribute("open")||n&&!e.has(o)||!n&&e.has(o)||document.fullscreenElement===o)}function a(o,n){if(!s(o,n))throw new DOMException("Cannot show or hide popover on invalid or already visible element","InvalidStateError")}class g extends Event{constructor(p,{currentState:i="",newState:r="",...v}={}){super(p,v);this.currentState=String(i||""),this.newState=String(r||"")}}window.BeforeToggleEvent=window.BeforeToggleEvent||g,Object.defineProperties(HTMLElement.prototype,{popover:{enumerable:!0,configurable:!0,get(){let o=(this.getAttribute("popover")||"").toLowerCase();return o==="manual"?"manual":o===""||o=="auto"?"auto":null},set(o){this.setAttribute("popover",o)}},showPopover:{enumerable:!0,configurable:!0,value(){a(this,!1);let o=new g("beforetoggle",{cancelable:!0,currentState:"closed",newState:"open"});if(!this.dispatchEvent(o))return;a(this,!1),this.classList.add(":open"),e.add(this);let n=this.hasAttribute("autofocus")?this:this.querySelector("[autofocus]");if(this.ownerDocument.activeElement instanceof HTMLElement&&(t=this.ownerDocument.activeElement),n?.focus(),this.popover==="auto"){for(let p of b(this))u(p);m(this)}}},hidePopover:{enumerable:!0,configurable:!0,value(){if(a(this,!0),this.dispatchEvent(new g("beforetoggle",{cancelable:!1,currentState:"open",newState:"closed"})),a(this,!0),this.classList.remove(":open"),e.delete(this),this.popover==="auto"){t&&(t.focus(),t=null);for(let o of b(this))u(o)}}}});let T=o=>{let n=new WeakMap,p={set(i){if(i===null)this.removeAttribute(o.toLowerCase()),n.delete(this);else if(i instanceof Element)this.setAttribute(o.toLowerCase(),""),n.set(this,i);else throw new TypeError(`${o}Element must be an element or null`)},get(){if(this.localName!=="button"&&this.localName!=="input"||this.localName==="input"&&this.type!=="reset"&&this.type!=="image"&&this.type!=="button"||this.disabled||this.form&&this.type==="submit")return null;let i=n.get(this);if(i?.isConnected||n.delete(this),i)return i;let r=this.getRootNode(),v=this.getAttribute(o.toLowerCase());return(r instanceof Document||r instanceof ShadowRoot)&&v&&r.getElementById(v)||null}};Object.defineProperty(HTMLButtonElement.prototype,`${o}Element`,p),Object.defineProperty(HTMLInputElement.prototype,`${o}Element`,p)};T("popoverToggleTarget"),T("popoverShowTarget"),T("popoverHideTarget");let x=o=>{let n=o.target;if(!(n instanceof Element)||n?.shadowRoot)return;let p=n.getRootNode();if(!(p instanceof ShadowRoot||p instanceof Document))return;let i=n.closest(f),r=null;(i instanceof HTMLButtonElement||i instanceof HTMLInputElement)&&(i.popoverToggleTargetElement?(r=i.popoverToggleTargetElement,r&&(e.has(r)?r.hidePopover():r.showPopover())):i.popoverShowTargetElement?(r=i.popoverShowTargetElement,r&&!e.has(r)&&r.showPopover()):i.popoverHideTargetElement&&(r=i.popoverHideTargetElement,r&&e.has(r)&&r.hidePopover())),m(r||L(d,n))},A=o=>{let n=o.key;(n==="Escape"||n==="Esc")&&m()},S=o=>{o.addEventListener("click",x),o.addEventListener("keydown",A)};H(document),S(document),y(H),y(S)}P()||I();})();
//# sourceMappingURL=popover.iife.min.js.map

@@ -19,2 +19,3 @@ // src/data.ts

}).join(", ");
var openPopoverSelector = '[popover="" i].\\:open, [popover=auto i].\\:open';

@@ -34,2 +35,26 @@ // src/popover-helpers.ts

}
function* getOpenAutoPopovers() {
for (const popover of popovers) {
if (popover.matches(openPopoverSelector)) {
yield popover;
}
}
}
function hideOpenAutoPopovers(except) {
for (const popover of getOpenAutoPopovers()) {
if (popover !== except)
popover.hidePopover();
}
}
function closestShadowPenetrating(selector, target) {
const found = target.closest(selector);
if (found) {
return found;
}
const root = target.getRootNode();
if (root === document || !(root instanceof ShadowRoot)) {
return;
}
return closestShadowPenetrating(selector, root.host);
}
function setInvokerAriaExpanded(el) {

@@ -167,20 +192,5 @@ if (!initialAriaExpandedValue.has(el)) {

}
var closestElement = (selector, target) => {
const found = target.closest(selector);
if (found) {
return found;
}
const root = target.getRootNode();
if (root === document || !(root instanceof ShadowRoot)) {
return null;
}
return closestElement(selector, root.host);
};
var queryAncestorAll = (element, selector, popovers2 = []) => {
const ancestor = closestElement(selector, element);
const parent = ancestor?.parentElement || ancestor?.getRootNode()?.host;
return ancestor && parent ? queryAncestorAll(parent, selector, [ancestor, ...popovers2]) : popovers2;
};
function apply() {
const visibleElements = /* @__PURE__ */ new WeakSet();
let lastFocusedElement = null;
function checkPopoverValidity(element, expectedToBeShowing) {

@@ -254,8 +264,12 @@ if (element.popover !== "auto" && element.popover !== "manual") {

visibleElements.add(this);
const focusEl = this.hasAttribute("autofocus") ? this : this.querySelector("[autofocus]");
if (this.ownerDocument.activeElement instanceof HTMLElement) {
lastFocusedElement = this.ownerDocument.activeElement;
}
focusEl?.focus();
if (this.popover === "auto") {
const focusEl = this.hasAttribute("autofocus") ? this : this.querySelector("[autofocus]");
focusEl?.focus();
for (const invoker of getInvokersFor(this)) {
setInvokerAriaExpanded(invoker);
}
hideOpenAutoPopovers(this);
}

@@ -280,2 +294,6 @@ }

if (this.popover === "auto") {
if (lastFocusedElement) {
lastFocusedElement.focus();
lastFocusedElement = null;
}
for (const invoker of getInvokersFor(this)) {

@@ -344,25 +362,2 @@ setInvokerAriaExpanded(invoker);

definePopoverTargetElementProperty("popoverHideTarget");
const handlePopoverTargetElementInvocation = (invoker) => {
if (!(invoker instanceof HTMLButtonElement) && !(invoker instanceof HTMLInputElement)) {
return;
}
let popoverTargetElement = null;
if (invoker.popoverToggleTargetElement) {
popoverTargetElement = invoker.popoverToggleTargetElement;
if (popoverTargetElement) {
if (visibleElements.has(popoverTargetElement)) {
popoverTargetElement.hidePopover();
} else {
popoverTargetElement.showPopover();
}
}
} else if (invoker.popoverShowTargetElement) {
popoverTargetElement = invoker.popoverShowTargetElement;
popoverTargetElement?.showPopover();
} else if (invoker.popoverHideTargetElement) {
popoverTargetElement = invoker.popoverHideTargetElement;
popoverTargetElement?.hidePopover();
}
return popoverTargetElement;
};
const onClick = (event) => {

@@ -378,12 +373,39 @@ const target = event.target;

const invoker = target.closest(popoverInvokerSelector);
const popoverTargetElement = handlePopoverTargetElementInvocation(invoker);
for (const popover of [...popovers]) {
if (popover.matches('[popover="" i].\\:open, [popover=auto i].\\:open') && popover !== popoverTargetElement && !queryAncestorAll(target, "[popover]").includes(popover)) {
popover.hidePopover();
let popoverTargetElement = null;
if (invoker instanceof HTMLButtonElement || invoker instanceof HTMLInputElement) {
if (invoker.popoverToggleTargetElement) {
popoverTargetElement = invoker.popoverToggleTargetElement;
if (popoverTargetElement) {
if (visibleElements.has(popoverTargetElement)) {
popoverTargetElement.hidePopover();
} else {
popoverTargetElement.showPopover();
}
}
} else if (invoker.popoverShowTargetElement) {
popoverTargetElement = invoker.popoverShowTargetElement;
if (popoverTargetElement && !visibleElements.has(popoverTargetElement)) {
popoverTargetElement.showPopover();
}
} else if (invoker.popoverHideTargetElement) {
popoverTargetElement = invoker.popoverHideTargetElement;
if (popoverTargetElement && visibleElements.has(popoverTargetElement)) {
popoverTargetElement.hidePopover();
}
}
}
hideOpenAutoPopovers(
popoverTargetElement || closestShadowPenetrating(openPopoverSelector, target)
);
};
const addOnClickEventListener = ((callback) => (root) => {
root.addEventListener("click", callback);
})(onClick);
const onKeydown = (event) => {
const key = event.key;
if (key === "Escape" || key === "Esc") {
hideOpenAutoPopovers();
}
};
const addOnClickEventListener = (root) => {
root.addEventListener("click", onClick);
root.addEventListener("keydown", onKeydown);
};
observePopoversMutations(document);

@@ -390,0 +412,0 @@ addOnClickEventListener(document);

@@ -1,2 +0,2 @@

var a=new Set,v=new Set,P=["button",'input[type="button"]','input[type="submit"]','input[type="image"]','input[type="reset"]'],E=["popoverToggleTarget","popoverShowTarget","popoverHideTarget"],d=P.flatMap(e=>E.map(t=>`${e}[${t}]`)).join(", ");var h=new WeakMap;function*T(e){if(a.has(e))for(let t of v)w(t)===e&&(yield t)}function w(e){return e.popoverToggleTargetElement||e.popoverShowTargetElement||e.popoverHideTargetElement}function c(e){h.has(e)||h.set(e,e.getAttribute("aria-expanded"));let t=w(e);if(t?v.add(e):v.delete(e),t&&t.popover==="auto")e.setAttribute("aria-expanded",String(t.classList.contains(":open")));else{let r=h.get(e);r?e.setAttribute("aria-expanded",r):e.removeAttribute("aria-expanded")}}function*m(e){if(e instanceof HTMLElement&&e.hasAttribute("popover")&&(yield e),e instanceof Document||e instanceof ShadowRoot||e instanceof HTMLElement)for(let t of e.querySelectorAll("[popover]"))t instanceof HTMLElement&&(yield t)}function*g(e){if((e instanceof HTMLInputElement||e instanceof HTMLButtonElement)&&e.matches(d)&&(yield e),e instanceof Document||e instanceof ShadowRoot||e instanceof HTMLElement)for(let t of e.querySelectorAll(d))(t instanceof HTMLInputElement||t instanceof HTMLButtonElement)&&(yield t)}var x=e=>{for(let t of e.addedNodes){for(let r of g(t))c(r);for(let r of m(t))a.add(r)}for(let t of e.removedNodes){for(let r of g(t))v.delete(r);for(let r of m(t))a.delete(r)}},A=e=>{let t=e.target;t instanceof HTMLElement&&(t.hasAttribute("popover")?a.add(t):a.delete(t))},B=e=>{let t=e.target;(t instanceof HTMLButtonElement||t instanceof HTMLInputElement)&&c(t)},R=e=>{e.forEach(t=>{switch(t.type){case"attributes":switch(t.attributeName){case"popover":A(t);break;default:B(t);break}break;case"childList":x(t);break}})},N=new MutationObserver(R),M=e=>{if(e===document){for(let t of m(e))a.add(t);for(let t of g(e))c(t)}N.observe(e,{attributeFilter:["popover",...E],childList:!0,subtree:!0})};function H(){return typeof HTMLElement<"u"&&typeof HTMLElement.prototype=="object"&&"popover"in HTMLElement.prototype}function L(e){let t=Element.prototype.attachShadow;Element.prototype.attachShadow=function(r){let i=t.call(this,r);return e(i),i}}var S=(e,t)=>{let r=t.closest(e);if(r)return r;let i=t.getRootNode();return i===document||!(i instanceof ShadowRoot)?null:S(e,i.host)},y=(e,t,r=[])=>{let i=S(t,e),f=i?.parentElement||i?.getRootNode()?.host;return i&&f?y(f,t,[i,...r]):r};function k(){let e=new WeakSet;function t(o,n){return!(o.popover!=="auto"&&o.popover!=="manual"||!o.isConnected||o instanceof HTMLDialogElement&&o.hasAttribute("open")||n&&!e.has(o)||!n&&e.has(o)||document.fullscreenElement===o)}function r(o,n){if(!t(o,n))throw new DOMException("Cannot show or hide popover on invalid or already visible element","InvalidStateError")}class i extends Event{constructor(l,{currentState:s="",newState:u="",...p}={}){super(l,p);this.currentState=String(s||""),this.newState=String(u||"")}}window.BeforeToggleEvent=window.BeforeToggleEvent||i,Object.defineProperties(HTMLElement.prototype,{popover:{enumerable:!0,configurable:!0,get(){let o=(this.getAttribute("popover")||"").toLowerCase();return o==="manual"?"manual":o===""||o=="auto"?"auto":null},set(o){this.setAttribute("popover",o)}},showPopover:{enumerable:!0,configurable:!0,value(){r(this,!1);let o=new i("beforetoggle",{cancelable:!0,currentState:"closed",newState:"open"});if(this.dispatchEvent(o)&&(r(this,!1),this.classList.add(":open"),e.add(this),this.popover==="auto")){(this.hasAttribute("autofocus")?this:this.querySelector("[autofocus]"))?.focus();for(let l of T(this))c(l)}}},hidePopover:{enumerable:!0,configurable:!0,value(){if(r(this,!0),this.dispatchEvent(new i("beforetoggle",{cancelable:!1,currentState:"open",newState:"closed"})),r(this,!0),this.classList.remove(":open"),e.delete(this),this.popover==="auto")for(let o of T(this))c(o)}}});let f=o=>{let n=new WeakMap,l={set(s){if(s===null)this.removeAttribute(o.toLowerCase()),n.delete(this);else if(s instanceof Element)this.setAttribute(o.toLowerCase(),""),n.set(this,s);else throw new TypeError(`${o}Element must be an element or null`)},get(){if(this.localName!=="button"&&this.localName!=="input"||this.localName==="input"&&this.type!=="reset"&&this.type!=="image"&&this.type!=="button"||this.disabled||this.form&&this.type==="submit")return null;let s=n.get(this);if(s?.isConnected||n.delete(this),s)return s;let u=this.getRootNode(),p=this.getAttribute(o.toLowerCase());return(u instanceof Document||u instanceof ShadowRoot)&&p&&u.getElementById(p)||null}};Object.defineProperty(HTMLButtonElement.prototype,`${o}Element`,l),Object.defineProperty(HTMLInputElement.prototype,`${o}Element`,l)};f("popoverToggleTarget"),f("popoverShowTarget"),f("popoverHideTarget");let I=o=>{if(!(o instanceof HTMLButtonElement)&&!(o instanceof HTMLInputElement))return;let n=null;return o.popoverToggleTargetElement?(n=o.popoverToggleTargetElement,n&&(e.has(n)?n.hidePopover():n.showPopover())):o.popoverShowTargetElement?(n=o.popoverShowTargetElement,n?.showPopover()):o.popoverHideTargetElement&&(n=o.popoverHideTargetElement,n?.hidePopover()),n},b=(o=>n=>{n.addEventListener("click",o)})(o=>{let n=o.target;if(!(n instanceof Element)||n?.shadowRoot)return;let l=n.getRootNode();if(!(l instanceof ShadowRoot||l instanceof Document))return;let s=n.closest(d),u=I(s);for(let p of[...a])p.matches('[popover="" i].\\:open, [popover=auto i].\\:open')&&p!==u&&!y(n,"[popover]").includes(p)&&p.hidePopover()});M(document),b(document),L(M),L(b)}H()||k();
var l=new Set,c=new Set,B=["button",'input[type="button"]','input[type="submit"]','input[type="image"]','input[type="reset"]'],M=["popoverToggleTarget","popoverShowTarget","popoverHideTarget"],f=B.flatMap(e=>M.map(t=>`${e}[${t}]`)).join(", "),d='[popover="" i].\\:open, [popover=auto i].\\:open';var w=new WeakMap;function*b(e){if(l.has(e))for(let t of c)k(t)===e&&(yield t)}function k(e){return e.popoverToggleTargetElement||e.popoverShowTargetElement||e.popoverHideTargetElement}function*R(){for(let e of l)e.matches(d)&&(yield e)}function m(e){for(let t of R())t!==e&&t.hidePopover()}function L(e,t){let s=t.closest(e);if(s)return s;let a=t.getRootNode();if(!(a===document||!(a instanceof ShadowRoot)))return L(e,a.host)}function u(e){w.has(e)||w.set(e,e.getAttribute("aria-expanded"));let t=k(e);if(t?c.add(e):c.delete(e),t&&t.popover==="auto")e.setAttribute("aria-expanded",String(t.classList.contains(":open")));else{let s=w.get(e);s?e.setAttribute("aria-expanded",s):e.removeAttribute("aria-expanded")}}function*h(e){if(e instanceof HTMLElement&&e.hasAttribute("popover")&&(yield e),e instanceof Document||e instanceof ShadowRoot||e instanceof HTMLElement)for(let t of e.querySelectorAll("[popover]"))t instanceof HTMLElement&&(yield t)}function*E(e){if((e instanceof HTMLInputElement||e instanceof HTMLButtonElement)&&e.matches(f)&&(yield e),e instanceof Document||e instanceof ShadowRoot||e instanceof HTMLElement)for(let t of e.querySelectorAll(f))(t instanceof HTMLInputElement||t instanceof HTMLButtonElement)&&(yield t)}var N=e=>{for(let t of e.addedNodes){for(let s of E(t))u(s);for(let s of h(t))l.add(s)}for(let t of e.removedNodes){for(let s of E(t))c.delete(s);for(let s of h(t))l.delete(s)}},D=e=>{let t=e.target;t instanceof HTMLElement&&(t.hasAttribute("popover")?l.add(t):l.delete(t))},C=e=>{let t=e.target;(t instanceof HTMLButtonElement||t instanceof HTMLInputElement)&&u(t)},F=e=>{e.forEach(t=>{switch(t.type){case"attributes":switch(t.attributeName){case"popover":D(t);break;default:C(t);break}break;case"childList":N(t);break}})},O=new MutationObserver(F),H=e=>{if(e===document){for(let t of h(e))l.add(t);for(let t of E(e))u(t)}O.observe(e,{attributeFilter:["popover",...M],childList:!0,subtree:!0})};function P(){return typeof HTMLElement<"u"&&typeof HTMLElement.prototype=="object"&&"popover"in HTMLElement.prototype}function y(e){let t=Element.prototype.attachShadow;Element.prototype.attachShadow=function(s){let a=t.call(this,s);return e(a),a}}function I(){let e=new WeakSet,t=null;function s(o,n){return!(o.popover!=="auto"&&o.popover!=="manual"||!o.isConnected||o instanceof HTMLDialogElement&&o.hasAttribute("open")||n&&!e.has(o)||!n&&e.has(o)||document.fullscreenElement===o)}function a(o,n){if(!s(o,n))throw new DOMException("Cannot show or hide popover on invalid or already visible element","InvalidStateError")}class g extends Event{constructor(p,{currentState:i="",newState:r="",...v}={}){super(p,v);this.currentState=String(i||""),this.newState=String(r||"")}}window.BeforeToggleEvent=window.BeforeToggleEvent||g,Object.defineProperties(HTMLElement.prototype,{popover:{enumerable:!0,configurable:!0,get(){let o=(this.getAttribute("popover")||"").toLowerCase();return o==="manual"?"manual":o===""||o=="auto"?"auto":null},set(o){this.setAttribute("popover",o)}},showPopover:{enumerable:!0,configurable:!0,value(){a(this,!1);let o=new g("beforetoggle",{cancelable:!0,currentState:"closed",newState:"open"});if(!this.dispatchEvent(o))return;a(this,!1),this.classList.add(":open"),e.add(this);let n=this.hasAttribute("autofocus")?this:this.querySelector("[autofocus]");if(this.ownerDocument.activeElement instanceof HTMLElement&&(t=this.ownerDocument.activeElement),n?.focus(),this.popover==="auto"){for(let p of b(this))u(p);m(this)}}},hidePopover:{enumerable:!0,configurable:!0,value(){if(a(this,!0),this.dispatchEvent(new g("beforetoggle",{cancelable:!1,currentState:"open",newState:"closed"})),a(this,!0),this.classList.remove(":open"),e.delete(this),this.popover==="auto"){t&&(t.focus(),t=null);for(let o of b(this))u(o)}}}});let T=o=>{let n=new WeakMap,p={set(i){if(i===null)this.removeAttribute(o.toLowerCase()),n.delete(this);else if(i instanceof Element)this.setAttribute(o.toLowerCase(),""),n.set(this,i);else throw new TypeError(`${o}Element must be an element or null`)},get(){if(this.localName!=="button"&&this.localName!=="input"||this.localName==="input"&&this.type!=="reset"&&this.type!=="image"&&this.type!=="button"||this.disabled||this.form&&this.type==="submit")return null;let i=n.get(this);if(i?.isConnected||n.delete(this),i)return i;let r=this.getRootNode(),v=this.getAttribute(o.toLowerCase());return(r instanceof Document||r instanceof ShadowRoot)&&v&&r.getElementById(v)||null}};Object.defineProperty(HTMLButtonElement.prototype,`${o}Element`,p),Object.defineProperty(HTMLInputElement.prototype,`${o}Element`,p)};T("popoverToggleTarget"),T("popoverShowTarget"),T("popoverHideTarget");let x=o=>{let n=o.target;if(!(n instanceof Element)||n?.shadowRoot)return;let p=n.getRootNode();if(!(p instanceof ShadowRoot||p instanceof Document))return;let i=n.closest(f),r=null;(i instanceof HTMLButtonElement||i instanceof HTMLInputElement)&&(i.popoverToggleTargetElement?(r=i.popoverToggleTargetElement,r&&(e.has(r)?r.hidePopover():r.showPopover())):i.popoverShowTargetElement?(r=i.popoverShowTargetElement,r&&!e.has(r)&&r.showPopover()):i.popoverHideTargetElement&&(r=i.popoverHideTargetElement,r&&e.has(r)&&r.hidePopover())),m(r||L(d,n))},A=o=>{let n=o.key;(n==="Escape"||n==="Esc")&&m()},S=o=>{o.addEventListener("click",x),o.addEventListener("keydown",A)};H(document),S(document),y(H),y(S)}P()||I();
//# sourceMappingURL=popover.min.js.map
{
"name": "@oddbird/popover-polyfill",
"version": "0.0.10",
"version": "0.0.11",
"description": "Popover Attribute Polyfill",

@@ -91,7 +91,7 @@ "license": "BSD-3-Clause",

"@types/node": "*",
"@typescript-eslint/eslint-plugin": "^5.54.0",
"@typescript-eslint/parser": "^5.54.0",
"esbuild": "^0.17.10",
"eslint": "^8.35.0",
"eslint-config-prettier": "^8.6.0",
"@typescript-eslint/eslint-plugin": "^5.54.1",
"@typescript-eslint/parser": "^5.54.1",
"esbuild": "^0.17.11",
"eslint": "^8.36.0",
"eslint-config-prettier": "^8.7.0",
"eslint-import-resolver-typescript": "^3.5.3",

@@ -102,3 +102,3 @@ "eslint-plugin-import": "^2.27.5",

"husky": "^8.0.3",
"lint-staged": "^13.1.2",
"lint-staged": "^13.2.0",
"npm-run-all": "^4.1.5",

@@ -105,0 +105,0 @@ "prettier": "^2.8.4",

@@ -23,1 +23,4 @@ export const popovers = new Set<HTMLElement>();

.join(', ');
export const openPopoverSelector =
'[popover="" i].\\:open, [popover=auto i].\\:open';

@@ -1,2 +0,7 @@

import { invokers, popoverInvokerSelector, popovers } from './data.js';
import {
invokers,
openPopoverSelector,
popoverInvokerSelector,
popovers,
} from './data.js';
export const initialAriaExpandedValue = new WeakMap<

@@ -22,2 +27,33 @@ HTMLButtonElement | HTMLInputElement,

export function* getOpenAutoPopovers() {
for (const popover of popovers) {
if (popover.matches(openPopoverSelector)) {
yield popover;
}
}
}
export function hideOpenAutoPopovers(except?: Element) {
for (const popover of getOpenAutoPopovers()) {
if (popover !== except) popover.hidePopover();
}
}
export function closestShadowPenetrating(
selector: string,
target: Element,
): Element | undefined {
const found = target.closest(selector);
if (found) {
return found;
}
const root = target.getRootNode();
if (root === document || !(root instanceof ShadowRoot)) {
return;
}
return closestShadowPenetrating(selector, root.host);
}
export function setInvokerAriaExpanded(

@@ -24,0 +60,0 @@ el: HTMLButtonElement | HTMLInputElement,

@@ -1,4 +0,9 @@

import { popoverInvokerSelector, popovers } from './data.js';
import { openPopoverSelector, popoverInvokerSelector } from './data.js';
import { observePopoversMutations } from './observer.js';
import { getInvokersFor, setInvokerAriaExpanded } from './popover-helpers.js';
import {
closestShadowPenetrating,
getInvokersFor,
hideOpenAutoPopovers,
setInvokerAriaExpanded,
} from './popover-helpers.js';

@@ -22,36 +27,5 @@ export function isSupported() {

const closestElement: (selector: string, target: Element) => Element | null = (
selector: string,
target: Element,
) => {
const found = target.closest(selector);
if (found) {
return found;
}
const root = target.getRootNode();
if (root === document || !(root instanceof ShadowRoot)) {
return null;
}
return closestElement(selector, root.host);
};
const queryAncestorAll = (
element: Element,
selector: string,
popovers: Element[] = [],
): Element[] => {
const ancestor = closestElement(selector, element);
const parent =
ancestor?.parentElement || (ancestor?.getRootNode() as ShadowRoot)?.host;
return ancestor && parent
? queryAncestorAll(parent, selector, [ancestor, ...popovers])
: popovers;
};
export function apply() {
const visibleElements = new WeakSet<HTMLElement>();
let lastFocusedElement: HTMLElement | null = null;

@@ -141,10 +115,14 @@ // https://whatpr.org/html/8221/popover.html#check-popover-validity

visibleElements.add(this);
const focusEl = this.hasAttribute('autofocus')
? this
: this.querySelector('[autofocus]');
if (this.ownerDocument.activeElement instanceof HTMLElement) {
lastFocusedElement = this.ownerDocument.activeElement;
}
focusEl?.focus();
if (this.popover === 'auto') {
const focusEl = this.hasAttribute('autofocus')
? this
: this.querySelector('[autofocus]');
focusEl?.focus();
for (const invoker of getInvokersFor(this)) {
setInvokerAriaExpanded(invoker);
}
hideOpenAutoPopovers(this);
}

@@ -171,2 +149,6 @@ },

if (this.popover === 'auto') {
if (lastFocusedElement) {
lastFocusedElement.focus();
lastFocusedElement = null;
}
for (const invoker of getInvokersFor(this)) {

@@ -244,29 +226,2 @@ setInvokerAriaExpanded(invoker);

const handlePopoverTargetElementInvocation = (invoker: Element | null) => {
if (
!(invoker instanceof HTMLButtonElement) &&
!(invoker instanceof HTMLInputElement)
) {
return;
}
let popoverTargetElement: HTMLElement | null = null;
if (invoker.popoverToggleTargetElement) {
popoverTargetElement = invoker.popoverToggleTargetElement;
if (popoverTargetElement) {
if (visibleElements.has(popoverTargetElement)) {
popoverTargetElement.hidePopover();
} else {
popoverTargetElement.showPopover();
}
}
} else if (invoker.popoverShowTargetElement) {
popoverTargetElement = invoker.popoverShowTargetElement;
popoverTargetElement?.showPopover();
} else if (invoker.popoverHideTargetElement) {
popoverTargetElement = invoker.popoverHideTargetElement;
popoverTargetElement?.hidePopover();
}
return popoverTargetElement;
};
const onClick = (event: Event) => {

@@ -282,20 +237,49 @@ const target = event.target;

const invoker = target.closest(popoverInvokerSelector);
const popoverTargetElement = handlePopoverTargetElementInvocation(invoker);
for (const popover of [...popovers]) {
if (
popover.matches('[popover="" i].\\:open, [popover=auto i].\\:open') &&
popover !== popoverTargetElement &&
!queryAncestorAll(target, '[popover]').includes(popover)
) {
popover.hidePopover();
let popoverTargetElement: HTMLElement | null = null;
if (
invoker instanceof HTMLButtonElement ||
invoker instanceof HTMLInputElement
) {
if (invoker.popoverToggleTargetElement) {
popoverTargetElement = invoker.popoverToggleTargetElement;
if (popoverTargetElement) {
if (visibleElements.has(popoverTargetElement)) {
popoverTargetElement.hidePopover();
} else {
popoverTargetElement.showPopover();
}
}
} else if (invoker.popoverShowTargetElement) {
popoverTargetElement = invoker.popoverShowTargetElement;
if (
popoverTargetElement &&
!visibleElements.has(popoverTargetElement)
) {
popoverTargetElement.showPopover();
}
} else if (invoker.popoverHideTargetElement) {
popoverTargetElement = invoker.popoverHideTargetElement;
if (popoverTargetElement && visibleElements.has(popoverTargetElement)) {
popoverTargetElement.hidePopover();
}
}
}
hideOpenAutoPopovers(
popoverTargetElement ||
closestShadowPenetrating(openPopoverSelector, target),
);
};
const addOnClickEventListener = (
(callback: (event: Event) => void) => (root: Document | ShadowRoot) => {
root.addEventListener('click', callback);
const onKeydown = (event: Event) => {
const key = (event as KeyboardEvent).key;
if (key === 'Escape' || key === 'Esc') {
hideOpenAutoPopovers();
}
)(onClick);
};
const addOnClickEventListener = (root: Document | ShadowRoot) => {
root.addEventListener('click', onClick);
root.addEventListener('keydown', onKeydown);
};
observePopoversMutations(document);

@@ -302,0 +286,0 @@ addOnClickEventListener(document);

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc